bfd/
[deliverable/binutils-gdb.git] / bfd / peXXigen.c
index 0e1eaeac53610e93caa44a5029cff4e9628236b2..d7a2991690b9b2aab8397babca1909ac44095add 100644 (file)
@@ -1,29 +1,28 @@
 /* Support for the generic parts of PE/PEI; the common executable parts.
-   Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001
-   Free Software Foundation, Inc.
+   Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+   2005, 2006 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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, 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]!
 
@@ -51,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+.  */
@@ -90,19 +88,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
    the code is in peigen.c.  PowerPC NT is said to be dead.  If
    anybody wants to revive the code, you will have to figure out how
    to handle those issues.  */
-
-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));
-
-/**********************************************************************/
-
+\f
 void
-_bfd_XXi_swap_sym_in (abfd, ext1, in1)
-     bfd *abfd;
-     PTR ext1;
-     PTR in1;
+_bfd_XXi_swap_sym_in (bfd * abfd, void * ext1, void * in1)
 {
   SYMENT *ext = (SYMENT *) ext1;
   struct internal_syment *in = (struct internal_syment *) in1;
@@ -110,26 +98,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.  */
@@ -144,28 +127,11 @@ _bfd_XXi_swap_sym_in (abfd, ext1, in1)
     {
       in->n_value = 0x0;
 
-#if 0
-      /* FIXME: This is clearly wrong.  The problem seems to be that
-         undefined C_SECTION symbols appear in the first object of a
-         MS generated .lib file, and the symbols are not defined
-         anywhere.  */
-      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 0
-      if (strcmp (in->_n._n_name, ".idata$4") == 0)
-       in->n_scnum = 3;
-      else
-       in->n_scnum = 2;
-#endif
-#else
       /* Create synthetic empty sections as needed.  DJ */
       if (in->n_scnum == 0)
        {
          asection *sec;
+
          for (sec = abfd->sections; sec; sec = sec->next)
            {
              if (strcmp (sec->name, in->n_name) == 0)
@@ -175,42 +141,42 @@ _bfd_XXi_swap_sym_in (abfd, ext1, in1)
                }
            }
        }
+
       if (in->n_scnum == 0)
        {
          int unused_section_number = 0;
          asection *sec;
          char *name;
+         flagword flags;
+
          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);
-         sec = bfd_make_section_anyway (abfd, name);
+         flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_DATA | SEC_LOAD;
+         sec = bfd_make_section_anyway_with_flags (abfd, name, flags);
 
          sec->vma = 0;
          sec->lma = 0;
-         sec->_cooked_size = 0;
-         sec->_raw_size = 0;
+         sec->size = 0;
          sec->filepos = 0;
          sec->rel_filepos = 0;
          sec->reloc_count = 0;
          sec->line_filepos = 0;
          sec->lineno_count = 0;
          sec->userdata = NULL;
-         sec->next = (asection *) NULL;
-         sec->flags = 0;
+         sec->next = NULL;
          sec->alignment_power = 2;
-         sec->flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_DATA | SEC_LOAD;
 
          sec->target_index = unused_section_number;
 
          in->n_scnum = unused_section_number;
        }
       in->n_sclass = C_STAT;
-#endif
     }
 #endif
 
@@ -222,48 +188,41 @@ _bfd_XXi_swap_sym_in (abfd, ext1, in1)
 }
 
 unsigned int
-_bfd_XXi_swap_sym_out (abfd, inp, extp)
-     bfd       *abfd;
-     PTR       inp;
-     PTR       extp;
+_bfd_XXi_swap_sym_out (bfd * abfd, void * inp, void * 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;
 }
 
 void
-_bfd_XXi_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1)
-     bfd            *abfd;
-     PTR            ext1;
-     int             type;
-     int             class;
-     int            indx ATTRIBUTE_UNUSED;
-     int            numaux ATTRIBUTE_UNUSED;
-     PTR            in1;
+_bfd_XXi_swap_aux_in (bfd *    abfd,
+                     void *    ext1,
+                     int       type,
+                     int       class,
+                     int       indx ATTRIBUTE_UNUSED,
+                     int       numaux ATTRIBUTE_UNUSED,
+                     void *    in1)
 {
   AUXENT *ext = (AUXENT *) ext1;
   union internal_auxent *in = (union internal_auxent *) in1;
@@ -274,13 +233,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:
@@ -291,19 +247,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))
     {
@@ -313,19 +266,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
     {
@@ -335,33 +287,30 @@ _bfd_XXi_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1)
 }
 
 unsigned int
-_bfd_XXi_swap_aux_out (abfd, inp, type, class, indx, numaux, extp)
-     bfd  *abfd;
-     PTR   inp;
-     int   type;
-     int   class;
-     int   indx ATTRIBUTE_UNUSED;
-     int   numaux ATTRIBUTE_UNUSED;
-     PTR   extp;
+_bfd_XXi_swap_aux_out (bfd *  abfd,
+                      void * inp,
+                      int    type,
+                      int    class,
+                      int    indx ATTRIBUTE_UNUSED,
+                      int    numaux ATTRIBUTE_UNUSED,
+                      void * extp)
 {
   union internal_auxent *in = (union internal_auxent *) inp;
   AUXENT *ext = (AUXENT *) extp;
 
-  memset ((PTR) ext, 0, AUXESZ);
+  memset (ext, 0, AUXESZ);
+
   switch (class)
     {
     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:
@@ -372,19 +321,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))
     {
@@ -393,19 +339,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);
@@ -416,101 +361,92 @@ _bfd_XXi_swap_aux_out (abfd, inp, type, class, indx, numaux, extp)
 }
 
 void
-_bfd_XXi_swap_lineno_in (abfd, ext1, in1)
-     bfd *abfd;
-     PTR ext1;
-     PTR in1;
+_bfd_XXi_swap_lineno_in (bfd * abfd, void * ext1, void * 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);
 }
 
 unsigned int
-_bfd_XXi_swap_lineno_out (abfd, inp, outp)
-     bfd       *abfd;
-     PTR       inp;
-     PTR       outp;
+_bfd_XXi_swap_lineno_out (bfd * abfd, void * inp, void * 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;
 }
 
 void
-_bfd_XXi_swap_aouthdr_in (abfd, aouthdr_ext1, aouthdr_int1)
-     bfd *abfd;
-     PTR aouthdr_ext1;
-     PTR aouthdr_int1;
+_bfd_XXi_swap_aouthdr_in (bfd * abfd,
+                         void * aouthdr_ext1,
+                         void * aouthdr_int1)
 {
   struct internal_extra_pe_aouthdr *a;
-  PEAOUTHDR *src = (PEAOUTHDR *) (aouthdr_ext1);
-  AOUTHDR        *aouthdr_ext = (AOUTHDR *) aouthdr_ext1;
+  PEAOUTHDR * src = (PEAOUTHDR *) (aouthdr_ext1);
+  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! */
+  /* 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;
       }
@@ -523,6 +459,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;
@@ -530,8 +467,9 @@ _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! */
+  /* PE32+ does not have data_start member!  */
   if (aouthdr_int->dsize)
     {
       aouthdr_int->data_start += a->ImageBase;
@@ -547,27 +485,25 @@ _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.  */
 
 static void
-add_data_entry (abfd, aout, idx, name, base)
-     bfd *abfd;
-     struct internal_extra_pe_aouthdr *aout;
-     int idx;
-     char *name;
-     bfd_vma base;
+add_data_entry (bfd * abfd,
+               struct internal_extra_pe_aouthdr *aout,
+               int idx,
+               char *name,
+               bfd_vma 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;
 
@@ -581,17 +517,15 @@ add_data_entry (abfd, aout, idx, name, base)
 }
 
 unsigned int
-_bfd_XXi_swap_aouthdr_out (abfd, in, out)
-     bfd       *abfd;
-     PTR       in;
-     PTR       out;
+_bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
 {
   struct internal_aouthdr *aouthdr_in = (struct internal_aouthdr *) in;
   pe_data_type *pe = pe_data (abfd);
   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)
@@ -607,6 +541,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;
@@ -614,6 +552,7 @@ _bfd_XXi_swap_aouthdr_out (abfd, in, out)
       aouthdr_in->text_start &= 0xffffffff;
 #endif
     }
+
   if (aouthdr_in->dsize)
     {
       aouthdr_in->data_start -= ib;
@@ -621,6 +560,7 @@ _bfd_XXi_swap_aouthdr_out (abfd, in, out)
       aouthdr_in->data_start &= 0xffffffff;
 #endif
     }
+
   if (aouthdr_in->entry)
     {
       aouthdr_in->entry -= ib;
@@ -633,28 +573,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),
@@ -665,14 +612,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);
+       int rounded = FA (sec->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)
@@ -682,88 +634,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]);
       }
   }
 
@@ -771,10 +713,7 @@ _bfd_XXi_swap_aouthdr_out (abfd, in, out)
 }
 
 unsigned int
-_bfd_XXi_only_swap_filehdr_out (abfd, in, out)
-     bfd       *abfd;
-     PTR       in;
-     PTR       out;
+_bfd_XXi_only_swap_filehdr_out (bfd * abfd, void * in, void * out)
 {
   int idx;
   struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in;
@@ -832,93 +771,74 @@ _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;
 }
 
 unsigned int
-_bfd_XX_only_swap_filehdr_out (abfd, in, out)
-     bfd       *abfd;
-     PTR       in;
-     PTR       out;
+_bfd_XX_only_swap_filehdr_out (bfd * abfd, void * in, void * 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;
 }
 
 unsigned int
-_bfd_XXi_swap_scnhdr_out (abfd, in, out)
-     bfd       *abfd;
-     PTR       in;
-     PTR       out;
+_bfd_XXi_swap_scnhdr_out (bfd * abfd, void * in, void * out)
 {
   struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
   SCNHDR *scnhdr_ext = (SCNHDR *) out;
@@ -932,111 +852,158 @@ _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);
-#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);
-         ret = 0;
-#endif
+         H_PUT_32 (abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags);
        }
     }
   return ret;
 }
 
-static char * dir_names[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] = {
+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]"),
@@ -1055,7 +1022,6 @@ static char * dir_names[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] = {
   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
@@ -1064,11 +1030,8 @@ static char * dir_names[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] = {
    PPC- specific code.  */
 #endif
 
-/**********************************************************************/
-static boolean
-pe_print_idata (abfd, vfile)
-     bfd *abfd;
-     PTR vfile;
+static bfd_boolean
+pe_print_idata (bfd * abfd, void * vfile)
 {
   FILE *file = (FILE *) vfile;
   bfd_byte *data;
@@ -1096,19 +1059,19 @@ 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);
+      datasize = section->size;
       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);
+         datasize = section->size;
          if (addr >= section->vma && addr < section->vma + datasize)
            break;
        }
@@ -1117,7 +1080,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;
        }
     }
 
@@ -1128,7 +1091,7 @@ pe_print_idata (abfd, vfile)
   datasize -= dataoff;
 
 #ifdef POWERPC_LE_PE
-  if (rel_section != 0 && bfd_section_size (abfd, rel_section) != 0)
+  if (rel_section != 0 && rel_section->size != 0)
     {
       /* The toc address can be found by taking the starting address,
         which on the PPC locates a function descriptor. The
@@ -1140,21 +1103,25 @@ pe_print_idata (abfd, vfile)
       bfd_vma loadable_toc_address;
       bfd_vma toc_address;
       bfd_vma start_address;
-      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;
+      bfd_byte *data;
+      bfd_vma offset;
 
-      bfd_get_section_contents (abfd,
-                               rel_section,
-                               (PTR) data, 0,
-                               bfd_section_size (abfd, rel_section));
+      if (!bfd_malloc_and_get_section (abfd, rel_section, &data))
+       {
+         if (data != NULL)
+           free (data);
+         return FALSE;
+       }
 
       offset = abfd->start_address - rel_section->vma;
 
+      if (offset >= rel_section->size || offset + 8 > rel_section->size)
+        {
+          if (data != NULL)
+            free (data);
+          return FALSE;
+        }
+
       start_address = bfd_get_32 (abfd, data + offset);
       loadable_toc_address = bfd_get_32 (abfd, data + offset + 4);
       toc_address = loadable_toc_address - 32768;
@@ -1165,6 +1132,8 @@ pe_print_idata (abfd, vfile)
       fprintf (file,
               _("\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n"),
               start_address, loadable_toc_address, toc_address);
+      if (data != NULL)
+       free (data);
     }
   else
     {
@@ -1177,21 +1146,21 @@ 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"));
-
-  data = (bfd_byte *) bfd_malloc (dataoff + datasize);
-  if (data == NULL)
-    return false;
+          _("\
+ vma:            Hint    Time      Forward  DLL       First\n\
+                 Table   Stamp     Chain    Name      Thunk\n"));
 
   /* 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_malloc_and_get_section (abfd, section, &data))
+    {
+      if (data != NULL)
+       free (data);
+      return FALSE;
+    }
 
   adj = section->vma - extra->ImageBase;
 
+  /* Print all image import descriptors.  */
   for (i = 0; i < datasize; i += onaline)
     {
       bfd_vma hint_addr;
@@ -1203,15 +1172,8 @@ 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 (i + 20 > datasize)
-       {
-         /* Check stuff.  */
-         ;
-       }
-
       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);
@@ -1228,24 +1190,89 @@ pe_print_idata (abfd, vfile)
       if (hint_addr == 0 && first_thunk == 0)
        break;
 
+      if (dll_name - adj >= section->size)
+        break;
+
       dll = (char *) data + dll_name - adj;
       fprintf (file, _("\n\tDLL Name: %s\n"), dll);
 
       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 = ft_section->size;
+                 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_malloc (datasize);
+                 if (ft_data == NULL)
+                   continue;
+
+                 /* Read datasize bfd_bytes starting at offset ft_idx.  */
+                 if (! bfd_get_section_contents
+                     (abfd, ft_section, 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;
@@ -1258,108 +1285,51 @@ 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
-pe_print_edata (abfd, vfile)
-     bfd *abfd;
-     PTR vfile;
+static bfd_boolean
+pe_print_edata (bfd * abfd, void * 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);
@@ -1374,44 +1344,50 @@ 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);
+      dataoff = 0;
+      datasize = section->size;
       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;
-       }
+       if (addr >= section->vma && addr < section->vma + section->size)
+         break;
 
       if (section == NULL)
        {
          fprintf (file,
                   _("\nThere is an export table, but the section containing it could not be found\n"));
-         return true;
+         return TRUE;
+       }
+
+      dataoff = addr - section->vma;
+      datasize = extra->DataDirectory[0].Size;
+      if (datasize > section->size - dataoff)
+       {
+         fprintf (file,
+                  _("\nThere is an export table in %s, but it does not fit into that section\n"),
+                  section->name);
+         return TRUE;
        }
     }
 
   fprintf (file, _("\nThere is an export table in %s at 0x%lx\n"),
           section->name, (unsigned long) addr);
 
-  dataoff = addr - section->vma;
-  datasize -= dataoff;
-
-  data = (bfd_byte *) bfd_malloc (datasize);
+  data = 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, data,
+                                 (file_ptr) dataoff, datasize))
+    return FALSE;
 
   /* Go get Export Directory Table.  */
   edt.export_flags   = bfd_get_32 (abfd, data +  0);
@@ -1428,7 +1404,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);
@@ -1482,11 +1458,11 @@ 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;
-  */
+      } export_address_table_entry;  */
 
   fprintf (file,
          _("\nExport Address Table -- Ordinal Base %ld\n"),
@@ -1547,7 +1523,7 @@ pe_print_edata (abfd, vfile)
 
   free (data);
 
-  return true;
+  return TRUE;
 }
 
 /* This really is architecture dependent.  On IA-64, a .pdata entry
@@ -1555,10 +1531,8 @@ 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
-pe_print_pdata (abfd, vfile)
-     bfd *abfd;
-     PTR vfile;
+static bfd_boolean
+pe_print_pdata (bfd * abfd, void * vfile)
 {
 #ifdef COFF_WITH_pep
 # define PDATA_ROW_SIZE        (3*8)
@@ -1576,7 +1550,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)
@@ -1590,24 +1564,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 (data == NULL && datasize != 0)
-    return false;
+  datasize = section->size;
+  if (datasize == 0)
+    return TRUE;
 
-  bfd_get_section_contents (abfd,
-                           section,
-                           (PTR) data, 0,
-                           bfd_section_size (abfd, section));
+  if (! bfd_malloc_and_get_section (abfd, section, &data))
+    {
+      if (data != NULL)
+       free (data);
+      return FALSE;
+    }
 
   start = 0;
 
@@ -1631,10 +1602,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;
@@ -1656,12 +1625,12 @@ pe_print_pdata (abfd, vfile)
       if (eh_handler == 0 && eh_data != 0)
        {
          /* Special bits here, although the meaning may be a little
-            mysterious. The only one I know for sure is 0x03.  */
-         /* Code Significance                           */
-         /* 0x00 None                                   */
-         /* 0x01 Register Save Millicode                */
-         /* 0x02 Register Restore Millicode             */
-         /* 0x03 Glue Code Sequence                     */
+            mysterious. The only one I know for sure is 0x03
+            Code Significance
+            0x00 None
+            0x01 Register Save Millicode
+            0x02 Register Restore Millicode
+            0x03 Glue Code Sequence.  */
          switch (eh_data)
            {
            case 0x01:
@@ -1683,11 +1652,12 @@ pe_print_pdata (abfd, vfile)
 
   free (data);
 
-  return true;
+  return TRUE;
 }
 
 #define IMAGE_REL_BASED_HIGHADJ 4
-static const char * const tbl[] = {
+static const char * const tbl[] =
+{
   "ABSOLUTE",
   "HIGH",
   "LOW",
@@ -1699,44 +1669,40 @@ static const char * const tbl[] = {
   "RESERVED1",
   "MIPS_JMPADDR16",
   "DIR64",
-  "HIGH3ADJ"
-  "UNKNOWN",   /* MUST be last */
+  "HIGH3ADJ",
+  "UNKNOWN",   /* MUST be last */
 };
 
-static boolean
-pe_print_reloc (abfd, vfile)
-     bfd *abfd;
-     PTR vfile;
+static bfd_boolean
+pe_print_reloc (bfd * abfd, void * 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;
+  if (section->size == 0)
+    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);
-  if (data == NULL && datasize != 0)
-    return false;
-
-  bfd_get_section_contents (abfd,
-                           section,
-                           (PTR) data, 0,
-                           bfd_section_size (abfd, section));
+  datasize = section->size;
+  if (! bfd_malloc_and_get_section (abfd, section, &data))
+    {
+      if (data != NULL)
+       free (data);
+      return FALSE;
+    }
 
   start = 0;
 
-  stop = bfd_section_size (abfd, section);
+  stop = section->size;
 
   for (i = start; i < stop;)
     {
@@ -1745,16 +1711,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"),
@@ -1785,20 +1748,19 @@ pe_print_reloc (abfd, vfile)
 
          fprintf (file, "\n");
        }
+
       i += size;
     }
 
   free (data);
 
-  return true;
+  return TRUE;
 }
 
 /* Print out the program headers.  */
 
-boolean
-_bfd_XX_print_private_bfd_data_common (abfd, vfile)
-     bfd *abfd;
-     PTR vfile;
+bfd_boolean
+_bfd_XX_print_private_bfd_data_common (bfd * abfd, void * vfile)
 {
   FILE *file = (FILE *) vfile;
   int j;
@@ -1812,20 +1774,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");
@@ -1842,6 +1808,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:
@@ -1872,6 +1839,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);
@@ -1901,96 +1869,84 @@ _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_XX_bfd_copy_private_bfd_data_common (ibfd, obfd)
-     bfd *ibfd, *obfd;
+bfd_boolean
+_bfd_XX_bfd_copy_private_bfd_data_common (bfd * ibfd, bfd * 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_XX_bfd_copy_private_section_data (ibfd, isec, obfd, osec)
-     bfd *ibfd;
-     asection *isec;
-     bfd *obfd;
-     asection *osec;
+
+bfd_boolean
+_bfd_XX_bfd_copy_private_section_data (bfd *ibfd,
+                                      asection *isec,
+                                      bfd *obfd,
+                                      asection *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 = 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 = 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
-_bfd_XX_get_symbol_info (abfd, symbol, ret)
-     bfd *abfd;
-     asymbol *symbol;
-     symbol_info *ret;
+_bfd_XX_get_symbol_info (bfd * abfd, asymbol *symbol, symbol_info *ret)
 {
   coff_get_symbol_info (abfd, symbol, ret);
-#if 0 /* This code no longer appears to be necessary.
-        ImageBase has already been added in by coff_swap_scnhdr_in.  */
-  if (pe_data (abfd) != NULL
-      && ((symbol->flags & BSF_DEBUGGING) == 0
-         || (symbol->flags & BSF_DEBUGGING_RELOC) != 0)
-      && ! bfd_is_abs_section (symbol->section))
-    ret->value += pe_data (abfd)->pe_opthdr.ImageBase;
-#endif
 }
 
 /* Handle the .idata section and other things that need symbol table
    access.  */
 
-boolean
-_bfd_XXi_final_link_postscript (abfd, pfinfo)
-     bfd *abfd;
-     struct coff_final_link_info *pfinfo;
+bfd_boolean
+_bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
 {
   struct coff_link_hash_entry *h1;
   struct bfd_link_info *info = pfinfo->info;
@@ -2004,7 +1960,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 =
@@ -2012,7 +1968,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
@@ -2022,22 +1978,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.050043 seconds and 4 git commands to generate.