diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2021-03-18 20:46:28 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2021-03-18 20:57:02 -0700 |
commit | 3818d4ab066ee40b976513b247b5da5f20379b66 (patch) | |
tree | ebb68ff9dea8c35f68178204ce3de18989126655 /bfd | |
parent | 51f6e7a9f4210aed0f8156c1d2e348de6f96f37d (diff) | |
download | gdb-3818d4ab066ee40b976513b247b5da5f20379b66.zip gdb-3818d4ab066ee40b976513b247b5da5f20379b66.tar.gz gdb-3818d4ab066ee40b976513b247b5da5f20379b66.tar.bz2 |
elf: Handle .gnu.debuglto_.debug_* sections
commit 994b25132814f4c2be93ce53a616a74139c4cf3c
Author: H.J. Lu <hjl.tools@gmail.com>
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.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 11 | ||||
-rw-r--r-- | bfd/elf.c | 4 | ||||
-rw-r--r-- | bfd/elflink.c | 78 |
3 files changed, 69 insertions, 24 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 94155de..2e43a4d 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,16 @@ 2021-03-18 H.J. Lu <hongjiu.lu@intel.com> + 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 <hongjiu.lu@intel.com> + PR ld/27587 * dwarf2.c (read_attribute_value): Check version >= 3 for DW_FORM_ref_addr. @@ -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 e1278a5..6936267 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) |