This is an archive of the discontinued LLVM Phabricator instance.

[compiler-rt] Add dynamic_runtime_thunk for different sanitizers.
ClosedPublic

Authored by mpividori on Jan 25 2017, 4:20 PM.

Details

Summary

In Windows, when the sanitizer is implemented as a shared library (DLL), we need an auxiliary static library dynamic_runtime_thunk that will be linked to the main executable and dlls, and will include the weak aliases. Also, for asan, dynamic_runtime_thunk does other stuff, in addition to the weak aliases.

In the sanitizer DLL, we are exposing weak functions with WIN_WEAK_EXPORT_DEF(), which exports the default implementation with __dll suffix. For example: for sanitizer coverage, the default implementation of __sanitizer_cov_trace_cmp is exported as: __sanitizer_cov_trace_cmp__dll.

So, in the dynamic_runtime_thunk static library, we include weak aliases to the imported implementation from the dll, using the macro WIN_WEAK_IMPORT_DEF() like:

WIN_WEAK_IMPORT_DEF(__sanitizer_cov_trace_cmp);
WIN_WEAK_IMPORT_DEF(__sanitizer_cov_trace_cmp1);
....

Which will be expanded to "weak aliases":

  __sanitizer_cov_trace_cmp = __sanitizer_cov_trace_cmp__dll
  __sanitizer_cov_trace_cmp1 = __sanitizer_cov_trace_cmp1__dll 
.....

So, by default, all users's programs that include calls to weak functions like __sanitizer_cov_trace_cmp, will be redirected to the implementation in the dll, when linking to dynamic_runtime_thunk.

After this diff, we are able to compile code with sanitizer coverage instrumentation on Windows. When the instrumented object files are linked with clang-rt_asan_dynamic_runtime_thunk-arch.lib all the weak symbols will be resolved to the implementation imported from asan dll.


All the files sanitizer_dynamic_runtime_thunk.cc are independent, so we don't need to include a specific list of sanitizers.
To create a dynamic_runtime_thunk for sanitizers SanitizerA and SanitizerB, we only need to compile: sanitizera/sanitizera_dynamic_runtime_thunk.cc sanitizerb/sanitizerb_dynamic_runtime_thunk.cc and sanitizer_common/sanitizer_dynamic_runtime_thunk.cc.

Now, we compile: asan_win_dynamic_runtime_thunk.cc ubsan_win_dynamic_runtime_thunk.cc sanitizer_coverage_win_dynamic_runtime_thunk.cc and sanitizer_win_dynamic_runtime_thunk.cc, to generate asan_dynamic_runtime_thunk, because we include asan, ubsan and sanitizer coverage in the address sanitizer library.

But we could also compile: sanitizer_coverage_win_dynamic_runtime_thunk.cc and sanitizer_win_dynamic_runtime_thunk.cc , to generate a dynamic_runtime_thunk only for sanitizer_coverage.


I addition, I needed to modify clang driver for windows to include: -wholearchive:asan_dynamic_runtime_thunk, so all the object files in the static library are considered by the linker. This is necessary, because some dynamic_runtime_thunks will only include linker pragmas, and doesn't resolve any symbol, so if we don't include that flag, the linker will ignore them, and won't read the linker pragmas. I will include these changes in a different diff.

Diff Detail

Repository
rL LLVM

Event Timeline

mpividori created this revision.Jan 25 2017, 4:20 PM
mpividori updated this revision to Diff 85838.Jan 25 2017, 4:23 PM

@alekseyshl Ready to land? This is a simple change. I split dynamic_runtime_thunks for different sanitizers, and define the weak alias for weak functions from each sanitizer.

rnk accepted this revision.Feb 2 2017, 11:28 AM

Looks good to me. The only shared code changed is CMake, and I think the impact is low, so let's go ahead and land this.

lib/sanitizer_common/CMakeLists.txt
204 ↗(On Diff #85838)

This is in an if (MSVC) block. Let's simplify it.

This revision is now accepted and ready to land.Feb 2 2017, 11:28 AM
This revision was automatically updated to reflect the committed changes.