This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Recursive function calls vs. ELF shared libraries
- From: Alan Modra <amodra at gmail dot com>
- To: binutils at sourceware dot org
- Date: Mon, 6 May 2013 13:31:24 +0930
- Subject: 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