Tue Aug 29 13:50:21 1995 steve chamberlain <sac@slash.cygnus.com>
authorSteve Chamberlain <sac@cygnus>
Tue, 29 Aug 1995 21:05:59 +0000 (21:05 +0000)
committerSteve Chamberlain <sac@cygnus>
Tue, 29 Aug 1995 21:05:59 +0000 (21:05 +0000)
* libbfd.h, bfd-in2.h: regenerated.
* coff-arm.c (aoutarm_std_relo): New entry at 11.
(arm_reloc_type_lookup) : Understand type 11.
* coff-i386.c (howto_table): fix name of rva type.
(coff-i386_rtype_to_howto): Understand R_IMAGEBASE type.
* coffcode.h (sec_to_styp_flags): .edata is data.
(coff_compute_section_file_positions): Get page size right for PE.
(fill_pe_header_info): Fix fields.
(coff_write_object_contents): Remove end_of_image calc.
(_bfd_coff_generate_reloc_section): Remove orphaned comment.
* coffswap.h (coff_swap_scnhdr_in): Don't always add IMAGE_BASE.
(coff_swap_scnhdr_out): Setup PE flags correctly.
* reloc.c (BFD_RELOC_RVA): New field.

bfd/ChangeLog
bfd/coff-arm.c
bfd/coffcode.h
bfd/cofflink.c
bfd/coffswap.h

index 1a13b00..96f22ac 100644 (file)
@@ -1,3 +1,12 @@
+Tue Aug 29 13:50:21 1995  steve chamberlain  <sac@slash.cygnus.com>
+
+       * bfd-in2.h: regenerated.
+
+Thu Aug 24 17:49:59 1995  Ian Lance Taylor  (ian@cygnus.com)
+
+       * cofflink.c (coff_link_input_bfd): Don't include line numbers for
+       a section if its output section has no contents.
+
 Wed Aug 23 16:48:52 1995  Ian Lance Taylor  (ian@cygnus.com)
 
        * ecoff.c (_bfd_ecoff_slurp_symbolic_info): Add parentheses to FIX
index f9d12b0..3136a8d 100644 (file)
@@ -128,6 +128,10 @@ coff_arm_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
   return bfd_reloc_continue;
 }
 
+#ifndef PCRELOFFSET
+#define PCRELOFFSET true
+#endif
+
 static reloc_howto_type aoutarm_std_reloc_howto[] = 
 {
   /* type              rs size bsz  pcrel bitpos ovrf                     sf name     part_inpl readmask  setmask    pcdone */
@@ -172,7 +176,7 @@ static reloc_howto_type aoutarm_std_reloc_howto[] =
        PCRELOFFSET),
   HOWTO( 3,
        2,
-       3, 
+       2,
        26,
        true,
        0,
@@ -224,7 +228,7 @@ static reloc_howto_type aoutarm_std_reloc_howto[] =
        true),
   HOWTO( 7,  
        2, 
-       3,   
+       2,
        26,
        false,
        0,
@@ -261,7 +265,20 @@ static reloc_howto_type aoutarm_std_reloc_howto[] =
         true,
        0xffffffff,
        0xffffffff,
-       false)
+       false),
+  HOWTO( 11, 
+       0,
+       2, 
+       32,
+       false,
+       0,
+       complain_overflow_bitfield,
+       coff_arm_reloc,
+       "rva32",
+        true,
+       0xffffffff,
+       0xffffffff,
+       PCRELOFFSET),
 };
 
 
@@ -366,6 +383,7 @@ arm_reloc_type_lookup(abfd,code)
       ASTD (BFD_RELOC_8_PCREL, 4);
       ASTD (BFD_RELOC_16_PCREL, 5);
       ASTD (BFD_RELOC_32_PCREL, 6);
+      ASTD (BFD_RELOC_RVA, 11);
     default: return (CONST struct reloc_howto_struct *) 0;
     }
 }
@@ -505,18 +523,10 @@ i3coff_object_p(a)
   return coff_object_p(a);
 }
 
-const bfd_target
-#ifdef TARGET_SYM
-  TARGET_SYM =
-#else
-  armcoff_vec =
-#endif
+#ifdef TARGET_LITTLE_SYM
+const bfd_target TARGET_LITTLE_SYM =
 {
-#ifdef TARGET_NAME
-  TARGET_NAME,
-#else
-  "coff-arm",                  /* name */
-#endif
+  TARGET_LITTLE_NAME,          /* name or coff-arm-little */
   bfd_target_coff_flavour,
   false,                       /* data byte order is little */
   false,                       /* header byte order is little */
@@ -562,3 +572,55 @@ const bfd_target
 
   COFF_SWAP_TABLE,
 };
+#endif
+
+#ifdef TARGET_BIG_SYM
+const bfd_target TARGET_BIG_SYM =
+{
+  TARGET_BIG_NAME,             /* name or coff-arm-big */
+  bfd_target_coff_flavour,
+  true,                                /* data byte order is big */
+  true,                                /* header byte order is big */
+
+  (HAS_RELOC | EXEC_P |                /* object flags */
+   HAS_LINENO | HAS_DEBUG |
+   HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+
+  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+#ifdef TARGET_UNDERSCORE
+  TARGET_UNDERSCORE,           /* leading underscore */
+#else
+  0,                           /* leading underscore */
+#endif
+  '/',                         /* ar_pad_char */
+  15,                          /* ar_max_namelen */
+
+  2,                           /* minimum alignment power */
+  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+     bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+     bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+     bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+     bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
+
+/* Note that we allow an object file to be treated as a core file as well. */
+    {_bfd_dummy_target, i3coff_object_p, /* bfd_check_format */
+       bfd_generic_archive_p, i3coff_object_p},
+    {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
+       bfd_false},
+    {bfd_false, coff_write_object_contents, /* bfd_write_contents */
+       _bfd_write_archive_contents, bfd_false},
+
+     BFD_JUMP_TABLE_GENERIC (coff),
+     BFD_JUMP_TABLE_COPY (coff),
+     BFD_JUMP_TABLE_CORE (_bfd_nocore),
+     BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+     BFD_JUMP_TABLE_SYMBOLS (coff),
+     BFD_JUMP_TABLE_RELOCS (coff),
+     BFD_JUMP_TABLE_WRITE (coff),
+     BFD_JUMP_TABLE_LINK (coff),
+     BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+  COFF_SWAP_TABLE,
+};
+#endif
index f155ce2..d5282e3 100644 (file)
@@ -304,7 +304,9 @@ CODE_FRAGMENT
 
 
 static bfd_vma
-pe_value(bfd_link_pe_info_dval *ptr, bfd_vma def)
+pe_value(ptr, def)
+     bfd_link_pe_info_dval *ptr;
+     bfd_vma def;
 {
   if (ptr && ptr->defined)
     return ptr->value;
@@ -377,6 +379,12 @@ sec_to_styp_flags (sec_name, sec_flags)
     {
       styp_flags = STYP_INFO;
     }
+#ifdef COFF_WITH_PE
+  else if (!strcmp (sec_name, ".edata"))
+    {
+      styp_flags = STYP_DATA;
+    }
+#endif
   /* Try and figure out what it should be */
   else if (sec_flags & SEC_CODE)
     {
@@ -1499,11 +1507,19 @@ coff_compute_section_file_positions (abfd)
   asection *current;
   asection *previous = (asection *) NULL;
   file_ptr sofar = FILHSZ;
+  int page_size;
 #ifndef I960
   file_ptr old_sofar;
 #endif
   unsigned int count;
 
+#ifdef COFF_IMAGE_WITH_PE
+  page_size = pe_value (&(coff_data (abfd)->link_info->pe_info->file_alignment),
+                       PE_DEF_FILE_ALIGNMENT);
+#else
+  page_size = COFF_PAGE_SIZE;
+#endif
+
   if (bfd_get_start_address (abfd))
     {
       /*  A start address may have been added to the original file. In this
@@ -1554,13 +1570,11 @@ coff_compute_section_file_positions (abfd)
 
 #endif
 
-#ifdef COFF_PAGE_SIZE
       /* In demand paged files the low order bits of the file offset
         must match the low order bits of the virtual address.  */
       if ((abfd->flags & D_PAGED) != 0
          && (current->flags & SEC_ALLOC) != 0)
-       sofar += (current->vma - sofar) % COFF_PAGE_SIZE;
-#endif
+       sofar += (current->vma - sofar) % page_size;
 
       current->filepos = sofar;
 
@@ -1582,12 +1596,14 @@ coff_compute_section_file_positions (abfd)
 
       previous = current;
     }
-#ifdef COFF_WITH_PE
+#ifdef COFF_IMAGE_WITH_PE
   /* Normally, the starting location for the symbol table will be at the end
      of the last section.  However, when dealing with NT, the last section
      must be as long as its size rounded up to the next page (0x1000). */
-  sofar = ((sofar + NT_FILE_ALIGNMENT - 1) /
-                           NT_FILE_ALIGNMENT) * NT_FILE_ALIGNMENT; 
+  sofar = (sofar + page_size - 1) & -page_size;
+
+  if (previous)
+    previous->_raw_size = (previous->_raw_size + page_size -1) & -page_size;
 #endif
 
   obj_relocbase (abfd) = sofar;
@@ -1685,19 +1701,22 @@ static void add_data_entry (abfd, aout, idx, name, base)
     {
       aout->pe->DataDirectory[idx].VirtualAddress = sec->lma - base;
       aout->pe->DataDirectory[idx].Size = sec->_raw_size;
+      sec->flags |= SEC_DATA;
     }
 }
 
 
 static void 
-fill_pe_header_info (abfd, internal_f, internal_a, end_of_image)
+fill_pe_header_info (abfd, internal_f, internal_a)
      bfd *abfd;
      struct internal_filehdr *internal_f;
      struct internal_aouthdr *internal_a;
-     bfd_vma end_of_image;
 {
   /* assign other filehdr fields for DOS header and NT signature */
 
+  int sa;
+  int fa;
+  bfd_vma ib;
   bfd_link_pe_info *pe_info = coff_data (abfd)->link_info->pe_info;
 
   internal_f->f_timdat = time (0);
@@ -1714,15 +1733,28 @@ fill_pe_header_info (abfd, internal_f, internal_a, end_of_image)
   memset (internal_a->pe, 0, sizeof (struct internal_extra_pe_aouthdr));
 
 
-  internal_a->pe->ImageBase =  pe_value (&pe_info->image_base, IMAGE_BASE);
+  ib =  internal_a->pe->ImageBase =  pe_value (&pe_info->image_base, NT_EXE_IMAGE_BASE);
 
   if (internal_a->tsize) 
-    internal_a->text_start -= internal_a->pe->ImageBase;
+    internal_a->text_start -= ib;
   if (internal_a->dsize) 
-    internal_a->data_start -= internal_a->pe->ImageBase;
+    internal_a->data_start -= ib;
   if (internal_a->entry) 
-    internal_a->entry -= internal_a->pe->ImageBase;
+    internal_a->entry -= ib;
+
+
+  sa =   internal_a->pe->SectionAlignment = pe_value (&pe_info->section_alignment,
+                                                     NT_SECTION_ALIGNMENT);
+
+  fa =   internal_a->pe->FileAlignment = pe_value (&pe_info->file_alignment, 
+                                                  NT_FILE_ALIGNMENT);
+
+#define FA(x)  (((x) + fa -1 ) & (- fa))
+#define SA(x)  (((x) + sa -1 ) & (- sa))
 
+  /* We like to have the sizes aligned */
+
+  internal_a->bsize = FA (internal_a->bsize);
 
   internal_f->pe->e_magic    = DOSMAGIC;
   internal_f->pe->e_cblp     = 0x90;
@@ -1775,14 +1807,6 @@ fill_pe_header_info (abfd, internal_f, internal_a, end_of_image)
 
   /* write all of the other optional header data */
 
-
-
-  internal_a->pe->SectionAlignment = pe_value (&pe_info->section_alignment,
-                                              NT_SECTION_ALIGNMENT);
-
-  internal_a->pe->FileAlignment = pe_value (&pe_info->file_alignment, 
-                                           NT_FILE_ALIGNMENT);
-
   internal_a->pe->MajorOperatingSystemVersion =
     pe_value (&pe_info->major_os_version, 1);
 
@@ -1803,28 +1827,20 @@ fill_pe_header_info (abfd, internal_f, internal_a, end_of_image)
   internal_a->pe->MinorSubsystemVersion =
     pe_value (&pe_info->minor_subsystem_version, 10);
 
-
-
   internal_a->pe->Subsystem =
     pe_value (&pe_info->subsystem, BFD_PE_CONSOLE);
 
-
-
-
   /* Virtual start address, take virtual start address of last section, 
      add its physical size and round up the next page (NT_SECTION_ALIGNMENT).
      An assumption has been made that the sections stored in the abfd
      structure are in order and that I have successfully saved the last
      section's address and size. */
 
-  internal_a->pe->SizeOfImage = 
-    (end_of_image - internal_a->pe->ImageBase
-     + internal_a->pe->SectionAlignment - 1)
-      & ~ (internal_a->pe->SectionAlignment-1);
 
-  /* Start of .text section will do here since it is the first section after
-     the headers.  Note that NT_IMAGE_BASE has already been removed above */
-  internal_a->pe->SizeOfHeaders = internal_a->text_start; 
+
+  /* The headers go up to where the first section starts. */
+
+  internal_a->pe->SizeOfHeaders = abfd->sections->filepos;
   internal_a->pe->CheckSum = 0;
   internal_a->pe->DllCharacteristics = 0;
 
@@ -1844,12 +1860,30 @@ fill_pe_header_info (abfd, internal_f, internal_a, end_of_image)
   /* first null out all data directory entries .. */
   memset (internal_a->pe->DataDirectory, sizeof (internal_a->pe->DataDirectory), 0);
 
-  add_data_entry (abfd, internal_a, 0, ".edata", internal_a->pe->ImageBase);
-  add_data_entry (abfd, internal_a, 1, ".idata", internal_a->pe->ImageBase);
-  add_data_entry (abfd, internal_a, 2, ".rsrc" ,internal_a->pe->ImageBase);
-  add_data_entry (abfd, internal_a, 5, ".reloc", internal_a->pe->ImageBase);
-
+  add_data_entry (abfd, internal_a, 0, ".edata", ib);
+  add_data_entry (abfd, internal_a, 1, ".idata", ib);
+  add_data_entry (abfd, internal_a, 2, ".rsrc" ,ib);
+  add_data_entry (abfd, internal_a, 5, ".reloc", ib);
+  {
+    asection *sec;
+    bfd_vma dsize= 0;
+    bfd_vma isize = SA(abfd->sections->filepos);
+    bfd_vma tsize= 0;
+    bfd_vma dstart = 0;
+    for (sec = abfd->sections; sec; sec = sec->next)
+      {
+       int rounded = FA(sec->_raw_size);
+       if (sec->flags & SEC_DATA) 
+         dsize += rounded;
+       if (sec->flags & SEC_CODE)
+         tsize += rounded;
+       isize += SA(rounded);
+      }
 
+    internal_a->dsize = dsize;
+    internal_a->tsize = tsize;
+    internal_a->pe->SizeOfImage = isize;
+  }
 
 }
 #endif
@@ -1871,7 +1905,6 @@ coff_write_object_contents (abfd)
   asection *text_sec = NULL;
   asection *data_sec = NULL;
   asection *bss_sec = NULL;
-  bfd_vma end_of_image = 0;
 
   struct internal_filehdr internal_f;
   struct internal_aouthdr internal_a;
@@ -1891,7 +1924,7 @@ coff_write_object_contents (abfd)
       coff_data (abfd)->link_info = info = &dummy_info;
       info->pe_info = 0;
     }
-  pe_info = info->pe_info;
+  pe_info = (struct bfd_link_pe_info *)(info->pe_info);
 
   if (!pe_info)
     {
@@ -1991,15 +2024,10 @@ coff_write_object_contents (abfd)
          section.s_vaddr = 0;
        else
 #endif
-         section.s_vaddr = current->lma;
+       section.s_vaddr = current->lma;
        section.s_paddr = current->lma;
        section.s_size = current->_raw_size;
 
-        /* Remember the address of the end of the last section */
-
-       if (current->lma + current->_raw_size > end_of_image)
-         end_of_image = current->lma + current->_raw_size ;
-
        /*
           If this section has no size or is unloadable then the scnptr
           will be 0 too
@@ -2052,24 +2080,27 @@ coff_write_object_contents (abfd)
        {
          SCNHDR buff;
 
-#ifdef WINDOWS_NT
-         /* suppress output of the sections if they are null.  ld includes
-            the bss and data sections even if there is no size assigned
-            to them.  NT loader doesn't like it if these section headers are
-            included if the sections themselves are not needed */
-         if (section.s_size == 0)
-           internal_f.f_nscns--;
-         else
-           { 
-             coff_swap_scnhdr_out (abfd, &section, &buff);
-             if (bfd_write ((PTR) (&buff), 1, SCNHSZ, abfd) != SCNHSZ)
-               return false;
-            }
-#else
-         if (coff_swap_scnhdr_out (abfd, &section, &buff) == 0
-             || bfd_write ((PTR) (&buff), 1, SCNHSZ, abfd) != SCNHSZ)
-           return false;
-#endif
+         if (obj_pe (abfd)) 
+           {
+           /* suppress output of the sections if they are null.  ld includes
+              the bss and data sections even if there is no size assigned
+              to them.  NT loader doesn't like it if these section headers are
+              included if the sections themselves are not needed */
+           if (section.s_size == 0)
+             internal_f.f_nscns--;
+           else
+             { 
+               coff_swap_scnhdr_out (abfd, &section, &buff);
+               if (bfd_write ((PTR) (&buff), 1, SCNHSZ, abfd) != SCNHSZ)
+                 return false;
+             }
+         }
+         else 
+           {
+           if (coff_swap_scnhdr_out (abfd, &section, &buff) == 0
+               || bfd_write ((PTR) (&buff), 1, SCNHSZ, abfd) != SCNHSZ)
+             return false;
+         }
 
        }
       }
@@ -2247,7 +2278,7 @@ coff_write_object_contents (abfd)
   internal_f.pe = & extra_f;
   internal_a.pe = & extra_a;
 
-  fill_pe_header_info (abfd, &internal_f, &internal_a, end_of_image);
+  fill_pe_header_info (abfd, &internal_f, &internal_a);
 #endif
 
   /* now write them */
index c4c42d5..43bb69f 100644 (file)
@@ -1622,7 +1622,17 @@ coff_link_input_bfd (finfo, input_bfd)
          bfd_byte *eline;
          bfd_byte *elineend;
 
-         if (o->lineno_count == 0)
+         /* FIXME: If SEC_HAS_CONTENTS is not for the section, then
+            build_link_order in ldwrite.c will not have created a
+            link order, which means that we will not have seen this
+            input section in _bfd_coff_final_link, which means that
+            we will not have allocated space for the line numbers of
+            this section.  I don't think line numbers can be
+            meaningful for a section which does not have
+            SEC_HAS_CONTENTS set, but, if they do, this must be
+            changed.  */
+         if (o->lineno_count == 0
+             || (o->output_section->flags & SEC_HAS_CONTENTS) == 0)
            continue;
 
          if (bfd_seek (input_bfd, o->line_filepos, SEEK_SET) != 0
@@ -2225,15 +2235,6 @@ _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,
       if (howto == NULL)
        return false;
 
-      /* WINDOWS_NT; in this next section, the value of 'val' will be computed.
-         With respect to the .idata and .rsrc sections, the NT_IMAGE_BASE
-         must be removed from the value that is to be relocated (NT_IMAGE_BASE
-         is currently defined in internal.h and has value 400000).  Now this
-         value should only be removed from addresses being relocated in the
-         .idata and .rsrc sections, not the .text section which should have
-         the 'real' address.  In addition, the .rsrc val's must also be
-         adjusted by the input_section->vma.  */
-
       val = 0;
 
       if (h == NULL)
index 3e15ddc..4b35942 100644 (file)
@@ -1,5 +1,5 @@
 /* Generic COFF swapping routines, for BFD.
-   Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
+   Copyright 1990, 1991, 1992, 1993, 1995 Free Software Foundation, Inc.
    Written by Cygnus Support.
 
 This file is part of BFD, the Binary File Descriptor library.
@@ -16,7 +16,7 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 /* This file contains routines used to swap COFF data.  It is a header
    file because the details of swapping depend on the details of the
@@ -26,6 +26,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
    Any file which uses this must first include "coff/internal.h" and
    "coff/CPU.h".  The functions will then be correct for that CPU.  */
 
+#ifndef IMAGE_BASE
+#define IMAGE_BASE 0
+#endif
+
 #define PUTWORD bfd_h_put_32
 #define PUTHALF bfd_h_put_16
 #define        PUTBYTE bfd_h_put_8
@@ -168,11 +172,14 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #ifndef NO_COFF_RELOCS
 
 static void
-DEFUN(bfd_swap_reloc_in,(abfd, reloc_src, reloc_dst),
-      bfd            *abfd AND
-      RELOC *reloc_src AND
-      struct internal_reloc *reloc_dst)
+coff_swap_reloc_in (abfd, src, dst)
+     bfd *abfd;
+     PTR src;
+     PTR dst;
 {
+  RELOC *reloc_src = (RELOC *) src;
+  struct internal_reloc *reloc_dst = (struct internal_reloc *) dst;
+
   reloc_dst->r_vaddr = bfd_h_get_32(abfd, (bfd_byte *)reloc_src->r_vaddr);
   reloc_dst->r_symndx = bfd_h_get_signed_32(abfd, (bfd_byte *) reloc_src->r_symndx);
 
@@ -191,17 +198,23 @@ DEFUN(bfd_swap_reloc_in,(abfd, reloc_src, reloc_dst),
 
 
 static unsigned int
-DEFUN(coff_swap_reloc_out,(abfd, src, dst),
-      bfd       *abfd AND
-      PTR      src AND
-      PTR      dst)
+coff_swap_reloc_out (abfd, src, dst)
+     bfd       *abfd;
+     PTR       src;
+     PTR       dst;
 {
   struct internal_reloc *reloc_src = (struct internal_reloc *)src;
   struct external_reloc *reloc_dst = (struct external_reloc *)dst;
   bfd_h_put_32(abfd, reloc_src->r_vaddr, (bfd_byte *) reloc_dst->r_vaddr);
   bfd_h_put_32(abfd, reloc_src->r_symndx, (bfd_byte *) reloc_dst->r_symndx);
+
+#ifdef RS6000COFF_C
+  bfd_h_put_8 (abfd, reloc_src->r_type, (bfd_byte *) reloc_dst->r_type);
+  bfd_h_put_8 (abfd, reloc_src->r_size, (bfd_byte *) reloc_dst->r_size);
+#else
   bfd_h_put_16(abfd, reloc_src->r_type, (bfd_byte *)
               reloc_dst->r_type);
+#endif
 
 #ifdef SWAP_OUT_RELOC_OFFSET
   SWAP_OUT_RELOC_OFFSET(abfd,
@@ -218,10 +231,10 @@ DEFUN(coff_swap_reloc_out,(abfd, src, dst),
 #endif /* NO_COFF_RELOCS */
 
 static void
-DEFUN(coff_swap_filehdr_in,(abfd, src, dst),
-      bfd            *abfd AND
-      PTR           src AND
-      PTR           dst)
+coff_swap_filehdr_in (abfd, src, dst)
+     bfd            *abfd;
+     PTR            src;
+     PTR            dst;
 {
   FILHDR *filehdr_src = (FILHDR *) src;
   struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst;
@@ -236,13 +249,14 @@ DEFUN(coff_swap_filehdr_in,(abfd, src, dst),
 }
 
 static  unsigned int
-DEFUN(coff_swap_filehdr_out,(abfd, in, out),
-      bfd       *abfd AND
-      PTR      in AND
-      PTR      out)
+coff_swap_filehdr_out (abfd, in, out)
+     bfd       *abfd;
+     PTR       in;
+     PTR       out;
 {
   struct internal_filehdr *filehdr_in = (struct internal_filehdr *)in;
   FILHDR *filehdr_out = (FILHDR *)out;
+
   bfd_h_put_16(abfd, filehdr_in->f_magic, (bfd_byte *) filehdr_out->f_magic);
   bfd_h_put_16(abfd, filehdr_in->f_nscns, (bfd_byte *) filehdr_out->f_nscns);
   bfd_h_put_32(abfd, filehdr_in->f_timdat, (bfd_byte *) filehdr_out->f_timdat);
@@ -251,6 +265,61 @@ DEFUN(coff_swap_filehdr_out,(abfd, in, out),
   bfd_h_put_32(abfd, filehdr_in->f_nsyms, (bfd_byte *) filehdr_out->f_nsyms);
   bfd_h_put_16(abfd, filehdr_in->f_opthdr, (bfd_byte *) filehdr_out->f_opthdr);
   bfd_h_put_16(abfd, filehdr_in->f_flags, (bfd_byte *) filehdr_out->f_flags);
+
+#ifdef COFF_IMAGE_WITH_PE
+  /* put in extra dos header stuff.  This data remains essentially
+     constant, it just has to be tacked on to the beginning of all exes 
+     for NT */
+  bfd_h_put_16(abfd, filehdr_in->pe->e_magic, (bfd_byte *) filehdr_out->e_magic);
+  bfd_h_put_16(abfd, filehdr_in->pe->e_cblp, (bfd_byte *) filehdr_out->e_cblp);
+  bfd_h_put_16(abfd, filehdr_in->pe->e_cp, (bfd_byte *) filehdr_out->e_cp);
+  bfd_h_put_16(abfd, filehdr_in->pe->e_crlc, (bfd_byte *) filehdr_out->e_crlc);
+  bfd_h_put_16(abfd, filehdr_in->pe->e_cparhdr, 
+                     (bfd_byte *) filehdr_out->e_cparhdr);
+  bfd_h_put_16(abfd, filehdr_in->pe->e_minalloc, 
+                     (bfd_byte *) filehdr_out->e_minalloc);
+  bfd_h_put_16(abfd, filehdr_in->pe->e_maxalloc, 
+                     (bfd_byte *) filehdr_out->e_maxalloc);
+  bfd_h_put_16(abfd, filehdr_in->pe->e_ss, (bfd_byte *) filehdr_out->e_ss);
+  bfd_h_put_16(abfd, filehdr_in->pe->e_sp, (bfd_byte *) filehdr_out->e_sp);
+  bfd_h_put_16(abfd, filehdr_in->pe->e_csum, (bfd_byte *) filehdr_out->e_csum);
+  bfd_h_put_16(abfd, filehdr_in->pe->e_ip, (bfd_byte *) filehdr_out->e_ip);
+  bfd_h_put_16(abfd, filehdr_in->pe->e_cs, (bfd_byte *) filehdr_out->e_cs);
+  bfd_h_put_16(abfd, filehdr_in->pe->e_lfarlc, (bfd_byte *) filehdr_out->e_lfarlc);
+  bfd_h_put_16(abfd, filehdr_in->pe->e_ovno, (bfd_byte *) filehdr_out->e_ovno);
+  {
+    int idx;
+    for (idx=0; idx < 4; idx++)
+      bfd_h_put_16(abfd, filehdr_in->pe->e_res[idx], 
+                         (bfd_byte *) filehdr_out->e_res[idx]);
+  }
+  bfd_h_put_16(abfd, filehdr_in->pe->e_oemid, (bfd_byte *) filehdr_out->e_oemid);
+  bfd_h_put_16(abfd, filehdr_in->pe->e_oeminfo,
+                     (bfd_byte *) filehdr_out->e_oeminfo);
+  {
+    int idx;
+    for (idx=0; idx < 10; idx++)
+      bfd_h_put_16(abfd, filehdr_in->pe->e_res2[idx],
+                         (bfd_byte *) filehdr_out->e_res2[idx]);
+  }
+  bfd_h_put_32(abfd, filehdr_in->pe->e_lfanew, (bfd_byte *) filehdr_out->e_lfanew);
+
+  {
+    int idx;
+    for (idx=0; idx < 16; idx++)
+      bfd_h_put_32(abfd, filehdr_in->pe->dos_message[idx],
+                         (bfd_byte *) filehdr_out->dos_message[idx]);
+  }
+
+  /* also put in the NT signature */
+  bfd_h_put_32(abfd, filehdr_in->pe->nt_signature, 
+                     (bfd_byte *) filehdr_out->nt_signature);
+
+
+#endif
+
+
+
   return sizeof(FILHDR);
 }
 
@@ -258,10 +327,10 @@ DEFUN(coff_swap_filehdr_out,(abfd, in, out),
 #ifndef NO_COFF_SYMBOLS
 
 static void
-DEFUN(coff_swap_sym_in,(abfd, ext1, in1),
-      bfd            *abfd AND
-      PTR ext1 AND
-      PTR in1)
+coff_swap_sym_in (abfd, ext1, in1)
+     bfd            *abfd;
+     PTR ext1;
+     PTR in1;
 {
   SYMENT *ext = (SYMENT *)ext1;
   struct internal_syment      *in = (struct internal_syment *)in1;
@@ -277,7 +346,7 @@ DEFUN(coff_swap_sym_in,(abfd, ext1, in1),
     memcpy(in->_n._n_name, ext->e.e_name, SYMNMLEN);
 #endif
   }
-  in->n_value = bfd_h_get_32(abfd, (bfd_byte *) ext->e_value);
+  in->n_value = bfd_h_get_32(abfd, (bfd_byte *) ext->e_value); 
   in->n_scnum = bfd_h_get_16(abfd, (bfd_byte *) ext->e_scnum);
   if (sizeof(ext->e_type) == 2){
     in->n_type = bfd_h_get_16(abfd, (bfd_byte *) ext->e_type);
@@ -287,13 +356,34 @@ DEFUN(coff_swap_sym_in,(abfd, ext1, in1),
   }
   in->n_sclass = bfd_h_get_8(abfd, ext->e_sclass);
   in->n_numaux = bfd_h_get_8(abfd, ext->e_numaux);
+
+#ifdef COFF_WITH_PE
+  /* The section symbols for the .idata$ sections have class 68, which MS
+     documentation indicates is a section symbol.  The problem is that the
+     value field in the symbol is simply a copy of the .idata section's flags
+     rather than something useful.  When these symbols are encountered, change
+     the value to 0 and the section number to 1 so that they will be handled
+     somewhat correctly in the bfd code. */
+  if (in->n_sclass == 0x68) {
+    in->n_value = 0x0;
+    in->n_scnum = 1;
+    /* I have tried setting the class to 3 and using the following to set
+       the section number.  This will put the address of the pointer to the
+       string kernel32.dll at addresses 0 and 0x10 off start of idata section
+       which is not correct */
+/*    if (strcmp (in->_n._n_name, ".idata$4") == 0) */
+/*      in->n_scnum = 3; */
+/*    else */
+/*      in->n_scnum = 2; */
+    }
+#endif
 }
 
 static unsigned int
-DEFUN(coff_swap_sym_out,(abfd, inp, extp),
-      bfd       *abfd AND
-      PTR      inp AND
-      PTR      extp)
+coff_swap_sym_out (abfd, inp, extp)
+     bfd       *abfd;
+     PTR       inp;
+     PTR       extp;
 {
   struct internal_syment *in = (struct internal_syment *)inp;
   SYMENT *ext =(SYMENT *)extp;
@@ -324,14 +414,14 @@ DEFUN(coff_swap_sym_out,(abfd, inp, extp),
 }
 
 static void
-DEFUN(coff_swap_aux_in,(abfd, ext1, type, class, indx, numaux, in1),
-      bfd            *abfd AND
-      PTR            ext1 AND
-      int             type AND
-      int             class AND
-      int            indx AND
-      int            numaux AND
-      PTR            in1)
+coff_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1)
+     bfd            *abfd;
+     PTR             ext1;
+     int             type;
+     int             class;
+     int             indx;
+     int             numaux;
+     PTR             in1;
 {
   AUXENT    *ext = (AUXENT *)ext1;
   union internal_auxent *in = (union internal_auxent *)in1;
@@ -357,7 +447,7 @@ DEFUN(coff_swap_aux_in,(abfd, ext1, type, class, indx, numaux, in1),
     case C_HIDEXT:
       if (indx + 1 == numaux)
        {
-         in->x_csect.x_scnlen   = bfd_h_get_32 (abfd, ext->x_csect.x_scnlen);
+         in->x_csect.x_scnlen.l = bfd_h_get_32 (abfd, ext->x_csect.x_scnlen);
          in->x_csect.x_parmhash = bfd_h_get_32 (abfd,
                                                 ext->x_csect.x_parmhash);
          in->x_csect.x_snhash   = bfd_h_get_16 (abfd, ext->x_csect.x_snhash);
@@ -392,20 +482,25 @@ DEFUN(coff_swap_aux_in,(abfd, ext1, type, class, indx, numaux, in1),
   in->x_sym.x_tvndx = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_tvndx);
 #endif
 
-  if (ISARY(type)) {
+  if (class == C_BLOCK || ISFCN (type) || ISTAG (class))
+    {
+      in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR (abfd, ext);
+      in->x_sym.x_fcnary.x_fcn.x_endndx.l = GET_FCN_ENDNDX (abfd, ext);
+    }
+  else
+    {
 #if DIMNUM != E_DIMNUM
-    -> Error, we need to cope with truncating or extending DIMNUM!;
-#else
-    in->x_sym.x_fcnary.x_ary.x_dimen[0] = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
-    in->x_sym.x_fcnary.x_ary.x_dimen[1] = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
-    in->x_sym.x_fcnary.x_ary.x_dimen[2] = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
-    in->x_sym.x_fcnary.x_ary.x_dimen[3] = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
-#endif
-  }
-  if (class == C_BLOCK || ISFCN(type) || ISTAG(class)) {
-    in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR(abfd, ext);
-    in->x_sym.x_fcnary.x_fcn.x_endndx.l = GET_FCN_ENDNDX(abfd, ext);
-  }
+ #error we need to cope with truncating or extending DIMNUM
+#endif
+      in->x_sym.x_fcnary.x_ary.x_dimen[0] =
+       bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
+      in->x_sym.x_fcnary.x_ary.x_dimen[1] =
+       bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
+      in->x_sym.x_fcnary.x_ary.x_dimen[2] =
+       bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
+      in->x_sym.x_fcnary.x_ary.x_dimen[3] =
+       bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
+    }
 
   if (ISFCN(type)) {
     in->x_sym.x_misc.x_fsize = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_misc.x_fsize);
@@ -417,14 +512,14 @@ DEFUN(coff_swap_aux_in,(abfd, ext1, type, class, indx, numaux, in1),
 }
 
 static unsigned int
-DEFUN(coff_swap_aux_out,(abfd, inp, type, class, indx, numaux, extp),
-  bfd   *abfd AND
-  PTR  inp AND
-  int   type AND
-  int   class AND
-  int   indx AND
-  int   numaux AND
-  PTR  extp)
+coff_swap_aux_out (abfd, inp, type, class, indx, numaux, extp)
+     bfd   *abfd;
+     PTR       inp;
+     int   type;
+     int   class;
+     int   indx;
+     int   numaux;
+     PTR       extp;
 {
   union internal_auxent *in = (union internal_auxent *)inp;
   AUXENT *ext = (AUXENT *)extp;
@@ -453,7 +548,7 @@ DEFUN(coff_swap_aux_out,(abfd, inp, type, class, indx, numaux, extp),
   case C_HIDEXT:
     if (indx + 1 == numaux)
       {
-       PUTWORD (abfd, in->x_csect.x_scnlen,    ext->x_csect.x_scnlen);
+       PUTWORD (abfd, in->x_csect.x_scnlen.l,  ext->x_csect.x_scnlen);
        PUTWORD (abfd, in->x_csect.x_parmhash,  ext->x_csect.x_parmhash);
        PUTHALF (abfd, in->x_csect.x_snhash,    ext->x_csect.x_snhash);
        /* We don't have to hack bitfields in x_smtyp because it's
@@ -487,28 +582,35 @@ DEFUN(coff_swap_aux_out,(abfd, inp, type, class, indx, numaux, extp),
   bfd_h_put_16(abfd, in->x_sym.x_tvndx , (bfd_byte *) ext->x_sym.x_tvndx);
 #endif
 
-  if (class == C_BLOCK || ISFCN(type) || ISTAG(class)) {
-    PUT_FCN_LNNOPTR(abfd,  in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext);
-    PUT_FCN_ENDNDX(abfd,  in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext);
-  }
-
-  if (ISFCN(type)) {
-    PUTWORD(abfd, in->x_sym.x_misc.x_fsize, (bfd_byte *)  ext->x_sym.x_misc.x_fsize);
-  }
-  else {
-    if (ISARY(type)) {
+  if (class == C_BLOCK || ISFCN (type) || ISTAG (class))
+    {
+      PUT_FCN_LNNOPTR(abfd,  in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext);
+      PUT_FCN_ENDNDX(abfd,  in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext);
+    }
+  else
+    {
 #if DIMNUM != E_DIMNUM
-      -> Error, we need to cope with truncating or extending DIMNUM!;
-#else
-      bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0], (bfd_byte *)ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
-      bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1], (bfd_byte *)ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
-      bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2], (bfd_byte *)ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
-      bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3], (bfd_byte *)ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
-#endif
+ #error we need to cope with truncating or extending DIMNUM
+#endif
+      bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],
+                   (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
+      bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],
+                   (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
+      bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],
+                   (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
+      bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],
+                   (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
     }
-    PUT_LNSZ_LNNO(abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext);
-    PUT_LNSZ_SIZE(abfd, in->x_sym.x_misc.x_lnsz.x_size, ext);
-  }
+
+  if (ISFCN (type))
+    PUTWORD (abfd, in->x_sym.x_misc.x_fsize,
+            (bfd_byte *)  ext->x_sym.x_misc.x_fsize);
+  else
+    {
+      PUT_LNSZ_LNNO (abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext);
+      PUT_LNSZ_SIZE (abfd, in->x_sym.x_misc.x_lnsz.x_size, ext);
+    }
+
   return sizeof(AUXENT);
 }
 
@@ -517,10 +619,10 @@ DEFUN(coff_swap_aux_out,(abfd, inp, type, class, indx, numaux, extp),
 #ifndef NO_COFF_LINENOS
 
 static void
-DEFUN(coff_swap_lineno_in,(abfd, ext1, in1),
-      bfd            *abfd AND
-      PTR ext1 AND
-      PTR in1)
+coff_swap_lineno_in (abfd, ext1, in1)
+     bfd            *abfd;
+     PTR ext1;
+     PTR in1;
 {
   LINENO *ext = (LINENO *)ext1;
   struct internal_lineno      *in = (struct internal_lineno *)in1;
@@ -530,10 +632,10 @@ DEFUN(coff_swap_lineno_in,(abfd, ext1, in1),
 }
 
 static unsigned int
-DEFUN(coff_swap_lineno_out,(abfd, inp, outp),
-      bfd       *abfd AND
-      PTR      inp AND
-      PTR      outp)
+coff_swap_lineno_out (abfd, inp, outp)
+     bfd       *abfd;
+     PTR       inp;
+     PTR       outp;
 {
   struct internal_lineno *in = (struct internal_lineno *)inp;
   struct external_lineno *ext = (struct external_lineno *)outp;
@@ -548,10 +650,10 @@ DEFUN(coff_swap_lineno_out,(abfd, inp, outp),
 
 
 static void
-DEFUN(coff_swap_aouthdr_in,(abfd, aouthdr_ext1, aouthdr_int1),
-      bfd            *abfd AND
-      PTR aouthdr_ext1 AND
-      PTR aouthdr_int1)
+coff_swap_aouthdr_in (abfd, aouthdr_ext1, aouthdr_int1)
+     bfd            *abfd;
+     PTR aouthdr_ext1;
+     PTR aouthdr_int1;
 {
   AOUTHDR        *aouthdr_ext = (AOUTHDR *) aouthdr_ext1;
   struct internal_aouthdr *aouthdr_int = (struct internal_aouthdr *)aouthdr_int1;
@@ -616,10 +718,10 @@ DEFUN(coff_swap_aouthdr_in,(abfd, aouthdr_ext1, aouthdr_int1),
 }
 
 static unsigned int
-DEFUN(coff_swap_aouthdr_out,(abfd, in, out),
-      bfd       *abfd AND
-      PTR      in AND
-      PTR      out)
+coff_swap_aouthdr_out (abfd, in, out)
+     bfd       *abfd;
+     PTR       in;
+     PTR       out;
 {
   struct internal_aouthdr *aouthdr_in = (struct internal_aouthdr *)in;
   AOUTHDR *aouthdr_out = (AOUTHDR *)out;
@@ -634,6 +736,64 @@ DEFUN(coff_swap_aouthdr_out,(abfd, in, out),
                          (bfd_byte *) aouthdr_out->text_start);
   PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start,
                          (bfd_byte *) aouthdr_out->data_start);
+#ifdef COFF_WITH_PE
+  {
+  PEAOUTHDR *peaouthdr_out = (PEAOUTHDR *)aouthdr_out;
+  bfd_h_put_32 (abfd, aouthdr_in->pe->ImageBase, 
+                (bfd_byte *) peaouthdr_out->ImageBase);
+  bfd_h_put_32 (abfd, aouthdr_in->pe->SectionAlignment,
+                (bfd_byte *) peaouthdr_out->SectionAlignment);
+  bfd_h_put_32 (abfd, aouthdr_in->pe->FileAlignment,
+                (bfd_byte *) peaouthdr_out->FileAlignment);
+  bfd_h_put_16 (abfd, aouthdr_in->pe->MajorOperatingSystemVersion,
+                (bfd_byte *) peaouthdr_out->MajorOperatingSystemVersion);
+  bfd_h_put_16 (abfd, aouthdr_in->pe->MinorOperatingSystemVersion,
+                (bfd_byte *) peaouthdr_out->MinorOperatingSystemVersion);
+  bfd_h_put_16 (abfd, aouthdr_in->pe->MajorImageVersion,
+                (bfd_byte *) peaouthdr_out->MajorImageVersion);
+  bfd_h_put_16 (abfd, aouthdr_in->pe->MinorImageVersion,
+                (bfd_byte *) peaouthdr_out->MinorImageVersion);
+  bfd_h_put_16 (abfd, aouthdr_in->pe->MajorSubsystemVersion,
+                (bfd_byte *) peaouthdr_out->MajorSubsystemVersion);
+  bfd_h_put_16 (abfd, aouthdr_in->pe->MinorSubsystemVersion,
+                (bfd_byte *) peaouthdr_out->MinorSubsystemVersion);
+  bfd_h_put_32 (abfd, aouthdr_in->pe->Reserved1,
+                (bfd_byte *) peaouthdr_out->Reserved1);
+  bfd_h_put_32 (abfd, aouthdr_in->pe->SizeOfImage,
+                (bfd_byte *) peaouthdr_out->SizeOfImage);
+  bfd_h_put_32 (abfd, aouthdr_in->pe->SizeOfHeaders,
+                (bfd_byte *) peaouthdr_out->SizeOfHeaders);
+  bfd_h_put_32 (abfd, aouthdr_in->pe->CheckSum,
+                (bfd_byte *) peaouthdr_out->CheckSum);
+  bfd_h_put_16 (abfd, aouthdr_in->pe->Subsystem,
+                (bfd_byte *) peaouthdr_out->Subsystem);
+  bfd_h_put_16 (abfd, aouthdr_in->pe->DllCharacteristics,
+                (bfd_byte *) peaouthdr_out->DllCharacteristics);
+  bfd_h_put_32 (abfd, aouthdr_in->pe->SizeOfStackReserve,
+                (bfd_byte *) peaouthdr_out->SizeOfStackReserve);
+  bfd_h_put_32 (abfd, aouthdr_in->pe->SizeOfStackCommit,
+                (bfd_byte *) peaouthdr_out->SizeOfStackCommit);
+  bfd_h_put_32 (abfd, aouthdr_in->pe->SizeOfHeapReserve,
+                (bfd_byte *) peaouthdr_out->SizeOfHeapReserve);
+  bfd_h_put_32 (abfd, aouthdr_in->pe->SizeOfHeapCommit,
+                (bfd_byte *) peaouthdr_out->SizeOfHeapCommit);
+  bfd_h_put_32 (abfd, aouthdr_in->pe->LoaderFlags,
+                (bfd_byte *) peaouthdr_out->LoaderFlags);
+  bfd_h_put_32 (abfd, aouthdr_in->pe->NumberOfRvaAndSizes,
+                (bfd_byte *) peaouthdr_out->NumberOfRvaAndSizes);
+  {
+    int idx;
+    for (idx=0; idx < 16; idx++)
+    {
+      bfd_h_put_32 (abfd, aouthdr_in->pe->DataDirectory[idx].VirtualAddress,
+               (bfd_byte *) peaouthdr_out->DataDirectory[idx][0]);
+      bfd_h_put_32 (abfd, aouthdr_in->pe->DataDirectory[idx].Size,
+                (bfd_byte *) peaouthdr_out->DataDirectory[idx][1]);
+    }
+  }
+}
+#endif
+
 #ifdef I960
   bfd_h_put_32(abfd, aouthdr_in->tagentries, (bfd_byte *) aouthdr_out->tagentries);
 #endif
@@ -662,10 +822,10 @@ DEFUN(coff_swap_aouthdr_out,(abfd, in, out),
 }
 
 static void
-DEFUN(coff_swap_scnhdr_in,(abfd, ext, in),
-      bfd            *abfd AND
-      PTR           ext AND
-      PTR           in)
+coff_swap_scnhdr_in (abfd, ext, in)
+     bfd            *abfd;
+     PTR            ext;
+     PTR            in;
 {
   SCNHDR *scnhdr_ext = (SCNHDR *) ext;
   struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
@@ -695,88 +855,137 @@ DEFUN(coff_swap_scnhdr_in,(abfd, ext, in),
 #ifdef I960
   scnhdr_int->s_align = bfd_h_get_32(abfd, (bfd_byte *) scnhdr_ext->s_align);
 #endif
+
+#ifdef NT_EXE_IMAGE_BASE
+/*
+  if (scnhdr_int->s_vaddr != 0) {
+    scnhdr_int->s_vaddr += NT_EXE_IMAGE_BASE;
+  }
+*/
+#endif
 }
-/* start-sanitize-mpw */
-#ifndef MPW_C
-/* end-sanitize-mpw */
 
 static unsigned int
-DEFUN(coff_swap_scnhdr_out,(abfd, in, out),
-      bfd       *abfd AND
-      PTR      in AND
-      PTR      out)
+coff_swap_scnhdr_out (abfd, in, out)
+     bfd       *abfd;
+     PTR       in;
+     PTR       out;
 {
   struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *)in;
   SCNHDR *scnhdr_ext = (SCNHDR *)out;
+  unsigned int ret = sizeof (SCNHDR);
 
   memcpy(scnhdr_ext->s_name, scnhdr_int->s_name, sizeof(scnhdr_int->s_name));
-  PUT_SCNHDR_VADDR (abfd, scnhdr_int->s_vaddr,
+
+#ifdef COFF_IMAGE_WITH_PE
+
+  {
+  bfd_link_pe_info *pe_info = coff_data (abfd)->link_info->pe_info;
+
+  PUT_SCNHDR_VADDR (abfd, 
+                   (scnhdr_int->s_vaddr 
+                    - pe_value (&pe_info->image_base,
+                                NT_EXE_IMAGE_BASE)),
                    (bfd_byte *) scnhdr_ext->s_vaddr);
-  PUT_SCNHDR_PADDR (abfd, scnhdr_int->s_paddr,
-                   (bfd_byte *) scnhdr_ext->s_paddr);
-  PUT_SCNHDR_SIZE (abfd, scnhdr_int->s_size,
-                  (bfd_byte *) scnhdr_ext->s_size);
-  PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr,
-                    (bfd_byte *) scnhdr_ext->s_scnptr);
-  PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr,
-                    (bfd_byte *) scnhdr_ext->s_relptr);
-  PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr,
-                     (bfd_byte *) scnhdr_ext->s_lnnoptr);
-  PUTWORD(abfd, scnhdr_int->s_flags, (bfd_byte *) scnhdr_ext->s_flags);
-#if defined(M88)
-  PUTWORD(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno);
-  PUTWORD(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc);
-#else
-  PUTHALF(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno);
-  PUTHALF(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc);
-#endif
 
-#if defined(I960)
-  PUTWORD(abfd, scnhdr_int->s_align, (bfd_byte *) scnhdr_ext->s_align);
+
+  /* NT wants the physical address data to be the size (s_size data) of
+     the section */
+#if 1
+  PUT_SCNHDR_PADDR (abfd, scnhdr_int->s_size,
+                   (bfd_byte *) scnhdr_ext->s_paddr);
 #endif
-  return sizeof(SCNHDR);
+  /* NT wants the size data to be rounded up to the next NT_FILE_ALIGNMENT
+     value except for the BSS section, its s_size should be 0 */
+  if (strcmp (scnhdr_int->s_name, _BSS) == 0)
+    PUT_SCNHDR_SIZE (abfd, 0, (bfd_byte *) scnhdr_ext->s_size);
+  else
+    {
+      bfd_vma rounded_size;
+      rounded_size = ((scnhdr_int->s_size + NT_FILE_ALIGNMENT - 1) / 
+                     NT_FILE_ALIGNMENT) *
+                       NT_FILE_ALIGNMENT;
+      PUT_SCNHDR_SIZE (abfd, rounded_size, (bfd_byte *) scnhdr_ext->s_size);
+    }
 }
-/* start-sanitize-mpw */
 #else
-/* Same routine, but with some pre-expanded macros, so ^&%$#&! MPW C doesn't
-   corrupt itself and then freak out. */
+  PUT_SCNHDR_VADDR (abfd, scnhdr_int->s_vaddr,
+                   (bfd_byte *) scnhdr_ext->s_vaddr);
 
-static unsigned int
-DEFUN(coff_swap_scnhdr_out,(abfd, in, out),
-      bfd       *abfd AND
-      PTR      in AND
-      PTR      out)
-{
-  struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *)in;
-  SCNHDR *scnhdr_ext = (SCNHDR *)out;
 
-  memcpy(scnhdr_ext->s_name, scnhdr_int->s_name, sizeof(scnhdr_int->s_name));
-  bfd_h_put_32 (abfd, scnhdr_int->s_vaddr,
-                   (bfd_byte *) scnhdr_ext->s_vaddr);
-  bfd_h_put_32 (abfd, scnhdr_int->s_paddr,
+  PUT_SCNHDR_PADDR (abfd, scnhdr_int->s_paddr,
                    (bfd_byte *) scnhdr_ext->s_paddr);
-  bfd_h_put_32 (abfd, scnhdr_int->s_size,
+  PUT_SCNHDR_SIZE (abfd, scnhdr_int->s_size,
                   (bfd_byte *) scnhdr_ext->s_size);
+#endif
   PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr,
                     (bfd_byte *) scnhdr_ext->s_scnptr);
   PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr,
                     (bfd_byte *) scnhdr_ext->s_relptr);
   PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr,
                      (bfd_byte *) scnhdr_ext->s_lnnoptr);
+#ifdef COFF_IMAGE_WITH_PE
+  /* Extra flags must be set when dealing with NT.  All sections should also
+     have the IMAGE_SCN_MEM_READ (0x40000000) flag set.  In addition, the
+     .text section must have IMAGE_SCN_MEM_EXECUTE (0x20000000) and the data
+     sections (.idata, .data, .bss, .CRT) must have IMAGE_SCN_MEM_WRITE set
+     (this is especially important when dealing with the .idata section since
+     the addresses for routines from .dlls must be overwritten).  If .reloc
+     section data is ever generated, we must add IMAGE_SCN_MEM_DISCARDABLE
+     (0x02000000).  Also, the resource data should also be read and
+     writable.  */
+  {
+    int flags = scnhdr_int->s_flags;
+    if (strcmp (scnhdr_int->s_name, ".data")  == 0 ||
+       strcmp (scnhdr_int->s_name, ".CRT")   == 0 ||
+       strcmp (scnhdr_int->s_name, ".rsrc")  == 0 ||
+       strcmp (scnhdr_int->s_name, ".bss")   == 0)
+      flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
+    else if (strcmp (scnhdr_int->s_name, ".text") == 0)
+      flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE;
+    else if (strcmp (scnhdr_int->s_name, ".reloc") == 0)
+      flags = SEC_DATA| IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE;
+    else if (strcmp (scnhdr_int->s_name, ".idata") == 0)
+      flags = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | SEC_DATA;     
+    else if (strcmp (scnhdr_int->s_name, ".rdata") == 0
+            || strcmp (scnhdr_int->s_name, ".edata") == 0)
+      flags =  IMAGE_SCN_MEM_READ | SEC_DATA;     
+
+    PUTWORD(abfd, flags, (bfd_byte *) scnhdr_ext->s_flags);
+  }
+#else
   PUTWORD(abfd, scnhdr_int->s_flags, (bfd_byte *) scnhdr_ext->s_flags);
+#endif
 #if defined(M88)
   PUTWORD(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno);
   PUTWORD(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc);
 #else
-  PUTHALF(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno);
-  PUTHALF(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc);
+  if (scnhdr_int->s_nlnno <= 0xffff)
+    PUTHALF(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno);
+  else
+    {
+      (*_bfd_error_handler) ("%s: line number overflow: 0x%lx > 0xffff",
+                            bfd_get_filename (abfd),
+                            scnhdr_int->s_nlnno);
+      bfd_set_error (bfd_error_file_truncated);
+      PUTHALF (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nlnno);
+      ret = 0;
+    }
+  if (scnhdr_int->s_nreloc <= 0xffff)
+    PUTHALF(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc);
+  else
+    {
+      (*_bfd_error_handler) ("%s: reloc overflow: 0x%lx > 0xffff",
+                            bfd_get_filename (abfd),
+                            scnhdr_int->s_nreloc);
+      bfd_set_error (bfd_error_file_truncated);
+      PUTHALF (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nreloc);
+      ret = 0;
+    }
 #endif
 
 #if defined(I960)
   PUTWORD(abfd, scnhdr_int->s_align, (bfd_byte *) scnhdr_ext->s_align);
 #endif
-  return sizeof(SCNHDR);
+  return ret;
 }
-
-#endif
-/* end-sanitize-mpw */