2008-11-14 Kai Tietz <kai.tietz@onevision.com>
authorKai Tietz <kai.tietz@onevision.com>
Fri, 14 Nov 2008 15:13:05 +0000 (15:13 +0000)
committerKai Tietz <kai.tietz@onevision.com>
Fri, 14 Nov 2008 15:13:05 +0000 (15:13 +0000)
* emultempl/pep.em (..._before_parse): initialize
pei386_runtime_pseudo_reloc by version 2.
(OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC_V1): New option.
(OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC_V2): New option.
(make_import_fixup): Use relocation size to read addend.
* emultempl/pe.em (..._before_parse): initialize
pei386_runtime_pseudo_reloc by version 1.
(OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC_V1): New option.
(OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC_V2): New option.
* pe-dll.c (pe-dll.h): Remove useless include.
(make_runtime_pseudo_reloc): Change addend to use bfd_vma.
Handle the two variants of pseudo-relocation.
(pe_create_import_fixup): Change addend to type bfd_vma.
Modify for the two pseudo_relocation variants.
(runtime_pseudp_reloc_v2_init): New static variable.
* pe-dll.h (pe_create_import_fixup): Change addend argument type
to bfd_vma.
* pep-dll.h (pep_create_import_fixup): Likewise.
* NEWS: Add comment.

ld/ChangeLog
ld/NEWS
ld/emultempl/pe.em
ld/emultempl/pep.em
ld/pe-dll.c
ld/pe-dll.h
ld/pep-dll.h

index e26ee7e6178a5f5d3c4be3ce06738197fb5668bf..44160c9f2ad022929be6df2400ac43b0a5834464 100644 (file)
@@ -1,3 +1,25 @@
+2008-11-14  Kai Tietz  <kai.tietz@onevision.com>
+
+       * emultempl/pep.em (..._before_parse): initialize
+       pei386_runtime_pseudo_reloc by version 2.
+       (OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC_V1): New option.
+       (OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC_V2): New option.
+       (make_import_fixup): Use relocation size to read addend.
+       * emultempl/pe.em (..._before_parse): initialize 
+       pei386_runtime_pseudo_reloc by version 1.
+       (OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC_V1): New option.
+       (OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC_V2): New option.
+       * pe-dll.c (pe-dll.h): Remove useless include.
+       (make_runtime_pseudo_reloc): Change addend to use bfd_vma.
+       Handle the two variants of pseudo-relocation.
+       (pe_create_import_fixup): Change addend to type bfd_vma.
+       Modify for the two pseudo_relocation variants.
+       (runtime_pseudp_reloc_v2_init): New static variable.
+       * pe-dll.h (pe_create_import_fixup): Change addend argument type 
+       to bfd_vma.
+       * pep-dll.h (pep_create_import_fixup): Likewise.
+       * NEWS: Add comment.
+
 2008-11-14  Alan Modra  <amodra@bigpond.net.au>
 
        * Makefile.am (spu_ovl.o_c): Add missing line continuations.
diff --git a/ld/NEWS b/ld/NEWS
index e28e3d840163afbd6768c9019b95d7a45a3bc088..962c2dba36ca2e7fe002e84fd7edf1f49e7996af 100644 (file)
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -1,5 +1,11 @@
 -*- text -*-
 
+* Add to the PE/PE+ targets the support of two different kinds of
+  pseudo-relocations.  They can be selected by the switches
+  --enable-runtime-pseudo-reloc-v1 and --enable-runtime-pseudo-reloc-v2.
+  For the switch --enable-runtime-pseudo-reloc it uses for 32-bit
+  runtime pseudo relocation version one, for 64-bit the version two.
+
 Changes in 2.19:
 
 * Linker scripts support a new INSERT command that makes it easier to
index b963d030918872586a87b8094f67cc31dd998803..43c0be348f372df8e4aa7e29ec60f556f593ffb7 100644 (file)
@@ -146,7 +146,7 @@ gld_${EMULATION_NAME}_before_parse (void)
   config.dynamic_link = TRUE;
   config.has_shared = 1;
   link_info.pei386_auto_import = -1;
-  link_info.pei386_runtime_pseudo_reloc = -1;
+  link_info.pei386_runtime_pseudo_reloc = 1; /* Use by default version 1.  */
 
 #if (PE_DEF_SUBSYSTEM == 9) || (PE_DEF_SUBSYSTEM == 2)
 #if defined TARGET_IS_mipspe || defined TARGET_IS_armpe || defined TARGET_IS_arm_wince_pe
@@ -203,6 +203,10 @@ gld_${EMULATION_NAME}_before_parse (void)
                                        (OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC + 1)
 #define OPTION_LARGE_ADDRESS_AWARE \
                                        (OPTION_DLL_DISABLE_RUNTIME_PSEUDO_RELOC + 1)
+#define OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC_V1      \
+                                       (OPTION_LARGE_ADDRESS_AWARE + 1)
+#define OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC_V2      \
+                                       (OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC_V1 + 1)
 
 static void
 gld${EMULATION_NAME}_add_options
@@ -255,6 +259,8 @@ gld${EMULATION_NAME}_add_options
     {"enable-extra-pe-debug", no_argument, NULL, OPTION_ENABLE_EXTRA_PE_DEBUG},
     {"enable-runtime-pseudo-reloc", no_argument, NULL, OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC},
     {"disable-runtime-pseudo-reloc", no_argument, NULL, OPTION_DLL_DISABLE_RUNTIME_PSEUDO_RELOC},
+    {"enable-runtime-pseudo-reloc-v1", no_argument, NULL, OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC_V1},
+    {"enable-runtime-pseudo-reloc-v2", no_argument, NULL, OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC_V2},
 #endif
     {"large-address-aware", no_argument, NULL, OPTION_LARGE_ADDRESS_AWARE},
     {NULL, no_argument, NULL, 0}
@@ -639,6 +645,12 @@ gld${EMULATION_NAME}_handle_option (int optc)
     case OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC:
       link_info.pei386_runtime_pseudo_reloc = 1;
       break;
+    case OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC_V1:
+      link_info.pei386_runtime_pseudo_reloc = 1;
+      break;
+    case OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC_V2:
+      link_info.pei386_runtime_pseudo_reloc = 2;
+      break;
     case OPTION_DLL_DISABLE_RUNTIME_PSEUDO_RELOC:
       link_info.pei386_runtime_pseudo_reloc = 0;
       break;
index d70f635f6ec822b8ea25b12d75f65ec33b8e0324..35fd6e0924fa0f5a84579f94c53e1574afdb7e77 100644 (file)
@@ -124,7 +124,7 @@ gld_${EMULATION_NAME}_before_parse (void)
   config.dynamic_link = TRUE;
   config.has_shared = 1;
   link_info.pei386_auto_import = -1;
-  link_info.pei386_runtime_pseudo_reloc = -1;
+  link_info.pei386_runtime_pseudo_reloc = 2; /* Use by default version 2.  */
 
 #if (PE_DEF_SUBSYSTEM == 9) || (PE_DEF_SUBSYSTEM == 2)
   lang_default_entry ("_WinMainCRTStartup");
@@ -173,7 +173,9 @@ enum options
   OPTION_ENABLE_EXTRA_PE_DEBUG,
   OPTION_EXCLUDE_LIBS,
   OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC,
-  OPTION_DLL_DISABLE_RUNTIME_PSEUDO_RELOC
+  OPTION_DLL_DISABLE_RUNTIME_PSEUDO_RELOC,
+  OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC_V1,
+  OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC_V2
 };
 
 static void
@@ -230,6 +232,8 @@ gld${EMULATION_NAME}_add_options
     {"enable-extra-pep-debug", no_argument, NULL, OPTION_ENABLE_EXTRA_PE_DEBUG},
     {"enable-runtime-pseudo-reloc", no_argument, NULL, OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC},
     {"disable-runtime-pseudo-reloc", no_argument, NULL, OPTION_DLL_DISABLE_RUNTIME_PSEUDO_RELOC},
+    {"enable-runtime-pseudo-reloc-v1", no_argument, NULL, OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC_V1},
+    {"enable-runtime-pseudo-reloc-v2", no_argument, NULL, OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC_V2},
 #endif
     {NULL, no_argument, NULL, 0}
   };
@@ -600,11 +604,17 @@ gld${EMULATION_NAME}_handle_option (int optc)
       link_info.pei386_auto_import = 0;
       break;
     case OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC:
-      link_info.pei386_runtime_pseudo_reloc = 1;
+      link_info.pei386_runtime_pseudo_reloc = 2;
       break;
     case OPTION_DLL_DISABLE_RUNTIME_PSEUDO_RELOC:
       link_info.pei386_runtime_pseudo_reloc = 0;
       break;
+    case OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC_V1:
+      link_info.pei386_runtime_pseudo_reloc = 1;
+      break;
+    case OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC_V2:
+      link_info.pei386_runtime_pseudo_reloc = 2;
+      break;
     case OPTION_ENABLE_EXTRA_PE_DEBUG:
       pep_dll_extra_pe_debug = 1;
       break;
@@ -840,17 +850,55 @@ static int
 make_import_fixup (arelent *rel, asection *s)
 {
   struct bfd_symbol *sym = *rel->sym_ptr_ptr;
-  char addend[4];
+  char addend[8];
+  bfd_vma _addend = 0;
+  int suc = 0;
 
   if (pep_dll_extra_pe_debug)
     printf ("arelent: %s@%#lx: add=%li\n", sym->name,
            (unsigned long) rel->address, (long) rel->addend);
 
-  if (! bfd_get_section_contents (s->owner, s, addend, rel->address, sizeof (addend)))
+  memset (addend, 0, sizeof (addend));
+  switch ((rel->howto->bitsize))
+    {
+      case 8:
+        suc = bfd_get_section_contents (s->owner, s, addend, rel->address, 1);
+        if (suc && rel->howto->pc_relative)
+          _addend = (bfd_vma) ((bfd_signed_vma) ((char) bfd_get_8 (s->owner, addend)));
+        else if (suc)
+          _addend = ((bfd_vma) bfd_get_8 (s->owner, addend)) & 0xff;
+        break;
+      case 16:
+        suc = bfd_get_section_contents (s->owner, s, addend, rel->address, 2);
+        if (suc && rel->howto->pc_relative)
+          _addend = (bfd_vma) ((bfd_signed_vma) ((short) bfd_get_16 (s->owner, addend)));
+        else if (suc)
+          _addend = ((bfd_vma) bfd_get_16 (s->owner, addend)) & 0xffff;
+        break;
+      case 32:
+        suc = bfd_get_section_contents (s->owner, s, addend, rel->address, 4);
+        if (suc && rel->howto->pc_relative)
+          _addend = (bfd_vma) ((bfd_signed_vma) ((int) bfd_get_32 (s->owner, addend)));
+        else if (suc)
+          _addend = ((bfd_vma) bfd_get_32 (s->owner, addend)) & 0xffffffff;
+        break;
+      case 64:
+        suc = bfd_get_section_contents (s->owner, s, addend, rel->address, 8);
+        if (suc)
+          _addend = ((bfd_vma) bfd_get_64 (s->owner, addend));
+        break;
+    }
+  if (! suc)
     einfo (_("%C: Cannot get section contents - auto-import exception\n"),
           s->owner, s, rel->address);
 
-  pep_create_import_fixup (rel, s, bfd_get_32 (s->owner, addend));
+  if (pep_dll_extra_pe_debug)
+    {
+      printf ("import of 0x%lx(0x%lx) sec_addr=0x%lx", (long) _addend, (long) rel->addend, (long) rel->address);
+      if (rel->howto->pc_relative) printf (" pcrel");
+      printf (" %d bit rel.\n",(int) rel->howto->bitsize);
+  }
+  pep_create_import_fixup (rel, s, _addend);
 
   return 1;
 }
index bf4b5093336aa35ef450852b584348692fc3accc..35836a7566fdf3f6e7bab52f5b5374f69873d0d9 100644 (file)
@@ -40,7 +40,6 @@
 #include "coff/internal.h"
 #include "../bfd/libcoff.h"
 #include "deffile.h"
-#include "pe-dll.h"
 
 #ifdef pe_use_x86_64
 
@@ -165,6 +164,7 @@ static struct bfd_section *edata_s, *reloc_s;
 static unsigned char *edata_d, *reloc_d;
 static size_t edata_sz, reloc_sz;
 static int runtime_pseudo_relocs_created = 0;
+static int runtime_pseudp_reloc_v2_init = 0;
 
 typedef struct
 {
@@ -2264,14 +2264,14 @@ make_import_fixup_entry (const char *name,
 static bfd *
 make_runtime_pseudo_reloc (const char *name ATTRIBUTE_UNUSED,
                           const char *fixup_name,
-                          int addend,
+                          bfd_vma addend ATTRIBUTE_UNUSED,
+                          bfd_vma bitsize,
                           bfd *parent)
 {
   asection *rt_rel;
   unsigned char *rt_rel_d;
   char *oname;
   bfd *abfd;
-
   oname = xmalloc (20);
   sprintf (oname, "rtr%06d.o", tmp_seq);
   tmp_seq++;
@@ -2290,19 +2290,47 @@ make_runtime_pseudo_reloc (const char *name ATTRIBUTE_UNUSED,
 
   quick_symbol (abfd, "", fixup_name, "", UNDSEC, BSF_GLOBAL, 0);
 
-  bfd_set_section_size (abfd, rt_rel, 8);
-  rt_rel_d = xmalloc (8);
-  rt_rel->contents = rt_rel_d;
-  memset (rt_rel_d, 0, 8);
-  bfd_put_32 (abfd, addend, rt_rel_d);
+  if (link_info.pei386_runtime_pseudo_reloc == 2)
+    {
+         size_t size = 12;
+         if (! runtime_pseudp_reloc_v2_init)
+           {
+                 size += 12;
+                 runtime_pseudp_reloc_v2_init = 1;
+           }
+      quick_symbol (abfd, U ("_imp_"), name, "", UNDSEC, BSF_GLOBAL, 0);
+
+      bfd_set_section_size (abfd, rt_rel, size);
+      rt_rel_d = xmalloc (size);
+      rt_rel->contents = rt_rel_d;
+      memset (rt_rel_d, 0, size);
+         quick_reloc (abfd, size - 8, BFD_RELOC_RVA, 1);
+         quick_reloc (abfd, size - 12, BFD_RELOC_RVA, 2);
+         bfd_put_32 (abfd, bitsize, rt_rel_d + (size - 4));
+         if (size != 12)
+           bfd_put_32 (abfd, 1, rt_rel_d + 8);
+      save_relocs (rt_rel);
+
+      bfd_set_symtab (abfd, symtab, symptr);
+
+      bfd_set_section_contents (abfd, rt_rel, rt_rel_d, 0, size);
+   }
+  else
+   {
+      bfd_set_section_size (abfd, rt_rel, 8);
+      rt_rel_d = xmalloc (8);
+      rt_rel->contents = rt_rel_d;
+      memset (rt_rel_d, 0, 8);
 
-  quick_reloc (abfd, 4, BFD_RELOC_RVA, 1);
-  save_relocs (rt_rel);
+      bfd_put_32 (abfd, addend, rt_rel_d);
+      quick_reloc (abfd, 4, BFD_RELOC_RVA, 1);
 
-  bfd_set_symtab (abfd, symtab, symptr);
+      save_relocs (rt_rel);
 
-  bfd_set_section_contents (abfd, rt_rel, rt_rel_d, 0, 8);
+      bfd_set_symtab (abfd, symtab, symptr);
 
+      bfd_set_section_contents (abfd, rt_rel, rt_rel_d, 0, 8);
+   }
   bfd_make_readable (abfd);
   return abfd;
 }
@@ -2352,7 +2380,7 @@ pe_create_runtime_relocator_reference (bfd *parent)
 }
 
 void
-pe_create_import_fixup (arelent *rel, asection *s, int addend)
+pe_create_import_fixup (arelent *rel, asection *s, bfd_vma addend)
 {
   char buf[300];
   struct bfd_symbol *sym = *rel->sym_ptr_ptr;
@@ -2385,31 +2413,30 @@ pe_create_import_fixup (arelent *rel, asection *s, int addend)
       add_bfd_to_link (b, b->filename, &link_info);
     }
 
-  if (addend != 0)
-    {
-      if (link_info.pei386_runtime_pseudo_reloc)
-       {
-         if (pe_dll_extra_pe_debug)
-           printf ("creating runtime pseudo-reloc entry for %s (addend=%d)\n",
-                  fixup_name, addend);
-         b = make_runtime_pseudo_reloc (name, fixup_name, addend,
-                                        link_info.output_bfd);
-         add_bfd_to_link (b, b->filename, &link_info);
+    if ((link_info.pei386_runtime_pseudo_reloc != 0 && addend != 0)
+        || link_info.pei386_runtime_pseudo_reloc == 2)
+      {
+       if (pe_dll_extra_pe_debug)
+         printf ("creating runtime pseudo-reloc entry for %s (addend=%d)\n",
+                 fixup_name, (int) addend);
 
-         if (runtime_pseudo_relocs_created == 0)
-           {
-             b = pe_create_runtime_relocator_reference (link_info.output_bfd);
-             add_bfd_to_link (b, b->filename, &link_info);
-           }
-         runtime_pseudo_relocs_created++;
-       }
-      else
-       {
-         einfo (_("%C: variable '%T' can't be auto-imported. Please read the documentation for ld's --enable-auto-import for details.\n"),
-                s->owner, s, rel->address, sym->name);
-         einfo ("%X");
-       }
-    }
+       b = make_runtime_pseudo_reloc (name, fixup_name, addend, rel->howto->bitsize,
+                                      link_info.output_bfd);
+       add_bfd_to_link (b, b->filename, &link_info);
+
+       if (runtime_pseudo_relocs_created == 0)
+         {
+           b = pe_create_runtime_relocator_reference (link_info.output_bfd);
+           add_bfd_to_link (b, b->filename, &link_info);
+         }
+       runtime_pseudo_relocs_created++;
+      }
+    else if (addend != 0)
+      {
+       einfo (_("%C: variable '%T' can't be auto-imported. Please read the documentation for ld's --enable-auto-import for details.\n"),
+              s->owner, s, rel->address, sym->name);
+       einfo ("%X");
+      }
 }
 
 
index ce4a2e6d11b0e590f8251ab7894ef230e15be2a9..6645c4c83b82488629218f34461014555f79c74f 100644 (file)
@@ -59,7 +59,7 @@ extern void pe_exe_fill_sections
 extern void pe_walk_relocs_of_symbol
   (struct bfd_link_info *, const char *, int (*) (arelent *, asection *));
 extern void pe_create_import_fixup
-  (arelent * rel, asection *, int);
+  (arelent * rel, asection *, bfd_vma);
 extern bfd_boolean pe_bfd_is_dll
   (bfd *);
 
index dba76bed1f037cb0d5d11366e8ea63b009fdf4f6..ae0dcbe9d83aa9bb1b10b6d1f3f347e2bef1a843 100644 (file)
@@ -48,7 +48,7 @@ extern void pep_dll_fill_sections  (bfd *, struct bfd_link_info *);
 extern void pep_exe_fill_sections  (bfd *, struct bfd_link_info *);
 extern void pep_walk_relocs_of_symbol
   (struct bfd_link_info *, const char *, int (*) (arelent *, asection *));
-extern void pep_create_import_fixup  (arelent * rel, asection *, int);
+extern void pep_create_import_fixup  (arelent * rel, asection *, bfd_vma);
 extern bfd_boolean pep_bfd_is_dll  (bfd *);
 
 #endif /* PEP_DLL_H */
This page took 0.03311 seconds and 4 git commands to generate.