diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp @@ -203,6 +203,17 @@ if (*end == '\0') break; beg = end + 1; } + + // If not in PATH, search in the same directory as the executable. + if (ReadBinaryName(buffer.data(), kMaxPathLength)) { + const char *exec_name_pos = StripModuleName(buffer.data()); + uptr path_to_exec_len = exec_name_pos - buffer.data(); + buffer[path_to_exec_len] = '\0'; + internal_strncat(buffer.data(), name, buffer.size()); + if (FileExists(buffer.data())) + return internal_strdup(buffer.data()); + } + return nullptr; } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp @@ -1042,10 +1042,19 @@ } uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) { - // FIXME: Actually implement this function. CHECK_GT(buf_len, 0); - buf[0] = 0; - return 0; + + // Get the UTF-16 path and convert to UTF-8. + wchar_t binname_utf16[kMaxPathLength]; + int binname_utf16_len = + GetModuleFileNameW(NULL, binname_utf16, kMaxPathLength); + if (binname_utf16_len == 0) + binname_utf16[0] = '\0'; + int binary_name_len = + ::WideCharToMultiByte(CP_UTF8, 0, binname_utf16, binname_utf16_len + 1, + &buf[0], kMaxPathLength, NULL, NULL); + buf[binary_name_len] = '\0'; + return binary_name_len; } uptr ReadLongProcessName(/*out*/char *buf, uptr buf_len) { diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_common_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_common_test.cpp --- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_common_test.cpp +++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_common_test.cpp @@ -281,6 +281,10 @@ EXPECT_NE((char*)0, internal_strstr(true_path, "/bin/true")); InternalFree(true_path); EXPECT_EQ(0, FindPathToBinary("unexisting_binary.ergjeorj")); + + // Search for something in the llvm build directory. + char *clang_path = FindPathToBinary("clang"); + EXPECT_NE((char *)0, internal_strstr(clang_path, "clang")); } #elif SANITIZER_WINDOWS TEST(SanitizerCommon, FindPathToBinary) { @@ -290,6 +294,10 @@ EXPECT_NE((char*)0, internal_strstr(ntdll_path, "ntdll.dll")); InternalFree(ntdll_path); EXPECT_EQ(0, FindPathToBinary("unexisting_binary.ergjeorj")); + + // Search for something in the llvm build directory. + char *clang_path = FindPathToBinary("clang-cl.exe"); + EXPECT_NE((char *)0, internal_strstr(clang_path, "clang-cl.exe")); } #endif diff --git a/compiler-rt/test/asan/TestCases/suppressions-exec-relative-location.cpp b/compiler-rt/test/asan/TestCases/suppressions-exec-relative-location.cpp --- a/compiler-rt/test/asan/TestCases/suppressions-exec-relative-location.cpp +++ b/compiler-rt/test/asan/TestCases/suppressions-exec-relative-location.cpp @@ -24,7 +24,6 @@ // RUN: FileCheck --check-prefix=CHECK-WRONG-FILE-NAME %s // XFAIL: android -// XFAIL: windows-msvc // UNSUPPORTED: ios #include