2010-09-14 Kai Tietz <kai.tietz@onevision.com>
authorKai Tietz <kai.tietz@onevision.com>
Tue, 14 Sep 2010 20:25:34 +0000 (20:25 +0000)
committerKai Tietz <kai.tietz@onevision.com>
Tue, 14 Sep 2010 20:25:34 +0000 (20:25 +0000)
        * peXXigen.c (sort_x64_pdata): New helper.
        (_bfd_XXi_final_link_postscript): Do pdata sorting.

bfd/ChangeLog
bfd/peXXigen.c

index 0fb449a6c6df2a72c10d3111c00e51e402d1d489..0e1cf00c110bd75202718959db840f539e78e503 100644 (file)
@@ -1,3 +1,8 @@
+2010-09-14  Kai Tietz  <kai.tietz@onevision.com>
+
+       * peXXigen.c (sort_x64_pdata): New helper.
+       (_bfd_XXi_final_link_postscript): Do pdata sorting.
+
 2010-09-09  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR ld/11998
index f78d2d7f70dd6fe76279a8f9d70a9d874b4f5859..8f351bacb32780d266c691be834fffc100b0af61 100644 (file)
@@ -2256,6 +2256,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.  */
 
@@ -2383,6 +2398,28 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
       pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].Size = 0x18;
     }
 
+/* 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 ? sec->rawsize : sec->size;
+
+       if (x && bfd_get_section_contents (abfd, sec, pfinfo->contents, 0, x))
+         {
+           qsort (pfinfo->contents,
+                  (size_t) ((sec->size <x ? sec->size : x) / 12),
+                  12, sort_x64_pdata);
+           bfd_set_section_contents (pfinfo->output_bfd, sec,
+                                     pfinfo->contents, 0, x);
+         }
+      }
+  }
+#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....  */