From 97196564c7e981bab7b968e19b171c5dfcb28c3c Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Fri, 6 May 2016 09:46:34 -0700 Subject: [PATCH] Strip global symbol defined in discarded section When a global symbol is defined in COMDAT group, we shouldn't leave an undefined symbol in symbol table when the symbol section is discarded unless there is a reference to the symbol outside of COMDAT group. bfd/ PR ld/17550 * elf-bfd.h (elf_link_hash_entry): Update comments for indx, documenting that indx == -3 if symbol is defined in a discarded section. * elflink.c (elf_link_add_object_symbols): Set indx to -3 if symbol is defined in a discarded section. (elf_link_output_extsym): Strip a global symbol defined in a discarded section. ld/ PR ld/17550 * testsuite/ld-elf/pr17550-1.s: New file. * testsuite/ld-elf/pr17550-2.s: Likewise. * testsuite/ld-elf/pr17550-3.s: Likewise. * testsuite/ld-elf/pr17550-4.s: Likewise. * testsuite/ld-elf/pr17550a.d: Likewise. * testsuite/ld-elf/pr17550b.d: Likewise. * testsuite/ld-elf/pr17550c.d: Likewise. * testsuite/ld-elf/pr17550d.d: Likewise. --- bfd/ChangeLog | 11 +++++++++++ bfd/elf-bfd.h | 3 ++- bfd/elflink.c | 12 ++++++++++++ ld/ChangeLog | 12 ++++++++++++ ld/testsuite/ld-elf/pr17550-1.s | 9 +++++++++ ld/testsuite/ld-elf/pr17550-2.s | 6 ++++++ ld/testsuite/ld-elf/pr17550-3.s | 14 ++++++++++++++ ld/testsuite/ld-elf/pr17550-4.s | 15 +++++++++++++++ ld/testsuite/ld-elf/pr17550a.d | 14 ++++++++++++++ ld/testsuite/ld-elf/pr17550b.d | 14 ++++++++++++++ ld/testsuite/ld-elf/pr17550c.d | 9 +++++++++ ld/testsuite/ld-elf/pr17550d.d | 13 +++++++++++++ 12 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 ld/testsuite/ld-elf/pr17550-1.s create mode 100644 ld/testsuite/ld-elf/pr17550-2.s create mode 100644 ld/testsuite/ld-elf/pr17550-3.s create mode 100644 ld/testsuite/ld-elf/pr17550-4.s create mode 100644 ld/testsuite/ld-elf/pr17550a.d create mode 100644 ld/testsuite/ld-elf/pr17550b.d create mode 100644 ld/testsuite/ld-elf/pr17550c.d create mode 100644 ld/testsuite/ld-elf/pr17550d.d diff --git a/bfd/ChangeLog b/bfd/ChangeLog index c6a51c4d4e..dfd9c1b79a 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,14 @@ +2016-05-06 H.J. Lu + + PR ld/17550 + * elf-bfd.h (elf_link_hash_entry): Update comments for indx, + documenting that indx == -3 if symbol is defined in a discarded + section. + * elflink.c (elf_link_add_object_symbols): Set indx to -3 if + symbol is defined in a discarded section. + (elf_link_output_extsym): Strip a global symbol defined in a + discarded section. + 2016-05-06 H.J. Lu * elf32-i386.c (elf_backend_add_symbol_hook): Defined for Intel diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 9067dd9aea..863fc39f2f 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -124,7 +124,8 @@ struct elf_link_hash_entry struct bfd_link_hash_entry root; /* Symbol index in output file. This is initialized to -1. It is - set to -2 if the symbol is used by a reloc. */ + set to -2 if the symbol is used by a reloc. It is set to -3 if + this symbol is defined in a discarded section. */ long indx; /* Symbol index as a dynamic symbol. Initialized to -1, and remains diff --git a/bfd/elflink.c b/bfd/elflink.c index b6ff6b650a..6ccd5fcd13 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -4082,6 +4082,7 @@ error_free_dyn: bfd_boolean old_weak; bfd_boolean override; bfd_boolean common; + bfd_boolean discarded; unsigned int old_alignment; bfd *old_bfd; bfd_boolean matched; @@ -4092,6 +4093,7 @@ error_free_dyn: sec = NULL; value = isym->st_value; common = bed->common_definition (isym); + discarded = FALSE; bind = ELF_ST_BIND (isym->st_info); switch (bind) @@ -4142,6 +4144,7 @@ error_free_dyn: /* Symbols from discarded section are undefined. We keep its visibility. */ sec = bfd_und_section_ptr; + discarded = TRUE; isym->st_shndx = SHN_UNDEF; } else if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0) @@ -4385,6 +4388,11 @@ error_free_dyn: || h->root.type == bfd_link_hash_warning) h = (struct elf_link_hash_entry *) h->root.u.i.link; + /* Setting the index to -3 tells elf_link_output_extsym that + this symbol is defined in a discarded section. */ + if (discarded) + h->indx = -3; + *sym_hash = h; new_weak = (flags & BSF_WEAK) != 0; @@ -9201,6 +9209,10 @@ elf_link_output_extsym (struct bfd_hash_entry *bh, void *data) return FALSE; } } + + /* Strip a global symbol defined in a discarded section. */ + if (h->indx == -3) + return TRUE; } /* We should also warn if a forced local symbol is referenced from diff --git a/ld/ChangeLog b/ld/ChangeLog index ecb9cd9195..97031bd3c3 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,15 @@ +2016-05-06 H.J. Lu + + PR ld/17550 + * testsuite/ld-elf/pr17550-1.s: New file. + * testsuite/ld-elf/pr17550-2.s: Likewise. + * testsuite/ld-elf/pr17550-3.s: Likewise. + * testsuite/ld-elf/pr17550-4.s: Likewise. + * testsuite/ld-elf/pr17550a.d: Likewise. + * testsuite/ld-elf/pr17550b.d: Likewise. + * testsuite/ld-elf/pr17550c.d: Likewise. + * testsuite/ld-elf/pr17550d.d: Likewise. + 2016-05-06 Senthil Kumar Selvaraj * ld/testsuite/ld-srec/srec.exp: Mark test as XFAIL for AVR. diff --git a/ld/testsuite/ld-elf/pr17550-1.s b/ld/testsuite/ld-elf/pr17550-1.s new file mode 100644 index 0000000000..3da73dcfa6 --- /dev/null +++ b/ld/testsuite/ld-elf/pr17550-1.s @@ -0,0 +1,9 @@ + .section .data,"awG",%progbits,foo_group,comdat + .dc.a x_alias + .type x, %object + .p2align 2 + .size x, 4 +x: + .zero 4 + .globl x_alias + .set x_alias,x diff --git a/ld/testsuite/ld-elf/pr17550-2.s b/ld/testsuite/ld-elf/pr17550-2.s new file mode 100644 index 0000000000..eb4120f90b --- /dev/null +++ b/ld/testsuite/ld-elf/pr17550-2.s @@ -0,0 +1,6 @@ + .section .data,"awG",%progbits,foo_group,comdat + .type x, %object + .p2align 2 + .size x, 4 +x: + .zero 4 diff --git a/ld/testsuite/ld-elf/pr17550-3.s b/ld/testsuite/ld-elf/pr17550-3.s new file mode 100644 index 0000000000..3d7c2525bd --- /dev/null +++ b/ld/testsuite/ld-elf/pr17550-3.s @@ -0,0 +1,14 @@ + .data + .dc.a y + .section .data,"awG",%progbits,foo_group,comdat + .type y, %object + .size y, 4 +y: + .zero 4 + .globl x + .type x, %object + .size x, 4 +x: + .zero 4 + .globl x_alias + .set x_alias,x diff --git a/ld/testsuite/ld-elf/pr17550-4.s b/ld/testsuite/ld-elf/pr17550-4.s new file mode 100644 index 0000000000..d0442fd4f0 --- /dev/null +++ b/ld/testsuite/ld-elf/pr17550-4.s @@ -0,0 +1,15 @@ + .data + .dc.a y + .section .data,"awG",%progbits,foo_group,comdat + .globl y + .type y, %object + .size y, 4 +y: + .zero 4 + .globl x + .type x, %object + .size x, 4 +x: + .zero 4 + .globl x_alias + .set x_alias,x diff --git a/ld/testsuite/ld-elf/pr17550a.d b/ld/testsuite/ld-elf/pr17550a.d new file mode 100644 index 0000000000..c8f0424bad --- /dev/null +++ b/ld/testsuite/ld-elf/pr17550a.d @@ -0,0 +1,14 @@ +#source: pr17550-1.s +#source: pr17550-2.s +#ld: -r +#readelf: -s --wide +#notarget: alpha-*-* cr16-*-* crx-*-* d30v-*-* dlx-*-* i960-*-* pj*-*-* +# Disabled on alpha because alpha has a different .set directive. +# cr16 and crx use non-standard scripts with memory regions, which don't +# play well with comdat group sections under ld -r. Generic linker +# targets don't support comdat group sections. + +#failif +#... + +[0-9]+: +[0-9a-f]+ +0 +OBJECT +GLOBAL +DEFAULT +UND x_alias +#... diff --git a/ld/testsuite/ld-elf/pr17550b.d b/ld/testsuite/ld-elf/pr17550b.d new file mode 100644 index 0000000000..d189747383 --- /dev/null +++ b/ld/testsuite/ld-elf/pr17550b.d @@ -0,0 +1,14 @@ +#source: pr17550-2.s +#source: pr17550-1.s +#ld: -r +#readelf: -s --wide +#notarget: alpha-*-* cr16-*-* crx-*-* d30v-*-* dlx-*-* i960-*-* pj*-*-* +# Disabled on alpha because alpha has a different .set directive. +# cr16 and crx use non-standard scripts with memory regions, which don't +# play well with comdat group sections under ld -r. Generic linker +# targets don't support comdat group sections. + +#failif +#... + +[0-9]+: +[0-9a-f]+ +0 +OBJECT +GLOBAL +DEFAULT +UND x_alias +#... diff --git a/ld/testsuite/ld-elf/pr17550c.d b/ld/testsuite/ld-elf/pr17550c.d new file mode 100644 index 0000000000..23a83f14fc --- /dev/null +++ b/ld/testsuite/ld-elf/pr17550c.d @@ -0,0 +1,9 @@ +#source: pr17550-2.s +#source: pr17550-3.s +#ld: -r +#error: .*: defined in discarded section `\.data\[foo_group\]' +#notarget: alpha-*-* cr16-*-* crx-*-* d30v-*-* dlx-*-* i960-*-* pj*-*-* +# Disabled on alpha because alpha has a different .set directive. +# cr16 and crx use non-standard scripts with memory regions, which don't +# play well with comdat group sections under ld -r. Generic linker +# targets don't support comdat group sections. diff --git a/ld/testsuite/ld-elf/pr17550d.d b/ld/testsuite/ld-elf/pr17550d.d new file mode 100644 index 0000000000..e8fad96507 --- /dev/null +++ b/ld/testsuite/ld-elf/pr17550d.d @@ -0,0 +1,13 @@ +#source: pr17550-2.s +#source: pr17550-4.s +#ld: -r +#readelf: -s --wide +#notarget: alpha-*-* cr16-*-* crx-*-* d30v-*-* dlx-*-* i960-*-* pj*-*-* +# Disabled on alpha because alpha has a different .set directive. +# cr16 and crx use non-standard scripts with memory regions, which don't +# play well with comdat group sections under ld -r. Generic linker +# targets don't support comdat group sections. + +#... + +[0-9]+: +[0-9a-f]+ +0 +OBJECT +GLOBAL +DEFAULT +UND y +#pass