Problem linking in some dataflow sanitizer functions?

Hello, I'm using the dataflow sanitizer in clang 3.6 for the first
time, I'm I'm running into some linker errors. I was wondering if
someone could point out my mistake?

I downloaded (today) from git the current llvm, clang, and compiler-rt
code. It built without any problem.

Using that build of clang/llvm, I'm able to run the example code shown
here: http://clang.llvm.org/docs/DataFlowSanitizer.html#example

However, I have a linking problem when I try to extend the example.
When I try to call the function "dfsan_get_label_info", the linker
can't find it. This is a bit of a surprise, because it does appear to
be defined in my LLVM build:

cconvey@spaceman /tmp $ nm
/home/cconvey/dw/clang-llvm-git/build/bin/../lib/clang/3.6.0/lib/linux/libclang_rt.dfsan-x86_64.a

grep dfsan_get_label_info

0000000000000990 T _Z20dfsan_get_label_infot
cconvey@spaceman /tmp $ c++filt _Z20dfsan_get_label_infot
dfsan_get_label_info(unsigned short)

And I'm reasonably sure I'm linking in that .a file:

cconvey@spaceman /tmp $
/home/cconvey/dw/clang-llvm-git/build/bin/clang -fsanitize=dataflow
foo.c -v
clang version 3.6.0 (http://llvm.org/git/clang.git
48d2f2367001a51a3253cc34aea4a91c92fd45fb)
(http://llvm.org/git/llvm.git
ad017096fc8eec5afd256f572d8d0b9d5d8aa09f)
...
End of search list.
"/usr/bin/ld" -pie --eh-frame-hdr -m elf_x86_64 -dynamic-linker
/lib64/ld-linux-x86-64.so.2 -o a.out
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/Scrt1.o
/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/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/home/cconvey/dw/clang-llvm-git/build/bin/../lib -L/lib -L/usr/lib
-whole-archive /home/cconvey/dw/clang-llvm-git/build/bin/../lib/clang/3.6.0/lib/linux/libclang_rt.dfsan-x86_64.a
-no-whole-archive
--dynamic-list=/home/cconvey/dw/clang-llvm-git/build/bin/../lib/clang/3.6.0/lib/linux/libclang_rt.dfsan-x86_64.a.syms
/tmp/foo-5310a2.o --no-as-needed -lpthread -lrt -lm -ldl -lgcc
--as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s
--no-as-needed /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
/tmp/foo-5310a2.o: In function `dfs$execute_tree':
foo.c:(.text+0xa89): undefined reference to `dfsan_get_label_info'
/tmp/foo-5310a2.o: In function `dfsw$dfsan_get_label_info':
foo.c:(.text.dfsw$dfsan_get_label_info[dfsw$dfsan_get_label_info]+0xb):
undefined reference to `dfsan_get_label_info'
clang-3.6: error: linker command failed with exit code 1 (use -v to
see invocation)
cconvey@spaceman /tmp $

(I'm also having linkage problems when my code uses C++ iostreams, but
I figured I'd work through this issue first.)

Hi Christian,

There was a bug that prevented clients from using the dfsan_get_label_info
function. That bug is now fixed in compiler-rt r225692.

Peter

Thanks Peter. That seems to have done the trick for dfsan_get_label_info.

I'm still having trouble with C++ STL functions, though. Any idea why
I might be getting the following?

I have this simple test program, foo2.c:

#include <iostream>

using namespace std;

int main(void) {
    cout << "Hellow, world!" << endl;
    return 0;
}

When I build it without the dataflow sanitizer, things work fine:
/home/cconvey/dw/clang-llvm-git/build/bin/clang++ -std=c++11 foo2.cpp

However, when I enable the sanitizer, there are a lot of unmet
dependencies. Any idea if I'm doing something wrong on the command
line?
cconvey@spaceman /tmp $
/home/cconvey/dw/clang-llvm-git/build/bin/clang++ -std=c++11
-fsanitize=dataflow foo2.cpp
/tmp/foo2-8b9f0f.o: In function `main':
foo2.cpp:(.text+0xb): undefined reference to
`dfs$_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_'
foo2.cpp:(.text+0x44): undefined reference to
`dfs$_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc'
foo2.cpp:(.text+0x6a): undefined reference to `dfs$_ZNSolsEPFRSoS_E'
/tmp/foo2-8b9f0f.o: In function `dfs$__cxx_global_var_init':
foo2.cpp:(.text.startup+0x1d): undefined reference to
`dfs$_ZNSt8ios_base4InitC1Ev'
foo2.cpp:(.text.startup+0x24): undefined reference to
`dfs$_ZNSt8ios_base4InitD1Ev'
clang-3.6: error: linker command failed with exit code 1 (use -v to
see invocation)

Thanks,
Christian

Hi Christian,

If you wish to compile C++ programs with DFSan, you will first need to
compile the C++ standard library with DFSan. Unfortunately, the way to do
this is quite painful at the moment, and needs to be simplified and documented
better. This way worked for me:

1. Check out the libcxx and libcxxabi projects into the LLVM projects directory.

2. Use cmake to configure a separate build directory in which to build libcxx
   and libcxxabi with DFSan:

    # assuming that your LLVM source directory is ~/src/llvm and build directory is ~/src/llvm-build
    mkdir ~/src/llvm-build-dfsan
    cd ~/src/llvm-build-dfsan
    CC=~/src/llvm-build/bin/clang CXX=~/src/llvm-build/bin/clang++ cmake -G Ninja ../llvm -DCMAKE_C_FLAGS=-fsanitize=dataflow -DCMAKE_CXX_FLAGS=-fsanitize=dataflow -DLIBCXXABI_ENABLE_SHARED=NO -DLIBCXX_ENABLE_SHARED=NO -DLLVM_FORCE_USE_OLD_TOOLCHAIN=YES -DLIBCXX_CXX_ABI=libcxxabi

3. Build only libc++ and libc++abi in the just-configured build directory:
    ninja cxx cxxabi

3. To compile your program, pass the following flags to clang++:

   compile flags: -stdlib=libc++ -fsanitize=dataflow -I$HOME/src/llvm-build-dfsan/include/c++/v1
   link flags: -stdlib=libc++ -fsanitize=dataflow -L$HOME/src/llvm-build-dfsan/lib -Wl,--start-group,-lc++abi

I was able to compile and run your hello world program this way. Please let
me know if it works for you.

Thanks,
Peter

Hi Peter,

Sorry for the slow reply. I tried to following your instructions
precisely (since I think that was one of your main points), and I ran
into trouble on the "ninja" invocation:

cconvey@spaceman ~/dw/clang-llvm-git/llvm-build-dfsan $ ninja cxx cxxabi
ninja: error: unknown target 'cxx', did you mean 'lli'?

Please let me know if you'd like me to try something else.

Cheers,
Christian

Hi Christian,

Are you sure that you have checked out libcxx and libcxxabi into llvm/projects
(i.e. alongside compiler-rt)? Once you have done so, it may be necessary
to run CMake again to pick up the new projects (the safest thing to do is
probably to delete the llvm-build-dfsan directory and redo step 2).

Peter