This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH 5/5] PR ld/20828: Reorder the symbol sweep stage of section GC


On Wed, 25 Jan 2017, Alan Modra wrote:

> >  BTW, in the process of making this change I have discovered that the 
> > linker script PROVIDE keyword causes the symbol requested to be emitted 
> > even in the absence of a local reference if there is an identically named 
> > symbol exported from a DSO present in the link.  This can be reproduced 
> > with the `pr20828-1.so' test and its `pr20828.ld' script modified to use 
> > PROVIDE with its symbols, regardless of the presence of `--gc-sections', 
> > as long as `libpr20828.so' is included in the link.  If the DSO is absent, 
> > then the symbols are not emitted.
> > 
> >  I believe this is due to this piece:
> > 
> >   /* If this symbol is being provided by the linker script, and it is
> >      currently defined by a dynamic object, but not by a regular
> >      object, then mark it as undefined so that the generic linker will
> >      force the correct value.  */
> >   if (provide
> >       && h->def_dynamic
> >       && !h->def_regular)
> >     h->root.type = bfd_link_hash_undefined;
> > 
> > in `bfd_elf_record_link_assignment', the presence of which however 
> > predates our repo history and therefore any justification is hard to track 
> > down.
> 
> This one goes back to
> commit b5279eb6a9672dba08ce9bbef0490f4bf26243f3
> Author: Ian Lance Taylor <ian@airs.com>
> Date:   Tue Jul 4 17:43:05 1995 +0000

 Thanks, though unsurprisingly this doesn't provide any input beyond what 
we already know.  I take it PR 7164 refers to our old GNATS bug tracker or 
maybe even Cygnus's internal records -- has this data been migrated 
anywhere or has it been lost (or perhaps sits catching dust on tapes 
somewhere)?

> The old history is in our git repo but it's a little difficult to go
> beyond 1999-05-03.  You need to pick one of the commits before the
> multiple "Initial creation of sourceware repository" commits..  In
> this case
> 
> git blame 1730ec6b -- bfd/elflink.h
> 
> gets you the old history.

 Thanks, that's really useful indeed!  I didn't realise we had this data.  
I'm not a GIT expert, but for the record:

$ git log --full-history

seems to go past commit 252b5132c753 ("19990502 sourceware import") 
automagically.

> > Our manual however only states that:
> > 
> > "In some cases, it is desirable for a linker script to define a symbol
> > only if it is referenced and is not defined by any object included in
> > the link.  For example, traditional linkers defined the symbol `etext'.
> > However, ANSI C requires that the user be able to use `etext' as a
> > function name without encountering an error.  The `PROVIDE' keyword may
> > be used to define a symbol, such as `etext', only if it is referenced
> > but not defined.  The syntax is `PROVIDE(SYMBOL = EXPRESSION)'."
> > 
> > which given our semantics is I believe at least ambiguous as it does not 
> > tell static and dynamic objects apart -- it merely states "any object".
> > 
> >  Do you or does anyone know what the purpose of this special case is?  It 
> > might be to preempt the DSO symbol so that the DSO uses ours and not its 
> > own, however preemption is not going to happen in a `-shared' link anyway 
> > (and it seems against the spirit of PROVIDE).
> > 
> >  Shall we keep it (presumably yes, owing to its long history) and make it 
> > clear in documentation?
> 
> I think we have to keep the current behaviour.  PROVIDE is likely the
> way it is for symbols like "etext" that might be exported from shared
> libraries but the executable needs its own value as given by the script.

 Right, but why is the symbol PROVIDEd defined even if there's no regular 
reference?  I'm thinking in terms of a change like below, which makes the 
keyword match its description -- in the absence of a regular reference I'd 
expect no regular definition regardless of whether there's a dynamic 
definition present or not.  I wonder if this was a deliberate choice or an 
omission; and either way if we decide to keep the current semantics, then 
I think we need to properly document it to avoid people's confusion.

> A doc patch is preapproved.

 I'm tempted to just s/any object/any static object/ in the paragraph 
quoted above, but let's sort out my concern first.

  Maciej

binutils-bfd-record-link-assignment-provide-unref.diff
Index: binutils/bfd/elflink.c
===================================================================
--- binutils.orig/bfd/elflink.c	2017-01-25 22:35:51.360905740 +0000
+++ binutils/bfd/elflink.c	2017-01-25 23:05:51.315467007 +0000
@@ -667,7 +667,12 @@ bfd_elf_record_link_assignment (bfd *out
   if (provide
       && h->def_dynamic
       && !h->def_regular)
-    h->root.type = bfd_link_hash_undefined;
+    {
+      if (h->ref_regular)
+	h->root.type = bfd_link_hash_undefined;
+      else
+	return TRUE;
+    }
 
   /* If this symbol is not being provided by the linker script, and it is
      currently defined by a dynamic object, but not by a regular object,


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