Index: compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc =================================================================== --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc @@ -640,6 +640,10 @@ #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(getauxval(AT_EXECFN)); #endif GetArgsAndEnv(&argv, &envp); Index: compiler-rt/trunk/test/msan/Linux/reexec_unlimited_stack.cc =================================================================== --- compiler-rt/trunk/test/msan/Linux/reexec_unlimited_stack.cc +++ compiler-rt/trunk/test/msan/Linux/reexec_unlimited_stack.cc @@ -0,0 +1,23 @@ +// MSAN re-execs on unlimited stacks. We use that to verify ReExec() uses the +// right path. +// RUN: %clangxx_msan -O0 %s -o %t && ulimit -s unlimited && %run %t | FileCheck %s + +#include + +#if !defined(__GLIBC_PREREQ) +#define __GLIBC_PREREQ(a, b) 0 +#endif + +#if __GLIBC_PREREQ(2, 16) +#include +#endif + +int main() { +#if __GLIBC_PREREQ(2, 16) + // Make sure AT_EXECFN didn't get overwritten by re-exec. + puts(reinterpret_cast(getauxval(AT_EXECFN))); +#else + puts("No getauxval"); +#endif + // CHECK-NOT: /proc/self/exe +}