[v3] elf: Handle .gnu.debuglto_.debug_* sections

Message ID CAMe9rOo2_+nKk49GKKVSRmdW+L1cO_U-7ORRVD6YBmGezT5_cQ@mail.gmail.com
State New
Headers show
Series
  • [v3] elf: Handle .gnu.debuglto_.debug_* sections
Related show

Commit Message

Nick Clifton via Binutils March 19, 2021, 2:21 a.m.
On Thu, Mar 18, 2021 at 6:48 PM Alan Modra <amodra@gmail.com> wrote:
>

> On Thu, Mar 18, 2021 at 07:08:19AM -0700, H.J. Lu wrote:

> > On Thu, Mar 18, 2021 at 2:21 AM Alan Modra <amodra@gmail.com> wrote:

> > >

> > > On Wed, Mar 17, 2021 at 03:43:57PM -0700, H.J. Lu via Binutils wrote:

> > > > 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.

> > >

> > > This part is OK.

> > >

> > > > 2. Ignore section symbols only when matching non-debugging sections or

> > > > linkonce section with comdat section.

> > >

> > > This part has a problem.  elf_create_symbuf stashes away symbols of

> > > interest for an object file, and that set of symbols might be used for

> > > multiple invocations of bfd_elf_match_symbols_in_sections.  You can't

> > > vary the set of symbols stashed based on section, since that would

> > > give the right answer for the first section but possibly wrong answers

> > > for subsequent sections.  Any per-section logic must go in

> > > bfd_elf_match_symbols_in_sections.

> >

> > Here is the v2 patch to revert commit 994b2513281 in elf_create_symbuf

> > and put per-section logic in bfd_elf_match_symbols_in_sections.

> >

> > OK for master?

>

> Did you test with --reduce-memory-overheads?  I don't see any changes

> to bfd_elf_match_symbols_in_sections in code handling that case..


Good point.  Here is the v3 patch with a testcase for
--reduce-memory-overheads.  OK for master?

Thanks.

-- 
H.J.

Comments

Nick Clifton via Binutils March 19, 2021, 3:30 a.m. | #1
On Thu, Mar 18, 2021 at 07:21:13PM -0700, H.J. Lu wrote:
> Good point.  Here is the v3 patch with a testcase for

> --reduce-memory-overheads.  OK for master?


Looks OK to me.

-- 
Alan Modra
Australia Development Lab, IBM
Nick Clifton via Binutils March 19, 2021, 6:36 a.m. | #2
On Fri, Mar 19, 2021 at 02:00:14PM +1030, Alan Modra wrote:
> On Thu, Mar 18, 2021 at 07:21:13PM -0700, H.J. Lu wrote:

> > Good point.  Here is the v3 patch with a testcase for

> > --reduce-memory-overheads.  OK for master?

> 

> Looks OK to me.


The testcase needs tweaking for targets that don't reduce the label to
a section symbol.

alpha-linux  +FAIL: ld-elf/pr27590a
alpha-linux  +FAIL: ld-elf/pr27590b
alpha-netbsd  +FAIL: ld-elf/pr27590a
alpha-netbsd  +FAIL: ld-elf/pr27590b
alpha-unknown-freebsd4.7  +FAIL: ld-elf/pr27590a
alpha-unknown-freebsd4.7  +FAIL: ld-elf/pr27590b
am33_2.0-linux  +FAIL: ld-elf/pr27590a
am33_2.0-linux  +FAIL: ld-elf/pr27590b
cr16-elf  +FAIL: ld-elf/pr27590a
cr16-elf  +FAIL: ld-elf/pr27590b
crx-elf  +FAIL: ld-elf/pr27590a
crx-elf  +FAIL: ld-elf/pr27590b
h8300-elf  +FAIL: ld-elf/pr27590a
h8300-elf  +FAIL: ld-elf/pr27590b
h8300-linux  +FAIL: ld-elf/pr27590a
h8300-linux  +FAIL: ld-elf/pr27590b
m68hc11-elf  +FAIL: ld-elf/pr27590a
m68hc11-elf  +FAIL: ld-elf/pr27590b
m68hc12-elf  +FAIL: ld-elf/pr27590a
m68hc12-elf  +FAIL: ld-elf/pr27590b
mips64el-openbsd  +FAIL: ld-elf/pr27590a
mips64el-openbsd  +FAIL: ld-elf/pr27590b
mips64-openbsd  +FAIL: ld-elf/pr27590a
mips64-openbsd  +FAIL: ld-elf/pr27590b
mn10200-elf  +FAIL: ld-elf/pr27590a
mn10200-elf  +FAIL: ld-elf/pr27590b
mn10300-elf  +FAIL: ld-elf/pr27590a
mn10300-elf  +FAIL: ld-elf/pr27590b
riscv32-elf  +FAIL: ld-elf/pr27590a
riscv32-elf  +FAIL: ld-elf/pr27590b
riscv64-linux  +FAIL: ld-elf/pr27590a
riscv64-linux  +FAIL: ld-elf/pr27590b
rl78-elf  +FAIL: ld-elf/pr27590a
rl78-elf  +FAIL: ld-elf/pr27590b
rx-elf  +FAIL: ld-elf/pr27590a
rx-elf  +FAIL: ld-elf/pr27590b

-- 
Alan Modra
Australia Development Lab, IBM
Nick Clifton via Binutils March 19, 2021, 9:44 a.m. | #3
On Fri, Mar 19, 2021 at 05:06:56PM +1030, Alan Modra wrote:
> On Fri, Mar 19, 2021 at 02:00:14PM +1030, Alan Modra wrote:

> > On Thu, Mar 18, 2021 at 07:21:13PM -0700, H.J. Lu wrote:

> > > Good point.  Here is the v3 patch with a testcase for

> > > --reduce-memory-overheads.  OK for master?

> > 

> > Looks OK to me.

> 

> The testcase needs tweaking for targets that don't reduce the label to

> a section symbol.


	PR 27590
	* testsuite/ld-elf/pr27590a.d: Match relocs using label, and
	R_MIPS_NONE.
	* testsuite/ld-elf/pr27590b.d: Likewise.

diff --git a/ld/testsuite/ld-elf/pr27590a.d b/ld/testsuite/ld-elf/pr27590a.d
index c24cd8907a..7c97975fd5 100644
--- a/ld/testsuite/ld-elf/pr27590a.d
+++ b/ld/testsuite/ld-elf/pr27590a.d
@@ -5,6 +5,8 @@
 
 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.*
+[0-9a-f]+[ \t]+[0-9a-f]+[ \t]+R_.*[ \t]+[0]+[ \t]+(\.gnu\.debuglto_\.debug_macro|\.Ldebug_macro2).*
+#?.*R_MIPS_NONE.*
+#?.*R_MIPS_NONE.*
+[0-9a-f]+[ \t]+[0-9a-f]+[ \t]+R_.*[ \t]+[0]+[ \t]+(\.gnu\.debuglto_\.debug_macro|\.Ldebug_macro2).*
 #pass
diff --git a/ld/testsuite/ld-elf/pr27590b.d b/ld/testsuite/ld-elf/pr27590b.d
index 68b198b299..49a7c3a1e8 100644
--- a/ld/testsuite/ld-elf/pr27590b.d
+++ b/ld/testsuite/ld-elf/pr27590b.d
@@ -5,6 +5,8 @@
 
 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.*
+[0-9a-f]+[ \t]+[0-9a-f]+[ \t]+R_.*[ \t]+[0]+[ \t]+(\.gnu\.debuglto_\.debug_macro|\.Ldebug_macro2).*
+#?.*R_MIPS_NONE.*
+#?.*R_MIPS_NONE.*
+[0-9a-f]+[ \t]+[0-9a-f]+[ \t]+R_.*[ \t]+[0]+[ \t]+(\.gnu\.debuglto_\.debug_macro|\.Ldebug_macro2).*
 #pass


-- 
Alan Modra
Australia Development Lab, IBM

Patch

From 68eb4af7406649bf1fc417940c2d035186b39713 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Wed, 17 Mar 2021 15:33:12 -0700
Subject: [PATCH v3] 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
	* testsuite/ld-elf/pr27590.d: New test.
	* testsuite/ld-elf/pr27590.s: Likewise.

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.

bfd/

	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.
---
 bfd/elf.c                      |  4 ++
 bfd/elflink.c                  | 78 +++++++++++++++++++++++-----------
 ld/testsuite/ld-elf/pr27590.s  |  6 +++
 ld/testsuite/ld-elf/pr27590a.d |  9 ++++
 ld/testsuite/ld-elf/pr27590b.d |  9 ++++
 ld/testsuite/ld-i386/i386.exp  |  9 +++-
 6 files changed, 89 insertions(+), 26 deletions(-)
 create mode 100644 ld/testsuite/ld-elf/pr27590.s
 create mode 100644 ld/testsuite/ld-elf/pr27590a.d
 create mode 100644 ld/testsuite/ld-elf/pr27590b.d

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/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..a654b613891
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr27590a.d
@@ -0,0 +1,9 @@ 
+#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.*
+#pass
diff --git a/ld/testsuite/ld-elf/pr27590b.d b/ld/testsuite/ld-elf/pr27590b.d
new file mode 100644
index 00000000000..d9a5d2a3459
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr27590b.d
@@ -0,0 +1,9 @@ 
+#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.*
+#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 {} {
-- 
2.30.2