public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* RFC: Add dynamic list to version script
@ 2006-07-24 22:27 H. J. Lu
  2006-07-25 12:53 ` Ulrich Drepper
  2006-07-26 16:42 ` Michael Matz
  0 siblings, 2 replies; 27+ messages in thread
From: H. J. Lu @ 2006-07-24 22:27 UTC (permalink / raw)
  To: Michael Matz; +Cc: binutils

On Tue, Jul 18, 2006 at 06:10:18PM +0200, Michael Matz wrote:
> Hi,
> 
> On Sun, 16 Jul 2006, H. J. Lu wrote:
> 
> > ld -shared -Bsymbolic will reduce number of dynamic relocations in
> > a shared library. Unfortunately, it won't work correctly with C++
> > exception and maybe other language features.
> > 
> > However, I think it is possible to make -shared -Bsymbolic to work
> > for C++ by providing a way to specify a list of symbols which must
> > be dynamic. We then can do
> > 
> > # g++ -Wl,-Bsymbolic -shared -xxx "list of dynamic symbols" -o libfoo.so ...
> > 
> > and libfoo.so written in C++ will work correctly with much fewer dynamic
> > relocations.
> 
> Yes, I'd like that too (actually a customer of us).  There is some 
> precedent set by the HP-UX linker (and I believe the Solaris linker has 
> that too).  Actually I would make -xxx (whatever the final name would be) 
> accept a list of globs, not just a list of symbols.  Then you simply can 
> say -xxx "_ZTS*,_ZTI*" and have the typeinfo symbols and names exported, 
> while all others are bound symbolically.
> 
> 

Here is a prototype, which added dynamic list to version script. I used

{
dynamic:
  extern "C++"
  {
    *typeinfo*;
  };
};

It seems to work correctly with execptions between shared C++ libraries.


H.J.
-----
bfd/

2006-07-24  H.J. Lu  <hongjiu.lu@intel.com>

	* elf-bfd.h (elf_link_hash_entry): Add a dynamic field.
	(bfd_elf_link_mark_dynamic_symbol): New.

	* elf32-i386.c (elf_i386_check_relocs): Also check the dynamic
	field.
	(elf_i386_relocate_section): Likewise.
	* elf64-x86-64.c (elf64_x86_64_check_relocs): Likewise.
	(elf64_x86_64_relocate_section): Likewise.
	* elflink.c (_bfd_elf_merge_symbol): Likewise.
	(_bfd_elf_fix_symbol_flags): Likewise.
	(_bfd_elf_dynamic_symbol_p): Likewise.
	(_bfd_elf_symbol_refs_local_p): Likewise.
	* elfxx-ia64.c (elfNN_ia64_check_relocs): Likewise.

	* elflink.c (bfd_elf_link_mark_dynamic_symbol): New.
	(bfd_elf_record_link_assignment): Call
	bfd_elf_link_mark_dynamic_symbol on new entry.
	(_bfd_elf_merge_symbol): Likewise.
	(_bfd_elf_export_symbol): Return if the symbol isn't exported.
	(_bfd_elf_link_assign_sym_version): Don't hide a symbol if it
	is marked dynamic.
	(bfd_elf_size_dynamic_sections): Updated.

include/

2006-07-24  H.J. Lu  <hongjiu.lu@intel.com>

	* bfdlink.h (bfd_elf_dynamic_list): New.
	(bfd_link_info): Add a dynamic field.

	* ld.texinfo: Updated.

	* ldgram.y: Support dynamic list.
	* ldlex.l: Likewise.

	* ldlang.c (lang_register_vers_node): Handle dynamic list.
	(lang_new_dynamic_list): New.
	* ldlang.h (lang_new_dynamic_list): Likewise.

	* ldmain.c (main): Initialize link_info.dynamic.

--- binutils/bfd/elf-bfd.h.dynamic	2006-07-18 13:26:51.000000000 -0700
+++ binutils/bfd/elf-bfd.h	2006-07-24 12:40:19.000000000 -0700
@@ -155,6 +155,8 @@ struct elf_link_hash_entry
   unsigned int hidden : 1;
   /* Symbol was forced to local scope due to a version script file.  */
   unsigned int forced_local : 1;
+  /* Symbol was forced to be dynamic due to a version script file.  */
+  unsigned int dynamic : 1;
   /* Symbol was marked during garbage collection.  */
   unsigned int mark : 1;
   /* Symbol is referenced by a non-GOT/non-PLT relocation.  This is
@@ -1833,6 +1835,9 @@ extern bfd_boolean bfd_elf_link_record_d
 extern int bfd_elf_link_record_local_dynamic_symbol
   (struct bfd_link_info *, bfd *, long);
 
+extern void bfd_elf_link_mark_dynamic_symbol
+  (struct bfd_link_info *, struct elf_link_hash_entry *);
+
 extern bfd_boolean _bfd_elf_close_and_cleanup
   (bfd *);
 
--- binutils/bfd/elf32-i386.c.dynamic	2006-07-11 12:53:42.000000000 -0700
+++ binutils/bfd/elf32-i386.c	2006-07-24 13:42:00.000000000 -0700
@@ -1151,6 +1151,8 @@ elf_i386_check_relocs (bfd *abfd,
 	       && (r_type != R_386_PC32
 		   || (h != NULL
 		       && (! info->symbolic
+			   || ! info->dynamic
+			   || h->dynamic
 			   || h->root.type == bfd_link_hash_defweak
 			   || !h->def_regular))))
 	      || (ELIMINATE_COPY_RELOCS
@@ -2630,6 +2632,8 @@ elf_i386_relocate_section (bfd *output_b
 		       && (r_type == R_386_PC32
 			   || !info->shared
 			   || !info->symbolic
+			   || !info->dynamic
+			   || h->dynamic
 			   || !h->def_regular))
 		outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
 	      else
--- binutils/bfd/elf64-x86-64.c.dynamic	2006-07-11 12:53:42.000000000 -0700
+++ binutils/bfd/elf64-x86-64.c	2006-07-24 13:42:14.000000000 -0700
@@ -998,6 +998,8 @@ elf64_x86_64_check_relocs (bfd *abfd, st
 		    && (r_type != R_X86_64_PC64))
 		   || (h != NULL
 		       && (! info->symbolic
+			   || ! info->dynamic
+			   || h->dynamic
 			   || h->root.type == bfd_link_hash_defweak
 			   || !h->def_regular))))
 	      || (ELIMINATE_COPY_RELOCS
@@ -2446,6 +2448,8 @@ elf64_x86_64_relocate_section (bfd *outp
 			   || r_type == R_X86_64_PC64
 			   || !info->shared
 			   || !info->symbolic
+			   || !info->dynamic
+			   || h->dynamic
 			   || !h->def_regular))
 		{
 		  outrel.r_info = ELF64_R_INFO (h->dynindx, r_type);
--- binutils/bfd/elflink.c.dynamic	2006-07-18 13:26:51.000000000 -0700
+++ binutils/bfd/elflink.c	2006-07-24 13:52:56.000000000 -0700
@@ -444,6 +444,21 @@ bfd_elf_link_record_dynamic_symbol (stru
   return TRUE;
 }
 \f
+/* Mark a symbol dynamic.  */
+
+void
+bfd_elf_link_mark_dynamic_symbol (struct bfd_link_info *info,
+				  struct elf_link_hash_entry *h)
+{
+  struct bfd_elf_dynamic_list *d = info->dynamic;
+
+  if (d == NULL || info->relocatable)
+    return;
+
+  if ((*d->match) (&d->head, NULL, h->root.root.string))
+    h->dynamic = 1;
+}
+
 /* Record an assignment to a symbol made by a linker script.  We need
    this in case some dynamic object refers to this symbol.  */
 
@@ -477,7 +492,10 @@ bfd_elf_record_link_assignment (bfd *out
     }
 
   if (h->root.type == bfd_link_hash_new)
-    h->non_elf = 0;
+    {
+      bfd_elf_link_mark_dynamic_symbol (info, h);
+      h->non_elf = 0;
+    }
 
   /* If this symbol is being provided by the linker script, and it is
      currently defined by a dynamic object, but not by a regular
@@ -840,6 +858,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
 
   if (h->root.type == bfd_link_hash_new)
     {
+      bfd_elf_link_mark_dynamic_symbol (info, h);
       h->non_elf = 0;
       return TRUE;
     }
@@ -914,6 +933,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
   if (pold_alignment == NULL
       && !info->shared
       && !info->export_dynamic
+      && !h->dynamic
       && !h->ref_dynamic
       && newdyn
       && newdef
@@ -1626,6 +1646,10 @@ _bfd_elf_export_symbol (struct elf_link_
 {
   struct elf_info_failed *eif = data;
 
+  /* Ignore this if we won't export it.  */
+  if (!eif->info->export_dynamic && !h->dynamic)
+    return TRUE;
+
   /* Ignore indirect symbols.  These are added by the versioning code.  */
   if (h->root.type == bfd_link_hash_indirect)
     return TRUE;
@@ -1842,6 +1866,7 @@ _bfd_elf_link_assign_sym_version (struct
 		  d = (*t->match) (&t->locals, NULL, alc);
 		  if (d != NULL
 		      && h->dynindx != -1
+		      && ! h->dynamic
 		      && ! info->export_dynamic)
 		    (*bed->elf_backend_hide_symbol) (info, h, TRUE);
 		}
@@ -1968,6 +1993,7 @@ _bfd_elf_link_assign_sym_version (struct
 	{
 	  h->verinfo.vertree = local_ver;
 	  if (h->dynindx != -1
+	      && ! h->dynamic
 	      && ! info->export_dynamic)
 	    {
 	      (*bed->elf_backend_hide_symbol) (info, h, TRUE);
@@ -2380,6 +2406,7 @@ _bfd_elf_fix_symbol_flags (struct elf_li
       && eif->info->shared
       && is_elf_hash_table (eif->info->hash)
       && (eif->info->symbolic
+	  || (eif->info->dynamic && !h->dynamic)
 	  || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
       && h->def_regular)
     {
@@ -2608,7 +2635,9 @@ _bfd_elf_dynamic_symbol_p (struct elf_li
 
   /* Identify the cases where name binding rules say that a
      visible symbol resolves locally.  */
-  binding_stays_local_p = info->executable || info->symbolic;
+  binding_stays_local_p = (info->executable
+			   || info->symbolic
+			   || (info->dynamic && !h->dynamic));
 
   switch (ELF_ST_VISIBILITY (h->other))
     {
@@ -2671,7 +2700,9 @@ _bfd_elf_symbol_refs_local_p (struct elf
   /* At this point, we know the symbol is defined and dynamic.  In an
      executable it must resolve locally, likewise when building symbolic
      shared libraries.  */
-  if (info->executable || info->symbolic)
+  if (info->executable
+      || info->symbolic 
+      || (info->dynamic && !h->dynamic))
     return TRUE;
 
   /* Now deal with defined dynamic symbols in shared libraries.  Ones
@@ -5306,7 +5337,7 @@ bfd_elf_size_dynamic_sections (bfd *outp
 
       /* If we are supposed to export all symbols into the dynamic symbol
 	 table (this is not the normal case), then do so.  */
-      if (info->export_dynamic)
+      if (info->export_dynamic || info->dynamic)
 	{
 	  elf_link_hash_traverse (elf_hash_table (info),
 				  _bfd_elf_export_symbol,
--- binutils/bfd/elfxx-ia64.c.dynamic	2006-06-20 11:59:14.000000000 -0700
+++ binutils/bfd/elfxx-ia64.c	2006-07-24 13:42:31.000000000 -0700
@@ -2742,6 +2742,8 @@ elfNN_ia64_check_relocs (abfd, info, sec
 	 this may help reduce memory usage and processing time later.  */
       maybe_dynamic = (h && ((!info->executable
 			      && (!info->symbolic
+				  || !info->dynamic
+				  || h->dynamic
 				  || info->unresolved_syms_in_shared_libs == RM_IGNORE))
 			     || !h->def_regular
 			     || h->root.type == bfd_link_hash_defweak));
@@ -2914,6 +2916,8 @@ elfNN_ia64_check_relocs (abfd, info, sec
 	 this may help reduce memory usage and processing time later.  */
       maybe_dynamic = (h && ((!info->executable
 			      && (!info->symbolic
+				  || !info->dynamic
+				  || h->dynamic
 				  || info->unresolved_syms_in_shared_libs == RM_IGNORE))
 			     || !h->def_regular
 			     || h->root.type == bfd_link_hash_defweak));
--- binutils/include/bfdlink.h.dynamic	2006-07-11 12:53:43.000000000 -0700
+++ binutils/include/bfdlink.h	2006-07-24 11:16:17.000000000 -0700
@@ -221,6 +221,8 @@ enum report_method
   RM_GENERATE_ERROR
 };
 
+struct bfd_elf_dynamic_list;
+
 /* This structure holds all the information needed to communicate
    between BFD and the linker when doing a link.  */
 
@@ -428,6 +430,9 @@ struct bfd_link_info
 
   /* Start and end of RELRO region.  */
   bfd_vma relro_start, relro_end;
+
+  /* List of symbols should be dynamic.  */
+  struct bfd_elf_dynamic_list *dynamic;
 };
 
 /* This structures holds a set of callback functions.  These are
@@ -721,4 +726,12 @@ struct bfd_elf_version_tree
      struct bfd_elf_version_expr *prev, const char *sym);
 };
 
+struct bfd_elf_dynamic_list
+{
+  struct bfd_elf_version_expr_head head;
+  struct bfd_elf_version_expr *(*match)
+    (struct bfd_elf_version_expr_head *head,
+     struct bfd_elf_version_expr *prev, const char *sym);
+};
+
 #endif
--- binutils/ld/ld.texinfo.dynamic	2006-07-11 12:53:43.000000000 -0700
+++ binutils/ld/ld.texinfo	2006-07-24 14:16:15.000000000 -0700
@@ -485,11 +485,11 @@ mentioned in the link.
 If you use @code{dlopen} to load a dynamic object which needs to refer
 back to the symbols defined by the program, rather than some other
 dynamic object, then you will probably need to use this option when
-linking the program itself.
-
-You can also use the version script to control what symbols should
-be added to the dynamic symbol table if the output format supports it.
-See the description of @samp{--version-script} in @ref{VERSION}.
+linking the program itself.  If the output format supports the version
+script, you can also use it to add the symbols needed by the dynamic
+object to the dynamic symbol table in th executable or keep the dynamic
+relocation in the dynamic object.  See the description of
+@samp{--version-script} in @ref{VERSION}.
 
 @ifclear SingleFormat
 @cindex big-endian objects
@@ -1128,7 +1128,10 @@ When creating a shared library, bind ref
 definition within the shared library, if any.  Normally, it is possible
 for a program linked against a shared library to override the definition
 within the shared library.  This option is only meaningful on ELF
-platforms which support shared libraries.
+platforms which support shared libraries.  You can use the version
+script to control which symbols shouldn't be bound to the definitions
+within the shared library.  See the description of
+@samp{--version-script} in @ref{VERSION}.
 
 @kindex --check-sections
 @kindex --no-check-sections
@@ -4464,6 +4467,24 @@ might change in the future, even if the 
 should check that all of your version directives are behaving as you
 expect when you upgrade.
 
+The nameless version node in the version script can be used to control
+which symbols should be exported in an executable or which symbols
+shouldn't be bound within a shared library.
+
+@smallexample
+@{ dynamic: foo; bar; @};
+@end smallexample
+
+When it is used to export symbols in executables, it is similar to
+@samp{--export-dynamic}, except for that symbols can be exported
+selectively with a version script.  When a symbol in a shared library
+is listed as dynamic in a version script, its reference won't be bound
+to the definition within the shared library.  If a symbol isn't listed
+as dynamic, its reference will be bound to the definition within
+the shared library.  It is similar to @samp{-Bsymbolic}, except for
+that those symbols listed as dynamic won't be bound to their
+definitions.
+
 @node Expressions
 @section Expressions in Linker Scripts
 @cindex expressions
--- binutils/ld/ldgram.y.dynamic	2006-06-08 22:37:07.000000000 -0700
+++ binutils/ld/ldgram.y	2006-07-24 11:37:07.000000000 -0700
@@ -150,6 +150,7 @@ static int error_index;
 %token INPUT_SCRIPT INPUT_MRI_SCRIPT INPUT_DEFSYM CASE EXTERN START
 %token <name> VERS_TAG VERS_IDENTIFIER
 %token GLOBAL LOCAL VERSIONK INPUT_VERSION_SCRIPT
+%token LD_DYNAMIC
 %token KEEP ONLY_IF_RO ONLY_IF_RW SPECIAL
 %token EXCLUDE_FILE
 %token CONSTANT
@@ -1217,6 +1218,10 @@ vers_tag:
 		{
 		  $$ = lang_new_vers_node ($3, $7);
 		}
+	|	LD_DYNAMIC ':' vers_defns ';'
+		{
+		  $$ = lang_new_dynamic_list ($3);
+		}
 	;
 
 vers_defns:
@@ -1283,6 +1288,14 @@ vers_defns:
 		{
 		  $$ = lang_new_vers_pattern ($1, "extern", ldgram_vers_current_lang, FALSE);
 		}
+	|	LD_DYNAMIC
+		{
+		  $$ = lang_new_vers_pattern (NULL, "dynamic", ldgram_vers_current_lang, FALSE);
+		}
+	|	vers_defns ';' LD_DYNAMIC
+		{
+		  $$ = lang_new_vers_pattern ($1, "dynamic", ldgram_vers_current_lang, FALSE);
+		}
 	;
 
 opt_semicolon:
--- binutils/ld/ldlang.c.dynamic	2006-07-18 13:26:51.000000000 -0700
+++ binutils/ld/ldlang.c	2006-07-24 14:49:20.000000000 -0700
@@ -6599,6 +6599,15 @@ lang_register_vers_node (const char *nam
   if (name == NULL)
     name = "";
 
+  if (version == NULL)
+    {
+      ASSERT (deps == NULL);
+      if (name[0] != '\0')
+	einfo (_("%F%P: Invalid version tag `%s'. Only anonymous "
+		 "version tag is allowed for dynamic list.\n"), name);
+      return;
+    }
+
   if ((name[0] == '\0' && lang_elf_version_info != NULL)
       || (lang_elf_version_info && lang_elf_version_info->name[0] == '\0'))
     {
@@ -6763,3 +6772,23 @@ lang_add_unique (const char *name)
   ent->next = unique_section_list;
   unique_section_list = ent;
 }
+
+/* Create a list of dynamic symbols.  */
+
+struct bfd_elf_version_tree *
+lang_new_dynamic_list (struct bfd_elf_version_expr *dynamic)
+{
+  struct bfd_elf_dynamic_list *d;
+
+  if (link_info.dynamic != NULL)
+    einfo (_("%F%P: Duplicated dynamic lists.\n"));
+
+  d = xcalloc (1, sizeof *d);
+  d->head.list = dynamic;
+  d->match = lang_vers_match;
+  link_info.dynamic = d;
+
+  lang_finalize_version_expr_head (&d->head);
+
+  return NULL;
+}
--- binutils/ld/ldlang.h.dynamic	2006-06-20 11:59:15.000000000 -0700
+++ binutils/ld/ldlang.h	2006-07-24 11:17:44.000000000 -0700
@@ -591,6 +591,8 @@ extern struct bfd_elf_version_deps *lang
   (struct bfd_elf_version_deps *, const char *);
 extern void lang_register_vers_node
   (const char *, struct bfd_elf_version_tree *, struct bfd_elf_version_deps *);
+extern struct bfd_elf_version_tree *lang_new_dynamic_list
+  (struct bfd_elf_version_expr *);
 bfd_boolean unique_section_p
   (const asection *);
 extern void lang_add_unique
--- binutils/ld/ldlex.l.dynamic	2006-05-30 09:45:42.000000000 -0700
+++ binutils/ld/ldlex.l	2006-07-23 15:30:01.000000000 -0700
@@ -405,6 +405,8 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([
 
 <VERS_NODE>local		{ RTOKEN(LOCAL); }
 
+<VERS_NODE>dynamic		{ RTOKEN(LD_DYNAMIC); }
+
 <VERS_NODE>extern		{ RTOKEN(EXTERN); }
 
 <VERS_NODE>{V_IDENTIFIER}	{ yylval.name = xstrdup (yytext);
--- binutils/ld/ldmain.c.dynamic	2006-07-11 12:53:43.000000000 -0700
+++ binutils/ld/ldmain.c	2006-07-24 11:22:55.000000000 -0700
@@ -318,6 +318,7 @@ main (int argc, char **argv)
   link_info.relax_pass = 1;
   link_info.warn_shared_textrel = FALSE;
   link_info.gc_sections = FALSE;
+  link_info.dynamic = NULL;
 
   config.maxpagesize = 0;
   config.commonpagesize = 0;

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: RFC: Add dynamic list to version script
  2006-07-24 22:27 RFC: Add dynamic list to version script H. J. Lu
@ 2006-07-25 12:53 ` Ulrich Drepper
  2006-07-25 13:49   ` H. J. Lu
  2006-07-26 16:42 ` Michael Matz
  1 sibling, 1 reply; 27+ messages in thread
From: Ulrich Drepper @ 2006-07-25 12:53 UTC (permalink / raw)
  To: H. J. Lu; +Cc: binutils

[-- Attachment #1: Type: text/plain, Size: 457 bytes --]

H. J. Lu wrote:
> Here is a prototype, which added dynamic list to version script.

I think this is stupid at best.  Nobody in their right mind would ever
use DF_SYMBOLIC.  It is the most expensive way to achieve the outcome.
We should not encourage using this option at all.  If anything should be
changed it is adding a warning whenever -Bsymbolic is used.

-- 
➧ Ulrich Drepper ➧ Red Hat, Inc. ➧ 444 Castro St ➧ Mountain View, CA ❖


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 251 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: RFC: Add dynamic list to version script
  2006-07-25 12:53 ` Ulrich Drepper
@ 2006-07-25 13:49   ` H. J. Lu
  2006-07-25 14:04     ` Ulrich Drepper
  0 siblings, 1 reply; 27+ messages in thread
From: H. J. Lu @ 2006-07-25 13:49 UTC (permalink / raw)
  To: Ulrich Drepper; +Cc: binutils

On Tue, Jul 25, 2006 at 05:55:00AM -0700, Ulrich Drepper wrote:
> H. J. Lu wrote:
> > Here is a prototype, which added dynamic list to version script.
> 
> I think this is stupid at best.  Nobody in their right mind would ever
> use DF_SYMBOLIC.  It is the most expensive way to achieve the outcome.
> We should not encourage using this option at all.  If anything should be
> changed it is adding a warning whenever -Bsymbolic is used.
> 

My patch doesn't set DF_SYMBOLIC.


H.J.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: RFC: Add dynamic list to version script
  2006-07-25 13:49   ` H. J. Lu
@ 2006-07-25 14:04     ` Ulrich Drepper
  2006-07-25 14:36       ` H. J. Lu
  0 siblings, 1 reply; 27+ messages in thread
From: Ulrich Drepper @ 2006-07-25 14:04 UTC (permalink / raw)
  To: H. J. Lu; +Cc: binutils

[-- Attachment #1: Type: text/plain, Size: 312 bytes --]

H. J. Lu wrote:
> My patch doesn't set DF_SYMBOLIC.

I know, but it makes no sense to use this without using -Bsymbolic.  It
is entirely a support mechanism for users of -Bsymbolic and that
shouldn't be encouraged.

-- 
➧ Ulrich Drepper ➧ Red Hat, Inc. ➧ 444 Castro St ➧ Mountain View, CA ❖


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 251 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: RFC: Add dynamic list to version script
  2006-07-25 14:04     ` Ulrich Drepper
@ 2006-07-25 14:36       ` H. J. Lu
  2006-07-25 14:49         ` Ulrich Drepper
  0 siblings, 1 reply; 27+ messages in thread
From: H. J. Lu @ 2006-07-25 14:36 UTC (permalink / raw)
  To: Ulrich Drepper; +Cc: binutils

On Tue, Jul 25, 2006 at 07:06:05AM -0700, Ulrich Drepper wrote:
> H. J. Lu wrote:
> > My patch doesn't set DF_SYMBOLIC.
> 
> I know, but it makes no sense to use this without using -Bsymbolic.  It
> is entirely a support mechanism for users of -Bsymbolic and that
> shouldn't be encouraged.
> 

I see nothing wrong with it. First, there is no way to make a global
symbol dynamic selectively in executable. Also the protected symbol
is expensive at run-time.


H.J.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: RFC: Add dynamic list to version script
  2006-07-25 14:36       ` H. J. Lu
@ 2006-07-25 14:49         ` Ulrich Drepper
  0 siblings, 0 replies; 27+ messages in thread
From: Ulrich Drepper @ 2006-07-25 14:49 UTC (permalink / raw)
  To: H. J. Lu; +Cc: binutils

[-- Attachment #1: Type: text/plain, Size: 417 bytes --]

H. J. Lu wrote:
> I see nothing wrong with it. First, there is no way to make a global
> symbol dynamic selectively in executable.

The usual global/local selection is sufficient for that.


> Also the protected symbol
> is expensive at run-time.

Who is talked about protected?  The correct way are local aliases.

-- 
➧ Ulrich Drepper ➧ Red Hat, Inc. ➧ 444 Castro St ➧ Mountain View, CA ❖


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 251 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: RFC: Add dynamic list to version script
  2006-07-24 22:27 RFC: Add dynamic list to version script H. J. Lu
  2006-07-25 12:53 ` Ulrich Drepper
@ 2006-07-26 16:42 ` Michael Matz
  2006-07-27 17:11   ` H. J. Lu
  1 sibling, 1 reply; 27+ messages in thread
From: Michael Matz @ 2006-07-26 16:42 UTC (permalink / raw)
  To: H. J. Lu; +Cc: binutils

Hi H.J.,

On Mon, 24 Jul 2006, H. J. Lu wrote:

> Here is a prototype, which added dynamic list to version script. I used
> 
> {
> dynamic:
>   extern "C++"
>   {
>     *typeinfo*;
>   };
> };
> 
> It seems to work correctly with execptions between shared C++ libraries.

Yep.  Though it slightly changes the output even without using a version 
script but using -Bsymbolic.  For instance a very simple library defining 
just one class 'A' with a ctor has this set of interesting relocs without 
the patch, without any flag:

000017a0  00001201 R_386_32          00000730   _ZTS1A
00001884  00001506 R_386_GLOB_DAT    0000179c   _ZTI1A
0000189c  00001407 R_386_JUMP_SLOT   000006ca   _ZN1AC1Ei

With -Bsymbolic (still not applied the patch) this changes as expected to:

000018a0  00000008 R_386_RELATIVE
000018a4  00000008 R_386_RELATIVE

(and no JUMP_SLOT entry for the ctor), i.e. all three references are bound 
locally.  When the patch is applied, no version script is used, but 
-Bsymbolic I have this set of relocs:

000018a4  00000008 R_386_RELATIVE
00001790  00001201 R_386_32          00000720   _ZTS1A

So, no reference to the typeinfo node or the ctor anymore, locally bound.  
But still a reference to the typeinfo name symbol.  As said, with 
-Bsymbolic and no version script.  I think some of the (info->dynamic && 
!h->dynamic) conditions are wrong.  With a version script I get this set 
of relocs:

00001790  00001201 R_386_32          00000720   _ZTS1A
00001874  00001506 R_386_GLOB_DAT    0000178c   _ZTI1A

(no JUMP_SLOT, as expected that's now bound locally).  With -Bsymbolic the 
_ZTI1A reloc goes away, but the _ZTS1A remains.

I find the overloading of semantics a bit confusing.  I mean that using a 
version script with the "dynamic" tag implicitely has the effect of 
-Bsymbolic without actually mentioning that flag.  This means that an 
empty version script using the "dynamic" tag is the opposite of using no 
version script.  Perhaps such version script should only have an effect if 
the user also specifies -Bsymbolic (i.e. creating exceptions to the 
-Bsymbolic symbol set).  OTOH it's documented so it's not that important.

Oh, and yes, throwing exceptions does work, while without the version 
script it does not :-)  Nice.


Ciao,
Michael.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: RFC: Add dynamic list to version script
  2006-07-26 16:42 ` Michael Matz
@ 2006-07-27 17:11   ` H. J. Lu
  2006-07-28 13:14     ` Michael Matz
  0 siblings, 1 reply; 27+ messages in thread
From: H. J. Lu @ 2006-07-27 17:11 UTC (permalink / raw)
  To: Michael Matz; +Cc: binutils

On Wed, Jul 26, 2006 at 06:42:03PM +0200, Michael Matz wrote:
> Hi H.J.,
> 
> On Mon, 24 Jul 2006, H. J. Lu wrote:
> 
> > Here is a prototype, which added dynamic list to version script. I used
> > 
> > {
> > dynamic:
> >   extern "C++"
> >   {
> >     *typeinfo*;
> >   };
> > };
> > 
> > It seems to work correctly with execptions between shared C++ libraries.
> 
> Yep.  Though it slightly changes the output even without using a version 
> script but using -Bsymbolic.  For instance a very simple library defining 
> just one class 'A' with a ctor has this set of interesting relocs without 
> the patch, without any flag:
> 
> 000017a0  00001201 R_386_32          00000730   _ZTS1A
> 00001884  00001506 R_386_GLOB_DAT    0000179c   _ZTI1A
> 0000189c  00001407 R_386_JUMP_SLOT   000006ca   _ZN1AC1Ei
> 
> With -Bsymbolic (still not applied the patch) this changes as expected to:
> 
> 000018a0  00000008 R_386_RELATIVE
> 000018a4  00000008 R_386_RELATIVE
> 
> (and no JUMP_SLOT entry for the ctor), i.e. all three references are bound 
> locally.  When the patch is applied, no version script is used, but 
> -Bsymbolic I have this set of relocs:
> 
> 000018a4  00000008 R_386_RELATIVE
> 00001790  00001201 R_386_32          00000720   _ZTS1A
> 
> So, no reference to the typeinfo node or the ctor anymore, locally bound.  
> But still a reference to the typeinfo name symbol.  As said, with 
> -Bsymbolic and no version script.  I think some of the (info->dynamic && 
> !h->dynamic) conditions are wrong.  With a version script I get this set 
> of relocs:
> 
> 00001790  00001201 R_386_32          00000720   _ZTS1A
> 00001874  00001506 R_386_GLOB_DAT    0000178c   _ZTI1A
> 
> (no JUMP_SLOT, as expected that's now bound locally).  With -Bsymbolic the 
> _ZTI1A reloc goes away, but the _ZTS1A remains.

Can you show me your example?

> 
> I find the overloading of semantics a bit confusing.  I mean that using a 
> version script with the "dynamic" tag implicitely has the effect of 
> -Bsymbolic without actually mentioning that flag.  This means that an 
> empty version script using the "dynamic" tag is the opposite of using no 
> version script.  Perhaps such version script should only have an effect if 
> the user also specifies -Bsymbolic (i.e. creating exceptions to the 
> -Bsymbolic symbol set).  OTOH it's documented so it's not that important.
> 

The dynamic verion script doesn't imply -Bsymbolic and shouldn't be used
together with -Bsymbolic since -Bsymbolic will set DF_SYMBOLIC and
dynamic linker will treat the DSO differently. What it does is to bind
all symbols locally except for which are undefined or on the dynamic
list.

BTW, I'd like to have a new option name and I am thinking to add an
option to make C++ symbols dynamic automatically. Does anyone have
any suggestions for new option name?


H.J.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: RFC: Add dynamic list to version script
  2006-07-27 17:11   ` H. J. Lu
@ 2006-07-28 13:14     ` Michael Matz
  2006-07-28 17:40       ` H. J. Lu
  0 siblings, 1 reply; 27+ messages in thread
From: Michael Matz @ 2006-07-28 13:14 UTC (permalink / raw)
  To: H. J. Lu; +Cc: binutils

Hi,

On Thu, 27 Jul 2006, H. J. Lu wrote:

> > (no JUMP_SLOT, as expected that's now bound locally).  With -Bsymbolic the 
> > _ZTI1A reloc goes away, but the _ZTS1A remains.
> 
> Can you show me your example?

% cat header.h
struct A {
  int i;
  A(int i): i(i) {}
};

% cat lib.cpp
#include "header.h"
void f()
{
  throw (A(42));
}

% cat app.cpp
#include <stdio.h>
#include "header.h"
extern void f();
int main()
{
  try {
    f();
  } catch (A a) {
    printf ("Got A: %d\n", a.i);
  } catch (...) {
    printf ("Got something\n");
  }
  return 0;
}

> > I find the overloading of semantics a bit confusing.  I mean that 
> > using a version script with the "dynamic" tag implicitely has the 
> > effect of -Bsymbolic without actually mentioning that flag.  This 
> > means that an empty version script using the "dynamic" tag is the 
> > opposite of using no version script.  Perhaps such version script 
> > should only have an effect if the user also specifies -Bsymbolic (i.e. 
> > creating exceptions to the -Bsymbolic symbol set).  OTOH it's 
> > documented so it's not that important.
> > 
> 
> The dynamic verion script doesn't imply -Bsymbolic and shouldn't be used 
> together with -Bsymbolic since -Bsymbolic will set DF_SYMBOLIC and 
> dynamic linker will treat the DSO differently.

Ah yes, I only mean the effect of -Bsymbolic to bind self-defined symbols 
locally.  I wonder if DT_SYMBOLIC makes a difference in the end.  During 
link editing all references to symbols defined in the DSO are bound 
locally by ld.  So there's no reference left for ld.so which could be 
satisfied by the DSO itself, hence it shouldn't matter that it comes first 
in the symbol search order with DT_SYMBOLIC.  Hmm.

> What it does is to bind all symbols locally except for which are 
> undefined or on the dynamic list.

With an empty dynamic list, isn't that exactly what -Bsymbolic does, 
ignoring the setting of DT_SYMBOLIC?

> BTW, I'd like to have a new option name and I am thinking to add an 
> option to make C++ symbols dynamic automatically. Does anyone have any 
> suggestions for new option name?

How do you envision should it work?  Would you implement a rule of what 
C++ symbols are in ld (i.e. something like the globs), or would you 
somehow mark the symbols in the compiler?  How about -dynamic-only-cpp or 
similar?


Ciao,
Michael.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: RFC: Add dynamic list to version script
  2006-07-28 13:14     ` Michael Matz
@ 2006-07-28 17:40       ` H. J. Lu
  2006-07-28 17:59         ` Ulrich Drepper
  2006-08-08 17:22         ` H. J. Lu
  0 siblings, 2 replies; 27+ messages in thread
From: H. J. Lu @ 2006-07-28 17:40 UTC (permalink / raw)
  To: Michael Matz; +Cc: binutils

On Fri, Jul 28, 2006 at 03:13:49PM +0200, Michael Matz wrote:
> Hi,
> 
> On Thu, 27 Jul 2006, H. J. Lu wrote:
> 
> > > (no JUMP_SLOT, as expected that's now bound locally).  With -Bsymbolic the 
> > > _ZTI1A reloc goes away, but the _ZTS1A remains.
> > 
> > Can you show me your example?

This updated patch fixes it.

> 
> 
> > > I find the overloading of semantics a bit confusing.  I mean that 
> > > using a version script with the "dynamic" tag implicitely has the 
> > > effect of -Bsymbolic without actually mentioning that flag.  This 
> > > means that an empty version script using the "dynamic" tag is the 
> > > opposite of using no version script.  Perhaps such version script 
> > > should only have an effect if the user also specifies -Bsymbolic (i.e. 
> > > creating exceptions to the -Bsymbolic symbol set).  OTOH it's 
> > > documented so it's not that important.
> > > 
> > 
> > The dynamic verion script doesn't imply -Bsymbolic and shouldn't be used 
> > together with -Bsymbolic since -Bsymbolic will set DF_SYMBOLIC and 
> > dynamic linker will treat the DSO differently.
> 
> Ah yes, I only mean the effect of -Bsymbolic to bind self-defined symbols 
> locally.  I wonder if DT_SYMBOLIC makes a difference in the end.  During 
> link editing all references to symbols defined in the DSO are bound 
> locally by ld.  So there's no reference left for ld.so which could be 
> satisfied by the DSO itself, hence it shouldn't matter that it comes first 
> in the symbol search order with DT_SYMBOLIC.  Hmm.
> 
> > What it does is to bind all symbols locally except for which are 
> > undefined or on the dynamic list.
> 
> With an empty dynamic list, isn't that exactly what -Bsymbolic does, 
> ignoring the setting of DT_SYMBOLIC?

The current scheme won't allow empty dynamic list. How useful is empty
dynamic list?

> 
> > BTW, I'd like to have a new option name and I am thinking to add an 
> > option to make C++ symbols dynamic automatically. Does anyone have any 
> > suggestions for new option name?
> 
> How do you envision should it work?  Would you implement a rule of what 
> C++ symbols are in ld (i.e. something like the globs), or would you 
> somehow mark the symbols in the compiler?  How about -dynamic-only-cpp or 
> similar?
> 

I am thinking a special section containing a dynamic list and we can
have a builtin dynamic list for C++. How about --dynamic-list and
--dynamic-list-cpp?


H.J.
-----
bfd/

2006-07-24  H.J. Lu  <hongjiu.lu@intel.com>

	* elf-bfd.h (elf_link_hash_entry): Add a dynamic field.
	(bfd_elf_link_mark_dynamic_symbol): New.

	* elf32-i386.c (elf_i386_check_relocs): Also check the dynamic
	field.
	(elf_i386_relocate_section): Likewise.
	* elf64-x86-64.c (elf64_x86_64_check_relocs): Likewise.
	(elf64_x86_64_relocate_section): Likewise.
	* elflink.c (_bfd_elf_merge_symbol): Likewise.
	(_bfd_elf_fix_symbol_flags): Likewise.
	(_bfd_elf_dynamic_symbol_p): Likewise.
	(_bfd_elf_symbol_refs_local_p): Likewise.
	* elfxx-ia64.c (elfNN_ia64_check_relocs): Likewise.

	* elflink.c (bfd_elf_link_mark_dynamic_symbol): New.
	(bfd_elf_record_link_assignment): Call
	bfd_elf_link_mark_dynamic_symbol on new entry.
	(_bfd_elf_merge_symbol): Likewise.
	(_bfd_elf_export_symbol): Return if the symbol isn't exported.
	(_bfd_elf_link_assign_sym_version): Don't hide a symbol if it
	is marked dynamic.
	(bfd_elf_size_dynamic_sections): Updated.

include/

2006-07-24  H.J. Lu  <hongjiu.lu@intel.com>

	* bfdlink.h (bfd_elf_dynamic_list): New.
	(bfd_link_info): Add a dynamic field.

	* ld.texinfo: Updated.

	* ldgram.y: Support dynamic list.
	* ldlex.l: Likewise.

	* ldlang.c (lang_register_vers_node): Handle dynamic list.
	(lang_new_dynamic_list): New.
	* ldlang.h (lang_new_dynamic_list): Likewise.

	* ldmain.c (main): Initialize link_info.dynamic.

--- binutils/bfd/elf-bfd.h.dynamic	2006-07-18 13:26:51.000000000 -0700
+++ binutils/bfd/elf-bfd.h	2006-07-24 12:40:19.000000000 -0700
@@ -155,6 +155,8 @@ struct elf_link_hash_entry
   unsigned int hidden : 1;
   /* Symbol was forced to local scope due to a version script file.  */
   unsigned int forced_local : 1;
+  /* Symbol was forced to be dynamic due to a version script file.  */
+  unsigned int dynamic : 1;
   /* Symbol was marked during garbage collection.  */
   unsigned int mark : 1;
   /* Symbol is referenced by a non-GOT/non-PLT relocation.  This is
@@ -1833,6 +1835,9 @@ extern bfd_boolean bfd_elf_link_record_d
 extern int bfd_elf_link_record_local_dynamic_symbol
   (struct bfd_link_info *, bfd *, long);
 
+extern void bfd_elf_link_mark_dynamic_symbol
+  (struct bfd_link_info *, struct elf_link_hash_entry *);
+
 extern bfd_boolean _bfd_elf_close_and_cleanup
   (bfd *);
 
--- binutils/bfd/elf32-i386.c.dynamic	2006-07-11 12:53:42.000000000 -0700
+++ binutils/bfd/elf32-i386.c	2006-07-28 10:09:01.000000000 -0700
@@ -1150,7 +1150,8 @@ elf_i386_check_relocs (bfd *abfd,
 	       && (sec->flags & SEC_ALLOC) != 0
 	       && (r_type != R_386_PC32
 		   || (h != NULL
-		       && (! info->symbolic
+		       && (! (info->symbolic
+			      || (info->dynamic && !h->dynamic))
 			   || h->root.type == bfd_link_hash_defweak
 			   || !h->def_regular))))
 	      || (ELIMINATE_COPY_RELOCS
@@ -2629,7 +2630,8 @@ elf_i386_relocate_section (bfd *output_b
 		       && h->dynindx != -1
 		       && (r_type == R_386_PC32
 			   || !info->shared
-			   || !info->symbolic
+			   || !(info->symbolic
+				|| (info->dynamic && !h->dynamic))
 			   || !h->def_regular))
 		outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
 	      else
--- binutils/bfd/elf64-x86-64.c.dynamic	2006-07-11 12:53:42.000000000 -0700
+++ binutils/bfd/elf64-x86-64.c	2006-07-28 10:09:49.000000000 -0700
@@ -997,7 +997,8 @@ elf64_x86_64_check_relocs (bfd *abfd, st
 		    && (r_type != R_X86_64_PC32)
 		    && (r_type != R_X86_64_PC64))
 		   || (h != NULL
-		       && (! info->symbolic
+		       && (! (info->symbolic
+			      || (info->dynamic && !h->dynamic))
 			   || h->root.type == bfd_link_hash_defweak
 			   || !h->def_regular))))
 	      || (ELIMINATE_COPY_RELOCS
@@ -2445,7 +2446,8 @@ elf64_x86_64_relocate_section (bfd *outp
 			   || r_type == R_X86_64_PC32
 			   || r_type == R_X86_64_PC64
 			   || !info->shared
-			   || !info->symbolic
+			   || !(info->symbolic
+				|| (info->dynamic && !h->dynamic))
 			   || !h->def_regular))
 		{
 		  outrel.r_info = ELF64_R_INFO (h->dynindx, r_type);
--- binutils/bfd/elflink.c.dynamic	2006-07-18 13:26:51.000000000 -0700
+++ binutils/bfd/elflink.c	2006-07-24 13:52:56.000000000 -0700
@@ -444,6 +444,21 @@ bfd_elf_link_record_dynamic_symbol (stru
   return TRUE;
 }
 \f
+/* Mark a symbol dynamic.  */
+
+void
+bfd_elf_link_mark_dynamic_symbol (struct bfd_link_info *info,
+				  struct elf_link_hash_entry *h)
+{
+  struct bfd_elf_dynamic_list *d = info->dynamic;
+
+  if (d == NULL || info->relocatable)
+    return;
+
+  if ((*d->match) (&d->head, NULL, h->root.root.string))
+    h->dynamic = 1;
+}
+
 /* Record an assignment to a symbol made by a linker script.  We need
    this in case some dynamic object refers to this symbol.  */
 
@@ -477,7 +492,10 @@ bfd_elf_record_link_assignment (bfd *out
     }
 
   if (h->root.type == bfd_link_hash_new)
-    h->non_elf = 0;
+    {
+      bfd_elf_link_mark_dynamic_symbol (info, h);
+      h->non_elf = 0;
+    }
 
   /* If this symbol is being provided by the linker script, and it is
      currently defined by a dynamic object, but not by a regular
@@ -840,6 +858,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
 
   if (h->root.type == bfd_link_hash_new)
     {
+      bfd_elf_link_mark_dynamic_symbol (info, h);
       h->non_elf = 0;
       return TRUE;
     }
@@ -914,6 +933,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
   if (pold_alignment == NULL
       && !info->shared
       && !info->export_dynamic
+      && !h->dynamic
       && !h->ref_dynamic
       && newdyn
       && newdef
@@ -1626,6 +1646,10 @@ _bfd_elf_export_symbol (struct elf_link_
 {
   struct elf_info_failed *eif = data;
 
+  /* Ignore this if we won't export it.  */
+  if (!eif->info->export_dynamic && !h->dynamic)
+    return TRUE;
+
   /* Ignore indirect symbols.  These are added by the versioning code.  */
   if (h->root.type == bfd_link_hash_indirect)
     return TRUE;
@@ -1842,6 +1866,7 @@ _bfd_elf_link_assign_sym_version (struct
 		  d = (*t->match) (&t->locals, NULL, alc);
 		  if (d != NULL
 		      && h->dynindx != -1
+		      && ! h->dynamic
 		      && ! info->export_dynamic)
 		    (*bed->elf_backend_hide_symbol) (info, h, TRUE);
 		}
@@ -1968,6 +1993,7 @@ _bfd_elf_link_assign_sym_version (struct
 	{
 	  h->verinfo.vertree = local_ver;
 	  if (h->dynindx != -1
+	      && ! h->dynamic
 	      && ! info->export_dynamic)
 	    {
 	      (*bed->elf_backend_hide_symbol) (info, h, TRUE);
@@ -2380,6 +2406,7 @@ _bfd_elf_fix_symbol_flags (struct elf_li
       && eif->info->shared
       && is_elf_hash_table (eif->info->hash)
       && (eif->info->symbolic
+	  || (eif->info->dynamic && !h->dynamic)
 	  || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
       && h->def_regular)
     {
@@ -2608,7 +2635,9 @@ _bfd_elf_dynamic_symbol_p (struct elf_li
 
   /* Identify the cases where name binding rules say that a
      visible symbol resolves locally.  */
-  binding_stays_local_p = info->executable || info->symbolic;
+  binding_stays_local_p = (info->executable
+			   || info->symbolic
+			   || (info->dynamic && !h->dynamic));
 
   switch (ELF_ST_VISIBILITY (h->other))
     {
@@ -2671,7 +2700,9 @@ _bfd_elf_symbol_refs_local_p (struct elf
   /* At this point, we know the symbol is defined and dynamic.  In an
      executable it must resolve locally, likewise when building symbolic
      shared libraries.  */
-  if (info->executable || info->symbolic)
+  if (info->executable
+      || info->symbolic 
+      || (info->dynamic && !h->dynamic))
     return TRUE;
 
   /* Now deal with defined dynamic symbols in shared libraries.  Ones
@@ -5306,7 +5337,7 @@ bfd_elf_size_dynamic_sections (bfd *outp
 
       /* If we are supposed to export all symbols into the dynamic symbol
 	 table (this is not the normal case), then do so.  */
-      if (info->export_dynamic)
+      if (info->export_dynamic || info->dynamic)
 	{
 	  elf_link_hash_traverse (elf_hash_table (info),
 				  _bfd_elf_export_symbol,
--- binutils/bfd/elfxx-ia64.c.dynamic	2006-06-20 11:59:14.000000000 -0700
+++ binutils/bfd/elfxx-ia64.c	2006-07-28 10:12:44.000000000 -0700
@@ -2741,7 +2741,8 @@ elfNN_ia64_check_relocs (abfd, info, sec
 	 have yet been processed.  Do something with what we know, as
 	 this may help reduce memory usage and processing time later.  */
       maybe_dynamic = (h && ((!info->executable
-			      && (!info->symbolic
+			      && (!(info->symbolic
+				    || (info->dynamic && !h->dynamic))
 				  || info->unresolved_syms_in_shared_libs == RM_IGNORE))
 			     || !h->def_regular
 			     || h->root.type == bfd_link_hash_defweak));
@@ -2913,7 +2914,8 @@ elfNN_ia64_check_relocs (abfd, info, sec
 	 have yet been processed.  Do something with what we know, as
 	 this may help reduce memory usage and processing time later.  */
       maybe_dynamic = (h && ((!info->executable
-			      && (!info->symbolic
+			      && (!(info->symbolic
+				    || (info->dynamic && !h->dynamic))
 				  || info->unresolved_syms_in_shared_libs == RM_IGNORE))
 			     || !h->def_regular
 			     || h->root.type == bfd_link_hash_defweak));
--- binutils/include/bfdlink.h.dynamic	2006-07-11 12:53:43.000000000 -0700
+++ binutils/include/bfdlink.h	2006-07-24 11:16:17.000000000 -0700
@@ -221,6 +221,8 @@ enum report_method
   RM_GENERATE_ERROR
 };
 
+struct bfd_elf_dynamic_list;
+
 /* This structure holds all the information needed to communicate
    between BFD and the linker when doing a link.  */
 
@@ -428,6 +430,9 @@ struct bfd_link_info
 
   /* Start and end of RELRO region.  */
   bfd_vma relro_start, relro_end;
+
+  /* List of symbols should be dynamic.  */
+  struct bfd_elf_dynamic_list *dynamic;
 };
 
 /* This structures holds a set of callback functions.  These are
@@ -721,4 +726,12 @@ struct bfd_elf_version_tree
      struct bfd_elf_version_expr *prev, const char *sym);
 };
 
+struct bfd_elf_dynamic_list
+{
+  struct bfd_elf_version_expr_head head;
+  struct bfd_elf_version_expr *(*match)
+    (struct bfd_elf_version_expr_head *head,
+     struct bfd_elf_version_expr *prev, const char *sym);
+};
+
 #endif
--- binutils/ld/ld.texinfo.dynamic	2006-07-11 12:53:43.000000000 -0700
+++ binutils/ld/ld.texinfo	2006-07-24 14:16:15.000000000 -0700
@@ -485,11 +485,11 @@ mentioned in the link.
 If you use @code{dlopen} to load a dynamic object which needs to refer
 back to the symbols defined by the program, rather than some other
 dynamic object, then you will probably need to use this option when
-linking the program itself.
-
-You can also use the version script to control what symbols should
-be added to the dynamic symbol table if the output format supports it.
-See the description of @samp{--version-script} in @ref{VERSION}.
+linking the program itself.  If the output format supports the version
+script, you can also use it to add the symbols needed by the dynamic
+object to the dynamic symbol table in th executable or keep the dynamic
+relocation in the dynamic object.  See the description of
+@samp{--version-script} in @ref{VERSION}.
 
 @ifclear SingleFormat
 @cindex big-endian objects
@@ -1128,7 +1128,10 @@ When creating a shared library, bind ref
 definition within the shared library, if any.  Normally, it is possible
 for a program linked against a shared library to override the definition
 within the shared library.  This option is only meaningful on ELF
-platforms which support shared libraries.
+platforms which support shared libraries.  You can use the version
+script to control which symbols shouldn't be bound to the definitions
+within the shared library.  See the description of
+@samp{--version-script} in @ref{VERSION}.
 
 @kindex --check-sections
 @kindex --no-check-sections
@@ -4464,6 +4467,24 @@ might change in the future, even if the 
 should check that all of your version directives are behaving as you
 expect when you upgrade.
 
+The nameless version node in the version script can be used to control
+which symbols should be exported in an executable or which symbols
+shouldn't be bound within a shared library.
+
+@smallexample
+@{ dynamic: foo; bar; @};
+@end smallexample
+
+When it is used to export symbols in executables, it is similar to
+@samp{--export-dynamic}, except for that symbols can be exported
+selectively with a version script.  When a symbol in a shared library
+is listed as dynamic in a version script, its reference won't be bound
+to the definition within the shared library.  If a symbol isn't listed
+as dynamic, its reference will be bound to the definition within
+the shared library.  It is similar to @samp{-Bsymbolic}, except for
+that those symbols listed as dynamic won't be bound to their
+definitions.
+
 @node Expressions
 @section Expressions in Linker Scripts
 @cindex expressions
--- binutils/ld/ldgram.y.dynamic	2006-06-08 22:37:07.000000000 -0700
+++ binutils/ld/ldgram.y	2006-07-24 11:37:07.000000000 -0700
@@ -150,6 +150,7 @@ static int error_index;
 %token INPUT_SCRIPT INPUT_MRI_SCRIPT INPUT_DEFSYM CASE EXTERN START
 %token <name> VERS_TAG VERS_IDENTIFIER
 %token GLOBAL LOCAL VERSIONK INPUT_VERSION_SCRIPT
+%token LD_DYNAMIC
 %token KEEP ONLY_IF_RO ONLY_IF_RW SPECIAL
 %token EXCLUDE_FILE
 %token CONSTANT
@@ -1217,6 +1218,10 @@ vers_tag:
 		{
 		  $$ = lang_new_vers_node ($3, $7);
 		}
+	|	LD_DYNAMIC ':' vers_defns ';'
+		{
+		  $$ = lang_new_dynamic_list ($3);
+		}
 	;
 
 vers_defns:
@@ -1283,6 +1288,14 @@ vers_defns:
 		{
 		  $$ = lang_new_vers_pattern ($1, "extern", ldgram_vers_current_lang, FALSE);
 		}
+	|	LD_DYNAMIC
+		{
+		  $$ = lang_new_vers_pattern (NULL, "dynamic", ldgram_vers_current_lang, FALSE);
+		}
+	|	vers_defns ';' LD_DYNAMIC
+		{
+		  $$ = lang_new_vers_pattern ($1, "dynamic", ldgram_vers_current_lang, FALSE);
+		}
 	;
 
 opt_semicolon:
--- binutils/ld/ldlang.c.dynamic	2006-07-18 13:26:51.000000000 -0700
+++ binutils/ld/ldlang.c	2006-07-24 14:49:20.000000000 -0700
@@ -6599,6 +6599,15 @@ lang_register_vers_node (const char *nam
   if (name == NULL)
     name = "";
 
+  if (version == NULL)
+    {
+      ASSERT (deps == NULL);
+      if (name[0] != '\0')
+	einfo (_("%F%P: Invalid version tag `%s'. Only anonymous "
+		 "version tag is allowed for dynamic list.\n"), name);
+      return;
+    }
+
   if ((name[0] == '\0' && lang_elf_version_info != NULL)
       || (lang_elf_version_info && lang_elf_version_info->name[0] == '\0'))
     {
@@ -6763,3 +6772,23 @@ lang_add_unique (const char *name)
   ent->next = unique_section_list;
   unique_section_list = ent;
 }
+
+/* Create a list of dynamic symbols.  */
+
+struct bfd_elf_version_tree *
+lang_new_dynamic_list (struct bfd_elf_version_expr *dynamic)
+{
+  struct bfd_elf_dynamic_list *d;
+
+  if (link_info.dynamic != NULL)
+    einfo (_("%F%P: Duplicated dynamic lists.\n"));
+
+  d = xcalloc (1, sizeof *d);
+  d->head.list = dynamic;
+  d->match = lang_vers_match;
+  link_info.dynamic = d;
+
+  lang_finalize_version_expr_head (&d->head);
+
+  return NULL;
+}
--- binutils/ld/ldlang.h.dynamic	2006-06-20 11:59:15.000000000 -0700
+++ binutils/ld/ldlang.h	2006-07-24 11:17:44.000000000 -0700
@@ -591,6 +591,8 @@ extern struct bfd_elf_version_deps *lang
   (struct bfd_elf_version_deps *, const char *);
 extern void lang_register_vers_node
   (const char *, struct bfd_elf_version_tree *, struct bfd_elf_version_deps *);
+extern struct bfd_elf_version_tree *lang_new_dynamic_list
+  (struct bfd_elf_version_expr *);
 bfd_boolean unique_section_p
   (const asection *);
 extern void lang_add_unique
--- binutils/ld/ldlex.l.dynamic	2006-05-30 09:45:42.000000000 -0700
+++ binutils/ld/ldlex.l	2006-07-23 15:30:01.000000000 -0700
@@ -405,6 +405,8 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([
 
 <VERS_NODE>local		{ RTOKEN(LOCAL); }
 
+<VERS_NODE>dynamic		{ RTOKEN(LD_DYNAMIC); }
+
 <VERS_NODE>extern		{ RTOKEN(EXTERN); }
 
 <VERS_NODE>{V_IDENTIFIER}	{ yylval.name = xstrdup (yytext);
--- binutils/ld/ldmain.c.dynamic	2006-07-11 12:53:43.000000000 -0700
+++ binutils/ld/ldmain.c	2006-07-24 11:22:55.000000000 -0700
@@ -318,6 +318,7 @@ main (int argc, char **argv)
   link_info.relax_pass = 1;
   link_info.warn_shared_textrel = FALSE;
   link_info.gc_sections = FALSE;
+  link_info.dynamic = NULL;
 
   config.maxpagesize = 0;
   config.commonpagesize = 0;

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: RFC: Add dynamic list to version script
  2006-07-28 17:40       ` H. J. Lu
@ 2006-07-28 17:59         ` Ulrich Drepper
  2006-07-28 18:05           ` H. J. Lu
  2006-08-08 17:22         ` H. J. Lu
  1 sibling, 1 reply; 27+ messages in thread
From: Ulrich Drepper @ 2006-07-28 17:59 UTC (permalink / raw)
  To: H. J. Lu; +Cc: binutils

[-- Attachment #1: Type: text/plain, Size: 204 bytes --]

H. J. Lu wrote:
> This updated patch fixes it.

Again, what is all this supposed to be for if no -Bsymbolic?

-- 
➧ Ulrich Drepper ➧ Red Hat, Inc. ➧ 444 Castro St ➧ Mountain View, CA ❖


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 251 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: RFC: Add dynamic list to version script
  2006-07-28 17:59         ` Ulrich Drepper
@ 2006-07-28 18:05           ` H. J. Lu
  0 siblings, 0 replies; 27+ messages in thread
From: H. J. Lu @ 2006-07-28 18:05 UTC (permalink / raw)
  To: Ulrich Drepper; +Cc: binutils

On Fri, Jul 28, 2006 at 11:00:55AM -0700, Ulrich Drepper wrote:
> H. J. Lu wrote:
> > This updated patch fixes it.
> 
> Again, what is all this supposed to be for if no -Bsymbolic?
> 

It will bind all symbols locally except for those on the dynamic list.


H.J.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: RFC: Add dynamic list to version script
  2006-07-28 17:40       ` H. J. Lu
  2006-07-28 17:59         ` Ulrich Drepper
@ 2006-08-08 17:22         ` H. J. Lu
  2006-08-08 18:49           ` Michael Matz
  2006-08-09  2:02           ` RFC: Add dynamic list to version script Alan Modra
  1 sibling, 2 replies; 27+ messages in thread
From: H. J. Lu @ 2006-08-08 17:22 UTC (permalink / raw)
  To: Michael Matz; +Cc: binutils

On Fri, Jul 28, 2006 at 10:40:40AM -0700, H. J. Lu wrote:
> 
> I am thinking a special section containing a dynamic list and we can
> have a builtin dynamic list for C++. How about --dynamic-list and
> --dynamic-list-cpp?
> 
> 

This patch adds a new linker --dynamic-list option. You can have
as many --dynamic-list as you need. I can add a builtin option for
C++, something like --dynamic-list-cpp. I will add a few testcases if
this patch is accepted.


H.J.
----
bfd/

2006-08-08  H.J. Lu  <hongjiu.lu@intel.com>

	* elf-bfd.h (elf_link_hash_entry): Add a dynamic field.
	(bfd_elf_link_mark_dynamic_symbol): New.

	* elf32-i386.c (elf_i386_check_relocs): Also check the dynamic
	field.
	(elf_i386_relocate_section): Likewise.
	* elf64-x86-64.c (elf64_x86_64_check_relocs): Likewise.
	(elf64_x86_64_relocate_section): Likewise.
	* elflink.c (_bfd_elf_merge_symbol): Likewise.
	(_bfd_elf_fix_symbol_flags): Likewise.
	(_bfd_elf_dynamic_symbol_p): Likewise.
	(_bfd_elf_symbol_refs_local_p): Likewise.
	* elfxx-ia64.c (elfNN_ia64_check_relocs): Likewise.

	* elflink.c (bfd_elf_link_mark_dynamic_symbol): New.
	(bfd_elf_record_link_assignment): Call
	bfd_elf_link_mark_dynamic_symbol on new entry.
	(_bfd_elf_merge_symbol): Likewise.
	(_bfd_elf_export_symbol): Return if the symbol isn't exported.
	(_bfd_elf_link_assign_sym_version): Don't hide a symbol if it
	is marked dynamic.
	(bfd_elf_size_dynamic_sections): Updated.

include/

2006-08-08  H.J. Lu  <hongjiu.lu@intel.com>

	* bfdlink.h (bfd_elf_dynamic_list): New.
	(bfd_link_info): Add a dynamic field.

ld/

2006-08-08  H.J. Lu  <hongjiu.lu@intel.com>

	* NEWS: Mention --dynamic-list.

	* ld.texinfo: Document --dynamic-list.

	* ldgram.y: Support dynamic list.

	* ldlang.c (lang_process): Call lang_finalize_version_expr_head
	on link_info.dynamic if needed.
	(lang_append_dynamic_list): New.
	* ldlang.h (lang_append_dynamic_list): Likewise.

	* ldlex.h (input_enum): Add input_dynamic_list.
	* ldlex.l: Handle it.

	* ldmain.c (main): Initialize link_info.dynamic.

	* lexsup.c (option_values): Add OPTION_DYNAMIC_LIST.
	(ld_options): Add an entry for OPTION_DYNAMIC_LIST.
	(parse_args): Handle OPTION_DYNAMIC_LIST.

--- binutils/bfd/elf-bfd.h.dynamic	2006-08-07 15:34:30.000000000 -0700
+++ binutils/bfd/elf-bfd.h	2006-08-07 15:34:30.000000000 -0700
@@ -155,6 +155,8 @@ struct elf_link_hash_entry
   unsigned int hidden : 1;
   /* Symbol was forced to local scope due to a version script file.  */
   unsigned int forced_local : 1;
+  /* Symbol was forced to be dynamic due to a version script file.  */
+  unsigned int dynamic : 1;
   /* Symbol was marked during garbage collection.  */
   unsigned int mark : 1;
   /* Symbol is referenced by a non-GOT/non-PLT relocation.  This is
@@ -1833,6 +1835,9 @@ extern bfd_boolean bfd_elf_link_record_d
 extern int bfd_elf_link_record_local_dynamic_symbol
   (struct bfd_link_info *, bfd *, long);
 
+extern void bfd_elf_link_mark_dynamic_symbol
+  (struct bfd_link_info *, struct elf_link_hash_entry *);
+
 extern bfd_boolean _bfd_elf_close_and_cleanup
   (bfd *);
 
--- binutils/bfd/elf32-i386.c.dynamic	2006-07-11 12:53:42.000000000 -0700
+++ binutils/bfd/elf32-i386.c	2006-08-07 15:34:30.000000000 -0700
@@ -1150,7 +1150,8 @@ elf_i386_check_relocs (bfd *abfd,
 	       && (sec->flags & SEC_ALLOC) != 0
 	       && (r_type != R_386_PC32
 		   || (h != NULL
-		       && (! info->symbolic
+		       && (! (info->symbolic
+			      || (info->dynamic && !h->dynamic))
 			   || h->root.type == bfd_link_hash_defweak
 			   || !h->def_regular))))
 	      || (ELIMINATE_COPY_RELOCS
@@ -2629,7 +2630,8 @@ elf_i386_relocate_section (bfd *output_b
 		       && h->dynindx != -1
 		       && (r_type == R_386_PC32
 			   || !info->shared
-			   || !info->symbolic
+			   || !(info->symbolic
+				|| (info->dynamic && !h->dynamic))
 			   || !h->def_regular))
 		outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
 	      else
--- binutils/bfd/elf64-x86-64.c.dynamic	2006-08-07 08:43:40.000000000 -0700
+++ binutils/bfd/elf64-x86-64.c	2006-08-07 15:34:30.000000000 -0700
@@ -997,7 +997,8 @@ elf64_x86_64_check_relocs (bfd *abfd, st
 		    && (r_type != R_X86_64_PC32)
 		    && (r_type != R_X86_64_PC64))
 		   || (h != NULL
-		       && (! info->symbolic
+		       && (! (info->symbolic
+			      || (info->dynamic && !h->dynamic))
 			   || h->root.type == bfd_link_hash_defweak
 			   || !h->def_regular))))
 	      || (ELIMINATE_COPY_RELOCS
@@ -2445,7 +2446,8 @@ elf64_x86_64_relocate_section (bfd *outp
 			   || r_type == R_X86_64_PC32
 			   || r_type == R_X86_64_PC64
 			   || !info->shared
-			   || !info->symbolic
+			   || !(info->symbolic
+				|| (info->dynamic && !h->dynamic))
 			   || !h->def_regular))
 		{
 		  outrel.r_info = ELF64_R_INFO (h->dynindx, r_type);
--- binutils/bfd/elflink.c.dynamic	2006-08-07 15:34:30.000000000 -0700
+++ binutils/bfd/elflink.c	2006-08-07 15:34:30.000000000 -0700
@@ -444,6 +444,21 @@ bfd_elf_link_record_dynamic_symbol (stru
   return TRUE;
 }
 \f
+/* Mark a symbol dynamic.  */
+
+void
+bfd_elf_link_mark_dynamic_symbol (struct bfd_link_info *info,
+				  struct elf_link_hash_entry *h)
+{
+  struct bfd_elf_dynamic_list *d = info->dynamic;
+
+  if (d == NULL || info->relocatable)
+    return;
+
+  if ((*d->match) (&d->head, NULL, h->root.root.string))
+    h->dynamic = 1;
+}
+
 /* Record an assignment to a symbol made by a linker script.  We need
    this in case some dynamic object refers to this symbol.  */
 
@@ -477,7 +492,10 @@ bfd_elf_record_link_assignment (bfd *out
     }
 
   if (h->root.type == bfd_link_hash_new)
-    h->non_elf = 0;
+    {
+      bfd_elf_link_mark_dynamic_symbol (info, h);
+      h->non_elf = 0;
+    }
 
   /* If this symbol is being provided by the linker script, and it is
      currently defined by a dynamic object, but not by a regular
@@ -840,6 +858,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
 
   if (h->root.type == bfd_link_hash_new)
     {
+      bfd_elf_link_mark_dynamic_symbol (info, h);
       h->non_elf = 0;
       return TRUE;
     }
@@ -914,6 +933,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
   if (pold_alignment == NULL
       && !info->shared
       && !info->export_dynamic
+      && !h->dynamic
       && !h->ref_dynamic
       && newdyn
       && newdef
@@ -1626,6 +1646,10 @@ _bfd_elf_export_symbol (struct elf_link_
 {
   struct elf_info_failed *eif = data;
 
+  /* Ignore this if we won't export it.  */
+  if (!eif->info->export_dynamic && !h->dynamic)
+    return TRUE;
+
   /* Ignore indirect symbols.  These are added by the versioning code.  */
   if (h->root.type == bfd_link_hash_indirect)
     return TRUE;
@@ -1842,6 +1866,7 @@ _bfd_elf_link_assign_sym_version (struct
 		  d = (*t->match) (&t->locals, NULL, alc);
 		  if (d != NULL
 		      && h->dynindx != -1
+		      && ! h->dynamic
 		      && ! info->export_dynamic)
 		    (*bed->elf_backend_hide_symbol) (info, h, TRUE);
 		}
@@ -1968,6 +1993,7 @@ _bfd_elf_link_assign_sym_version (struct
 	{
 	  h->verinfo.vertree = local_ver;
 	  if (h->dynindx != -1
+	      && ! h->dynamic
 	      && ! info->export_dynamic)
 	    {
 	      (*bed->elf_backend_hide_symbol) (info, h, TRUE);
@@ -2380,6 +2406,7 @@ _bfd_elf_fix_symbol_flags (struct elf_li
       && eif->info->shared
       && is_elf_hash_table (eif->info->hash)
       && (eif->info->symbolic
+	  || (eif->info->dynamic && !h->dynamic)
 	  || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
       && h->def_regular)
     {
@@ -2608,7 +2635,9 @@ _bfd_elf_dynamic_symbol_p (struct elf_li
 
   /* Identify the cases where name binding rules say that a
      visible symbol resolves locally.  */
-  binding_stays_local_p = info->executable || info->symbolic;
+  binding_stays_local_p = (info->executable
+			   || info->symbolic
+			   || (info->dynamic && !h->dynamic));
 
   switch (ELF_ST_VISIBILITY (h->other))
     {
@@ -2671,7 +2700,9 @@ _bfd_elf_symbol_refs_local_p (struct elf
   /* At this point, we know the symbol is defined and dynamic.  In an
      executable it must resolve locally, likewise when building symbolic
      shared libraries.  */
-  if (info->executable || info->symbolic)
+  if (info->executable
+      || info->symbolic 
+      || (info->dynamic && !h->dynamic))
     return TRUE;
 
   /* Now deal with defined dynamic symbols in shared libraries.  Ones
@@ -5322,7 +5353,7 @@ bfd_elf_size_dynamic_sections (bfd *outp
 
       /* If we are supposed to export all symbols into the dynamic symbol
 	 table (this is not the normal case), then do so.  */
-      if (info->export_dynamic)
+      if (info->export_dynamic || info->dynamic)
 	{
 	  elf_link_hash_traverse (elf_hash_table (info),
 				  _bfd_elf_export_symbol,
--- binutils/bfd/elfxx-ia64.c.dynamic	2006-07-28 13:51:45.000000000 -0700
+++ binutils/bfd/elfxx-ia64.c	2006-08-07 15:34:30.000000000 -0700
@@ -2741,7 +2741,8 @@ elfNN_ia64_check_relocs (abfd, info, sec
 	 have yet been processed.  Do something with what we know, as
 	 this may help reduce memory usage and processing time later.  */
       maybe_dynamic = (h && ((!info->executable
-			      && (!info->symbolic
+			      && (!(info->symbolic
+				    || (info->dynamic && !h->dynamic))
 				  || info->unresolved_syms_in_shared_libs == RM_IGNORE))
 			     || !h->def_regular
 			     || h->root.type == bfd_link_hash_defweak));
@@ -2913,7 +2914,8 @@ elfNN_ia64_check_relocs (abfd, info, sec
 	 have yet been processed.  Do something with what we know, as
 	 this may help reduce memory usage and processing time later.  */
       maybe_dynamic = (h && ((!info->executable
-			      && (!info->symbolic
+			      && (!(info->symbolic
+				    || (info->dynamic && !h->dynamic))
 				  || info->unresolved_syms_in_shared_libs == RM_IGNORE))
 			     || !h->def_regular
 			     || h->root.type == bfd_link_hash_defweak));
--- binutils/include/bfdlink.h.dynamic	2006-08-07 08:43:40.000000000 -0700
+++ binutils/include/bfdlink.h	2006-08-07 15:34:30.000000000 -0700
@@ -221,6 +221,8 @@ enum report_method
   RM_GENERATE_ERROR
 };
 
+struct bfd_elf_dynamic_list;
+
 /* This structure holds all the information needed to communicate
    between BFD and the linker when doing a link.  */
 
@@ -431,6 +433,9 @@ struct bfd_link_info
 
   /* Start and end of RELRO region.  */
   bfd_vma relro_start, relro_end;
+
+  /* List of symbols should be dynamic.  */
+  struct bfd_elf_dynamic_list *dynamic;
 };
 
 /* This structures holds a set of callback functions.  These are
@@ -724,4 +729,12 @@ struct bfd_elf_version_tree
      struct bfd_elf_version_expr *prev, const char *sym);
 };
 
+struct bfd_elf_dynamic_list
+{
+  struct bfd_elf_version_expr_head head;
+  struct bfd_elf_version_expr *(*match)
+    (struct bfd_elf_version_expr_head *head,
+     struct bfd_elf_version_expr *prev, const char *sym);
+};
+
 #endif
--- binutils/ld/NEWS.dynamic	2006-08-07 08:43:40.000000000 -0700
+++ binutils/ld/NEWS	2006-08-08 09:49:22.000000000 -0700
@@ -1,4 +1,9 @@
 -*- text -*-
+* ELF: Add --dynamic-list option to specify a list of global symbols
+  whose references shouldn't be bound to the definition within the
+  shared library, or a list of symbols which should be added to the
+  symbol table in the executable. 
+
 * New switch: --print-gc-sections to list any sections removed by garabge
   collection.
 
--- binutils/ld/ld.texinfo.dynamic	2006-08-07 08:43:40.000000000 -0700
+++ binutils/ld/ld.texinfo	2006-08-08 09:47:22.000000000 -0700
@@ -487,9 +487,9 @@ back to the symbols defined by the progr
 dynamic object, then you will probably need to use this option when
 linking the program itself.
 
-You can also use the version script to control what symbols should
+You can also use the dynamic list to control what symbols should
 be added to the dynamic symbol table if the output format supports it.
-See the description of @samp{--version-script} in @ref{VERSION}.
+See the description of @samp{--dynamic-list}.
 
 @ifclear SingleFormat
 @cindex big-endian objects
@@ -1130,6 +1130,19 @@ for a program linked against a shared li
 within the shared library.  This option is only meaningful on ELF
 platforms which support shared libraries.
 
+@kindex --dynamic-list=@var{dynamic-list-file}
+@item --dynamic-list=@var{dynamic-list-file}
+Specify the name of a dynamic list file to the linker.  This is
+typically used when creating shared libraries to specify a list of
+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.
+
+The format of the dynamic list is the same as the version node without
+scope and node name.  See @ref{VERSION} for more information.
+
 @kindex --check-sections
 @kindex --no-check-sections
 @item --check-sections
--- binutils/ld/ldgram.y.dynamic	2006-06-08 22:37:07.000000000 -0700
+++ binutils/ld/ldgram.y	2006-08-08 08:58:33.000000000 -0700
@@ -156,6 +156,7 @@ static int error_index;
 %type <versyms> vers_defns
 %type <versnode> vers_tag
 %type <deflist> verdep
+%token INPUT_DYNAMIC_LIST
 
 %%
 
@@ -163,6 +164,7 @@ file:
 		INPUT_SCRIPT script_file
 	|	INPUT_MRI_SCRIPT mri_script_file
 	|	INPUT_VERSION_SCRIPT version_script_file
+	|	INPUT_DYNAMIC_LIST dynamic_list_file
 	|	INPUT_DEFSYM defsym_expr
 	;
 
@@ -1139,6 +1141,34 @@ phdr_val:
 		}
 	;
 
+dynamic_list_file:
+		{
+		  ldlex_version_file ();
+		  PUSH_ERROR (_("dynamic list"));
+		}
+		dynamic_list_nodes
+		{
+		  ldlex_popstate ();
+		  POP_ERROR ();
+		}
+	;
+
+dynamic_list_nodes:
+		dynamic_list_node
+	|	dynamic_list_nodes dynamic_list_node
+	;
+
+dynamic_list_node:
+		'{' dynamic_list_tag '}' ';'
+	;
+
+dynamic_list_tag:
+		vers_defns ';'
+		{
+		  lang_append_dynamic_list ($1);
+		}
+	;
+
 /* This syntax is used within an external version script file.  */
 
 version_script_file:
--- binutils/ld/ldlang.c.dynamic	2006-08-07 15:34:30.000000000 -0700
+++ binutils/ld/ldlang.c	2006-08-08 08:52:25.000000000 -0700
@@ -83,6 +83,8 @@ static void print_input_section (asectio
 static bfd_boolean lang_one_common (struct bfd_link_hash_entry *, void *);
 static void lang_record_phdrs (void);
 static void lang_do_version_exports_section (void);
+static void lang_finalize_version_expr_head
+  (struct bfd_elf_version_expr_head *);
 
 /* Exported variables.  */
 lang_output_section_statement_type *abs_output_section;
@@ -5583,6 +5585,10 @@ relax_sections (void)
 void
 lang_process (void)
 {
+  /* Finalize dynamic list.  */
+  if (link_info.dynamic)
+    lang_finalize_version_expr_head (&link_info.dynamic->head);
+
   current_target = default_target;
 
   /* Open the output file.  */
@@ -6885,3 +6891,24 @@ lang_add_unique (const char *name)
   ent->next = unique_section_list;
   unique_section_list = ent;
 }
+
+/* Append the list of dynamic symbols to the existing one.  */
+
+void
+lang_append_dynamic_list (struct bfd_elf_version_expr *dynamic)
+{
+  if (link_info.dynamic)
+    {
+      dynamic->next = link_info.dynamic->head.list;
+      link_info.dynamic->head.list = dynamic;
+    }
+  else
+    {
+      struct bfd_elf_dynamic_list *d;
+
+      d = xcalloc (1, sizeof *d);
+      d->head.list = dynamic;
+      d->match = lang_vers_match;
+      link_info.dynamic = d;
+    }
+}
--- binutils/ld/ldlang.h.dynamic	2006-08-07 15:34:30.000000000 -0700
+++ binutils/ld/ldlang.h	2006-08-08 08:52:51.000000000 -0700
@@ -601,6 +601,7 @@ extern struct bfd_elf_version_deps *lang
   (struct bfd_elf_version_deps *, const char *);
 extern void lang_register_vers_node
   (const char *, struct bfd_elf_version_tree *, struct bfd_elf_version_deps *);
+extern void lang_append_dynamic_list (struct bfd_elf_version_expr *);
 bfd_boolean unique_section_p
   (const asection *);
 extern void lang_add_unique
--- binutils/ld/ldlex.h.dynamic	2005-05-16 11:04:40.000000000 -0700
+++ binutils/ld/ldlex.h	2006-08-07 18:44:47.000000000 -0700
@@ -30,6 +30,7 @@ typedef enum input_enum {
   input_script,
   input_mri_script,
   input_version_script,
+  input_dynamic_list,
   input_defsym
 } input_type;
 
--- binutils/ld/ldlex.l.dynamic	2006-05-30 09:45:42.000000000 -0700
+++ binutils/ld/ldlex.l	2006-08-07 19:25:59.000000000 -0700
@@ -132,6 +132,7 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([
 	case input_script: return INPUT_SCRIPT; break;
 	case input_mri_script: return INPUT_MRI_SCRIPT; break;
 	case input_version_script: return INPUT_VERSION_SCRIPT; break;
+	case input_dynamic_list: return INPUT_DYNAMIC_LIST; break;
 	case input_defsym: return INPUT_DEFSYM; break;
 	default: abort ();
 	}
--- binutils/ld/ldmain.c.dynamic	2006-08-07 08:43:40.000000000 -0700
+++ binutils/ld/ldmain.c	2006-08-07 15:34:31.000000000 -0700
@@ -319,6 +319,7 @@ main (int argc, char **argv)
   link_info.warn_shared_textrel = FALSE;
   link_info.gc_sections = FALSE;
   link_info.print_gc_sections = FALSE;
+  link_info.dynamic = NULL;
 
   config.maxpagesize = 0;
   config.commonpagesize = 0;
--- binutils/ld/lexsup.c.dynamic	2006-08-07 08:43:40.000000000 -0700
+++ binutils/ld/lexsup.c	2006-08-07 18:49:50.000000000 -0700
@@ -107,6 +107,7 @@ enum option_values
   OPTION_VERSION,
   OPTION_VERSION_SCRIPT,
   OPTION_VERSION_EXPORTS_SECTION,
+  OPTION_DYNAMIC_LIST,
   OPTION_WARN_COMMON,
   OPTION_WARN_CONSTRUCTORS,
   OPTION_WARN_FATAL,
@@ -501,6 +502,8 @@ static const struct ld_option ld_options
      OPTION_VERSION_EXPORTS_SECTION },
     '\0', N_("SYMBOL"), N_("Take export symbols list from .exports, using\n"
 			   "\t\t\t\tSYMBOL as the version."), TWO_DASHES },
+  { {"dynamic-list", required_argument, NULL, OPTION_DYNAMIC_LIST},
+    '\0', N_("FILE"), N_("Read dynamic list"), TWO_DASHES },
   { {"warn-common", no_argument, NULL, OPTION_WARN_COMMON},
     '\0', NULL, N_("Warn about duplicate common symbols"), TWO_DASHES },
   { {"warn-constructors", no_argument, NULL, OPTION_WARN_CONSTRUCTORS},
@@ -1236,6 +1239,20 @@ parse_args (unsigned argc, char **argv)
 	     .exports sections.  */
 	  command_line.version_exports_section = optarg;
 	  break;
+	case OPTION_DYNAMIC_LIST:
+	  /* This option indicates a small script that only specifies
+	     a dynamic list.  Read it, but don't assume that we've
+	     seen a linker script.  */
+	  {
+	    FILE *hold_script_handle;
+
+	    hold_script_handle = saved_script_handle;
+	    ldfile_open_command_file (optarg);
+	    saved_script_handle = hold_script_handle;
+	    parser_input = input_dynamic_list;
+	    yyparse ();
+	  }
+	  break;
 	case OPTION_WARN_COMMON:
 	  config.warn_common = TRUE;
 	  break;

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: RFC: Add dynamic list to version script
  2006-08-08 17:22         ` H. J. Lu
@ 2006-08-08 18:49           ` Michael Matz
  2006-08-09 20:36             ` PATCH: Add --dynamic-list to ld H. J. Lu
  2006-08-09  2:02           ` RFC: Add dynamic list to version script Alan Modra
  1 sibling, 1 reply; 27+ messages in thread
From: Michael Matz @ 2006-08-08 18:49 UTC (permalink / raw)
  To: H. J. Lu; +Cc: binutils

Hi,

On Tue, 8 Aug 2006, H. J. Lu wrote:

> On Fri, Jul 28, 2006 at 10:40:40AM -0700, H. J. Lu wrote:
> > 
> > I am thinking a special section containing a dynamic list and we can
> > have a builtin dynamic list for C++. How about --dynamic-list and
> > --dynamic-list-cpp?
> > 
> > 
> 
> This patch adds a new linker --dynamic-list option. You can have
> as many --dynamic-list as you need. I can add a builtin option for
> C++, something like --dynamic-list-cpp. I will add a few testcases if
> this patch is accepted.

FWIW I like this :)


Ciao,
Michael.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: RFC: Add dynamic list to version script
  2006-08-08 17:22         ` H. J. Lu
  2006-08-08 18:49           ` Michael Matz
@ 2006-08-09  2:02           ` Alan Modra
  2006-08-09 16:05             ` Michael Matz
  1 sibling, 1 reply; 27+ messages in thread
From: Alan Modra @ 2006-08-09  2:02 UTC (permalink / raw)
  To: H. J. Lu; +Cc: Michael Matz, binutils

On Tue, Aug 08, 2006 at 09:59:50AM -0700, H. J. Lu wrote:
> +  binding_stays_local_p = (info->executable
> +			   || info->symbolic
> +			   || (info->dynamic && !h->dynamic));

> +@kindex --dynamic-list=@var{dynamic-list-file}
> +@item --dynamic-list=@var{dynamic-list-file}
> +Specify the name of a dynamic list file to the linker.  This is
> +typically used when creating shared libraries to specify a list of
> +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.

Your documentation doesn't agree with what the patch does.  In a
previous email you said

> It will bind all symbols locally except for those on the dynamic list.

which is quite different to the description in ld.texinfo.  Please fix.
Also, if you really mean that if --dynamic-list is specified then all
symbols not on the dynamic list will be local, please rewrite the patch
to use forced_local rather than adding a new field to
elf_link_hash_entry.  Extra fields unnecessarily complicate the code and
in this case increase the size of the struct.  I'm almost certain you
haven't found all places that will need to deal with your new field.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: RFC: Add dynamic list to version script
  2006-08-09  2:02           ` RFC: Add dynamic list to version script Alan Modra
@ 2006-08-09 16:05             ` Michael Matz
  2006-08-09 16:19               ` Alan Modra
  2006-08-09 16:25               ` H. J. Lu
  0 siblings, 2 replies; 27+ messages in thread
From: Michael Matz @ 2006-08-09 16:05 UTC (permalink / raw)
  To: Alan Modra; +Cc: H. J. Lu, binutils

Hi,

On Wed, 9 Aug 2006, Alan Modra wrote:

> On Tue, Aug 08, 2006 at 09:59:50AM -0700, H. J. Lu wrote:
> > +  binding_stays_local_p = (info->executable
> > +			   || info->symbolic
> > +			   || (info->dynamic && !h->dynamic));
> 
> > +@kindex --dynamic-list=@var{dynamic-list-file}
> > +@item --dynamic-list=@var{dynamic-list-file}
> > +Specify the name of a dynamic list file to the linker.  This is
> > +typically used when creating shared libraries to specify a list of
> > +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.
> 
> Your documentation doesn't agree with what the patch does.  In a
> previous email you said
> 
> > It will bind all symbols locally except for those on the dynamic list.
> 
> which is quite different to the description in ld.texinfo.  Please fix.
> Also, if you really mean that if --dynamic-list is specified then all
> symbols not on the dynamic list will be local, please rewrite the patch
> to use forced_local rather than adding a new field to
> elf_link_hash_entry.

I don't know what forced_local semantics are exactly, so forgive me if I'm 
spelling out the obvious: the symbols not specified as dynamic symbols 
should be bound locally, but they should still be exported, for others to 
link against.  If that is what forced_local does, nice, but from what I 
read in elflink.c it seems that it's doing something more?


Ciao,
Michael.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: RFC: Add dynamic list to version script
  2006-08-09 16:05             ` Michael Matz
@ 2006-08-09 16:19               ` Alan Modra
  2006-08-09 17:40                 ` H. J. Lu
  2006-08-09 16:25               ` H. J. Lu
  1 sibling, 1 reply; 27+ messages in thread
From: Alan Modra @ 2006-08-09 16:19 UTC (permalink / raw)
  To: Michael Matz; +Cc: H. J. Lu, binutils

On Wed, Aug 09, 2006 at 04:45:42PM +0200, Michael Matz wrote:
> I don't know what forced_local semantics are exactly, so forgive me if I'm 
> spelling out the obvious: the symbols not specified as dynamic symbols 
> should be bound locally, but they should still be exported, for others to 
> link against.  If that is what forced_local does, nice, but from what I 
> read in elflink.c it seems that it's doing something more?

Yes, forced_local does more.  I guess I should have read the entire
thread before commenting.

"bound locally, but they should still be exported" says protected to me,
but I gather you don't want to mark them STV_PROTECTED in the output
because ld.so is slow resolving protected symbols for some reason.  So
why can't ld.so be fixed?

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: RFC: Add dynamic list to version script
  2006-08-09 16:05             ` Michael Matz
  2006-08-09 16:19               ` Alan Modra
@ 2006-08-09 16:25               ` H. J. Lu
  1 sibling, 0 replies; 27+ messages in thread
From: H. J. Lu @ 2006-08-09 16:25 UTC (permalink / raw)
  To: Michael Matz; +Cc: Alan Modra, binutils

On Wed, Aug 09, 2006 at 04:45:42PM +0200, Michael Matz wrote:
> Hi,
> 
> On Wed, 9 Aug 2006, Alan Modra wrote:
> 
> > On Tue, Aug 08, 2006 at 09:59:50AM -0700, H. J. Lu wrote:
> > > +  binding_stays_local_p = (info->executable
> > > +			   || info->symbolic
> > > +			   || (info->dynamic && !h->dynamic));
> > 
> > > +@kindex --dynamic-list=@var{dynamic-list-file}
> > > +@item --dynamic-list=@var{dynamic-list-file}
> > > +Specify the name of a dynamic list file to the linker.  This is
> > > +typically used when creating shared libraries to specify a list of
> > > +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.
> > 
> > Your documentation doesn't agree with what the patch does.  In a
> > previous email you said
> > 
> > > It will bind all symbols locally except for those on the dynamic list.
> > 
> > which is quite different to the description in ld.texinfo.  Please fix.
> > Also, if you really mean that if --dynamic-list is specified then all
> > symbols not on the dynamic list will be local, please rewrite the patch
> > to use forced_local rather than adding a new field to
> > elf_link_hash_entry.
> 
> I don't know what forced_local semantics are exactly, so forgive me if I'm 
> spelling out the obvious: the symbols not specified as dynamic symbols 
> should be bound locally, but they should still be exported, for others to 
> link against.  If that is what forced_local does, nice, but from what I 

It should be:

The symbols not specified as dynamic symbols should be bound locally,
But the symbols specified as dynamic symbols, exported for others to 
link against, can be bound locally or dynamically.

> read in elflink.c it seems that it's doing something more?

We have 2 things going on here:

1. If a symbol should be visible to outside. That affects
dynamic symbol table.
2. If a symbol should be bound locally. That affects dynamic
relocation.

--verion-script will decide #1 for shared library.
--dynamic-list will decide #1 for executable and #2 for
shared library.


H.J.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: RFC: Add dynamic list to version script
  2006-08-09 16:19               ` Alan Modra
@ 2006-08-09 17:40                 ` H. J. Lu
  0 siblings, 0 replies; 27+ messages in thread
From: H. J. Lu @ 2006-08-09 17:40 UTC (permalink / raw)
  To: Michael Matz, binutils

On Thu, Aug 10, 2006 at 01:34:47AM +0930, Alan Modra wrote:
> On Wed, Aug 09, 2006 at 04:45:42PM +0200, Michael Matz wrote:
> > I don't know what forced_local semantics are exactly, so forgive me if I'm 
> > spelling out the obvious: the symbols not specified as dynamic symbols 
> > should be bound locally, but they should still be exported, for others to 
> > link against.  If that is what forced_local does, nice, but from what I 
> > read in elflink.c it seems that it's doing something more?
> 
> Yes, forced_local does more.  I guess I should have read the entire
> thread before commenting.
> 
> "bound locally, but they should still be exported" says protected to me,
> but I gather you don't want to mark them STV_PROTECTED in the output
> because ld.so is slow resolving protected symbols for some reason.  So
> why can't ld.so be fixed?

Yes, protected symbols are expensive. I don't see a way to speed it
up. --dynamic-list is selective -Bsymbolic without DF_SYMBOLIC.


H.J.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* PATCH: Add --dynamic-list to ld
  2006-08-08 18:49           ` Michael Matz
@ 2006-08-09 20:36             ` H. J. Lu
  2006-09-07 15:28               ` Nick Clifton
  0 siblings, 1 reply; 27+ messages in thread
From: H. J. Lu @ 2006-08-09 20:36 UTC (permalink / raw)
  To: Michael Matz; +Cc: binutils

On Tue, Aug 08, 2006 at 07:29:26PM +0200, Michael Matz wrote:
> Hi,
> 
> On Tue, 8 Aug 2006, H. J. Lu wrote:
> 
> > On Fri, Jul 28, 2006 at 10:40:40AM -0700, H. J. Lu wrote:
> > > 
> > > I am thinking a special section containing a dynamic list and we can
> > > have a builtin dynamic list for C++. How about --dynamic-list and
> > > --dynamic-list-cpp?
> > > 
> > > 
> > 
> > This patch adds a new linker --dynamic-list option. You can have
> > as many --dynamic-list as you need. I can add a builtin option for
> > C++, something like --dynamic-list-cpp. I will add a few testcases if
> > this patch is accepted.
> 
> FWIW I like this :)
> 

Here is the updated patch. I added a few testcases. I added
--dynamic-list-cpp-typeinfo. I am not sure how useful it is since
in many cases, you want to add more than just RTTI in a C++ DSO.
--dynamic-list-cpp will be kind of misleading.



H.J.
-----
bfd/

2006-08-08  H.J. Lu  <hongjiu.lu@intel.com>

	* elf-bfd.h (elf_link_hash_entry): Add a dynamic field.
	(bfd_elf_link_mark_dynamic_symbol): New.
	(SYMBOLIC_BIND): New.

	* elf32-i386.c (elf_i386_check_relocs): Replace info->symbolic
	with SYMBOLIC_BIND (info, h).
	(elf_i386_relocate_section): Likewise.
	* elf64-x86-64.c (elf64_x86_64_check_relocs): Likewise.
	(elf64_x86_64_relocate_section): Likewise.
	* elfxx-ia64.c (elfNN_ia64_check_relocs): Likewise.

	* elflink.c (bfd_elf_link_mark_dynamic_symbol): New.
	(bfd_elf_record_link_assignment): Call
	bfd_elf_link_mark_dynamic_symbol on new entry.
	(_bfd_elf_merge_symbol): Likewise.
	(_bfd_elf_export_symbol): Return if the symbol isn't exported.
	(_bfd_elf_fix_symbol_flags): Replace info->symbolic with
	SYMBOLIC_BIND (info, h).
	(_bfd_elf_dynamic_symbol_p): Likewise.
	(_bfd_elf_symbol_refs_local_p): Likewise.
	(bfd_elf_size_dynamic_sections): Updated.

include/

2006-08-08  H.J. Lu  <hongjiu.lu@intel.com>

	* bfdlink.h (bfd_elf_dynamic_list): New.
	(bfd_link_info): Add a dynamic field.

ld/

2006-08-08  H.J. Lu  <hongjiu.lu@intel.com>

	* Makefile.am (CXX): Set to g++.
	(CXX_FOR_TARGET): Likewise.
	* Makefile.in: Regenerated.

	* NEWS: Mention --dynamic-list.

	* ld.texinfo: Document --dynamic-list.

	* ldgram.y: Support dynamic list.

	* ldlang.c (lang_process): Call lang_finalize_version_expr_head
	on link_info.dynamic if needed.
	(lang_append_dynamic_list): New.
	(lang_append_dynamic_list_cpp_typeinfo): New.
	* ldlang.h (lang_append_dynamic_list): Likewise.
	* ldlang.h (lang_append_dynamic_list_cpp_typeinfo): Likewise.

	* ldlex.h (input_enum): Add input_dynamic_list.
	* ldlex.l: Handle it.

	* ldmain.c (main): Initialize link_info.dynamic.

	* lexsup.c (option_values): Add OPTION_DYNAMIC_LIST and
	OPTION_DYNAMIC_LIST_CPP_TYPEINFO.
	(ld_options): Add entries for OPTION_DYNAMIC_LIST and
	OPTION_DYNAMIC_LIST_CPP_TYPEINFO.
	(parse_args): Handle OPTION_DYNAMIC_LIST and
	OPTION_DYNAMIC_LIST_CPP_TYPEINFO.

ld/testsuite/ld-elf/

2006-08-08  H.J. Lu  <hongjiu.lu@intel.com>

	* ld-elf/dl1.c: New file.
	* ld-elf/dl1.list: Likewise.
	* ld-elf/dl1.out: Likewise.
	* ld-elf/dl1main.c: Likewise.
	* ld-elf/dl2.c: Likewise.
	* ld-elf/dl2.list: Likewise.
	* ld-elf/dl2a.out: Likewise.
	* ld-elf/dl2b.out: Likewise.
	* ld-elf/dl2main.c: Likewise.
	* ld-elf/dl2xxx.c: Likewise.
	* ld-elf/dl2xxx.list: Likewise.
	* ld-elf/dl3.cc: Likewise.
	* ld-elf/dl3.list: Likewise.
	* ld-elf/dl3a.out: Likewise.
	* ld-elf/dl3b.out: Likewise.
	* ld-elf/dl3header.h: Likewise.
	* ld-elf/dl3main.cc: Likewise.

	* ld-elf/shared.exp: Updated.

	* lib/ld-lib.exp (run_ld_link_exec_tests): Take an optional
	argument for source language. Use CC/CXX for link, depending
	on source language.
	(run_cc_link_tests): Likewise.

--- binutils/bfd/elf-bfd.h.dynamic	2006-08-08 12:44:47.000000000 -0700
+++ binutils/bfd/elf-bfd.h	2006-08-09 11:21:04.000000000 -0700
@@ -155,6 +155,8 @@ struct elf_link_hash_entry
   unsigned int hidden : 1;
   /* Symbol was forced to local scope due to a version script file.  */
   unsigned int forced_local : 1;
+  /* Symbol was forced to be dynamic due to a version script file.  */
+  unsigned int dynamic : 1;
   /* Symbol was marked during garbage collection.  */
   unsigned int mark : 1;
   /* Symbol is referenced by a non-GOT/non-PLT relocation.  This is
@@ -1833,6 +1835,9 @@ extern bfd_boolean bfd_elf_link_record_d
 extern int bfd_elf_link_record_local_dynamic_symbol
   (struct bfd_link_info *, bfd *, long);
 
+extern void bfd_elf_link_mark_dynamic_symbol
+  (struct bfd_link_info *, struct elf_link_hash_entry *);
+
 extern bfd_boolean _bfd_elf_close_and_cleanup
   (bfd *);
 
@@ -1985,4 +1990,9 @@ extern bfd_boolean _sh_elf_set_mach_from
     }									\
   while (0)
 
+/* Will a symbol be bound to the the definition within the shared
+   library, if any.  */
+#define SYMBOLIC_BIND(INFO, H) \
+    ((INFO)->symbolic || ((INFO)->dynamic && !(H)->dynamic))
+
 #endif /* _LIBELF_H_ */
--- binutils/bfd/elf32-i386.c.dynamic	2006-07-11 12:53:42.000000000 -0700
+++ binutils/bfd/elf32-i386.c	2006-08-09 11:22:03.000000000 -0700
@@ -1150,7 +1150,7 @@ elf_i386_check_relocs (bfd *abfd,
 	       && (sec->flags & SEC_ALLOC) != 0
 	       && (r_type != R_386_PC32
 		   || (h != NULL
-		       && (! info->symbolic
+		       && (! SYMBOLIC_BIND (info, h)
 			   || h->root.type == bfd_link_hash_defweak
 			   || !h->def_regular))))
 	      || (ELIMINATE_COPY_RELOCS
@@ -2629,7 +2629,7 @@ elf_i386_relocate_section (bfd *output_b
 		       && h->dynindx != -1
 		       && (r_type == R_386_PC32
 			   || !info->shared
-			   || !info->symbolic
+			   || !SYMBOLIC_BIND (info, h)
 			   || !h->def_regular))
 		outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
 	      else
--- binutils/bfd/elf64-x86-64.c.dynamic	2006-08-07 08:43:40.000000000 -0700
+++ binutils/bfd/elf64-x86-64.c	2006-08-09 11:23:39.000000000 -0700
@@ -997,7 +997,7 @@ elf64_x86_64_check_relocs (bfd *abfd, st
 		    && (r_type != R_X86_64_PC32)
 		    && (r_type != R_X86_64_PC64))
 		   || (h != NULL
-		       && (! info->symbolic
+		       && (! SYMBOLIC_BIND (info, h)
 			   || h->root.type == bfd_link_hash_defweak
 			   || !h->def_regular))))
 	      || (ELIMINATE_COPY_RELOCS
@@ -2445,7 +2445,7 @@ elf64_x86_64_relocate_section (bfd *outp
 			   || r_type == R_X86_64_PC32
 			   || r_type == R_X86_64_PC64
 			   || !info->shared
-			   || !info->symbolic
+			   || !SYMBOLIC_BIND (info, h)
 			   || !h->def_regular))
 		{
 		  outrel.r_info = ELF64_R_INFO (h->dynindx, r_type);
--- binutils/bfd/elflink.c.dynamic	2006-08-08 12:44:47.000000000 -0700
+++ binutils/bfd/elflink.c	2006-08-09 11:30:41.000000000 -0700
@@ -444,6 +444,21 @@ bfd_elf_link_record_dynamic_symbol (stru
   return TRUE;
 }
 \f
+/* Mark a symbol dynamic.  */
+
+void
+bfd_elf_link_mark_dynamic_symbol (struct bfd_link_info *info,
+				  struct elf_link_hash_entry *h)
+{
+  struct bfd_elf_dynamic_list *d = info->dynamic;
+
+  if (d == NULL || info->relocatable)
+    return;
+
+  if ((*d->match) (&d->head, NULL, h->root.root.string))
+    h->dynamic = 1;
+}
+
 /* Record an assignment to a symbol made by a linker script.  We need
    this in case some dynamic object refers to this symbol.  */
 
@@ -477,7 +492,10 @@ bfd_elf_record_link_assignment (bfd *out
     }
 
   if (h->root.type == bfd_link_hash_new)
-    h->non_elf = 0;
+    {
+      bfd_elf_link_mark_dynamic_symbol (info, h);
+      h->non_elf = 0;
+    }
 
   /* If this symbol is being provided by the linker script, and it is
      currently defined by a dynamic object, but not by a regular
@@ -840,6 +858,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
 
   if (h->root.type == bfd_link_hash_new)
     {
+      bfd_elf_link_mark_dynamic_symbol (info, h);
       h->non_elf = 0;
       return TRUE;
     }
@@ -1626,6 +1645,10 @@ _bfd_elf_export_symbol (struct elf_link_
 {
   struct elf_info_failed *eif = data;
 
+  /* Ignore this if we won't export it.  */
+  if (!eif->info->export_dynamic && !h->dynamic)
+    return TRUE;
+
   /* Ignore indirect symbols.  These are added by the versioning code.  */
   if (h->root.type == bfd_link_hash_indirect)
     return TRUE;
@@ -2379,7 +2402,7 @@ _bfd_elf_fix_symbol_flags (struct elf_li
   if (h->needs_plt
       && eif->info->shared
       && is_elf_hash_table (eif->info->hash)
-      && (eif->info->symbolic
+      && (SYMBOLIC_BIND (eif->info, h)
 	  || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
       && h->def_regular)
     {
@@ -2608,7 +2631,7 @@ _bfd_elf_dynamic_symbol_p (struct elf_li
 
   /* Identify the cases where name binding rules say that a
      visible symbol resolves locally.  */
-  binding_stays_local_p = info->executable || info->symbolic;
+  binding_stays_local_p = info->executable || SYMBOLIC_BIND (info, h);
 
   switch (ELF_ST_VISIBILITY (h->other))
     {
@@ -2671,7 +2694,7 @@ _bfd_elf_symbol_refs_local_p (struct elf
   /* At this point, we know the symbol is defined and dynamic.  In an
      executable it must resolve locally, likewise when building symbolic
      shared libraries.  */
-  if (info->executable || info->symbolic)
+  if (info->executable || SYMBOLIC_BIND (info, h))
     return TRUE;
 
   /* Now deal with defined dynamic symbols in shared libraries.  Ones
@@ -5322,7 +5345,8 @@ bfd_elf_size_dynamic_sections (bfd *outp
 
       /* If we are supposed to export all symbols into the dynamic symbol
 	 table (this is not the normal case), then do so.  */
-      if (info->export_dynamic)
+      if (info->export_dynamic
+	  || (info->executable && info->dynamic))
 	{
 	  elf_link_hash_traverse (elf_hash_table (info),
 				  _bfd_elf_export_symbol,
--- binutils/bfd/elfxx-ia64.c.dynamic	2006-07-28 13:51:45.000000000 -0700
+++ binutils/bfd/elfxx-ia64.c	2006-08-09 11:23:10.000000000 -0700
@@ -2741,7 +2741,7 @@ elfNN_ia64_check_relocs (abfd, info, sec
 	 have yet been processed.  Do something with what we know, as
 	 this may help reduce memory usage and processing time later.  */
       maybe_dynamic = (h && ((!info->executable
-			      && (!info->symbolic
+			      && (!SYMBOLIC_BIND (info, h)
 				  || info->unresolved_syms_in_shared_libs == RM_IGNORE))
 			     || !h->def_regular
 			     || h->root.type == bfd_link_hash_defweak));
@@ -2913,7 +2913,7 @@ elfNN_ia64_check_relocs (abfd, info, sec
 	 have yet been processed.  Do something with what we know, as
 	 this may help reduce memory usage and processing time later.  */
       maybe_dynamic = (h && ((!info->executable
-			      && (!info->symbolic
+			      && (!SYMBOLIC_BIND (info, h)
 				  || info->unresolved_syms_in_shared_libs == RM_IGNORE))
 			     || !h->def_regular
 			     || h->root.type == bfd_link_hash_defweak));
--- binutils/include/bfdlink.h.dynamic	2006-08-07 08:43:40.000000000 -0700
+++ binutils/include/bfdlink.h	2006-08-08 12:44:48.000000000 -0700
@@ -221,6 +221,8 @@ enum report_method
   RM_GENERATE_ERROR
 };
 
+struct bfd_elf_dynamic_list;
+
 /* This structure holds all the information needed to communicate
    between BFD and the linker when doing a link.  */
 
@@ -431,6 +433,9 @@ struct bfd_link_info
 
   /* Start and end of RELRO region.  */
   bfd_vma relro_start, relro_end;
+
+  /* List of symbols should be dynamic.  */
+  struct bfd_elf_dynamic_list *dynamic;
 };
 
 /* This structures holds a set of callback functions.  These are
@@ -724,4 +729,12 @@ struct bfd_elf_version_tree
      struct bfd_elf_version_expr *prev, const char *sym);
 };
 
+struct bfd_elf_dynamic_list
+{
+  struct bfd_elf_version_expr_head head;
+  struct bfd_elf_version_expr *(*match)
+    (struct bfd_elf_version_expr_head *head,
+     struct bfd_elf_version_expr *prev, const char *sym);
+};
+
 #endif
--- binutils/ld/Makefile.am.dynamic	2006-08-07 08:43:40.000000000 -0700
+++ binutils/ld/Makefile.am	2006-08-09 10:47:10.000000000 -0700
@@ -73,19 +73,19 @@ CC_FOR_TARGET = ` \
     fi; \
   fi`
 
-CXX = gcc
+CXX = g++
 CXX_FOR_TARGET = ` \
-  if [ -f $$r/../gcc/xgcc ] ; then \
+  if [ -f $$r/../gcc/g++ ] ; then \
     if [ -f $$r/../newlib/Makefile ] ; then \
-      echo $$r/../gcc/xgcc -B$$r/../gcc/ -idirafter $$r/../newlib/targ-include -idirafter $${srcroot}/../newlib/libc/include -nostdinc; \
+      echo $$r/../gcc/g++ -B$$r/../gcc/ -idirafter $$r/../newlib/targ-include -idirafter $${srcroot}/../newlib/libc/include -nostdinc; \
     else \
-      echo $$r/../gcc/xgcc -B$$r/../gcc/; \
+      echo $$r/../gcc/g++ -B$$r/../gcc/; \
     fi; \
   else \
     if [ "@host@" = "@target@" ] ; then \
       echo $(CXX); \
     else \
-      echo gcc | sed '$(transform)'; \
+      echo g++ | sed '$(transform)'; \
     fi; \
   fi`
 
--- binutils/ld/Makefile.in.dynamic	2006-08-07 08:43:40.000000000 -0700
+++ binutils/ld/Makefile.in	2006-08-09 10:51:07.000000000 -0700
@@ -302,19 +302,19 @@ CC_FOR_TARGET = ` \
     fi; \
   fi`
 
-CXX = gcc
+CXX = g++
 CXX_FOR_TARGET = ` \
-  if [ -f $$r/../gcc/xgcc ] ; then \
+  if [ -f $$r/../gcc/g++ ] ; then \
     if [ -f $$r/../newlib/Makefile ] ; then \
-      echo $$r/../gcc/xgcc -B$$r/../gcc/ -idirafter $$r/../newlib/targ-include -idirafter $${srcroot}/../newlib/libc/include -nostdinc; \
+      echo $$r/../gcc/g++ -B$$r/../gcc/ -idirafter $$r/../newlib/targ-include -idirafter $${srcroot}/../newlib/libc/include -nostdinc; \
     else \
-      echo $$r/../gcc/xgcc -B$$r/../gcc/; \
+      echo $$r/../gcc/g++ -B$$r/../gcc/; \
     fi; \
   else \
     if [ "@host@" = "@target@" ] ; then \
       echo $(CXX); \
     else \
-      echo gcc | sed '$(transform)'; \
+      echo g++ | sed '$(transform)'; \
     fi; \
   fi`
 
--- binutils/ld/NEWS.dynamic	2006-08-07 08:43:40.000000000 -0700
+++ binutils/ld/NEWS	2006-08-08 12:44:48.000000000 -0700
@@ -1,4 +1,9 @@
 -*- text -*-
+* ELF: Add --dynamic-list option to specify a list of global symbols
+  whose references shouldn't be bound to the definition within the
+  shared library, or a list of symbols which should be added to the
+  symbol table in the executable. 
+
 * New switch: --print-gc-sections to list any sections removed by garabge
   collection.
 
--- binutils/ld/ld.texinfo.dynamic	2006-08-07 08:43:40.000000000 -0700
+++ binutils/ld/ld.texinfo	2006-08-08 12:44:48.000000000 -0700
@@ -487,9 +487,9 @@ back to the symbols defined by the progr
 dynamic object, then you will probably need to use this option when
 linking the program itself.
 
-You can also use the version script to control what symbols should
+You can also use the dynamic list to control what symbols should
 be added to the dynamic symbol table if the output format supports it.
-See the description of @samp{--version-script} in @ref{VERSION}.
+See the description of @samp{--dynamic-list}.
 
 @ifclear SingleFormat
 @cindex big-endian objects
@@ -1130,6 +1130,19 @@ for a program linked against a shared li
 within the shared library.  This option is only meaningful on ELF
 platforms which support shared libraries.
 
+@kindex --dynamic-list=@var{dynamic-list-file}
+@item --dynamic-list=@var{dynamic-list-file}
+Specify the name of a dynamic list file to the linker.  This is
+typically used when creating shared libraries to specify a list of
+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.
+
+The format of the dynamic list is the same as the version node without
+scope and node name.  See @ref{VERSION} for more information.
+
 @kindex --check-sections
 @kindex --no-check-sections
 @item --check-sections
--- binutils/ld/ldgram.y.dynamic	2006-06-08 22:37:07.000000000 -0700
+++ binutils/ld/ldgram.y	2006-08-08 12:44:48.000000000 -0700
@@ -156,6 +156,7 @@ static int error_index;
 %type <versyms> vers_defns
 %type <versnode> vers_tag
 %type <deflist> verdep
+%token INPUT_DYNAMIC_LIST
 
 %%
 
@@ -163,6 +164,7 @@ file:
 		INPUT_SCRIPT script_file
 	|	INPUT_MRI_SCRIPT mri_script_file
 	|	INPUT_VERSION_SCRIPT version_script_file
+	|	INPUT_DYNAMIC_LIST dynamic_list_file
 	|	INPUT_DEFSYM defsym_expr
 	;
 
@@ -1139,6 +1141,34 @@ phdr_val:
 		}
 	;
 
+dynamic_list_file:
+		{
+		  ldlex_version_file ();
+		  PUSH_ERROR (_("dynamic list"));
+		}
+		dynamic_list_nodes
+		{
+		  ldlex_popstate ();
+		  POP_ERROR ();
+		}
+	;
+
+dynamic_list_nodes:
+		dynamic_list_node
+	|	dynamic_list_nodes dynamic_list_node
+	;
+
+dynamic_list_node:
+		'{' dynamic_list_tag '}' ';'
+	;
+
+dynamic_list_tag:
+		vers_defns ';'
+		{
+		  lang_append_dynamic_list ($1);
+		}
+	;
+
 /* This syntax is used within an external version script file.  */
 
 version_script_file:
--- binutils/ld/ldlang.c.dynamic	2006-08-08 12:44:47.000000000 -0700
+++ binutils/ld/ldlang.c	2006-08-09 09:47:45.000000000 -0700
@@ -83,6 +83,8 @@ static void print_input_section (asectio
 static bfd_boolean lang_one_common (struct bfd_link_hash_entry *, void *);
 static void lang_record_phdrs (void);
 static void lang_do_version_exports_section (void);
+static void lang_finalize_version_expr_head
+  (struct bfd_elf_version_expr_head *);
 
 /* Exported variables.  */
 lang_output_section_statement_type *abs_output_section;
@@ -5583,6 +5585,10 @@ relax_sections (void)
 void
 lang_process (void)
 {
+  /* Finalize dynamic list.  */
+  if (link_info.dynamic)
+    lang_finalize_version_expr_head (&link_info.dynamic->head);
+
   current_target = default_target;
 
   /* Open the output file.  */
@@ -6885,3 +6891,45 @@ lang_add_unique (const char *name)
   ent->next = unique_section_list;
   unique_section_list = ent;
 }
+
+/* Append the list of dynamic symbols to the existing one.  */
+
+void
+lang_append_dynamic_list (struct bfd_elf_version_expr *dynamic)
+{
+  if (link_info.dynamic)
+    {
+      dynamic->next = link_info.dynamic->head.list;
+      link_info.dynamic->head.list = dynamic;
+    }
+  else
+    {
+      struct bfd_elf_dynamic_list *d;
+
+      d = xcalloc (1, sizeof *d);
+      d->head.list = dynamic;
+      d->match = lang_vers_match;
+      link_info.dynamic = d;
+    }
+}
+
+/* Append the list of C++ typeinfo dynamic symbols to the existing
+   one.  */
+
+void
+lang_append_dynamic_list_cpp_typeinfo (void)
+{
+  const char * symbols [] =
+    {
+      "typeinfo name for*",
+      "typeinfo for*"
+    };
+  struct bfd_elf_version_expr *dynamic = NULL;
+  unsigned int i;
+
+  for (i = 0; i < ARRAY_SIZE (symbols); i++)
+    dynamic = lang_new_vers_pattern (dynamic, symbols [i], "C++",
+				     FALSE);
+
+  lang_append_dynamic_list (dynamic);
+}
--- binutils/ld/ldlang.h.dynamic	2006-08-08 12:43:37.000000000 -0700
+++ binutils/ld/ldlang.h	2006-08-09 09:46:50.000000000 -0700
@@ -601,6 +601,8 @@ extern struct bfd_elf_version_deps *lang
   (struct bfd_elf_version_deps *, const char *);
 extern void lang_register_vers_node
   (const char *, struct bfd_elf_version_tree *, struct bfd_elf_version_deps *);
+extern void lang_append_dynamic_list (struct bfd_elf_version_expr *);
+extern void lang_append_dynamic_list_cpp_typeinfo (void);
 bfd_boolean unique_section_p
   (const asection *);
 extern void lang_add_unique
--- binutils/ld/ldlex.h.dynamic	2005-05-16 11:04:40.000000000 -0700
+++ binutils/ld/ldlex.h	2006-08-08 12:44:48.000000000 -0700
@@ -30,6 +30,7 @@ typedef enum input_enum {
   input_script,
   input_mri_script,
   input_version_script,
+  input_dynamic_list,
   input_defsym
 } input_type;
 
--- binutils/ld/ldlex.l.dynamic	2006-05-30 09:45:42.000000000 -0700
+++ binutils/ld/ldlex.l	2006-08-08 12:44:48.000000000 -0700
@@ -132,6 +132,7 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([
 	case input_script: return INPUT_SCRIPT; break;
 	case input_mri_script: return INPUT_MRI_SCRIPT; break;
 	case input_version_script: return INPUT_VERSION_SCRIPT; break;
+	case input_dynamic_list: return INPUT_DYNAMIC_LIST; break;
 	case input_defsym: return INPUT_DEFSYM; break;
 	default: abort ();
 	}
--- binutils/ld/ldmain.c.dynamic	2006-08-07 08:43:40.000000000 -0700
+++ binutils/ld/ldmain.c	2006-08-08 12:44:48.000000000 -0700
@@ -319,6 +319,7 @@ main (int argc, char **argv)
   link_info.warn_shared_textrel = FALSE;
   link_info.gc_sections = FALSE;
   link_info.print_gc_sections = FALSE;
+  link_info.dynamic = NULL;
 
   config.maxpagesize = 0;
   config.commonpagesize = 0;
--- binutils/ld/lexsup.c.dynamic	2006-08-07 08:43:40.000000000 -0700
+++ binutils/ld/lexsup.c	2006-08-09 09:46:37.000000000 -0700
@@ -107,6 +107,8 @@ enum option_values
   OPTION_VERSION,
   OPTION_VERSION_SCRIPT,
   OPTION_VERSION_EXPORTS_SECTION,
+  OPTION_DYNAMIC_LIST,
+  OPTION_DYNAMIC_LIST_CPP_TYPEINFO,
   OPTION_WARN_COMMON,
   OPTION_WARN_CONSTRUCTORS,
   OPTION_WARN_FATAL,
@@ -501,6 +503,10 @@ static const struct ld_option ld_options
      OPTION_VERSION_EXPORTS_SECTION },
     '\0', N_("SYMBOL"), N_("Take export symbols list from .exports, using\n"
 			   "\t\t\t\tSYMBOL as the version."), TWO_DASHES },
+  { {"dynamic-list-cpp-typeinfo", no_argument, NULL, OPTION_DYNAMIC_LIST_CPP_TYPEINFO},
+    '\0', NULL, N_("Use C++ typeinfo dynamic list"), TWO_DASHES },
+  { {"dynamic-list", required_argument, NULL, OPTION_DYNAMIC_LIST},
+    '\0', N_("FILE"), N_("Read dynamic list"), TWO_DASHES },
   { {"warn-common", no_argument, NULL, OPTION_WARN_COMMON},
     '\0', NULL, N_("Warn about duplicate common symbols"), TWO_DASHES },
   { {"warn-constructors", no_argument, NULL, OPTION_WARN_CONSTRUCTORS},
@@ -1236,6 +1242,23 @@ parse_args (unsigned argc, char **argv)
 	     .exports sections.  */
 	  command_line.version_exports_section = optarg;
 	  break;
+	case OPTION_DYNAMIC_LIST_CPP_TYPEINFO:
+	  lang_append_dynamic_list_cpp_typeinfo ();
+	  break;
+	case OPTION_DYNAMIC_LIST:
+	  /* This option indicates a small script that only specifies
+	     a dynamic list.  Read it, but don't assume that we've
+	     seen a linker script.  */
+	  {
+	    FILE *hold_script_handle;
+
+	    hold_script_handle = saved_script_handle;
+	    ldfile_open_command_file (optarg);
+	    saved_script_handle = hold_script_handle;
+	    parser_input = input_dynamic_list;
+	    yyparse ();
+	  }
+	  break;
 	case OPTION_WARN_COMMON:
 	  config.warn_common = TRUE;
 	  break;
--- binutils/ld/testsuite/ld-elf/dl1.c.dynamic	2006-08-09 12:11:22.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/dl1.c	2006-08-08 15:38:50.000000000 -0700
@@ -0,0 +1,10 @@
+#include <stdio.h>
+
+extern int bar;
+
+void
+foo (void)
+{
+  if (bar == -20)
+    printf ("OK\n");
+}
--- binutils/ld/testsuite/ld-elf/dl1.list.dynamic	2006-08-09 12:11:22.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/dl1.list	2006-08-08 15:44:27.000000000 -0700
@@ -0,0 +1,6 @@
+{
+  extern "C"
+    {
+      bar;
+    };
+};
--- binutils/ld/testsuite/ld-elf/dl1.out.dynamic	2006-08-09 12:11:22.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/dl1.out	2006-08-08 15:38:27.000000000 -0700
@@ -0,0 +1 @@
+OK
--- binutils/ld/testsuite/ld-elf/dl1main.c.dynamic	2006-08-09 12:11:22.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/dl1main.c	2006-08-08 15:42:32.000000000 -0700
@@ -0,0 +1,33 @@
+#include <stdio.h>
+#include <dlfcn.h>
+
+int bar = -20;
+
+int 
+main (void)
+{
+  int ret = 0;
+  void *handle;
+  void (*fcn) (void);
+
+  handle = dlopen("./tmpdir/libdl1.so", RTLD_GLOBAL|RTLD_LAZY);
+  if (!handle)
+    {
+      printf("dlopen libfoo.so: %s\n", dlerror ());
+      return 1;
+    }
+
+  fcn = (void (*)(void)) dlsym(handle, "foo");
+  if (!fcn)
+    {
+      printf("dlsym foo: %s\n", dlerror ());
+      ret += 1;
+    }
+  else
+    {
+      (*fcn) ();
+    }
+
+  dlclose (handle);
+  return ret;
+}
--- binutils/ld/testsuite/ld-elf/dl2.c.dynamic	2006-08-09 12:11:22.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/dl2.c	2006-08-08 16:03:10.000000000 -0700
@@ -0,0 +1,16 @@
+#include <stdio.h>
+
+int foo;
+
+extern void xxx (void);
+
+void
+bar (int x)
+{
+  if (foo == 1)
+    printf ("OK1\n");
+  else if (foo == 0)
+    printf ("OK2\n");
+  foo = -1;
+  xxx ();
+}
--- binutils/ld/testsuite/ld-elf/dl2.list.dynamic	2006-08-09 12:11:22.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/dl2.list	2006-08-08 15:58:54.000000000 -0700
@@ -0,0 +1,3 @@
+{
+  foo;
+};
--- binutils/ld/testsuite/ld-elf/dl2a.out.dynamic	2006-08-09 12:11:22.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/dl2a.out	2006-08-08 16:04:54.000000000 -0700
@@ -0,0 +1,3 @@
+OK1
+DSO
+OK1
--- binutils/ld/testsuite/ld-elf/dl2b.out.dynamic	2006-08-09 12:11:22.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/dl2b.out	2006-08-08 16:07:07.000000000 -0700
@@ -0,0 +1,3 @@
+OK1
+MAIN
+OK1
--- binutils/ld/testsuite/ld-elf/dl2main.c.dynamic	2006-08-09 12:11:22.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/dl2main.c	2006-08-08 16:03:15.000000000 -0700
@@ -0,0 +1,22 @@
+#include <stdio.h>
+
+extern int foo;
+extern void bar (void);
+
+void
+xxx (void)
+{
+  printf ("MAIN\n");
+}
+
+int
+main (void)
+{
+  foo = 1;
+  bar ();
+  if (foo == -1)
+    printf ("OK1\n");
+  else if (foo == 1)
+    printf ("OK2\n");
+  return 0;
+}
--- binutils/ld/testsuite/ld-elf/dl2xxx.c.dynamic	2006-08-09 12:11:22.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/dl2xxx.c	2006-08-08 16:03:23.000000000 -0700
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+void
+xxx (void)
+{
+  printf ("DSO\n");
+}
--- binutils/ld/testsuite/ld-elf/dl2xxx.list.dynamic	2006-08-09 12:11:22.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/dl2xxx.list	2006-08-08 16:05:30.000000000 -0700
@@ -0,0 +1,3 @@
+{
+  xxx;
+};
--- binutils/ld/testsuite/ld-elf/dl3.cc.dynamic	2006-08-09 12:11:22.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/dl3.cc	2006-08-08 16:17:42.000000000 -0700
@@ -0,0 +1,7 @@
+#include "dl3header.h"
+
+void
+f (void)
+{
+  throw (A (42));
+}
--- binutils/ld/testsuite/ld-elf/dl3.list.dynamic	2006-08-09 12:11:22.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/dl3.list	2006-08-08 16:16:12.000000000 -0700
@@ -0,0 +1,6 @@
+{
+  extern "C++"
+  {
+    typeinfo*;
+  };
+};
--- binutils/ld/testsuite/ld-elf/dl3a.out.dynamic	2006-08-09 12:11:22.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/dl3a.out	2006-08-09 11:05:44.000000000 -0700
@@ -0,0 +1 @@
+OK
--- binutils/ld/testsuite/ld-elf/dl3b.out.dynamic	2006-08-09 12:11:22.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/dl3b.out	2006-08-09 11:06:03.000000000 -0700
@@ -0,0 +1 @@
+BAD2
--- binutils/ld/testsuite/ld-elf/dl3header.h.dynamic	2006-08-09 12:11:22.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/dl3header.h	2006-08-08 16:11:48.000000000 -0700
@@ -0,0 +1,5 @@
+struct A
+{
+  int i;
+  A (int i): i(i) {}
+};
--- binutils/ld/testsuite/ld-elf/dl3main.cc.dynamic	2006-08-09 12:11:22.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/dl3main.cc	2006-08-08 16:18:56.000000000 -0700
@@ -0,0 +1,25 @@
+#include <stdio.h>
+#include "dl3header.h"
+
+extern void f (void);
+
+int
+main (void)
+{
+  try
+    {
+      f();
+    }
+  catch (A a)
+    {
+      if (a.i == 42)
+	printf ("OK\n");
+      else
+	printf ("BAD1\n");
+    }
+  catch (...)
+    {
+      printf ("BAD2\n");
+    }
+  return 0;
+}
--- binutils/ld/testsuite/ld-elf/shared.exp.dynamic	2006-07-12 08:45:33.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/shared.exp	2006-08-09 12:05:34.000000000 -0700
@@ -38,7 +38,7 @@ set build_tests {
    {foo.c} {} "libfoo.so"}
   {"Build versioned libfoo.so"
    "-shared -Wl,--version-script=foo.map" "-fPIC"
-   {foo.c} {} "libfoov.so" "-fPIC"}
+   {foo.c} {} "libfoov.so"}
   {"Build libbar.so"
    "-shared" "-fPIC"
    {begin.c end.c} {} "libbar.so"}
@@ -66,6 +66,15 @@ set build_tests {
   {"Build protected libbar.so with versioned libfoo.so"
    "-shared tmpdir/begin.o tmpdir/libfoov.so" "-fPIC"
    {endprotected.c} {} "libbarpfoov.so"}
+  {"Build libdl1.so"
+   "-shared" "-fPIC"
+   {dl1.c} {} "libdl1.so"}
+  {"Build libdl2a.so with --dynamic-list=dl2.list"
+   "-shared -Wl,--dynamic-list=dl2.list" "-fPIC"
+   {dl2.c dl2xxx.c} {} "libdl2a.so"}
+  {"Build libdl2b.so with --dynamic-list=dl2.list and dl2xxx.list"
+   "-shared -Wl,--dynamic-list=dl2.list,--dynamic-list=dl2xxx.list" "-fPIC"
+   {dl2.c dl2xxx.c} {} "libdl2b.so"}
 }
 
 set run_tests {
@@ -105,8 +114,49 @@ set run_tests {
     {"Run hidden libbar.so with versioned libfoo.so"
      "tmpdir/libbarhfoov.so tmpdir/libfoov.so" ""
      {main.c} "hidden" "hidden.out"}
+    {"Run with dlopen on libdl1.so"
+     "--dynamic-list=dl1.list -ldl" ""
+     {dl1main.c} "dl1" "dl1.out"}
+    {"Run with libdl2a.so"
+     "tmpdir/libdl2a.so" ""
+     {dl2main.c} "dl2a" "dl2a.out"}
+    {"Run with libdl2b.so"
+     "tmpdir/libdl2b.so" ""
+     {dl2main.c} "dl2b" "dl2b.out"}
 }
 
 run_cc_link_tests $build_tests
 # NetBSD ELF systems do not currently support the .*_array sections.
 run_ld_link_exec_tests [list "*-*-netbsdelf*"] $run_tests
+
+# Check if compiler works
+if { [which $CXX] == 0 } {
+    return
+}
+
+set build_cxx_tests {
+  {"Build libdl3a.so with --dynamic-list=dl3.list"
+   "-shared -Wl,--dynamic-list=dl3.list" "-fPIC"
+   {dl3.cc} {} "libdl3a.so" "c++"}
+  {"Build libdl3b.so with -Bsymbolic"
+   "-shared -Wl,-Bsymbolic" "-fPIC"
+   {dl3.cc} {} "libdl3b.so" "c++"}
+  {"Build libdl3a.so with --dynamic-list-cpp-typeinfo"
+   "-shared -Wl,--dynamic-list-cpp-typeinfo" "-fPIC"
+   {dl3.cc} {} "libdl3c.so" "c++"}
+}
+
+set run_cxx_tests {
+    {"Run with libdl3a.so"
+     "tmpdir/libdl3a.so" ""
+     {dl3main.cc} "dl3a" "dl3a.out" "" "c++"}
+    {"Run with libdl3b.so"
+     "tmpdir/libdl3b.so" ""
+     {dl3main.cc} "dl3b" "dl3b.out" "" "c++"}
+    {"Run with libdl3c.so"
+     "tmpdir/libdl3c.so" ""
+     {dl3main.cc} "dl3c" "dl3a.out" "" "c++"}
+}
+
+run_cc_link_tests $build_cxx_tests
+run_ld_link_exec_tests [] $run_cxx_tests
--- binutils/ld/testsuite/lib/ld-lib.exp.dynamic	2006-07-12 08:46:01.000000000 -0700
+++ binutils/ld/testsuite/lib/ld-lib.exp	2006-08-09 11:04:52.000000000 -0700
@@ -1246,14 +1246,15 @@ if ![string length [info proc prune_warn
 
 # targets_to_xfail is a list of target triplets to be xfailed.
 # ldtests contains test-items with 3 items followed by 1 lists, 2 items
-# and one optional item:
+# and 2 optional items:
 #   0:name
 #   1:ld options
 #   2:assembler options
-#   3:filenames of assembler files
+#   3:filenames of source files
 #   4:name of output file
 #   5:expected output
 #   6:compiler flags (optional)
+#   7:language (optional)
 
 proc run_ld_link_exec_tests { targets_to_xfail ldtests } {
     global ld
@@ -1262,6 +1263,7 @@ proc run_ld_link_exec_tests { targets_to
     global subdir
     global env
     global CC
+    global CXX
     global CFLAGS
     global errcnt
 
@@ -1276,6 +1278,7 @@ proc run_ld_link_exec_tests { targets_to
 	set binfile tmpdir/[lindex $testitem 4]
 	set expfile [lindex $testitem 5]
 	set cflags [lindex $testitem 6]
+	set lang [lindex $testitem 7]
 	set objfiles {}
 	set failed 0
 
@@ -1297,7 +1300,13 @@ proc run_ld_link_exec_tests { targets_to
 	    ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
 
 	    # We have to use $CC to build PIE and shared library.
-	    if { [ string match "-shared" $ld_options ] \
+	    if { [ string match "c" $lang ] } {
+		set link_proc ld_simple_link
+		set link_cmd $CC
+	    } elseif { [ string match "c++" $lang ] } {
+		set link_proc ld_simple_link
+		set link_cmd $CXX
+	    } elseif { [ string match "-shared" $ld_options ] \
 		 || [ string match "-pie" $ld_options ] } {
 		set link_proc ld_simple_link
 		set link_cmd $CC
@@ -1344,8 +1353,13 @@ proc run_ld_link_exec_tests { targets_to
 
 # List contains test-items with 3 items followed by 2 lists, one item and
 # one optional item:
-# 0:name 1:link options 2:compile options
-# 3:filenames of assembler files 4: action and options. 5: name of output file
+#  0:name
+#  1:link options
+#  2:compile options
+#  3:filenames of source files
+#  4:action and options.
+#  5:name of output file
+#  6:language (optional)
 #
 # Actions:
 # objdump: Apply objdump options on result.  Compare with regex (last arg).
@@ -1360,6 +1374,7 @@ proc run_cc_link_tests { ldtests } {
     global subdir
     global env
     global CC
+    global CXX
     global CFLAGS
 
     foreach testitem $ldtests {
@@ -1369,6 +1384,7 @@ proc run_cc_link_tests { ldtests } {
 	set src_files  [lindex $testitem 3]
 	set actions [lindex $testitem 4]
 	set binfile tmpdir/[lindex $testitem 5]
+	set lang [lindex $testitem 6]
 	set objfiles {}
 	set is_unresolved 0
 	set failed 0
@@ -1387,7 +1403,13 @@ proc run_cc_link_tests { ldtests } {
 	# Clear error and warning counts.
 	reset_vars
 
-	if ![ld_simple_link $CC $binfile "-L$srcdir/$subdir $ldflags $objfiles"] {
+	if { [ string match "c++" $lang ] } {
+	    set cc_cmd $CXX
+	} else {
+	    set cc_cmd $CC
+	}
+
+	if ![ld_simple_link $cc_cmd $binfile "-L$srcdir/$subdir $ldflags $objfiles"] {
 	    fail $testname
 	} else {
 	    set failed 0

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: PATCH: Add --dynamic-list to ld
  2006-08-09 20:36             ` PATCH: Add --dynamic-list to ld H. J. Lu
@ 2006-09-07 15:28               ` Nick Clifton
  2006-09-07 19:41                 ` H. J. Lu
  2006-10-10 15:50                 ` [PATCH] Fix --dynamic-list Jakub Jelinek
  0 siblings, 2 replies; 27+ messages in thread
From: Nick Clifton @ 2006-09-07 15:28 UTC (permalink / raw)
  To: H. J. Lu; +Cc: Michael Matz, binutils

Hi H.J.

> bfd/
> 
> 2006-08-08  H.J. Lu  <hongjiu.lu@intel.com>
> 
> 	* elf-bfd.h (elf_link_hash_entry): Add a dynamic field.
> 	(bfd_elf_link_mark_dynamic_symbol): New.
> 	(SYMBOLIC_BIND): New.
> 
> 	* elf32-i386.c (elf_i386_check_relocs): Replace info->symbolic
> 	with SYMBOLIC_BIND (info, h).
> 	(elf_i386_relocate_section): Likewise.
> 	* elf64-x86-64.c (elf64_x86_64_check_relocs): Likewise.
> 	(elf64_x86_64_relocate_section): Likewise.
> 	* elfxx-ia64.c (elfNN_ia64_check_relocs): Likewise.
> 
> 	* elflink.c (bfd_elf_link_mark_dynamic_symbol): New.
> 	(bfd_elf_record_link_assignment): Call
> 	bfd_elf_link_mark_dynamic_symbol on new entry.
> 	(_bfd_elf_merge_symbol): Likewise.
> 	(_bfd_elf_export_symbol): Return if the symbol isn't exported.
> 	(_bfd_elf_fix_symbol_flags): Replace info->symbolic with
> 	SYMBOLIC_BIND (info, h).
> 	(_bfd_elf_dynamic_symbol_p): Likewise.
> 	(_bfd_elf_symbol_refs_local_p): Likewise.
> 	(bfd_elf_size_dynamic_sections): Updated.
> 
> include/
> 
> 2006-08-08  H.J. Lu  <hongjiu.lu@intel.com>
> 
> 	* bfdlink.h (bfd_elf_dynamic_list): New.
> 	(bfd_link_info): Add a dynamic field.
> 
> ld/
> 
> 2006-08-08  H.J. Lu  <hongjiu.lu@intel.com>
> 
> 	* Makefile.am (CXX): Set to g++.
> 	(CXX_FOR_TARGET): Likewise.
> 	* Makefile.in: Regenerated.
> 
> 	* NEWS: Mention --dynamic-list.
> 
> 	* ld.texinfo: Document --dynamic-list.
> 
> 	* ldgram.y: Support dynamic list.
> 
> 	* ldlang.c (lang_process): Call lang_finalize_version_expr_head
> 	on link_info.dynamic if needed.
> 	(lang_append_dynamic_list): New.
> 	(lang_append_dynamic_list_cpp_typeinfo): New.
> 	* ldlang.h (lang_append_dynamic_list): Likewise.
> 	* ldlang.h (lang_append_dynamic_list_cpp_typeinfo): Likewise.
> 
> 	* ldlex.h (input_enum): Add input_dynamic_list.
> 	* ldlex.l: Handle it.
> 
> 	* ldmain.c (main): Initialize link_info.dynamic.
> 
> 	* lexsup.c (option_values): Add OPTION_DYNAMIC_LIST and
> 	OPTION_DYNAMIC_LIST_CPP_TYPEINFO.
> 	(ld_options): Add entries for OPTION_DYNAMIC_LIST and
> 	OPTION_DYNAMIC_LIST_CPP_TYPEINFO.
> 	(parse_args): Handle OPTION_DYNAMIC_LIST and
> 	OPTION_DYNAMIC_LIST_CPP_TYPEINFO.
> 
> ld/testsuite/ld-elf/
> 
> 2006-08-08  H.J. Lu  <hongjiu.lu@intel.com>
> 
> 	* ld-elf/dl1.c: New file.
> 	* ld-elf/dl1.list: Likewise.
> 	* ld-elf/dl1.out: Likewise.
> 	* ld-elf/dl1main.c: Likewise.
> 	* ld-elf/dl2.c: Likewise.
> 	* ld-elf/dl2.list: Likewise.
> 	* ld-elf/dl2a.out: Likewise.
> 	* ld-elf/dl2b.out: Likewise.
> 	* ld-elf/dl2main.c: Likewise.
> 	* ld-elf/dl2xxx.c: Likewise.
> 	* ld-elf/dl2xxx.list: Likewise.
> 	* ld-elf/dl3.cc: Likewise.
> 	* ld-elf/dl3.list: Likewise.
> 	* ld-elf/dl3a.out: Likewise.
> 	* ld-elf/dl3b.out: Likewise.
> 	* ld-elf/dl3header.h: Likewise.
> 	* ld-elf/dl3main.cc: Likewise.
> 
> 	* ld-elf/shared.exp: Updated.
> 
> 	* lib/ld-lib.exp (run_ld_link_exec_tests): Take an optional
> 	argument for source language. Use CC/CXX for link, depending
> 	on source language.
> 	(run_cc_link_tests): Likewise.

Approved = please apply.

Cheers
   Nick

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: PATCH: Add --dynamic-list to ld
  2006-09-07 15:28               ` Nick Clifton
@ 2006-09-07 19:41                 ` H. J. Lu
  2006-09-08  8:17                   ` Nick Clifton
  2006-10-10 15:50                 ` [PATCH] Fix --dynamic-list Jakub Jelinek
  1 sibling, 1 reply; 27+ messages in thread
From: H. J. Lu @ 2006-09-07 19:41 UTC (permalink / raw)
  To: Nick Clifton; +Cc: Michael Matz, binutils

On Thu, Sep 07, 2006 at 04:27:49PM +0100, Nick Clifton wrote:
> Hi H.J.
> 
> 
> Approved = please apply.
> 

Here is a patch to document --dynamic-list-cpp-typeinfo.


H.J.
---
2006-09-07  H.J. Lu  <hongjiu.lu@intel.com>

	* ld.texinfo: Document --dynamic-list-cpp-typeinfo.

--- ld/ld.texinfo.typeinfo	2006-09-07 10:16:48.000000000 -0700
+++ ld/ld.texinfo	2006-09-07 12:39:17.000000000 -0700
@@ -1143,6 +1143,10 @@ 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.
 
+@kindex --dynamic-list-cpp-typeinfo
+@item --dynamic-list-cpp-typeinfo
+Provide the builtin dynamic list for C++ runtime type identification.
+
 @kindex --check-sections
 @kindex --no-check-sections
 @item --check-sections

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: PATCH: Add --dynamic-list to ld
  2006-09-07 19:41                 ` H. J. Lu
@ 2006-09-08  8:17                   ` Nick Clifton
  0 siblings, 0 replies; 27+ messages in thread
From: Nick Clifton @ 2006-09-08  8:17 UTC (permalink / raw)
  To: H. J. Lu; +Cc: Michael Matz, binutils

Hi H.J.

> 2006-09-07  H.J. Lu  <hongjiu.lu@intel.com>
> 
> 	* ld.texinfo: Document --dynamic-list-cpp-typeinfo.

Approved - please apply.

Cheers
   Nick

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH] Fix --dynamic-list
  2006-09-07 15:28               ` Nick Clifton
  2006-09-07 19:41                 ` H. J. Lu
@ 2006-10-10 15:50                 ` Jakub Jelinek
  2006-10-11 15:39                   ` Nick Clifton
  1 sibling, 1 reply; 27+ messages in thread
From: Jakub Jelinek @ 2006-10-10 15:50 UTC (permalink / raw)
  To: H. J. Lu, Nick Clifton; +Cc: binutils

On Thu, Sep 07, 2006 at 04:27:49PM +0100, Nick Clifton wrote:
> >2006-08-08  H.J. Lu  <hongjiu.lu@intel.com>
...
> >	* ldlang.c (lang_process): Call lang_finalize_version_expr_head
> >	on link_info.dynamic if needed.
> >	(lang_append_dynamic_list): New.
> >	(lang_append_dynamic_list_cpp_typeinfo): New.
> >	* ldlang.h (lang_append_dynamic_list): Likewise.
> >	* ldlang.h (lang_append_dynamic_list_cpp_typeinfo): Likewise.
...

I'm getting
FAIL: Run with libdl2b.so
failure on ppc64.

The problem is that unlike the other arches, ppc64 has for the dl2xxx.list
dynamic-list 2 entries in the list rather than just one (.xxx and xxx) and
lang_append_dynamic_list clearly assumes that the second and following
--dynamic-list's have just a single symbol name in it.

Fixed thusly, ok to commit?

BTW, I have noticed that you have changed info->symbolic to SYMBOLIC_BIND
in a bunch of generic places and i386,x86_64,ia64 ELF backends, but not at
all in the other backends.  Should that be changed in all the other
backends too?  I see the remaining ->symbolic in elflink.c is intentional,
but what about elf32-arm.c, elf32-bfin.c, elf32-cris.c, elf32-hppa.c,
elf32-i370.c, elf32-m32r.c, elf32-m68k.c, elf32-ppc.c, elf32-s390.c,
elf32-score.c, elf32-sh.c, elf32-vax.c, elf64-alpha.c, elf64-hppa.c,
elf64-s390.c, elf64-sh64.c, elf-m10300.c, elfxx-mips.c and elfxx-sparc.c?

2006-10-10  Jakub Jelinek  <jakub@redhat.com>

	* ldlang.c (lang_append_dynamic_list): When appending, add all elements
	of the dynamic list rather than just the first entry.

--- ld/ldlang.c.jj	2006-09-27 19:24:20.000000000 +0200
+++ ld/ldlang.c	2006-10-10 17:35:16.000000000 +0200
@@ -6960,7 +6960,10 @@ lang_append_dynamic_list (struct bfd_elf
 {
   if (link_info.dynamic)
     {
-      dynamic->next = link_info.dynamic->head.list;
+      struct bfd_elf_version_expr *tail;
+      for (tail = dynamic; tail->next != NULL; tail = tail->next)
+	;
+      tail->next = link_info.dynamic->head.list;
       link_info.dynamic->head.list = dynamic;
     }
   else


	Jakub

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH] Fix --dynamic-list
  2006-10-10 15:50                 ` [PATCH] Fix --dynamic-list Jakub Jelinek
@ 2006-10-11 15:39                   ` Nick Clifton
  2006-10-16 22:45                     ` H. J. Lu
  0 siblings, 1 reply; 27+ messages in thread
From: Nick Clifton @ 2006-10-11 15:39 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: H. J. Lu, binutils

Hi Jakub,

> BTW, I have noticed that you have changed info->symbolic to SYMBOLIC_BIND
> in a bunch of generic places and i386,x86_64,ia64 ELF backends, but not at
> all in the other backends.  Should that be changed in all the other
> backends too?  I see the remaining ->symbolic in elflink.c is intentional,
> but what about elf32-arm.c, elf32-bfin.c, elf32-cris.c, elf32-hppa.c,
> elf32-i370.c, elf32-m32r.c, elf32-m68k.c, elf32-ppc.c, elf32-s390.c,
> elf32-score.c, elf32-sh.c, elf32-vax.c, elf64-alpha.c, elf64-hppa.c,
> elf64-s390.c, elf64-sh64.c, elf-m10300.c, elfxx-mips.c and elfxx-sparc.c?

Yes I think that this would be a good idea.  Thanks for catching it.

> 2006-10-10  Jakub Jelinek  <jakub@redhat.com>
> 
> 	* ldlang.c (lang_append_dynamic_list): When appending, add all elements
> 	of the dynamic list rather than just the first entry.

Approved - please apply.

Cheers
   Nick

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH] Fix --dynamic-list
  2006-10-11 15:39                   ` Nick Clifton
@ 2006-10-16 22:45                     ` H. J. Lu
  2006-10-18 18:19                       ` Nick Clifton
  0 siblings, 1 reply; 27+ messages in thread
From: H. J. Lu @ 2006-10-16 22:45 UTC (permalink / raw)
  To: Nick Clifton; +Cc: Jakub Jelinek, binutils

On Wed, Oct 11, 2006 at 09:04:06AM +0100, Nick Clifton wrote:
> Hi Jakub,
> 
> >BTW, I have noticed that you have changed info->symbolic to SYMBOLIC_BIND
> >in a bunch of generic places and i386,x86_64,ia64 ELF backends, but not at
> >all in the other backends.  Should that be changed in all the other
> >backends too?  I see the remaining ->symbolic in elflink.c is intentional,
> >but what about elf32-arm.c, elf32-bfin.c, elf32-cris.c, elf32-hppa.c,
> >elf32-i370.c, elf32-m32r.c, elf32-m68k.c, elf32-ppc.c, elf32-s390.c,
> >elf32-score.c, elf32-sh.c, elf32-vax.c, elf64-alpha.c, elf64-hppa.c,
> >elf64-s390.c, elf64-sh64.c, elf-m10300.c, elfxx-mips.c and elfxx-sparc.c?
> 
> Yes I think that this would be a good idea.  Thanks for catching it.
> 
> >2006-10-10  Jakub Jelinek  <jakub@redhat.com>
> >
> >	* ldlang.c (lang_append_dynamic_list): When appending, add all 
> >	elements
> >	of the dynamic list rather than just the first entry.
> 
> Approved - please apply.
> 

Here is the patch to add some testcases for this.


H.J.
-----
2006-10-16  H.J. Lu  <hongjiu.lu@intel.com>

	* ld-elf/dl4.c: New file.
	* ld-elf/dl4.list: Likewise.
	* ld-elf/dl4a.out: Likewise.
	* ld-elf/dl4b.out: Likewise.
	* ld-elf/dl4main.c: Likewise.
	* ld-elf/dl4xxx.c: Likewise.
	* ld-elf/dl4xxx.list: Likewise.

	* ld-elf/shared.exp (build_tests): Add libdl4a.so and
	libdl4b.so.
	(run_tests): Likewise.

--- ld/testsuite/ld-elf/dl4.c.dl	2006-10-16 09:42:09.000000000 -0700
+++ ld/testsuite/ld-elf/dl4.c	2006-10-16 09:42:09.000000000 -0700
@@ -0,0 +1,24 @@
+#include <stdio.h>
+
+int foo1;
+int foo2;
+
+extern void xxx1 (void);
+extern void xxx2 (void);
+
+void
+bar (int x)
+{
+  if (foo1 == 1)
+    printf ("bar OK1\n");
+  else if (foo1 == 0)
+    printf ("bar OK2\n");
+  if (foo2 == 1)
+    printf ("bar OK3\n");
+  else if (foo2 == 0)
+    printf ("bar OK4\n");
+  foo1 = -1;
+  foo2 = -1;
+  xxx1 ();
+  xxx2 ();
+}
--- ld/testsuite/ld-elf/dl4.list.dl	2006-10-16 09:42:09.000000000 -0700
+++ ld/testsuite/ld-elf/dl4.list	2006-10-16 09:42:09.000000000 -0700
@@ -0,0 +1,4 @@
+{
+  foo1;
+  foo2;
+};
--- ld/testsuite/ld-elf/dl4a.out.dl	2006-10-16 09:42:09.000000000 -0700
+++ ld/testsuite/ld-elf/dl4a.out	2006-10-16 09:42:09.000000000 -0700
@@ -0,0 +1,6 @@
+bar OK1
+bar OK3
+DSO1
+DSO2
+OK1
+OK3
--- ld/testsuite/ld-elf/dl4b.out.dl	2006-10-16 09:42:09.000000000 -0700
+++ ld/testsuite/ld-elf/dl4b.out	2006-10-16 09:55:17.000000000 -0700
@@ -0,0 +1,6 @@
+bar OK1
+bar OK3
+MAIN1
+MAIN2
+OK1
+OK3
--- ld/testsuite/ld-elf/dl4main.c.dl	2006-10-16 09:42:09.000000000 -0700
+++ ld/testsuite/ld-elf/dl4main.c	2006-10-16 09:53:44.000000000 -0700
@@ -0,0 +1,34 @@
+#include <stdio.h>
+
+extern int foo1;
+extern int foo2;
+extern void bar (void);
+
+void
+xxx1 (void)
+{
+  printf ("MAIN1\n");
+}
+
+void
+xxx2 (void)
+{
+  printf ("MAIN2\n");
+}
+
+int
+main (void)
+{
+  foo1 = 1;
+  foo2 = 1;
+  bar ();
+  if (foo1 == -1)
+    printf ("OK1\n");
+  else if (foo1 == 1)
+    printf ("OK2\n");
+  if (foo2 == -1)
+    printf ("OK3\n");
+  else if (foo2 == 1)
+    printf ("OK4\n");
+  return 0;
+}
--- ld/testsuite/ld-elf/dl4xxx.c.dl	2006-10-16 09:42:09.000000000 -0700
+++ ld/testsuite/ld-elf/dl4xxx.c	2006-10-16 09:42:09.000000000 -0700
@@ -0,0 +1,13 @@
+#include <stdio.h>
+
+void
+xxx1 (void)
+{
+  printf ("DSO1\n");
+}
+
+void
+xxx2 (void)
+{
+  printf ("DSO2\n");
+}
--- ld/testsuite/ld-elf/dl4xxx.list.dl	2006-10-16 09:42:09.000000000 -0700
+++ ld/testsuite/ld-elf/dl4xxx.list	2006-10-16 09:42:09.000000000 -0700
@@ -0,0 +1,4 @@
+{
+  xxx1;
+  xxx2;
+};
--- ld/testsuite/ld-elf/shared.exp.dl	2006-10-16 08:30:47.000000000 -0700
+++ ld/testsuite/ld-elf/shared.exp	2006-10-16 09:42:09.000000000 -0700
@@ -75,6 +75,12 @@ set build_tests {
   {"Build libdl2b.so with --dynamic-list=dl2.list and dl2xxx.list"
    "-shared -Wl,--dynamic-list=dl2.list,--dynamic-list=dl2xxx.list" "-fPIC"
    {dl2.c dl2xxx.c} {} "libdl2b.so"}
+  {"Build libdl4a.so with --dynamic-list=dl4.list"
+   "-shared -Wl,--dynamic-list=dl4.list" "-fPIC"
+   {dl4.c dl4xxx.c} {} "libdl4a.so"}
+  {"Build libdl4b.so with --dynamic-list=dl4.list and dl4xxx.list"
+   "-shared -Wl,--dynamic-list=dl4.list,--dynamic-list=dl4xxx.list" "-fPIC"
+   {dl4.c dl4xxx.c} {} "libdl4b.so"}
 }
 
 set run_tests {
@@ -123,6 +129,12 @@ set run_tests {
     {"Run with libdl2b.so"
      "tmpdir/libdl2b.so" ""
      {dl2main.c} "dl2b" "dl2b.out"}
+    {"Run with libdl4a.so"
+     "tmpdir/libdl4a.so" ""
+     {dl4main.c} "dl4a" "dl4a.out"}
+    {"Run with libdl4b.so"
+     "tmpdir/libdl4b.so" ""
+     {dl4main.c} "dl4b" "dl4b.out"}
 }
 
 run_cc_link_tests $build_tests

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH] Fix --dynamic-list
  2006-10-16 22:45                     ` H. J. Lu
@ 2006-10-18 18:19                       ` Nick Clifton
  0 siblings, 0 replies; 27+ messages in thread
From: Nick Clifton @ 2006-10-18 18:19 UTC (permalink / raw)
  To: H. J. Lu; +Cc: Jakub Jelinek, binutils

Hi H. J.

> H.J.
> -----
> 2006-10-16  H.J. Lu  <hongjiu.lu@intel.com>
> 
> 	* ld-elf/dl4.c: New file.
> 	* ld-elf/dl4.list: Likewise.
> 	* ld-elf/dl4a.out: Likewise.
> 	* ld-elf/dl4b.out: Likewise.
> 	* ld-elf/dl4main.c: Likewise.
> 	* ld-elf/dl4xxx.c: Likewise.
> 	* ld-elf/dl4xxx.list: Likewise.
> 
> 	* ld-elf/shared.exp (build_tests): Add libdl4a.so and
> 	libdl4b.so.
> 	(run_tests): Likewise.

Approved - please apply.

Cheers
   Nick

^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2006-10-18 14:42 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-07-24 22:27 RFC: Add dynamic list to version script H. J. Lu
2006-07-25 12:53 ` Ulrich Drepper
2006-07-25 13:49   ` H. J. Lu
2006-07-25 14:04     ` Ulrich Drepper
2006-07-25 14:36       ` H. J. Lu
2006-07-25 14:49         ` Ulrich Drepper
2006-07-26 16:42 ` Michael Matz
2006-07-27 17:11   ` H. J. Lu
2006-07-28 13:14     ` Michael Matz
2006-07-28 17:40       ` H. J. Lu
2006-07-28 17:59         ` Ulrich Drepper
2006-07-28 18:05           ` H. J. Lu
2006-08-08 17:22         ` H. J. Lu
2006-08-08 18:49           ` Michael Matz
2006-08-09 20:36             ` PATCH: Add --dynamic-list to ld H. J. Lu
2006-09-07 15:28               ` Nick Clifton
2006-09-07 19:41                 ` H. J. Lu
2006-09-08  8:17                   ` Nick Clifton
2006-10-10 15:50                 ` [PATCH] Fix --dynamic-list Jakub Jelinek
2006-10-11 15:39                   ` Nick Clifton
2006-10-16 22:45                     ` H. J. Lu
2006-10-18 18:19                       ` Nick Clifton
2006-08-09  2:02           ` RFC: Add dynamic list to version script Alan Modra
2006-08-09 16:05             ` Michael Matz
2006-08-09 16:19               ` Alan Modra
2006-08-09 17:40                 ` H. J. Lu
2006-08-09 16:25               ` H. J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).