summaryrefslogtreecommitdiff
path: root/lib/asan/asan_mac.cc
diff options
context:
space:
mode:
authorAlexander Potapenko <glider@google.com>2012-08-24 09:22:05 +0000
committerAlexander Potapenko <glider@google.com>2012-08-24 09:22:05 +0000
commiteb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3 (patch)
tree40f52671a2bdfb021c1ea0de850820cbde74a27c /lib/asan/asan_mac.cc
parent1e2525d0ec9ac64e583b57316ea30cecce591fb1 (diff)
downloadcompiler-rt-eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3.tar.gz
compiler-rt-eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3.tar.bz2
compiler-rt-eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3.tar.xz
If the program is linked to a dynamic ASan runtime which is not present in DYLD_INSERT_LIBRARIES
(which, in turn, is required for our interceptors to take effect), re-exec the program with DYLD_INSERT_LIBRARIES set. git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@162547 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/asan/asan_mac.cc')
-rw-r--r--lib/asan/asan_mac.cc39
1 files changed, 38 insertions, 1 deletions
diff --git a/lib/asan/asan_mac.cc b/lib/asan/asan_mac.cc
index 8e8b6649..4a5b6ecf 100644
--- a/lib/asan/asan_mac.cc
+++ b/lib/asan/asan_mac.cc
@@ -23,7 +23,8 @@
#include "asan_thread_registry.h"
#include "sanitizer_common/sanitizer_libc.h"
-#include <crt_externs.h> // for _NSGetEnviron
+#include <crt_externs.h> // for _NSGetArgv
+#include <dlfcn.h> // for dladdr()
#include <mach-o/dyld.h>
#include <mach-o/loader.h>
#include <sys/mman.h>
@@ -83,6 +84,42 @@ bool PlatformHasDifferentMemcpyAndMemmove() {
return GetMacosVersion() == MACOS_VERSION_SNOW_LEOPARD;
}
+extern "C"
+void __asan_init();
+
+static const char kDyldInsertLibraries[] = "DYLD_INSERT_LIBRARIES";
+
+void MaybeReexec() {
+ if (!flags()->allow_reexec) return;
+#if MAC_INTERPOSE_FUNCTIONS
+ // If the program is linked with the dynamic ASan runtime library, make sure
+ // the library is preloaded so that the wrappers work. If it is not, set
+ // DYLD_INSERT_LIBRARIES and re-exec ourselves.
+ Dl_info info;
+ int result = dladdr((void*)__asan_init, &info);
+ const char *dyld_insert_libraries = GetEnv(kDyldInsertLibraries);
+ if (!dyld_insert_libraries ||
+ !REAL(strstr)(dyld_insert_libraries, info.dli_fname)) {
+ // DYLD_INSERT_LIBRARIES is not set or does not contain the runtime
+ // library.
+ char program_name[1024];
+ uint32_t buf_size = sizeof(program_name);
+ _NSGetExecutablePath(program_name, &buf_size);
+ // Ok to use setenv() since the wrappers don't depend on the value of
+ // asan_inited.
+ setenv(kDyldInsertLibraries, info.dli_fname, /*overwrite*/0);
+ if (flags()->verbosity >= 1) {
+ Report("exec()-ing the program with\n");
+ Report("%s=%s\n", kDyldInsertLibraries, info.dli_fname);
+ Report("to enable ASan wrappers.\n");
+ Report("Set ASAN_OPTIONS=allow_reexec=0 to disable this.\n");
+ }
+ execv(program_name, *_NSGetArgv());
+ }
+#endif // MAC_INTERPOSE_FUNCTIONS
+ // If we're not using the dynamic runtime, do nothing.
+}
+
// No-op. Mac does not support static linkage anyway.
void *AsanDoesNotSupportStaticLinkage() {
return 0;