This is the mail archive of the mailing list for the binutils project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: PATCH: PR ld/16428: autoconf tests don't terminate on ix86-linux-gnu with -static -fPIE -pie on glibc-2.18 based systems

On Tue, Jan 14, 2014 at 04:47:40PM -0800, H.J. Lu wrote:
> We discard dynamic relocations against weak undef
> __ehdr_start which is defined by
> assign_file_positions_for_non_load_sections later.
> Glibc 2.18 started using __ehdr_start and we
> under allocate dynamic relocations.  I checked in
> this patch to check __ehdr_start.
> Alan, many backends have the same problem.

This is a bit of a pest.  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.  The only way to
ensure we emit the dynamic relocations is to define the symbol
early, or hack all backends.  But, 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

I really don't want to hack all the backends.  So, lets see if this
generic hack passes testing..

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

diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index 9a2fe89..13f86f0 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -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;
+    }
diff --git a/ld/testsuite/ld-elf/ehdr_start-shared.d b/ld/testsuite/ld-elf/ehdr_start-shared.d
new file mode 100644
index 0000000..51c4e66
--- /dev/null
+++ b/ld/testsuite/ld-elf/ehdr_start-shared.d
@@ -0,0 +1,8 @@
+#source: ehdr_start.s
+#ld: -e _start -shared
+#nm: -n
+#target: *-*-linux* *-*-gnu* *-*-nacl*
+[0-9a-f]*000 [Adrt] __ehdr_start

Alan Modra
Australia Development Lab, IBM

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]