#define TARGET_SYM go32stubbedcoff_vec
#define TARGET_NAME "coff-go32-exe"
#define TARGET_UNDERSCORE '_'
#define COFF_GO32_EXE
#define COFF_LONG_SECTION_NAMES
#define COFF_SUPPORT_GNU_LINKONCE
#define COFF_LONG_FILENAMES
#define COFF_SECTION_ALIGNMENT_ENTRIES \
{ COFF_SECTION_NAME_EXACT_MATCH (".data"), \
COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
{ COFF_SECTION_NAME_EXACT_MATCH (".text"), \
COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
{ COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \
COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }, \
{ COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.wi"), \
COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }
#include "bfd.h"
static void
adjust_filehdr_in_post PARAMS ((bfd *, PTR, PTR));
static void
adjust_filehdr_out_pre PARAMS ((bfd *, PTR, PTR));
static void
adjust_filehdr_out_post PARAMS ((bfd *, PTR, PTR));
static void
adjust_scnhdr_in_post PARAMS ((bfd *, PTR, PTR));
static void
adjust_scnhdr_out_pre PARAMS ((bfd *, PTR, PTR));
static void
adjust_scnhdr_out_post PARAMS ((bfd *, PTR, PTR));
static void
adjust_aux_in_post PARAMS ((bfd *, PTR, int, int, int, int, PTR));
static void
adjust_aux_out_pre PARAMS ((bfd *, PTR, int, int, int, int, PTR));
static void
adjust_aux_out_post PARAMS ((bfd *, PTR, int, int, int, int, PTR));
static void
create_go32_stub PARAMS ((bfd *));
#define COFF_ADJUST_FILEHDR_IN_POST adjust_filehdr_in_post
#define COFF_ADJUST_FILEHDR_OUT_PRE adjust_filehdr_out_pre
#define COFF_ADJUST_FILEHDR_OUT_POST adjust_filehdr_out_post
#define COFF_ADJUST_SCNHDR_IN_POST adjust_scnhdr_in_post
#define COFF_ADJUST_SCNHDR_OUT_PRE adjust_scnhdr_out_pre
#define COFF_ADJUST_SCNHDR_OUT_POST adjust_scnhdr_out_post
#define COFF_ADJUST_AUX_IN_POST adjust_aux_in_post
#define COFF_ADJUST_AUX_OUT_PRE adjust_aux_out_pre
#define COFF_ADJUST_AUX_OUT_POST adjust_aux_out_post
static bfd_boolean
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"
#define bfd_coff_go32stub bfd_usrdata
#define _H(index) (H_GET_16 (abfd, (header+index*2)))
static const unsigned char stub_bytes[STUBSIZE] =
{
#include "go32stub.h"
};
#define ADJUST_VAL(val,diff) \
if (val != 0) val += diff
static void
adjust_filehdr_in_post (abfd, src, dst)
bfd *abfd;
PTR src;
PTR dst;
{
FILHDR *filehdr_src = (FILHDR *) src;
struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst;
ADJUST_VAL (filehdr_dst->f_symptr, STUBSIZE);
bfd_coff_go32stub (abfd) = (PTR) bfd_alloc (abfd, (bfd_size_type) STUBSIZE);
if (bfd_coff_go32stub (abfd) == NULL)
return;
memcpy (bfd_coff_go32stub (abfd), filehdr_src->stub, STUBSIZE);
}
static void
adjust_filehdr_out_pre (abfd, in, out)
bfd *abfd;
PTR in;
PTR out;
{
struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in;
FILHDR *filehdr_out = (FILHDR *) out;
create_go32_stub (abfd);
if (bfd_coff_go32stub (abfd) != NULL)
memcpy (filehdr_out->stub, bfd_coff_go32stub (abfd), STUBSIZE);
else
memcpy (filehdr_out->stub, stub_bytes, STUBSIZE);
ADJUST_VAL (filehdr_in->f_symptr, -STUBSIZE);
}
static void
adjust_filehdr_out_post (abfd, in, out)
bfd *abfd ATTRIBUTE_UNUSED;
PTR in;
PTR out ATTRIBUTE_UNUSED;
{
struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in;
ADJUST_VAL (filehdr_in->f_symptr, STUBSIZE);
}
static void
adjust_scnhdr_in_post (abfd, ext, in)
bfd *abfd ATTRIBUTE_UNUSED;
PTR ext ATTRIBUTE_UNUSED;
PTR in;
{
struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
ADJUST_VAL (scnhdr_int->s_scnptr, STUBSIZE);
ADJUST_VAL (scnhdr_int->s_relptr, STUBSIZE);
ADJUST_VAL (scnhdr_int->s_lnnoptr, STUBSIZE);
}
static void
adjust_scnhdr_out_pre (abfd, in, out)
bfd *abfd ATTRIBUTE_UNUSED;
PTR in;
PTR out ATTRIBUTE_UNUSED;
{
struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
ADJUST_VAL (scnhdr_int->s_scnptr, -STUBSIZE);
ADJUST_VAL (scnhdr_int->s_relptr, -STUBSIZE);
ADJUST_VAL (scnhdr_int->s_lnnoptr, -STUBSIZE);
}
static void
adjust_scnhdr_out_post (abfd, in, out)
bfd *abfd ATTRIBUTE_UNUSED;
PTR in;
PTR out ATTRIBUTE_UNUSED;
{
struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
ADJUST_VAL (scnhdr_int->s_scnptr, STUBSIZE);
ADJUST_VAL (scnhdr_int->s_relptr, STUBSIZE);
ADJUST_VAL (scnhdr_int->s_lnnoptr, STUBSIZE);
}
static void
adjust_aux_in_post (abfd, ext1, type, class, indx, numaux, in1)
bfd *abfd ATTRIBUTE_UNUSED;
PTR ext1 ATTRIBUTE_UNUSED;
int type;
int class;
int indx ATTRIBUTE_UNUSED;
int numaux ATTRIBUTE_UNUSED;
PTR in1;
{
union internal_auxent *in = (union internal_auxent *) in1;
if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
{
ADJUST_VAL (in->x_sym.x_fcnary.x_fcn.x_lnnoptr, STUBSIZE);
}
}
static void
adjust_aux_out_pre (abfd, inp, type, class, indx, numaux, extp)
bfd *abfd ATTRIBUTE_UNUSED;
PTR inp;
int type;
int class;
int indx ATTRIBUTE_UNUSED;
int numaux ATTRIBUTE_UNUSED;
PTR extp ATTRIBUTE_UNUSED;
{
union internal_auxent *in = (union internal_auxent *) inp;
if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
{
ADJUST_VAL (in->x_sym.x_fcnary.x_fcn.x_lnnoptr, -STUBSIZE);
}
}
static void
adjust_aux_out_post (abfd, inp, type, class, indx, numaux, extp)
bfd *abfd ATTRIBUTE_UNUSED;
PTR inp;
int type;
int class;
int indx ATTRIBUTE_UNUSED;
int numaux ATTRIBUTE_UNUSED;
PTR extp ATTRIBUTE_UNUSED;
{
union internal_auxent *in = (union internal_auxent *) inp;
if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
{
ADJUST_VAL (in->x_sym.x_fcnary.x_fcn.x_lnnoptr, STUBSIZE);
}
}
static void
create_go32_stub (abfd)
bfd *abfd;
{
if (bfd_coff_go32stub (abfd) == NULL)
{
char *stub;
struct stat st;
int f;
unsigned char header[10];
char magic[8];
unsigned long coff_start;
long exe_start;
stub = getenv ("GO32STUB");
if (stub == NULL)
stub = getenv ("STUB");
if (stub == NULL)
goto stub_end;
if (stat (stub, &st) != 0)
goto stub_end;
#ifdef O_BINARY
f = open (stub, O_RDONLY | O_BINARY);
#else
f = open (stub, O_RDONLY);
#endif
if (f < 0)
goto stub_end;
if (read (f, &header, sizeof (header)) < 0)
{
close (f);
goto stub_end;
}
if (_H (0) != 0x5a4d)
{
close (f);
goto stub_end;
}
coff_start = (long) _H (2) * 512L;
if (_H (1))
coff_start += (long) _H (1) - 512L;
if (coff_start != 2048)
{
close (f);
goto stub_end;
}
exe_start = _H (4) * 16;
if ((long) lseek (f, exe_start, SEEK_SET) != exe_start)
{
close (f);
goto stub_end;
}
if (read (f, &magic, 8) != 8)
{
close (f);
goto stub_end;
}
if (memcmp (magic, "go32stub", 8) != 0)
{
close (f);
goto stub_end;
}
bfd_coff_go32stub (abfd)
= (PTR) bfd_alloc (abfd, (bfd_size_type) coff_start);
if (bfd_coff_go32stub (abfd) == NULL)
{
close (f);
return;
}
lseek (f, 0L, SEEK_SET);
if ((unsigned long) read (f, bfd_coff_go32stub (abfd), coff_start)
!= coff_start)
{
bfd_release (abfd, bfd_coff_go32stub (abfd));
bfd_coff_go32stub (abfd) = NULL;
}
close (f);
}
stub_end:
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;
memcpy (bfd_coff_go32stub (abfd), stub_bytes, STUBSIZE);
}
}
static bfd_boolean
go32_stubbed_coff_bfd_copy_private_bfd_data (ibfd, obfd)
bfd *ibfd;
bfd *obfd;
{
if (ibfd->xvec != obfd->xvec)
return TRUE;
if (bfd_coff_go32stub (ibfd) == NULL
|| bfd_coff_go32stub (obfd) == NULL)
return TRUE;
memcpy (bfd_coff_go32stub (obfd), bfd_coff_go32stub (ibfd), STUBSIZE);
return TRUE;
}