From 9f11c00cdf18f77c10caa7b0c0513a2b27f6b97a Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Tue, 19 Nov 2013 10:54:00 -0800 Subject: 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. (cherry picked from commit c2763e270c6627e55ac7a75ed3c0a717fbca9bd0) --- ld/ChangeLog | 8 ++++++++ ld/emultempl/elf32.em | 23 +++++++++++++++++++---- ld/testsuite/ChangeLog | 10 ++++++++++ ld/testsuite/ld-elf/ehdr_start-missing.d | 4 ++++ ld/testsuite/ld-elf/ehdr_start-missing.t | 8 ++++++++ ld/testsuite/ld-elf/ehdr_start-strongref.s | 9 +++++++++ ld/testsuite/ld-elf/ehdr_start-userdef.d | 9 +++++++++ ld/testsuite/ld-elf/ehdr_start-userdef.t | 10 ++++++++++ ld/testsuite/ld-elf/ehdr_start-weak.d | 8 ++++++++ ld/testsuite/ld-mips-elf/ehdr_start-2.nd | 2 +- 10 files changed, 86 insertions(+), 5 deletions(-) create mode 100644 ld/testsuite/ld-elf/ehdr_start-missing.d create mode 100644 ld/testsuite/ld-elf/ehdr_start-missing.t create mode 100644 ld/testsuite/ld-elf/ehdr_start-strongref.s create mode 100644 ld/testsuite/ld-elf/ehdr_start-userdef.d create mode 100644 ld/testsuite/ld-elf/ehdr_start-userdef.t create mode 100644 ld/testsuite/ld-elf/ehdr_start-weak.d (limited to 'ld') diff --git a/ld/ChangeLog b/ld/ChangeLog index abb87d1a18..02e85afb03 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,11 @@ +2013-11-19 Roland McGrath + Alan Modra + + * 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 Backport from master diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em index 682f5e5393..9a2fe89947 100644 --- a/ld/emultempl/elf32.em +++ b/ld/emultempl/elf32.em @@ -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 diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index f2f4eb94d5..342d5b2117 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2013-11-19 Roland McGrath + + * 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 * ld-x86-64/mpx.exp: New file. diff --git a/ld/testsuite/ld-elf/ehdr_start-missing.d b/ld/testsuite/ld-elf/ehdr_start-missing.d new file mode 100644 index 0000000000..5c2090fe69 --- /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* diff --git a/ld/testsuite/ld-elf/ehdr_start-missing.t b/ld/testsuite/ld-elf/ehdr_start-missing.t new file mode 100644 index 0000000000..a4daf06660 --- /dev/null +++ b/ld/testsuite/ld-elf/ehdr_start-missing.t @@ -0,0 +1,8 @@ +SECTIONS +{ + . = 0x10000000; + .text : { *(.text) } + + . = 0x20000000; + .rodata : { *(.rodata) } +} diff --git a/ld/testsuite/ld-elf/ehdr_start-strongref.s b/ld/testsuite/ld-elf/ehdr_start-strongref.s new file mode 100644 index 0000000000..39375070e4 --- /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 diff --git a/ld/testsuite/ld-elf/ehdr_start-userdef.d b/ld/testsuite/ld-elf/ehdr_start-userdef.d new file mode 100644 index 0000000000..16d2749d24 --- /dev/null +++ b/ld/testsuite/ld-elf/ehdr_start-userdef.d @@ -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 diff --git a/ld/testsuite/ld-elf/ehdr_start-userdef.t b/ld/testsuite/ld-elf/ehdr_start-userdef.t new file mode 100644 index 0000000000..6ef1de7418 --- /dev/null +++ b/ld/testsuite/ld-elf/ehdr_start-userdef.t @@ -0,0 +1,10 @@ +SECTIONS +{ + . = 0x10000000; + .text : { *(.text) } + + __ehdr_start = 0x12345678; + + . = 0x20000000; + .rodata : { *(.rodata) } +} diff --git a/ld/testsuite/ld-elf/ehdr_start-weak.d b/ld/testsuite/ld-elf/ehdr_start-weak.d new file mode 100644 index 0000000000..8bd90357a4 --- /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+[wU] __ehdr_start +#pass diff --git a/ld/testsuite/ld-mips-elf/ehdr_start-2.nd b/ld/testsuite/ld-mips-elf/ehdr_start-2.nd index 986c2a26cf..0a6c06e9b2 100644 --- a/ld/testsuite/ld-mips-elf/ehdr_start-2.nd +++ b/ld/testsuite/ld-mips-elf/ehdr_start-2.nd @@ -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 -- cgit v1.2.1