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 11:19:19AM +0000, Joseph Myers wrote:
> On Sat, 24 Oct 2015, Rich Felker wrote:
> 
> > > So simply using aliases is not a solution in the case of data symbols.  
> > > The solution I propose instead is as follows.  math.h would (under 
> > > appropriate feature test macros) do:
> > 
> > I don't follow. How is this any different from environ, timezone,
> > daylight, etc.? They are all handled correctly by an alias; when
> > linking produces copy relocations, the linker does the right thing
> > automatically and preserves the aliasing.
> 
> 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.
POSIX even has a note alluding to that somewhere (probably in part of
the rationale; I don't remember right off). Apparently that knowledge
was lost somewhere along the way.

> 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
defines tzname, there is no copy relocation, tzname refers to the
object in the main program, and &tzname != &__tzname. If the main
program does not define tzname but references it, then one of two
things happens:

1. If libc.so has a public symbol __tzname for which tzname is an
alias, the main program has a copy relocation referencing __tzname and 
pseudo-definitions for tzname and __tzname as the address of the copy
relocation, and libc sees &tzname == &__tzname.

2. If libc.so only exports tzname as the public symbol, the main
program has a copy relocation referencing tzname and a
pseudo-definition for tzname as the address of the copy relocation,
but __tzname is just the libc-internal definition, and &tzname !=
&__tzname.

> So you'd need at least four new public symbols (__signgam, plus new 
> versions for lgamma, lgammaf, lgammal; gamma* could be kept pointing to 
> old versions, which would have to set both __signgam and signgam in case 
> the aliasing was broken) to do things with aliases.  It might still be 

Yes, this is the canonical fix and exactly what should be done.

> safer than __signgam_location, but we want to be sparing with public ABIs.  
> (stdin / stdout / stderr would be much worse to do with versioning 
> functions, but there macro definitions are unambiguously OK.)

Indeed.

> > > extern int *__signgam_location (void);
> > > #define signgam (*__signgam_location ())
> > 
> > This is non-conforming. POSIX requries an extern object. Note that the
> > rule about being able to use the interface without including the
> > header applies to most of the interfaces in math.h.
> 
> That rule is for *functions* (with certain types), not *variables*.  
> POSIX seems silent on being able to use non-function interfaces like that 
> (and as I said in my mail to the Austin Group list, the missing 
> reservation as macros for all file scope identifiers seems a clear mistake 
> in updating POSIX for C99).

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
to go around defining things as macros when they're required to exist
as objects or functions.

Rich


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