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

H.J. Lu hjl.tools@gmail.com
Wed Mar 17 22:43:57 GMT 2021


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. 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): Add an ignore_section_symbol_p
	argument.  Ignore section symbols only if ignore_section_symbol_p
	is true.
	(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.d: New test.
	* testsuite/ld-elf/pr27590.s: Likewise.
---
 bfd/elf.c                     |  4 ++++
 bfd/elflink.c                 | 20 ++++++++++++++++----
 ld/testsuite/ld-elf/pr27590.d |  8 ++++++++
 ld/testsuite/ld-elf/pr27590.s |  6 ++++++
 4 files changed, 34 insertions(+), 4 deletions(-)
 create mode 100644 ld/testsuite/ld-elf/pr27590.d
 create mode 100644 ld/testsuite/ld-elf/pr27590.s

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..a8076b394fb 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -8123,7 +8123,8 @@ elf_sym_name_compare (const void *arg1, const void *arg2)
 }
 
 static struct elf_symbuf_head *
-elf_create_symbuf (size_t symcount, Elf_Internal_Sym *isymbuf)
+elf_create_symbuf (size_t symcount, Elf_Internal_Sym *isymbuf,
+		   bfd_boolean ignore_section_symbol_p)
 {
   Elf_Internal_Sym **ind, **indbufend, **indbuf;
   struct elf_symbuf_symbol *ssym;
@@ -8140,7 +8141,8 @@ elf_create_symbuf (size_t symcount, Elf_Internal_Sym *isymbuf)
      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)
+	&& (!ignore_section_symbol_p
+	    || ELF_ST_TYPE (isymbuf[i].st_info) != STT_SECTION))
       *ind++ = &isymbuf[i];
   indbufend = ind;
 
@@ -8206,6 +8208,7 @@ bfd_elf_match_symbols_in_sections (asection *sec1, asection *sec2,
   size_t count1, count2, i;
   unsigned int shndx1, shndx2;
   bfd_boolean result;
+  bfd_boolean ignore_section_symbol_p;
 
   bfd1 = sec1->owner;
   bfd2 = sec2->owner;
@@ -8239,6 +8242,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,
@@ -8248,7 +8258,8 @@ bfd_elf_match_symbols_in_sections (asection *sec1, asection *sec2,
 
       if (info != NULL && !info->reduce_memory_overheads)
 	{
-	  ssymbuf1 = elf_create_symbuf (symcount1, isymbuf1);
+	  ssymbuf1 = elf_create_symbuf (symcount1, isymbuf1,
+					ignore_section_symbol_p);
 	  elf_tdata (bfd1)->symbuf = ssymbuf1;
 	}
     }
@@ -8262,7 +8273,8 @@ bfd_elf_match_symbols_in_sections (asection *sec1, asection *sec2,
 
       if (ssymbuf1 != NULL && info != NULL && !info->reduce_memory_overheads)
 	{
-	  ssymbuf2 = elf_create_symbuf (symcount2, isymbuf2);
+	  ssymbuf2 = elf_create_symbuf (symcount2, isymbuf2,
+					ignore_section_symbol_p);
 	  elf_tdata (bfd2)->symbuf = ssymbuf2;
 	}
     }
diff --git a/ld/testsuite/ld-elf/pr27590.d b/ld/testsuite/ld-elf/pr27590.d
new file mode 100644
index 00000000000..ff967a164bb
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr27590.d
@@ -0,0 +1,8 @@
+#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/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
-- 
2.30.2



More information about the Binutils mailing list