common/filestuff.c: No sockets on DJGPP.
[deliverable/binutils-gdb.git] / bfd / peXXigen.c
index a95af9cd8680565b253587bdb22dce34543b2839..d0f7a96e1f96d6defed8ac6c3c941db092040c55 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,
-   2005, 2006, 2007, 2008, 2009  Free Software Foundation, Inc.
+   2005, 2006, 2007, 2008, 2009, 2010  Free Software Foundation, Inc.
    Written by Cygnus Solutions.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -62,6 +62,7 @@
 #include "bfd.h"
 #include "libbfd.h"
 #include "coff/internal.h"
+#include "bfdver.h"
 
 /* NOTE: it's strange to be including an architecture specific header
    in what's supposed to be general (to PE/PEI) code.  However, that's
@@ -129,6 +130,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)
     {
+      char namebuf[SYMNMLEN + 1];
+      const char *name = NULL;
+
       in->n_value = 0x0;
 
       /* Create synthetic empty sections as needed.  DJ */
@@ -136,33 +140,38 @@ _bfd_XXi_swap_sym_in (bfd * abfd, void * ext1, void * in1)
        {
          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;
-         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, (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);
+         if (sec == NULL)
+           /* FIXME: Return error.  */
+           abort ();
 
          sec->vma = 0;
          sec->lma = 0;
@@ -223,7 +232,7 @@ void
 _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)
@@ -231,7 +240,7 @@ _bfd_XXi_swap_aux_in (bfd * abfd,
   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)
@@ -262,7 +271,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);
 
-  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);
@@ -294,7 +304,7 @@ unsigned int
 _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)
@@ -304,7 +314,7 @@ _bfd_XXi_swap_aux_out (bfd *  abfd,
 
   memset (ext, 0, AUXESZ);
 
-  switch (class)
+  switch (in_class)
     {
     case C_FILE:
       if (in->x_file.x_fname[0] == 0)
@@ -336,7 +346,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);
 
-  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);
@@ -450,7 +461,7 @@ _bfd_XXi_swap_aouthdr_in (bfd * abfd,
   {
     int idx;
 
-    for (idx = 0; idx < 16; idx++)
+    for (idx = 0; idx < a->NumberOfRvaAndSizes; idx++)
       {
         /* If data directory is empty, rva also should be 0.  */
        int size =
@@ -539,17 +550,6 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
   PEAOUTHDR *aouthdr_out = (PEAOUTHDR *) out;
   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;
@@ -558,7 +558,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
   idata2 = pe->pe_opthdr.DataDirectory[PE_IMPORT_TABLE];
   idata5 = pe->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE];
   tls = pe->pe_opthdr.DataDirectory[PE_TLS_TABLE];
-  
+
   if (aouthdr_in->tsize)
     {
       aouthdr_in->text_start -= ib;
@@ -591,9 +591,6 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
 
   extra->NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
 
-  /* First null out all data directory entries.  */
-  memset (extra->DataDirectory, 0, sizeof (extra->DataDirectory));
-
   add_data_entry (abfd, extra, 0, ".edata", ib);
   add_data_entry (abfd, extra, 2, ".rsrc", ib);
   add_data_entry (abfd, extra, 3, ".pdata", ib);
@@ -615,7 +612,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
     /* 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),
@@ -667,7 +664,8 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
 
   H_PUT_16 (abfd, aouthdr_in->magic, aouthdr_out->standard.magic);
 
-#define LINKER_VERSION 256 /* That is, 2.56 */
+/* e.g. 219510000 is linker version 2.19  */
+#define LINKER_VERSION ((short) (BFD_VERSION / 1000000))
 
   /* This piece of magic sets the "linker version" field to
      LINKER_VERSION.  */
@@ -739,7 +737,8 @@ _bfd_XXi_only_swap_filehdr_out (bfd * abfd, void * in, void * out)
   struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in;
   struct external_PEI_filehdr *filehdr_out = (struct external_PEI_filehdr *) out;
 
-  if (pe_data (abfd)->has_reloc_section)
+  if (pe_data (abfd)->has_reloc_section
+      || pe_data (abfd)->dont_strip_reloc)
     filehdr_in->f_flags &= ~F_RELFLG;
 
   if (pe_data (abfd)->dll)
@@ -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)
     {
-      if (bfd_pe_executable_p (abfd))
+      if (bfd_pei_p (abfd))
        {
          ps = scnhdr_int->s_size;
          ss = 0;
@@ -892,7 +891,7 @@ _bfd_XXi_swap_scnhdr_out (bfd * abfd, void * in, void * out)
     }
   else
     {
-      if (bfd_pe_executable_p (abfd))
+      if (bfd_pei_p (abfd))
        ps = scnhdr_int->s_paddr;
       else
        ps = 0;
@@ -924,7 +923,7 @@ _bfd_XXi_swap_scnhdr_out (bfd * abfd, void * in, void * out)
        (0x02000000).  Also, the resource data should also be read and
        writable.  */
 
-    /* FIXME: Alignment is also encoded in this field, at least on PPC and 
+    /* 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 ?  */
 
@@ -934,7 +933,7 @@ _bfd_XXi_swap_scnhdr_out (bfd * abfd, void * in, void * out)
       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 },
@@ -1108,7 +1107,6 @@ pe_print_idata (bfd * abfd, void * vfile)
           section->name, (unsigned long) addr);
 
   dataoff = addr - section->vma;
-  datasize -= dataoff;
 
 #ifdef POWERPC_LE_PE
   if (rel_section != 0 && rel_section->size != 0)
@@ -1181,7 +1179,7 @@ pe_print_idata (bfd * abfd, void * vfile)
   adj = section->vma - extra->ImageBase;
 
   /* Print all image import descriptors.  */
-  for (i = 0; i < datasize; i += onaline)
+  for (i = dataoff; i + onaline <= datasize; i += onaline)
     {
       bfd_vma hint_addr;
       bfd_vma time_stamp;
@@ -1193,12 +1191,12 @@ pe_print_idata (bfd * abfd, void * vfile)
       char *dll;
 
       /* Print (i + extra->DataDirectory[PE_IMPORT_TABLE].VirtualAddress).  */
-      fprintf (file, " %08lx\t", (unsigned long) (i + adj + dataoff));
-      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);
-      dll_name = bfd_get_32 (abfd, data + i + 12 + dataoff);
-      first_thunk = bfd_get_32 (abfd, data + i + 16 + dataoff);
+      fprintf (file, " %08lx\t", (unsigned long) (i + adj));
+      hint_addr = bfd_get_32 (abfd, data + i);
+      time_stamp = bfd_get_32 (abfd, data + i + 4);
+      forward_chain = bfd_get_32 (abfd, data + i + 8);
+      dll_name = bfd_get_32 (abfd, data + i + 12);
+      first_thunk = bfd_get_32 (abfd, data + i + 16);
 
       fprintf (file, "%08lx %08lx %08lx %08lx %08lx\n",
               (unsigned long) hint_addr,
@@ -1223,16 +1221,17 @@ pe_print_idata (bfd * abfd, void * vfile)
          bfd_vma ft_addr;
          bfd_size_type ft_datasize;
          int ft_idx;
-         int ft_allocated = 0;
+         int ft_allocated;
 
          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; 
+         ft_data = data + ft_idx;
+         ft_datasize = datasize - ft_idx;
+         ft_allocated = 0;
 
          if (first_thunk != hint_addr)
            {
@@ -1241,9 +1240,8 @@ pe_print_idata (bfd * abfd, void * vfile)
                   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)
+                     && ft_addr < ft_section->vma + ft_section->size)
                    break;
                }
 
@@ -1256,34 +1254,28 @@ pe_print_idata (bfd * abfd, void * vfile)
 
              /* 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
+             if (ft_section != section)
                {
                  ft_idx = first_thunk - (ft_section->vma - extra->ImageBase);
-                 ft_data = bfd_malloc (datasize);
+                 ft_datasize = ft_section->size - ft_idx;
+                 ft_data = (bfd_byte *) bfd_malloc (ft_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))
+                 /* Read ft_datasize bytes starting at offset ft_idx.  */
+                 if (!bfd_get_section_contents (abfd, ft_section, ft_data,
+                                                (bfd_vma) ft_idx, ft_datasize))
                    {
                      free (ft_data);
                      continue;
                    }
-
-                 ft_idx = 0;
                  ft_allocated = 1;
                }
            }
 
          /* Print HintName vector entries.  */
 #ifdef COFF_WITH_pex64
-         for (j = 0; j < datasize; j += 8)
+         for (j = 0; idx + j + 8 <= datasize; j += 8)
            {
              unsigned long member = bfd_get_32 (abfd, data + idx + j);
              unsigned long member_high = bfd_get_32 (abfd, data + idx + j + 4);
@@ -1308,17 +1300,18 @@ pe_print_idata (bfd * abfd, void * vfile)
                 table holds actual addresses.  */
              if (time_stamp != 0
                  && first_thunk != 0
-                 && first_thunk != hint_addr)
+                 && first_thunk != hint_addr
+                 && j + 4 <= ft_datasize)
                fprintf (file, "\t%04lx",
-                        (unsigned long) bfd_get_32 (abfd, ft_data + ft_idx + j));
+                        (unsigned long) bfd_get_32 (abfd, ft_data + j));
              fprintf (file, "\n");
            }
 #else
-         for (j = 0; j < datasize; j += 4)
+         for (j = 0; idx + j + 4 <= datasize; j += 4)
            {
              unsigned long member = bfd_get_32 (abfd, data + idx + j);
 
-             /* Print single IMAGE_IMPORT_BY_NAME vector.  */ 
+             /* Print single IMAGE_IMPORT_BY_NAME vector.  */
              if (member == 0)
                break;
 
@@ -1340,9 +1333,10 @@ pe_print_idata (bfd * abfd, void * vfile)
                 table holds actual addresses.  */
              if (time_stamp != 0
                  && first_thunk != 0
-                 && first_thunk != hint_addr)
+                 && first_thunk != hint_addr
+                 && j + 4 <= ft_datasize)
                fprintf (file, "\t%04lx",
-                        (unsigned long) bfd_get_32 (abfd, ft_data + ft_idx + j));
+                        (unsigned long) bfd_get_32 (abfd, ft_data + j));
 
              fprintf (file, "\n");
            }
@@ -1433,7 +1427,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);
 
-  data = bfd_malloc (datasize);
+  data = (bfd_byte *) bfd_malloc (datasize);
   if (data == NULL)
     return FALSE;
 
@@ -1472,7 +1466,7 @@ pe_print_edata (bfd * abfd, void * vfile)
 
   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);
 
@@ -1494,17 +1488,17 @@ pe_print_edata (bfd * abfd, void * vfile)
 
   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_vma (file, edt.npt_addr);
+  bfd_fprintf_vma (abfd, file, edt.npt_addr);
   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
@@ -1581,7 +1575,7 @@ 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
-   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
@@ -1648,7 +1642,9 @@ pe_print_pdata (bfd * abfd, void * vfile)
       bfd_vma eh_handler;
       bfd_vma eh_data;
       bfd_vma prolog_end_addr;
+#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64)
       int em_data;
+#endif
 
       if (i + PDATA_ROW_SIZE > stop)
        break;
@@ -1664,19 +1660,21 @@ pe_print_pdata (bfd * abfd, void * vfile)
        /* We are probably into the padding of the section now.  */
        break;
 
+#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64)
       em_data = ((eh_handler & 0x1) << 2) | (prolog_end_addr & 0x3);
+#endif
       eh_handler &= ~(bfd_vma) 0x3;
       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);
-      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
 
@@ -1737,7 +1735,7 @@ slurp_symtab (bfd *abfd, sym_cache *psc)
   if (storage < 0)
     return NULL;
   if (storage)
-    sy = bfd_malloc (storage);
+    sy = (asymbol **) bfd_malloc (storage);
 
   psc->symcount = bfd_canonicalize_symtab (abfd, sy);
   if (psc->symcount < 0)
@@ -1783,7 +1781,7 @@ _bfd_XX_print_ce_compressed_pdata (bfd * abfd, void * vfile)
   bfd_size_type i;
   bfd_size_type start, stop;
   int onaline = PDATA_ROW_SIZE;
-  struct sym_cache sym_cache = {0, 0} ;
+  struct sym_cache cache = {0, 0} ;
 
   if (section == NULL
       || coff_section_data (abfd, section) == NULL
@@ -1822,7 +1820,6 @@ _bfd_XX_print_ce_compressed_pdata (bfd * abfd, void * vfile)
       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)
@@ -1841,10 +1838,10 @@ _bfd_XX_print_ce_compressed_pdata (bfd * abfd, void * vfile)
       exception_flag = (int)((other_data & 0x80000000) >> 31);
 
       fputc (' ', file);
-      fprintf_vma (file, i + section->vma); fputc ('\t', file);
-      fprintf_vma (file, begin_addr); fputc (' ', file);
-      fprintf_vma (file, prolog_length); fputc (' ', file);
-      fprintf_vma (file, function_length); 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
@@ -1854,12 +1851,13 @@ _bfd_XX_print_ce_compressed_pdata (bfd * abfd, void * vfile)
       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;
+         bfd_vma eh_off = (begin_addr - 8) - tsection->vma;
+         bfd_byte *tdata;
 
-             tdata = bfd_malloc (8);
-             if (bfd_get_section_contents (abfd, tsection, tdata, (bfd_vma) xx, 8))
+         tdata = (bfd_byte *) bfd_malloc (8);
+         if (tdata)
+           {
+             if (bfd_get_section_contents (abfd, tsection, tdata, eh_off, 8))
                {
                  bfd_vma eh, eh_data;
 
@@ -1869,7 +1867,7 @@ _bfd_XX_print_ce_compressed_pdata (bfd * abfd, void * vfile)
                  fprintf (file, "%08x", (unsigned int) eh_data);
                  if (eh != 0)
                    {
-                     const char *s = my_symbol_for_address (abfd, eh, &sym_cache);
+                     const char *s = my_symbol_for_address (abfd, eh, &cache);
 
                      if (s)
                        fprintf (file, " (%s) ", s);
@@ -1877,11 +1875,6 @@ _bfd_XX_print_ce_compressed_pdata (bfd * abfd, void * vfile)
                }
              free (tdata);
            }
-         else
-           {
-             if (tdata)
-               free (tdata);
-           }
        }
 
       fprintf (file, "\n");
@@ -1889,91 +1882,12 @@ _bfd_XX_print_ce_compressed_pdata (bfd * abfd, void * vfile)
 
   free (data);
 
-  cleanup_syms (& sym_cache);
+  cleanup_syms (& cache);
 
   return TRUE;
 #undef PDATA_ROW_SIZE
 }
 
-/* The PE+ x64 variant.  */
-bfd_boolean
-_bfd_pep_print_x64_pdata (bfd *abfd, void *vfile)
-{
-# define PDATA_ROW_SIZE        (3 * 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\t\tBeginAddress\t EndAddress\t  UnwindData\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 end_addr;
-      bfd_vma unwind_data_addr;
-
-      if (i + PDATA_ROW_SIZE > stop)
-       break;
-
-      begin_addr = bfd_get_32 (abfd, data + i);
-      end_addr = bfd_get_32 (abfd, data + i + 4);
-      unwind_data_addr = bfd_get_32 (abfd, data + i +  8);
-
-      if (begin_addr == 0 && end_addr == 0 && unwind_data_addr == 0)
-       /* We are probably into the padding of the section now.  */
-       break;
-
-      fputc (' ', file);
-      fprintf_vma (file, i + section->vma);
-      fprintf (file, ":\t");
-      fprintf_vma (file, begin_addr);
-      fputc (' ', file);
-      fprintf_vma (file, end_addr);
-      fputc (' ', file);
-      fprintf_vma (file, unwind_data_addr);
-
-      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[] =
@@ -1999,7 +1913,6 @@ 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;
   bfd_size_type i;
   bfd_size_type start, stop;
 
@@ -2012,7 +1925,6 @@ pe_print_reloc (bfd * abfd, void * vfile)
   fprintf (file,
           _("\n\nPE File Base Relocations (interpreted .reloc section contents)\n"));
 
-  datasize = section->size;
   if (! bfd_malloc_and_get_section (abfd, section, &data))
     {
       if (data != NULL)
@@ -2150,21 +2062,21 @@ _bfd_XX_print_private_bfd_data_common (bfd * abfd, void * vfile)
   fprintf (file, "SizeOfUninitializedData\t%08lx\n",
           (unsigned long) i->SizeOfUninitializedData);
   fprintf (file, "AddressOfEntryPoint\t");
-  fprintf_vma (file, i->AddressOfEntryPoint);
+  bfd_fprintf_vma (abfd, file, i->AddressOfEntryPoint);
   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");
-  fprintf_vma (file, i->BaseOfData);
+  bfd_fprintf_vma (abfd, file, i->BaseOfData);
 #endif
 
   fprintf (file, "\nImageBase\t\t");
-  fprintf_vma (file, i->ImageBase);
+  bfd_fprintf_vma (abfd, file, i->ImageBase);
   fprintf (file, "\nSectionAlignment\t");
-  fprintf_vma (file, i->SectionAlignment);
+  bfd_fprintf_vma (abfd, file, i->SectionAlignment);
   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);
@@ -2196,6 +2108,7 @@ _bfd_XX_print_private_bfd_data_common (bfd * abfd, void * vfile)
     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;
@@ -2205,10 +2118,10 @@ _bfd_XX_print_private_bfd_data_common (bfd * abfd, void * vfile)
     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;
+    // This is from revision 8.0 of the MS PE/COFF spec
     case IMAGE_SUBSYSTEM_XBOX:
       subsystem_name = "XBOX";
       break;
@@ -2222,13 +2135,13 @@ _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_vma (file, i->SizeOfStackReserve);
+  bfd_fprintf_vma (abfd, file, i->SizeOfStackReserve);
   fprintf (file, "\nSizeOfStackCommit\t");
-  fprintf_vma (file, i->SizeOfStackCommit);
+  bfd_fprintf_vma (abfd, file, i->SizeOfStackCommit);
   fprintf (file, "\nSizeOfHeapReserve\t");
-  fprintf_vma (file, i->SizeOfHeapReserve);
+  bfd_fprintf_vma (abfd, file, i->SizeOfHeapReserve);
   fprintf (file, "\nSizeOfHeapCommit\t");
-  fprintf_vma (file, i->SizeOfHeapCommit);
+  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);
@@ -2237,7 +2150,7 @@ _bfd_XX_print_private_bfd_data_common (bfd * abfd, void * vfile)
   for (j = 0; j < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; j++)
     {
       fprintf (file, "Entry %1x ", j);
-      fprintf_vma (file, i->DataDirectory[j].VirtualAddress);
+      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]);
     }
@@ -2268,8 +2181,8 @@ _bfd_XX_bfd_copy_private_bfd_data_common (bfd * ibfd, bfd * obfd)
 
   ipe = pe_data (ibfd);
   ope = pe_data (obfd);
-  ope->pe_opthdr = ipe->pe_opthdr;
+
+  /* pe_opthdr is copied in copy_object.  */
   ope->dll = ipe->dll;
 
   /* Don't copy input subsystem if output is different from input.  */
@@ -2283,6 +2196,14 @@ _bfd_XX_bfd_copy_private_bfd_data_common (bfd * ibfd, bfd * obfd)
       pe_data (obfd)->pe_opthdr.DataDirectory[PE_BASE_RELOCATION_TABLE].VirtualAddress = 0;
       pe_data (obfd)->pe_opthdr.DataDirectory[PE_BASE_RELOCATION_TABLE].Size = 0;
     }
+
+  /* For PIE, if there is .reloc, we won't add IMAGE_FILE_RELOCS_STRIPPED.
+     But there is no .reloc, we make sure that IMAGE_FILE_RELOCS_STRIPPED
+     won't be added.  */
+  if (! pe_data (ibfd)->has_reloc_section
+      && ! (pe_data (ibfd)->real_flags & IMAGE_FILE_RELOCS_STRIPPED))
+    pe_data (obfd)->dont_strip_reloc = 1;
+
   return TRUE;
 }
 
@@ -2332,6 +2253,21 @@ _bfd_XX_get_symbol_info (bfd * abfd, asymbol *symbol, symbol_info *ret)
   coff_get_symbol_info (abfd, symbol, ret);
 }
 
+#if !defined(COFF_WITH_pep) && defined(COFF_WITH_pex64)
+static int
+sort_x64_pdata (const void *l, const void *r)
+{
+  const char *lp = (const char *) l;
+  const char *rp = (const char *) r;
+  bfd_vma vl, vr;
+  vl = bfd_getl32 (lp); vr = bfd_getl32 (rp);
+  if (vl != vr)
+    return (vl < vr ? -1 : 1);
+  /* We compare just begin address.  */
+  return 0;
+}
+#endif
+
 /* Handle the .idata section and other things that need symbol table
    access.  */
 
@@ -2354,7 +2290,7 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
                              ".idata$2", FALSE, FALSE, TRUE);
   if (h1 != NULL)
     {
-      /* PR ld/2729: We cannot rely upon all the output sections having been 
+      /* 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.type == bfd_link_hash_defined
@@ -2368,7 +2304,7 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
       else
        {
          _bfd_error_handler
-           (_("%B: unable to fill in DataDictionary[1] because .idata$2 is missing"), 
+           (_("%B: unable to fill in DataDictionary[1] because .idata$2 is missing"),
             abfd);
          result = FALSE;
        }
@@ -2388,7 +2324,7 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
       else
        {
          _bfd_error_handler
-           (_("%B: unable to fill in DataDictionary[1] because .idata$4 is missing"), 
+           (_("%B: unable to fill in DataDictionary[1] because .idata$4 is missing"),
             abfd);
          result = FALSE;
        }
@@ -2409,7 +2345,7 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
       else
        {
          _bfd_error_handler
-           (_("%B: unable to fill in DataDictionary[12] because .idata$5 is missing"), 
+           (_("%B: unable to fill in DataDictionary[12] because .idata$5 is missing"),
             abfd);
          result = FALSE;
        }
@@ -2425,18 +2361,63 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
          ((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[PE_IMPORT_ADDRESS_TABLE].VirtualAddress);      
+          - pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE].VirtualAddress);
       else
        {
          _bfd_error_handler
-           (_("%B: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE (12)] because .idata$6 is missing"), 
+           (_("%B: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE (12)] because .idata$6 is missing"),
             abfd);
          result = FALSE;
        }
     }
+  else
+    {
+      h1 = coff_link_hash_lookup (coff_hash_table (info),
+                                 "__IAT_start__", 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)
+       {
+         bfd_vma iat_va;
+
+         iat_va =
+           (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),
+                                     "__IAT_end__", 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.value
+                 + h1->root.u.def.section->output_section->vma
+                 + h1->root.u.def.section->output_offset)
+                - iat_va);
+             if (pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE].Size != 0)
+               pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE].VirtualAddress =
+                 iat_va - pe_data (abfd)->pe_opthdr.ImageBase;
+           }
+         else
+           {
+             _bfd_error_handler
+               (_("%B: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE(12)]"
+                  " because .idata$6 is missing"), abfd);
+             result = FALSE;
+           }
+        }
+    }
 
   h1 = coff_link_hash_lookup (coff_hash_table (info),
-                             "__tls_used", FALSE, FALSE, TRUE);
+                             (bfd_get_symbol_leading_char(abfd) != 0
+                              ? "__tls_used" : "_tls_used"),
+                             FALSE, FALSE, TRUE);
   if (h1 != NULL)
     {
       if ((h1->root.type == bfd_link_hash_defined
@@ -2451,14 +2432,51 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
       else
        {
          _bfd_error_handler
-           (_("%B: unable to fill in DataDictionary[9] because __tls_used is missing"), 
+           (_("%B: unable to fill in DataDictionary[9] because __tls_used is missing"),
             abfd);
          result = FALSE;
        }
-
+     /* According to PECOFF sepcifications by Microsoft version 8.2
+       the TLS data directory consists of 4 pointers, followed
+       by two 4-byte integer. This implies that the total size
+       is different for 32-bit and 64-bit executables.  */
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
       pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].Size = 0x18;
+#else
+      pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].Size = 0x28;
+#endif
     }
 
+/* If there is a .pdata section and we have linked pdata finally, we
+     need to sort the entries ascending.  */
+#if !defined(COFF_WITH_pep) && defined(COFF_WITH_pex64)
+  {
+    asection *sec = bfd_get_section_by_name (abfd, ".pdata");
+
+    if (sec)
+      {
+       bfd_size_type x = sec->rawsize;
+       bfd_byte *tmp_data = NULL;
+
+       if (x)
+         tmp_data = bfd_malloc (x);
+
+       if (tmp_data != NULL)
+         {
+           if (bfd_get_section_contents (abfd, sec, tmp_data, 0, x))
+             {
+               qsort (tmp_data,
+                      (size_t) (x / 12),
+                      12, sort_x64_pdata);
+               bfd_set_section_contents (pfinfo->output_bfd, sec,
+                                         tmp_data, 0, x);
+             }
+           free (tmp_data);
+         }
+      }
+  }
+#endif
+
   /* 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....  */
This page took 0.042066 seconds and 4 git commands to generate.