Building LLVM with asan

Hello everybody,

after moving from OS X to Linux build llvm with asan enabled (I also updated to trunk, but not sure if that’s related). However, it’s totally possible that I missed a step that I took back when I set this up for me, so I might be doing something very stupid. Anyway, I’m configuring LLVM with

…/configure --prefix=/home/kfischer/julia/usr --build=x86_64-pc-linux-gnu FC=gfortran CC=“/home/kfischer/julia/deps/llvm-svn/build_Release+Asserts/Release+Asserts/bin/clang -fsanitize=address” CXX=“/home/kfischer/julia/deps/llvm-svn/build_Release+Asserts/Release+Asserts/bin/clang++” -fsanitize=address --disable-profiling --enable-shared --enable-static --enable-targets=host --disable-bindings --disable-docs --enable-assertions --enable-optimized --disable-threads

in a different directory (build_Release+Asserts+Sanitize). As you can see I’m bootstrapping this through a different copy of clang I just built. However, now I’m getting tons of
undefined reference to `__asan_report_store8’
even though the command the failing command being invoked is

/home/kfischer/julia/deps/llvm-svn/build_Release+Asserts/Release+Asserts/bin/clang++ -fsanitize=address -O3 -Wl,-R -Wl,‘$ORIGIN’ -rdynamic -L/home/kfischer/julia/deps/llvm-svn/build_Release+Asserts+Sanitize/Release+Asserts/lib -L/home/kfischer/julia/deps/llvm-svn/build_Release+Asserts+Sanitize/Release+Asserts/lib -shared -o /home/kfischer/julia/deps/llvm-svn/build_Release+Asserts+Sanitize/Release+Asserts/lib/libLLVM-3.5svn.so -Wl,–whole-archive -lLLVMAnalysis -lLLVMAsmParser -lLLVMAsmPrinter -lLLVMBitReader -lLLVMBitWriter -lLLVMCodeGen -lLLVMCore -lLLVMDebugInfo -lLLVMExecutionEngine -lLLVMInstCombine -lLLVMInstrumentation -lLLVMInterpreter -lLLVMipa -lLLVMipo -lLLVMIRReader -lLLVMLinker -lLLVMLTO -lLLVMMC -lLLVMMCDisassembler -lLLVMMCJIT -lLLVMMCParser -lLLVMObjCARCOpts -lLLVMObject -lLLVMOption -lLLVMRuntimeDyld -lLLVMScalarOpts -lLLVMSelectionDAG -lLLVMSupport -lLLVMTarget -lLLVMTransformUtils -lLLVMVectorize -lLLVMX86AsmParser -lLLVMX86AsmPrinter -lLLVMX86CodeGen -lLLVMX86Desc -lLLVMX86Disassembler -lLLVMX86Info -lLLVMX86Utils -Wl,–no-whole-archive -Wl,–soname,libLLVM-3.5svn.so -Wl,–no-undefined -lz -ltinfo -lm

Am I doing something stupid?
Thanks,
Keno

Hello everybody,

after moving from OS X to Linux build llvm with asan enabled

Sorry, I failed to parse this. You're compiling Clang on Linux, and
OSX is unrelated, right?

(I also updated
to trunk, but not sure if that's related). However, it's totally possible
that I missed a step that I took back when I set this up for me, so I might
be doing something very stupid. Anyway, I'm configuring LLVM with

../configure --prefix=/home/kfischer/julia/usr --build=x86_64-pc-linux-gnu
FC=gfortran
CC="/home/kfischer/julia/deps/llvm-svn/build_Release+Asserts/Release+Asserts/bin/clang
-fsanitize=address"
CXX="/home/kfischer/julia/deps/llvm-svn/build_Release+Asserts/Release+Asserts/bin/clang++"
-fsanitize=address --disable-profiling --enable-shared --enable-static
--enable-targets=host --disable-bindings --disable-docs --enable-assertions
--enable-optimized --disable-threads

So you're building Clang with -fsanitize=address. Note: you won't be
able to build libsanitizer this way.

in a different directory (build_Release+Asserts+Sanitize). As you can see
I'm bootstrapping this through a different copy of clang I just built.
However, now I'm getting tons of
undefined reference to `__asan_report_store8'
even though the command the failing command being invoked is

/home/kfischer/julia/deps/llvm-svn/build_Release+Asserts/Release+Asserts/bin/clang++
-fsanitize=address -O3 -Wl,-R -Wl,'$ORIGIN' -rdynamic
-L/home/kfischer/julia/deps/llvm-svn/build_Release+Asserts+Sanitize/Release+Asserts/lib
-L/home/kfischer/julia/deps/llvm-svn/build_Release+Asserts+Sanitize/Release+Asserts/lib
-shared -o
/home/kfischer/julia/deps/llvm-svn/build_Release+Asserts+Sanitize/Release+Asserts/lib/libLLVM-3.5svn.so
-Wl,--whole-archive -lLLVMAnalysis -lLLVMAsmParser -lLLVMAsmPrinter
-lLLVMBitReader -lLLVMBitWriter -lLLVMCodeGen -lLLVMCore -lLLVMDebugInfo
-lLLVMExecutionEngine -lLLVMInstCombine -lLLVMInstrumentation
-lLLVMInterpreter -lLLVMipa -lLLVMipo -lLLVMIRReader -lLLVMLinker -lLLVMLTO
-lLLVMMC -lLLVMMCDisassembler -lLLVMMCJIT -lLLVMMCParser -lLLVMObjCARCOpts
-lLLVMObject -lLLVMOption -lLLVMRuntimeDyld -lLLVMScalarOpts
-lLLVMSelectionDAG -lLLVMSupport -lLLVMTarget -lLLVMTransformUtils
-lLLVMVectorize -lLLVMX86AsmParser -lLLVMX86AsmPrinter -lLLVMX86CodeGen
-lLLVMX86Desc -lLLVMX86Disassembler -lLLVMX86Info -lLLVMX86Utils
-Wl,--no-whole-archive -Wl,--soname,libLLVM-3.5svn.so -Wl,--no-undefined -lz
-ltinfo -lm

Can you please add -v to the command line to see the ld invocation line?
You'll need to locate the ASan runtime library and check whether it's
a 32-bit one and if __asan_report_store8 is present in its symbol
table.

What I meant to say was that it worked for me on OS X on a slightly older version of LLVM. Anyway, here’s the ld line:

“/usr/bin/ld” -export-dynamic -z relro --hash-style=gnu --build-id --eh-frame-hdr -m elf_x86_64 -shared -o /home/kfischer/julia/deps/llvm-svn/build_Release+Asserts+Sanitize/Release+Asserts/lib/libLLVM-3.5svn.so /usr/lib/gcc/x86_64-linux-gnu/4.8/…/…/…/x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.8/crtbeginS.o -L/home/kfischer/julia/deps/llvm-svn/build_Release+Asserts+Sanitize/Release+Asserts/lib -L/home/kfischer/julia/deps/llvm-svn/build_Release+Asserts+Sanitize/Release+Asserts/lib -L/usr/lib/gcc/x86_64-linux-gnu/4.8 -L/usr/lib/gcc/x86_64-linux-gnu/4.8/…/…/…/x86_64-linux-gnu -L/lib/x86_64-linux-gnu -L/lib/…/lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.8/…/…/… -L/lib -L/usr/lib -R “$ORIGIN” --whole-archive -lLLVMAnalysis -lLLVMAsmParser -lLLVMAsmPrinter -lLLVMBitReader -lLLVMBitWriter -lLLVMCodeGen -lLLVMCore -lLLVMDebugInfo -lLLVMExecutionEngine -lLLVMInstCombine -lLLVMInstrumentation -lLLVMInterpreter -lLLVMipa -lLLVMipo -lLLVMIRReader -lLLVMLinker -lLLVMLTO -lLLVMMC -lLLVMMCDisassembler -lLLVMMCJIT -lLLVMMCParser -lLLVMObjCARCOpts -lLLVMObject -lLLVMOption -lLLVMRuntimeDyld -lLLVMScalarOpts -lLLVMSelectionDAG -lLLVMSupport -lLLVMTarget -lLLVMTransformUtils -lLLVMVectorize -lLLVMX86AsmParser -lLLVMX86AsmPrinter -lLLVMX86CodeGen -lLLVMX86Desc -lLLVMX86Disassembler -lLLVMX86Info -lLLVMX86Utils --no-whole-archive --soname libLLVM-3.5svn.so --no-undefined -lz -ltinfo -lm -lstdc++ -lm -lgcc_s -lc -lgcc_s /usr/lib/gcc/x86_64-linux-gnu/4.8/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/4.8/…/…/…/x86_64-linux-gnu/crtn.o

It doesn’t seem to be linking the asan runtime which seems weird since I’m passing -faddress=sanitize.

Yeah, it’s not linking the runtime because you’re building a shared library. This is totally ok. In this case there are undefined _asan* symbols that are resolved when an instrumented binary loads your library.
What’s wrong here is that some flag passed to ld prevents it from creating undefined symbols (–no-undefined?). This flag must be removed when building with ASan.
This isn’t the case on OSX where the runtime is a dynamic library and can safely be linked to instrumented dynamic libraries.

What I meant to say was that it worked for me on OS X on a slightly older version of LLVM. Anyway, here’s the ld line:

“/usr/bin/ld” -export-dynamic -z relro --hash-style=gnu --build-id --eh-frame-hdr -m elf_x86_64 -shared -o /home/kfischer/julia/deps/llvm-svn/build_Release+Asserts+Sanitize/Release+Asserts/lib/libLLVM-3.5svn.so /usr/lib/gcc/x86_64-linux-gnu/4.8/…/…/…/x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.8/crtbeginS.o -L/home/kfischer/julia/deps/llvm-svn/build_Release+Asserts+Sanitize/Release+Asserts/lib -L/home/kfischer/julia/deps/llvm-svn/build_Release+Asserts+Sanitize/Release+Asserts/lib -L/usr/lib/gcc/x86_64-linux-gnu/4.8 -L/usr/lib/gcc/x86_64-linux-gnu/4.8/…/…/…/x86_64-linux-gnu -L/lib/x86_64-linux-gnu -L/lib/…/lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.8/…/…/… -L/lib -L/usr/lib -R “$ORIGIN” --whole-archive -lLLVMAnalysis -lLLVMAsmParser -lLLVMAsmPrinter -lLLVMBitReader -lLLVMBitWriter -lLLVMCodeGen -lLLVMCore -lLLVMDebugInfo -lLLVMExecutionEngine -lLLVMInstCombine -lLLVMInstrumentation -lLLVMInterpreter -lLLVMipa -lLLVMipo -lLLVMIRReader -lLLVMLinker -lLLVMLTO -lLLVMMC -lLLVMMCDisassembler -lLLVMMCJIT -lLLVMMCParser -lLLVMObjCARCOpts -lLLVMObject -lLLVMOption -lLLVMRuntimeDyld -lLLVMScalarOpts -lLLVMSelectionDAG -lLLVMSupport -lLLVMTarget -lLLVMTransformUtils -lLLVMVectorize -lLLVMX86AsmParser -lLLVMX86AsmPrinter -lLLVMX86CodeGen -lLLVMX86Desc -lLLVMX86Disassembler -lLLVMX86Info -lLLVMX86Utils --no-whole-archive --soname libLLVM-3.5svn.so --no-undefined -lz -ltinfo -lm -lstdc++ -lm -lgcc_s -lc -lgcc_s /usr/lib/gcc/x86_64-linux-gnu/4.8/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/4.8/…/…/…/x86_64-linux-gnu/crtn.o

It doesn’t seem to be linking the asan runtime which seems weird since I’m passing -faddress=sanitize.

Indeed, removing that flag works fine, the only question is why this is added in tools/llvm-shlib/Makefile in the first place then and what to do about it:

ifeq ($(HOST_OS), $(filter $(HOST_OS), Linux GNU GNU/kFreeBSD))

Don’t allow unresolved symbols.

LLVMLibsOptions += -Wl,–no-undefined
endif

Actually it only link the shlib fine. Linking any executable against it fails:

llvm[2]: Linking Release+Asserts executable llvm-lto (without symbols)
/home/kfischer/julia/deps/llvm-svn/build_Release+Asserts/Release+Asserts/bin/clang++ -fsanitize=address -O3 -Wl,-R -Wl,‘$ORIGIN/…/lib’ -L/home/kfischer/julia/deps/llvm-svn/build_Release+Asserts+Sanitize/Release+Asserts/lib -L/home/kfischer/julia/deps/llvm-svn/build_Release+Asserts+Sanitize/Release+Asserts/lib -Wl,–version-script=/home/kfischer/julia/deps/llvm-svn/autoconf/ExportMap.map -fsanitize=address -o /home/kfischer/julia/deps/llvm-svn/build_Release+Asserts+Sanitize/Release+Asserts/bin/llvm-lto /home/kfischer/julia/deps/llvm-svn/build_Release+Asserts+Sanitize/tools/llvm-lto/Release+Asserts/llvm-lto.o
-lLLVM-3.5svn -lz -ltinfo -lm
/usr/bin/ld: /home/kfischer/julia/deps/llvm-svn/build_Release+Asserts+Sanitize/Release+Asserts/bin/llvm-lto: local symbol `__asan_report_store4’ in /home/kfischer/julia/deps/llvm-svn/build_Release+Asserts/Release+Asserts/bin/…/lib/clang/3.5/lib/linux/libclang_rt.asan-x86_64.a(asan_rtl.o) is referenced by DSO
/usr/bin/ld: final link failed: Bad value

Alright, this somehow started to work after I blew away both the bootstrapped and the instrumented version using the above removing the above lines from tools/llvm-shlib/Makefile. Does anybody know why they are there in the first place? Nothing seemed broken after removing them.

For the benefit of anybody who may be finding this in the archives later, the problem was that we’re controlling what symbols are considered global using --version-script, so the asan symbols were not considered global and thus failed in the final link step.