non-PIC references to __ehdr_start in pie and shared

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.
This commit is contained in:
Alan Modra 2014-01-15 21:50:55 +10:30
parent bb4142cf49
commit 4199e3b866
7 changed files with 44 additions and 0 deletions

View 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

View 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

View 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.

View File

@ -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

View 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:

View 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

View File

@ -2,6 +2,7 @@
#ld: -e _start
#nm: -n
#target: *-*-linux* *-*-gnu* *-*-nacl*
#xfail: frv-*-*
#...
[0-9a-f]*000 [Adrt] __ehdr_start