2003-06-02 Roland McGrath <roland@redhat.com>

* configure.ac, defs.h, mem.c, process.c, sock.c, syscall.c, util.c:
	Merged in SHmedia port from Stephen Thomas <stephen.thomas@superh.com>.
This commit is contained in:
Roland McGrath 2003-06-02 19:18:58 +00:00
parent d0835361d6
commit e1e584b8fa
7 changed files with 282 additions and 8 deletions

View File

@ -91,6 +91,10 @@ sh)
arch=sh
AC_DEFINE([SH], 1, [Define for the SH architecture.])
;;
shmedia)
arch=shmedia
AC_DEFINE([SHMEDIA], 1, [Define for the SHmedia architecture.])
;;
x86?64*)
arch=x86_64
AC_DEFINE([X86_64], 1, [Define for the AMD x86-64 architecture.])

18
defs.h
View File

@ -170,6 +170,22 @@ extern int ptrace();
# define PT_IAOQ0 (106*4)
# define PT_IAOQ1 (107*4)
#endif /* HPPA */
#ifdef SHMEDIA
/* SHmedia Linux - this code assumes the following kernel API for system calls:
PC Offset 0
System Call Offset 16 (actually, (syscall no.) | (0x1n << 16),
where n = no. of parameters.
Other regs Offset 24+
On entry: R2-7 = parameters 1-6 (as many as necessary)
On return: R9 = result. */
/* Offset for peeks of registers */
# define REG_OFFSET (24)
# define REG_GENERAL(x) (8*(x)+REG_OFFSET)
# define REG_PC (0*8)
# define REG_SYSCALL (2*8)
#endif /* SHMEDIA */
#endif /* LINUX */
#define SUPPORTED_PERSONALITIES 1
@ -302,7 +318,7 @@ struct tcb {
#define TCB_FOLLOWFORK 00400 /* Process should have forks followed */
#define TCB_REPRINT 01000 /* We should reprint this syscall on exit */
#ifdef LINUX
# if defined(ALPHA) || defined(SPARC) || defined(POWERPC) || defined(IA64) || defined(HPPA) || defined(SH) || defined(S390) || defined(S390X)
# if defined(ALPHA) || defined(SPARC) || defined(POWERPC) || defined(IA64) || defined(HPPA) || defined(SH) || defined(SHMEDIA) || defined(S390) || defined(S390X)
# define TCB_WAITEXECVE 02000 /* ignore SIGTRAP after exceve */
# endif
# define TCB_CLONE_DETACHED 04000 /* CLONE_DETACHED set in creating syscall */

16
mem.c
View File

@ -3,6 +3,8 @@
* Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
* Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
* Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
* Copyright (c) 2000 PocketPenguins Inc. Linux for Hitachi SuperH
* port by Greg Banks <gbanks@pocketpenguins.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -40,6 +42,9 @@
#if defined(LINUX) && defined(I386)
#include <asm/ldt.h>
#endif
#if defined(LINUX) && defined(SHMEDIA)
#include <asm/page.h> /* for PAGE_SHIFT */
#endif
#ifdef HAVE_LONG_LONG_OFF_T
/*
@ -222,7 +227,7 @@ struct tcb *tcp;
return 0;
else
u_arg[i] = v;
#elif defined(SH)
#elif defined(SH) || defined(SHMEDIA)
/* SH has always passed the args in registers */
int i;
for (i=0; i<6; i++)
@ -240,6 +245,15 @@ int
sys_mmap(tcp)
struct tcb *tcp;
{
#if defined(LINUX) && defined(SHMEDIA)
/*
* Old mmap differs from new mmap in specifying the
* offset in units of bytes rather than pages. We
* pretend it's in byte units so the user only ever
* sees bytes in the printout.
*/
tcp->u_arg[5] <<= PAGE_SHIFT;
#endif
return print_mmap(tcp, tcp->u_arg);
}
#endif /* !HAVE_LONG_LONG_OFF_T */

166
process.c
View File

@ -663,6 +663,13 @@ int new;
if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*(REG_REG0+3)), new)<0)
return -1;
return 0;
#elif defined(SHMEDIA)
/* Top half of reg encodes the no. of args n as 0x1n.
Assume 0 args as kernel never actually checks... */
if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL),
0x100000 | new) < 0)
return -1;
return 0;
#else
#warning Do not know how to handle change_syscall for this architecture
#endif /* architecture */
@ -2465,6 +2472,160 @@ struct xlat struct_user_offsets[] = {
{ 4*REG_XDREG14, "4*REG_XDREG14" },
{ 4*REG_FPSCR, "4*REG_FPSCR" },
#endif /* SH */
#ifdef SHMEDIA
{ 0, "PC(L)" },
{ 4, "PC(U)" },
{ 8, "SR(L)" },
{ 12, "SR(U)" },
{ 16, "syscall no.(L)" },
{ 20, "syscall_no.(U)" },
{ 24, "R0(L)" },
{ 28, "R0(U)" },
{ 32, "R1(L)" },
{ 36, "R1(U)" },
{ 40, "R2(L)" },
{ 44, "R2(U)" },
{ 48, "R3(L)" },
{ 52, "R3(U)" },
{ 56, "R4(L)" },
{ 60, "R4(U)" },
{ 64, "R5(L)" },
{ 68, "R5(U)" },
{ 72, "R6(L)" },
{ 76, "R6(U)" },
{ 80, "R7(L)" },
{ 84, "R7(U)" },
{ 88, "R8(L)" },
{ 92, "R8(U)" },
{ 96, "R9(L)" },
{ 100, "R9(U)" },
{ 104, "R10(L)" },
{ 108, "R10(U)" },
{ 112, "R11(L)" },
{ 116, "R11(U)" },
{ 120, "R12(L)" },
{ 124, "R12(U)" },
{ 128, "R13(L)" },
{ 132, "R13(U)" },
{ 136, "R14(L)" },
{ 140, "R14(U)" },
{ 144, "R15(L)" },
{ 148, "R15(U)" },
{ 152, "R16(L)" },
{ 156, "R16(U)" },
{ 160, "R17(L)" },
{ 164, "R17(U)" },
{ 168, "R18(L)" },
{ 172, "R18(U)" },
{ 176, "R19(L)" },
{ 180, "R19(U)" },
{ 184, "R20(L)" },
{ 188, "R20(U)" },
{ 192, "R21(L)" },
{ 196, "R21(U)" },
{ 200, "R22(L)" },
{ 204, "R22(U)" },
{ 208, "R23(L)" },
{ 212, "R23(U)" },
{ 216, "R24(L)" },
{ 220, "R24(U)" },
{ 224, "R25(L)" },
{ 228, "R25(U)" },
{ 232, "R26(L)" },
{ 236, "R26(U)" },
{ 240, "R27(L)" },
{ 244, "R27(U)" },
{ 248, "R28(L)" },
{ 252, "R28(U)" },
{ 256, "R29(L)" },
{ 260, "R29(U)" },
{ 264, "R30(L)" },
{ 268, "R30(U)" },
{ 272, "R31(L)" },
{ 276, "R31(U)" },
{ 280, "R32(L)" },
{ 284, "R32(U)" },
{ 288, "R33(L)" },
{ 292, "R33(U)" },
{ 296, "R34(L)" },
{ 300, "R34(U)" },
{ 304, "R35(L)" },
{ 308, "R35(U)" },
{ 312, "R36(L)" },
{ 316, "R36(U)" },
{ 320, "R37(L)" },
{ 324, "R37(U)" },
{ 328, "R38(L)" },
{ 332, "R38(U)" },
{ 336, "R39(L)" },
{ 340, "R39(U)" },
{ 344, "R40(L)" },
{ 348, "R40(U)" },
{ 352, "R41(L)" },
{ 356, "R41(U)" },
{ 360, "R42(L)" },
{ 364, "R42(U)" },
{ 368, "R43(L)" },
{ 372, "R43(U)" },
{ 376, "R44(L)" },
{ 380, "R44(U)" },
{ 384, "R45(L)" },
{ 388, "R45(U)" },
{ 392, "R46(L)" },
{ 396, "R46(U)" },
{ 400, "R47(L)" },
{ 404, "R47(U)" },
{ 408, "R48(L)" },
{ 412, "R48(U)" },
{ 416, "R49(L)" },
{ 420, "R49(U)" },
{ 424, "R50(L)" },
{ 428, "R50(U)" },
{ 432, "R51(L)" },
{ 436, "R51(U)" },
{ 440, "R52(L)" },
{ 444, "R52(U)" },
{ 448, "R53(L)" },
{ 452, "R53(U)" },
{ 456, "R54(L)" },
{ 460, "R54(U)" },
{ 464, "R55(L)" },
{ 468, "R55(U)" },
{ 472, "R56(L)" },
{ 476, "R56(U)" },
{ 480, "R57(L)" },
{ 484, "R57(U)" },
{ 488, "R58(L)" },
{ 492, "R58(U)" },
{ 496, "R59(L)" },
{ 500, "R59(U)" },
{ 504, "R60(L)" },
{ 508, "R60(U)" },
{ 512, "R61(L)" },
{ 516, "R61(U)" },
{ 520, "R62(L)" },
{ 524, "R62(U)" },
{ 528, "TR0(L)" },
{ 532, "TR0(U)" },
{ 536, "TR1(L)" },
{ 540, "TR1(U)" },
{ 544, "TR2(L)" },
{ 548, "TR2(U)" },
{ 552, "TR3(L)" },
{ 556, "TR3(U)" },
{ 560, "TR4(L)" },
{ 564, "TR4(U)" },
{ 568, "TR5(L)" },
{ 572, "TR5(U)" },
{ 576, "TR6(L)" },
{ 580, "TR6(U)" },
{ 584, "TR7(L)" },
{ 588, "TR7(U)" },
/* This entry is in case pt_regs contains dregs (depends on
the kernel build options). */
{ uoff(regs), "offsetof(struct user, regs)" },
{ uoff(fpu), "offsetof(struct user, fpu)" },
#endif
#if !defined(S390) && !defined(S390X) && !defined(MIPS)
{ uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
@ -2480,9 +2641,12 @@ struct xlat struct_user_offsets[] = {
{ uoff(u_dsize), "offsetof(struct user, u_dsize)" },
{ uoff(u_ssize), "offsetof(struct user, u_ssize)" },
{ uoff(start_code), "offsetof(struct user, start_code)" },
#ifdef SHMEDIA
{ uoff(start_data), "offsetof(struct user, start_data)" },
#endif
{ uoff(start_stack), "offsetof(struct user, start_stack)" },
{ uoff(signal), "offsetof(struct user, signal)" },
#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH)
#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SHMEDIA)
{ uoff(reserved), "offsetof(struct user, reserved)" },
#endif
{ uoff(u_ar0), "offsetof(struct user, u_ar0)" },

2
sock.c
View File

@ -35,7 +35,7 @@
#include <sys/sockio.h>
#endif
#if defined (ALPHA) || defined(SH)
#if defined (ALPHA) || defined(SH) || defined(SHMEDIA)
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#elif defined(HAVE_IOCTLS_H)

View File

@ -713,6 +713,8 @@ struct tcb *tcp;
static long r28;
#elif defined(SH)
static long r0;
#elif defined(SHMEDIA)
static long r9;
#elif defined(X86_64)
static long rax;
#endif
@ -1093,15 +1095,32 @@ struct tcb *tcp;
return 0;
}
}
#endif /* SH */
#elif defined(SHMEDIA)
if (upeek(pid, REG_SYSCALL, &scno) < 0)
return -1;
scno &= 0xFFFF;
if (!(tcp->flags & TCB_INSYSCALL)) {
/* Check if we return from execve. */
if (tcp->flags & TCB_WAITEXECVE) {
tcp->flags &= ~TCB_WAITEXECVE;
return 0;
}
}
#endif /* SHMEDIA */
#endif /* LINUX */
#ifdef SUNOS4
if (upeek(pid, uoff(u_arg[7]), &scno) < 0)
return -1;
#elif defined(SH)
/* new syscall ABI returns result in R0 */
if (upeek(pid, 4*REG_REG0, (long *)&r0) < 0)
return -1;
/* new syscall ABI returns result in R0 */
if (upeek(pid, 4*REG_REG0, (long *)&r0) < 0)
return -1;
#elif defined(SHMEDIA)
/* ABI defines result returned in r9 */
if (upeek(pid, REG_GENERAL(9), (long *)&r9) < 0)
return -1;
#endif
#ifdef USE_PROCFS
#ifdef HAVE_PR_SYSCALL
@ -1416,6 +1435,18 @@ struct tcb *tcp;
tcp->u_rval = r0;
u_error = 0;
}
#else
#ifdef SHMEDIA
/* interpret result as return value or error number */
if (r9 && (unsigned) -r9 < nerrnos) {
tcp->u_rval = -1;
u_error = -r9;
}
else {
tcp->u_rval = r9;
u_error = 0;
}
#endif /* SHMEDIA */
#endif /* SH */
#endif /* HPPA */
#endif /* SPARC */
@ -1622,6 +1653,12 @@ force_result(tcp, error, rval)
r0 = error ? -error : rval;
if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*REG_REG0), r0) < 0)
return -1;
#else
#ifdef SHMEDIA
r9 = error ? -error : rval;
if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)REG_GENERAL(9), r9) < 0)
return -1;
#endif /* SHMEDIA */
#endif /* SH */
#endif /* HPPA */
#endif /* SPARC */
@ -1841,6 +1878,28 @@ struct tcb *tcp;
return -1;
}
}
#elif defined(SHMEDIA)
{
int i;
/* Registers used by SH5 Linux system calls for parameters */
static int syscall_regs[] = { 2, 3, 4, 5, 6, 7 };
/*
* TODO: should also check that the number of arguments encoded
* in the trap number matches the number strace expects.
*/
/*
assert(sysent[tcp->scno].nargs <
sizeof(syscall_regs)/sizeof(syscall_regs[0]));
*/
tcp->u_nargs = sysent[tcp->scno].nargs;
for (i = 0; i < tcp->u_nargs; i++) {
if (upeek(pid, REG_GENERAL(syscall_regs[i]), &tcp->u_arg[i]) < 0)
return -1;
}
}
#elif defined(X86_64)
{
int i;

17
util.c
View File

@ -974,6 +974,9 @@ struct tcb *tcp;
#elif defined(SH)
if (upeek(tcp->pid, 4*REG_PC ,&pc) < 0)
return -1;
#elif defined(SHMEDIA)
if (upeek(tcp->pid, REG_PC ,&pc) < 0)
return -1;
#endif
return pc;
#endif /* LINUX */
@ -1089,6 +1092,15 @@ struct tcb *tcp;
return;
}
tprintf("[%08lx] ", pc);
#elif defined(SHMEDIA)
long pc;
if (upeek(tcp->pid, REG_PC, &pc) < 0) {
tprintf ("[????????] ");
return;
}
tprintf("[%08lx] ", pc);
#endif /* !architecture */
#endif /* LINUX */
@ -1226,6 +1238,11 @@ typedef struct regs arg_setup_state;
# elif defined (SH)
# define arg0_offset (4*(REG_REG0+4))
# define arg1_offset (4*(REG_REG0+5))
# elif defined (SHMEDIA)
/* ABI defines arg0 & 1 in r2 & r3 */
# define arg0_offset (REG_OFFSET+16)
# define arg1_offset (REG_OFFSET+24)
# define restore_arg0(tcp, state, val) 0
# else
# define arg0_offset 0
# define arg1_offset 4