diff options
Diffstat (limited to 'compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc')
-rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc index 7859557c82d..84da23e3fad 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc @@ -23,6 +23,7 @@ #include "sanitizer_file.h" #include "sanitizer_flags.h" #include "sanitizer_freebsd.h" +#include "sanitizer_getauxval.h" #include "sanitizer_linux.h" #include "sanitizer_placement_new.h" #include "sanitizer_procmaps.h" @@ -806,6 +807,40 @@ u64 MonotonicNanoTime() { } #endif // SANITIZER_LINUX && !SANITIZER_GO +#if !SANITIZER_OPENBSD +void ReExec() { + const char *pathname = "/proc/self/exe"; + +#if SANITIZER_NETBSD + static const int name[] = { + CTL_KERN, + KERN_PROC_ARGS, + -1, + KERN_PROC_PATHNAME, + }; + char path[400]; + uptr len; + + len = sizeof(path); + if (internal_sysctl(name, ARRAY_SIZE(name), path, &len, NULL, 0) != -1) + pathname = path; +#elif SANITIZER_SOLARIS + pathname = getexecname(); + CHECK_NE(pathname, NULL); +#elif SANITIZER_USE_GETAUXVAL + // Calling execve with /proc/self/exe sets that as $EXEC_ORIGIN. Binaries that + // rely on that will fail to load shared libraries. Query AT_EXECFN instead. + pathname = reinterpret_cast<const char *>(getauxval(AT_EXECFN)); +#endif + + uptr rv = internal_execve(pathname, GetArgv(), GetEnviron()); + int rverrno; + CHECK_EQ(internal_iserror(rv, &rverrno), true); + Printf("execve failed, errno %d\n", rverrno); + Die(); +} +#endif // !SANITIZER_OPENBSD + } // namespace __sanitizer #endif |