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: Evolution of ELF symbol management


On 11/16/2016 04:55 PM, Zack Weinberg wrote:

First, I don't have a problem with adding __libc_* aliases as
non-default but public alternative names, so that third-party libraries
can avoid namespace pollution in static linkage and/or choose to refer
to symbols that are more likely to get resolved to the C library's
export than to a colliding symbol in the main executable.  I'd reserve
that for cases where there is already a demonstrated need, though, such
as libstdc++.  I also don't have a problem with a hypothetical policy
that all new symbols that aren't in the current revisions of C+POSIX
should be given an impl-namespace name as their primary definition, with
the user-namespace name being a weak alias (but still the only name used
in the public headers).

If we don't declare the library-safe names in headers, how can libraries call them?

I also do not want to encourage application or library code to reference the implementation namespace at the source code level. It's ugly, and I suspect it encourages implementation namespace pollution once programmers are used to it.

I _do_ have problems with causing these symbols to be used by default.
My main concern is that I think it's tackling the problem in the wrong
place.  If we want to back away from the original principle that the
executable always wins, isn't an expanded version of -Bsymbolic mode
what's _really_ wanted?

We could cover a lot of ground if we had a new flag on versioned symbol definitions which tells the static linker to set a flag on the versioned symbol reference, and the dynamic linker would then use this flag to ignore unversioned symbols for binding symbols.

(The static linker currently does not add the version of the interposed symbol when interposition happens at static link time.)

*However*, this is hardly a complete solution. It does not cover symbol references from public C++ headers because there is no static linker invocation that comes between application use of the symbol and the use from system headers.

It also does not work for static libraries. In those cases, we could perhaps do some post-processing to add the symbol versions to the .a files, but it would still need the interposition protection mentioned above *and* changes to how we build static libraries.

That is, an opt-in link-time declaration that
you want all dynamic symbols resolved at load-time to the same library
that provided them at link-time.  Once that exists, we could try to move
slowly in the direction of turning it on by default, along with various
other "yes, fix the bug" linker toggles like -z relro and --as-needed.

The build changes I mentioned in the previous paragraph are more invasive than just adding a flag to gcc's ld invocation because there is currently no such invocation at all. We could put it into ar or ranlib, but that's perhaps too much magic. A new linking step would be needed.

The header files could contain the symbol version and instruct GCC to put it into the header file. (Even today, it is possible to link against specific symbol versions without a custom DSO containing them as the default version, but please don't tell anyone.) But this would still need the interposition protection. I still think this is the most promising option, all things considered.

But then we need to step back and ask ourselves: If we have to put the versioning information in the header, why do we even need symbol versioning? Why can't we version the interface through its name?

Hence my proposal.

A secondary reason for not wanting __libc_* aliases to be activated by
default is that it doesn't seem to me that it actually solves the
problem.  Applications that _want_ to interpose are going to shift to
the __libc_* names; depending on what the headers actually do,
applications that don't care (but do define a conflicting symbol) might
wind up shifting to those names by accident.

What I would like is a GCC attribute which tells the compiler that the declaration must not be completed with a definition in this translation unit. That would make the asm aliases pretty robust because then you can only reach the implementation namespace by explicitly referencing it in your sources.

Deliberate interposition is much easier if you don't have to worry about linker tricks and the unversioned-symbol-interposes-all-versioned-symbol issue (which you cannot detect in the interposing DSO).

__REDIRECT doesn't work
without GCC(-compatible) extensions, after all.  (I would not object to
a _documented and enforced_ set of GCC-compatible extensions being a
baseline requirement for use of glibc headers -- but that would need to
happen _first_.)

I wouldn't like that, there are many consumers for header files which aren't compilers (and would not be forced to implement many GNU extensions).

Thanks,
Florian


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