aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2021-03-18 20:46:28 -0700
committerH.J. Lu <hjl.tools@gmail.com>2021-03-18 20:57:02 -0700
commit3818d4ab066ee40b976513b247b5da5f20379b66 (patch)
treeebb68ff9dea8c35f68178204ce3de18989126655 /bfd
parent51f6e7a9f4210aed0f8156c1d2e348de6f96f37d (diff)
downloadgdb-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/ChangeLog11
-rw-r--r--bfd/elf.c4
-rw-r--r--bfd/elflink.c78
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.
diff --git a/bfd/elf.c b/bfd/elf.c
index 35c31cf..7bd12df 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 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)