* acinclude.m4 (AC_LITTLE_ENDIAN_LONG_LONG): Use int instead of long. * configure.ac: Use arch=powerpc64 and define POWERPC64 for powerpc64. * defs.h (SUPPORTED_PERSONALITIES, PERSONALITY0_WORDSIZE) (PERSONALITY1_WORDSIZE) [POWERPC64]: Define. * file.c: Handle POWERPC64 like POWERPC. (struct stat_powerpc32, printstat_powerpc32) [POWERPC64]: Define. (printstat) [POWERPC64]: Call printstat_powerpc32 for 32bit personality. (sys_newfstatat) [POWERPC64]: Handle personality. * ioctl.c: Handle POWERPC64 like POWERPC. * linux/errnoent.h: Handle POWERPC64 like POWERPC. * linux/powerpc64/errnoent1.h: New file. * linux/powerpc64/ioctlent.h: New file. * linux/powerpc64/ioctlent1.h: New file. * linux/powerpc64/signalent1.h: New file. * linux/powerpc64/syscallent.h: New file. * linux/powerpc64/syscallent1.h: New file. * linux/syscall.h: Handle POWERPC64 like POWERPC. * mem.c: Handle POWERPC64 like POWERPC. * process.c: Handle POWERPC64 like POWERPC. * signal.c: Handle POWERPC64 like POWERPC. (sys_sigreturn) [POWERPC64]: Check for personality. * syscall.c: Handle POWERPC64 like POWERPC. (get_scno) [POWERPC64]: Check for 64/32 bit mode. * util.c:Handle POWERPC64 like POWERPC. (printllval) [POWERPC64]: Check for personality. --- acinclude.m4 | 2 +- configure.ac | 4 ++ defs.h | 11 ++++- file.c | 83 +++++++++++++++++++++++++++++++++++++++- ioctl.c | 2 +- linux/errnoent.h | 2 +- linux/powerpc64/errnoent1.h | 1 + linux/powerpc64/ioctlent.h | 1 + linux/powerpc64/ioctlent1.h | 1 + linux/powerpc64/signalent1.h | 1 + linux/powerpc64/syscallent.h | 1 + linux/powerpc64/syscallent1.h | 1 + linux/syscall.h | 4 +- mem.c | 2 +- process.c | 7 ++- signal.c | 9 +++- syscall.c | 34 ++++++++++++++--- util.c | 20 +++++++--- 18 files changed, 157 insertions(+), 29 deletions(-) create mode 100644 linux/powerpc64/errnoent1.h create mode 100644 linux/powerpc64/ioctlent.h create mode 100644 linux/powerpc64/ioctlent1.h create mode 100644 linux/powerpc64/signalent1.h create mode 100644 linux/powerpc64/syscallent.h create mode 100644 linux/powerpc64/syscallent1.h
diff --git a/acinclude.m4 b/acinclude.m4 index da66c64..1741ab9 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -280,7 +280,7 @@ AC_CACHE_VAL(ac_cv_have_little_endian_long_long, int main () { union { long long ll; - long l [2]; + int l [2]; } u; u.ll = 0x12345678; if (u.l[0] == 0x12345678) diff --git a/configure.ac b/configure.ac index 76f55d2..5f86783 100644 --- a/configure.ac +++ b/configure.ac @@ -76,6 +76,10 @@ alpha*) arch=alpha AC_DEFINE([ALPHA], 1, [Define for the Alpha architecture.]) ;; +powerpc64*) + arch=powerpc64 + AC_DEFINE([POWERPC64], 1, [Define for the PowerPC64 architecture.]) + ;; powerpc*) arch=powerpc AC_DEFINE([POWERPC], 1, [Define for the PowerPC architecture.]) diff --git a/defs.h b/defs.h index a7e8793..3f04b1b 100644 --- a/defs.h +++ b/defs.h @@ -246,6 +246,13 @@ extern int ptrace(int, int, char *, int, ...); #define PERSONALITY1_WORDSIZE 4 #endif +#if defined POWERPC64 +#undef SUPPORTED_PERSONALITIES +#define SUPPORTED_PERSONALITIES 2 +#define PERSONALITY0_WORDSIZE 8 +#define PERSONALITY1_WORDSIZE 4 +#endif + #ifdef SVR4 #ifdef HAVE_MP_PROCFS extern int mp_ioctl (int f, int c, void *a, int s); @@ -370,7 +377,7 @@ struct tcb { * See "stray syscall exit: eax = " message in syscall_fixup(). */ # if defined(ALPHA) || defined(AVR32) || defined(SPARC) || defined(SPARC64) \ - || defined(POWERPC) || defined(IA64) || defined(HPPA) \ + || defined(POWERPC) || defined(POWERPC64) || defined(IA64) || defined(HPPA) \ || defined(SH) || defined(SH64) || defined(S390) || defined(S390X) \ || defined(ARM) || defined(MIPS) || defined(BFIN) || defined(TILE) # define TCB_WAITEXECVE 02000 /* ignore SIGTRAP after exceve */ @@ -389,7 +396,7 @@ struct tcb { # define __NR_exit_group 231 # elif defined IA64 # define __NR_exit_group 1236 -# elif defined POWERPC +# elif defined POWERPC || defined POWERPC64 # define __NR_exit_group 234 # elif defined S390 || defined S390X # define __NR_exit_group 248 diff --git a/file.c b/file.c index 854548f..876e148 100644 --- a/file.c +++ b/file.c @@ -859,6 +859,71 @@ printstat_sparc64(struct tcb *tcp, long addr) #endif /* SPARC64 */ #endif /* LINUXSPARC */ +#if defined LINUX && defined POWERPC64 +struct stat_powerpc32 { + unsigned int st_dev; + unsigned int st_ino; + unsigned int st_mode; + unsigned short st_nlink; + unsigned int st_uid; + unsigned int st_gid; + unsigned int st_rdev; + unsigned int st_size; + unsigned int st_blksize; + unsigned int st_blocks; + unsigned int st_atime; + unsigned int st_atime_nsec; + unsigned int st_mtime; + unsigned int st_mtime_nsec; + unsigned int st_ctime; + unsigned int st_ctime_nsec; + unsigned int __unused4; + unsigned int __unused5; +}; + +static void +printstat_powerpc32(struct tcb *tcp, long addr) +{ + struct stat_powerpc32 statbuf; + + if (umove(tcp, addr, &statbuf) < 0) { + tprintf("{...}"); + return; + } + + if (!abbrev(tcp)) { + tprintf("{st_dev=makedev(%u, %u), st_ino=%u, st_mode=%s, ", + major(statbuf.st_dev), minor(statbuf.st_dev), + statbuf.st_ino, + sprintmode(statbuf.st_mode)); + tprintf("st_nlink=%u, st_uid=%u, st_gid=%u, ", + statbuf.st_nlink, statbuf.st_uid, statbuf.st_gid); + tprintf("st_blksize=%u, ", statbuf.st_blksize); + tprintf("st_blocks=%u, ", statbuf.st_blocks); + } + else + tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode)); + switch (statbuf.st_mode & S_IFMT) { + case S_IFCHR: case S_IFBLK: + tprintf("st_rdev=makedev(%lu, %lu), ", + (unsigned long) major(statbuf.st_rdev), + (unsigned long) minor(statbuf.st_rdev)); + break; + default: + tprintf("st_size=%u, ", statbuf.st_size); + break; + } + if (!abbrev(tcp)) { + tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime)); + tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime)); + tprintf("st_ctime=%s", sprinttime(statbuf.st_ctime)); + tprintf("}"); + } + else + tprintf("...}"); +} +#endif /* LINUX && POWERPC64 */ + static const struct xlat fileflags[] = { #ifdef FREEBSD { UF_NODUMP, "UF_NODUMP" }, @@ -998,6 +1063,13 @@ printstat(struct tcb *tcp, long addr) #endif #endif /* LINUXSPARC */ +#if defined LINUX && defined POWERPC64 + if (current_personality == 1) { + printstat_powerpc32(tcp, addr); + return; + } +#endif + if (umove(tcp, addr, &statbuf) < 0) { tprintf("{...}"); return; @@ -1259,7 +1331,12 @@ sys_newfstatat(struct tcb *tcp) printpath(tcp, tcp->u_arg[1]); tprintf(", "); } else { -#if defined HAVE_STAT64 && !(defined POWERPC && defined __powerpc64__) +#ifdef POWERPC64 + if (current_personality == 0) + printstat(tcp, tcp->u_arg[2]); + else + printstat64(tcp, tcp->u_arg[2]); +#elif defined HAVE_STAT64 printstat64(tcp, tcp->u_arg[2]); #else printstat(tcp, tcp->u_arg[2]); @@ -2824,13 +2901,13 @@ sys_fadvise64_64(struct tcb *tcp) if (entering(tcp)) { int argn; tprintf("%ld, ", tcp->u_arg[0]); -#if defined ARM || defined POWERPC +#if defined ARM || defined POWERPC || defined POWERPC64 argn = printllval(tcp, "%lld, ", 2); #else argn = printllval(tcp, "%lld, ", 1); #endif argn = printllval(tcp, "%lld, ", argn); -#if defined ARM || defined POWERPC +#if defined ARM || defined POWERPC || defined POWERPC64 printxval(advise, tcp->u_arg[1], "POSIX_FADV_???"); #else printxval(advise, tcp->u_arg[argn], "POSIX_FADV_???"); diff --git a/ioctl.c b/ioctl.c index 906c71e..3f97dfd 100644 --- a/ioctl.c +++ b/ioctl.c @@ -117,7 +117,7 @@ long code, arg; { switch ((code >> 8) & 0xff) { #ifdef LINUX -#if defined(ALPHA) || defined(POWERPC) +#if defined(ALPHA) || defined(POWERPC) || defined(POWERPC64) case 'f': case 't': case 'T': #else /* !ALPHA */ case 0x54: diff --git a/linux/errnoent.h b/linux/errnoent.h index c52d1d0..aead207 100644 --- a/linux/errnoent.h +++ b/linux/errnoent.h @@ -56,7 +56,7 @@ "ENOANO", /* 55 */ "EBADRQC", /* 56 */ "EBADSLT", /* 57 */ -#ifdef POWERPC +#if defined POWERPC || defined POWERPC64 "EDEADLOCK", /* 58 */ #else "ERRNO_58", /* 58 */ diff --git a/linux/powerpc64/errnoent1.h b/linux/powerpc64/errnoent1.h new file mode 100644 index 0000000..441c66b --- /dev/null +++ b/linux/powerpc64/errnoent1.h @@ -0,0 +1 @@ +#include "../errnoent.h" diff --git a/linux/powerpc64/ioctlent.h b/linux/powerpc64/ioctlent.h new file mode 100644 index 0000000..f65411c --- /dev/null +++ b/linux/powerpc64/ioctlent.h @@ -0,0 +1 @@ +#include "../powerpc/ioctlent.h" diff --git a/linux/powerpc64/ioctlent1.h b/linux/powerpc64/ioctlent1.h new file mode 100644 index 0000000..f65411c --- /dev/null +++ b/linux/powerpc64/ioctlent1.h @@ -0,0 +1 @@ +#include "../powerpc/ioctlent.h" diff --git a/linux/powerpc64/signalent1.h b/linux/powerpc64/signalent1.h new file mode 100644 index 0000000..d31e6a4 --- /dev/null +++ b/linux/powerpc64/signalent1.h @@ -0,0 +1 @@ +#include "../signalent.h" diff --git a/linux/powerpc64/syscallent.h b/linux/powerpc64/syscallent.h new file mode 100644 index 0000000..b909c82 --- /dev/null +++ b/linux/powerpc64/syscallent.h @@ -0,0 +1 @@ +#include "../powerpc/syscallent.h" diff --git a/linux/powerpc64/syscallent1.h b/linux/powerpc64/syscallent1.h new file mode 100644 index 0000000..b909c82 --- /dev/null +++ b/linux/powerpc64/syscallent1.h @@ -0,0 +1 @@ +#include "../powerpc/syscallent.h" diff --git a/linux/syscall.h b/linux/syscall.h index 6bfed87..68604a9 100644 --- a/linux/syscall.h +++ b/linux/syscall.h @@ -165,7 +165,7 @@ int sys_osf_utimes(); # define SYS_waitid 1270 # elif defined M68K # define SYS_waitid 277 -# elif defined POWERPC +# elif defined POWERPC || defined POWERPC64 # define SYS_waitid 272 # elif defined S390 || defined S390X # define SYS_waitid 281 @@ -328,7 +328,7 @@ int sys_cacheflush(); int sys_pread64(), sys_pwrite64(); -#ifdef POWERPC +#if defined POWERPC || defined POWERPC64 int sys_subpage_prot(); #endif diff --git a/mem.c b/mem.c index ec5707a..bacb1ea 100644 --- a/mem.c +++ b/mem.c @@ -955,7 +955,7 @@ struct tcb *tcp; } #endif -#if defined(LINUX) && defined(POWERPC) +#if defined(LINUX) && (defined(POWERPC) || defined(POWERPC64)) int sys_subpage_prot(tcp) struct tcb *tcp; diff --git a/process.c b/process.c index dadf830..388fcbd 100644 --- a/process.c +++ b/process.c @@ -689,7 +689,7 @@ change_syscall(struct tcb *tcp, int new) if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0) return -1; return 0; -#elif defined(POWERPC) +#elif defined(POWERPC) || defined(POWERPC64) if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(sizeof(unsigned long)*PT_R0), new) < 0) return -1; @@ -2401,7 +2401,7 @@ const struct xlat struct_user_offsets[] = { /* XXX No support for these offsets yet. */ # elif defined(HPPA) /* XXX No support for these offsets yet. */ -# elif defined(POWERPC) +# elif defined(POWERPC) || defined(POWERPC64) # ifndef PT_ORIG_R3 # define PT_ORIG_R3 34 # endif @@ -3094,7 +3094,8 @@ const struct xlat struct_user_offsets[] = { # if !defined(SPARC) && !defined(HPPA) && !defined(POWERPC) \ && !defined(ALPHA) && !defined(IA64) \ - && !defined(CRISV10) && !defined(CRISV32) + && !defined(CRISV10) && !defined(CRISV32) \ + && !defined(POWERPC64) # if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SPARC64) && !defined(AVR32) && !defined(BFIN) && !defined(TILE) { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" }, # endif diff --git a/signal.c b/signal.c index bf97e90..dcd0d00 100644 --- a/signal.c +++ b/signal.c @@ -1321,7 +1321,7 @@ sys_sigreturn(struct tcb *tcp) return RVAL_NONE | RVAL_STR; } return 0; -#elif defined(POWERPC) +#elif defined(POWERPC) || defined(POWERPC64) long esp; struct sigcontext_struct sc; @@ -1330,8 +1330,11 @@ sys_sigreturn(struct tcb *tcp) if (upeek(tcp, sizeof(unsigned long)*PT_R1, &esp) < 0) return 0; /* Skip dummy stack frame. */ -#ifdef __powerpc64__ - esp += 128; +#ifdef POWERPC64 + if (current_personality == 0) + esp += 128; + else + esp += 64; #else esp += 64; #endif diff --git a/syscall.c b/syscall.c index ba2185c..467ac87 100644 --- a/syscall.c +++ b/syscall.c @@ -724,7 +724,7 @@ internal_syscall(struct tcb *tcp) #elif defined (IA64) long r8, r10, psr; long ia32 = 0; -#elif defined (POWERPC) +#elif defined (POWERPC) || defined (POWERPC64) static long result,flags; #elif defined (M68K) static long d0; @@ -873,7 +873,7 @@ get_scno(struct tcb *tcp) scno = (scno | tmp) & 0xff; } } -# elif defined (POWERPC) +# elif defined (POWERPC) || defined (POWERPC64) if (upeek(tcp, sizeof(unsigned long)*PT_R0, &scno) < 0) return -1; if (!(tcp->flags & TCB_INSYSCALL)) { @@ -883,6 +883,28 @@ get_scno(struct tcb *tcp) return 0; } } + +# ifdef POWERPC64 + if (!(tcp->flags & TCB_INSYSCALL)) { + static int currpers = -1; + long val; + int pid = tcp->pid; + + /* Check for 64/32 bit mode. */ + if (upeek(tcp, sizeof (unsigned long)*PT_MSR, &val) < 0) + return -1; + if (val < 0) + currpers = 0; + else + currpers = 1; + if (currpers != current_personality) { + static const char *const names[] = {"64 bit", "32 bit"}; + set_personality(currpers); + printf("[ Process PID=%d runs in %s mode. ]\n", + pid, names[current_personality]); + } +# endif + } # elif defined(AVR32) /* * Read complete register set in one go. @@ -1460,7 +1482,7 @@ syscall_fixup(struct tcb *tcp) */ gpr2 = 0; } -#elif defined (POWERPC) +#elif defined (POWERPC) || defined (POWERPC64) # define SO_MASK 0x10000000 if (upeek(tcp, sizeof(unsigned long)*PT_CCR, &flags) < 0) return -1; @@ -1588,7 +1610,7 @@ get_error(struct tcb *tcp) tcp->u_rval = r2; u_error = 0; } -# elif defined(POWERPC) +# elif defined(POWERPC) || defined(POWERPC64) if (is_negated_errno(result)) { tcp->u_rval = -1; u_error = -result; @@ -1842,7 +1864,7 @@ force_result(tcp, error, rval) if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), a3) < 0 || ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), r2) < 0) return -1; -# elif defined(POWERPC) +# elif defined(POWERPC) || defined(POWERPC64) if (upeek(tcp, sizeof(unsigned long)*PT_CCR, &flags) < 0) return -1; if (error) { @@ -2092,7 +2114,7 @@ syscall_enter(struct tcb *tcp) } } } -#elif defined (POWERPC) +#elif defined (POWERPC) || defined (POWERPC64) # ifndef PT_ORIG_R3 # define PT_ORIG_R3 34 # endif diff --git a/util.c b/util.c index bd12c0f..69d1e44 100644 --- a/util.c +++ b/util.c @@ -251,20 +251,24 @@ int printllval(struct tcb *tcp, const char *format, int llarg) { # if defined(FREEBSD) \ - || (defined(LINUX) && defined(POWERPC) && !defined(__powerpc64__)) \ + || (defined(LINUX) && defined(POWERPC)) \ || defined (LINUX_MIPSO32) /* Align 64bit argument to 64bit boundary. */ if (llarg % 2) llarg++; # endif -# if defined LINUX && defined X86_64 +# if defined LINUX && (defined X86_64 || defined POWERPC64) if (current_personality == 0) { tprintf(format, tcp->u_arg[llarg]); llarg++; } else { +# ifdef POWERPC64 + /* Align 64bit argument to 64bit boundary. */ + if (llarg % 2) llarg++; +# endif tprintf(format, LONG_LONG(tcp->u_arg[llarg], tcp->u_arg[llarg + 1])); llarg += 2; } -# elif defined IA64 || defined ALPHA || (defined POWERPC && defined __powerpc64__) +# elif defined IA64 || defined ALPHA tprintf(format, tcp->u_arg[llarg]); llarg++; # elif defined LINUX_MIPSN32 @@ -1106,14 +1110,18 @@ printcall(struct tcb *tcp) return; } tprintf("[%08lx] ", ip); -# elif defined(POWERPC) +# elif defined(POWERPC) || defined(POWERPC64) long pc; if (upeek(tcp, sizeof(unsigned long)*PT_NIP, &pc) < 0) { - tprintf ("[????????] "); + PRINTBADPC; return; } +# ifdef POWERPC64 + tprintf("[%016lx] ", pc); +# else tprintf("[%08lx] ", pc); +# endif # elif defined(M68K) long pc; @@ -1402,7 +1410,7 @@ typedef struct pt_regs arg_setup_state; # elif defined (AVR32) # define arg0_offset (REG_R12) # define arg1_offset (REG_R11) -# elif defined (POWERPC) +# elif defined (POWERPC) || defined (POWERPC64) # define arg0_offset (sizeof(unsigned long)*PT_R3) # define arg1_offset (sizeof(unsigned long)*PT_R4) # define restore_arg0(tcp, state, val) ((void) (state), 0) -- 1.7.1.1 -- Andreas Schwab, sch...@linux-m68k.org GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 "And now for something completely different." ------------------------------------------------------------------------------ This SF.net email is sponsored by Sprint What will you do first with EVO, the first 4G phone? Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first _______________________________________________ Strace-devel mailing list Strace-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/strace-devel