2004-07-07 David S. Miller <davem@nuts.davemloft.net>
* linux/sparc/syscallent.h: Sync with reality.
* linux/sparc/syscall.h (sys_sendfile64, sys_futex, sys_gettid,
sys_sched_setaffinity, sys_sched_getaffinity, sys_setxattr,
sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr,
sys_fgetxattr, sys_listxattr, sys_llistxattr, sys_flistxattr,
sys_removexattr, sys_lremovexattr, sys_fremovexattr,
sys_remap_file_pages, sys_readahead, sys_tgkill, sys_statfs64,
sys_fstatfs64, sys_clock_settime, sys_clock_gettime,
sys_clock_getres, sys_clock_nanosleep, sys_timer_create,
sys_timer_settime, sys_timer_gettime): New declarations.
* linux/sparc64/dummy2.h, linux/sparc64/syscallent2.h,
linux/sparc64/syscall.h, linux/sparc64/errnoent.h,
linux/sparc64/errnoent1.h, linux/sparc64/errnoent2.h,
linux/sparc64/ioctlent.h, linux/sparc64/ioctlent1.h,
linux/sparc64/ioctlent2.h, linux/sparc64/signalent.h,
linux/sparc64/signalent.h, linux/sparc64/signalent.h,
linux/sparc64/signalent1.h, linux/sparc64/signalent2.h,
linux/sparc64/syscall1.h, linux/sparc64/syscallent.h,
linux/sparc64/syscallent1.h: New files.
* defs.h (LINUXSPARC): Define also when SPARC64.
(LINUX && SPARC64): Set SUPPORTED_PERSONALITIES to 3.
Ignore SIGTRAP after execve by defining TCB_WAITEXECVE.
Define possibly missing __NR_exit_group. Declare getrval2.
* configure.ac (sparc64): New architecture case.
* config.h.in (SPARC64): New define.
* file.c (stat_sparc64): New structure.
(printstat_sparc64): New output routine for that.
(printstat): Call it, if personality is 2.
(printstat64): Likewise.
* util.c: Conditionalize ptrace defines on LINUXSPARC
not LINUX && SPARC.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(_hack_syscall5): Correct trap number when SPARC64.
(PTRACE_WRITE{TEXT,DATA}): Add SPARC64 to ifdef guard.
(getpc): Handle SPARC64 && LINUX.
(printcall): Likewise.
(arg fetching/setting): Use same code for SPARC64 LINUX
as for SPARC.
(setbpt): Handle SPARC64 && LINUX.
(clearbpt): Likewise.
* signal.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(m_siginfo): Use same definition on SPARC64 as SPARC.
(sys_sigreturn): Handle LINUX && SPARC64.
* syscall.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(getscno): Use same static state on SPARC64 as SPARC,
and add SPARC64 handling.
(get_error): Handle LINUX && SPARC64.
(force_result): Likewise.
(syscall_enter): Likewise.
(trace_syscall): Handle sys_socketcall and sys_ipc on SPARC64
just like SPARC.
(getrval2): Handle LINUX && SPARC64.
* process.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(change_syscall): Handle LINUX && SPARC64.
(struct_user_offsets): Ifdef out those which do not exist
on SPARC64.
* net.c (sys_pipe): Handle LINUX && SPARC64.
* ioctl.c: Fix initializer typo for nioctlents2, was
nioctlents1 by accident.
diff --git a/syscall.c b/syscall.c
index 4264a80..b6d526d 100644
--- a/syscall.c
+++ b/syscall.c
@@ -43,13 +43,13 @@
#include <sys/param.h>
#if HAVE_ASM_REG_H
-#ifdef SPARC
+#if defined (SPARC) || defined (SPARC64)
# define fpq kernel_fpq
# define fq kernel_fq
# define fpu kernel_fpu
#endif
#include <asm/reg.h>
-#ifdef SPARC
+#if defined (SPARC) || defined (SPARC64)
# undef fpq
# undef fq
# undef fpu
@@ -74,6 +74,14 @@
# undef pt_all_user_regs
#endif
+#if defined (LINUX) && defined (SPARC64)
+# define r_pc r_tpc
+# undef PTRACE_GETREGS
+# define PTRACE_GETREGS PTRACE_GETREGS64
+# undef PTRACE_SETREGS
+# define PTRACE_SETREGS PTRACE_SETREGS64
+#endif /* LINUX && SPARC64 */
+
#if defined(LINUX) && defined(IA64)
# include <asm/ptrace_offsets.h>
# include <asm/rse.h>
@@ -715,7 +723,7 @@
#elif defined (ALPHA)
static long r0;
static long a3;
-#elif defined (SPARC)
+#elif defined (SPARC) || defined (SPARC64)
static struct regs regs;
static unsigned long trap;
#elif defined(MIPS)
@@ -1062,7 +1070,7 @@
if (upeek(pid, REG_R0, &r0) < 0)
return -1;
}
-#elif defined (SPARC)
+#elif defined (SPARC) || defined (SPARC64)
/* Everything we need is in the current register set. */
if (ptrace(PTRACE_GETREGS,pid,(char *)®s,0) < 0)
return -1;
@@ -1072,6 +1080,9 @@
/* Retrieve the syscall trap instruction. */
errno = 0;
trap = ptrace(PTRACE_PEEKTEXT,pid,(char *)regs.r_pc,0);
+#if defined(SPARC64)
+ trap >>= 32;
+#endif
if (errno)
return -1;
@@ -1083,8 +1094,8 @@
break;
case 0x91d0206d:
/* Linux/SPARC64 syscall trap. */
- fprintf(stderr,"syscall: Linux/SPARC64 not supported yet\n");
- return -1;
+ set_personality(2);
+ break;
case 0x91d02000:
/* SunOS syscall trap. (pers 1) */
fprintf(stderr,"syscall: SunOS no support\n");
@@ -1107,7 +1118,11 @@
tcp->flags &= ~TCB_WAITEXECVE;
return 0;
}
+#if defined (SPARC64)
+ fprintf(stderr,"syscall: unknown syscall trap %08lx %016lx\n", trap, regs.r_tpc);
+#else
fprintf(stderr,"syscall: unknown syscall trap %08x %08x\n", trap, regs.r_pc);
+#endif
return -1;
}
@@ -1478,6 +1493,16 @@
u_error = 0;
}
#else /* !SPARC */
+#ifdef SPARC64
+ if (regs.r_tstate & 0x1100000000UL) {
+ tcp->u_rval = -1;
+ u_error = regs.r_o0;
+ }
+ else {
+ tcp->u_rval = regs.r_o0;
+ u_error = 0;
+ }
+#else /* !SPARC64 */
#ifdef HPPA
if (r28 && (unsigned) -r28 < nerrnos) {
tcp->u_rval = -1;
@@ -1513,6 +1538,7 @@
#endif /* SH */
#endif /* HPPA */
#endif /* SPARC */
+#endif /* SPARC64 */
#endif /* ALPHA */
#endif /* ARM */
#endif /* M68K */
@@ -1705,6 +1731,20 @@
if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0)
return -1;
#else /* !SPARC */
+#ifdef SPARC64
+ if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0)
+ return -1;
+ if (error) {
+ regs.r_tstate |= 0x1100000000UL;
+ regs.r_o0 = error;
+ }
+ else {
+ regs.r_tstate &= ~0x1100000000UL;
+ regs.r_o0 = rval;
+ }
+ if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0)
+ return -1;
+#else /* !SPARC64 */
#ifdef HPPA
r28 = error ? -error : rval;
if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR28), r28) < 0)
@@ -1723,6 +1763,7 @@
#endif /* SH */
#endif /* HPPA */
#endif /* SPARC */
+#endif /* SPARC64 */
#endif /* ALPHA */
#endif /* ARM */
#endif /* M68K */
@@ -1901,7 +1942,7 @@
return -1;
}
}
-#elif defined (SPARC)
+#elif defined (SPARC) || defined (SPARC64)
{
int i;
@@ -2285,7 +2326,7 @@
switch (tcp->scno + NR_SYSCALL_BASE) {
#ifdef LINUX
-#if !defined (ALPHA) && !defined(SPARC) && !defined(MIPS) && !defined(HPPA) && !defined(X86_64)
+#if !defined (ALPHA) && !defined(SPARC) && !defined(SPARC64) && !defined(MIPS) && !defined(HPPA) && !defined(X86_64)
case SYS_socketcall:
decode_subcall(tcp, SYS_socket_subcall,
SYS_socket_nsubcalls, deref_style);
@@ -2294,8 +2335,8 @@
decode_subcall(tcp, SYS_ipc_subcall,
SYS_ipc_nsubcalls, shift_style);
break;
-#endif /* !ALPHA && !MIPS && !SPARC && !HPPA && !X86_64 */
-#ifdef SPARC
+#endif /* !ALPHA && !MIPS && !SPARC && !SPARC64 && !HPPA && !X86_64 */
+#if defined (SPARC) || defined (SPARC64)
case SYS_socketcall:
sparc_socket_decode (tcp);
break;
@@ -2435,7 +2476,7 @@
long val = -1;
#ifdef LINUX
-#ifdef SPARC
+#if defined (SPARC) || defined (SPARC64)
struct regs regs;
if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)®s,0) < 0)
return -1;
@@ -2443,7 +2484,7 @@
#elif defined(SH)
if (upeek(tcp->pid, 4*(REG_REG0+1), &val) < 0)
return -1;
-#endif /* SPARC */
+#endif /* SPARC || SPARC64 */
#elif defined(IA64)
if (upeek(tcp->pid, PT_R9, &val) < 0)
return -1;