This is the mail archive of the binutils@sourceware.org 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]

[PATCH] Fix references to __ehdr_start when it cannot be defined


The change Maciej made to make the __ehdr_start symbol hidden broke the
cases when __ehdr_start cannot be defined (because the beginning of the
file does not appear in the memory image).

The failure mode was a BFD abort in elf_link_output_extsym.  When all the
references to __ehdr_start were weak, there were also undefined symbol
messages (which of course there should never be for weak references) before
the abort.

This fixes it by moving the logic that changes the __ehdr_start symbol's
visibility to be part of the logic that creates the symbol in the first
place (which does not run at all when the layout makes it impossible to
give it a proper definition).  I also added test coverage for both weak and
strong references to __ehdr_start when it cannot be defined.

I don't know why the call was put where it was (the before_allocation hook)
rather than where I moved it (the place where the __ehdr_start symbol is
created) and the latter seems the far more obvious thing to do, so perhaps
there is some reason the former is better that I don't understand.

I have tested this only for {x86_64,i386}-{linux-gnu,nacl} targets.
I am not set up to test any mips targets.

OK for trunk and 2.24?


Thanks,
Roland


bfd/
	* elf.c (assign_file_positions_for_non_load_sections):
	Call bfd_elf_record_link_assignment here to mark __ehdr_start as
	STV_HIDDEN when creating it.

ld/
	* emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation):
	Don't call bfd_elf_record_link_assignment on __ehdr_start here.

ld/testsuite/
	* ld-elf/ehdr_start-strongref.s: New file.
	* ld-elf/ehdr_start-missing.t: New file.
	* ld-elf/ehdr_start-missing.d: New file.
	* ld-elf/ehdr_start-weak.d: New file.

--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -4962,6 +4962,14 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
 	  hash->root.type = bfd_link_hash_defined;
 	  hash->def_regular = 1;
 	  hash->non_elf = 0;
+
+	  /* Make __ehdr_start hidden if it has been referenced, to
+	     prevent the symbol from being dynamic.  */
+	  if (!bfd_elf_record_link_assignment (link_info->output_bfd, link_info,
+					       "__ehdr_start", TRUE, TRUE))
+	    (*link_info->callbacks->einfo)
+	      (_("%P%F: failed to record assignment to %s: %E\n"),
+	       "__ehdr_start");
 	}
     }

--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -1485,13 +1485,6 @@ gld${EMULATION_NAME}_before_allocation (void)
     {
       _bfd_elf_tls_setup (link_info.output_bfd, &link_info);

-      /* Make __ehdr_start hidden if it has been referenced, to
-	 prevent the symbol from being dynamic.  */
-      if (!bfd_elf_record_link_assignment (link_info.output_bfd, &link_info,
-					   "__ehdr_start", TRUE, TRUE))
-	einfo ("%P%F: failed to record assignment to %s: %E\n",
-	       "__ehdr_start");
-
       /* If we are going to make any variable assignments, we need to
 	 let the ELF backend know about them in case the variables are
 	 referred to by dynamic objects.  */
--- /dev/null
+++ b/ld/testsuite/ld-elf/ehdr_start-missing.d
@@ -0,0 +1,4 @@
+#source: ehdr_start-strongref.s
+#ld: -e _start -T ehdr_start-missing.t
+#error: .*: undefined reference to `__ehdr_start'
+#target: *-*-linux* *-*-gnu* *-*-nacl*
--- /dev/null
+++ b/ld/testsuite/ld-elf/ehdr_start-missing.t
@@ -0,0 +1,8 @@
+SECTIONS
+{
+  . = 0x10000000;
+  .text : { *(.text) }
+
+  . = 0x20000000;
+  .rodata : { *(.rodata) }
+}
--- /dev/null
+++ b/ld/testsuite/ld-elf/ehdr_start-strongref.s
@@ -0,0 +1,9 @@
+	.text
+	.globl _start
+_start:
+	.space 16
+
+	.section .rodata,"a"
+	.globl foo
+foo:
+	.dc.a __ehdr_start
--- /dev/null
+++ b/ld/testsuite/ld-elf/ehdr_start-weak.d
@@ -0,0 +1,8 @@
+#source: ehdr_start.s
+#ld: -e _start -T ehdr_start-missing.t
+#nm: -n
+#target: *-*-linux* *-*-gnu* *-*-nacl*
+
+#...
+\s+w __ehdr_start
+#pass


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