diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp @@ -607,8 +607,15 @@ if (&__libc_stack_end) { #endif // !SANITIZER_GO uptr* stack_end = (uptr*)__libc_stack_end; - int argc = *stack_end; *argv = (char**)(stack_end + 1); + // Normally argc can be obtained from *__libc_stack_end, however, on ARM + // glibc's _start clobbers it: + // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/arm/start.S;hb=refs/heads/release/2.31/master#l75 + // Do not special-case ARM, but rather use a common solution everywhere: + // infer argc from argv. + int argc = 0; + while (stack_end[argc + 1]) + argc++; *envp = (char**)(stack_end + argc + 2); #if !SANITIZER_GO } else {