Line 1... |
Line 1... |
/* BFD back-end for Intel 386 COFF files (DJGPP variant with a stub).
|
/* BFD back-end for Intel 386 COFF files (DJGPP variant with a stub).
|
Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2006, 2007
|
Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2005, 2006, 2007, 2009
|
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
Written by Robert Hoehne.
|
Written by Robert Hoehne.
|
|
|
This file is part of BFD, the Binary File Descriptor library.
|
This file is part of BFD, the Binary File Descriptor library.
|
|
|
Line 100... |
Line 100... |
|
|
#define coff_bfd_copy_private_bfd_data go32_stubbed_coff_bfd_copy_private_bfd_data
|
#define coff_bfd_copy_private_bfd_data go32_stubbed_coff_bfd_copy_private_bfd_data
|
|
|
#include "coff-i386.c"
|
#include "coff-i386.c"
|
|
|
/* 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
|
/* 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)))
|
#define _H(index) (H_GET_16 (abfd, (header+index*2)))
|
|
|
/* These bytes are a 2048-byte DOS executable, which loads the COFF
|
/* 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 const unsigned char stub_bytes[STUBSIZE] =
|
static const unsigned char stub_bytes[GO32_STUBSIZE] =
|
{
|
{
|
#include "go32stub.h"
|
#include "go32stub.h"
|
};
|
};
|
|
|
/*
|
/*
|
I have not commented each swap function below, because the
|
I have not commented each swap function below, because the
|
technique is in any function the same. For the ...in function,
|
technique is in any function the same. For the ...in function,
|
all the pointers are adjusted by adding STUBSIZE and for the
|
all the pointers are adjusted by adding GO32_STUBSIZE and for the
|
...out function, it is subtracted first and after calling 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
|
/* 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. */
|
Line 130... |
Line 127... |
#define ADJUST_VAL(val,diff) \
|
#define ADJUST_VAL(val,diff) \
|
if (val != 0) val += diff
|
if (val != 0) val += diff
|
|
|
static void
|
static void
|
adjust_filehdr_in_post (abfd, src, dst)
|
adjust_filehdr_in_post (abfd, src, dst)
|
bfd *abfd;
|
bfd *abfd ATTRIBUTE_UNUSED;
|
PTR src;
|
PTR src;
|
PTR dst;
|
PTR dst;
|
{
|
{
|
FILHDR *filehdr_src = (FILHDR *) src;
|
FILHDR *filehdr_src = (FILHDR *) src;
|
struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst;
|
struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst;
|
|
|
ADJUST_VAL (filehdr_dst->f_symptr, STUBSIZE);
|
ADJUST_VAL (filehdr_dst->f_symptr, GO32_STUBSIZE);
|
|
|
/* Save now the stub to be used later. */
|
/* Save now the stub to be used later. Put the stub data to FILEHDR_DST
|
bfd_coff_go32stub (abfd) = (PTR) bfd_alloc (abfd, (bfd_size_type) STUBSIZE);
|
first as coff_data (abfd) still does not exist. It may not even be ever
|
|
created as we are just checking the file format of ABFD. */
|
/* Since this function returns no status, I do not set here
|
memcpy (filehdr_dst->go32stub, filehdr_src->stub, GO32_STUBSIZE);
|
any bfd_error_...
|
filehdr_dst->f_flags |= F_GO32STUB;
|
That means, before the use of bfd_coff_go32stub (), this value
|
|
should be checked if it is != NULL. */
|
|
if (bfd_coff_go32stub (abfd) == NULL)
|
|
return;
|
|
memcpy (bfd_coff_go32stub (abfd), filehdr_src->stub, STUBSIZE);
|
|
}
|
}
|
|
|
static void
|
static void
|
adjust_filehdr_out_pre (abfd, in, out)
|
adjust_filehdr_out_pre (abfd, in, out)
|
bfd *abfd;
|
bfd *abfd;
|
Line 164... |
Line 156... |
|
|
/* Generate the stub. */
|
/* Generate the stub. */
|
create_go32_stub (abfd);
|
create_go32_stub (abfd);
|
|
|
/* Copy the stub to the file header. */
|
/* Copy the stub to the file header. */
|
if (bfd_coff_go32stub (abfd) != NULL)
|
if (coff_data (abfd)->go32stub != NULL)
|
memcpy (filehdr_out->stub, bfd_coff_go32stub (abfd), STUBSIZE);
|
memcpy (filehdr_out->stub, coff_data (abfd)->go32stub, GO32_STUBSIZE);
|
else
|
else
|
/* Use the default. */
|
/* Use the default. */
|
memcpy (filehdr_out->stub, stub_bytes, STUBSIZE);
|
memcpy (filehdr_out->stub, stub_bytes, GO32_STUBSIZE);
|
|
|
ADJUST_VAL (filehdr_in->f_symptr, -STUBSIZE);
|
ADJUST_VAL (filehdr_in->f_symptr, -GO32_STUBSIZE);
|
}
|
}
|
|
|
static void
|
static void
|
adjust_filehdr_out_post (abfd, in, out)
|
adjust_filehdr_out_post (abfd, in, out)
|
bfd *abfd ATTRIBUTE_UNUSED;
|
bfd *abfd ATTRIBUTE_UNUSED;
|
PTR in;
|
PTR in;
|
PTR out ATTRIBUTE_UNUSED;
|
PTR out ATTRIBUTE_UNUSED;
|
{
|
{
|
struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in;
|
struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in;
|
/* Undo the above change. */
|
/* Undo the above change. */
|
ADJUST_VAL (filehdr_in->f_symptr, STUBSIZE);
|
ADJUST_VAL (filehdr_in->f_symptr, GO32_STUBSIZE);
|
}
|
}
|
|
|
static void
|
static void
|
adjust_scnhdr_in_post (abfd, ext, in)
|
adjust_scnhdr_in_post (abfd, ext, in)
|
bfd *abfd ATTRIBUTE_UNUSED;
|
bfd *abfd ATTRIBUTE_UNUSED;
|
PTR ext ATTRIBUTE_UNUSED;
|
PTR ext ATTRIBUTE_UNUSED;
|
PTR in;
|
PTR in;
|
{
|
{
|
struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
|
struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
|
|
|
ADJUST_VAL (scnhdr_int->s_scnptr, STUBSIZE);
|
ADJUST_VAL (scnhdr_int->s_scnptr, GO32_STUBSIZE);
|
ADJUST_VAL (scnhdr_int->s_relptr, STUBSIZE);
|
ADJUST_VAL (scnhdr_int->s_relptr, GO32_STUBSIZE);
|
ADJUST_VAL (scnhdr_int->s_lnnoptr, STUBSIZE);
|
ADJUST_VAL (scnhdr_int->s_lnnoptr, GO32_STUBSIZE);
|
}
|
}
|
|
|
static void
|
static void
|
adjust_scnhdr_out_pre (abfd, in, out)
|
adjust_scnhdr_out_pre (abfd, in, out)
|
bfd *abfd ATTRIBUTE_UNUSED;
|
bfd *abfd ATTRIBUTE_UNUSED;
|
PTR in;
|
PTR in;
|
PTR out ATTRIBUTE_UNUSED;
|
PTR out ATTRIBUTE_UNUSED;
|
{
|
{
|
struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
|
struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
|
|
|
ADJUST_VAL (scnhdr_int->s_scnptr, -STUBSIZE);
|
ADJUST_VAL (scnhdr_int->s_scnptr, -GO32_STUBSIZE);
|
ADJUST_VAL (scnhdr_int->s_relptr, -STUBSIZE);
|
ADJUST_VAL (scnhdr_int->s_relptr, -GO32_STUBSIZE);
|
ADJUST_VAL (scnhdr_int->s_lnnoptr, -STUBSIZE);
|
ADJUST_VAL (scnhdr_int->s_lnnoptr, -GO32_STUBSIZE);
|
}
|
}
|
|
|
static void
|
static void
|
adjust_scnhdr_out_post (abfd, in, out)
|
adjust_scnhdr_out_post (abfd, in, out)
|
bfd *abfd ATTRIBUTE_UNUSED;
|
bfd *abfd ATTRIBUTE_UNUSED;
|
PTR in;
|
PTR in;
|
PTR out ATTRIBUTE_UNUSED;
|
PTR out ATTRIBUTE_UNUSED;
|
{
|
{
|
struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
|
struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
|
|
|
ADJUST_VAL (scnhdr_int->s_scnptr, STUBSIZE);
|
ADJUST_VAL (scnhdr_int->s_scnptr, GO32_STUBSIZE);
|
ADJUST_VAL (scnhdr_int->s_relptr, STUBSIZE);
|
ADJUST_VAL (scnhdr_int->s_relptr, GO32_STUBSIZE);
|
ADJUST_VAL (scnhdr_int->s_lnnoptr, STUBSIZE);
|
ADJUST_VAL (scnhdr_int->s_lnnoptr, GO32_STUBSIZE);
|
}
|
}
|
|
|
static void
|
static void
|
adjust_aux_in_post (abfd, ext1, type, class, indx, numaux, in1)
|
adjust_aux_in_post (abfd, ext1, type, in_class, indx, numaux, in1)
|
bfd *abfd ATTRIBUTE_UNUSED;
|
bfd *abfd ATTRIBUTE_UNUSED;
|
PTR ext1 ATTRIBUTE_UNUSED;
|
PTR ext1 ATTRIBUTE_UNUSED;
|
int type;
|
int type;
|
int class;
|
int in_class;
|
int indx ATTRIBUTE_UNUSED;
|
int indx ATTRIBUTE_UNUSED;
|
int numaux ATTRIBUTE_UNUSED;
|
int numaux ATTRIBUTE_UNUSED;
|
PTR in1;
|
PTR in1;
|
{
|
{
|
union internal_auxent *in = (union internal_auxent *) in1;
|
union internal_auxent *in = (union internal_auxent *) in1;
|
|
|
if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
|
if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
|
|
|| ISTAG (in_class))
|
{
|
{
|
ADJUST_VAL (in->x_sym.x_fcnary.x_fcn.x_lnnoptr, STUBSIZE);
|
ADJUST_VAL (in->x_sym.x_fcnary.x_fcn.x_lnnoptr, GO32_STUBSIZE);
|
}
|
}
|
}
|
}
|
|
|
static void
|
static void
|
adjust_aux_out_pre (abfd, inp, type, class, indx, numaux, extp)
|
adjust_aux_out_pre (abfd, inp, type, in_class, indx, numaux, extp)
|
bfd *abfd ATTRIBUTE_UNUSED;
|
bfd *abfd ATTRIBUTE_UNUSED;
|
PTR inp;
|
PTR inp;
|
int type;
|
int type;
|
int class;
|
int in_class;
|
int indx ATTRIBUTE_UNUSED;
|
int indx ATTRIBUTE_UNUSED;
|
int numaux ATTRIBUTE_UNUSED;
|
int numaux ATTRIBUTE_UNUSED;
|
PTR extp ATTRIBUTE_UNUSED;
|
PTR extp ATTRIBUTE_UNUSED;
|
{
|
{
|
union internal_auxent *in = (union internal_auxent *) inp;
|
union internal_auxent *in = (union internal_auxent *) inp;
|
|
|
if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
|
if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
|
|
|| ISTAG (in_class))
|
{
|
{
|
ADJUST_VAL (in->x_sym.x_fcnary.x_fcn.x_lnnoptr, -STUBSIZE);
|
ADJUST_VAL (in->x_sym.x_fcnary.x_fcn.x_lnnoptr, -GO32_STUBSIZE);
|
}
|
}
|
}
|
}
|
|
|
static void
|
static void
|
adjust_aux_out_post (abfd, inp, type, class, indx, numaux, extp)
|
adjust_aux_out_post (abfd, inp, type, in_class, indx, numaux, extp)
|
bfd *abfd ATTRIBUTE_UNUSED;
|
bfd *abfd ATTRIBUTE_UNUSED;
|
PTR inp;
|
PTR inp;
|
int type;
|
int type;
|
int class;
|
int in_class;
|
int indx ATTRIBUTE_UNUSED;
|
int indx ATTRIBUTE_UNUSED;
|
int numaux ATTRIBUTE_UNUSED;
|
int numaux ATTRIBUTE_UNUSED;
|
PTR extp ATTRIBUTE_UNUSED;
|
PTR extp ATTRIBUTE_UNUSED;
|
{
|
{
|
union internal_auxent *in = (union internal_auxent *) inp;
|
union internal_auxent *in = (union internal_auxent *) inp;
|
|
|
if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
|
if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
|
|
|| ISTAG (in_class))
|
{
|
{
|
ADJUST_VAL (in->x_sym.x_fcnary.x_fcn.x_lnnoptr, STUBSIZE);
|
ADJUST_VAL (in->x_sym.x_fcnary.x_fcn.x_lnnoptr, GO32_STUBSIZE);
|
}
|
}
|
}
|
}
|
|
|
/* 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.
|
different cases from where the stub is taken.
|
Line 294... |
Line 289... |
static void
|
static void
|
create_go32_stub (abfd)
|
create_go32_stub (abfd)
|
bfd *abfd;
|
bfd *abfd;
|
{
|
{
|
/* Do it only once. */
|
/* Do it only once. */
|
if (bfd_coff_go32stub (abfd) == NULL)
|
if (coff_data (abfd)->go32stub == NULL)
|
{
|
{
|
char *stub;
|
char *stub;
|
struct stat st;
|
struct stat st;
|
int f;
|
int f;
|
unsigned char header[10];
|
unsigned char header[10];
|
Line 360... |
Line 355... |
{
|
{
|
close (f);
|
close (f);
|
goto stub_end;
|
goto stub_end;
|
}
|
}
|
/* Now we found a correct stub (hopefully). */
|
/* Now we found a correct stub (hopefully). */
|
bfd_coff_go32stub (abfd)
|
coff_data (abfd)->go32stub = bfd_alloc (abfd, (bfd_size_type) coff_start);
|
= (PTR) bfd_alloc (abfd, (bfd_size_type) coff_start);
|
if (coff_data (abfd)->go32stub == NULL)
|
if (bfd_coff_go32stub (abfd) == NULL)
|
|
{
|
{
|
close (f);
|
close (f);
|
return;
|
return;
|
}
|
}
|
lseek (f, 0L, SEEK_SET);
|
lseek (f, 0L, SEEK_SET);
|
if ((unsigned long) read (f, bfd_coff_go32stub (abfd), coff_start)
|
if ((unsigned long) read (f, coff_data (abfd)->go32stub, coff_start)
|
!= coff_start)
|
!= coff_start)
|
{
|
{
|
bfd_release (abfd, bfd_coff_go32stub (abfd));
|
bfd_release (abfd, coff_data (abfd)->go32stub);
|
bfd_coff_go32stub (abfd) = NULL;
|
coff_data (abfd)->go32stub = NULL;
|
}
|
}
|
close (f);
|
close (f);
|
}
|
}
|
stub_end:
|
stub_end:
|
/* There was something wrong above, so use now the standard builtin
|
/* There was something wrong above, so use now the standard builtin
|
stub. */
|
stub. */
|
if (bfd_coff_go32stub (abfd) == NULL)
|
if (coff_data (abfd)->go32stub == NULL)
|
{
|
{
|
bfd_coff_go32stub (abfd)
|
coff_data (abfd)->go32stub
|
= (PTR) bfd_alloc (abfd, (bfd_size_type) STUBSIZE);
|
= bfd_alloc (abfd, (bfd_size_type) GO32_STUBSIZE);
|
if (bfd_coff_go32stub (abfd) == NULL)
|
if (coff_data (abfd)->go32stub == NULL)
|
return;
|
return;
|
memcpy (bfd_coff_go32stub (abfd), stub_bytes, STUBSIZE);
|
memcpy (coff_data (abfd)->go32stub, stub_bytes, GO32_STUBSIZE);
|
}
|
}
|
}
|
}
|
|
|
/* If ibfd was a stubbed coff image, copy the stub from that bfd
|
/* If ibfd was a stubbed coff image, copy the stub from that bfd
|
to the new obfd. */
|
to the new obfd. */
|
Line 401... |
Line 395... |
{
|
{
|
/* Check if both are the same targets. */
|
/* Check if both are the same targets. */
|
if (ibfd->xvec != obfd->xvec)
|
if (ibfd->xvec != obfd->xvec)
|
return TRUE;
|
return TRUE;
|
|
|
/* Check if both have a valid stub. */
|
/* Check if we have a source stub. */
|
if (bfd_coff_go32stub (ibfd) == NULL
|
if (coff_data (ibfd)->go32stub == NULL)
|
|| bfd_coff_go32stub (obfd) == NULL)
|
|
return TRUE;
|
return TRUE;
|
|
|
|
/* As adjust_filehdr_out_pre may get called only after this function,
|
|
optionally allocate the output stub. */
|
|
if (coff_data (obfd)->go32stub == NULL)
|
|
coff_data (obfd)->go32stub = bfd_alloc (obfd,
|
|
(bfd_size_type) GO32_STUBSIZE);
|
|
|
/* Now copy the stub. */
|
/* Now copy the stub. */
|
memcpy (bfd_coff_go32stub (obfd), bfd_coff_go32stub (ibfd), STUBSIZE);
|
if (coff_data (obfd)->go32stub != NULL)
|
|
memcpy (coff_data (obfd)->go32stub, coff_data (ibfd)->go32stub,
|
|
GO32_STUBSIZE);
|
|
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
No newline at end of file
|
No newline at end of file
|