aboutsummaryrefslogtreecommitdiff
path: root/bfd/coffswap.h
diff options
context:
space:
mode:
Diffstat (limited to 'bfd/coffswap.h')
-rw-r--r--bfd/coffswap.h507
1 files changed, 358 insertions, 149 deletions
diff --git a/bfd/coffswap.h b/bfd/coffswap.h
index 3e15ddc..4b35942 100644
--- a/bfd/coffswap.h
+++ b/bfd/coffswap.h
@@ -1,5 +1,5 @@
/* Generic COFF swapping routines, for BFD.
- Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
+ Copyright 1990, 1991, 1992, 1993, 1995 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
@@ -16,7 +16,7 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* This file contains routines used to swap COFF data. It is a header
file because the details of swapping depend on the details of the
@@ -26,6 +26,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
Any file which uses this must first include "coff/internal.h" and
"coff/CPU.h". The functions will then be correct for that CPU. */
+#ifndef IMAGE_BASE
+#define IMAGE_BASE 0
+#endif
+
#define PUTWORD bfd_h_put_32
#define PUTHALF bfd_h_put_16
#define PUTBYTE bfd_h_put_8
@@ -168,11 +172,14 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef NO_COFF_RELOCS
static void
-DEFUN(bfd_swap_reloc_in,(abfd, reloc_src, reloc_dst),
- bfd *abfd AND
- RELOC *reloc_src AND
- struct internal_reloc *reloc_dst)
+coff_swap_reloc_in (abfd, src, dst)
+ bfd *abfd;
+ PTR src;
+ PTR dst;
{
+ RELOC *reloc_src = (RELOC *) src;
+ struct internal_reloc *reloc_dst = (struct internal_reloc *) dst;
+
reloc_dst->r_vaddr = bfd_h_get_32(abfd, (bfd_byte *)reloc_src->r_vaddr);
reloc_dst->r_symndx = bfd_h_get_signed_32(abfd, (bfd_byte *) reloc_src->r_symndx);
@@ -191,17 +198,23 @@ DEFUN(bfd_swap_reloc_in,(abfd, reloc_src, reloc_dst),
static unsigned int
-DEFUN(coff_swap_reloc_out,(abfd, src, dst),
- bfd *abfd AND
- PTR src AND
- PTR dst)
+coff_swap_reloc_out (abfd, src, dst)
+ bfd *abfd;
+ PTR src;
+ PTR dst;
{
struct internal_reloc *reloc_src = (struct internal_reloc *)src;
struct external_reloc *reloc_dst = (struct external_reloc *)dst;
bfd_h_put_32(abfd, reloc_src->r_vaddr, (bfd_byte *) reloc_dst->r_vaddr);
bfd_h_put_32(abfd, reloc_src->r_symndx, (bfd_byte *) reloc_dst->r_symndx);
+
+#ifdef RS6000COFF_C
+ bfd_h_put_8 (abfd, reloc_src->r_type, (bfd_byte *) reloc_dst->r_type);
+ bfd_h_put_8 (abfd, reloc_src->r_size, (bfd_byte *) reloc_dst->r_size);
+#else
bfd_h_put_16(abfd, reloc_src->r_type, (bfd_byte *)
reloc_dst->r_type);
+#endif
#ifdef SWAP_OUT_RELOC_OFFSET
SWAP_OUT_RELOC_OFFSET(abfd,
@@ -218,10 +231,10 @@ DEFUN(coff_swap_reloc_out,(abfd, src, dst),
#endif /* NO_COFF_RELOCS */
static void
-DEFUN(coff_swap_filehdr_in,(abfd, src, dst),
- bfd *abfd AND
- PTR src AND
- PTR dst)
+coff_swap_filehdr_in (abfd, src, dst)
+ bfd *abfd;
+ PTR src;
+ PTR dst;
{
FILHDR *filehdr_src = (FILHDR *) src;
struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst;
@@ -236,13 +249,14 @@ DEFUN(coff_swap_filehdr_in,(abfd, src, dst),
}
static unsigned int
-DEFUN(coff_swap_filehdr_out,(abfd, in, out),
- bfd *abfd AND
- PTR in AND
- PTR out)
+coff_swap_filehdr_out (abfd, in, out)
+ bfd *abfd;
+ PTR in;
+ PTR out;
{
struct internal_filehdr *filehdr_in = (struct internal_filehdr *)in;
FILHDR *filehdr_out = (FILHDR *)out;
+
bfd_h_put_16(abfd, filehdr_in->f_magic, (bfd_byte *) filehdr_out->f_magic);
bfd_h_put_16(abfd, filehdr_in->f_nscns, (bfd_byte *) filehdr_out->f_nscns);
bfd_h_put_32(abfd, filehdr_in->f_timdat, (bfd_byte *) filehdr_out->f_timdat);
@@ -251,6 +265,61 @@ DEFUN(coff_swap_filehdr_out,(abfd, in, out),
bfd_h_put_32(abfd, filehdr_in->f_nsyms, (bfd_byte *) filehdr_out->f_nsyms);
bfd_h_put_16(abfd, filehdr_in->f_opthdr, (bfd_byte *) filehdr_out->f_opthdr);
bfd_h_put_16(abfd, filehdr_in->f_flags, (bfd_byte *) filehdr_out->f_flags);
+
+#ifdef COFF_IMAGE_WITH_PE
+ /* put in extra dos header stuff. This data remains essentially
+ constant, it just has to be tacked on to the beginning of all exes
+ for NT */
+ bfd_h_put_16(abfd, filehdr_in->pe->e_magic, (bfd_byte *) filehdr_out->e_magic);
+ bfd_h_put_16(abfd, filehdr_in->pe->e_cblp, (bfd_byte *) filehdr_out->e_cblp);
+ bfd_h_put_16(abfd, filehdr_in->pe->e_cp, (bfd_byte *) filehdr_out->e_cp);
+ bfd_h_put_16(abfd, filehdr_in->pe->e_crlc, (bfd_byte *) filehdr_out->e_crlc);
+ bfd_h_put_16(abfd, filehdr_in->pe->e_cparhdr,
+ (bfd_byte *) filehdr_out->e_cparhdr);
+ bfd_h_put_16(abfd, filehdr_in->pe->e_minalloc,
+ (bfd_byte *) filehdr_out->e_minalloc);
+ bfd_h_put_16(abfd, filehdr_in->pe->e_maxalloc,
+ (bfd_byte *) filehdr_out->e_maxalloc);
+ bfd_h_put_16(abfd, filehdr_in->pe->e_ss, (bfd_byte *) filehdr_out->e_ss);
+ bfd_h_put_16(abfd, filehdr_in->pe->e_sp, (bfd_byte *) filehdr_out->e_sp);
+ bfd_h_put_16(abfd, filehdr_in->pe->e_csum, (bfd_byte *) filehdr_out->e_csum);
+ bfd_h_put_16(abfd, filehdr_in->pe->e_ip, (bfd_byte *) filehdr_out->e_ip);
+ bfd_h_put_16(abfd, filehdr_in->pe->e_cs, (bfd_byte *) filehdr_out->e_cs);
+ bfd_h_put_16(abfd, filehdr_in->pe->e_lfarlc, (bfd_byte *) filehdr_out->e_lfarlc);
+ bfd_h_put_16(abfd, filehdr_in->pe->e_ovno, (bfd_byte *) filehdr_out->e_ovno);
+ {
+ int idx;
+ for (idx=0; idx < 4; idx++)
+ bfd_h_put_16(abfd, filehdr_in->pe->e_res[idx],
+ (bfd_byte *) filehdr_out->e_res[idx]);
+ }
+ bfd_h_put_16(abfd, filehdr_in->pe->e_oemid, (bfd_byte *) filehdr_out->e_oemid);
+ bfd_h_put_16(abfd, filehdr_in->pe->e_oeminfo,
+ (bfd_byte *) filehdr_out->e_oeminfo);
+ {
+ int idx;
+ for (idx=0; idx < 10; idx++)
+ bfd_h_put_16(abfd, filehdr_in->pe->e_res2[idx],
+ (bfd_byte *) filehdr_out->e_res2[idx]);
+ }
+ bfd_h_put_32(abfd, filehdr_in->pe->e_lfanew, (bfd_byte *) filehdr_out->e_lfanew);
+
+ {
+ int idx;
+ for (idx=0; idx < 16; idx++)
+ bfd_h_put_32(abfd, filehdr_in->pe->dos_message[idx],
+ (bfd_byte *) filehdr_out->dos_message[idx]);
+ }
+
+ /* also put in the NT signature */
+ bfd_h_put_32(abfd, filehdr_in->pe->nt_signature,
+ (bfd_byte *) filehdr_out->nt_signature);
+
+
+#endif
+
+
+
return sizeof(FILHDR);
}
@@ -258,10 +327,10 @@ DEFUN(coff_swap_filehdr_out,(abfd, in, out),
#ifndef NO_COFF_SYMBOLS
static void
-DEFUN(coff_swap_sym_in,(abfd, ext1, in1),
- bfd *abfd AND
- PTR ext1 AND
- PTR in1)
+coff_swap_sym_in (abfd, ext1, in1)
+ bfd *abfd;
+ PTR ext1;
+ PTR in1;
{
SYMENT *ext = (SYMENT *)ext1;
struct internal_syment *in = (struct internal_syment *)in1;
@@ -277,7 +346,7 @@ DEFUN(coff_swap_sym_in,(abfd, ext1, in1),
memcpy(in->_n._n_name, ext->e.e_name, SYMNMLEN);
#endif
}
- in->n_value = bfd_h_get_32(abfd, (bfd_byte *) ext->e_value);
+ in->n_value = bfd_h_get_32(abfd, (bfd_byte *) ext->e_value);
in->n_scnum = bfd_h_get_16(abfd, (bfd_byte *) ext->e_scnum);
if (sizeof(ext->e_type) == 2){
in->n_type = bfd_h_get_16(abfd, (bfd_byte *) ext->e_type);
@@ -287,13 +356,34 @@ DEFUN(coff_swap_sym_in,(abfd, ext1, in1),
}
in->n_sclass = bfd_h_get_8(abfd, ext->e_sclass);
in->n_numaux = bfd_h_get_8(abfd, ext->e_numaux);
+
+#ifdef COFF_WITH_PE
+ /* The section symbols for the .idata$ sections have class 68, which MS
+ documentation indicates is a section symbol. The problem is that the
+ value field in the symbol is simply a copy of the .idata section's flags
+ rather than something useful. When these symbols are encountered, change
+ the value to 0 and the section number to 1 so that they will be handled
+ somewhat correctly in the bfd code. */
+ if (in->n_sclass == 0x68) {
+ in->n_value = 0x0;
+ in->n_scnum = 1;
+ /* I have tried setting the class to 3 and using the following to set
+ the section number. This will put the address of the pointer to the
+ string kernel32.dll at addresses 0 and 0x10 off start of idata section
+ which is not correct */
+/* if (strcmp (in->_n._n_name, ".idata$4") == 0) */
+/* in->n_scnum = 3; */
+/* else */
+/* in->n_scnum = 2; */
+ }
+#endif
}
static unsigned int
-DEFUN(coff_swap_sym_out,(abfd, inp, extp),
- bfd *abfd AND
- PTR inp AND
- PTR extp)
+coff_swap_sym_out (abfd, inp, extp)
+ bfd *abfd;
+ PTR inp;
+ PTR extp;
{
struct internal_syment *in = (struct internal_syment *)inp;
SYMENT *ext =(SYMENT *)extp;
@@ -324,14 +414,14 @@ DEFUN(coff_swap_sym_out,(abfd, inp, extp),
}
static void
-DEFUN(coff_swap_aux_in,(abfd, ext1, type, class, indx, numaux, in1),
- bfd *abfd AND
- PTR ext1 AND
- int type AND
- int class AND
- int indx AND
- int numaux AND
- PTR in1)
+coff_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1)
+ bfd *abfd;
+ PTR ext1;
+ int type;
+ int class;
+ int indx;
+ int numaux;
+ PTR in1;
{
AUXENT *ext = (AUXENT *)ext1;
union internal_auxent *in = (union internal_auxent *)in1;
@@ -357,7 +447,7 @@ DEFUN(coff_swap_aux_in,(abfd, ext1, type, class, indx, numaux, in1),
case C_HIDEXT:
if (indx + 1 == numaux)
{
- in->x_csect.x_scnlen = bfd_h_get_32 (abfd, ext->x_csect.x_scnlen);
+ in->x_csect.x_scnlen.l = bfd_h_get_32 (abfd, ext->x_csect.x_scnlen);
in->x_csect.x_parmhash = bfd_h_get_32 (abfd,
ext->x_csect.x_parmhash);
in->x_csect.x_snhash = bfd_h_get_16 (abfd, ext->x_csect.x_snhash);
@@ -392,20 +482,25 @@ DEFUN(coff_swap_aux_in,(abfd, ext1, type, class, indx, numaux, in1),
in->x_sym.x_tvndx = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_tvndx);
#endif
- if (ISARY(type)) {
+ if (class == C_BLOCK || ISFCN (type) || ISTAG (class))
+ {
+ in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR (abfd, ext);
+ in->x_sym.x_fcnary.x_fcn.x_endndx.l = GET_FCN_ENDNDX (abfd, ext);
+ }
+ else
+ {
#if DIMNUM != E_DIMNUM
- -> Error, we need to cope with truncating or extending DIMNUM!;
-#else
- in->x_sym.x_fcnary.x_ary.x_dimen[0] = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
- in->x_sym.x_fcnary.x_ary.x_dimen[1] = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
- in->x_sym.x_fcnary.x_ary.x_dimen[2] = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
- in->x_sym.x_fcnary.x_ary.x_dimen[3] = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
-#endif
- }
- if (class == C_BLOCK || ISFCN(type) || ISTAG(class)) {
- in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR(abfd, ext);
- in->x_sym.x_fcnary.x_fcn.x_endndx.l = GET_FCN_ENDNDX(abfd, ext);
- }
+ #error we need to cope with truncating or extending DIMNUM
+#endif
+ in->x_sym.x_fcnary.x_ary.x_dimen[0] =
+ bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
+ in->x_sym.x_fcnary.x_ary.x_dimen[1] =
+ bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
+ in->x_sym.x_fcnary.x_ary.x_dimen[2] =
+ bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
+ in->x_sym.x_fcnary.x_ary.x_dimen[3] =
+ bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
+ }
if (ISFCN(type)) {
in->x_sym.x_misc.x_fsize = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_misc.x_fsize);
@@ -417,14 +512,14 @@ DEFUN(coff_swap_aux_in,(abfd, ext1, type, class, indx, numaux, in1),
}
static unsigned int
-DEFUN(coff_swap_aux_out,(abfd, inp, type, class, indx, numaux, extp),
- bfd *abfd AND
- PTR inp AND
- int type AND
- int class AND
- int indx AND
- int numaux AND
- PTR extp)
+coff_swap_aux_out (abfd, inp, type, class, indx, numaux, extp)
+ bfd *abfd;
+ PTR inp;
+ int type;
+ int class;
+ int indx;
+ int numaux;
+ PTR extp;
{
union internal_auxent *in = (union internal_auxent *)inp;
AUXENT *ext = (AUXENT *)extp;
@@ -453,7 +548,7 @@ DEFUN(coff_swap_aux_out,(abfd, inp, type, class, indx, numaux, extp),
case C_HIDEXT:
if (indx + 1 == numaux)
{
- PUTWORD (abfd, in->x_csect.x_scnlen, ext->x_csect.x_scnlen);
+ PUTWORD (abfd, in->x_csect.x_scnlen.l, ext->x_csect.x_scnlen);
PUTWORD (abfd, in->x_csect.x_parmhash, ext->x_csect.x_parmhash);
PUTHALF (abfd, in->x_csect.x_snhash, ext->x_csect.x_snhash);
/* We don't have to hack bitfields in x_smtyp because it's
@@ -487,28 +582,35 @@ DEFUN(coff_swap_aux_out,(abfd, inp, type, class, indx, numaux, extp),
bfd_h_put_16(abfd, in->x_sym.x_tvndx , (bfd_byte *) ext->x_sym.x_tvndx);
#endif
- if (class == C_BLOCK || ISFCN(type) || ISTAG(class)) {
- PUT_FCN_LNNOPTR(abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext);
- PUT_FCN_ENDNDX(abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext);
- }
-
- if (ISFCN(type)) {
- PUTWORD(abfd, in->x_sym.x_misc.x_fsize, (bfd_byte *) ext->x_sym.x_misc.x_fsize);
- }
- else {
- if (ISARY(type)) {
+ if (class == C_BLOCK || ISFCN (type) || ISTAG (class))
+ {
+ PUT_FCN_LNNOPTR(abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext);
+ PUT_FCN_ENDNDX(abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext);
+ }
+ else
+ {
#if DIMNUM != E_DIMNUM
- -> Error, we need to cope with truncating or extending DIMNUM!;
-#else
- bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0], (bfd_byte *)ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
- bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1], (bfd_byte *)ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
- bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2], (bfd_byte *)ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
- bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3], (bfd_byte *)ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
-#endif
+ #error we need to cope with truncating or extending DIMNUM
+#endif
+ bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],
+ (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
+ bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],
+ (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
+ bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],
+ (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
+ bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],
+ (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
}
- PUT_LNSZ_LNNO(abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext);
- PUT_LNSZ_SIZE(abfd, in->x_sym.x_misc.x_lnsz.x_size, ext);
- }
+
+ if (ISFCN (type))
+ PUTWORD (abfd, in->x_sym.x_misc.x_fsize,
+ (bfd_byte *) ext->x_sym.x_misc.x_fsize);
+ else
+ {
+ PUT_LNSZ_LNNO (abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext);
+ PUT_LNSZ_SIZE (abfd, in->x_sym.x_misc.x_lnsz.x_size, ext);
+ }
+
return sizeof(AUXENT);
}
@@ -517,10 +619,10 @@ DEFUN(coff_swap_aux_out,(abfd, inp, type, class, indx, numaux, extp),
#ifndef NO_COFF_LINENOS
static void
-DEFUN(coff_swap_lineno_in,(abfd, ext1, in1),
- bfd *abfd AND
- PTR ext1 AND
- PTR in1)
+coff_swap_lineno_in (abfd, ext1, in1)
+ bfd *abfd;
+ PTR ext1;
+ PTR in1;
{
LINENO *ext = (LINENO *)ext1;
struct internal_lineno *in = (struct internal_lineno *)in1;
@@ -530,10 +632,10 @@ DEFUN(coff_swap_lineno_in,(abfd, ext1, in1),
}
static unsigned int
-DEFUN(coff_swap_lineno_out,(abfd, inp, outp),
- bfd *abfd AND
- PTR inp AND
- PTR outp)
+coff_swap_lineno_out (abfd, inp, outp)
+ bfd *abfd;
+ PTR inp;
+ PTR outp;
{
struct internal_lineno *in = (struct internal_lineno *)inp;
struct external_lineno *ext = (struct external_lineno *)outp;
@@ -548,10 +650,10 @@ DEFUN(coff_swap_lineno_out,(abfd, inp, outp),
static void
-DEFUN(coff_swap_aouthdr_in,(abfd, aouthdr_ext1, aouthdr_int1),
- bfd *abfd AND
- PTR aouthdr_ext1 AND
- PTR aouthdr_int1)
+coff_swap_aouthdr_in (abfd, aouthdr_ext1, aouthdr_int1)
+ bfd *abfd;
+ PTR aouthdr_ext1;
+ PTR aouthdr_int1;
{
AOUTHDR *aouthdr_ext = (AOUTHDR *) aouthdr_ext1;
struct internal_aouthdr *aouthdr_int = (struct internal_aouthdr *)aouthdr_int1;
@@ -616,10 +718,10 @@ DEFUN(coff_swap_aouthdr_in,(abfd, aouthdr_ext1, aouthdr_int1),
}
static unsigned int
-DEFUN(coff_swap_aouthdr_out,(abfd, in, out),
- bfd *abfd AND
- PTR in AND
- PTR out)
+coff_swap_aouthdr_out (abfd, in, out)
+ bfd *abfd;
+ PTR in;
+ PTR out;
{
struct internal_aouthdr *aouthdr_in = (struct internal_aouthdr *)in;
AOUTHDR *aouthdr_out = (AOUTHDR *)out;
@@ -634,6 +736,64 @@ DEFUN(coff_swap_aouthdr_out,(abfd, in, out),
(bfd_byte *) aouthdr_out->text_start);
PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start,
(bfd_byte *) aouthdr_out->data_start);
+#ifdef COFF_WITH_PE
+ {
+ PEAOUTHDR *peaouthdr_out = (PEAOUTHDR *)aouthdr_out;
+ bfd_h_put_32 (abfd, aouthdr_in->pe->ImageBase,
+ (bfd_byte *) peaouthdr_out->ImageBase);
+ bfd_h_put_32 (abfd, aouthdr_in->pe->SectionAlignment,
+ (bfd_byte *) peaouthdr_out->SectionAlignment);
+ bfd_h_put_32 (abfd, aouthdr_in->pe->FileAlignment,
+ (bfd_byte *) peaouthdr_out->FileAlignment);
+ bfd_h_put_16 (abfd, aouthdr_in->pe->MajorOperatingSystemVersion,
+ (bfd_byte *) peaouthdr_out->MajorOperatingSystemVersion);
+ bfd_h_put_16 (abfd, aouthdr_in->pe->MinorOperatingSystemVersion,
+ (bfd_byte *) peaouthdr_out->MinorOperatingSystemVersion);
+ bfd_h_put_16 (abfd, aouthdr_in->pe->MajorImageVersion,
+ (bfd_byte *) peaouthdr_out->MajorImageVersion);
+ bfd_h_put_16 (abfd, aouthdr_in->pe->MinorImageVersion,
+ (bfd_byte *) peaouthdr_out->MinorImageVersion);
+ bfd_h_put_16 (abfd, aouthdr_in->pe->MajorSubsystemVersion,
+ (bfd_byte *) peaouthdr_out->MajorSubsystemVersion);
+ bfd_h_put_16 (abfd, aouthdr_in->pe->MinorSubsystemVersion,
+ (bfd_byte *) peaouthdr_out->MinorSubsystemVersion);
+ bfd_h_put_32 (abfd, aouthdr_in->pe->Reserved1,
+ (bfd_byte *) peaouthdr_out->Reserved1);
+ bfd_h_put_32 (abfd, aouthdr_in->pe->SizeOfImage,
+ (bfd_byte *) peaouthdr_out->SizeOfImage);
+ bfd_h_put_32 (abfd, aouthdr_in->pe->SizeOfHeaders,
+ (bfd_byte *) peaouthdr_out->SizeOfHeaders);
+ bfd_h_put_32 (abfd, aouthdr_in->pe->CheckSum,
+ (bfd_byte *) peaouthdr_out->CheckSum);
+ bfd_h_put_16 (abfd, aouthdr_in->pe->Subsystem,
+ (bfd_byte *) peaouthdr_out->Subsystem);
+ bfd_h_put_16 (abfd, aouthdr_in->pe->DllCharacteristics,
+ (bfd_byte *) peaouthdr_out->DllCharacteristics);
+ bfd_h_put_32 (abfd, aouthdr_in->pe->SizeOfStackReserve,
+ (bfd_byte *) peaouthdr_out->SizeOfStackReserve);
+ bfd_h_put_32 (abfd, aouthdr_in->pe->SizeOfStackCommit,
+ (bfd_byte *) peaouthdr_out->SizeOfStackCommit);
+ bfd_h_put_32 (abfd, aouthdr_in->pe->SizeOfHeapReserve,
+ (bfd_byte *) peaouthdr_out->SizeOfHeapReserve);
+ bfd_h_put_32 (abfd, aouthdr_in->pe->SizeOfHeapCommit,
+ (bfd_byte *) peaouthdr_out->SizeOfHeapCommit);
+ bfd_h_put_32 (abfd, aouthdr_in->pe->LoaderFlags,
+ (bfd_byte *) peaouthdr_out->LoaderFlags);
+ bfd_h_put_32 (abfd, aouthdr_in->pe->NumberOfRvaAndSizes,
+ (bfd_byte *) peaouthdr_out->NumberOfRvaAndSizes);
+ {
+ int idx;
+ for (idx=0; idx < 16; idx++)
+ {
+ bfd_h_put_32 (abfd, aouthdr_in->pe->DataDirectory[idx].VirtualAddress,
+ (bfd_byte *) peaouthdr_out->DataDirectory[idx][0]);
+ bfd_h_put_32 (abfd, aouthdr_in->pe->DataDirectory[idx].Size,
+ (bfd_byte *) peaouthdr_out->DataDirectory[idx][1]);
+ }
+ }
+}
+#endif
+
#ifdef I960
bfd_h_put_32(abfd, aouthdr_in->tagentries, (bfd_byte *) aouthdr_out->tagentries);
#endif
@@ -662,10 +822,10 @@ DEFUN(coff_swap_aouthdr_out,(abfd, in, out),
}
static void
-DEFUN(coff_swap_scnhdr_in,(abfd, ext, in),
- bfd *abfd AND
- PTR ext AND
- PTR in)
+coff_swap_scnhdr_in (abfd, ext, in)
+ bfd *abfd;
+ PTR ext;
+ PTR in;
{
SCNHDR *scnhdr_ext = (SCNHDR *) ext;
struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
@@ -695,88 +855,137 @@ DEFUN(coff_swap_scnhdr_in,(abfd, ext, in),
#ifdef I960
scnhdr_int->s_align = bfd_h_get_32(abfd, (bfd_byte *) scnhdr_ext->s_align);
#endif
+
+#ifdef NT_EXE_IMAGE_BASE
+/*
+ if (scnhdr_int->s_vaddr != 0) {
+ scnhdr_int->s_vaddr += NT_EXE_IMAGE_BASE;
+ }
+*/
+#endif
}
-/* start-sanitize-mpw */
-#ifndef MPW_C
-/* end-sanitize-mpw */
static unsigned int
-DEFUN(coff_swap_scnhdr_out,(abfd, in, out),
- bfd *abfd AND
- PTR in AND
- PTR out)
+coff_swap_scnhdr_out (abfd, in, out)
+ bfd *abfd;
+ PTR in;
+ PTR out;
{
struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *)in;
SCNHDR *scnhdr_ext = (SCNHDR *)out;
+ unsigned int ret = sizeof (SCNHDR);
memcpy(scnhdr_ext->s_name, scnhdr_int->s_name, sizeof(scnhdr_int->s_name));
- PUT_SCNHDR_VADDR (abfd, scnhdr_int->s_vaddr,
+
+#ifdef COFF_IMAGE_WITH_PE
+
+ {
+ bfd_link_pe_info *pe_info = coff_data (abfd)->link_info->pe_info;
+
+ PUT_SCNHDR_VADDR (abfd,
+ (scnhdr_int->s_vaddr
+ - pe_value (&pe_info->image_base,
+ NT_EXE_IMAGE_BASE)),
(bfd_byte *) scnhdr_ext->s_vaddr);
- PUT_SCNHDR_PADDR (abfd, scnhdr_int->s_paddr,
- (bfd_byte *) scnhdr_ext->s_paddr);
- PUT_SCNHDR_SIZE (abfd, scnhdr_int->s_size,
- (bfd_byte *) scnhdr_ext->s_size);
- PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr,
- (bfd_byte *) scnhdr_ext->s_scnptr);
- PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr,
- (bfd_byte *) scnhdr_ext->s_relptr);
- PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr,
- (bfd_byte *) scnhdr_ext->s_lnnoptr);
- PUTWORD(abfd, scnhdr_int->s_flags, (bfd_byte *) scnhdr_ext->s_flags);
-#if defined(M88)
- PUTWORD(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno);
- PUTWORD(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc);
-#else
- PUTHALF(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno);
- PUTHALF(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc);
-#endif
-#if defined(I960)
- PUTWORD(abfd, scnhdr_int->s_align, (bfd_byte *) scnhdr_ext->s_align);
+
+ /* NT wants the physical address data to be the size (s_size data) of
+ the section */
+#if 1
+ PUT_SCNHDR_PADDR (abfd, scnhdr_int->s_size,
+ (bfd_byte *) scnhdr_ext->s_paddr);
#endif
- return sizeof(SCNHDR);
+ /* NT wants the size data to be rounded up to the next NT_FILE_ALIGNMENT
+ value except for the BSS section, its s_size should be 0 */
+ if (strcmp (scnhdr_int->s_name, _BSS) == 0)
+ PUT_SCNHDR_SIZE (abfd, 0, (bfd_byte *) scnhdr_ext->s_size);
+ else
+ {
+ bfd_vma rounded_size;
+ rounded_size = ((scnhdr_int->s_size + NT_FILE_ALIGNMENT - 1) /
+ NT_FILE_ALIGNMENT) *
+ NT_FILE_ALIGNMENT;
+ PUT_SCNHDR_SIZE (abfd, rounded_size, (bfd_byte *) scnhdr_ext->s_size);
+ }
}
-/* start-sanitize-mpw */
#else
-/* Same routine, but with some pre-expanded macros, so ^&%$#&! MPW C doesn't
- corrupt itself and then freak out. */
+ PUT_SCNHDR_VADDR (abfd, scnhdr_int->s_vaddr,
+ (bfd_byte *) scnhdr_ext->s_vaddr);
-static unsigned int
-DEFUN(coff_swap_scnhdr_out,(abfd, in, out),
- bfd *abfd AND
- PTR in AND
- PTR out)
-{
- struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *)in;
- SCNHDR *scnhdr_ext = (SCNHDR *)out;
- memcpy(scnhdr_ext->s_name, scnhdr_int->s_name, sizeof(scnhdr_int->s_name));
- bfd_h_put_32 (abfd, scnhdr_int->s_vaddr,
- (bfd_byte *) scnhdr_ext->s_vaddr);
- bfd_h_put_32 (abfd, scnhdr_int->s_paddr,
+ PUT_SCNHDR_PADDR (abfd, scnhdr_int->s_paddr,
(bfd_byte *) scnhdr_ext->s_paddr);
- bfd_h_put_32 (abfd, scnhdr_int->s_size,
+ PUT_SCNHDR_SIZE (abfd, scnhdr_int->s_size,
(bfd_byte *) scnhdr_ext->s_size);
+#endif
PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr,
(bfd_byte *) scnhdr_ext->s_scnptr);
PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr,
(bfd_byte *) scnhdr_ext->s_relptr);
PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr,
(bfd_byte *) scnhdr_ext->s_lnnoptr);
+#ifdef COFF_IMAGE_WITH_PE
+ /* Extra flags must be set when dealing with NT. All sections should also
+ have the IMAGE_SCN_MEM_READ (0x40000000) flag set. In addition, the
+ .text section must have IMAGE_SCN_MEM_EXECUTE (0x20000000) and the data
+ sections (.idata, .data, .bss, .CRT) must have IMAGE_SCN_MEM_WRITE set
+ (this is especially important when dealing with the .idata section since
+ the addresses for routines from .dlls must be overwritten). If .reloc
+ section data is ever generated, we must add IMAGE_SCN_MEM_DISCARDABLE
+ (0x02000000). Also, the resource data should also be read and
+ writable. */
+ {
+ int flags = scnhdr_int->s_flags;
+ if (strcmp (scnhdr_int->s_name, ".data") == 0 ||
+ strcmp (scnhdr_int->s_name, ".CRT") == 0 ||
+ strcmp (scnhdr_int->s_name, ".rsrc") == 0 ||
+ strcmp (scnhdr_int->s_name, ".bss") == 0)
+ flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
+ else if (strcmp (scnhdr_int->s_name, ".text") == 0)
+ flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE;
+ else if (strcmp (scnhdr_int->s_name, ".reloc") == 0)
+ flags = SEC_DATA| IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE;
+ else if (strcmp (scnhdr_int->s_name, ".idata") == 0)
+ flags = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | SEC_DATA;
+ else if (strcmp (scnhdr_int->s_name, ".rdata") == 0
+ || strcmp (scnhdr_int->s_name, ".edata") == 0)
+ flags = IMAGE_SCN_MEM_READ | SEC_DATA;
+
+ PUTWORD(abfd, flags, (bfd_byte *) scnhdr_ext->s_flags);
+ }
+#else
PUTWORD(abfd, scnhdr_int->s_flags, (bfd_byte *) scnhdr_ext->s_flags);
+#endif
#if defined(M88)
PUTWORD(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno);
PUTWORD(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc);
#else
- PUTHALF(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno);
- PUTHALF(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc);
+ if (scnhdr_int->s_nlnno <= 0xffff)
+ PUTHALF(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno);
+ else
+ {
+ (*_bfd_error_handler) ("%s: line number overflow: 0x%lx > 0xffff",
+ bfd_get_filename (abfd),
+ scnhdr_int->s_nlnno);
+ bfd_set_error (bfd_error_file_truncated);
+ PUTHALF (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nlnno);
+ ret = 0;
+ }
+ if (scnhdr_int->s_nreloc <= 0xffff)
+ PUTHALF(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc);
+ else
+ {
+ (*_bfd_error_handler) ("%s: reloc overflow: 0x%lx > 0xffff",
+ bfd_get_filename (abfd),
+ scnhdr_int->s_nreloc);
+ bfd_set_error (bfd_error_file_truncated);
+ PUTHALF (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nreloc);
+ ret = 0;
+ }
#endif
#if defined(I960)
PUTWORD(abfd, scnhdr_int->s_align, (bfd_byte *) scnhdr_ext->s_align);
#endif
- return sizeof(SCNHDR);
+ return ret;
}
-
-#endif
-/* end-sanitize-mpw */