PATCH: PR ld/11218: --gc-sections does not detect unresolved symbol

H.J. Lu hjl.tools@gmail.com
Mon Jan 25 19:25:00 GMT 2010


On Mon, Jan 25, 2010 at 3:10 AM, Stern, Eli <eli.stern@ti.com> wrote:
> In the constellation described below, the linker does not detect an unresolved symbol. This is only detected at run-time.
> Seems to me the problem arises from the use of "-ffunction-sections" and "--gc-sections".
>
> The problem was detected with the following tool releases:
> - gcc 4.2.0, binutils 2.19
> - gcc 3.4.6, binutils 2.15.92.0.2
>
>
> Is this a bug or a misuse of the tools?
>
> Suppose the following files:
>
> a.c: This file is compiled using "-ffunction-sections", then "ar" is used to create a statis library.
> extern void unresolved_detected_at_runtime_not_at_linktime(void);
> void bar_in_a(void)
> {
>    ;
> }
>
> void call_unresolved(void)
> {
>    unresolved_detected_at_runtime_not_at_linktime();
> }
>
> so.c: This file is compiled to create a shared library.
> extern void unresolved_detected_at_runtime_not_at_linktime(void);
> void foo_in_so(void)
> {
>    unresolved_detected_at_runtime_not_at_linktime();
> }
>
>
> main.c:
> extern void bar_in_a();
> extern void foo_in_so(void);
> int main(int argc, char *argv[])
> {
>    foo_in_so();
>    bar_in_a();
>
>    return 0;
> }
>
> Note that the symbol "unresolved_detected_at_runtime_not_at_linktime" is not defined at all.
>
> Use the following script to build:
> #!/bin/bash -x
> gcc -ffunction-sections -c a.c -o a.o
> ar rc a.a a.o
> gcc -fPIC -c so.c -o so.o
> gcc -shared -o so.so so.o
> gcc -c main.c -o main.o
> gcc -o main main.o -Wl,--gc-sections a.a ./so.so
>
> All goes well (actually, not so well, since the linker failed to detect an unresolved symbol), till we try to run the executable:
>
> $ ./main
> ./main: symbol lookup error: ./so.so: undefined symbol: unresolved_detected_at_runtime_not_at_linktime
> $
>
>

Here is a patch.  OK to install?

Thanks.

-- 
H.J.
---
bfd/

2010-01-25  Alan Modra  <amodra@gmail.com>
	    H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/11218
	* elflink.c (elf_link_output_extsym): Do not ignore undefined
	symbols with ref_regular set when gc_sections is active.

ld/testsuite/

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

	PR ld/11218
	* ld-gc/dummy.s: New.
	* ld-gc/pr11218-1.c: Likewise.
	* ld-gc/pr11218-2.c: Likewise.
	* ld-gc/pr11218.d: Likewise.
-------------- next part --------------
bfd/

2010-01-25  Alan Modra  <amodra@gmail.com>
	    H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/11218
	* elflink.c (elf_link_output_extsym): Do not ignore undefined
	symbols with ref_regular set when gc_sections is active.

ld/testsuite/

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

	PR ld/11218
	* ld-gc/dummy.s: New.
	* ld-gc/pr11218-1.c: Likewise.
	* ld-gc/pr11218-2.c: Likewise.
	* ld-gc/pr11218.d: Likewise.

diff --git a/bfd/elflink.c b/bfd/elflink.c
index 6576252..cca2d53 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -8579,7 +8579,9 @@ elf_link_output_extsym (struct elf_link_hash_entry *h, void *data)
     {
       /* If we have an undefined symbol reference here then it must have
 	 come from a shared library that is being linked in.  (Undefined
-	 references in regular files have already been handled).  */
+	 references in regular files have already been handled unless
+	 they are in unreferenced sections which are removed by garbage
+	 collection).  */
       bfd_boolean ignore_undef = FALSE;
 
       /* Some symbols may be special in that the fact that they're
@@ -8590,12 +8592,13 @@ elf_link_output_extsym (struct elf_link_hash_entry *h, void *data)
       /* If we are reporting errors for this situation then do so now.  */
       if (ignore_undef == FALSE
 	  && h->ref_dynamic
-	  && ! h->ref_regular
+	  && (!h->ref_regular || finfo->info->gc_sections)
 	  && ! elf_link_check_versioned_symbol (finfo->info, bed, h)
 	  && finfo->info->unresolved_syms_in_shared_libs != RM_IGNORE)
 	{
 	  if (! (finfo->info->callbacks->undefined_symbol
-		 (finfo->info, h->root.root.string, h->root.u.undef.abfd,
+		 (finfo->info, h->root.root.string,
+		  h->ref_regular ? NULL : h->root.u.undef.abfd,
 		  NULL, 0, finfo->info->unresolved_syms_in_shared_libs == RM_GENERATE_ERROR)))
 	    {
 	      eoinfo->failed = TRUE;
diff --git a/ld/testsuite/ld-gc/dummy.s b/ld/testsuite/ld-gc/dummy.s
new file mode 100644
index 0000000..403f980
--- /dev/null
+++ b/ld/testsuite/ld-gc/dummy.s
@@ -0,0 +1 @@
+# Dummy
diff --git a/ld/testsuite/ld-gc/gc.exp b/ld/testsuite/ld-gc/gc.exp
index c271a3d..7005442 100644
--- a/ld/testsuite/ld-gc/gc.exp
+++ b/ld/testsuite/ld-gc/gc.exp
@@ -92,3 +92,11 @@ test_gc "Check --gc-section/-r/-u" "gcrel" $ld "-r --gc-sections -u used_func"
 run_dump_test "noent"
 run_dump_test "abi-note"
 run_dump_test "start"
+if { [is_remote host] || [which $CC] != 0 } {
+    if { [istarget "*-*-linux*"] } {
+	ld_compile "$CC -fPIC $CFLAGS $cflags" $srcdir/$subdir/pr11218-1.c tmpdir/pr11218-1.o
+	ld_simple_link $ld tmpdir/pr11218-1.so "-shared tmpdir/pr11218-1.o"
+ 	ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/pr11218-2.c tmpdir/pr11218-2.o
+	run_dump_test "pr11218"
+    }
+}
diff --git a/ld/testsuite/ld-gc/pr11218-1.c b/ld/testsuite/ld-gc/pr11218-1.c
new file mode 100644
index 0000000..9cc79f0
--- /dev/null
+++ b/ld/testsuite/ld-gc/pr11218-1.c
@@ -0,0 +1,5 @@
+extern void unresolved_detected_at_runtime_not_at_linktime(void);
+void foo_in_so(void)
+{
+   unresolved_detected_at_runtime_not_at_linktime();
+}
diff --git a/ld/testsuite/ld-gc/pr11218-2.c b/ld/testsuite/ld-gc/pr11218-2.c
new file mode 100644
index 0000000..2515bc6
--- /dev/null
+++ b/ld/testsuite/ld-gc/pr11218-2.c
@@ -0,0 +1,13 @@
+extern void foo_in_so(void);
+
+void call_unresolved(void)
+{
+   unresolved_detected_at_runtime_not_at_linktime();
+}
+
+int main(int argc, char *argv[])
+{
+   foo_in_so();
+
+   return 0;
+}
diff --git a/ld/testsuite/ld-gc/pr11218.d b/ld/testsuite/ld-gc/pr11218.d
new file mode 100644
index 0000000..1d891d3
--- /dev/null
+++ b/ld/testsuite/ld-gc/pr11218.d
@@ -0,0 +1,5 @@
+# name: --gc-sections with shared library
+# source: dummy.s
+# ld: --gc-sections -e main tmpdir/pr11218-2.o tmpdir/pr11218-1.so
+# target: x86_64-*-linux-gnu i?86-*-linux-gnu
+# error: undefined reference to `unresolved_detected_at_runtime_not_at_linktime'


More information about the Binutils mailing list