ld unpredictable lookup failure building shared library

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


On Fri, 20 Apr 2012 17:54:39 -0700
Ian Lance Taylor <iant@google.com> wrote:

> "James K. Lowden" <jklowden@schemamania.org> writes:
> 
> > 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.
> 
> Relocatable is not the same as -fPIC Relocatable just means
> relocatable at link tie.  The -fPIC option constructs an object file
> that is relocatable at runtime.  

Good to know, thanks.  How to verify a .o file was compiled with
-fPIC?  The linker knows, but readelf and objdump don't seem to say.
For a .so, perhaps that's what "DYNAMIC" means?  

$ objdump -x /usr/lib/libstdc++.so | sed '/DYN/q'

/usr/lib/libstdc++.so:     file format elf64-x86-64
/usr/lib/libstdc++.so
architecture: i386:x86-64, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED

> Have you tried actually using the -fPIC option when compiling the
> file?

Yes.  The clang makefiles use -fPIC for everything afaict.  I have
verified -fPIC appears on the command-line for the clang object file
under discussion, ShrinkWrapping.o.  The command is:

c++ \
-I/[src]/llvm/include \
-I/[src]/llvm/lib/CodeGen \
-DNDEBUG \
-D_GNU_SOURCE \
-D__STDC_CONSTANT_MACROS \
-D__STDC_FORMAT_MACROS \
-D__STDC_LIMIT_MACROS \
-O1 \
-fomit-frame-pointer \
-fvisibility-inlines-hidden \
-fno-exceptions \
-fno-rtti \
-fPIC \
-Woverloaded-virtual \
-Wcast-qual \
-pedantic \
-Wno-long-long \
-Wall \
-W \
-Wno-unused-parameter \
-Wwrite-strings \
-c \
-MMD \
-MP \
-MF "/[src]/llvm/lib/CodeGen/Release/ShrinkWrapping.d.tmp" \
-MT "/[src]/llvm/lib/CodeGen/Release/ShrinkWrapping.o" \
-MT "/[src]/llvm/lib/CodeGen/Release/ShrinkWrapping.d" \
ShrinkWrapping.cpp \
-o /[src]/llvm/lib/CodeGen/Release/ShrinkWrapping.o 

I haven't researched how string-inst.o in libstdc++ was compiled, but
another clang reference to the same std::string symbol links fine.  (It
creates a different clang .so.)

I satisfied myself where the symbol is defined, btw:  

$ nm -o libstdc++*[ao] \
	| grep _ZNSs4_Rep10_M_disposeERKSaIcE \
	| grep -v i386 
libstdc++.a:string-inst.o:0000000000000000 W
	_ZNSs4_Rep10_M_disposeERKSaIcE 
libstdc++.so:000000000006f830 W	<== here
	_ZNSs4_Rep10_M_disposeERKSaIcE 
libstdc++_p.a:string-inst.po:0000000000000000 W 
	_ZNSs4_Rep10_M_disposeERKSaIcE
libstdc++_pic.a:string-inst.so:0000000000000000 W
	_ZNSs4_Rep10_M_disposeERKSaIcE

Thanks for your interest.  I'm happy to provide any further information
needed to get to the bottom of this.  

--jkl



More information about the Binutils mailing list