This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH] ld --dynamic-list=
- From: James Lemke <jwlemke at codesourcery dot com>
- To: <binutils at sourceware dot org>
- Date: Mon, 29 Oct 2012 12:49:15 -0400
- Subject: [PATCH] ld --dynamic-list=
I recently had a customer complaint about building an ELF executable that
exports entry points. They used --dynamic-list=$file to specify the names
for export. To make that work they also had to specify -u for each name
and make a reference to each name in their code.
It seems wrong that they have to make a call to a symbol in order to have
it exported.
It seems wrong that names specified by --dynamic-list= don't create an
undefined reference (as per -u).
My solution is attached. There is no functional change for building shared
objects. Only for using --dynamic-list when building executables.
Tested & bootstrapped on x86_64-unknown-linux-gnu
Also tested on a MIPS target.
Comments?
--
Jim Lemke
Mentor Graphics / CodeSourcery
Orillia Ontario, +1-613-963-1073
2012-10-29 James Lemke <jwlemke@codesourcery.com>
bfd/
* elflink.c (bfd_elf_link_mark_dynamic_symbol): Also process type
bfd_link_hash_undefined for --dynamic-list.
2012-10-29 James Lemke <jwlemke@codesourcery.com>
ld/
* ldlang.c (lang_place_undefineds): For executables also add
--dynamic-list names that do not contain wildcards.
* ld.texinfo (--dynamic-list): Document the change above.
2012-10-29 James Lemke <jwlemke@codesourcery.com>
ld/testsuite/
* ld-undefined/entry.exp: Create tmpdir/exports for entry-8.exp.
* ld-undefined/entry-8.exp: New test for --dynamic-list.
* ld-undefined/main.s: Likewise.
Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.455
diff -u -p -r1.455 elflink.c
--- bfd/elflink.c 23 Oct 2012 09:33:54 -0000 1.455
+++ bfd/elflink.c 29 Oct 2012 16:38:32 -0000
@@ -486,7 +486,8 @@ bfd_elf_link_mark_dynamic_symbol (struct
|| (sym != NULL
&& ELF_ST_TYPE (sym->st_info) == STT_OBJECT)))
|| (d != NULL
- && h->root.type == bfd_link_hash_new
+ && (h->root.type == bfd_link_hash_new
+ || h->root.type == bfd_link_hash_undefined)
&& (*d->match) (&d->head, NULL, h->root.root.string)))
h->dynamic = 1;
}
Index: ld/ld.texinfo
===================================================================
RCS file: /cvs/src/src/ld/ld.texinfo,v
retrieving revision 1.286
diff -u -p -r1.286 ld.texinfo
--- ld/ld.texinfo 23 Oct 2012 09:33:55 -0000 1.286
+++ ld/ld.texinfo 29 Oct 2012 16:38:34 -0000
@@ -1224,8 +1224,9 @@ typically used when creating shared libr
global symbols whose references shouldn't be bound to the definition
within the shared library, or creating dynamically linked executables
to specify a list of symbols which should be added to the symbol table
-in the executable. This option is only meaningful on ELF platforms
-which support shared libraries.
+in the executable. If creating an executable, this option will also
+create references as if -u was given for each symbol.
+This option is only meaningful on ELF platforms which support shared libraries.
The format of the dynamic list is the same as the version node without
scope and node name. See @ref{VERSION} for more information.
Index: ld/ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.400
diff -u -p -r1.400 ldlang.c
--- ld/ldlang.c 6 Aug 2012 22:27:52 -0000 1.400
+++ ld/ldlang.c 29 Oct 2012 16:38:34 -0000
@@ -3434,6 +3434,18 @@ lang_place_undefineds (void)
for (ptr = ldlang_undef_chain_list_head; ptr != NULL; ptr = ptr->next)
insert_undefined (ptr->name);
+
+ if (link_info.executable && link_info.dynamic_list)
+ {
+ struct bfd_elf_version_expr *e;
+ for (e = link_info.dynamic_list->head.list; e; e = e->next)
+ {
+ /* If there are no globbing wildcards, create a symbol. */
+ size_t len = strcspn (e->pattern, "*?[");
+ if (e->pattern[len] == '\0')
+ insert_undefined (e->pattern);
+ }
+ }
}
/* Check for all readonly or some readwrite sections. */
Index: ld/testsuite/ld-undefined/entry-8.d
===================================================================
RCS file: ld/testsuite/ld-undefined/entry-8.d
diff -N ld/testsuite/ld-undefined/entry-8.d
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-undefined/entry-8.d 29 Oct 2012 16:38:34 -0000
@@ -0,0 +1,8 @@
+#name: main --dynamic-list archive
+#source: main.s
+#ld: --dynamic-list=tmpdir/exports /usr/lib/crt1.o /usr/lib/crti.o -lc /usr/lib/crtn.o tmpdir/libentry.a
+#objdump: -T
+
+#...
+[0-9a-f]+ +g +D +\.text.* +foo$
+#...
Index: ld/testsuite/ld-undefined/entry.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-undefined/entry.exp,v
retrieving revision 1.1
diff -u -p -r1.1 entry.exp
--- ld/testsuite/ld-undefined/entry.exp 18 Mar 2009 12:11:38 -0000 1.1
+++ ld/testsuite/ld-undefined/entry.exp 29 Oct 2012 16:38:34 -0000
@@ -27,6 +27,10 @@ set build_tests {
run_ld_link_tests $build_tests
+set fp [open "tmpdir/exports" w]
+puts $fp "{\nfoo;\n};"
+close $fp
+
set test_list [lsort [glob -nocomplain $srcdir/$subdir/entry*.d]]
foreach t $test_list {
# We need to strip the ".d", but can leave the dirname.
Index: ld/testsuite/ld-undefined/main.s
===================================================================
RCS file: ld/testsuite/ld-undefined/main.s
diff -N ld/testsuite/ld-undefined/main.s
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-undefined/main.s 29 Oct 2012 16:38:34 -0000
@@ -0,0 +1,4 @@
+ .text
+ .globl main
+main:
+ .byte 2