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]

[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

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