[sanitizer_common] Don't use syscall(SYS_clone) on Linux/sparc64 (#100534)
authorRainer Orth <ro@gcc.gnu.org>
Tue, 30 Jul 2024 06:57:25 +0000 (08:57 +0200)
committerTobias Hieta <tobias@hieta.se>
Sat, 10 Aug 2024 09:49:18 +0000 (11:49 +0200)
```
  SanitizerCommon-Unit :: ./Sanitizer-sparc-Test/SanitizerCommon/StartSubprocessTest
```
and every single test using the `llvm-symbolizer` `FAIL` on
Linux/sparc64 in a very weird way: when using `StartSubprocess`, there's
a call to `internal_fork`, but we never reach `internal_execve`.
`internal_fork` is implemented using `syscall(SYS_clone)`. The calling
convention of that syscall already varies considerably between targets,
but as documented in `clone(2)`, SPARC again is widely different.
Instead of trying to match `glibc` here, this patch just calls `__fork`.

Tested on `sparc64-unknown-linux-gnu` and `x86_64-pc-linux-gnu`.

(cherry picked from commit 1c53b907bd6348138a59da270836fc9b4c161a07)

compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp

index 1d6a55bdb7f3850d160ca408c40bc6b2c01771df..50e41da68d959ab4e522415a1ac58e383b65d5ee 100644 (file)
@@ -826,10 +826,16 @@ uptr internal_sigaltstack(const void *ss, void *oss) {
   return internal_syscall(SYSCALL(sigaltstack), (uptr)ss, (uptr)oss);
 }
 
+extern "C" pid_t __fork(void);
+
 int internal_fork() {
 #    if SANITIZER_LINUX
 #      if SANITIZER_S390
   return internal_syscall(SYSCALL(clone), 0, SIGCHLD);
+#      elif SANITIZER_SPARC
+  // The clone syscall interface on SPARC differs massively from the rest,
+  // so fall back to __fork.
+  return __fork();
 #      else
   return internal_syscall(SYSCALL(clone), SIGCHLD, 0);
 #      endif