diff options
author | James Hogan <james.hogan@imgtec.com> | 2013-02-22 14:44:10 +0000 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2013-03-05 12:57:06 +0100 |
commit | 5f999a869b681ff69cbb801225677fc125b6aefd (patch) | |
tree | 8b1f7995248bbb93d56564b1727fccb69d5f5b6a /syscall.c | |
parent | 1694092d7d92953dbee0639ead0ae379f145c4dd (diff) | |
download | strace-5f999a869b681ff69cbb801225677fc125b6aefd.tar.gz strace-5f999a869b681ff69cbb801225677fc125b6aefd.tar.bz2 strace-5f999a869b681ff69cbb801225677fc125b6aefd.tar.xz |
Add support for Imagination Technologies Meta
Add support for Imagination Technologies Meta architecture (the
architecture/ABI is usually referred to as metag in code). The Meta
Linux kernel port is in the process of being upstreamed for v3.9 so it
uses generic system call numbers.
sys_lookup_dcookie writes a filename to buffer argument, so I've set
TF flag.
nfsservctl appears to be set to sys_ni_syscall in asm-generic/unistd.h
so I've left it blank.
truncate64/ftruncate64/pread64/pwrite64/readahead have unaligned 64bit
args which are packed tightly on metag, so less arguments on metag.
fchdir/llseek takes a file descriptor so s/TF/TD/
sync_file_range has 2 64bit args so uses 6 args, so s/4/6/
timerfd_create/msgget/msgctl/msgrcv/semget/segtimedop/semop/shmget/
shmctl/shmat/shmdt/recvmsg/migrate_pages have different number of args.
oldgetrlimit is just getrlimit for metag.
add TM flag to various memory syscalls.
metag doesn't directly use sys_mmap_pgoff for mmap2.
prlimit64/process_vm_readv/process_vm_writev take a pid so add TP flag.
fanotify_init doesn't appear to take a file descriptor so remove TD.
Add kcmp syscall.
Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Christian Svensson <blue@cmd.nu>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'syscall.c')
-rw-r--r-- | syscall.c | 32 |
1 files changed, 32 insertions, 0 deletions
@@ -82,6 +82,11 @@ # include <elf.h> #endif +#if defined(METAG) +# include <sys/uio.h> +# include <elf.h> +#endif + #ifndef ERESTARTSYS # define ERESTARTSYS 512 #endif @@ -802,6 +807,11 @@ static struct user_regs_struct or1k_regs; static struct iovec or1k_io = { .iov_base = &or1k_regs }; +#elif defined(METAG) +static struct user_gp_regs metag_regs; +static struct iovec metag_io = { + .iov_base = &metag_regs +}; #endif void @@ -937,6 +947,8 @@ printcall(struct tcb *tcp) # endif #elif defined(OR1K) tprintf("[%08lx] ", or1k_regs.pc); +#elif defined(METAG) + tprintf("[%08lx] ", metag_regs.pc); #endif /* architecture */ } @@ -1061,6 +1073,9 @@ get_regs(pid_t pid) # elif defined(OR1K) or1k_io.iov_len = sizeof(or1k_regs); get_regs_error = ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, &or1k_io); +# elif defined(METAG) + metag_io.iov_len = sizeof(metag_regs); + get_regs_error = ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, &metag_io); # endif } #endif @@ -1491,6 +1506,8 @@ get_scno(struct tcb *tcp) return -1; #elif defined(OR1K) scno = or1k_regs.gpr[11]; +#elif defined(METAG) + scno = metag_regs.dx[0][1]; /* syscall number in D1Re0 (D1.0) */ #endif tcp->scno = scno; @@ -1887,6 +1904,10 @@ get_syscall_args(struct tcb *tcp) (void)nargs; for (i = 0; i < 6; ++i) tcp->u_arg[i] = or1k_regs.gpr[3 + i]; +#elif defined(METAG) + for (i = 0; i < nargs; i++) + /* arguments go backwards from D1Ar1 (D1.3) */ + tcp->u_arg[i] = ((unsigned long *)&metag_regs.dx[3][1])[-i]; #else /* Other architecture (32bits specific) */ for (i = 0; i < nargs; ++i) if (upeek(tcp, i*4, &tcp->u_arg[i]) < 0) @@ -2081,6 +2102,8 @@ get_syscall_result(struct tcb *tcp) return -1; #elif defined(OR1K) /* already done by get_regs */ +#elif defined(METAG) + /* already done by get_regs */ #endif return 1; } @@ -2334,6 +2357,15 @@ get_error(struct tcb *tcp) else { tcp->u_rval = sh64_r9; } +#elif defined(METAG) + /* result pointer in D0Re0 (D0.0) */ + if (check_errno && is_negated_errno(metag_regs.dx[0][0])) { + tcp->u_rval = -1; + u_error = -metag_regs.dx[0][0]; + } + else { + tcp->u_rval = metag_regs.dx[0][0]; + } #elif defined(CRISV10) || defined(CRISV32) if (check_errno && cris_r10 && (unsigned) -cris_r10 < nerrnos) { tcp->u_rval = -1; |