From: H.J. Lu Date: Fri, 19 Mar 2021 03:46:28 +0000 (-0700) Subject: elf: Handle .gnu.debuglto_.debug_* sections X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3818d4ab066ee40b976513b247b5da5f20379b66;p=binutils-gdb.git elf: Handle .gnu.debuglto_.debug_* sections commit 994b25132814f4c2be93ce53a616a74139c4cf3c Author: H.J. Lu Date: Sun Jan 17 20:01:16 2021 -0800 ld/elf: Ignore section symbols when matching linkonce with comdat ignored section symbols when comparing symbols in 2 sections. Since all references to debugging sections are done with section symbols, symbols in debugging sections are ignored and we fail to match symbols in comdat debugging sections. Also .gnu.debuglto_.debug_* sections aren't treated as debugging sections. 1. Treate .gnu.debuglto_.debug_ section as debugging section unless it is marked with SHF_EXCLUDE. 2. Revert commit 994b2513281 in elf_create_symbuf. 3. Ignore section symbols only when matching non-debugging sections or linkonce section with comdat section. bfd/ PR ld/27590 * elf.c (_bfd_elf_make_section_from_shdr): Treate .gnu.debuglto_.debug_ section as debugging section unless it is marked with SHF_EXCLUDE. * elflink.c (elf_create_symbuf): Revert commit 994b2513281. (bfd_elf_match_symbols_in_sections): Ignore section symbols when matching non-debugging sections or linkonce section with comdat section. ld/ PR ld/27590 * testsuite/ld-elf/pr27590.s: New file. * testsuite/ld-elf/pr27590a.d: Likewise. * testsuite/ld-elf/pr27590b.d: Likewise. * testsuite/ld-i386/i386.exp: Also run ld/27193 test with --reduce-memory-overheads. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 94155de66eb..2e43a4d784d 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,14 @@ +2021-03-18 H.J. Lu + + PR ld/27590 + * elf.c (_bfd_elf_make_section_from_shdr): Treate + .gnu.debuglto_.debug_ section as debugging section unless it is + marked with SHF_EXCLUDE. + * elflink.c (elf_create_symbuf): Revert commit 994b2513281. + (bfd_elf_match_symbols_in_sections): Ignore section symbols when + matching non-debugging sections or linkonce section with comdat + section. + 2021-03-18 H.J. Lu PR ld/27587 diff --git a/bfd/elf.c b/bfd/elf.c index 35c31cf40bf..7bd12dfbf37 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -1085,6 +1085,10 @@ _bfd_elf_make_section_from_shdr (bfd *abfd, if (name [0] == '.') { if (strncmp (name, ".debug", 6) == 0 + /* NB: Treate .gnu.debuglto_.debug_ section as debugging + section unless it is marked with SHF_EXCLUDE. */ + || ((flags & SEC_EXCLUDE) == 0 + && strncmp (name, ".gnu.debuglto_.debug_", 21) == 0) || strncmp (name, ".gnu.linkonce.wi.", 17) == 0 || strncmp (name, ".zdebug", 7) == 0) flags |= SEC_DEBUGGING | SEC_ELF_OCTETS; diff --git a/bfd/elflink.c b/bfd/elflink.c index e1278a5d95e..69362670667 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -8135,12 +8135,8 @@ elf_create_symbuf (size_t symcount, Elf_Internal_Sym *isymbuf) if (indbuf == NULL) return NULL; - /* NB: When checking if 2 sections define the same set of local and - global symbols, ignore both undefined and section symbols in the - symbol table. */ for (ind = indbuf, i = 0; i < symcount; i++) - if (isymbuf[i].st_shndx != SHN_UNDEF - && ELF_ST_TYPE (isymbuf[i].st_info) != STT_SECTION) + if (isymbuf[i].st_shndx != SHN_UNDEF) *ind++ = &isymbuf[i]; indbufend = ind; @@ -8203,9 +8199,10 @@ bfd_elf_match_symbols_in_sections (asection *sec1, asection *sec2, struct elf_symbuf_head *ssymbuf1, *ssymbuf2; Elf_Internal_Sym *isym, *isymend; struct elf_symbol *symtable1 = NULL, *symtable2 = NULL; - size_t count1, count2, i; + size_t count1, count2, sec_count1, sec_count2, i; unsigned int shndx1, shndx2; bfd_boolean result; + bfd_boolean ignore_section_symbol_p; bfd1 = sec1->owner; bfd2 = sec2->owner; @@ -8239,6 +8236,13 @@ bfd_elf_match_symbols_in_sections (asection *sec1, asection *sec2, ssymbuf1 = (struct elf_symbuf_head *) elf_tdata (bfd1)->symbuf; ssymbuf2 = (struct elf_symbuf_head *) elf_tdata (bfd2)->symbuf; + /* Ignore section symbols only when matching non-debugging sections + or linkonce section with comdat section. */ + ignore_section_symbol_p + = ((sec1->flags & SEC_DEBUGGING) == 0 + || ((elf_section_flags (sec1) & SHF_GROUP) + != (elf_section_flags (sec2) & SHF_GROUP))); + if (ssymbuf1 == NULL) { isymbuf1 = bfd_elf_get_elf_syms (bfd1, hdr1, symcount1, 0, @@ -8278,6 +8282,7 @@ bfd_elf_match_symbols_in_sections (asection *sec1, asection *sec2, hi = ssymbuf1->count; ssymbuf1++; count1 = 0; + sec_count1 = 0; while (lo < hi) { mid = (lo + hi) / 2; @@ -8292,11 +8297,19 @@ bfd_elf_match_symbols_in_sections (asection *sec1, asection *sec2, break; } } + if (ignore_section_symbol_p) + { + for (i = 0; i < count1; i++) + if (ELF_ST_TYPE (ssymbuf1->ssym[i].st_info) == STT_SECTION) + sec_count1++; + count1 -= sec_count1; + } lo = 0; hi = ssymbuf2->count; ssymbuf2++; count2 = 0; + sec_count2 = 0; while (lo < hi) { mid = (lo + hi) / 2; @@ -8311,6 +8324,13 @@ bfd_elf_match_symbols_in_sections (asection *sec1, asection *sec2, break; } } + if (ignore_section_symbol_p) + { + for (i = 0; i < count2; i++) + if (ELF_ST_TYPE (ssymbuf2->ssym[i].st_info) == STT_SECTION) + sec_count2++; + count2 -= sec_count2; + } if (count1 == 0 || count2 == 0 || count1 != count2) goto done; @@ -8323,24 +8343,30 @@ bfd_elf_match_symbols_in_sections (asection *sec1, asection *sec2, goto done; symp = symtable1; - for (ssym = ssymbuf1->ssym, ssymend = ssym + count1; - ssym < ssymend; ssym++, symp++) - { - symp->u.ssym = ssym; - symp->name = bfd_elf_string_from_elf_section (bfd1, - hdr1->sh_link, - ssym->st_name); - } + for (ssym = ssymbuf1->ssym, ssymend = ssym + count1 + sec_count1; + ssym < ssymend; ssym++) + if (sec_count1 == 0 + || ELF_ST_TYPE (ssym->st_info) != STT_SECTION) + { + symp->u.ssym = ssym; + symp->name = bfd_elf_string_from_elf_section (bfd1, + hdr1->sh_link, + ssym->st_name); + symp++; + } symp = symtable2; - for (ssym = ssymbuf2->ssym, ssymend = ssym + count2; - ssym < ssymend; ssym++, symp++) - { - symp->u.ssym = ssym; - symp->name = bfd_elf_string_from_elf_section (bfd2, - hdr2->sh_link, - ssym->st_name); - } + for (ssym = ssymbuf2->ssym, ssymend = ssym + count2 + sec_count2; + ssym < ssymend; ssym++) + if (sec_count2 == 0 + || ELF_ST_TYPE (ssym->st_info) != STT_SECTION) + { + symp->u.ssym = ssym; + symp->name = bfd_elf_string_from_elf_section (bfd2, + hdr2->sh_link, + ssym->st_name); + symp++; + } /* Sort symbol by name. */ qsort (symtable1, count1, sizeof (struct elf_symbol), @@ -8369,12 +8395,16 @@ bfd_elf_match_symbols_in_sections (asection *sec1, asection *sec2, /* Count definitions in the section. */ count1 = 0; for (isym = isymbuf1, isymend = isym + symcount1; isym < isymend; isym++) - if (isym->st_shndx == shndx1) + if (isym->st_shndx == shndx1 + && (!ignore_section_symbol_p + || ELF_ST_TYPE (isym->st_info) != STT_SECTION)) symtable1[count1++].u.isym = isym; count2 = 0; for (isym = isymbuf2, isymend = isym + symcount2; isym < isymend; isym++) - if (isym->st_shndx == shndx2) + if (isym->st_shndx == shndx2 + && (!ignore_section_symbol_p + || ELF_ST_TYPE (isym->st_info) != STT_SECTION)) symtable2[count2++].u.isym = isym; if (count1 == 0 || count2 == 0 || count1 != count2) diff --git a/ld/ChangeLog b/ld/ChangeLog index d9b049f003c..30ac9b4d470 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,12 @@ +2021-03-18 H.J. Lu + + PR ld/27590 + * testsuite/ld-elf/pr27590.s: New file. + * testsuite/ld-elf/pr27590a.d: Likewise. + * testsuite/ld-elf/pr27590b.d: Likewise. + * testsuite/ld-i386/i386.exp: Also run ld/27193 test with + --reduce-memory-overheads. + 2021-03-18 H.J. Lu PR ld/27587 diff --git a/ld/testsuite/ld-elf/pr27590.s b/ld/testsuite/ld-elf/pr27590.s new file mode 100644 index 00000000000..f7340b4d46f --- /dev/null +++ b/ld/testsuite/ld-elf/pr27590.s @@ -0,0 +1,6 @@ + .section .gnu.debuglto_.debug_macro,"",%progbits +.Ldebug_macro0: + .dc.a .Ldebug_macro2 + .section .gnu.debuglto_.debug_macro,"G",%progbits,wm4,comdat +.Ldebug_macro2: + .long 0x4 diff --git a/ld/testsuite/ld-elf/pr27590a.d b/ld/testsuite/ld-elf/pr27590a.d new file mode 100644 index 00000000000..c24cd8907ae --- /dev/null +++ b/ld/testsuite/ld-elf/pr27590a.d @@ -0,0 +1,10 @@ +#source: pr27590.s +#ld: -r tmpdir/pr27590.o +#readelf: -rW +#xfail: [is_generic] + +Relocation section '\.rel.*\.gnu\.debuglto_\.debug_macro' at offset 0x[0-9a-z]+ contains 2 entries: +[ \t]+Offset[ \t]+Info[ \t]+Type[ \t]+Sym.* +[0-9a-f]+[ \t]+[0-9a-f]+[ \t]+R_.*[ \t]+[0]+[ \t]+\.gnu\.debuglto_\.debug_macro.* +[0-9a-f]+[ \t]+[0-9a-f]+[ \t]+R_.*[ \t]+[0]+[ \t]+\.gnu\.debuglto_\.debug_macro.* +#pass diff --git a/ld/testsuite/ld-elf/pr27590b.d b/ld/testsuite/ld-elf/pr27590b.d new file mode 100644 index 00000000000..68b198b2992 --- /dev/null +++ b/ld/testsuite/ld-elf/pr27590b.d @@ -0,0 +1,10 @@ +#source: pr27590.s +#ld: -r tmpdir/pr27590.o --reduce-memory-overheads +#readelf: -rW +#xfail: [is_generic] + +Relocation section '\.rel.*\.gnu\.debuglto_\.debug_macro' at offset 0x[0-9a-z]+ contains 2 entries: +[ \t]+Offset[ \t]+Info[ \t]+Type[ \t]+Sym.* +[0-9a-f]+[ \t]+[0-9a-f]+[ \t]+R_.*[ \t]+[0]+[ \t]+\.gnu\.debuglto_\.debug_macro.* +[0-9a-f]+[ \t]+[0-9a-f]+[ \t]+R_.*[ \t]+[0]+[ \t]+\.gnu\.debuglto_\.debug_macro.* +#pass diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp index d9075bf27b5..6ad69a818f5 100644 --- a/ld/testsuite/ld-i386/i386.exp +++ b/ld/testsuite/ld-i386/i386.exp @@ -245,11 +245,16 @@ set i386tests { "-melf_i386 -shared -Bsymbolic -z notext" "" "--32 -mx86-used-note=yes" { pr19827a.S } {{readelf {-rW} pr19827.rd}} "pr19827.so"} - {"Build pr27193.so" + {"Build pr27193a.so" "-melf_i386 -shared" "" "--32" { pr27193a.o.bz2 pr27193b.s } - {{objdump {-dw} pr27193.dd}} "pr27193.so"} + {{objdump {-dw} pr27193.dd}} "pr27193a.so"} + {"Build pr27193b.so" + "-melf_i386 -shared --reduce-memory-overheads" "" + "--32" + { pr27193a.o.bz2 pr27193b.s } + {{objdump {-dw} pr27193.dd}} "pr27193b.so"} } proc iamcu_tests {} {