https://github.com/rorth created https://github.com/llvm/llvm-project/pull/101236
Backport of fcd6bd5587cc376cd8f43b60d1c7d61fdfe0f535 and 16e9bb9cd7f50ae2ec7f29a80bc3b95f528bfdbf to `release/19.x` branch. >From 7d97041c217bcb4b04cacb3a5d17285f8b241a88 Mon Sep 17 00:00:00 2001 From: Rainer Orth <r...@gcc.gnu.org> Date: Tue, 30 Jul 2024 09:03:00 +0200 Subject: [PATCH 1/2] [sanitizer_common] Fix internal_*stat on Linux/sparc64 (#101012) ``` SanitizerCommon-Unit :: ./Sanitizer-sparcv9-Test/SanitizerCommon/FileOps ``` `FAIL`s on 64-bit Linux/sparc64: ``` projects/compiler-rt/lib/sanitizer_common/tests/./Sanitizer-sparcv9-Test --gtest_filter=SanitizerCommon.FileOps -- compiler-rt/lib/sanitizer_common/tests/sanitizer_libc_test.cpp:144: Failure Expected equality of these values: len1 + len2 Which is: 10 fsize Which is: 1721875535 ``` The issue is similar to the mips64 case: the Linux/sparc64 `*stat` syscalls take a `struct kernel_stat64 *` arg. Also the syscalls actually used differ. This patch handles this, adopting the mips64 code to avoid too much duplication. Tested on `sparc64-unknown-linux-gnu` and `x86_64-pc-linux-gnu`. (cherry picked from commit fcd6bd5587cc376cd8f43b60d1c7d61fdfe0f535) --- .../lib/sanitizer_common/sanitizer_linux.cpp | 41 +++++++++++++++---- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp index 76acf591871ab..09f58b7ced2e9 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp @@ -33,11 +33,15 @@ // For mips64, syscall(__NR_stat) fills the buffer in the 'struct kernel_stat' // format. Struct kernel_stat is defined as 'struct stat' in asm/stat.h. To // access stat from asm/stat.h, without conflicting with definition in -// sys/stat.h, we use this trick. -# if SANITIZER_MIPS64 +// sys/stat.h, we use this trick. sparc64 is similar, using +// syscall(__NR_stat64) and struct kernel_stat64. +# if SANITIZER_MIPS64 || SANITIZER_SPARC64 # include <asm/unistd.h> # include <sys/types.h> # define stat kernel_stat +# if SANITIZER_SPARC64 +# define stat64 kernel_stat64 +# endif # if SANITIZER_GO # undef st_atime # undef st_mtime @@ -48,6 +52,7 @@ # endif # include <asm/stat.h> # undef stat +# undef stat64 # endif # include <dlfcn.h> @@ -285,8 +290,7 @@ uptr internal_ftruncate(fd_t fd, uptr size) { return res; } -# if (!SANITIZER_LINUX_USES_64BIT_SYSCALLS || SANITIZER_SPARC) && \ - SANITIZER_LINUX +# if !SANITIZER_LINUX_USES_64BIT_SYSCALLS && SANITIZER_LINUX static void stat64_to_stat(struct stat64 *in, struct stat *out) { internal_memset(out, 0, sizeof(*out)); out->st_dev = in->st_dev; @@ -327,7 +331,12 @@ static void statx_to_stat(struct statx *in, struct stat *out) { } # endif -# if SANITIZER_MIPS64 +# if SANITIZER_MIPS64 || SANITIZER_SPARC64 +# if SANITIZER_MIPS64 +typedef struct kernel_stat kstat_t; +# else +typedef struct kernel_stat64 kstat_t; +# endif // Undefine compatibility macros from <sys/stat.h> // so that they would not clash with the kernel_stat // st_[a|m|c]time fields @@ -345,7 +354,7 @@ static void statx_to_stat(struct statx *in, struct stat *out) { # undef st_mtime_nsec # undef st_ctime_nsec # endif -static void kernel_stat_to_stat(struct kernel_stat *in, struct stat *out) { +static void kernel_stat_to_stat(kstat_t *in, struct stat *out) { internal_memset(out, 0, sizeof(*out)); out->st_dev = in->st_dev; out->st_ino = in->st_ino; @@ -391,6 +400,12 @@ uptr internal_stat(const char *path, void *buf) { !SANITIZER_SPARC return internal_syscall(SYSCALL(newfstatat), AT_FDCWD, (uptr)path, (uptr)buf, 0); +# elif SANITIZER_SPARC64 + kstat_t buf64; + int res = internal_syscall(SYSCALL(fstatat64), AT_FDCWD, (uptr)path, + (uptr)&buf64, 0); + kernel_stat_to_stat(&buf64, (struct stat *)buf); + return res; # else struct stat64 buf64; int res = internal_syscall(SYSCALL(fstatat64), AT_FDCWD, (uptr)path, @@ -423,6 +438,12 @@ uptr internal_lstat(const char *path, void *buf) { !SANITIZER_SPARC return internal_syscall(SYSCALL(newfstatat), AT_FDCWD, (uptr)path, (uptr)buf, AT_SYMLINK_NOFOLLOW); +# elif SANITIZER_SPARC64 + kstat_t buf64; + int res = internal_syscall(SYSCALL(fstatat64), AT_FDCWD, (uptr)path, + (uptr)&buf64, AT_SYMLINK_NOFOLLOW); + kernel_stat_to_stat(&buf64, (struct stat *)buf); + return res; # else struct stat64 buf64; int res = internal_syscall(SYSCALL(fstatat64), AT_FDCWD, (uptr)path, @@ -442,10 +463,16 @@ uptr internal_fstat(fd_t fd, void *buf) { # if SANITIZER_FREEBSD || SANITIZER_LINUX_USES_64BIT_SYSCALLS # if SANITIZER_MIPS64 // For mips64, fstat syscall fills buffer in the format of kernel_stat - struct kernel_stat kbuf; + kstat_t kbuf; int res = internal_syscall(SYSCALL(fstat), fd, &kbuf); kernel_stat_to_stat(&kbuf, (struct stat *)buf); return res; +# elif SANITIZER_LINUX && SANITIZER_SPARC64 + // For sparc64, fstat64 syscall fills buffer in the format of kernel_stat64 + kstat_t kbuf; + int res = internal_syscall(SYSCALL(fstat64), fd, &kbuf); + kernel_stat_to_stat(&kbuf, (struct stat *)buf); + return res; # elif SANITIZER_LINUX && defined(__loongarch__) struct statx bufx; int res = internal_syscall(SYSCALL(statx), fd, "", AT_EMPTY_PATH, >From 079c97a91b3b134c746d1aa02db90ef3357998d6 Mon Sep 17 00:00:00 2001 From: Rainer Orth <r...@gcc.gnu.org> Date: Tue, 30 Jul 2024 10:06:45 +0200 Subject: [PATCH 2/2] [sanitizer_common] Make sanitizer_linux.cpp kernel_stat* handling Linux-specific fcd6bd5587cc376cd8f43b60d1c7d61fdfe0f535 broke the Solaris/sparcv9 buildbot: ``` compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp:39:14: fatal error: 'asm/unistd.h' file not found 39 | # include <asm/unistd.h> | ^~~~~~~~~~~~~~ ``` That section should have been Linux-specific in the first place, which is what this patch does. Tested on sparcv9-sun-solaris2.11. (cherry picked from commit 16e9bb9cd7f50ae2ec7f29a80bc3b95f528bfdbf) --- compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp index 09f58b7ced2e9..d1c50cbda7d7e 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp @@ -35,7 +35,7 @@ // access stat from asm/stat.h, without conflicting with definition in // sys/stat.h, we use this trick. sparc64 is similar, using // syscall(__NR_stat64) and struct kernel_stat64. -# if SANITIZER_MIPS64 || SANITIZER_SPARC64 +# if SANITIZER_LINUX && (SANITIZER_MIPS64 || SANITIZER_SPARC64) # include <asm/unistd.h> # include <sys/types.h> # define stat kernel_stat _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits