This is the mail archive of the binutils@sourceware.org mailing list for the binutils 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]

Recursive function calls vs. ELF shared libraries


I was intending to remove the special case for self-calls at
gold/powerpc.cc:6334, but decided not to after running into

[alan@squeak testsuite]$ `echo g++ -DHAVE_CONFIG_H -I. -I/src/binutils-current/gold/testsuite -I..  -I/src/binutils-current/gold/testsuite -I/src/binutils-current/gold/testsuite/.. -I/src/binutils-current/gold/testsuite/../../include -I/src/binutils-current/gold/testsuite/../../elfcpp -I.. -DLOCALEDIR="\"/usr/local/share/locale\""   -W -Wall    -Werror -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -fmerge-constants -g -O -fno-inline -msecure-plt | sed -e 's/-Wp,-D_FORTIFY_SOURCE=[0-9][0-9]*//'` -Bgcctestdir/ -O0 -g -shared -fPIC -w -o odr_violation1.so /src/binutils-current/gold/testsuite/odr_violation1.cc -save-temps
/usr/lib/gcc/ppc64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/stl_algo.h:2363: error: call lacks nop, can't restore toc; recompile with -fPIC

Notice we already have -fPIC.  A little investigation showed this to be 

        .loc 5 2363 0
        ld 3,112(31)
        ld 4,232(31)
        ld 5,240(31)
        mr 6,30
        bl _ZSt16__introsort_loopIPil8OrderingEvT_S2_T0_T1_
        .loc 5 2364 0
        lfd 0,112(31)

   126: 00000000000000c0   252 FUNC    WEAK   DEFAULT   49 _ZSt16__introsort_loopIPil8OrderingEvT_S2_T0_T1_

So we have a self-call using a global symbol that g++ treats as a
local call.  This was ((GCC) 4.7.2 20120921 (Red Hat 4.7.2-2)).  I
reckon g++ is incorrect.

We know that ELF shared library symbol resolution rules say that any
global default visibility symbol can be overridden by a definition in
the executable or another shared library earlier in search order, so
generally you can't assume a call like this is local when compiling
with -fPIC.  Indeed, g++ doesn't do so for other symbols, just the
self-calls.

You might think that if execution arrived at this function, then
another call via the same symbol ought to get there too, but I can
imagine a situation where this isn't so.  For example, the main
executable might override this function, perhaps for as innocuous a
reason as counting the number of calls, then call the library
function via a pointer.  If we go direct then some calls are missed by
the executable interceptor.  Another type of interception might effect
a "patch" of the library function for some parameter values.

Or am I off in the weeds here?

-- 
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]