diff options
author | Anna Zaks <ganna@apple.com> | 2015-02-27 03:12:19 +0000 |
---|---|---|
committer | Anna Zaks <ganna@apple.com> | 2015-02-27 03:12:19 +0000 |
commit | 2249049db2d0341a037da92c25f141db7ceea6d8 (patch) | |
tree | 1d75096068743a2d8bac42c0bac1c8ff7e6ff662 /compiler-rt/lib | |
parent | 5bc883f39ebab81b54629feebc7da6b6d5e2b8aa (diff) | |
download | bcm5719-llvm-2249049db2d0341a037da92c25f141db7ceea6d8.tar.gz bcm5719-llvm-2249049db2d0341a037da92c25f141db7ceea6d8.zip |
[compiler-rt] Allow suppression file to be relative to the location of the executable
The ASanified executable could be launched from different locations. When we
cannot find the suppression file relative to the current directory, try to
see if the specified path is relative to the location of the executable.
llvm-svn: 230723
Diffstat (limited to 'compiler-rt/lib')
6 files changed, 77 insertions, 4 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h index f4eed0c5f33..486efc98a7e 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.h @@ -216,6 +216,11 @@ const char *GetEnv(const char *name); bool SetEnv(const char *name, const char *value); const char *GetPwd(); char *FindPathToBinary(const char *name); +bool IsPathSeparator(const char c); +bool IsAbsolutePath(const char *path); + +// Returns the path to the main executable. +uptr ReadBinaryName(/*out*/char *buf, uptr buf_len); u32 GetUid(); void ReExec(); bool StackSizeIsUnlimited(); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h index b2e603d3a23..2ce2025d2ab 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h @@ -80,8 +80,6 @@ uptr ThreadSelfOffset(); // information). bool LibraryNameIs(const char *full_name, const char *base_name); -// Read the name of the current binary from /proc/self/exe. -uptr ReadBinaryName(/*out*/char *buf, uptr buf_len); // Cache the value of /proc/self/exe. void CacheBinaryName(); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cc b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cc index 39a5c7e8d24..9669402865e 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cc @@ -31,9 +31,11 @@ #include <crt_externs.h> // for _NSGetEnviron #include <fcntl.h> +#include <mach-o/dyld.h> #include <pthread.h> #include <sched.h> #include <signal.h> +#include <stdlib.h> #include <sys/mman.h> #include <sys/resource.h> #include <sys/stat.h> @@ -204,6 +206,21 @@ const char *GetEnv(const char *name) { return 0; } +uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) { + CHECK_LE(kMaxPathLength, buf_len); + + // On OS X the executable path is saved to the stack by dyld. Reading it + // from there is much faster than calling dladdr, especially for large + // binaries with symbols. + InternalScopedString exe_path(kMaxPathLength); + uint32_t size = exe_path.size(); + if (_NSGetExecutablePath(exe_path.data(), &size) == 0 && + realpath(exe_path.data(), buf) != 0) { + return internal_strlen(buf); + } + return 0; +} + void ReExec() { UNIMPLEMENTED(); } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix.cc b/compiler-rt/lib/sanitizer_common/sanitizer_posix.cc index 5bc41c2580f..b8bd1b2b8e5 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_posix.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix.cc @@ -293,6 +293,14 @@ char *FindPathToBinary(const char *name) { return 0; } +bool IsPathSeparator(const char c) { + return c == '/'; +} + +bool IsAbsolutePath(const char *path) { + return path != nullptr && IsPathSeparator(path[0]); +} + void ReportFile::Write(const char *buffer, uptr length) { SpinMutexLock l(mu); static const char *kWriteError = diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_suppressions.cc b/compiler-rt/lib/sanitizer_common/sanitizer_suppressions.cc index 2b697e95570..8009b4d6aad 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_suppressions.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_suppressions.cc @@ -30,18 +30,50 @@ SuppressionContext::SuppressionContext(const char *suppression_types[], internal_memset(has_suppression_type_, 0, suppression_types_num_); } +static bool GetPathAssumingFileIsRelativeToExec(const char *file_path, + /*out*/char *new_file_path, + uptr new_file_path_size) { + InternalScopedString exec(kMaxPathLength); + if (ReadBinaryName(exec.data(), exec.size())) { + const char *file_name_pos = StripModuleName(exec.data()); + uptr path_to_exec_len = file_name_pos - exec.data(); + internal_strncat(new_file_path, exec.data(), + Min(path_to_exec_len, new_file_path_size - 1)); + internal_strncat(new_file_path, file_path, + new_file_path_size - internal_strlen(new_file_path) - 1); + return true; + } + return false; +} + void SuppressionContext::ParseFromFile(const char *filename) { if (filename[0] == '\0') return; + + // If we cannot find the file, check if its location is relative to + // the location of the executable. + InternalScopedString new_file_path(kMaxPathLength); + if (!FileExists(filename) && !IsAbsolutePath(filename) && + GetPathAssumingFileIsRelativeToExec(filename, new_file_path.data(), + new_file_path.size())) { + filename = new_file_path.data(); + } + + // Read the file. char *file_contents; uptr buffer_size; - uptr contents_size = ReadFileToBuffer(filename, &file_contents, &buffer_size, - 1 << 26 /* max_len */); + const uptr max_len = 1 << 26; + uptr contents_size = + ReadFileToBuffer(filename, &file_contents, &buffer_size, max_len); + VPrintf(1, "%s: reading suppressions file at %s\n", + SanitizerToolName, filename); + if (contents_size == 0) { Printf("%s: failed to read suppressions file '%s'\n", SanitizerToolName, filename); Die(); } + Parse(file_contents); } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win.cc b/compiler-rt/lib/sanitizer_common/sanitizer_win.cc index 335cecabe11..e019d0302e8 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_win.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_win.cc @@ -313,6 +313,19 @@ char *FindPathToBinary(const char *name) { return 0; } +uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) { + // Nothing here for now. + return 0; +} + +bool IsPathSeparator(const char c) { + return c == '\\' || c == '/'; +} + +bool IsAbsolutePath(const char *path) { + UNIMPLEMENTED(); +} + void SleepForSeconds(int seconds) { Sleep(seconds * 1000); } |