This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] PR ld/20882: Mark debug sections referenced by kept debug sections


On Tue, May 16, 2017 at 6:27 PM, Alan Modra <amodra@gmail.com> wrote:
> On Tue, May 16, 2017 at 01:06:18PM -0700, H.J. Lu wrote:
>>        if (! debug_frag_seen)
>> -     continue;
>> +     {
>> +       if (has_kept_debug_info)
>> +         goto mark_kept_debug_info;
>> +       else
>> +         continue;
>> +     }
>>
>>        /* Look for CODE sections which are going to be discarded,
>>        and find and discard any fragmented debug sections which
>
> I think the loop handling .debug*.text.* should be run before your new
> gc_mark loop.  ie. Rather than the above hunk, you should condition
> the loop immediately after the comment as
>
>       if (debug_frag_seen)
>         for (isec = ibfd->sections; isec != NULL; isec = isec->next)
>           if ((isec->flags & SEC_CODE) != 0
>               && isec->gc_mark == 0)
>
> OK with that change and of course deleting the goto label.  Also,
> please tabify the testcase source files.
>

This is the patch I am going to check in.

Thanks.

-- 
H.J.
From 849bc5f646e17bacc0ead8830df3b4037356a86c Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Tue, 16 May 2017 19:58:05 -0700
Subject: [PATCH] Mark debug sections referenced by kept debug sections

If a debug section is referenced by a kept debug section, it should
also be kept.

Some targets, like mips, keep input files when there are some special
sections, like .gnu.attributes, even if input file is unused otherwise.
In this case, all debug sections are kept.  The new test will fail on
such targets.  We can either fix those targets or XFAIL the test.

bfd/

	PR ld/20882
	* elflink.c (elf_gc_mark_debug_section): New function.
	(_bfd_elf_gc_mark_extra_sections): Mark any debug sections
	referenced by kept debug sections.

ld/

	PR ld/20882
	* testsuite/ld-gc/gc.exp: Run pr20882.
	* testsuite/ld-gc/pr20882.d: New file.
	* testsuite/ld-gc/pr20882a.s: Likewise.
	* testsuite/ld-gc/pr20882b.s: Likewise.
	* testsuite/ld-gc/pr20882c.s: Likewise.
---
 bfd/elflink.c                 | 82 ++++++++++++++++++++++++++++---------------
 ld/testsuite/ld-gc/gc.exp     |  1 +
 ld/testsuite/ld-gc/pr20882.d  | 10 ++++++
 ld/testsuite/ld-gc/pr20882a.s |  8 +++++
 ld/testsuite/ld-gc/pr20882b.s |  5 +++
 ld/testsuite/ld-gc/pr20882c.s |  5 +++
 6 files changed, 83 insertions(+), 28 deletions(-)
 create mode 100644 ld/testsuite/ld-gc/pr20882.d
 create mode 100644 ld/testsuite/ld-gc/pr20882a.s
 create mode 100644 ld/testsuite/ld-gc/pr20882b.s
 create mode 100644 ld/testsuite/ld-gc/pr20882c.s

diff --git a/bfd/elflink.c b/bfd/elflink.c
index 60e0a32..bc10428 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -12669,6 +12669,24 @@ _bfd_elf_gc_mark_hook (asection *sec,
   return NULL;
 }
 
+/* Return the global debug definition section.  */
+
+static asection *
+elf_gc_mark_debug_section (asection *sec ATTRIBUTE_UNUSED,
+			   struct bfd_link_info *info ATTRIBUTE_UNUSED,
+			   Elf_Internal_Rela *rel ATTRIBUTE_UNUSED,
+			   struct elf_link_hash_entry *h,
+			   Elf_Internal_Sym *sym ATTRIBUTE_UNUSED)
+{
+  if (h != NULL
+      && (h->root.type == bfd_link_hash_defined
+	  || h->root.type == bfd_link_hash_defweak)
+      && (h->root.u.def.section->flags & SEC_DEBUGGING) != 0)
+    return h->root.u.def.section;
+
+  return NULL;
+}
+
 /* For undefined __start_<name> and __stop_<name> symbols, return the
    first input section matching <name>.  Return NULL otherwise.  */
 
@@ -12930,6 +12948,7 @@ _bfd_elf_gc_mark_extra_sections (struct bfd_link_info *info,
       asection *isec;
       bfd_boolean some_kept;
       bfd_boolean debug_frag_seen;
+      bfd_boolean has_kept_debug_info;
 
       if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
 	continue;
@@ -12937,7 +12956,7 @@ _bfd_elf_gc_mark_extra_sections (struct bfd_link_info *info,
       /* Ensure all linker created sections are kept,
 	 see if any other section is already marked,
 	 and note if we have any fragmented debug sections.  */
-      debug_frag_seen = some_kept = FALSE;
+      debug_frag_seen = some_kept = has_kept_debug_info = FALSE;
       for (isec = ibfd->sections; isec != NULL; isec = isec->next)
 	{
 	  if ((isec->flags & SEC_LINKER_CREATED) != 0)
@@ -12967,45 +12986,52 @@ _bfd_elf_gc_mark_extra_sections (struct bfd_link_info *info,
 		    || (isec->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0)
 		   && elf_next_in_group (isec) == NULL)
 	    isec->gc_mark = 1;
+	  if (isec->gc_mark && (isec->flags & SEC_DEBUGGING) != 0)
+	    has_kept_debug_info = TRUE;
 	}
 
-      if (! debug_frag_seen)
-	continue;
-
       /* Look for CODE sections which are going to be discarded,
 	 and find and discard any fragmented debug sections which
 	 are associated with that code section.  */
-      for (isec = ibfd->sections; isec != NULL; isec = isec->next)
-	if ((isec->flags & SEC_CODE) != 0
-	    && isec->gc_mark == 0)
-	  {
-	    unsigned int ilen;
-	    asection *dsec;
+      if (debug_frag_seen)
+	for (isec = ibfd->sections; isec != NULL; isec = isec->next)
+	  if ((isec->flags & SEC_CODE) != 0
+	      && isec->gc_mark == 0)
+	    {
+	      unsigned int ilen;
+	      asection *dsec;
 
-	    ilen = strlen (isec->name);
+	      ilen = strlen (isec->name);
 
-	    /* Association is determined by the name of the debug section
-	       containing the name of the code section as a suffix.  For
-	       example .debug_line.text.foo is a debug section associated
-	       with .text.foo.  */
-	    for (dsec = ibfd->sections; dsec != NULL; dsec = dsec->next)
-	      {
-		unsigned int dlen;
+	      /* Association is determined by the name of the debug
+	         section containing the name of the code section as
+		 a suffix.  For example .debug_line.text.foo is a
+		 debug section associated with .text.foo.  */
+	      for (dsec = ibfd->sections; dsec != NULL; dsec = dsec->next)
+		{
+		  unsigned int dlen;
 
-		if (dsec->gc_mark == 0
-		    || (dsec->flags & SEC_DEBUGGING) == 0)
-		  continue;
+		  if (dsec->gc_mark == 0
+		      || (dsec->flags & SEC_DEBUGGING) == 0)
+		    continue;
 
-		dlen = strlen (dsec->name);
+		  dlen = strlen (dsec->name);
 
-		if (dlen > ilen
-		    && strncmp (dsec->name + (dlen - ilen),
-				isec->name, ilen) == 0)
-		  {
+		  if (dlen > ilen
+		      && strncmp (dsec->name + (dlen - ilen),
+				  isec->name, ilen) == 0)
 		    dsec->gc_mark = 0;
-		  }
-	      }
+		}
 	  }
+
+      /* Mark debug sections referenced by kept debug sections.  */
+      if (has_kept_debug_info)
+	for (isec = ibfd->sections; isec != NULL; isec = isec->next)
+	  if (isec->gc_mark
+	      && (isec->flags & SEC_DEBUGGING) != 0)
+	    if (!_bfd_elf_gc_mark (info, isec,
+				   elf_gc_mark_debug_section))
+	      return FALSE;
     }
   return TRUE;
 }
diff --git a/ld/testsuite/ld-gc/gc.exp b/ld/testsuite/ld-gc/gc.exp
index ba4f70b..ba5c46b 100644
--- a/ld/testsuite/ld-gc/gc.exp
+++ b/ld/testsuite/ld-gc/gc.exp
@@ -104,6 +104,7 @@ run_dump_test "start"
 run_dump_test "pr19167"
 if { [is_elf_format] } then {
     run_dump_test "all-debug-sections"
+    run_dump_test "pr20882"
 }
 
 if { [is_elf_format] && [check_shared_lib_support] } then {
diff --git a/ld/testsuite/ld-gc/pr20882.d b/ld/testsuite/ld-gc/pr20882.d
new file mode 100644
index 0000000..55fa141
--- /dev/null
+++ b/ld/testsuite/ld-gc/pr20882.d
@@ -0,0 +1,10 @@
+#name: --gc-sections with relocations in debug section
+#source: pr20882a.s
+#source: pr20882b.s
+#source: pr20882c.s
+#as: -gdwarf-sections
+#ld: --gc-sections -e main
+#readelf: -x .debug_info
+
+#...
+ +0x0+ [0-9a-f ]+ 28 +.+\(
diff --git a/ld/testsuite/ld-gc/pr20882a.s b/ld/testsuite/ld-gc/pr20882a.s
new file mode 100644
index 0000000..46bc1ad
--- /dev/null
+++ b/ld/testsuite/ld-gc/pr20882a.s
@@ -0,0 +1,8 @@
+	.text
+	.globl  main
+	.type   main, %function
+main:
+	.byte 0
+
+	.section .debug_info,"",%progbits
+	.dc.a  t.c.4903c230+2
diff --git a/ld/testsuite/ld-gc/pr20882b.s b/ld/testsuite/ld-gc/pr20882b.s
new file mode 100644
index 0000000..ea0cf2e
--- /dev/null
+++ b/ld/testsuite/ld-gc/pr20882b.s
@@ -0,0 +1,5 @@
+	.section .debug_info,"",%progbits
+	.hidden t.c.4903c230
+	.globl t.c.4903c230
+t.c.4903c230:
+	.byte 0x28
diff --git a/ld/testsuite/ld-gc/pr20882c.s b/ld/testsuite/ld-gc/pr20882c.s
new file mode 100644
index 0000000..44d27349
--- /dev/null
+++ b/ld/testsuite/ld-gc/pr20882c.s
@@ -0,0 +1,5 @@
+	.section .debug_info,"",%progbits
+	.hidden t.c.4903c231
+	.globl t.c.4903c231
+t.c.4903c231:
+	.byte   0x29
-- 
2.9.3


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]