提交 4073f03a 编写于 作者: R Rich Felker

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.
上级 81f4a120
...@@ -149,13 +149,15 @@ static inline long __syscall4(long n, long a, long b, long c, long d) ...@@ -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 r7 __asm__("$7");
register long r2 __asm__("$2"); register long r2 __asm__("$2");
r4 = a;
r5 = b; r5 = b;
r6 = c;
r7 = d;
if (n == SYS_stat || n == SYS_fstat || n == SYS_lstat) if (n == SYS_stat || n == SYS_fstat || n == SYS_lstat)
r5 = (long) &kst; r5 = (long) &kst;
if (n == SYS_newfstatat)
r6 = (long) &kst;
r4 = a;
r6 = c;
r7 = d;
__asm__ __volatile__ ( __asm__ __volatile__ (
"daddu $2,$0,%2 ; syscall" "daddu $2,$0,%2 ; syscall"
: "=&r"(r2), "=r"(r7) : "ir"(n), "0"(r2), "1"(r7), : "=&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) ...@@ -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) if (n == SYS_stat || n == SYS_fstat || n == SYS_lstat)
__stat_fix(&kst, (struct stat *)b); __stat_fix(&kst, (struct stat *)b);
if (n == SYS_newfstatat)
__stat_fix(&kst, (struct stat *)c);
return ret; return ret;
} }
...@@ -224,16 +228,21 @@ static inline long __syscall4(long n, long a, long b, long c, long d) ...@@ -224,16 +228,21 @@ static inline long __syscall4(long n, long a, long b, long c, long d)
{ {
long r2; long r2;
long old_b = b; long old_b = b;
long old_c = c;
struct kernel_stat kst; struct kernel_stat kst;
if (n == SYS_stat || n == SYS_fstat || n == SYS_lstat) if (n == SYS_stat || n == SYS_fstat || n == SYS_lstat)
b = (long) &kst; b = (long) &kst;
if (n == SYS_newfstatat)
c = (long) &kst;
r2 = (__syscall)(n, a, b, c, d); r2 = (__syscall)(n, a, b, c, d);
if (r2 > -4096UL) return r2; if (r2 > -4096UL) return r2;
if (n == SYS_stat || n == SYS_fstat || n == SYS_lstat) if (n == SYS_stat || n == SYS_fstat || n == SYS_lstat)
__stat_fix(&kst, (struct stat *)old_b); __stat_fix(&kst, (struct stat *)old_b);
if (n == SYS_newfstatat)
__stat_fix(&kst, (struct stat *)old_c);
return r2; return r2;
} }
...@@ -244,16 +253,21 @@ static inline long __syscall5(long n, long a, long b, long c, long d, long e) ...@@ -244,16 +253,21 @@ static inline long __syscall5(long n, long a, long b, long c, long d, long e)
{ {
long r2; long r2;
long old_b = b; long old_b = b;
long old_c = c;
struct kernel_stat kst; struct kernel_stat kst;
if (n == SYS_stat || n == SYS_fstat || n == SYS_lstat) if (n == SYS_stat || n == SYS_fstat || n == SYS_lstat)
b = (long) &kst; b = (long) &kst;
if (n == SYS_newfstatat)
c = (long) &kst;
r2 = (__syscall)(n, a, b, c, d, e); r2 = (__syscall)(n, a, b, c, d, e);
if (r2 > -4096UL) return r2; if (r2 > -4096UL) return r2;
if (n == SYS_stat || n == SYS_fstat || n == SYS_lstat) if (n == SYS_stat || n == SYS_fstat || n == SYS_lstat)
__stat_fix(&kst, (struct stat *)old_b); __stat_fix(&kst, (struct stat *)old_b);
if (n == SYS_newfstatat)
__stat_fix(&kst, (struct stat *)old_c);
return r2; return r2;
} }
...@@ -262,16 +276,21 @@ static inline long __syscall6(long n, long a, long b, long c, long d, long e, lo ...@@ -262,16 +276,21 @@ static inline long __syscall6(long n, long a, long b, long c, long d, long e, lo
{ {
long r2; long r2;
long old_b = b; long old_b = b;
long old_c = c;
struct kernel_stat kst; struct kernel_stat kst;
if (n == SYS_stat || n == SYS_fstat || n == SYS_lstat) if (n == SYS_stat || n == SYS_fstat || n == SYS_lstat)
b = (long) &kst; b = (long) &kst;
if (n == SYS_newfstatat)
c = (long) &kst;
r2 = (__syscall)(n, a, b, c, d, e, f); r2 = (__syscall)(n, a, b, c, d, e, f);
if (r2 > -4096UL) return r2; if (r2 > -4096UL) return r2;
if (n == SYS_stat || n == SYS_fstat || n == SYS_lstat) if (n == SYS_stat || n == SYS_fstat || n == SYS_lstat)
__stat_fix(&kst, (struct stat *)old_b); __stat_fix(&kst, (struct stat *)old_b);
if (n == SYS_newfstatat)
__stat_fix(&kst, (struct stat *)old_c);
return r2; return r2;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册