Date: Tue, 14 Apr 2015 00:21:07 -0400 From: Rich Felker <dalias@...c.org> To: musl@...ts.openwall.com Subject: Direction on GNUC features, visibility, __libc struct hacks A few of the recent commits introduced unconditional visibility attributes in some places, whereas in the past they were conditional on compiler versions, so I'd like to clarify what's going on with that. For a shared libc.so, having visibility is essential to providing a compatible ABI. Without it, some symbols which need to exist internally for libc with specific names (like __stack_chk_fail_local and math symbols pulled in from libgcc) would become public ABI for libc.so. It's plausible that some future compiler could offer it via a different syntactical mechanism than the GNUC __attribute__ system, but unless this happens I don't want to spend effort being gratuitously general. So for now, visibility attributes will be used unconditionally where needed for SHARED libc. What's less clear is what to do with uses that are not needed. Now that the dynamic linker fully relocates ldso/libc itself before making any external calls, the whole libc.h mechanism of hiding important globals inside a hidden struct (with fallback to ugly accessor function for theoretical compilers that lack visibility but somehow can make a working libc.so) is completely unnecessary. These globals could all be split up into their own named objects. In particular the global locale object could probably be optimized out of some static binaries. What I found more troubling is that we have a number of other broken uses of visibility, like in src/internal/syscall.h, where the declaration of a symbol specifies hidden visibility but the point of definition does not. This often happens when the declaration is in C and the definition is in asm (__syscall) or vice versa (access of __hwcap as if it were .hidden, by arm setjmp asm). Most or all of this inconsistent usage of visibility has been papered over by -Bsymbolic-functions, which binds the symbols at ld time and prevents the TEXTRELs or linking errors that would otherwise arise due to the inconsistency. Playing with building without -Bsymbolic-functions, I ran into a lot of such problems, and the number increases drastically if you use an old toolchain (like the GPLv2 one from Aboriginal Linux) that's less forgiving about the mismatches. Yet another related issue is all the places where i386 asm makes function calls to external, public symbols (like sigprocmask, exp2l, etc.) without @PLT. Using @PLT would be undesirable because it would require loading %ebx with the GOT pointer in all this asm (which is shared between PIC and non-PIC builds). Some ideas for fixes: For things that semantically should be hidden, it seems pretty simple: just make sure the declaration and definition are consistent and both are hidden. This is a bit of work but not too bad. For things that are just bypassing PLT/GOT access bloat, on the other hand, I don't see a really good solution. In some cases (where both the caller and callee are asm, like expl/exp2l) we could add extra hidden symbols to use for the call instead of the public symbol, but that seems ugly. That doesn't really work for calls to public functions written in C though. An alternative approach is to declare the target symbol .protected from the calling asm. Even with old binutils, this seems to produce the desired results, but the final symbol in the .so does come out marked PROTECTED which may be weird. The other solution would be to just phase out these types of calls. I'll start by making some cleanups/fixes that should be uncontroversial we try to figure out what to do with the rest. Rich
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.