diff options
author | Rich Felker <dalias@aerifal.cx> | 2017-05-31 21:46:15 -0400 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2017-05-31 21:46:15 -0400 |
commit | 4073f03add269be8be9f84d374fe69920b78d53d (patch) | |
tree | 2ba122ca766f4288b9a08cfbe7e6628637f8f3ec /arch | |
parent | 81f4a1200a58a84c83e73da645d4f226a8785bdf (diff) | |
download | musl-4073f03add269be8be9f84d374fe69920b78d53d.tar.gz musl-4073f03add269be8be9f84d374fe69920b78d53d.tar.bz2 musl-4073f03add269be8be9f84d374fe69920b78d53d.tar.xz musl-4073f03add269be8be9f84d374fe69920b78d53d.zip |
fix fstatat syscall on mips64
mips64 requires 'struct stat' conversion due to incorrect 32-bit
fields where time_t should be in the kernel version of the structure.
syscall_arch.h already performed the correct translation for stat,
fstat, and lstat syscalls, but omitted special handling for fstatat.
Diffstat (limited to 'arch')
-rw-r--r-- | arch/mips64/syscall_arch.h | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/arch/mips64/syscall_arch.h b/arch/mips64/syscall_arch.h index 1bd6c18f..bb73dc3c 100644 --- a/arch/mips64/syscall_arch.h +++ b/arch/mips64/syscall_arch.h @@ -149,13 +149,15 @@ static inline long __syscall4(long n, long a, long b, long c, long d) register long r7 __asm__("$7"); register long r2 __asm__("$2"); + r4 = a; r5 = b; + r6 = c; + r7 = d; if (n == SYS_stat || n == SYS_fstat || n == SYS_lstat) r5 = (long) &kst; + if (n == SYS_newfstatat) + r6 = (long) &kst; - r4 = a; - r6 = c; - r7 = d; __asm__ __volatile__ ( "daddu $2,$0,%2 ; syscall" : "=&r"(r2), "=r"(r7) : "ir"(n), "0"(r2), "1"(r7), @@ -168,6 +170,8 @@ static inline long __syscall4(long n, long a, long b, long c, long d) if (n == SYS_stat || n == SYS_fstat || n == SYS_lstat) __stat_fix(&kst, (struct stat *)b); + if (n == SYS_newfstatat) + __stat_fix(&kst, (struct stat *)c); return ret; } @@ -224,16 +228,21 @@ static inline long __syscall4(long n, long a, long b, long c, long d) { long r2; long old_b = b; + long old_c = c; struct kernel_stat kst; if (n == SYS_stat || n == SYS_fstat || n == SYS_lstat) b = (long) &kst; + if (n == SYS_newfstatat) + c = (long) &kst; r2 = (__syscall)(n, a, b, c, d); if (r2 > -4096UL) return r2; if (n == SYS_stat || n == SYS_fstat || n == SYS_lstat) __stat_fix(&kst, (struct stat *)old_b); + if (n == SYS_newfstatat) + __stat_fix(&kst, (struct stat *)old_c); return r2; } @@ -244,16 +253,21 @@ static inline long __syscall5(long n, long a, long b, long c, long d, long e) { long r2; long old_b = b; + long old_c = c; struct kernel_stat kst; if (n == SYS_stat || n == SYS_fstat || n == SYS_lstat) b = (long) &kst; + if (n == SYS_newfstatat) + c = (long) &kst; r2 = (__syscall)(n, a, b, c, d, e); if (r2 > -4096UL) return r2; if (n == SYS_stat || n == SYS_fstat || n == SYS_lstat) __stat_fix(&kst, (struct stat *)old_b); + if (n == SYS_newfstatat) + __stat_fix(&kst, (struct stat *)old_c); return r2; } @@ -262,16 +276,21 @@ static inline long __syscall6(long n, long a, long b, long c, long d, long e, lo { long r2; long old_b = b; + long old_c = c; struct kernel_stat kst; if (n == SYS_stat || n == SYS_fstat || n == SYS_lstat) b = (long) &kst; + if (n == SYS_newfstatat) + c = (long) &kst; r2 = (__syscall)(n, a, b, c, d, e, f); if (r2 > -4096UL) return r2; if (n == SYS_stat || n == SYS_fstat || n == SYS_lstat) __stat_fix(&kst, (struct stat *)old_b); + if (n == SYS_newfstatat) + __stat_fix(&kst, (struct stat *)old_c); return r2; } |