ld unpredictable lookup failure building shared library

James K. Lowden jklowden@schemamania.org
Sat Apr 21 00:47:00 GMT 2012


I'm attempting to build clang on x86_64.  ld fails to look up a symbol
from std::string, recommending -fPIC, but file(1) reports the object
file is relocatable.  Upgrading to 1.22 has no effect.  Am I missing an
option, or have I found a bug?  It's not a common a problem,
but I'm not the only one to see it.  

$ /usr/pkg/bin/gnu-ld --version | grep ^GNU
GNU ld (GNU Binutils)2.22

$ /usr/pkg/bin/gnu-ld @linker.options
/usr/pkg/bin/gnu-ld: /usr/pkgsrc/wip/clang/work/llvm/Release/lib/libLLVMCodeGen.a
(ShrinkWrapping.o): 
relocation R_X86_64_PC32 against undefined symbol
	`_ZNSs4_Rep10_M_disposeERKSaIcE' 
can not be used when making a shared object; recompile with -fPIC 
/usr/pkg/bin/gnu-ld: final link failed: Bad value

The "linker.options" file is attached.  

Both the reported file and the GNU library that houses that symbol are
relocatable:

$ find ../../ -name ShrinkWrapping.o | xargs file
../../lib/CodeGen/Release/ShrinkWrapping.o: ELF 64-bit LSB relocatable,
x86-64, version 1 (SYSV), not stripped

The symbol is not defined in clang.  It's part of standard string
(wrapped for your viewing pleasure)

$ c++filt _ZNSs4_Rep10_M_disposeERKSaIcE
std::basic_string<char, 
		std::char_traits<char>, 
		std::allocator<char> >::_Rep::
	_M_dispose(std::allocator<char> const&)

nm(1) reports it's defined as a "weak  symbol that has not been
specifically tagged as a weak object symbol" (that's what the "W"
means):

$ find /usr/lib -name \*.a | xargs nm -o \
	| grep _ZNSs4_Rep10_M_disposeERKSaIcE \
	| grep -v i386 

/usr/lib/libstdc++_p.a:string-inst.po:0000000000000000 
	W _ZNSs4_Rep10_M_disposeERKSaIcE 
/usr/lib/libstdc++.a:string-inst.o:0000000000000000 
	W _ZNSs4_Rep10_M_disposeERKSaIcE 
/usr/lib/libstdc++_pic.a:string-inst.so:0000000000000000 
	W _ZNSs4_Rep10_M_disposeERKSaIcE

That object file, string-inst.o, is relocatable:  

$ ar x /usr/lib/libstdc++.a string-inst.o && file string-inst.o 
string-inst.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV),
not stripped  

$ nm string-inst.o | grep _ZNSs4_Rep10_M_disposeERKSaIcE
0000000000000000 W _ZNSs4_Rep10_M_disposeERKSaIcE

I don't really understand weak symbols, but I'm prepared to believe
this symbol, because it's based on a template, isn't really in the
library.  But if not, the compiler should have generated it, and it's
not defined among the .o files.  At least, nm never gives it a "T".  

It doesn't always happen.  The other clang file that uses that symbol,
GCOVProfiling.o, is successfully incorporated into a library,
libLLVMInstrumentation.a:

$ find ../.. -name \*.a 
	| while read F; do \
		ar t $F | grep GCOVProfiling $F && echo $F; \
	  done 
ar: ../../test/Archive/MacOSX.a: Malformed archive
Binary file ../../Release/lib/libLLVMInstrumentation.a matches
../../Release/lib/libLLVMInstrumentation.a
$ ar t ../../Release/lib/libLLVMInstrumentation.a
AddressSanitizer.o
EdgeProfiling.o
FunctionBlackList.o
GCOVProfiling.o
Instrumentation.o
OptimalEdgeProfiling.o
PathProfiling.o
ProfilingUtils.o
ThreadSanitizer.o

Thanks for any help.  I'm happy to try suggestions.  

--jkl
-------------- next part --------------
A non-text attachment was scrubbed...
Name: linker.options
Type: application/octet-stream
Size: 1019 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/binutils/attachments/20120421/e05ab24a/attachment.obj>


More information about the Binutils mailing list