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