-fsanitize=vptr implementation depends on RTTI descriptors for
cxxabiv1::class_type_info and friends.
Details
- Reviewers
kubamracek
Diff Detail
Event Timeline
lib/Driver/ToolChains.cpp | ||
---|---|---|
385 | Nothing should be linking directly with libc++abi.dylib. C++ code should link with libc++.dylib or libstdc++.dylib. I think there is some other setting in the clang driver that controls which to link with. But just linking with -lc++ will be right most of the time. |
lib/Driver/ToolChains.cpp | ||
---|---|---|
385 | What if chooses to provide -lstdc++? In that case we still need to get RTTI for __cxxabiv1::__class_type_info from somewhere... | |
385 | What if *user* chooses |
It will just work. libstdc++.dylib re-exports symbols from libc++abi.dylib:
[/tmp]> dyldinfo -export /usr/lib/libstdc++.dylib | grep class_type_info
[re-export] ZTVN10cxxabiv117class_type_infoE (from libc++abi)
[re-export] ZTSN10cxxabiv117class_type_infoE (from libc++abi)
[re-export] ZTVN10cxxabiv117class_type_infoE (from libc++abi)
[re-export] ZTSN10cxxabiv117__class_type_infoE (from libc++abi)
[/tmp]>
Well, users in that bug tell that they saw errors about unresolved symbols:
Undefined symbols for architecture x86_64: "__ZTIN10__cxxabiv117__class_type_infoE", referenced from: __ZN7__ubsan16checkDynamicTypeEPvS0_m in
but they went away after adding -lc++abi. Sorry, I don't have the Mac box at hand to verify it...
but they went away after adding -lc++abi.
and they would have gone away if they had added -lc++ or -lstdc++
Clang driver adds -lstdc++ to linker invocation automatically if user
provides -fsanitize=address or -fsanitize=undefined, yet we see linker
errors.
Alexander or Kuba, could you please check if the problem reproduces for you?
I can reproduce on the testcase from https://code.google.com/p/address-sanitizer/issues/detail?id=367:
$ ./bin/clang++ a.cpp $ ./bin/clang++ a.cpp -fsanitize=undefined Undefined symbols for architecture x86_64: "typeinfo for __cxxabiv1::__class_type_info", referenced from: __ubsan::checkDynamicType(void*, void*, unsigned long) in libclang_rt.ubsan_osx.a(ubsan_type_hash.cc.o) isDerivedFromAtOffset(__cxxabiv1::__class_type_info const*, __cxxabiv1::__class_type_info const*, long) in libclang_rt.ubsan_osx.a(ubsan_type_hash.cc.o) findBaseAtOffset(__cxxabiv1::__class_type_info const*, long) in libclang_rt.ubsan_osx.a(ubsan_type_hash.cc.o) "typeinfo for __cxxabiv1::__si_class_type_info", referenced from: isDerivedFromAtOffset(__cxxabiv1::__class_type_info const*, __cxxabiv1::__class_type_info const*, long) in libclang_rt.ubsan_osx.a(ubsan_type_hash.cc.o) findBaseAtOffset(__cxxabiv1::__class_type_info const*, long) in libclang_rt.ubsan_osx.a(ubsan_type_hash.cc.o) "typeinfo for __cxxabiv1::__vmi_class_type_info", referenced from: isDerivedFromAtOffset(__cxxabiv1::__class_type_info const*, __cxxabiv1::__class_type_info const*, long) in libclang_rt.ubsan_osx.a(ubsan_type_hash.cc.o) findBaseAtOffset(__cxxabiv1::__class_type_info const*, long) in libclang_rt.ubsan_osx.a(ubsan_type_hash.cc.o) ld: symbol(s) not found for architecture x86_64 clang-3.6: error: linker command failed with exit code 1 (use -v to see invocation) $ ./bin/clang++ a.cpp -fsanitize=undefined -lc++abi $
The mangled names of these are:
__ZTIN10__cxxabiv117__class_type_infoE __ZTIN10__cxxabiv120__si_class_type_infoE __ZTIN10__cxxabiv121__vmi_class_type_infoE
It looks like libc++ is actually re-exporting a lot of symbols from libc++abi, but it doesn't re-export all of them:
$ dyldinfo -export /usr/lib/libc++.dylib | grep cxxabiv117__class [re-export] __ZTSN10__cxxabiv117__class_type_infoE (from libc++abi) [re-export] __ZTVN10__cxxabiv117__class_type_infoE (from libc++abi) [re-export] __ZTSN10__cxxabiv117__class_type_infoE (from libc++abi) [re-export] __ZTVN10__cxxabiv117__class_type_infoE (from libc++abi) $ dyldinfo -export /usr/lib/libc++.dylib | grep __ZTIN10__cxxabiv117__class_type_infoE $
So it looks like a libc++ issue (assuming the missing symbols are meant to be re-exported), and they need to be added to libcxx/lib/libc++abi.exp.
Nothing should be linking directly with libc++abi.dylib. C++ code should link with libc++.dylib or libstdc++.dylib. I think there is some other setting in the clang driver that controls which to link with. But just linking with -lc++ will be right most of the time.