From 42cdfbcf3e92466754c175cb0e1e237e9f66749e Mon Sep 17 00:00:00 2001 From: Etienne Bergeron Date: Wed, 28 Sep 2016 18:04:07 +0000 Subject: [PATCH] [compiler-rt] Fix interception of multiple defined symbols. Summary: The MSVC compiler is generating multiple instance of the exception handler when compiling on win64 with /MD. see: https://msdn.microsoft.com/en-us/library/2kzt1wy3.aspx Two tests were failing when running: ``` ninja check-asan-dynamic. ``` The tests were failing because only the first occurence of the function was patched. The function `__C_specific_handler` is defined in `ntdll` and `vcruntime140`. After this patch, there is still two remaining tests failing. ``` ******************** Testing: 0 .. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90.. Testing Time: 87.81s ******************** Failing Tests (2): AddressSanitizer-x86_64-windows-dynamic :: TestCases/Windows/dll_intercept_memchr.cc AddressSanitizer-x86_64-windows-dynamic :: TestCases/Windows/dll_intercept_memcpy_indirect.cc Expected Passes : 342 Passes With Retry : 2 Expected Failures : 16 Unsupported Tests : 152 Unexpected Failures: 2 ``` Reviewers: rnk, vitalybuka Subscribers: vitalybuka, llvm-commits, chrisha, dberris Differential Revision: https://reviews.llvm.org/D24983 llvm-svn: 282614 --- .../lib/interception/interception_win.cc | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/compiler-rt/lib/interception/interception_win.cc b/compiler-rt/lib/interception/interception_win.cc index c8d67b976682..a967706e16ee 100644 --- a/compiler-rt/lib/interception/interception_win.cc +++ b/compiler-rt/lib/interception/interception_win.cc @@ -915,19 +915,18 @@ uptr InternalGetProcAddress(void *module, const char *func_name) { return 0; } -static bool GetFunctionAddressInDLLs(const char *func_name, uptr *func_addr) { - *func_addr = 0; +bool OverrideFunction( + const char *func_name, uptr new_func, uptr *orig_old_func) { + bool hooked = false; void **DLLs = InterestingDLLsAvailable(); - for (size_t i = 0; *func_addr == 0 && DLLs[i]; ++i) - *func_addr = InternalGetProcAddress(DLLs[i], func_name); - return (*func_addr != 0); -} - -bool OverrideFunction(const char *name, uptr new_func, uptr *orig_old_func) { - uptr orig_func; - if (!GetFunctionAddressInDLLs(name, &orig_func)) - return false; - return OverrideFunction(orig_func, new_func, orig_old_func); + for (size_t i = 0; DLLs[i]; ++i) { + uptr func_addr = InternalGetProcAddress(DLLs[i], func_name); + if (func_addr && + OverrideFunction(func_addr, new_func, orig_old_func)) { + hooked = true; + } + } + return hooked; } bool OverrideImportedFunction(const char *module_to_patch,