2004-05-28 H.J. Lu <hongjiu.lu@intel.com>
[deliverable/binutils-gdb.git] / bfd / peXXigen.c
index 8d819f26b17eb7d39722203ee288532cfa76d659..1b939e1013b567246b1c8db3e1a8c1bf7545cb30 100644 (file)
@@ -1,28 +1,28 @@
 /* Support for the generic parts of PE/PEI; the common executable parts.
-   Copyright 1995, 96, 97, 98, 99, 2000, 2001 Free Software Foundation, Inc.
+   Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+   Free Software Foundation, Inc.
    Written by Cygnus Solutions.
 
-This file is part of BFD, the Binary File Descriptor library.
+   This file is part of BFD, the Binary File Descriptor library.
 
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
 
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 /* Most of this hacked by Steve Chamberlain <sac@cygnus.com>.
 
    PE/PEI rearrangement (and code added): Donn Terry
-                                         Softway Systems, Inc.
-*/
+                                         Softway Systems, Inc.  */
 
 /* Hey look, some documentation [and in a place you expect to find it]!
 
@@ -50,8 +50,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
    FIXME: Please add more docs here so the next poor fool that has to hack
    on this code has a chance of getting something accomplished without
-   wasting too much time.
-*/
+   wasting too much time.  */
 
 /* This expands into COFF_WITH_pe or COFF_WITH_pep depending on whether
    we're compiling for straight PE or PE+.  */
@@ -92,10 +91,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 static void add_data_entry
   PARAMS ((bfd *, struct internal_extra_pe_aouthdr *, int, char *, bfd_vma));
-static boolean pe_print_pdata PARAMS ((bfd *, PTR));
-static boolean pe_print_reloc PARAMS ((bfd *, PTR));
-
-/**********************************************************************/
+static bfd_boolean pe_print_pdata PARAMS ((bfd *, PTR));
+static bfd_boolean pe_print_reloc PARAMS ((bfd *, PTR));
+static bfd_boolean pe_print_idata PARAMS ((bfd *, PTR));
+static bfd_boolean pe_print_edata PARAMS ((bfd *, PTR));
+\f
 
 void
 _bfd_XXi_swap_sym_in (abfd, ext1, in1)
@@ -109,26 +109,21 @@ _bfd_XXi_swap_sym_in (abfd, ext1, in1)
   if (ext->e.e_name[0] == 0)
     {
       in->_n._n_n._n_zeroes = 0;
-      in->_n._n_n._n_offset =
-       bfd_h_get_32 (abfd, (bfd_byte *) ext->e.e.e_offset);
+      in->_n._n_n._n_offset = H_GET_32 (abfd, ext->e.e.e_offset);
     }
   else
-    {
-      memcpy (in->_n._n_name, ext->e.e_name, SYMNMLEN);
-    }
+    memcpy (in->_n._n_name, ext->e.e_name, SYMNMLEN);
+
+  in->n_value = H_GET_32 (abfd, ext->e_value);
+  in->n_scnum = H_GET_16 (abfd, ext->e_scnum);
 
-  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);
-    }
+    in->n_type = H_GET_16 (abfd, ext->e_type);
   else
-    {
-      in->n_type = bfd_h_get_32 (abfd, (bfd_byte *) ext->e_type);
-    }
-  in->n_sclass = bfd_h_get_8 (abfd, ext->e_sclass);
-  in->n_numaux = bfd_h_get_8 (abfd, ext->e_numaux);
+    in->n_type = H_GET_32 (abfd, ext->e_type);
+
+  in->n_sclass = H_GET_8 (abfd, ext->e_sclass);
+  in->n_numaux = H_GET_8 (abfd, ext->e_numaux);
 
 #ifndef STRICT_PE_FORMAT
   /* This is for Gnu-created DLLs.  */
@@ -165,6 +160,7 @@ _bfd_XXi_swap_sym_in (abfd, ext1, in1)
       if (in->n_scnum == 0)
        {
          asection *sec;
+
          for (sec = abfd->sections; sec; sec = sec->next)
            {
              if (strcmp (sec->name, in->n_name) == 0)
@@ -174,16 +170,18 @@ _bfd_XXi_swap_sym_in (abfd, ext1, in1)
                }
            }
        }
+
       if (in->n_scnum == 0)
        {
          int unused_section_number = 0;
          asection *sec;
          char *name;
+
          for (sec = abfd->sections; sec; sec = sec->next)
            if (unused_section_number <= sec->target_index)
              unused_section_number = sec->target_index + 1;
 
-         name = bfd_alloc (abfd, strlen (in->n_name) + 10);
+         name = bfd_alloc (abfd, (bfd_size_type) strlen (in->n_name) + 10);
          if (name == NULL)
            return;
          strcpy (name, in->n_name);
@@ -200,7 +198,6 @@ _bfd_XXi_swap_sym_in (abfd, ext1, in1)
          sec->lineno_count = 0;
          sec->userdata = NULL;
          sec->next = (asection *) NULL;
-         sec->flags = 0;
          sec->alignment_power = 2;
          sec->flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_DATA | SEC_LOAD;
 
@@ -228,28 +225,25 @@ _bfd_XXi_swap_sym_out (abfd, inp, extp)
 {
   struct internal_syment *in = (struct internal_syment *) inp;
   SYMENT *ext = (SYMENT *) extp;
+
   if (in->_n._n_name[0] == 0)
     {
-      bfd_h_put_32 (abfd, 0, (bfd_byte *) ext->e.e.e_zeroes);
-      bfd_h_put_32 (abfd, in->_n._n_n._n_offset, (bfd_byte *) ext->e.e.e_offset);
+      H_PUT_32 (abfd, 0, ext->e.e.e_zeroes);
+      H_PUT_32 (abfd, in->_n._n_n._n_offset, ext->e.e.e_offset);
     }
   else
-    {
-      memcpy (ext->e.e_name, in->_n._n_name, SYMNMLEN);
-    }
+    memcpy (ext->e.e_name, in->_n._n_name, SYMNMLEN);
+
+  H_PUT_32 (abfd, in->n_value, ext->e_value);
+  H_PUT_16 (abfd, in->n_scnum, ext->e_scnum);
 
-  bfd_h_put_32 (abfd, in->n_value, (bfd_byte *) ext->e_value);
-  bfd_h_put_16 (abfd, in->n_scnum, (bfd_byte *) ext->e_scnum);
   if (sizeof (ext->e_type) == 2)
-    {
-      bfd_h_put_16 (abfd, in->n_type, (bfd_byte *) ext->e_type);
-    }
+    H_PUT_16 (abfd, in->n_type, ext->e_type);
   else
-    {
-      bfd_h_put_32 (abfd, in->n_type, (bfd_byte *) ext->e_type);
-    }
-  bfd_h_put_8 (abfd, in->n_sclass, ext->e_sclass);
-  bfd_h_put_8 (abfd, in->n_numaux, ext->e_numaux);
+    H_PUT_32 (abfd, in->n_type, ext->e_type);
+
+  H_PUT_8 (abfd, in->n_sclass, ext->e_sclass);
+  H_PUT_8 (abfd, in->n_numaux, ext->e_numaux);
 
   return SYMESZ;
 }
@@ -273,13 +267,10 @@ _bfd_XXi_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1)
       if (ext->x_file.x_fname[0] == 0)
        {
          in->x_file.x_n.x_zeroes = 0;
-         in->x_file.x_n.x_offset =
-           bfd_h_get_32 (abfd, (bfd_byte *) ext->x_file.x_n.x_offset);
+         in->x_file.x_n.x_offset = H_GET_32 (abfd, ext->x_file.x_n.x_offset);
        }
       else
-       {
-         memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
-       }
+       memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
       return;
 
     case C_STAT:
@@ -290,19 +281,16 @@ _bfd_XXi_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1)
          in->x_scn.x_scnlen = GET_SCN_SCNLEN (abfd, ext);
          in->x_scn.x_nreloc = GET_SCN_NRELOC (abfd, ext);
          in->x_scn.x_nlinno = GET_SCN_NLINNO (abfd, ext);
-         in->x_scn.x_checksum =
-           bfd_h_get_32 (abfd, (bfd_byte *) ext->x_scn.x_checksum);
-         in->x_scn.x_associated =
-           bfd_h_get_16 (abfd, (bfd_byte *) ext->x_scn.x_associated);
-         in->x_scn.x_comdat =
-           bfd_h_get_8 (abfd, (bfd_byte *) ext->x_scn.x_comdat);
+         in->x_scn.x_checksum = H_GET_32 (abfd, ext->x_scn.x_checksum);
+         in->x_scn.x_associated = H_GET_16 (abfd, ext->x_scn.x_associated);
+         in->x_scn.x_comdat = H_GET_8 (abfd, ext->x_scn.x_comdat);
          return;
        }
       break;
     }
 
-  in->x_sym.x_tagndx.l = bfd_h_get_32 (abfd, (bfd_byte *) ext->x_sym.x_tagndx);
-  in->x_sym.x_tvndx = bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_tvndx);
+  in->x_sym.x_tagndx.l = H_GET_32 (abfd, ext->x_sym.x_tagndx);
+  in->x_sym.x_tvndx = H_GET_16 (abfd, ext->x_sym.x_tvndx);
 
   if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
     {
@@ -312,19 +300,18 @@ _bfd_XXi_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1)
   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]);
+       H_GET_16 (abfd, 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]);
+       H_GET_16 (abfd, 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]);
+       H_GET_16 (abfd, 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]);
+       H_GET_16 (abfd, 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);
+      in->x_sym.x_misc.x_fsize = H_GET_32 (abfd, ext->x_sym.x_misc.x_fsize);
     }
   else
     {
@@ -352,15 +339,12 @@ _bfd_XXi_swap_aux_out (abfd, inp, type, class, indx, numaux, extp)
     case C_FILE:
       if (in->x_file.x_fname[0] == 0)
        {
-         bfd_h_put_32 (abfd, 0, (bfd_byte *) ext->x_file.x_n.x_zeroes);
-         bfd_h_put_32 (abfd,
-                       in->x_file.x_n.x_offset,
-                       (bfd_byte *) ext->x_file.x_n.x_offset);
+         H_PUT_32 (abfd, 0, ext->x_file.x_n.x_zeroes);
+         H_PUT_32 (abfd, in->x_file.x_n.x_offset, ext->x_file.x_n.x_offset);
        }
       else
-       {
-         memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
-       }
+       memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
+
       return AUXESZ;
 
     case C_STAT:
@@ -371,19 +355,16 @@ _bfd_XXi_swap_aux_out (abfd, inp, type, class, indx, numaux, extp)
          PUT_SCN_SCNLEN (abfd, in->x_scn.x_scnlen, ext);
          PUT_SCN_NRELOC (abfd, in->x_scn.x_nreloc, ext);
          PUT_SCN_NLINNO (abfd, in->x_scn.x_nlinno, ext);
-         bfd_h_put_32 (abfd, in->x_scn.x_checksum,
-                       (bfd_byte *) ext->x_scn.x_checksum);
-         bfd_h_put_16 (abfd, in->x_scn.x_associated,
-                       (bfd_byte *) ext->x_scn.x_associated);
-         bfd_h_put_8 (abfd, in->x_scn.x_comdat,
-                      (bfd_byte *) ext->x_scn.x_comdat);
+         H_PUT_32 (abfd, in->x_scn.x_checksum, ext->x_scn.x_checksum);
+         H_PUT_16 (abfd, in->x_scn.x_associated, ext->x_scn.x_associated);
+         H_PUT_8 (abfd, in->x_scn.x_comdat, ext->x_scn.x_comdat);
          return AUXESZ;
        }
       break;
     }
 
-  bfd_h_put_32 (abfd, in->x_sym.x_tagndx.l, (bfd_byte *) ext->x_sym.x_tagndx);
-  bfd_h_put_16 (abfd, in->x_sym.x_tvndx, (bfd_byte *) ext->x_sym.x_tvndx);
+  H_PUT_32 (abfd, in->x_sym.x_tagndx.l, ext->x_sym.x_tagndx);
+  H_PUT_16 (abfd, in->x_sym.x_tvndx, ext->x_sym.x_tvndx);
 
   if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
     {
@@ -392,19 +373,18 @@ _bfd_XXi_swap_aux_out (abfd, inp, type, class, indx, numaux, extp)
     }
   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]);
+      H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],
+               ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
+      H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],
+               ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
+      H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],
+               ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
+      H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],
+               ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
     }
 
   if (ISFCN (type))
-    bfd_h_put_32 (abfd, in->x_sym.x_misc.x_fsize,
-                 (bfd_byte *) ext->x_sym.x_misc.x_fsize);
+    H_PUT_32 (abfd, in->x_sym.x_misc.x_fsize, ext->x_sym.x_misc.x_fsize);
   else
     {
       PUT_LNSZ_LNNO (abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext);
@@ -423,7 +403,7 @@ _bfd_XXi_swap_lineno_in (abfd, ext1, in1)
   LINENO *ext = (LINENO *) ext1;
   struct internal_lineno *in = (struct internal_lineno *) in1;
 
-  in->l_addr.l_symndx = bfd_h_get_32 (abfd, (bfd_byte *) ext->l_addr.l_symndx);
+  in->l_addr.l_symndx = H_GET_32 (abfd, ext->l_addr.l_symndx);
   in->l_lnno = GET_LINENO_LNNO (abfd, ext);
 }
 
@@ -435,8 +415,7 @@ _bfd_XXi_swap_lineno_out (abfd, inp, outp)
 {
   struct internal_lineno *in = (struct internal_lineno *) inp;
   struct external_lineno *ext = (struct external_lineno *) outp;
-  bfd_h_put_32 (abfd, in->l_addr.l_symndx, (bfd_byte *)
-         ext->l_addr.l_symndx);
+  H_PUT_32 (abfd, in->l_addr.l_symndx, ext->l_addr.l_symndx);
 
   PUT_LINENO_LNNO (abfd, in->l_lnno, ext);
   return LINESZ;
@@ -453,63 +432,62 @@ _bfd_XXi_swap_aouthdr_in (abfd, aouthdr_ext1, aouthdr_int1)
   AOUTHDR        *aouthdr_ext = (AOUTHDR *) aouthdr_ext1;
   struct internal_aouthdr *aouthdr_int = (struct internal_aouthdr *)aouthdr_int1;
 
-  aouthdr_int->magic = bfd_h_get_16 (abfd, (bfd_byte *) aouthdr_ext->magic);
-  aouthdr_int->vstamp = bfd_h_get_16 (abfd, (bfd_byte *) aouthdr_ext->vstamp);
-  aouthdr_int->tsize =
-    GET_AOUTHDR_TSIZE (abfd, (bfd_byte *) aouthdr_ext->tsize);
-  aouthdr_int->dsize =
-    GET_AOUTHDR_DSIZE (abfd, (bfd_byte *) aouthdr_ext->dsize);
-  aouthdr_int->bsize =
-    GET_AOUTHDR_BSIZE (abfd, (bfd_byte *) aouthdr_ext->bsize);
-  aouthdr_int->entry =
-    GET_AOUTHDR_ENTRY (abfd, (bfd_byte *) aouthdr_ext->entry);
+  aouthdr_int->magic = H_GET_16 (abfd, aouthdr_ext->magic);
+  aouthdr_int->vstamp = H_GET_16 (abfd, aouthdr_ext->vstamp);
+  aouthdr_int->tsize = GET_AOUTHDR_TSIZE (abfd, aouthdr_ext->tsize);
+  aouthdr_int->dsize = GET_AOUTHDR_DSIZE (abfd, aouthdr_ext->dsize);
+  aouthdr_int->bsize = GET_AOUTHDR_BSIZE (abfd, aouthdr_ext->bsize);
+  aouthdr_int->entry = GET_AOUTHDR_ENTRY (abfd, aouthdr_ext->entry);
   aouthdr_int->text_start =
-    GET_AOUTHDR_TEXT_START (abfd, (bfd_byte *) aouthdr_ext->text_start);
+    GET_AOUTHDR_TEXT_START (abfd, aouthdr_ext->text_start);
 #ifndef COFF_WITH_pep
   /* PE32+ does not have data_start member! */
   aouthdr_int->data_start =
-    GET_AOUTHDR_DATA_START (abfd, (bfd_byte *) aouthdr_ext->data_start);
+    GET_AOUTHDR_DATA_START (abfd, aouthdr_ext->data_start);
 #endif
 
   a = &aouthdr_int->pe;
-  a->ImageBase = GET_OPTHDR_IMAGE_BASE (abfd, (bfd_byte *) src->ImageBase);
-  a->SectionAlignment = bfd_h_get_32 (abfd, (bfd_byte *) src->SectionAlignment);
-  a->FileAlignment = bfd_h_get_32 (abfd, (bfd_byte *) src->FileAlignment);
+  a->ImageBase = GET_OPTHDR_IMAGE_BASE (abfd, src->ImageBase);
+  a->SectionAlignment = H_GET_32 (abfd, src->SectionAlignment);
+  a->FileAlignment = H_GET_32 (abfd, src->FileAlignment);
   a->MajorOperatingSystemVersion =
-    bfd_h_get_16 (abfd, (bfd_byte *) src->MajorOperatingSystemVersion);
+    H_GET_16 (abfd, src->MajorOperatingSystemVersion);
   a->MinorOperatingSystemVersion =
-    bfd_h_get_16 (abfd, (bfd_byte *) src->MinorOperatingSystemVersion);
-  a->MajorImageVersion = bfd_h_get_16 (abfd, (bfd_byte *) src->MajorImageVersion);
-  a->MinorImageVersion = bfd_h_get_16 (abfd, (bfd_byte *) src->MinorImageVersion);
-  a->MajorSubsystemVersion = bfd_h_get_16 (abfd, (bfd_byte *) src->MajorSubsystemVersion);
-  a->MinorSubsystemVersion = bfd_h_get_16 (abfd, (bfd_byte *) src->MinorSubsystemVersion);
-  a->Reserved1 = bfd_h_get_32 (abfd, (bfd_byte *) src->Reserved1);
-  a->SizeOfImage = bfd_h_get_32 (abfd, (bfd_byte *) src->SizeOfImage);
-  a->SizeOfHeaders = bfd_h_get_32 (abfd, (bfd_byte *) src->SizeOfHeaders);
-  a->CheckSum = bfd_h_get_32 (abfd, (bfd_byte *) src->CheckSum);
-  a->Subsystem = bfd_h_get_16 (abfd, (bfd_byte *) src->Subsystem);
-  a->DllCharacteristics = bfd_h_get_16 (abfd, (bfd_byte *) src->DllCharacteristics);
-  a->SizeOfStackReserve = GET_OPTHDR_SIZE_OF_STACK_RESERVE (abfd, (bfd_byte *) src->SizeOfStackReserve);
-  a->SizeOfStackCommit = GET_OPTHDR_SIZE_OF_STACK_COMMIT (abfd, (bfd_byte *) src->SizeOfStackCommit);
-  a->SizeOfHeapReserve = GET_OPTHDR_SIZE_OF_HEAP_RESERVE (abfd, (bfd_byte *) src->SizeOfHeapReserve);
-  a->SizeOfHeapCommit = GET_OPTHDR_SIZE_OF_HEAP_COMMIT (abfd, (bfd_byte *) src->SizeOfHeapCommit);
-  a->LoaderFlags = bfd_h_get_32 (abfd, (bfd_byte *) src->LoaderFlags);
-  a->NumberOfRvaAndSizes = bfd_h_get_32 (abfd, (bfd_byte *) src->NumberOfRvaAndSizes);
+    H_GET_16 (abfd, src->MinorOperatingSystemVersion);
+  a->MajorImageVersion = H_GET_16 (abfd, src->MajorImageVersion);
+  a->MinorImageVersion = H_GET_16 (abfd, src->MinorImageVersion);
+  a->MajorSubsystemVersion = H_GET_16 (abfd, src->MajorSubsystemVersion);
+  a->MinorSubsystemVersion = H_GET_16 (abfd, src->MinorSubsystemVersion);
+  a->Reserved1 = H_GET_32 (abfd, src->Reserved1);
+  a->SizeOfImage = H_GET_32 (abfd, src->SizeOfImage);
+  a->SizeOfHeaders = H_GET_32 (abfd, src->SizeOfHeaders);
+  a->CheckSum = H_GET_32 (abfd, src->CheckSum);
+  a->Subsystem = H_GET_16 (abfd, src->Subsystem);
+  a->DllCharacteristics = H_GET_16 (abfd, src->DllCharacteristics);
+  a->SizeOfStackReserve =
+    GET_OPTHDR_SIZE_OF_STACK_RESERVE (abfd, src->SizeOfStackReserve);
+  a->SizeOfStackCommit =
+    GET_OPTHDR_SIZE_OF_STACK_COMMIT (abfd, src->SizeOfStackCommit);
+  a->SizeOfHeapReserve =
+    GET_OPTHDR_SIZE_OF_HEAP_RESERVE (abfd, src->SizeOfHeapReserve);
+  a->SizeOfHeapCommit =
+    GET_OPTHDR_SIZE_OF_HEAP_COMMIT (abfd, src->SizeOfHeapCommit);
+  a->LoaderFlags = H_GET_32 (abfd, src->LoaderFlags);
+  a->NumberOfRvaAndSizes = H_GET_32 (abfd, src->NumberOfRvaAndSizes);
 
   {
     int idx;
+
     for (idx = 0; idx < 16; idx++)
       {
         /* If data directory is empty, rva also should be 0.  */
        int size =
-         bfd_h_get_32 (abfd, (bfd_byte *) src->DataDirectory[idx][1]);
+         H_GET_32 (abfd, src->DataDirectory[idx][1]);
        a->DataDirectory[idx].Size = size;
 
        if (size)
-         {
-           a->DataDirectory[idx].VirtualAddress =
-             bfd_h_get_32 (abfd, (bfd_byte *) src->DataDirectory[idx][0]);
-         }
+         a->DataDirectory[idx].VirtualAddress =
+           H_GET_32 (abfd, src->DataDirectory[idx][0]);
        else
          a->DataDirectory[idx].VirtualAddress = 0;
       }
@@ -522,6 +500,7 @@ _bfd_XXi_swap_aouthdr_in (abfd, aouthdr_ext1, aouthdr_int1)
       aouthdr_int->entry &= 0xffffffff;
 #endif
     }
+
   if (aouthdr_int->tsize)
     {
       aouthdr_int->text_start += a->ImageBase;
@@ -529,6 +508,7 @@ _bfd_XXi_swap_aouthdr_in (abfd, aouthdr_ext1, aouthdr_int1)
       aouthdr_int->text_start &= 0xffffffff;
 #endif
     }
+
 #ifndef COFF_WITH_pep
   /* PE32+ does not have data_start member! */
   if (aouthdr_int->dsize)
@@ -546,7 +526,6 @@ _bfd_XXi_swap_aouthdr_in (abfd, aouthdr_ext1, aouthdr_int1)
   thunk_size = a->DataDirectory[12].Size;
   import_table_size = a->DataDirectory[1].Size;
 #endif
-
 }
 
 /* A support function for below.  */
@@ -561,12 +540,12 @@ add_data_entry (abfd, aout, idx, name, base)
 {
   asection *sec = bfd_get_section_by_name (abfd, name);
 
-  /* add import directory information if it exists */
+  /* Add import directory information if it exists.  */
   if ((sec != NULL)
       && (coff_section_data (abfd, sec) != NULL)
       && (pei_section_data (abfd, sec) != NULL))
     {
-      /* If data directory is empty, rva also should be 0 */
+      /* If data directory is empty, rva also should be 0 */
       int size = pei_section_data (abfd, sec)->virt_size;
       aout->DataDirectory[idx].Size = size;
 
@@ -590,7 +569,8 @@ _bfd_XXi_swap_aouthdr_out (abfd, in, out)
   struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
   PEAOUTHDR *aouthdr_out = (PEAOUTHDR *) out;
   bfd_vma sa, fa, ib;
-
+  IMAGE_DATA_DIRECTORY idata2, idata5, tls;
+  
   if (pe->force_minimum_alignment)
     {
       if (!extra->FileAlignment)
@@ -606,6 +586,10 @@ _bfd_XXi_swap_aouthdr_out (abfd, in, out)
   fa = extra->FileAlignment;
   ib = extra->ImageBase;
 
+  idata2 = pe->pe_opthdr.DataDirectory[1];
+  idata5 = pe->pe_opthdr.DataDirectory[12];
+  tls = pe->pe_opthdr.DataDirectory[9];
+  
   if (aouthdr_in->tsize)
     {
       aouthdr_in->text_start -= ib;
@@ -613,6 +597,7 @@ _bfd_XXi_swap_aouthdr_out (abfd, in, out)
       aouthdr_in->text_start &= 0xffffffff;
 #endif
     }
+
   if (aouthdr_in->dsize)
     {
       aouthdr_in->data_start -= ib;
@@ -620,6 +605,7 @@ _bfd_XXi_swap_aouthdr_out (abfd, in, out)
       aouthdr_in->data_start &= 0xffffffff;
 #endif
     }
+
   if (aouthdr_in->entry)
     {
       aouthdr_in->entry -= ib;
@@ -632,28 +618,35 @@ _bfd_XXi_swap_aouthdr_out (abfd, in, out)
 #define SA(x) (((x) + sa -1 ) & (- sa))
 
   /* We like to have the sizes aligned.  */
-
   aouthdr_in->bsize = FA (aouthdr_in->bsize);
 
   extra->NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
 
-  /* first null out all data directory entries ..  */
-  memset (extra->DataDirectory, sizeof (extra->DataDirectory), 0);
+  /* First null out all data directory entries.  */
+  memset (extra->DataDirectory, 0, sizeof (extra->DataDirectory));
 
   add_data_entry (abfd, extra, 0, ".edata", ib);
-
-  /* Don't call add_data_entry for .idata$2 or .idata$5.  It's done in
-     bfd_coff_final_link where all the required information is
-     available.  */
-
-  /* However, until other .idata fixes are made (pending patch), the
-     entry for .idata is needed for backwards compatability.  FIXME.  */
-  add_data_entry (abfd, extra, 1, ".idata", ib);
-
   add_data_entry (abfd, extra, 2, ".rsrc", ib);
-
   add_data_entry (abfd, extra, 3, ".pdata", ib);
 
+  /* In theory we do not need to call add_data_entry for .idata$2 or
+     .idata$5.  It will be done in bfd_coff_final_link where all the
+     required information is available.  If however, we are not going
+     to perform a final link, eg because we have been invoked by objcopy
+     or strip, then we need to make sure that these Data Directory
+     entries are initialised properly.
+
+     So - we copy the input values into the output values, and then, if
+     a final link is going to be performed, it can overwrite them.  */
+  extra->DataDirectory[1]  = idata2;
+  extra->DataDirectory[12] = idata5;
+  extra->DataDirectory[9] = tls;
+
+  if (extra->DataDirectory[1].VirtualAddress == 0)
+    /* Until other .idata fixes are made (pending patch), the entry for
+       .idata is needed for backwards compatibility.  FIXME.  */
+    add_data_entry (abfd, extra, 1, ".idata", ib);
+    
   /* For some reason, the virtual size (which is what's set by
      add_data_entry) for .reloc is not the same as the size recorded
      in this slot by MSVC; it doesn't seem to cause problems (so far),
@@ -664,14 +657,19 @@ _bfd_XXi_swap_aouthdr_out (abfd, in, out)
 
   {
     asection *sec;
+    bfd_vma hsize = 0;
     bfd_vma dsize = 0;
-    bfd_vma isize = SA(abfd->sections->filepos);
+    bfd_vma isize = 0;
     bfd_vma tsize = 0;
 
     for (sec = abfd->sections; sec; sec = sec->next)
       {
        int rounded = FA(sec->_raw_size);
 
+       /* The first non-zero section filepos is the header size.
+          Sections without contents will have a filepos of 0.  */
+       if (hsize == 0)
+         hsize = sec->filepos;
        if (sec->flags & SEC_DATA)
          dsize += rounded;
        if (sec->flags & SEC_CODE)
@@ -681,88 +679,78 @@ _bfd_XXi_swap_aouthdr_out (abfd, in, out)
           5.0 link.exe) where the file size of the .data segment is
           quite small compared to the virtual size.  Without this
           fix, strip munges the file.  */
-       isize += SA (FA (pei_section_data (abfd, sec)->virt_size));
+       if (coff_section_data (abfd, sec) != NULL
+           && pei_section_data (abfd, sec) != NULL)
+         isize += SA (FA (pei_section_data (abfd, sec)->virt_size));
       }
 
     aouthdr_in->dsize = dsize;
     aouthdr_in->tsize = tsize;
-    extra->SizeOfImage = isize;
+    extra->SizeOfHeaders = hsize;
+    extra->SizeOfImage = SA(hsize) + isize;
   }
 
-  extra->SizeOfHeaders = abfd->sections->filepos;
-  bfd_h_put_16 (abfd, aouthdr_in->magic, (bfd_byte *) aouthdr_out->standard.magic);
+  H_PUT_16 (abfd, aouthdr_in->magic, aouthdr_out->standard.magic);
 
 #define LINKER_VERSION 256 /* That is, 2.56 */
 
   /* This piece of magic sets the "linker version" field to
      LINKER_VERSION.  */
-  bfd_h_put_16 (abfd,
-               LINKER_VERSION / 100 + (LINKER_VERSION % 100) * 256,
-               (bfd_byte *) aouthdr_out->standard.vstamp);
-
-  PUT_AOUTHDR_TSIZE (abfd, aouthdr_in->tsize, (bfd_byte *) aouthdr_out->standard.tsize);
-  PUT_AOUTHDR_DSIZE (abfd, aouthdr_in->dsize, (bfd_byte *) aouthdr_out->standard.dsize);
-  PUT_AOUTHDR_BSIZE (abfd, aouthdr_in->bsize, (bfd_byte *) aouthdr_out->standard.bsize);
-  PUT_AOUTHDR_ENTRY (abfd, aouthdr_in->entry, (bfd_byte *) aouthdr_out->standard.entry);
+  H_PUT_16 (abfd, (LINKER_VERSION / 100 + (LINKER_VERSION % 100) * 256),
+           aouthdr_out->standard.vstamp);
+
+  PUT_AOUTHDR_TSIZE (abfd, aouthdr_in->tsize, aouthdr_out->standard.tsize);
+  PUT_AOUTHDR_DSIZE (abfd, aouthdr_in->dsize, aouthdr_out->standard.dsize);
+  PUT_AOUTHDR_BSIZE (abfd, aouthdr_in->bsize, aouthdr_out->standard.bsize);
+  PUT_AOUTHDR_ENTRY (abfd, aouthdr_in->entry, aouthdr_out->standard.entry);
   PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start,
-                         (bfd_byte *) aouthdr_out->standard.text_start);
+                         aouthdr_out->standard.text_start);
 
 #ifndef COFF_WITH_pep
-  /* PE32+ does not have data_start member! */
+  /* PE32+ does not have data_start member!  */
   PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start,
-                         (bfd_byte *) aouthdr_out->standard.data_start);
+                         aouthdr_out->standard.data_start);
 #endif
 
-  PUT_OPTHDR_IMAGE_BASE (abfd, extra->ImageBase,
-                        (bfd_byte *) aouthdr_out->ImageBase);
-  bfd_h_put_32 (abfd, extra->SectionAlignment,
-               (bfd_byte *) aouthdr_out->SectionAlignment);
-  bfd_h_put_32 (abfd, extra->FileAlignment,
-               (bfd_byte *) aouthdr_out->FileAlignment);
-  bfd_h_put_16 (abfd, extra->MajorOperatingSystemVersion,
-               (bfd_byte *) aouthdr_out->MajorOperatingSystemVersion);
-  bfd_h_put_16 (abfd, extra->MinorOperatingSystemVersion,
-               (bfd_byte *) aouthdr_out->MinorOperatingSystemVersion);
-  bfd_h_put_16 (abfd, extra->MajorImageVersion,
-               (bfd_byte *) aouthdr_out->MajorImageVersion);
-  bfd_h_put_16 (abfd, extra->MinorImageVersion,
-               (bfd_byte *) aouthdr_out->MinorImageVersion);
-  bfd_h_put_16 (abfd, extra->MajorSubsystemVersion,
-               (bfd_byte *) aouthdr_out->MajorSubsystemVersion);
-  bfd_h_put_16 (abfd, extra->MinorSubsystemVersion,
-               (bfd_byte *) aouthdr_out->MinorSubsystemVersion);
-  bfd_h_put_32 (abfd, extra->Reserved1,
-               (bfd_byte *) aouthdr_out->Reserved1);
-  bfd_h_put_32 (abfd, extra->SizeOfImage,
-               (bfd_byte *) aouthdr_out->SizeOfImage);
-  bfd_h_put_32 (abfd, extra->SizeOfHeaders,
-               (bfd_byte *) aouthdr_out->SizeOfHeaders);
-  bfd_h_put_32 (abfd, extra->CheckSum,
-               (bfd_byte *) aouthdr_out->CheckSum);
-  bfd_h_put_16 (abfd, extra->Subsystem,
-               (bfd_byte *) aouthdr_out->Subsystem);
-  bfd_h_put_16 (abfd, extra->DllCharacteristics,
-               (bfd_byte *) aouthdr_out->DllCharacteristics);
+  PUT_OPTHDR_IMAGE_BASE (abfd, extra->ImageBase, aouthdr_out->ImageBase);
+  H_PUT_32 (abfd, extra->SectionAlignment, aouthdr_out->SectionAlignment);
+  H_PUT_32 (abfd, extra->FileAlignment, aouthdr_out->FileAlignment);
+  H_PUT_16 (abfd, extra->MajorOperatingSystemVersion,
+           aouthdr_out->MajorOperatingSystemVersion);
+  H_PUT_16 (abfd, extra->MinorOperatingSystemVersion,
+           aouthdr_out->MinorOperatingSystemVersion);
+  H_PUT_16 (abfd, extra->MajorImageVersion, aouthdr_out->MajorImageVersion);
+  H_PUT_16 (abfd, extra->MinorImageVersion, aouthdr_out->MinorImageVersion);
+  H_PUT_16 (abfd, extra->MajorSubsystemVersion,
+           aouthdr_out->MajorSubsystemVersion);
+  H_PUT_16 (abfd, extra->MinorSubsystemVersion,
+           aouthdr_out->MinorSubsystemVersion);
+  H_PUT_32 (abfd, extra->Reserved1, aouthdr_out->Reserved1);
+  H_PUT_32 (abfd, extra->SizeOfImage, aouthdr_out->SizeOfImage);
+  H_PUT_32 (abfd, extra->SizeOfHeaders, aouthdr_out->SizeOfHeaders);
+  H_PUT_32 (abfd, extra->CheckSum, aouthdr_out->CheckSum);
+  H_PUT_16 (abfd, extra->Subsystem, aouthdr_out->Subsystem);
+  H_PUT_16 (abfd, extra->DllCharacteristics, aouthdr_out->DllCharacteristics);
   PUT_OPTHDR_SIZE_OF_STACK_RESERVE (abfd, extra->SizeOfStackReserve,
-                                   (bfd_byte *) aouthdr_out->SizeOfStackReserve);
+                                   aouthdr_out->SizeOfStackReserve);
   PUT_OPTHDR_SIZE_OF_STACK_COMMIT (abfd, extra->SizeOfStackCommit,
-                                  (bfd_byte *) aouthdr_out->SizeOfStackCommit);
+                                  aouthdr_out->SizeOfStackCommit);
   PUT_OPTHDR_SIZE_OF_HEAP_RESERVE (abfd, extra->SizeOfHeapReserve,
-                                  (bfd_byte *) aouthdr_out->SizeOfHeapReserve);
+                                  aouthdr_out->SizeOfHeapReserve);
   PUT_OPTHDR_SIZE_OF_HEAP_COMMIT (abfd, extra->SizeOfHeapCommit,
-                                 (bfd_byte *) aouthdr_out->SizeOfHeapCommit);
-  bfd_h_put_32 (abfd, extra->LoaderFlags,
-               (bfd_byte *) aouthdr_out->LoaderFlags);
-  bfd_h_put_32 (abfd, extra->NumberOfRvaAndSizes,
-               (bfd_byte *) aouthdr_out->NumberOfRvaAndSizes);
+                                 aouthdr_out->SizeOfHeapCommit);
+  H_PUT_32 (abfd, extra->LoaderFlags, aouthdr_out->LoaderFlags);
+  H_PUT_32 (abfd, extra->NumberOfRvaAndSizes,
+           aouthdr_out->NumberOfRvaAndSizes);
   {
     int idx;
+
     for (idx = 0; idx < 16; idx++)
       {
-       bfd_h_put_32 (abfd, extra->DataDirectory[idx].VirtualAddress,
-                     (bfd_byte *) aouthdr_out->DataDirectory[idx][0]);
-       bfd_h_put_32 (abfd, extra->DataDirectory[idx].Size,
-                     (bfd_byte *) aouthdr_out->DataDirectory[idx][1]);
+       H_PUT_32 (abfd, extra->DataDirectory[idx].VirtualAddress,
+                 aouthdr_out->DataDirectory[idx][0]);
+       H_PUT_32 (abfd, extra->DataDirectory[idx].Size,
+                 aouthdr_out->DataDirectory[idx][1]);
       }
   }
 
@@ -831,63 +819,51 @@ _bfd_XXi_only_swap_filehdr_out (abfd, in, out)
   filehdr_in->pe.dos_message[15] = 0x0;
   filehdr_in->pe.nt_signature = NT_SIGNATURE;
 
-  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);
+  H_PUT_16 (abfd, filehdr_in->f_magic, filehdr_out->f_magic);
+  H_PUT_16 (abfd, filehdr_in->f_nscns, filehdr_out->f_nscns);
 
-  bfd_h_put_32 (abfd, time (0), (bfd_byte *) filehdr_out->f_timdat);
-  PUT_FILEHDR_SYMPTR (abfd, (bfd_vma) filehdr_in->f_symptr,
-                     (bfd_byte *) filehdr_out->f_symptr);
-  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);
+  H_PUT_32 (abfd, time (0), filehdr_out->f_timdat);
+  PUT_FILEHDR_SYMPTR (abfd, filehdr_in->f_symptr,
+                     filehdr_out->f_symptr);
+  H_PUT_32 (abfd, filehdr_in->f_nsyms, filehdr_out->f_nsyms);
+  H_PUT_16 (abfd, filehdr_in->f_opthdr, filehdr_out->f_opthdr);
+  H_PUT_16 (abfd, filehdr_in->f_flags, filehdr_out->f_flags);
 
-  /* put in extra dos header stuff.  This data remains essentially
+  /* 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);
+     for NT.  */
+  H_PUT_16 (abfd, filehdr_in->pe.e_magic, filehdr_out->e_magic);
+  H_PUT_16 (abfd, filehdr_in->pe.e_cblp, filehdr_out->e_cblp);
+  H_PUT_16 (abfd, filehdr_in->pe.e_cp, filehdr_out->e_cp);
+  H_PUT_16 (abfd, filehdr_in->pe.e_crlc, filehdr_out->e_crlc);
+  H_PUT_16 (abfd, filehdr_in->pe.e_cparhdr, filehdr_out->e_cparhdr);
+  H_PUT_16 (abfd, filehdr_in->pe.e_minalloc, filehdr_out->e_minalloc);
+  H_PUT_16 (abfd, filehdr_in->pe.e_maxalloc, filehdr_out->e_maxalloc);
+  H_PUT_16 (abfd, filehdr_in->pe.e_ss, filehdr_out->e_ss);
+  H_PUT_16 (abfd, filehdr_in->pe.e_sp, filehdr_out->e_sp);
+  H_PUT_16 (abfd, filehdr_in->pe.e_csum, filehdr_out->e_csum);
+  H_PUT_16 (abfd, filehdr_in->pe.e_ip, filehdr_out->e_ip);
+  H_PUT_16 (abfd, filehdr_in->pe.e_cs, filehdr_out->e_cs);
+  H_PUT_16 (abfd, filehdr_in->pe.e_lfarlc, filehdr_out->e_lfarlc);
+  H_PUT_16 (abfd, filehdr_in->pe.e_ovno, filehdr_out->e_ovno);
 
-  {
-    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]);
-  }
+  for (idx = 0; idx < 4; idx++)
+    H_PUT_16 (abfd, filehdr_in->pe.e_res[idx], filehdr_out->e_res[idx]);
+
+  H_PUT_16 (abfd, filehdr_in->pe.e_oemid, filehdr_out->e_oemid);
+  H_PUT_16 (abfd, filehdr_in->pe.e_oeminfo, filehdr_out->e_oeminfo);
+
+  for (idx = 0; idx < 10; idx++)
+    H_PUT_16 (abfd, filehdr_in->pe.e_res2[idx], filehdr_out->e_res2[idx]);
+
+  H_PUT_32 (abfd, filehdr_in->pe.e_lfanew, filehdr_out->e_lfanew);
+
+  for (idx = 0; idx < 16; idx++)
+    H_PUT_32 (abfd, filehdr_in->pe.dos_message[idx],
+             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);
+  H_PUT_32 (abfd, filehdr_in->pe.nt_signature, filehdr_out->nt_signature);
 
   return FILHSZ;
 }
@@ -901,14 +877,13 @@ _bfd_XX_only_swap_filehdr_out (abfd, in, 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);
-  PUT_FILEHDR_SYMPTR (abfd, (bfd_vma) filehdr_in->f_symptr,
-                     (bfd_byte *) filehdr_out->f_symptr);
-  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);
+  H_PUT_16 (abfd, filehdr_in->f_magic, filehdr_out->f_magic);
+  H_PUT_16 (abfd, filehdr_in->f_nscns, filehdr_out->f_nscns);
+  H_PUT_32 (abfd, filehdr_in->f_timdat, filehdr_out->f_timdat);
+  PUT_FILEHDR_SYMPTR (abfd, filehdr_in->f_symptr, filehdr_out->f_symptr);
+  H_PUT_32 (abfd, filehdr_in->f_nsyms, filehdr_out->f_nsyms);
+  H_PUT_16 (abfd, filehdr_in->f_opthdr, filehdr_out->f_opthdr);
+  H_PUT_16 (abfd, filehdr_in->f_flags, filehdr_out->f_flags);
 
   return FILHSZ;
 }
@@ -931,103 +906,157 @@ _bfd_XXi_swap_scnhdr_out (abfd, in, out)
                    ((scnhdr_int->s_vaddr
                      - pe_data (abfd)->pe_opthdr.ImageBase)
                     & 0xffffffff),
-                   (bfd_byte *) scnhdr_ext->s_vaddr);
+                   scnhdr_ext->s_vaddr);
 
   /* NT wants the size data to be rounded up to the next
      NT_FILE_ALIGNMENT, but zero if it has no content (as in .bss,
      sometimes).  */
-
   if ((scnhdr_int->s_flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0)
     {
-      ps = scnhdr_int->s_size;
-      ss = 0;
+      if (bfd_pe_executable_p (abfd))
+       {
+         ps = scnhdr_int->s_size;
+         ss = 0;
+       }
+      else
+       {
+         ps = 0;
+         ss = scnhdr_int->s_size;
+       }
     }
   else
     {
-      ps = scnhdr_int->s_paddr;
+      if (bfd_pe_executable_p (abfd))
+       ps = scnhdr_int->s_paddr;
+      else
+       ps = 0;
+
       ss = scnhdr_int->s_size;
     }
 
   PUT_SCNHDR_SIZE (abfd, ss,
-                  (bfd_byte *) scnhdr_ext->s_size);
+                  scnhdr_ext->s_size);
 
   /* s_paddr in PE is really the virtual size.  */
-  PUT_SCNHDR_PADDR (abfd, ps, (bfd_byte *) scnhdr_ext->s_paddr);
+  PUT_SCNHDR_PADDR (abfd, ps, scnhdr_ext->s_paddr);
 
   PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr,
-                    (bfd_byte *) scnhdr_ext->s_scnptr);
+                    scnhdr_ext->s_scnptr);
   PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr,
-                    (bfd_byte *) scnhdr_ext->s_relptr);
+                    scnhdr_ext->s_relptr);
   PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr,
-                     (bfd_byte *) scnhdr_ext->s_lnnoptr);
-
-  /* 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.  */
-
-  /* FIXME: alignment is also encoded in this field, at least on ppc (krk) */
-  /* FIXME: even worse, I don't see how to get the original alignment field*/
-  /*        back...                                                        */
+                     scnhdr_ext->s_lnnoptr);
 
   {
-    int flags = scnhdr_int->s_flags;
-    bfd_h_put_32 (abfd, flags, (bfd_byte *) scnhdr_ext->s_flags);
+    /* Extra flags must be set when dealing with PE.  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.  */
+
+    /* FIXME: Alignment is also encoded in this field, at least on PPC and 
+       ARM-WINCE.  Although - how do we get the original alignment field
+       back ?  */
+
+    typedef struct
+    {
+      const char *     section_name;
+      unsigned long    must_have;
+    }
+    pe_required_section_flags;
+    
+    pe_required_section_flags known_sections [] =
+      {
+       { ".arch",  IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_DISCARDABLE | IMAGE_SCN_ALIGN_8BYTES },
+       { ".bss",   IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_WRITE },
+       { ".data",  IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_WRITE },
+       { ".edata", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA },
+       { ".idata", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_WRITE },
+       { ".pdata", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA },
+       { ".rdata", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA },
+       { ".reloc", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_DISCARDABLE },
+       { ".rsrc",  IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_WRITE },
+       { ".text" , IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE },
+       { ".tls",   IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_WRITE },
+       { ".xdata", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA },
+       { NULL, 0}
+      };
+
+    pe_required_section_flags * p;
+
+    /* We have defaulted to adding the IMAGE_SCN_MEM_WRITE flag, but now
+       we know exactly what this specific section wants so we remove it
+       and then allow the must_have field to add it back in if necessary.
+       However, we don't remove IMAGE_SCN_MEM_WRITE flag from .text if the
+       default WP_TEXT file flag has been cleared.  WP_TEXT may be cleared
+       by ld --enable-auto-import (if auto-import is actually needed),
+       by ld --omagic, or by obcopy --writable-text.  */
+
+    for (p = known_sections; p->section_name; p++)
+      if (strcmp (scnhdr_int->s_name, p->section_name) == 0)
+       {
+         if (strcmp (scnhdr_int->s_name, ".text")
+             || (bfd_get_file_flags (abfd) & WP_TEXT))
+           scnhdr_int->s_flags &= ~IMAGE_SCN_MEM_WRITE;
+         scnhdr_int->s_flags |= p->must_have;
+         break;
+       }
+
+    H_PUT_32 (abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags);
   }
 
   if (coff_data (abfd)->link_info
-      && ! coff_data (abfd)->link_info->relocateable
+      && ! coff_data (abfd)->link_info->relocatable
       && ! coff_data (abfd)->link_info->shared
       && strcmp (scnhdr_int->s_name, ".text") == 0)
     {
       /* By inference from looking at MS output, the 32 bit field
-        which is the combintion of the number_of_relocs and
+        which is the combination of the number_of_relocs and
         number_of_linenos is used for the line number count in
         executables.  A 16-bit field won't do for cc1.  The MS
         document says that the number of relocs is zero for
         executables, but the 17-th bit has been observed to be there.
         Overflow is not an issue: a 4G-line program will overflow a
         bunch of other fields long before this!  */
-      bfd_h_put_16 (abfd, scnhdr_int->s_nlnno & 0xffff,
-                   (bfd_byte *) scnhdr_ext->s_nlnno);
-      bfd_h_put_16 (abfd, scnhdr_int->s_nlnno >> 16,
-                   (bfd_byte *) scnhdr_ext->s_nreloc);
+      H_PUT_16 (abfd, (scnhdr_int->s_nlnno & 0xffff), scnhdr_ext->s_nlnno);
+      H_PUT_16 (abfd, (scnhdr_int->s_nlnno >> 16), scnhdr_ext->s_nreloc);
     }
   else
     {
       if (scnhdr_int->s_nlnno <= 0xffff)
-       bfd_h_put_16 (abfd, scnhdr_int->s_nlnno,
-                     (bfd_byte *) scnhdr_ext->s_nlnno);
+       H_PUT_16 (abfd, scnhdr_int->s_nlnno, 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);
-         bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nlnno);
+         H_PUT_16 (abfd, 0xffff, scnhdr_ext->s_nlnno);
          ret = 0;
        }
-      if (scnhdr_int->s_nreloc <= 0xffff)
-       bfd_h_put_16 (abfd, scnhdr_int->s_nreloc,
-                     (bfd_byte *) scnhdr_ext->s_nreloc);
+
+      /* Although we could encode 0xffff relocs here, we do not, to be
+         consistent with other parts of bfd. Also it lets us warn, as
+         we should never see 0xffff here w/o having the overflow flag
+         set.  */
+      if (scnhdr_int->s_nreloc < 0xffff)
+       H_PUT_16 (abfd, scnhdr_int->s_nreloc, scnhdr_ext->s_nreloc);
       else
        {
-         /* PE can deal with large #s of relocs, but not here */
-         bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nreloc);
+         /* PE can deal with large #s of relocs, but not here */
+         H_PUT_16 (abfd, 0xffff, scnhdr_ext->s_nreloc);
          scnhdr_int->s_flags |= IMAGE_SCN_LNK_NRELOC_OVFL;
-         bfd_h_put_32 (abfd, scnhdr_int->s_flags,
-                       (bfd_byte *) scnhdr_ext->s_flags);
+         H_PUT_32 (abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags);
 #if 0
          (*_bfd_error_handler) (_("%s: reloc overflow 1: 0x%lx > 0xffff"),
                                 bfd_get_filename (abfd),
                                 scnhdr_int->s_nreloc);
          bfd_set_error (bfd_error_file_truncated);
-         bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nreloc);
+         H_PUT_16 (abfd, 0xffff, scnhdr_ext->s_nreloc);
          ret = 0;
 #endif
        }
@@ -1035,26 +1064,26 @@ _bfd_XXi_swap_scnhdr_out (abfd, in, out)
   return ret;
 }
 
-static char * dir_names[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] = {
-  N_("Export Directory [.edata (or where ever we found it)]"),
-  N_("Import Directory [parts of .idata]"),
-  N_("Resource Directory [.rsrc]"),
-  N_("Exception Directory [.pdata]"),
-  N_("Security Directory"),
-  N_("Base Relocation Directory [.reloc]"),
-  N_("Debug Directory"),
-  N_("Description Directory"),
-  N_("Special Directory"),
-  N_("Thread Storage Directory [.tls]"),
-  N_("Load Configuration Directory"),
-  N_("Bound Import Directory"),
-  N_("Import Address Table Directory"),
-  N_("Delay Import Directory"),
-  N_("Reserved"),
-  N_("Reserved")
-};
-
-/**********************************************************************/
+static char * dir_names[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] =
+  {
+    N_("Export Directory [.edata (or where ever we found it)]"),
+    N_("Import Directory [parts of .idata]"),
+    N_("Resource Directory [.rsrc]"),
+    N_("Exception Directory [.pdata]"),
+    N_("Security Directory"),
+    N_("Base Relocation Directory [.reloc]"),
+    N_("Debug Directory"),
+    N_("Description Directory"),
+    N_("Special Directory"),
+    N_("Thread Storage Directory [.tls]"),
+    N_("Load Configuration Directory"),
+    N_("Bound Import Directory"),
+    N_("Import Address Table Directory"),
+    N_("Delay Import Directory"),
+    N_("Reserved"),
+    N_("Reserved")
+  };
+
 #ifdef POWERPC_LE_PE
 /* The code for the PPC really falls in the "architecture dependent"
    category.  However, it's not clear that anyone will ever care, so
@@ -1063,8 +1092,7 @@ static char * dir_names[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] = {
    PPC- specific code.  */
 #endif
 
-/**********************************************************************/
-static boolean
+static bfd_boolean
 pe_print_idata (abfd, vfile)
      bfd *abfd;
      PTR vfile;
@@ -1081,6 +1109,7 @@ pe_print_idata (abfd, vfile)
   bfd_size_type datasize = 0;
   bfd_size_type dataoff;
   bfd_size_type i;
+  bfd_size_type amt;
   int onaline = 20;
 
   pe_data_type *pe = pe_data (abfd);
@@ -1095,12 +1124,12 @@ pe_print_idata (abfd, vfile)
       /* Maybe the extra header isn't there.  Look for the section.  */
       section = bfd_get_section_by_name (abfd, ".idata");
       if (section == NULL)
-       return true;
+       return TRUE;
 
       addr = section->vma;
       datasize = bfd_section_size (abfd, section);
       if (datasize == 0)
-       return true;
+       return TRUE;
     }
   else
     {
@@ -1116,7 +1145,7 @@ pe_print_idata (abfd, vfile)
        {
          fprintf (file,
                   _("\nThere is an import table, but the section containing it could not be found\n"));
-         return true;
+         return TRUE;
        }
     }
 
@@ -1142,15 +1171,13 @@ pe_print_idata (abfd, vfile)
       bfd_byte *data = 0;
       int offset;
 
-      data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd,
-                                                                rel_section));
-      if (data == NULL && bfd_section_size (abfd, rel_section) != 0)
-       return false;
+      amt = bfd_section_size (abfd, rel_section);
+      data = (bfd_byte *) bfd_malloc (amt);
+      if (data == NULL && amt != 0)
+       return FALSE;
 
-      bfd_get_section_contents (abfd,
-                               rel_section,
-                               (PTR) data, 0,
-                               bfd_section_size (abfd, rel_section));
+      bfd_get_section_contents (abfd, rel_section, (PTR) data, (bfd_vma) 0,
+                               amt);
 
       offset = abfd->start_address - rel_section->vma;
 
@@ -1176,21 +1203,22 @@ pe_print_idata (abfd, vfile)
           _("\nThe Import Tables (interpreted %s section contents)\n"),
           section->name);
   fprintf (file,
-          _(" vma:            Hint    Time      Forward  DLL       First\n"));
-  fprintf (file,
-          _("                 Table   Stamp     Chain    Name      Thunk\n"));
+          _("\
+ vma:            Hint    Time      Forward  DLL       First\n\
+                 Table   Stamp     Chain    Name      Thunk\n"));
 
-  data = (bfd_byte *) bfd_malloc (dataoff + datasize);
+  amt = dataoff + datasize;
+  data = (bfd_byte *) bfd_malloc (amt);
   if (data == NULL)
-    return false;
+    return FALSE;
 
   /* Read the whole section.  Some of the fields might be before dataoff.  */
-  if (! bfd_get_section_contents (abfd, section, (PTR) data,
-                                 0, dataoff + datasize))
-    return false;
+  if (! bfd_get_section_contents (abfd, section, (PTR) data, (bfd_vma) 0, amt))
+    return FALSE;
 
   adj = section->vma - extra->ImageBase;
 
+  /* Print all image import descriptors.  */
   for (i = 0; i < datasize; i += onaline)
     {
       bfd_vma hint_addr;
@@ -1202,15 +1230,13 @@ pe_print_idata (abfd, vfile)
       bfd_size_type j;
       char *dll;
 
-      /* print (i + extra->DataDirectory[1].VirtualAddress)  */
+      /* Print (i + extra->DataDirectory[1].VirtualAddress).  */
       fprintf (file, " %08lx\t", (unsigned long) (i + adj + dataoff));
-
+#if 0
       if (i + 20 > datasize)
-       {
-         /* Check stuff.  */
-         ;
-       }
-
+       /* Check stuff.  */
+       ;
+#endif
       hint_addr = bfd_get_32 (abfd, data + i + dataoff);
       time_stamp = bfd_get_32 (abfd, data + i + 4 + dataoff);
       forward_chain = bfd_get_32 (abfd, data + i + 8 + dataoff);
@@ -1232,19 +1258,83 @@ pe_print_idata (abfd, vfile)
 
       if (hint_addr != 0)
        {
-         fprintf (file, _("\tvma:  Hint/Ord Member-Name\n"));
+         bfd_byte *ft_data;
+         asection *ft_section;
+         bfd_vma ft_addr;
+         bfd_size_type ft_datasize;
+         int ft_idx;
+         int ft_allocated = 0;
+
+         fprintf (file, _("\tvma:  Hint/Ord Member-Name Bound-To\n"));
 
          idx = hint_addr - adj;
+         
+         ft_addr = first_thunk + extra->ImageBase;
+         ft_data = data;
+         ft_idx = first_thunk - adj;
+         ft_allocated = 0; 
+      
+         if (first_thunk != hint_addr) 
+           {
+             /* Find the section which contains the first thunk.  */
+             for (ft_section = abfd->sections;
+                  ft_section != NULL;
+                  ft_section = ft_section->next)
+               {
+                 ft_datasize = bfd_section_size (abfd, ft_section);
+                 if (ft_addr >= ft_section->vma
+                     && ft_addr < ft_section->vma + ft_datasize)
+                   break;
+               }
+
+             if (ft_section == NULL)
+               {
+                 fprintf (file,
+                      _("\nThere is a first thunk, but the section containing it could not be found\n"));
+                 continue;
+               }
 
+             /* Now check to see if this section is the same as our current
+                section.  If it is not then we will have to load its data in.  */
+             if (ft_section == section)
+               {
+                 ft_data = data;
+                 ft_idx = first_thunk - adj;
+               }
+             else
+               {
+                 ft_idx = first_thunk - (ft_section->vma - extra->ImageBase);
+                 ft_data = (bfd_byte *) bfd_malloc (datasize);
+                 if (ft_data == NULL)
+                   continue;
+
+                 /* Read datasize bfd_bytes starting at offset ft_idx.  */
+                 if (! bfd_get_section_contents (abfd, ft_section,
+                                                 (PTR) ft_data,
+                                                 (bfd_vma) ft_idx,
+                                                 datasize))
+                   {
+                     free (ft_data);
+                     continue;
+                   }
+
+                 ft_idx = 0;
+                 ft_allocated = 1;
+               }
+           }
+
+         /* Print HintName vector entries.  */
          for (j = 0; j < datasize; j += 4)
            {
              unsigned long member = bfd_get_32 (abfd, data + idx + j);
 
+             /* Print single IMAGE_IMPORT_BY_NAME vector.  */ 
              if (member == 0)
                break;
+
              if (member & 0x80000000)
-               fprintf (file, "\t%04lx\t %4lu", member,
-                        member & 0x7fffffff);
+               fprintf (file, "\t%04lx\t %4lu  <none>",
+                        member, member & 0x7fffffff);
              else
                {
                  int ordinal;
@@ -1257,83 +1347,29 @@ pe_print_idata (abfd, vfile)
                }
 
              /* If the time stamp is not zero, the import address
-                 table holds actual addresses.  */
+                table holds actual addresses.  */
              if (time_stamp != 0
                  && first_thunk != 0
                  && first_thunk != hint_addr)
                fprintf (file, "\t%04lx",
-                        (long) bfd_get_32 (abfd, data + first_thunk - adj + j));
+                        (long) bfd_get_32 (abfd, ft_data + ft_idx + j));
 
              fprintf (file, "\n");
            }
-       }
-
-      if (hint_addr != first_thunk && time_stamp == 0)
-       {
-         int differ = 0;
-         int idx2;
-
-         idx2 = first_thunk - adj;
 
-         for (j = 0; j < datasize; j += 4)
-           {
-             int ordinal;
-             char *member_name;
-             bfd_vma hint_member = 0;
-             bfd_vma iat_member;
-
-             if (hint_addr != 0)
-               hint_member = bfd_get_32 (abfd, data + idx + j);
-             iat_member = bfd_get_32 (abfd, data + idx2 + j);
-
-             if (hint_addr == 0 && iat_member == 0)
-               break;
-
-             if (hint_addr == 0 || hint_member != iat_member)
-               {
-                 if (differ == 0)
-                   {
-                     fprintf (file,
-                              _("\tThe Import Address Table (difference found)\n"));
-                     fprintf (file, _("\tvma:  Hint/Ord Member-Name\n"));
-                     differ = 1;
-                   }
-                 if (iat_member == 0)
-                   {
-                     fprintf (file,
-                             _("\t>>> Ran out of IAT members!\n"));
-                   }
-                 else
-                   {
-                     ordinal = bfd_get_16 (abfd, data + iat_member - adj);
-                     member_name = (char *) data + iat_member - adj + 2;
-                     fprintf (file, "\t%04lx\t %4d  %s\n",
-                             (unsigned long) iat_member,
-                             ordinal,
-                             member_name);
-                   }
-               }
-
-             if (hint_addr != 0 && hint_member == 0)
-               break;
-           }
-         if (differ == 0)
-           {
-             fprintf (file,
-                     _("\tThe Import Address Table is identical\n"));
-           }
+         if (ft_allocated)
+           free (ft_data);
        }
 
       fprintf (file, "\n");
-
     }
 
   free (data);
 
-  return true;
+  return TRUE;
 }
 
-static boolean
+static bfd_boolean
 pe_print_edata (abfd, vfile)
      bfd *abfd;
      PTR vfile;
@@ -1341,24 +1377,23 @@ pe_print_edata (abfd, vfile)
   FILE *file = (FILE *) vfile;
   bfd_byte *data;
   asection *section;
-
   bfd_size_type datasize = 0;
   bfd_size_type dataoff;
   bfd_size_type i;
-
   bfd_signed_vma adj;
-  struct EDT_type {
-    long export_flags;             /* reserved - should be zero */
+  struct EDT_type
+  {
+    long export_flags;          /* reserved - should be zero */
     long time_stamp;
     short major_ver;
     short minor_ver;
-    bfd_vma name;                  /* rva - relative to image base */
-    long base;                     /* ordinal base */
-    unsigned long num_functions;   /* Number in the export address table */
-    unsigned long num_names;       /* Number in the name pointer table */
-    bfd_vma eat_addr;    /* rva to the export address table */
-    bfd_vma npt_addr;        /* rva to the Export Name Pointer Table */
-    bfd_vma ot_addr; /* rva to the Ordinal Table */
+    bfd_vma name;               /* rva - relative to image base */
+    long base;                  /* ordinal base */
+    unsigned long num_functions;/* Number in the export address table */
+    unsigned long num_names;    /* Number in the name pointer table */
+    bfd_vma eat_addr;          /* rva to the export address table */
+    bfd_vma npt_addr;          /* rva to the Export Name Pointer Table */
+    bfd_vma ot_addr;           /* rva to the Ordinal Table */
   } edt;
 
   pe_data_type *pe = pe_data (abfd);
@@ -1373,19 +1408,21 @@ pe_print_edata (abfd, vfile)
       /* Maybe the extra header isn't there.  Look for the section.  */
       section = bfd_get_section_by_name (abfd, ".edata");
       if (section == NULL)
-       return true;
+       return TRUE;
 
       addr = section->vma;
       datasize = bfd_section_size (abfd, section);
       if (datasize == 0)
-       return true;
+       return TRUE;
     }
   else
     {
       addr += extra->ImageBase;
+
       for (section = abfd->sections; section != NULL; section = section->next)
        {
          datasize = bfd_section_size (abfd, section);
+
          if (addr >= section->vma && addr < section->vma + datasize)
            break;
        }
@@ -1394,7 +1431,7 @@ pe_print_edata (abfd, vfile)
        {
          fprintf (file,
                   _("\nThere is an export table, but the section containing it could not be found\n"));
-         return true;
+         return TRUE;
        }
     }
 
@@ -1406,11 +1443,11 @@ pe_print_edata (abfd, vfile)
 
   data = (bfd_byte *) bfd_malloc (datasize);
   if (data == NULL)
-    return false;
+    return FALSE;
 
-  if (! bfd_get_section_contents (abfd, section, (PTR) data, dataoff,
-                                 datasize))
-    return false;
+  if (! bfd_get_section_contents (abfd, section, (PTR) data,
+                                 (file_ptr) dataoff, datasize))
+    return FALSE;
 
   /* Go get Export Directory Table.  */
   edt.export_flags   = bfd_get_32 (abfd, data +  0);
@@ -1427,7 +1464,7 @@ pe_print_edata (abfd, vfile)
 
   adj = section->vma - extra->ImageBase + dataoff;
 
-  /* Dump the EDT first first */
+  /* Dump the EDT first */
   fprintf (file,
           _("\nThe Export Tables (interpreted %s section contents)\n\n"),
           section->name);
@@ -1481,7 +1518,8 @@ pe_print_edata (abfd, vfile)
   /* The next table to find is the Export Address Table. It's basically
      a list of pointers that either locate a function in this dll, or
      forward the call to another dll. Something like:
-      typedef union {
+      typedef union
+      {
         long export_rva;
         long forwarder_rva;
       } export_address_table_entry;
@@ -1546,7 +1584,7 @@ pe_print_edata (abfd, vfile)
 
   free (data);
 
-  return true;
+  return TRUE;
 }
 
 /* This really is architecture dependent.  On IA-64, a .pdata entry
@@ -1554,7 +1592,7 @@ pe_print_edata (abfd, vfile)
    specify the start and end address of the code range the entry
    covers and the address of the corresponding unwind info data.  */
 
-static boolean
+static bfd_boolean
 pe_print_pdata (abfd, vfile)
      bfd *abfd;
      PTR vfile;
@@ -1575,7 +1613,7 @@ pe_print_pdata (abfd, vfile)
   if (section == NULL
       || coff_section_data (abfd, section) == NULL
       || pei_section_data (abfd, section) == NULL)
-    return true;
+    return TRUE;
 
   stop = pei_section_data (abfd, section)->virt_size;
   if ((stop % onaline) != 0)
@@ -1589,24 +1627,21 @@ pe_print_pdata (abfd, vfile)
   fprintf (file,
           _(" vma:\t\t\tBegin Address    End Address      Unwind Info\n"));
 #else
-  fprintf (file,
-          _(" vma:\t\tBegin    End      EH       EH       PrologEnd  Exception\n"));
-  fprintf (file,
-          _("     \t\tAddress  Address  Handler  Data     Address    Mask\n"));
+  fprintf (file, _("\
+ vma:\t\tBegin    End      EH       EH       PrologEnd  Exception\n\
+     \t\tAddress  Address  Handler  Data     Address    Mask\n"));
 #endif
 
-  if (bfd_section_size (abfd, section) == 0)
-    return true;
-
-  data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section));
   datasize = bfd_section_size (abfd, section);
+  if (datasize == 0)
+    return TRUE;
+
+  data = (bfd_byte *) bfd_malloc (datasize);
   if (data == NULL && datasize != 0)
-    return false;
+    return FALSE;
 
-  bfd_get_section_contents (abfd,
-                           section,
-                           (PTR) data, 0,
-                           bfd_section_size (abfd, section));
+  bfd_get_section_contents (abfd, section, (PTR) data, (bfd_vma) 0,
+                           datasize);
 
   start = 0;
 
@@ -1630,10 +1665,8 @@ pe_print_pdata (abfd, vfile)
 
       if (begin_addr == 0 && end_addr == 0 && eh_handler == 0
          && eh_data == 0 && prolog_end_addr == 0)
-       {
-         /* We are probably into the padding of the section now.  */
-         break;
-       }
+       /* We are probably into the padding of the section now.  */
+       break;
 
       em_data = ((eh_handler & 0x1) << 2) | (prolog_end_addr & 0x3);
       eh_handler &= ~(bfd_vma) 0x3;
@@ -1682,27 +1715,28 @@ pe_print_pdata (abfd, vfile)
 
   free (data);
 
-  return true;
+  return TRUE;
 }
 
 #define IMAGE_REL_BASED_HIGHADJ 4
-static const char * const tbl[] = {
-  "ABSOLUTE",
-  "HIGH",
-  "LOW",
-  "HIGHLOW",
-  "HIGHADJ",
-  "MIPS_JMPADDR",
-  "SECTION",
-  "REL32",
-  "RESERVED1",
-  "MIPS_JMPADDR16",
-  "DIR64",
-  "HIGH3ADJ"
-  "UNKNOWN",   /* MUST be last */
-};
-
-static boolean
+static const char * const tbl[] =
+  {
+    "ABSOLUTE",
+    "HIGH",
+    "LOW",
+    "HIGHLOW",
+    "HIGHADJ",
+    "MIPS_JMPADDR",
+    "SECTION",
+    "REL32",
+    "RESERVED1",
+    "MIPS_JMPADDR16",
+    "DIR64",
+    "HIGH3ADJ"
+    "UNKNOWN",   /* MUST be last */
+  };
+
+static bfd_boolean
 pe_print_reloc (abfd, vfile)
      bfd *abfd;
      PTR vfile;
@@ -1710,28 +1744,26 @@ pe_print_reloc (abfd, vfile)
   FILE *file = (FILE *) vfile;
   bfd_byte *data = 0;
   asection *section = bfd_get_section_by_name (abfd, ".reloc");
-  bfd_size_type datasize = 0;
+  bfd_size_type datasize;
   bfd_size_type i;
   bfd_size_type start, stop;
 
   if (section == NULL)
-    return true;
+    return TRUE;
 
   if (bfd_section_size (abfd, section) == 0)
-    return true;
+    return TRUE;
 
   fprintf (file,
           _("\n\nPE File Base Relocations (interpreted .reloc section contents)\n"));
 
-  data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section));
   datasize = bfd_section_size (abfd, section);
+  data = (bfd_byte *) bfd_malloc (datasize);
   if (data == NULL && datasize != 0)
-    return false;
+    return FALSE;
 
-  bfd_get_section_contents (abfd,
-                           section,
-                           (PTR) data, 0,
-                           bfd_section_size (abfd, section));
+  bfd_get_section_contents (abfd, section, (PTR) data, (bfd_vma) 0,
+                           datasize);
 
   start = 0;
 
@@ -1744,16 +1776,13 @@ pe_print_reloc (abfd, vfile)
       long number, size;
 
       /* The .reloc section is a sequence of blocks, with a header consisting
-        of two 32 bit quantities, followed by a number of 16 bit entries */
-
+        of two 32 bit quantities, followed by a number of 16 bit entries.  */
       virtual_address = bfd_get_32 (abfd, data+i);
       size = bfd_get_32 (abfd, data+i+4);
       number = (size - 8) / 2;
 
       if (size == 0)
-       {
-         break;
-       }
+       break;
 
       fprintf (file,
               _("\nVirtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n"),
@@ -1784,17 +1813,18 @@ pe_print_reloc (abfd, vfile)
 
          fprintf (file, "\n");
        }
+
       i += size;
     }
 
   free (data);
 
-  return true;
+  return TRUE;
 }
 
 /* Print out the program headers.  */
 
-boolean
+bfd_boolean
 _bfd_XX_print_private_bfd_data_common (abfd, vfile)
      bfd *abfd;
      PTR vfile;
@@ -1811,20 +1841,24 @@ _bfd_XX_print_private_bfd_data_common (abfd, vfile)
   fprintf (file, _("\nCharacteristics 0x%x\n"), pe->real_flags);
 #undef PF
 #define PF(x, y) if (pe->real_flags & x) { fprintf (file, "\t%s\n", y); }
-  PF (F_RELFLG, "relocations stripped");
-  PF (F_EXEC, "executable");
-  PF (F_LNNO, "line numbers stripped");
-  PF (F_LSYMS, "symbols stripped");
-  PF (0x80, "little endian");
-  PF (F_AR32WR, "32 bit words");
-  PF (0x200, "debugging information removed");
-  PF (0x1000, "system file");
-  PF (F_DLL, "DLL");
-  PF (0x8000, "big endian");
+  PF (IMAGE_FILE_RELOCS_STRIPPED, "relocations stripped");
+  PF (IMAGE_FILE_EXECUTABLE_IMAGE, "executable");
+  PF (IMAGE_FILE_LINE_NUMS_STRIPPED, "line numbers stripped");
+  PF (IMAGE_FILE_LOCAL_SYMS_STRIPPED, "symbols stripped");
+  PF (IMAGE_FILE_LARGE_ADDRESS_AWARE, "large address aware");
+  PF (IMAGE_FILE_BYTES_REVERSED_LO, "little endian");
+  PF (IMAGE_FILE_32BIT_MACHINE, "32 bit words");
+  PF (IMAGE_FILE_DEBUG_STRIPPED, "debugging information removed");
+  PF (IMAGE_FILE_SYSTEM, "system file");
+  PF (IMAGE_FILE_DLL, "DLL");
+  PF (IMAGE_FILE_BYTES_REVERSED_HI, "big endian");
 #undef PF
 
   /* ctime implies '\n'.  */
-  fprintf (file, "\nTime/Date\t\t%s", ctime (&pe->coff.timestamp));
+  {
+    time_t t = pe->coff.timestamp;
+    fprintf (file, "\nTime/Date\t\t%s", ctime (&t));
+  }
   fprintf (file, "\nImageBase\t\t");
   fprintf_vma (file, i->ImageBase);
   fprintf (file, "\nSectionAlignment\t");
@@ -1841,6 +1875,7 @@ _bfd_XX_print_private_bfd_data_common (abfd, vfile)
   fprintf (file, "SizeOfImage\t\t%08lx\n", i->SizeOfImage);
   fprintf (file, "SizeOfHeaders\t\t%08lx\n", i->SizeOfHeaders);
   fprintf (file, "CheckSum\t\t%08lx\n", i->CheckSum);
+
   switch (i->Subsystem)
     {
     case IMAGE_SUBSYSTEM_UNKNOWN:
@@ -1871,6 +1906,7 @@ _bfd_XX_print_private_bfd_data_common (abfd, vfile)
       subsystem_name = "EFI runtime driver";
       break;
     }
+
   fprintf (file, "Subsystem\t\t%08x", i->Subsystem);
   if (subsystem_name)
     fprintf (file, "\t(%s)", subsystem_name);
@@ -1900,36 +1936,37 @@ _bfd_XX_print_private_bfd_data_common (abfd, vfile)
   pe_print_pdata (abfd, vfile);
   pe_print_reloc (abfd, vfile);
 
-  return true;
+  return TRUE;
 }
 
 /* Copy any private info we understand from the input bfd
    to the output bfd.  */
 
-boolean
+bfd_boolean
 _bfd_XX_bfd_copy_private_bfd_data_common (ibfd, obfd)
      bfd *ibfd, *obfd;
 {
   /* One day we may try to grok other private data.  */
   if (ibfd->xvec->flavour != bfd_target_coff_flavour
       || obfd->xvec->flavour != bfd_target_coff_flavour)
-    return true;
+    return TRUE;
 
   pe_data (obfd)->pe_opthdr = pe_data (ibfd)->pe_opthdr;
   pe_data (obfd)->dll = pe_data (ibfd)->dll;
 
-  /* for strip: if we removed .reloc, we'll make a real mess of things
+  /* For strip: if we removed .reloc, we'll make a real mess of things
      if we don't remove this entry as well.  */
   if (! pe_data (obfd)->has_reloc_section)
     {
       pe_data (obfd)->pe_opthdr.DataDirectory[5].VirtualAddress = 0;
       pe_data (obfd)->pe_opthdr.DataDirectory[5].Size = 0;
     }
-  return true;
+  return TRUE;
 }
 
 /* Copy private section data.  */
-boolean
+
+bfd_boolean
 _bfd_XX_bfd_copy_private_section_data (ibfd, isec, obfd, osec)
      bfd *ibfd;
      asection *isec;
@@ -1938,32 +1975,34 @@ _bfd_XX_bfd_copy_private_section_data (ibfd, isec, obfd, osec)
 {
   if (bfd_get_flavour (ibfd) != bfd_target_coff_flavour
       || bfd_get_flavour (obfd) != bfd_target_coff_flavour)
-    return true;
+    return TRUE;
 
   if (coff_section_data (ibfd, isec) != NULL
       && pei_section_data (ibfd, isec) != NULL)
     {
       if (coff_section_data (obfd, osec) == NULL)
        {
-         osec->used_by_bfd =
-           (PTR) bfd_zalloc (obfd, sizeof (struct coff_section_tdata));
+         bfd_size_type amt = sizeof (struct coff_section_tdata);
+         osec->used_by_bfd = (PTR) bfd_zalloc (obfd, amt);
          if (osec->used_by_bfd == NULL)
-           return false;
+           return FALSE;
        }
+
       if (pei_section_data (obfd, osec) == NULL)
        {
-         coff_section_data (obfd, osec)->tdata =
-           (PTR) bfd_zalloc (obfd, sizeof (struct pei_section_tdata));
+         bfd_size_type amt = sizeof (struct pei_section_tdata);
+         coff_section_data (obfd, osec)->tdata = (PTR) bfd_zalloc (obfd, amt);
          if (coff_section_data (obfd, osec)->tdata == NULL)
-           return false;
+           return FALSE;
        }
+
       pei_section_data (obfd, osec)->virt_size =
        pei_section_data (ibfd, isec)->virt_size;
       pei_section_data (obfd, osec)->pe_flags =
        pei_section_data (ibfd, isec)->pe_flags;
     }
 
-  return true;
+  return TRUE;
 }
 
 void
@@ -1986,7 +2025,7 @@ _bfd_XX_get_symbol_info (abfd, symbol, ret)
 /* Handle the .idata section and other things that need symbol table
    access.  */
 
-boolean
+bfd_boolean
 _bfd_XXi_final_link_postscript (abfd, pfinfo)
      bfd *abfd;
      struct coff_final_link_info *pfinfo;
@@ -2003,7 +2042,7 @@ _bfd_XXi_final_link_postscript (abfd, pfinfo)
   /* The import directory.  This is the address of .idata$2, with size
      of .idata$2 + .idata$3.  */
   h1 = coff_link_hash_lookup (coff_hash_table (info),
-                             ".idata$2", false, false, true);
+                             ".idata$2", FALSE, FALSE, TRUE);
   if (h1 != NULL)
     {
       pe_data (abfd)->pe_opthdr.DataDirectory[1].VirtualAddress =
@@ -2011,7 +2050,7 @@ _bfd_XXi_final_link_postscript (abfd, pfinfo)
         + h1->root.u.def.section->output_section->vma
         + h1->root.u.def.section->output_offset);
       h1 = coff_link_hash_lookup (coff_hash_table (info),
-                                 ".idata$4", false, false, true);
+                                 ".idata$4", FALSE, FALSE, TRUE);
       pe_data (abfd)->pe_opthdr.DataDirectory[1].Size =
        ((h1->root.u.def.value
          + h1->root.u.def.section->output_section->vma
@@ -2021,22 +2060,34 @@ _bfd_XXi_final_link_postscript (abfd, pfinfo)
       /* The import address table.  This is the size/address of
          .idata$5.  */
       h1 = coff_link_hash_lookup (coff_hash_table (info),
-                                 ".idata$5", false, false, true);
+                                 ".idata$5", FALSE, FALSE, TRUE);
       pe_data (abfd)->pe_opthdr.DataDirectory[12].VirtualAddress =
        (h1->root.u.def.value
         + h1->root.u.def.section->output_section->vma
         + h1->root.u.def.section->output_offset);
       h1 = coff_link_hash_lookup (coff_hash_table (info),
-                                 ".idata$6", false, false, true);
+                                 ".idata$6", FALSE, FALSE, TRUE);
       pe_data (abfd)->pe_opthdr.DataDirectory[12].Size =
        ((h1->root.u.def.value
          + h1->root.u.def.section->output_section->vma
          + h1->root.u.def.section->output_offset)
-        - pe_data (abfd)->pe_opthdr.DataDirectory[12].VirtualAddress);
+        - pe_data (abfd)->pe_opthdr.DataDirectory[12].VirtualAddress);      
+    }
+
+  h1 = coff_link_hash_lookup (coff_hash_table (info),
+                             "__tls_used", FALSE, FALSE, TRUE);
+  if (h1 != NULL)
+    {
+      pe_data (abfd)->pe_opthdr.DataDirectory[9].VirtualAddress =
+       (h1->root.u.def.value
+        + h1->root.u.def.section->output_section->vma
+        + h1->root.u.def.section->output_offset
+        - pe_data (abfd)->pe_opthdr.ImageBase);
+      pe_data (abfd)->pe_opthdr.DataDirectory[9].Size = 0x18;
     }
 
   /* If we couldn't find idata$2, we either have an excessively
      trivial program or are in DEEP trouble; we have to assume trivial
      program....  */
-  return true;
+  return TRUE;
 }
This page took 0.050746 seconds and 4 git commands to generate.