non-PIC references to __ehdr_start in pie and shared
authorAlan Modra <amodra@gmail.com>
Wed, 15 Jan 2014 11:20:55 +0000 (21:50 +1030)
committerAlan Modra <amodra@gmail.com>
Wed, 15 Jan 2014 11:53:16 +0000 (22:23 +1030)
Rather than hacking every backend to not discard dynamic relocations
against an undefined hidden __ehdr_start, make it appear to be defined
early.  We want __ehdr_start hidden before size_dynamic_sections so
that it isn't put in .dynsym, but we do need the dynamic relocations
for a PIE or shared library with a non-PIC reference.  Defining it
early is wrong if we don't actually define the symbol later to its
proper value.  (In some cases we want to leave the symbol undefined,
for example, when the ELF header isn't loaded, and we don't have this
infomation available in before_allocation.)

ld/
* emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation): Define
__ehdr_start before size_dynamic_sections and restore afterwards.
ld/testsuite/
* ld-elf/ehdr_start-shared.d: New.
* ld-elf/ehdr_start-userdef.d: xfail frv.
* ld-elf/ehdr_start-weak.d: Likewise.
* ld-elf/ehdr_start.d: Likewise.

ld/ChangeLog
ld/emultempl/elf32.em
ld/testsuite/ChangeLog
ld/testsuite/ld-elf/ehdr_start-shared.d [new file with mode: 0644]
ld/testsuite/ld-elf/ehdr_start-userdef.d
ld/testsuite/ld-elf/ehdr_start-weak.d
ld/testsuite/ld-elf/ehdr_start.d

index 2b7a5738ee524c96fbc9d3f5f55876c3b564d7fb..eaa6b935752aa1fb67610d69a0a09d942a71a2ab 100644 (file)
@@ -1,3 +1,8 @@
+2014-01-15  Alan Modra  <amodra@gmail.com>
+
+       * emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation): Define
+       __ehdr_start before size_dynamic_sections and restore afterwards.
+
 2014-01-10  Alan Modra  <amodra@gmail.com>
 
        PR ld/14207
index 9a2fe899477151079645b63c8fdf1ad61c222e13..13f86f084e58713abe39f6809a0fb3a54618a055 100644 (file)
@@ -1480,6 +1480,8 @@ gld${EMULATION_NAME}_before_allocation (void)
   const char *rpath;
   asection *sinterp;
   bfd *abfd;
+  struct elf_link_hash_entry *ehdr_start = NULL;
+  struct bfd_link_hash_entry ehdr_start_save;
 
   if (is_elf_hash_table (link_info.hash))
     {
@@ -1504,6 +1506,16 @@ gld${EMULATION_NAME}_before_allocation (void)
              _bfd_elf_link_hash_hide_symbol (&link_info, h, TRUE);
              if (ELF_ST_VISIBILITY (h->other) != STV_INTERNAL)
                h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN;
+            /* Don't leave the symbol undefined.  Undefined hidden
+               symbols typically won't have dynamic relocations, but
+               we most likely will need dynamic relocations for
+               __ehdr_start if we are building a PIE or shared
+               library.  */
+            ehdr_start = h;
+            ehdr_start_save = h->root;
+            h->root.type = bfd_link_hash_defined;
+            h->root.u.def.section = bfd_abs_section_ptr;
+            h->root.u.def.value = 0;
            }
        }
 
@@ -1620,6 +1632,14 @@ ${ELF_INTERPRETER_SET_DEFAULT}
 
   if (!bfd_elf_size_dynsym_hash_dynstr (link_info.output_bfd, &link_info))
     einfo ("%P%F: failed to set dynamic section sizes: %E\n");
+
+  if (ehdr_start != NULL)
+    {
+      /* If we twiddled __ehdr_start to defined earlier, put it back
+        as it was.  */
+      ehdr_start->root.type = ehdr_start_save.type;
+      ehdr_start->root.u = ehdr_start_save.u;
+    }
 }
 
 EOF
index cd97fd577facea7abb342f1e60773e3fd97ccb5f..8fbd3754bb53f46d6ad07ed5291b6fef90d62f55 100644 (file)
@@ -1,3 +1,10 @@
+2014-01-15  Alan Modra  <amodra@gmail.com>
+
+       * ld-elf/ehdr_start-shared.d: New.
+       * ld-elf/ehdr_start-userdef.d: xfail frv.
+       * ld-elf/ehdr_start-weak.d: Likewise.
+       * ld-elf/ehdr_start.d: Likewise.
+
 2014-01-14  Vidya Praveen  <vidyapraveen@arm.com>
 
        * lib/ld-lib.exp (default_ld_link): Remove support for ldflags.
diff --git a/ld/testsuite/ld-elf/ehdr_start-shared.d b/ld/testsuite/ld-elf/ehdr_start-shared.d
new file mode 100644 (file)
index 0000000..c17516a
--- /dev/null
@@ -0,0 +1,9 @@
+#source: ehdr_start.s
+#ld: -e _start -shared
+#nm: -n
+#target: *-*-linux* *-*-gnu* *-*-nacl*
+#xfail: cris*-*-* frv-*-*
+
+#...
+[0-9a-f]*000 [Adrt] __ehdr_start
+#pass
index 2a88e98ea55ca68d2c85febaa7498b57800f9476..b58ae3fa6cfa63c64394e9f270db4598de3b27dd 100644 (file)
@@ -2,6 +2,7 @@
 #ld: -e _start -T ehdr_start-userdef.t
 #readelf: -Ws
 #target: *-*-linux* *-*-gnu* *-*-nacl*
+#xfail: frv-*-*
 
 #...
 Symbol table '\.symtab' contains [0-9]+ entries:
index 8bd90357a4f2d3d94847e0b4809b3b4b0b0ec7ee..24ae34cda711f24a2c46ef5e8750b10620b609e0 100644 (file)
@@ -2,6 +2,7 @@
 #ld: -e _start -T ehdr_start-missing.t
 #nm: -n
 #target: *-*-linux* *-*-gnu* *-*-nacl*
+#xfail: frv-*-*
 
 #...
 \s+[wU] __ehdr_start
index 52e5b5488307c2debd58e9597be874137aaebe23..d538b66d9d399a7c86148043285651cf3c3c9163 100644 (file)
@@ -2,6 +2,7 @@
 #ld: -e _start
 #nm: -n
 #target: *-*-linux* *-*-gnu* *-*-nacl*
+#xfail: frv-*-*
 
 #...
 [0-9a-f]*000 [Adrt] __ehdr_start