-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[sanitizer_common] Fix internal_*stat on Linux/sparc64 #101236
[sanitizer_common] Fix internal_*stat on Linux/sparc64 #101236
Conversation
``` 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 fcd6bd5)
…ux-specific fcd6bd5 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 16e9bb9)
@llvm/pr-subscribers-compiler-rt-sanitizer Author: Rainer Orth (rorth) ChangesBackport of fcd6bd5 and 16e9bb9 to Full diff: https://github.com/llvm/llvm-project/pull/101236.diff 1 Files Affected:
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
index 76acf591871ab..d1c50cbda7d7e 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_LINUX && (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,
|
We usually do cherry-picks this way https://llvm.org/docs/GitHub.html#backporting-fixes-to-the-release-branches |
I know, that's how I did it for the original PR. However, when it turned out 16e9bb9 was necessary too to unbreak the Solaris/sparcv9 build, I added a separate cherry pick just for that one. I guess I should just have closed the original PR and added a new cherry pick referring to both the base commit and the adjustment. |
This needs to be fixed due to conflicts with other merged changes @rorth |
Backport of fcd6bd5 and 16e9bb9 to
release/19.x
branch.