]> oss.titaniummirror.com Git - msp430-binutils.git/blobdiff - bfd/peXXigen.c
Imported binutils-2.20
[msp430-binutils.git] / bfd / peXXigen.c
index 2d09561e33b1ef25e66d0a36228cb1377d879603..6ee03a758358bef383357ce8f24497236b036f6f 100644 (file)
@@ -1,6 +1,6 @@
 /* Support for the generic parts of PE/PEI; the common executable parts.
    Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
 /* Support for the generic parts of PE/PEI; the common executable parts.
    Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-   2005, 2006, 2007 Free Software Foundation, Inc.
+   2005, 2006, 2007, 2008, 2009  Free Software Foundation, Inc.
    Written by Cygnus Solutions.
 
    This file is part of BFD, the Binary File Descriptor library.
    Written by Cygnus Solutions.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -129,6 +129,9 @@ _bfd_XXi_swap_sym_in (bfd * abfd, void * ext1, void * in1)
      they will be handled somewhat correctly in the bfd code.  */
   if (in->n_sclass == C_SECTION)
     {
      they will be handled somewhat correctly in the bfd code.  */
   if (in->n_sclass == C_SECTION)
     {
+      char namebuf[SYMNMLEN + 1];
+      const char *name = NULL;
+
       in->n_value = 0x0;
 
       /* Create synthetic empty sections as needed.  DJ */
       in->n_value = 0x0;
 
       /* Create synthetic empty sections as needed.  DJ */
@@ -136,33 +139,38 @@ _bfd_XXi_swap_sym_in (bfd * abfd, void * ext1, void * in1)
        {
          asection *sec;
 
        {
          asection *sec;
 
-         for (sec = abfd->sections; sec; sec = sec->next)
-           {
-             if (strcmp (sec->name, in->n_name) == 0)
-               {
-                 in->n_scnum = sec->target_index;
-                 break;
-               }
-           }
+         name = _bfd_coff_internal_syment_name (abfd, in, namebuf);
+         if (name == NULL)
+           /* FIXME: Return error.  */
+           abort ();
+         sec = bfd_get_section_by_name (abfd, name);
+         if (sec != NULL)
+           in->n_scnum = sec->target_index;
        }
 
       if (in->n_scnum == 0)
        {
          int unused_section_number = 0;
          asection *sec;
        }
 
       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;
 
          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, (bfd_size_type) strlen (in->n_name) + 10);
-         if (name == NULL)
-           return;
-         strcpy (name, in->n_name);
+         if (name == namebuf)
+           {
+             name = (const char *) bfd_alloc (abfd, strlen (namebuf) + 1);
+             if (name == NULL)
+               /* FIXME: Return error.  */
+               abort ();
+             strcpy ((char *) name, namebuf);
+           }
          flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_DATA | SEC_LOAD;
          sec = bfd_make_section_anyway_with_flags (abfd, name, flags);
          flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_DATA | SEC_LOAD;
          sec = bfd_make_section_anyway_with_flags (abfd, name, flags);
+         if (sec == NULL)
+           /* FIXME: Return error.  */
+           abort ();
 
          sec->vma = 0;
          sec->lma = 0;
 
          sec->vma = 0;
          sec->lma = 0;
@@ -223,7 +231,7 @@ void
 _bfd_XXi_swap_aux_in (bfd *    abfd,
                      void *    ext1,
                      int       type,
 _bfd_XXi_swap_aux_in (bfd *    abfd,
                      void *    ext1,
                      int       type,
-                     int       class,
+                     int       in_class,
                      int       indx ATTRIBUTE_UNUSED,
                      int       numaux ATTRIBUTE_UNUSED,
                      void *    in1)
                      int       indx ATTRIBUTE_UNUSED,
                      int       numaux ATTRIBUTE_UNUSED,
                      void *    in1)
@@ -231,7 +239,7 @@ _bfd_XXi_swap_aux_in (bfd * abfd,
   AUXENT *ext = (AUXENT *) ext1;
   union internal_auxent *in = (union internal_auxent *) in1;
 
   AUXENT *ext = (AUXENT *) ext1;
   union internal_auxent *in = (union internal_auxent *) in1;
 
-  switch (class)
+  switch (in_class)
     {
     case C_FILE:
       if (ext->x_file.x_fname[0] == 0)
     {
     case C_FILE:
       if (ext->x_file.x_fname[0] == 0)
@@ -262,7 +270,8 @@ _bfd_XXi_swap_aux_in (bfd * abfd,
   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);
 
   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))
+  if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
+      || ISTAG (in_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);
     {
       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);
@@ -294,7 +303,7 @@ unsigned int
 _bfd_XXi_swap_aux_out (bfd *  abfd,
                       void * inp,
                       int    type,
 _bfd_XXi_swap_aux_out (bfd *  abfd,
                       void * inp,
                       int    type,
-                      int    class,
+                      int    in_class,
                       int    indx ATTRIBUTE_UNUSED,
                       int    numaux ATTRIBUTE_UNUSED,
                       void * extp)
                       int    indx ATTRIBUTE_UNUSED,
                       int    numaux ATTRIBUTE_UNUSED,
                       void * extp)
@@ -304,7 +313,7 @@ _bfd_XXi_swap_aux_out (bfd *  abfd,
 
   memset (ext, 0, AUXESZ);
 
 
   memset (ext, 0, AUXESZ);
 
-  switch (class)
+  switch (in_class)
     {
     case C_FILE:
       if (in->x_file.x_fname[0] == 0)
     {
     case C_FILE:
       if (in->x_file.x_fname[0] == 0)
@@ -336,7 +345,8 @@ _bfd_XXi_swap_aux_out (bfd *  abfd,
   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);
 
   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))
+  if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
+      || ISTAG (in_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);
     {
       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);
@@ -540,17 +550,6 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
   bfd_vma sa, fa, ib;
   IMAGE_DATA_DIRECTORY idata2, idata5, tls;
   
   bfd_vma sa, fa, ib;
   IMAGE_DATA_DIRECTORY idata2, idata5, tls;
   
-  if (pe->force_minimum_alignment)
-    {
-      if (!extra->FileAlignment)
-       extra->FileAlignment = PE_DEF_FILE_ALIGNMENT;
-      if (!extra->SectionAlignment)
-       extra->SectionAlignment = PE_DEF_SECTION_ALIGNMENT;
-    }
-
-  if (extra->Subsystem == IMAGE_SUBSYSTEM_UNKNOWN)
-    extra->Subsystem = pe->target_subsystem;
-
   sa = extra->SectionAlignment;
   fa = extra->FileAlignment;
   ib = extra->ImageBase;
   sa = extra->SectionAlignment;
   fa = extra->FileAlignment;
   ib = extra->ImageBase;
@@ -879,7 +878,7 @@ _bfd_XXi_swap_scnhdr_out (bfd * abfd, void * in, void * out)
      sometimes).  */
   if ((scnhdr_int->s_flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0)
     {
      sometimes).  */
   if ((scnhdr_int->s_flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0)
     {
-      if (bfd_pe_executable_p (abfd))
+      if (bfd_pei_p (abfd))
        {
          ps = scnhdr_int->s_size;
          ss = 0;
        {
          ps = scnhdr_int->s_size;
          ss = 0;
@@ -892,7 +891,7 @@ _bfd_XXi_swap_scnhdr_out (bfd * abfd, void * in, void * out)
     }
   else
     {
     }
   else
     {
-      if (bfd_pe_executable_p (abfd))
+      if (bfd_pei_p (abfd))
        ps = scnhdr_int->s_paddr;
       else
        ps = 0;
        ps = scnhdr_int->s_paddr;
       else
        ps = 0;
@@ -1264,7 +1263,7 @@ pe_print_idata (bfd * abfd, void * vfile)
              else
                {
                  ft_idx = first_thunk - (ft_section->vma - extra->ImageBase);
              else
                {
                  ft_idx = first_thunk - (ft_section->vma - extra->ImageBase);
-                 ft_data = bfd_malloc (datasize);
+                 ft_data = (bfd_byte *) bfd_malloc (datasize);
                  if (ft_data == NULL)
                    continue;
 
                  if (ft_data == NULL)
                    continue;
 
@@ -1310,7 +1309,7 @@ pe_print_idata (bfd * abfd, void * vfile)
                  && first_thunk != 0
                  && first_thunk != hint_addr)
                fprintf (file, "\t%04lx",
                  && first_thunk != 0
                  && first_thunk != hint_addr)
                fprintf (file, "\t%04lx",
-                        (long) bfd_get_32 (abfd, ft_data + ft_idx + j));
+                        (unsigned long) bfd_get_32 (abfd, ft_data + ft_idx + j));
              fprintf (file, "\n");
            }
 #else
              fprintf (file, "\n");
            }
 #else
@@ -1342,7 +1341,7 @@ pe_print_idata (bfd * abfd, void * vfile)
                  && first_thunk != 0
                  && first_thunk != hint_addr)
                fprintf (file, "\t%04lx",
                  && first_thunk != 0
                  && first_thunk != hint_addr)
                fprintf (file, "\t%04lx",
-                        (long) bfd_get_32 (abfd, ft_data + ft_idx + j));
+                        (unsigned long) bfd_get_32 (abfd, ft_data + ft_idx + j));
 
              fprintf (file, "\n");
            }
 
              fprintf (file, "\n");
            }
@@ -1433,7 +1432,7 @@ pe_print_edata (bfd * abfd, void * vfile)
   fprintf (file, _("\nThere is an export table in %s at 0x%lx\n"),
           section->name, (unsigned long) addr);
 
   fprintf (file, _("\nThere is an export table in %s at 0x%lx\n"),
           section->name, (unsigned long) addr);
 
-  data = bfd_malloc (datasize);
+  data = (bfd_byte *) bfd_malloc (datasize);
   if (data == NULL)
     return FALSE;
 
   if (data == NULL)
     return FALSE;
 
@@ -1472,7 +1471,7 @@ pe_print_edata (bfd * abfd, void * vfile)
 
   fprintf (file,
           _("Name \t\t\t\t"));
 
   fprintf (file,
           _("Name \t\t\t\t"));
-  fprintf_vma (file, edt.name);
+  bfd_fprintf_vma (abfd, file, edt.name);
   fprintf (file,
           " %s\n", data + edt.name - adj);
 
   fprintf (file,
           " %s\n", data + edt.name - adj);
 
@@ -1494,17 +1493,17 @@ pe_print_edata (bfd * abfd, void * vfile)
 
   fprintf (file,
           _("\tExport Address Table \t\t"));
 
   fprintf (file,
           _("\tExport Address Table \t\t"));
-  fprintf_vma (file, edt.eat_addr);
+  bfd_fprintf_vma (abfd, file, edt.eat_addr);
   fprintf (file, "\n");
 
   fprintf (file,
           _("\tName Pointer Table \t\t"));
   fprintf (file, "\n");
 
   fprintf (file,
           _("\tName Pointer Table \t\t"));
-  fprintf_vma (file, edt.npt_addr);
+  bfd_fprintf_vma (abfd, file, edt.npt_addr);
   fprintf (file, "\n");
 
   fprintf (file,
           _("\tOrdinal Table \t\t\t"));
   fprintf (file, "\n");
 
   fprintf (file,
           _("\tOrdinal Table \t\t\t"));
-  fprintf_vma (file, edt.ot_addr);
+  bfd_fprintf_vma (abfd, file, edt.ot_addr);
   fprintf (file, "\n");
 
   /* The next table to find is the Export Address Table. It's basically
   fprintf (file, "\n");
 
   /* The next table to find is the Export Address Table. It's basically
@@ -1581,7 +1580,14 @@ pe_print_edata (bfd * abfd, void * vfile)
 /* This really is architecture dependent.  On IA-64, a .pdata entry
    consists of three dwords containing relative virtual addresses that
    specify the start and end address of the code range the entry
 /* This really is architecture dependent.  On IA-64, a .pdata entry
    consists of three dwords containing relative virtual addresses that
    specify the start and end address of the code range the entry
-   covers and the address of the corresponding unwind info data.  */
+   covers and the address of the corresponding unwind info data. 
+
+   On ARM and SH-4, a compressed PDATA structure is used :
+   _IMAGE_CE_RUNTIME_FUNCTION_ENTRY, whereas MIPS is documented to use
+   _IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY.
+   See http://msdn2.microsoft.com/en-us/library/ms253988(VS.80).aspx .
+
+   This is the version for uncompressed data.  */
 
 static bfd_boolean
 pe_print_pdata (bfd * abfd, void * vfile)
 
 static bfd_boolean
 pe_print_pdata (bfd * abfd, void * vfile)
@@ -1662,14 +1668,14 @@ pe_print_pdata (bfd * abfd, void * vfile)
       prolog_end_addr &= ~(bfd_vma) 0x3;
 
       fputc (' ', file);
       prolog_end_addr &= ~(bfd_vma) 0x3;
 
       fputc (' ', file);
-      fprintf_vma (file, i + section->vma); fputc ('\t', file);
-      fprintf_vma (file, begin_addr); fputc (' ', file);
-      fprintf_vma (file, end_addr); fputc (' ', file);
-      fprintf_vma (file, eh_handler);
+      bfd_fprintf_vma (abfd, file, i + section->vma); fputc ('\t', file);
+      bfd_fprintf_vma (abfd, file, begin_addr); fputc (' ', file);
+      bfd_fprintf_vma (abfd, file, end_addr); fputc (' ', file);
+      bfd_fprintf_vma (abfd, file, eh_handler);
 #if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64)
       fputc (' ', file);
 #if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64)
       fputc (' ', file);
-      fprintf_vma (file, eh_data); fputc (' ', file);
-      fprintf_vma (file, prolog_end_addr);
+      bfd_fprintf_vma (abfd, file, eh_data); fputc (' ', file);
+      bfd_fprintf_vma (abfd, file, prolog_end_addr);
       fprintf (file, "   %x", em_data);
 #endif
 
       fprintf (file, "   %x", em_data);
 #endif
 
@@ -1705,8 +1711,190 @@ pe_print_pdata (bfd * abfd, void * vfile)
   free (data);
 
   return TRUE;
   free (data);
 
   return TRUE;
+#undef PDATA_ROW_SIZE
+}
+
+typedef struct sym_cache
+{
+  int        symcount;
+  asymbol ** syms;
+} sym_cache;
+
+static asymbol **
+slurp_symtab (bfd *abfd, sym_cache *psc)
+{
+  asymbol ** sy = NULL;
+  long storage;
+
+  if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
+    {
+      psc->symcount = 0;
+      return NULL;
+    }
+
+  storage = bfd_get_symtab_upper_bound (abfd);
+  if (storage < 0)
+    return NULL;
+  if (storage)
+    sy = (asymbol **) bfd_malloc (storage);
+
+  psc->symcount = bfd_canonicalize_symtab (abfd, sy);
+  if (psc->symcount < 0)
+    return NULL;
+  return sy;
+}
+
+static const char *
+my_symbol_for_address (bfd *abfd, bfd_vma func, sym_cache *psc)
+{
+  int i;
+
+  if (psc->syms == 0)
+    psc->syms = slurp_symtab (abfd, psc);
+
+  for (i = 0; i < psc->symcount; i++)
+    {
+      if (psc->syms[i]->section->vma + psc->syms[i]->value == func)
+       return psc->syms[i]->name;
+    }
+
+  return NULL;
+}
+
+static void
+cleanup_syms (sym_cache *psc)
+{
+  psc->symcount = 0;
+  free (psc->syms);
+  psc->syms = NULL;
 }
 
 }
 
+/* This is the version for "compressed" pdata.  */
+
+bfd_boolean
+_bfd_XX_print_ce_compressed_pdata (bfd * abfd, void * vfile)
+{
+# define PDATA_ROW_SIZE        (2 * 4)
+  FILE *file = (FILE *) vfile;
+  bfd_byte *data = NULL;
+  asection *section = bfd_get_section_by_name (abfd, ".pdata");
+  bfd_size_type datasize = 0;
+  bfd_size_type i;
+  bfd_size_type start, stop;
+  int onaline = PDATA_ROW_SIZE;
+  struct sym_cache sym_cache = {0, 0} ;
+
+  if (section == NULL
+      || coff_section_data (abfd, section) == NULL
+      || pei_section_data (abfd, section) == NULL)
+    return TRUE;
+
+  stop = pei_section_data (abfd, section)->virt_size;
+  if ((stop % onaline) != 0)
+    fprintf (file,
+            _("Warning, .pdata section size (%ld) is not a multiple of %d\n"),
+            (long) stop, onaline);
+
+  fprintf (file,
+          _("\nThe Function Table (interpreted .pdata section contents)\n"));
+
+  fprintf (file, _("\
+ vma:\t\tBegin    Prolog   Function Flags    Exception EH\n\
+     \t\tAddress  Length   Length   32b exc  Handler   Data\n"));
+
+  datasize = section->size;
+  if (datasize == 0)
+    return TRUE;
+
+  if (! bfd_malloc_and_get_section (abfd, section, &data))
+    {
+      if (data != NULL)
+       free (data);
+      return FALSE;
+    }
+
+  start = 0;
+
+  for (i = start; i < stop; i += onaline)
+    {
+      bfd_vma begin_addr;
+      bfd_vma other_data;
+      bfd_vma prolog_length, function_length;
+      int flag32bit, exception_flag;
+      bfd_byte *tdata = 0;
+      asection *tsection;
+
+      if (i + PDATA_ROW_SIZE > stop)
+       break;
+
+      begin_addr = GET_PDATA_ENTRY (abfd, data + i     );
+      other_data = GET_PDATA_ENTRY (abfd, data + i +  4);
+
+      if (begin_addr == 0 && other_data == 0)
+       /* We are probably into the padding of the section now.  */
+       break;
+
+      prolog_length = (other_data & 0x000000FF);
+      function_length = (other_data & 0x3FFFFF00) >> 8;
+      flag32bit = (int)((other_data & 0x40000000) >> 30);
+      exception_flag = (int)((other_data & 0x80000000) >> 31);
+
+      fputc (' ', file);
+      bfd_fprintf_vma (abfd, file, i + section->vma); fputc ('\t', file);
+      bfd_fprintf_vma (abfd, file, begin_addr); fputc (' ', file);
+      bfd_fprintf_vma (abfd, file, prolog_length); fputc (' ', file);
+      bfd_fprintf_vma (abfd, file, function_length); fputc (' ', file);
+      fprintf (file, "%2d  %2d   ", flag32bit, exception_flag);
+
+      /* Get the exception handler's address and the data passed from the
+         .text section. This is really the data that belongs with the .pdata
+         but got "compressed" out for the ARM and SH4 architectures.  */
+      tsection = bfd_get_section_by_name (abfd, ".text");
+      if (tsection && coff_section_data (abfd, tsection)
+         && pei_section_data (abfd, tsection))
+       {
+         if (bfd_malloc_and_get_section (abfd, tsection, & tdata))
+           {
+             int xx = (begin_addr - 8) - tsection->vma;
+
+             tdata = (bfd_byte *) bfd_malloc (8);
+             if (bfd_get_section_contents (abfd, tsection, tdata, (bfd_vma) xx, 8))
+               {
+                 bfd_vma eh, eh_data;
+
+                 eh = bfd_get_32 (abfd, tdata);
+                 eh_data = bfd_get_32 (abfd, tdata + 4);
+                 fprintf (file, "%08x  ", (unsigned int) eh);
+                 fprintf (file, "%08x", (unsigned int) eh_data);
+                 if (eh != 0)
+                   {
+                     const char *s = my_symbol_for_address (abfd, eh, &sym_cache);
+
+                     if (s)
+                       fprintf (file, " (%s) ", s);
+                   }
+               }
+             free (tdata);
+           }
+         else
+           {
+             if (tdata)
+               free (tdata);
+           }
+       }
+
+      fprintf (file, "\n");
+    }
+
+  free (data);
+
+  cleanup_syms (& sym_cache);
+
+  return TRUE;
+#undef PDATA_ROW_SIZE
+}
+
+\f
 #define IMAGE_REL_BASED_HIGHADJ 4
 static const char * const tbl[] =
 {
 #define IMAGE_REL_BASED_HIGHADJ 4
 static const char * const tbl[] =
 {
@@ -1773,7 +1961,7 @@ pe_print_reloc (bfd * abfd, void * vfile)
 
       fprintf (file,
               _("\nVirtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n"),
 
       fprintf (file,
               _("\nVirtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n"),
-              (unsigned long) virtual_address, size, size, number);
+              (unsigned long) virtual_address, size, (unsigned long) size, number);
 
       for (j = 0; j < number; ++j)
        {
 
       for (j = 0; j < number; ++j)
        {
@@ -1786,7 +1974,7 @@ pe_print_reloc (bfd * abfd, void * vfile)
 
          fprintf (file,
                   _("\treloc %4d offset %4x [%4lx] %s"),
 
          fprintf (file,
                   _("\treloc %4d offset %4x [%4lx] %s"),
-                  j, off, (long) (off + virtual_address), tbl[t]);
+                  j, off, (unsigned long) (off + virtual_address), tbl[t]);
 
          /* HIGHADJ takes an argument, - the next record *is* the
             low 16 bits of addend.  */
 
          /* HIGHADJ takes an argument, - the next record *is* the
             low 16 bits of addend.  */
@@ -1876,37 +2064,37 @@ _bfd_XX_print_private_bfd_data_common (bfd * abfd, void * vfile)
     fprintf (file, "\t(%s)",name);
   fprintf (file, "\nMajorLinkerVersion\t%d\n", i->MajorLinkerVersion);
   fprintf (file, "MinorLinkerVersion\t%d\n", i->MinorLinkerVersion);
     fprintf (file, "\t(%s)",name);
   fprintf (file, "\nMajorLinkerVersion\t%d\n", i->MajorLinkerVersion);
   fprintf (file, "MinorLinkerVersion\t%d\n", i->MinorLinkerVersion);
-  fprintf (file, "SizeOfCode\t\t%08lx\n", i->SizeOfCode);
+  fprintf (file, "SizeOfCode\t\t%08lx\n", (unsigned long) i->SizeOfCode);
   fprintf (file, "SizeOfInitializedData\t%08lx\n",
   fprintf (file, "SizeOfInitializedData\t%08lx\n",
-          i->SizeOfInitializedData);
+          (unsigned long) i->SizeOfInitializedData);
   fprintf (file, "SizeOfUninitializedData\t%08lx\n",
   fprintf (file, "SizeOfUninitializedData\t%08lx\n",
-          i->SizeOfUninitializedData);
+          (unsigned long) i->SizeOfUninitializedData);
   fprintf (file, "AddressOfEntryPoint\t");
   fprintf (file, "AddressOfEntryPoint\t");
-  fprintf_vma (file, i->AddressOfEntryPoint);
+  bfd_fprintf_vma (abfd, file, i->AddressOfEntryPoint);
   fprintf (file, "\nBaseOfCode\t\t");
   fprintf (file, "\nBaseOfCode\t\t");
-  fprintf_vma (file, i->BaseOfCode);
+  bfd_fprintf_vma (abfd, file, i->BaseOfCode);
 #if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
   /* PE32+ does not have BaseOfData member!  */
   fprintf (file, "\nBaseOfData\t\t");
 #if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
   /* PE32+ does not have BaseOfData member!  */
   fprintf (file, "\nBaseOfData\t\t");
-  fprintf_vma (file, i->BaseOfData);
+  bfd_fprintf_vma (abfd, file, i->BaseOfData);
 #endif
 
   fprintf (file, "\nImageBase\t\t");
 #endif
 
   fprintf (file, "\nImageBase\t\t");
-  fprintf_vma (file, i->ImageBase);
+  bfd_fprintf_vma (abfd, file, i->ImageBase);
   fprintf (file, "\nSectionAlignment\t");
   fprintf (file, "\nSectionAlignment\t");
-  fprintf_vma (file, i->SectionAlignment);
+  bfd_fprintf_vma (abfd, file, i->SectionAlignment);
   fprintf (file, "\nFileAlignment\t\t");
   fprintf (file, "\nFileAlignment\t\t");
-  fprintf_vma (file, i->FileAlignment);
+  bfd_fprintf_vma (abfd, file, i->FileAlignment);
   fprintf (file, "\nMajorOSystemVersion\t%d\n", i->MajorOperatingSystemVersion);
   fprintf (file, "MinorOSystemVersion\t%d\n", i->MinorOperatingSystemVersion);
   fprintf (file, "MajorImageVersion\t%d\n", i->MajorImageVersion);
   fprintf (file, "MinorImageVersion\t%d\n", i->MinorImageVersion);
   fprintf (file, "MajorSubsystemVersion\t%d\n", i->MajorSubsystemVersion);
   fprintf (file, "MinorSubsystemVersion\t%d\n", i->MinorSubsystemVersion);
   fprintf (file, "\nMajorOSystemVersion\t%d\n", i->MajorOperatingSystemVersion);
   fprintf (file, "MinorOSystemVersion\t%d\n", i->MinorOperatingSystemVersion);
   fprintf (file, "MajorImageVersion\t%d\n", i->MajorImageVersion);
   fprintf (file, "MinorImageVersion\t%d\n", i->MinorImageVersion);
   fprintf (file, "MajorSubsystemVersion\t%d\n", i->MajorSubsystemVersion);
   fprintf (file, "MinorSubsystemVersion\t%d\n", i->MinorSubsystemVersion);
-  fprintf (file, "Win32Version\t\t%08lx\n", i->Reserved1);
-  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);
+  fprintf (file, "Win32Version\t\t%08lx\n", (unsigned long) i->Reserved1);
+  fprintf (file, "SizeOfImage\t\t%08lx\n", (unsigned long) i->SizeOfImage);
+  fprintf (file, "SizeOfHeaders\t\t%08lx\n", (unsigned long) i->SizeOfHeaders);
+  fprintf (file, "CheckSum\t\t%08lx\n", (unsigned long) i->CheckSum);
 
   switch (i->Subsystem)
     {
 
   switch (i->Subsystem)
     {
@@ -1928,6 +2116,7 @@ _bfd_XX_print_private_bfd_data_common (bfd * abfd, void * vfile)
     case IMAGE_SUBSYSTEM_WINDOWS_CE_GUI:
       subsystem_name = "Wince CUI";
       break;
     case IMAGE_SUBSYSTEM_WINDOWS_CE_GUI:
       subsystem_name = "Wince CUI";
       break;
+    // These are from UEFI Platform Initialization Specification 1.1.
     case IMAGE_SUBSYSTEM_EFI_APPLICATION:
       subsystem_name = "EFI application";
       break;
     case IMAGE_SUBSYSTEM_EFI_APPLICATION:
       subsystem_name = "EFI application";
       break;
@@ -1937,10 +2126,10 @@ _bfd_XX_print_private_bfd_data_common (bfd * abfd, void * vfile)
     case IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
       subsystem_name = "EFI runtime driver";
       break;
     case IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
       subsystem_name = "EFI runtime driver";
       break;
-    // These are from revision 8.0 of the MS PE/COFF spec
-    case IMAGE_SUBSYSTEM_EFI_ROM:
-      subsystem_name = "EFI ROM";
+    case IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER:
+      subsystem_name = "SAL runtime driver";
       break;
       break;
+    // This is from revision 8.0 of the MS PE/COFF spec
     case IMAGE_SUBSYSTEM_XBOX:
       subsystem_name = "XBOX";
       break;
     case IMAGE_SUBSYSTEM_XBOX:
       subsystem_name = "XBOX";
       break;
@@ -1954,28 +2143,32 @@ _bfd_XX_print_private_bfd_data_common (bfd * abfd, void * vfile)
     fprintf (file, "\t(%s)", subsystem_name);
   fprintf (file, "\nDllCharacteristics\t%08x\n", i->DllCharacteristics);
   fprintf (file, "SizeOfStackReserve\t");
     fprintf (file, "\t(%s)", subsystem_name);
   fprintf (file, "\nDllCharacteristics\t%08x\n", i->DllCharacteristics);
   fprintf (file, "SizeOfStackReserve\t");
-  fprintf_vma (file, i->SizeOfStackReserve);
+  bfd_fprintf_vma (abfd, file, i->SizeOfStackReserve);
   fprintf (file, "\nSizeOfStackCommit\t");
   fprintf (file, "\nSizeOfStackCommit\t");
-  fprintf_vma (file, i->SizeOfStackCommit);
+  bfd_fprintf_vma (abfd, file, i->SizeOfStackCommit);
   fprintf (file, "\nSizeOfHeapReserve\t");
   fprintf (file, "\nSizeOfHeapReserve\t");
-  fprintf_vma (file, i->SizeOfHeapReserve);
+  bfd_fprintf_vma (abfd, file, i->SizeOfHeapReserve);
   fprintf (file, "\nSizeOfHeapCommit\t");
   fprintf (file, "\nSizeOfHeapCommit\t");
-  fprintf_vma (file, i->SizeOfHeapCommit);
-  fprintf (file, "\nLoaderFlags\t\t%08lx\n", i->LoaderFlags);
-  fprintf (file, "NumberOfRvaAndSizes\t%08lx\n", i->NumberOfRvaAndSizes);
+  bfd_fprintf_vma (abfd, file, i->SizeOfHeapCommit);
+  fprintf (file, "\nLoaderFlags\t\t%08lx\n", (unsigned long) i->LoaderFlags);
+  fprintf (file, "NumberOfRvaAndSizes\t%08lx\n",
+          (unsigned long) i->NumberOfRvaAndSizes);
 
   fprintf (file, "\nThe Data Directory\n");
   for (j = 0; j < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; j++)
     {
       fprintf (file, "Entry %1x ", j);
 
   fprintf (file, "\nThe Data Directory\n");
   for (j = 0; j < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; j++)
     {
       fprintf (file, "Entry %1x ", j);
-      fprintf_vma (file, i->DataDirectory[j].VirtualAddress);
-      fprintf (file, " %08lx ", i->DataDirectory[j].Size);
+      bfd_fprintf_vma (abfd, file, i->DataDirectory[j].VirtualAddress);
+      fprintf (file, " %08lx ", (unsigned long) i->DataDirectory[j].Size);
       fprintf (file, "%s\n", dir_names[j]);
     }
 
   pe_print_idata (abfd, vfile);
   pe_print_edata (abfd, vfile);
       fprintf (file, "%s\n", dir_names[j]);
     }
 
   pe_print_idata (abfd, vfile);
   pe_print_edata (abfd, vfile);
-  pe_print_pdata (abfd, vfile);
+  if (bfd_coff_have_print_pdata (abfd))
+    bfd_coff_print_pdata (abfd, vfile);
+  else
+    pe_print_pdata (abfd, vfile);
   pe_print_reloc (abfd, vfile);
 
   return TRUE;
   pe_print_reloc (abfd, vfile);
 
   return TRUE;
@@ -1987,13 +2180,22 @@ _bfd_XX_print_private_bfd_data_common (bfd * abfd, void * vfile)
 bfd_boolean
 _bfd_XX_bfd_copy_private_bfd_data_common (bfd * ibfd, bfd * obfd)
 {
 bfd_boolean
 _bfd_XX_bfd_copy_private_bfd_data_common (bfd * ibfd, bfd * obfd)
 {
+  pe_data_type *ipe, *ope;
+
   /* 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;
 
   /* 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;
 
-  pe_data (obfd)->pe_opthdr = pe_data (ibfd)->pe_opthdr;
-  pe_data (obfd)->dll = pe_data (ibfd)->dll;
+  ipe = pe_data (ibfd);
+  ope = pe_data (obfd);
+  /* pe_opthdr is copied in copy_object.  */
+  ope->dll = ipe->dll;
+
+  /* Don't copy input subsystem if output is different from input.  */
+  if (obfd->xvec != ibfd->xvec)
+    ope->pe_opthdr.Subsystem = IMAGE_SUBSYSTEM_UNKNOWN;
 
   /* For strip: if we removed .reloc, we'll make a real mess of things
      if we don't remove this entry as well.  */
 
   /* For strip: if we removed .reloc, we'll make a real mess of things
      if we don't remove this entry as well.  */
@@ -2076,7 +2278,9 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
       /* PR ld/2729: We cannot rely upon all the output sections having been 
         created properly, so check before referencing them.  Issue a warning
         message for any sections tht could not be found.  */
       /* PR ld/2729: We cannot rely upon all the output sections having been 
         created properly, so check before referencing them.  Issue a warning
         message for any sections tht could not be found.  */
-      if (h1->root.u.def.section != NULL
+      if ((h1->root.type == bfd_link_hash_defined
+          || h1->root.type == bfd_link_hash_defweak)
+         && h1->root.u.def.section != NULL
          && h1->root.u.def.section->output_section != NULL)
        pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_TABLE].VirtualAddress =
          (h1->root.u.def.value
          && h1->root.u.def.section->output_section != NULL)
        pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_TABLE].VirtualAddress =
          (h1->root.u.def.value
@@ -2093,6 +2297,8 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
       h1 = coff_link_hash_lookup (coff_hash_table (info),
                                  ".idata$4", FALSE, FALSE, TRUE);
       if (h1 != NULL
       h1 = coff_link_hash_lookup (coff_hash_table (info),
                                  ".idata$4", FALSE, FALSE, TRUE);
       if (h1 != NULL
+         && (h1->root.type == bfd_link_hash_defined
+          || h1->root.type == bfd_link_hash_defweak)
          && h1->root.u.def.section != NULL
          && h1->root.u.def.section->output_section != NULL)
        pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_TABLE].Size =
          && h1->root.u.def.section != NULL
          && h1->root.u.def.section->output_section != NULL)
        pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_TABLE].Size =
@@ -2113,6 +2319,8 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
       h1 = coff_link_hash_lookup (coff_hash_table (info),
                                  ".idata$5", FALSE, FALSE, TRUE);
       if (h1 != NULL
       h1 = coff_link_hash_lookup (coff_hash_table (info),
                                  ".idata$5", FALSE, FALSE, TRUE);
       if (h1 != NULL
+         && (h1->root.type == bfd_link_hash_defined
+          || h1->root.type == bfd_link_hash_defweak)
          && h1->root.u.def.section != NULL
          && h1->root.u.def.section->output_section != NULL)
        pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE].VirtualAddress =
          && h1->root.u.def.section != NULL
          && h1->root.u.def.section->output_section != NULL)
        pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE].VirtualAddress =
@@ -2130,6 +2338,8 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
       h1 = coff_link_hash_lookup (coff_hash_table (info),
                                  ".idata$6", FALSE, FALSE, TRUE);
       if (h1 != NULL
       h1 = coff_link_hash_lookup (coff_hash_table (info),
                                  ".idata$6", FALSE, FALSE, TRUE);
       if (h1 != NULL
+         && (h1->root.type == bfd_link_hash_defined
+          || h1->root.type == bfd_link_hash_defweak)
          && h1->root.u.def.section != NULL
          && h1->root.u.def.section->output_section != NULL)
        pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE].Size =
          && h1->root.u.def.section != NULL
          && h1->root.u.def.section->output_section != NULL)
        pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE].Size =
@@ -2150,7 +2360,9 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
                              "__tls_used", FALSE, FALSE, TRUE);
   if (h1 != NULL)
     {
                              "__tls_used", FALSE, FALSE, TRUE);
   if (h1 != NULL)
     {
-      if (h1->root.u.def.section != NULL
+      if ((h1->root.type == bfd_link_hash_defined
+          || h1->root.type == bfd_link_hash_defweak)
+         && h1->root.u.def.section != NULL
          && h1->root.u.def.section->output_section != NULL)
        pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].VirtualAddress =
          (h1->root.u.def.value
          && h1->root.u.def.section->output_section != NULL)
        pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].VirtualAddress =
          (h1->root.u.def.value