This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc 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: Fixing namespace issues for variables


On Sat, Oct 24, 2015 at 08:17:56PM +0000, Joseph Myers wrote:
> On Sat, 24 Oct 2015, Rich Felker wrote:
> 
> > > When I tried and failed to use aliases, it was for stdin / stdout / 
> > > stderr, with the main name used internally being hidden.  As noted in 
> > > <https://sourceware.org/ml/libc-alpha/2015-10/msg00876.html> I've since 
> > > located the linker magic that allows such aliases to work *if the internal 
> > > name is exported* (so this provides yet another reason to need non-compat 
> > > internal-namespace exports at public symbol versions, beyond uses in 
> > > macros, inline functions, libc_nonshared, libgcc, libstdc++ etc.).  As 
> > > also noted there, since __signgam was not an exported symbol alongside 
> > > signgam in glibc 2.0, use of aliases like that would break existing 
> > > binaries, as existing binaries would preempt only signgam and so break the 
> > > aliasing.
> > 
> > Yes. This is the traditional way things were always intended to work.
> 
> Apparently not traditional enough to have anything in the gABI that I 
> could find saying that in this particular case special treatment should be 
> given when two symbols are at the same address.  I have no idea if this is 
> actually portable across ELF linkers in practice.

I think what's traditional about it is that this method always worked
for static linking (hopefully that's obvious). And the original intent
of ELF dynamic linking was to reproduce all the properties of static
linking (often at a fairly high cost).

> > > Furthermore, address comparison is not a solution as I hoped for 
> > > distinguishing old and new binaries.  When I said that programs defining 
> > > their own tzname don't get it bound to the glibc symbol, I meant that the 
> > > dynamic tzname symbol from the executable was unversioned.  But an 
> > > unversioned symbol from an executable will still preempt a versioned 
> > > symbol from glibc (necessarily; recall that glibc 2.0 didn't have symbol 
> > > versioning, so you can't distinguish an unversioned signgam definition 
> > > from a binary linked with glibc 2.0 using the library's signgam from one 
> > > from a new binary defining its own), and so &signgam == &__signgam would 
> > > return false for the new binary as well as the old one.
> > 
> > I don't see how versioning is relevant here. If the main program
> 
> Because ideally any reference to a glibc symbol would be properly 
> versioned (so a binary referencing signgam at version GLIBC_2.0 
> unambiguously wants it set by lgamma, and a binary where it is unversioned 
> is unambigously doing its own thing with that symbol name, and, within 
> glibc, an unversioned signgam symbol from the executable simply wouldn't 
> be visible with the name signgam at all).  But because unversioned symbols 
> can bind to glibc symbols (and because this is necessary to support since 
> glibc 2.0 predated symbol versioning support), this doesn't work, and it's 
> not possible to distinguish the two cases just by properties of the 
> signgam and __signgam symbols without also adding new versions of lgamma 
> functions.

Indeed, I see how having a guarantee that a reference to the glibc
symbol would be versioned might allow detecting the situation without
new versioned symbols for the functions. I just assumed new versioned
symbols would be used to solve the problem, though.

> > Reservation as macros is not relevant. You're always allowed to
> > undef the macro and use the underlying object/function unless the
> > identifier is actually _specified_ to be a macro. It's non-conforming
> 
> No, that's simply not what POSIX says.  It says "Identifiers in 
> POSIX.1-2008 may only be undefined using the #undef directive as described 
> in Use and Implementation of Interfaces or The Name Space. These #undef 
> directives shall follow all #include directives of any header in 
> POSIX.1-2008.".  That is, no #undef of a standard header's macro unless 
> explicitly permitted.  Use and Implementation of Interfaces gives such 
> permission for macro definitions of functions, while The Name Space gives 
> such permission for macros beginning with certain prefixes (for <math.h>, 
> the only prefix with such permission is FP_[A-Z]).

The text I'm referring to is:

  "Any function declared in a header may also be implemented as a
  macro defined in the header, so a function should not be declared
  explicitly if its header is included. Any macro definition of a
  function can be suppressed locally by enclosing the name of the
  function in parentheses, because the name is then not followed by
  the <left-parenthesis> that indicates expansion of a macro function
  name. For the same syntactic reason, it is permitted to take the
  address of a function even if it is also defined as a macro. The use
  of the C-language #undef construct to remove any such macro
  definition shall also ensure that an actual function is referred
  to."

Note that macro definitions of identifiers specified to be objects are
not permitted _at all_ (I had forgotten this), so no text about
applying #undef to them is necessary.

The text you cited is about macros that are specified to exist or
permitted to exist.

Rich


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