Fix references to __ehdr_start when it cannot be defined

ld/
	* emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation):
	Don't use bfd_elf_record_link_assignment to mark __ehdr_start
	hidden.  Instead, just do it directly here, and only if it was
	referenced but not defined.

ld/testsuite/
	* ld-elf/ehdr_start-userdef.t: New file.
	* ld-elf/ehdr_start-userdef.d: New file.
	* 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.
	* ld-mips-elf/ehdr_start-2.nd: Expect __ehdr_start to be global.
This commit is contained in:
Roland McGrath
2013-11-19 10:54:00 -08:00
parent 03e621be97
commit c2763e270c
10 changed files with 86 additions and 5 deletions

View File

@ -1,3 +1,11 @@
2013-11-19 Roland McGrath <mcgrathr@google.com>
Alan Modra <amodra@gmail.com>
* emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation):
Don't use bfd_elf_record_link_assignment to mark __ehdr_start
hidden. Instead, just do it directly here, and only if it was
referenced but not defined.
2013-11-18 Chung-Lin Tang <cltang@codesourcery.com>
* emulparams/nios2linux.sh: New emulation file.

View File

@ -1487,10 +1487,25 @@ gld${EMULATION_NAME}_before_allocation (void)
/* 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 (!link_info.relocatable)
{
struct elf_link_hash_entry *h
= elf_link_hash_lookup (elf_hash_table (&link_info), "__ehdr_start",
FALSE, FALSE, TRUE);
/* Only adjust the export class if the symbol was referenced
and not defined, otherwise leave it alone. */
if (h != NULL
&& (h->root.type == bfd_link_hash_new
|| h->root.type == bfd_link_hash_undefined
|| h->root.type == bfd_link_hash_undefweak
|| h->root.type == bfd_link_hash_common))
{
_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;
}
}
/* If we are going to make any variable assignments, we need to
let the ELF backend know about them in case the variables are

View File

@ -1,3 +1,13 @@
2013-11-19 Roland McGrath <mcgrathr@google.com>
* ld-elf/ehdr_start-userdef.t: New file.
* ld-elf/ehdr_start-userdef.d: New file.
* 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.
* ld-mips-elf/ehdr_start-2.nd: Expect __ehdr_start to be global.
2013-11-17 H.J. Lu <hongjiu.lu@intel.com>
* ld-x86-64/mpx.exp: New file.

View File

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

View File

@ -0,0 +1,8 @@
SECTIONS
{
. = 0x10000000;
.text : { *(.text) }
. = 0x20000000;
.rodata : { *(.rodata) }
}

View File

@ -0,0 +1,9 @@
.text
.globl _start
_start:
.space 16
.section .rodata,"a"
.globl foo
foo:
.dc.a __ehdr_start

View File

@ -0,0 +1,9 @@
#source: ehdr_start-strongref.s
#ld: -e _start -T ehdr_start-userdef.t
#readelf: -Ws
#target: *-*-linux* *-*-gnu* *-*-nacl*
Symbol table '\.symtab' contains [0-9]+ entries:
#...
*[0-9]+: 0*12345678 +0 +NOTYPE +GLOBAL +DEFAULT +ABS +__ehdr_start
#pass

View File

@ -0,0 +1,10 @@
SECTIONS
{
. = 0x10000000;
.text : { *(.text) }
__ehdr_start = 0x12345678;
. = 0x20000000;
.rodata : { *(.rodata) }
}

View File

@ -0,0 +1,8 @@
#source: ehdr_start.s
#ld: -e _start -T ehdr_start-missing.t
#nm: -n
#target: *-*-linux* *-*-gnu* *-*-nacl*
#...
\s+[wU] __ehdr_start
#pass

View File

@ -1,4 +1,4 @@
Symbol table '\.symtab' contains [0-9]+ entries:
#...
*[0-9]+: 0*23400000 +0 (?:NOTYPE|OBJECT) +LOCAL +DEFAULT +[0-9]+ __ehdr_start
*[0-9]+: 0*23400000 +0 (?:NOTYPE|OBJECT) +GLOBAL +DEFAULT +[0-9]+ __ehdr_start
#pass