|
|
|
@ -32,8 +32,7 @@ |
|
|
|
image and NOT in the file. |
|
|
|
|
|
|
|
To be compatible with any existing executables I have fixed this |
|
|
|
here and NOT in the DJGPP startup code. |
|
|
|
*/ |
|
|
|
here and NOT in the DJGPP startup code. */ |
|
|
|
|
|
|
|
#define TARGET_SYM go32stubbedcoff_vec |
|
|
|
#define TARGET_NAME "coff-go32-exe" |
|
|
|
@ -55,40 +54,32 @@ |
|
|
|
|
|
|
|
#include "bfd.h" |
|
|
|
|
|
|
|
/* At first the prototypes */ |
|
|
|
/* At first the prototypes. */ |
|
|
|
|
|
|
|
static void |
|
|
|
adjust_filehdr_in_post PARAMS ((bfd * abfd, PTR src, PTR dst)); |
|
|
|
adjust_filehdr_in_post PARAMS ((bfd *, PTR, PTR)); |
|
|
|
static void |
|
|
|
adjust_filehdr_out_pre PARAMS ((bfd * abfd, PTR in, PTR out)); |
|
|
|
adjust_filehdr_out_pre PARAMS ((bfd *, PTR, PTR)); |
|
|
|
static void |
|
|
|
adjust_filehdr_out_post PARAMS ((bfd * abfd, PTR in, PTR out)); |
|
|
|
|
|
|
|
adjust_filehdr_out_post PARAMS ((bfd *, PTR, PTR)); |
|
|
|
static void |
|
|
|
adjust_scnhdr_in_post PARAMS ((bfd * abfd, PTR ext, PTR in)); |
|
|
|
adjust_scnhdr_in_post PARAMS ((bfd *, PTR, PTR)); |
|
|
|
static void |
|
|
|
adjust_scnhdr_out_pre PARAMS ((bfd * abfd, PTR in, PTR out)); |
|
|
|
adjust_scnhdr_out_pre PARAMS ((bfd *, PTR, PTR)); |
|
|
|
static void |
|
|
|
adjust_scnhdr_out_post PARAMS ((bfd * abfd, PTR in, PTR out)); |
|
|
|
|
|
|
|
adjust_scnhdr_out_post PARAMS ((bfd *, PTR, PTR)); |
|
|
|
static void |
|
|
|
adjust_aux_in_post PARAMS ((bfd * abfd, PTR ext1, int type, int class, int indx, |
|
|
|
int numaux, PTR in1)); |
|
|
|
adjust_aux_in_post PARAMS ((bfd *, PTR, int, int, int, int, PTR)); |
|
|
|
static void |
|
|
|
adjust_aux_out_pre PARAMS ((bfd * abfd, PTR inp, int type, int class, int indx, |
|
|
|
int numaux, PTR extp)); |
|
|
|
adjust_aux_out_pre PARAMS ((bfd *, PTR, int, int, int, int, PTR)); |
|
|
|
static void |
|
|
|
adjust_aux_out_post PARAMS ((bfd * abfd, PTR inp, int type, int class, int indx, |
|
|
|
int numaux, PTR extp)); |
|
|
|
|
|
|
|
adjust_aux_out_post PARAMS ((bfd *, PTR, int, int, int, int, PTR)); |
|
|
|
static void |
|
|
|
create_go32_stub PARAMS ((bfd * abfd)); |
|
|
|
create_go32_stub PARAMS ((bfd *)); |
|
|
|
|
|
|
|
/*
|
|
|
|
All that ..._PRE and ...POST functions are called from the corresponding |
|
|
|
/* All that ..._PRE and ...POST functions are called from the corresponding
|
|
|
|
coff_swap... functions. The ...PRE functions are called at the beginning |
|
|
|
of the function and the ...POST functions at the end of the swap routines. |
|
|
|
*/ |
|
|
|
of the function and the ...POST functions at the end of the swap routines. */ |
|
|
|
|
|
|
|
#define COFF_ADJUST_FILEHDR_IN_POST adjust_filehdr_in_post |
|
|
|
#define COFF_ADJUST_FILEHDR_OUT_PRE adjust_filehdr_out_pre |
|
|
|
@ -103,23 +94,23 @@ create_go32_stub PARAMS ((bfd * abfd)); |
|
|
|
#define COFF_ADJUST_AUX_OUT_POST adjust_aux_out_post |
|
|
|
|
|
|
|
static boolean |
|
|
|
go32_stubbed_coff_bfd_copy_private_bfd_data PARAMS ((bfd * ibfd, bfd * obfd)); |
|
|
|
go32_stubbed_coff_bfd_copy_private_bfd_data PARAMS ((bfd *, bfd *)); |
|
|
|
|
|
|
|
#define coff_bfd_copy_private_bfd_data go32_stubbed_coff_bfd_copy_private_bfd_data |
|
|
|
|
|
|
|
#include "coff-i386.c" |
|
|
|
|
|
|
|
/* I hold in the usrdata the stub */ |
|
|
|
/* I hold in the usrdata the stub. */ |
|
|
|
#define bfd_coff_go32stub bfd_usrdata |
|
|
|
|
|
|
|
/* This macro is used, because I cannot assume the endianess of the
|
|
|
|
host system */ |
|
|
|
host system. */ |
|
|
|
#define _H(index) (H_GET_16 (abfd, (header+index*2))) |
|
|
|
|
|
|
|
/* These bytes are a 2048-byte DOS executable, which loads the COFF
|
|
|
|
image into memory and then runs it. It is called 'stub' */ |
|
|
|
image into memory and then runs it. It is called 'stub'. */ |
|
|
|
|
|
|
|
static unsigned char stub_bytes[STUBSIZE] = |
|
|
|
static const unsigned char stub_bytes[STUBSIZE] = |
|
|
|
{ |
|
|
|
#include "go32stub.h" |
|
|
|
}; |
|
|
|
@ -129,10 +120,10 @@ static unsigned char stub_bytes[STUBSIZE] = |
|
|
|
technique is in any function the same. For the ...in function, |
|
|
|
all the pointers are adjusted by adding STUBSIZE and for the |
|
|
|
...out function, it is subtracted first and after calling the |
|
|
|
standard swap function it is reset to the old value */ |
|
|
|
standard swap function it is reset to the old value. */ |
|
|
|
|
|
|
|
/* This macro is used for adjusting the filepointers, which
|
|
|
|
is done only, if the pointer is nonzero */ |
|
|
|
is done only, if the pointer is nonzero. */ |
|
|
|
|
|
|
|
#define ADJUST_VAL(val,diff) \ |
|
|
|
if (val != 0) val += diff |
|
|
|
@ -148,13 +139,13 @@ adjust_filehdr_in_post (abfd, src, dst) |
|
|
|
|
|
|
|
ADJUST_VAL (filehdr_dst->f_symptr, STUBSIZE); |
|
|
|
|
|
|
|
/* Save now the stub to be used later */ |
|
|
|
/* Save now the stub to be used later. */ |
|
|
|
bfd_coff_go32stub (abfd) = (PTR) bfd_alloc (abfd, (bfd_size_type) STUBSIZE); |
|
|
|
|
|
|
|
/* Since this function returns no status, I do not set here
|
|
|
|
any bfd_error_... |
|
|
|
That means, before the use of bfd_coff_go32stub (), this value |
|
|
|
should be checked if it is != NULL */ |
|
|
|
should be checked if it is != NULL. */ |
|
|
|
if (bfd_coff_go32stub (abfd) == NULL) |
|
|
|
return; |
|
|
|
memcpy (bfd_coff_go32stub (abfd), filehdr_src->stub, STUBSIZE); |
|
|
|
@ -169,14 +160,14 @@ adjust_filehdr_out_pre (abfd, in, out) |
|
|
|
struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in; |
|
|
|
FILHDR *filehdr_out = (FILHDR *) out; |
|
|
|
|
|
|
|
/* Generate the stub */ |
|
|
|
/* Generate the stub. */ |
|
|
|
create_go32_stub (abfd); |
|
|
|
|
|
|
|
/* Copy the stub to the file header */ |
|
|
|
/* Copy the stub to the file header. */ |
|
|
|
if (bfd_coff_go32stub (abfd) != NULL) |
|
|
|
memcpy (filehdr_out->stub, bfd_coff_go32stub (abfd), STUBSIZE); |
|
|
|
else |
|
|
|
/* use the default */ |
|
|
|
/* Use the default. */ |
|
|
|
memcpy (filehdr_out->stub, stub_bytes, STUBSIZE); |
|
|
|
|
|
|
|
ADJUST_VAL (filehdr_in->f_symptr, -STUBSIZE); |
|
|
|
@ -189,7 +180,7 @@ adjust_filehdr_out_post (abfd, in, out) |
|
|
|
PTR out ATTRIBUTE_UNUSED; |
|
|
|
{ |
|
|
|
struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in; |
|
|
|
/* undo the above change */ |
|
|
|
/* Undo the above change. */ |
|
|
|
ADJUST_VAL (filehdr_in->f_symptr, STUBSIZE); |
|
|
|
} |
|
|
|
|
|
|
|
@ -286,8 +277,7 @@ adjust_aux_out_post (abfd, inp, type, class, indx, numaux, extp) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/*
|
|
|
|
That's the function, which creates the stub. There are |
|
|
|
/* That's the function, which creates the stub. There are
|
|
|
|
different cases from where the stub is taken. |
|
|
|
At first the environment variable $(GO32STUB) is checked and then |
|
|
|
$(STUB) if it was not set. |
|
|
|
@ -297,14 +287,13 @@ adjust_aux_out_post (abfd, inp, type, class, indx, numaux, extp) |
|
|
|
file. |
|
|
|
|
|
|
|
If there was any error, the standard stub (compiled in this file) |
|
|
|
is taken. |
|
|
|
*/ |
|
|
|
is taken. */ |
|
|
|
|
|
|
|
static void |
|
|
|
create_go32_stub (abfd) |
|
|
|
bfd *abfd; |
|
|
|
{ |
|
|
|
/* Do it only once */ |
|
|
|
/* Do it only once. */ |
|
|
|
if (bfd_coff_go32stub (abfd) == NULL) |
|
|
|
{ |
|
|
|
char *stub; |
|
|
|
@ -315,9 +304,9 @@ create_go32_stub (abfd) |
|
|
|
unsigned long coff_start; |
|
|
|
long exe_start; |
|
|
|
|
|
|
|
/* Check at first the environment variable $(GO32STUB) */ |
|
|
|
/* Check at first the environment variable $(GO32STUB). */ |
|
|
|
stub = getenv ("GO32STUB"); |
|
|
|
/* Now check the environment variable $(STUB) */ |
|
|
|
/* Now check the environment variable $(STUB). */ |
|
|
|
if (stub == NULL) |
|
|
|
stub = getenv ("STUB"); |
|
|
|
if (stub == NULL) |
|
|
|
@ -336,19 +325,19 @@ create_go32_stub (abfd) |
|
|
|
close (f); |
|
|
|
goto stub_end; |
|
|
|
} |
|
|
|
if (_H (0) != 0x5a4d) /* it is not an exe file */ |
|
|
|
if (_H (0) != 0x5a4d) /* It is not an exe file. */ |
|
|
|
{ |
|
|
|
close (f); |
|
|
|
goto stub_end; |
|
|
|
} |
|
|
|
/* Compute the size of the stub (it is every thing up
|
|
|
|
to the beginning of the coff image) */ |
|
|
|
to the beginning of the coff image). */ |
|
|
|
coff_start = (long) _H (2) * 512L; |
|
|
|
if (_H (1)) |
|
|
|
coff_start += (long) _H (1) - 512L; |
|
|
|
|
|
|
|
/* Currently there is only a fixed stub size of 2048 bytes
|
|
|
|
supported */ |
|
|
|
supported. */ |
|
|
|
if (coff_start != 2048) |
|
|
|
{ |
|
|
|
close (f); |
|
|
|
@ -370,7 +359,7 @@ create_go32_stub (abfd) |
|
|
|
close (f); |
|
|
|
goto stub_end; |
|
|
|
} |
|
|
|
/* Now we found a correct stub (hopefully) */ |
|
|
|
/* Now we found a correct stub (hopefully). */ |
|
|
|
bfd_coff_go32stub (abfd) |
|
|
|
= (PTR) bfd_alloc (abfd, (bfd_size_type) coff_start); |
|
|
|
if (bfd_coff_go32stub (abfd) == NULL) |
|
|
|
@ -389,39 +378,35 @@ create_go32_stub (abfd) |
|
|
|
} |
|
|
|
stub_end: |
|
|
|
/* There was something wrong above, so use now the standard builtin
|
|
|
|
stub */ |
|
|
|
stub. */ |
|
|
|
if (bfd_coff_go32stub (abfd) == NULL) |
|
|
|
{ |
|
|
|
bfd_coff_go32stub (abfd) |
|
|
|
= (PTR) bfd_alloc (abfd, (bfd_size_type) STUBSIZE); |
|
|
|
if (bfd_coff_go32stub (abfd) == NULL) |
|
|
|
{ |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
return; |
|
|
|
memcpy (bfd_coff_go32stub (abfd), stub_bytes, STUBSIZE); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* If ibfd was a stubbed coff image, copy the stub from that bfd
|
|
|
|
to the new obfd. |
|
|
|
*/ |
|
|
|
to the new obfd. */ |
|
|
|
|
|
|
|
static boolean |
|
|
|
go32_stubbed_coff_bfd_copy_private_bfd_data (ibfd, obfd) |
|
|
|
bfd *ibfd; |
|
|
|
bfd *obfd; |
|
|
|
{ |
|
|
|
/* check if both are the same targets */ |
|
|
|
/* Check if both are the same targets. */ |
|
|
|
if (ibfd->xvec != obfd->xvec) |
|
|
|
return true; |
|
|
|
|
|
|
|
/* check if both have a valid stub */ |
|
|
|
/* Check if both have a valid stub. */ |
|
|
|
if (bfd_coff_go32stub (ibfd) == NULL |
|
|
|
|| bfd_coff_go32stub (obfd) == NULL) |
|
|
|
return true; |
|
|
|
|
|
|
|
/* Now copy the stub */ |
|
|
|
/* Now copy the stub. */ |
|
|
|
memcpy (bfd_coff_go32stub (obfd), bfd_coff_go32stub (ibfd), STUBSIZE); |
|
|
|
|
|
|
|
return true; |
|
|
|
|