summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2013-10-15 11:34:59 +0000
committerDmitry Vyukov <dvyukov@google.com>2013-10-15 11:34:59 +0000
commit3dbbd850cde5728c35aa4c15a279d858604fc6ee (patch)
tree657554dbf5bd7bff58b3736eebf17a050f6e1977
parent600d51680fb20f670695e931de60df4d88616e96 (diff)
downloadcompiler-rt-3dbbd850cde5728c35aa4c15a279d858604fc6ee.tar.gz
compiler-rt-3dbbd850cde5728c35aa4c15a279d858604fc6ee.tar.bz2
compiler-rt-3dbbd850cde5728c35aa4c15a279d858604fc6ee.tar.xz
tsan: resolve symlinks for called_from_lib suppressions
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@192688 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/sanitizer_common/sanitizer_libignore.cc21
-rw-r--r--lib/sanitizer_common/sanitizer_libignore.h3
-rw-r--r--lib/tsan/rtl/tsan_interceptors.cc4
3 files changed, 21 insertions, 7 deletions
diff --git a/lib/sanitizer_common/sanitizer_libignore.cc b/lib/sanitizer_common/sanitizer_libignore.cc
index 9a0213e7..82841318 100644
--- a/lib/sanitizer_common/sanitizer_libignore.cc
+++ b/lib/sanitizer_common/sanitizer_libignore.cc
@@ -38,7 +38,12 @@ void LibIgnore::Init(const SuppressionContext &supp) {
}
}
-void LibIgnore::OnLibraryLoaded() {
+void LibIgnore::OnLibraryLoaded(const char *name) {
+ const char *real_name = 0;
+ InternalScopedBuffer<char> buf(4096);
+ if (name != 0 && internal_readlink(name, buf.data(), buf.size() - 1) > 0)
+ real_name = buf.data();
+
BlockingMutexLock lock(&mutex_);
MemoryMappingLayout proc_maps(/*cache_enabled*/false);
InternalScopedBuffer<char> fn(4096);
@@ -48,8 +53,14 @@ void LibIgnore::OnLibraryLoaded() {
proc_maps.Reset();
uptr b, e, off, prot;
while (proc_maps.Next(&b, &e, &off, fn.data(), fn.size(), &prot)) {
- if ((prot & MemoryMappingLayout::kProtectionExecute) != 0 &&
- TemplateMatch(lib->templ, fn.data())) {
+ bool symlink = false;
+ if (((prot & MemoryMappingLayout::kProtectionExecute) != 0) &&
+ (TemplateMatch(lib->templ, fn.data()) ||
+ // Resolve symlinks.
+ (real_name != 0 && real_name[0] != 0 &&
+ TemplateMatch(lib->templ, name) &&
+ internal_strcmp(real_name, fn.data()) == 0 &&
+ (symlink = true)))) {
if (loaded) {
Report("%s: called_from_lib suppression '%s' is matched against"
" 2 libraries: '%s' and '%s'\n",
@@ -60,6 +71,8 @@ void LibIgnore::OnLibraryLoaded() {
if (!lib->loaded) {
lib->loaded = true;
lib->name = internal_strdup(fn.data());
+ if (symlink)
+ lib->real_name = internal_strdup(real_name);
const uptr idx = atomic_load(&loaded_count_, memory_order_relaxed);
code_ranges_[idx].begin = b;
code_ranges_[idx].end = e;
@@ -77,7 +90,7 @@ void LibIgnore::OnLibraryLoaded() {
}
void LibIgnore::OnLibraryUnloaded() {
- OnLibraryLoaded();
+ OnLibraryLoaded(0);
}
} // namespace __sanitizer
diff --git a/lib/sanitizer_common/sanitizer_libignore.h b/lib/sanitizer_common/sanitizer_libignore.h
index 4e6f5a97..8e1d584d 100644
--- a/lib/sanitizer_common/sanitizer_libignore.h
+++ b/lib/sanitizer_common/sanitizer_libignore.h
@@ -33,7 +33,7 @@ class LibIgnore {
void Init(const SuppressionContext &supp);
// Must be called after a new dynamic library is loaded.
- void OnLibraryLoaded();
+ void OnLibraryLoaded(const char *name);
// Must be called after a dynamic library is unloaded.
void OnLibraryUnloaded();
@@ -45,6 +45,7 @@ class LibIgnore {
struct Lib {
char *templ;
char *name;
+ char *real_name; // target of symlink
bool loaded;
};
diff --git a/lib/tsan/rtl/tsan_interceptors.cc b/lib/tsan/rtl/tsan_interceptors.cc
index 596664bd..e28b9d25 100644
--- a/lib/tsan/rtl/tsan_interceptors.cc
+++ b/lib/tsan/rtl/tsan_interceptors.cc
@@ -136,7 +136,7 @@ static LibIgnore *libignore() {
void InitializeLibIgnore() {
libignore()->Init(*GetSuppressionContext());
- libignore()->OnLibraryLoaded();
+ libignore()->OnLibraryLoaded(0);
}
} // namespace __tsan
@@ -263,7 +263,7 @@ TSAN_INTERCEPTOR(void*, dlopen, const char *filename, int flag) {
thr->in_rtl = 0;
void *res = REAL(dlopen)(filename, flag);
thr->in_rtl = 1;
- libignore()->OnLibraryLoaded();
+ libignore()->OnLibraryLoaded(filename);
return res;
}