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]

GNU indirect functions vs. symbol visibility


Discussion started here:
https://gcc.gnu.org/ml/gcc-patches/2016-08/msg01678.html

On Wed, Aug 24, 2016 at 08:51:16PM +0300, Alexander Monakov wrote:
> On Wed, 24 Aug 2016, Alan Modra wrote:
> > Given a hidden visibility function declaration, the toolchain can say
> > that the function is local to the module.  This generally means that a
> > call to the function can be direct, ie. doesn't need to go via the PLT
> > even in a shared library.  However, ifunc breaks this promise.  GNU
> > indirect functions may resolve non-locally, and are implemented by
> > always using a PLT call.
> > 
> > This causes trouble for targets like ppc32 where the -msecure-plt PIC
> > PLT call stub needs a valid GOT pointer.  Any call that potentially
> > might be to an ifunc therefore requires a GOT pointer, and can't be a
> > sibling call (because the GOT pointer on ppc32 is a caller saved reg).
> 
> The same issue exists on 32-bit x86: PLT calls require that %ebx holds the
> address of GOT (and the sibcall issue arises as well).  I've just confirmed
> using a simple testcase that the scenario you describe leads to a runtime error
> on i386, and even LD_BIND_NOW=1 doesn't help, as it doesn't trigger early
> resolution of ifuncs.

I'm happy to see that ppc32 isn't alone.  ;-)

> > So unless we require that all ifuncs are declared as ifunc,
> 
> (note, that would be impossible with today's GCC because the ifunc attribute
> requires designating the resolver, and the resolver cannot be extern -- so
> ultimately you cannot declare an extern-ifunc symbol)
> 
> > it seems that ppc32 can't assume extern or weak functions are local.
> 
> It doesn't seem nice to penalize all normal calls due to this issue.

I whole-heartedly agree.

> I think a
> solution without this cost is possible: have ld synthesize a forwarder function
> when it sees a non-plt call to an ifunc symbol. The forwarder can push the GOT
> register, load the GOT address, call the ifunc symbol, pop the GOT register and
> return. Does this sound right?

I'd considered this idea too.  It should work, but isn't ideal.  The
resulting code will be slower than if the ifuncs were simply not
declared hidden.  The idea also isn't quite as simple to implement as
it might seem, since frame unwinding must work through any such stub,
and gdb probably would need to know about them too.

I prefer to simply make ld error on seeing calls to ifuncs where it
detects that such a stub would be needed.  ppc32 GNU ld should do that
reliably as of git commit 888a7fc3.

glibc people: As the main user of ifuncs, how do you feel about not
declaring functions hidden that are implemented in glibc by ifuncs?
It's fine to make them hidden via a version script, or even define
them as hidden (which requires just the rs6000_elf_encode_section_info
part of my gcc patch to make ppc32 behave).

-- 
Alan Modra
Australia Development Lab, IBM


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