PATCH: PR ld/11133: Static linking with gc-sections deletes sections with __start/__stop reference

H.J. Lu hjl.tools@gmail.com
Tue Jan 5 18:18:00 GMT 2010


On Tue, Jan 5, 2010 at 9:44 AM, Daniel Jacobowitz <dan@codesourcery.com> wrote:
> On Tue, Jan 05, 2010 at 09:32:21AM -0800, H.J. Lu wrote:
>> Hi,
>>
>>
>> __start_XXX and __stop_XXX symbols may reference the start address and
>> end address of the orphaned section.  We need to search all input files
>> for section XXX.  OK to install?
>
> I don't think this patch does what you want it to.  It's just going to
> keep the first entry.

Here is the updated patch, which keeps all XXX sections. I also
noticed that --gc-sections removed:

 [ 1] .note.ABI-tag     NOTE             0000000000400158  00000158
       0000000000000020  0000000000000000   A       0     0     4

We shouldn't gc SHT_NOTE sections.

> Can you start by saying what effect you think the __start and __stob
> symbols should have?
>

They should keep all XXX sections.

Thanks.

-- 
H.J.
---
bfd/

2010-01-05  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/11133
	* elflink.c (_bfd_elf_gc_mark_hook): Check section XXX for
	undefined __start_XXX/__stop_XXX in all input files and set
	its gc_mark to 1.
	(elf_gc_sweep): Keep SHT_NOTE section.

ld/testsuite/

2010-01-05  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/11133
	* ld-gc/gc.exp: Run start.

	* ld-gc/start.d: New.
	* ld-gc/start.s: Likewise.
-------------- next part --------------
bfd/

2010-01-05  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/11133
	* elflink.c (_bfd_elf_gc_mark_hook): Check section XXX for
	undefined __start_XXX/__stop_XXX in all input files and set
	its gc_mark to 1.
	(elf_gc_sweep): Keep SHT_NOTE section.

ld/testsuite/

2010-01-05  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/11133
	* ld-gc/gc.exp: Run start.

	* ld-gc/start.d: New.
	* ld-gc/start.s: Likewise.

diff --git a/bfd/elflink.c b/bfd/elflink.c
index bbdfe5e..6d2405b 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -11331,6 +11331,8 @@ _bfd_elf_gc_mark_hook (asection *sec,
 		       struct elf_link_hash_entry *h,
 		       Elf_Internal_Sym *sym)
 {
+  const char *sec_name;
+
   if (h != NULL)
     {
       switch (h->root.type)
@@ -11342,6 +11344,31 @@ _bfd_elf_gc_mark_hook (asection *sec,
 	case bfd_link_hash_common:
 	  return h->root.u.c.p->section;
 
+	case bfd_link_hash_undefined:
+	case bfd_link_hash_undefweak:
+	  /* __start_XXX and __stop_XXX symbols may reference the start
+	     address and end address of the orphaned section.  Search
+	     all input files for section XXX.  */
+	  if (strncmp (h->root.root.string, "__start_", 8) == 0)
+	    sec_name = h->root.root.string + 8;
+	  else if (strncmp (h->root.root.string, "__stop_", 7) == 0)
+	    sec_name = h->root.root.string + 7;
+	  else
+	    sec_name = NULL;
+
+	  if (sec_name)
+	    {
+	      bfd *i;
+	      
+	      for (i = info->input_bfds; i; i = i->link_next)
+		{
+		  sec = bfd_get_section_by_name (i, sec_name);
+		  if (sec)
+		    return sec;
+		}
+	    }
+	  break;
+
 	default:
 	  break;
 	}
diff --git a/ld/testsuite/ld-gc/gc.exp b/ld/testsuite/ld-gc/gc.exp
index c85d4f2..c85b909 100644
--- a/ld/testsuite/ld-gc/gc.exp
+++ b/ld/testsuite/ld-gc/gc.exp
@@ -90,3 +90,4 @@ test_gc "Check --gc-section/-r/-e" "gcrel" $ld "-r --gc-sections -e main"
 test_gc "Check --gc-section/-r/-u" "gcrel" $ld "-r --gc-sections -u used_func"
 
 run_dump_test "noent"
+run_dump_test "start"
diff --git a/ld/testsuite/ld-gc/start.d b/ld/testsuite/ld-gc/start.d
new file mode 100644
index 0000000..a6f748f
--- /dev/null
+++ b/ld/testsuite/ld-gc/start.d
@@ -0,0 +1,8 @@
+#name: --gc-sections with __start_
+#ld: --gc-sections -e _start
+#nm: -n
+#target: *-*-linux*
+
+#...
+[0-9a-f]+ A +__start__foo
+#...
diff --git a/ld/testsuite/ld-gc/start.s b/ld/testsuite/ld-gc/start.s
new file mode 100644
index 0000000..d9f1b2d
--- /dev/null
+++ b/ld/testsuite/ld-gc/start.s
@@ -0,0 +1,6 @@
+.globl _start
+_start:
+	.long __start__foo
+	.section	_foo,"aw",%progbits
+foo:
+	.long	1
diff --git a/ld/testsuite/ld-gc/gc.exp b/ld/testsuite/ld-gc/gc.exp
index c85d4f2..c85b909 100644
--- a/ld/testsuite/ld-gc/gc.exp
+++ b/ld/testsuite/ld-gc/gc.exp
@@ -90,3 +90,4 @@ test_gc "Check --gc-section/-r/-e" "gcrel" $ld "-r --gc-sections -e main"
 test_gc "Check --gc-section/-r/-u" "gcrel" $ld "-r --gc-sections -u used_func"
 
 run_dump_test "noent"
+run_dump_test "start"
diff --git a/ld/testsuite/ld-gc/start.d b/ld/testsuite/ld-gc/start.d
new file mode 100644
index 0000000..a6f748f
--- /dev/null
+++ b/ld/testsuite/ld-gc/start.d
@@ -0,0 +1,8 @@
+#name: --gc-sections with __start_
+#ld: --gc-sections -e _start
+#nm: -n
+#target: *-*-linux*
+
+#...
+[0-9a-f]+ A +__start__foo
+#...
diff --git a/ld/testsuite/ld-gc/start.s b/ld/testsuite/ld-gc/start.s
new file mode 100644
index 0000000..d9f1b2d
--- /dev/null
+++ b/ld/testsuite/ld-gc/start.s
@@ -0,0 +1,6 @@
+.globl _start
+_start:
+	.long __start__foo
+	.section	_foo,"aw",%progbits
+foo:
+	.long	1


More information about the Binutils mailing list