summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2017-06-01 01:46:15 (GMT)
committerRich Felker <dalias@aerifal.cx>2017-06-01 01:46:15 (GMT)
commit4073f03add269be8be9f84d374fe69920b78d53d (patch)
tree2ba122ca766f4288b9a08cfbe7e6628637f8f3ec
parent81f4a1200a58a84c83e73da645d4f226a8785bdf (diff)
downloadmusl-4073f03add269be8be9f84d374fe69920b78d53d.tar.gz
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.
-rw-r--r--arch/mips64/syscall_arch.h25
1 files changed, 22 insertions, 3 deletions
diff --git a/arch/mips64/syscall_arch.h b/arch/mips64/syscall_arch.h
index 1bd6c18..bb73dc3 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;
}