[PATCH] Add support for Imagination Technologies Meta
James Hogan
james.hogan at imgtec.com
Mon Mar 4 10:34:39 UTC 2013
Ping.
Any comments on this?
Thanks
James
On 22/02/13 14:44, James Hogan wrote:
> 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.
>
> Signed-off-by: James Hogan <james.hogan at imgtec.com>
> Cc: Christian Svensson <blue at cmd.nu>
> ---
> I've pulled the -C -C options on git format-patch so that the
> differences against or1k can be seen in the system call table (but can
> regenerate a clean patch if required):
> * 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
>
> configure.ac | 4 ++
> defs.h | 4 +-
> linux/{arm => metag}/ioctlent.h.in | 0
> linux/{or1k => metag}/syscallent.h | 103 +++++++++++++++++++------------------
> process.c | 2 +
> syscall.c | 32 ++++++++++++
> util.c | 3 ++
> 7 files changed, 97 insertions(+), 51 deletions(-)
> copy linux/{arm => metag}/ioctlent.h.in (100%)
> copy linux/{or1k => metag}/syscallent.h (80%)
>
> diff --git a/configure.ac b/configure.ac
> index 8703f7c..09056a5 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -37,6 +37,10 @@ sparc*)
> arch=sparc
> AC_DEFINE([SPARC], 1, [Define for the SPARC architecture.])
> ;;
> +metag*)
> + arch=metag
> + AC_DEFINE([METAG], 1, [Define for the Meta architecture.])
> + ;;
> mips*)
> arch=mips
> AC_DEFINE([MIPS], 1, [Define for the MIPS architecture.])
> diff --git a/defs.h b/defs.h
> index 3562079..d860382 100644
> --- a/defs.h
> +++ b/defs.h
> @@ -142,6 +142,7 @@ extern char *stpcpy(char *dst, const char *src);
> || defined(ARM) || defined(AARCH64) \
> || defined(AVR32) \
> || defined(OR1K) \
> + || defined(METAG) \
> ) && defined(__GLIBC__)
> # include <sys/ptrace.h>
> #else
> @@ -579,7 +580,8 @@ extern void call_summary(FILE *);
> || defined(ARM) \
> || defined(SPARC) || defined(SPARC64) \
> || defined(TILE) \
> - || defined(OR1K)
> + || defined(OR1K) \
> + || defined(METAG)
> extern long get_regs_error;
> # define clear_regs() (get_regs_error = -1)
> extern void get_regs(pid_t pid);
> diff --git a/linux/arm/ioctlent.h.in b/linux/metag/ioctlent.h.in
> similarity index 100%
> copy from linux/arm/ioctlent.h.in
> copy to linux/metag/ioctlent.h.in
> diff --git a/linux/or1k/syscallent.h b/linux/metag/syscallent.h
> similarity index 80%
> copy from linux/or1k/syscallent.h
> copy to linux/metag/syscallent.h
> index 3e7613f..38300ea 100644
> --- a/linux/or1k/syscallent.h
> +++ b/linux/metag/syscallent.h
> @@ -16,7 +16,7 @@
> { 2, TF, sys_removexattr, "lremovexattr" }, /* 15 */
> { 2, TD, sys_fremovexattr, "fremovexattr" }, /* 16 */
> { 2, TF, sys_getcwd, "getcwd" }, /* 17 */
> - { 4, 0, sys_lookup_dcookie, "lookup_dcookie" }, /* 18 */
> + { 4, TF, sys_lookup_dcookie, "lookup_dcookie" }, /* 18 */
> { 2, TD, sys_eventfd2, "eventfd2" }, /* 19 */
> { 1, TD, sys_epoll_create1, "epoll_create1" }, /* 20 */
> { 4, TD, sys_epoll_ctl, "epoll_ctl" }, /* 21 */
> @@ -40,15 +40,15 @@
> { 2, TF, sys_umount2, "umount" }, /* 39 */
> { 5, TF, sys_mount, "mount" }, /* 40 */
> { 2, TF, sys_pivotroot, "pivot_root" }, /* 41 */
> - { 3, 0, sys_nfsservctl, "nfsservctl" }, /* 42 */
> + { }, /* 42 */
> { 3, TF, sys_statfs64, "statfs64" }, /* 43 */
> { 3, TD, sys_fstatfs64, "fstatfs64" }, /* 44 */
> - { 4, TF, sys_truncate64, "truncate64" }, /* 45 */
> - { 4, TD, sys_ftruncate64, "ftruncate64" }, /* 46 */
> + { 3, TF, sys_truncate64, "truncate64" }, /* 45 */
> + { 3, TD, sys_ftruncate64, "ftruncate64" }, /* 46 */
> { 6, TD, sys_fallocate, "fallocate" }, /* 47 */
> { 3, TD|TF, sys_faccessat, "faccessat" }, /* 48 */
> { 1, TF, sys_chdir, "chdir" }, /* 49 */
> - { 1, TF, sys_fchdir, "fchdir" }, /* 50 */
> + { 1, TD, sys_fchdir, "fchdir" }, /* 50 */
> { 1, TF, sys_chroot, "chroot" }, /* 51 */
> { 2, TD, sys_fchmod, "fchmod" }, /* 52 */
> { 3, TD|TF, sys_fchmodat, "fchmodat" }, /* 53 */
> @@ -60,13 +60,13 @@
> { 2, TD, sys_pipe2, "pipe2" }, /* 59 */
> { 4, 0, sys_quotactl, "quotactl" }, /* 60 */
> { 3, TD, sys_getdents64, "getdents64" }, /* 61 */
> - { 5, TF, sys_llseek, "_llseek" }, /* 62 */
> + { 5, TD, sys_llseek, "llseek" }, /* 62 */
> { 3, TD, sys_read, "read" }, /* 63 */
> { 3, TD, sys_write, "write" }, /* 64 */
> { 3, TD, sys_readv, "readv" }, /* 65 */
> { 3, TD, sys_writev, "writev" }, /* 66 */
> - { 6, TD, sys_pread, "pread64" }, /* 67 */
> - { 6, TD, sys_pwrite, "pwrite64" }, /* 68 */
> + { 5, TD, sys_pread, "pread64" }, /* 67 */
> + { 5, TD, sys_pwrite, "pwrite64" }, /* 68 */
> { 5, TD, sys_preadv, "preadv" }, /* 69 */
> { 5, TD, sys_pwritev, "pwritev" }, /* 70 */
> { 4, TD|TN, sys_sendfile64, "sendfile64" }, /* 71 */
> @@ -82,8 +82,8 @@
> { 0, 0, sys_sync, "sync" }, /* 81 */
> { 1, TD, sys_fsync, "fsync" }, /* 82 */
> { 1, TD, sys_fdatasync, "fdatasync" }, /* 83 */
> - { 4, TD, sys_sync_file_range, "sync_file_range" }, /* 84 */
> - { 4, TD, sys_timerfd_create, "timerfd_create" }, /* 85 */
> + { 6, TD, sys_sync_file_range, "sync_file_range" }, /* 84 */
> + { 2, TD, sys_timerfd_create, "timerfd_create" }, /* 85 */
> { 4, TD, sys_timerfd_settime, "timerfd_settime" }, /* 86 */
> { 2, TD, sys_timerfd_gettime, "timerfd_gettime" }, /* 87 */
> { 4, TD|TF, sys_utimensat, "utimensat" }, /* 88 */
> @@ -125,7 +125,7 @@
> { 0, 0, sys_sched_yield, "sched_yield" }, /* 124 */
> { 1, 0, sys_sched_get_priority_max, "sched_get_priority_max"}, /* 125 */
> { 1, 0, sys_sched_get_priority_min, "sched_get_priority_min"}, /* 126 */
> - { 2, 0, sys_sched_rr_get_interval, "sched_rr_get_interval" }, /* 127 */
> + { 2, 0, sys_sched_rr_get_interval, "sched_rr_get_interval" }, /* 127 */
> { 0, 0, sys_restart_syscall, "restart_syscall" }, /* 128 */
> { 2, TS, sys_kill, "kill" }, /* 129 */
> { 2, TS, sys_kill, "tkill" }, /* 130 */
> @@ -161,7 +161,7 @@
> { 1, 0, sys_uname, "uname" }, /* 160 */
> { 2, 0, sys_sethostname, "sethostname" }, /* 161 */
> { 2, 0, sys_setdomainname, "setdomainname" }, /* 162 */
> - { 2, 0, sys_getrlimit, "oldgetrlimit" }, /* 163 */
> + { 2, 0, sys_getrlimit, "getrlimit" }, /* 163 */
> { 2, 0, sys_setrlimit, "setrlimit" }, /* 164 */
> { 2, 0, sys_getrusage, "getrusage" }, /* 165 */
> { 1, 0, sys_umask, "umask" }, /* 166 */
> @@ -184,18 +184,18 @@
> { 5, 0, sys_mq_timedreceive, "mq_timedreceive" }, /* 183 */
> { 2, 0, sys_mq_notify, "mq_notify" }, /* 184 */
> { 3, 0, sys_mq_getsetattr, "mq_getsetattr" }, /* 185 */
> - { 4, TI, sys_msgget, "msgget" }, /* 186 */
> - { 4, TI, sys_msgctl, "msgctl" }, /* 187 */
> - { 4, TI, sys_msgrcv, "msgrcv" }, /* 188 */
> + { 2, TI, sys_msgget, "msgget" }, /* 186 */
> + { 3, TI, sys_msgctl, "msgctl" }, /* 187 */
> + { 5, TI, sys_msgrcv, "msgrcv" }, /* 188 */
> { 4, TI, sys_msgsnd, "msgsnd" }, /* 189 */
> - { 4, TI, sys_semget, "semget" }, /* 190 */
> + { 3, TI, sys_semget, "semget" }, /* 190 */
> { 4, TI, sys_semctl, "semctl" }, /* 191 */
> - { 5, TI, sys_semtimedop, "semtimedop" }, /* 192 */
> - { 4, TI, sys_semop, "semop" }, /* 193 */
> - { 4, TI, sys_shmget, "shmget" }, /* 194 */
> - { 4, TI, sys_shmctl, "shmctl" }, /* 195 */
> - { 4, TI, sys_shmat, "shmat" }, /* 196 */
> - { 4, TI, sys_shmdt, "shmdt" }, /* 197 */
> + { 4, TI, sys_semtimedop, "semtimedop" }, /* 192 */
> + { 3, TI, sys_semop, "semop" }, /* 193 */
> + { 3, TI, sys_shmget, "shmget" }, /* 194 */
> + { 3, TI, sys_shmctl, "shmctl" }, /* 195 */
> + { 3, TI, sys_shmat, "shmat" }, /* 196 */
> + { 1, TI, sys_shmdt, "shmdt" }, /* 197 */
> { 3, TN, sys_socket, "socket" }, /* 198 */
> { 4, TN, sys_socketpair, "socketpair" }, /* 199 */
> { 3, TN, sys_bind, "bind" }, /* 200 */
> @@ -210,45 +210,47 @@
> { 5, TN, sys_getsockopt, "getsockopt" }, /* 209 */
> { 2, TN, sys_shutdown, "shutdown" }, /* 210 */
> { 3, TN, sys_sendmsg, "sendmsg" }, /* 211 */
> - { 5, TN, sys_recvmsg, "recvmsg" }, /* 212 */
> - { 5, TD, sys_readahead, "readahead" }, /* 213 */
> - { 1, 0, sys_brk, "brk" }, /* 214 */
> - { 2, 0, sys_munmap, "munmap" }, /* 215 */
> - { 5, 0, sys_mremap, "mremap" }, /* 216 */
> + { 3, TN, sys_recvmsg, "recvmsg" }, /* 212 */
> + { 4, TD, sys_readahead, "readahead" }, /* 213 */
> + { 1, TM, sys_brk, "brk" }, /* 214 */
> + { 2, TM, sys_munmap, "munmap" }, /* 215 */
> + { 5, TM, sys_mremap, "mremap" }, /* 216 */
> { 5, 0, sys_add_key, "add_key" }, /* 217 */
> { 4, 0, sys_request_key, "request_key" }, /* 218 */
> { 5, 0, sys_keyctl, "keyctl" }, /* 219 */
> { 5, TP, sys_clone, "clone" }, /* 220 */
> { 3, TF|TP, sys_execve, "execve" }, /* 221 */
> - { 6, TD|TM, sys_mmap_pgoff, "mmap2" }, /* 222 */
> + { 6, TD|TM, sys_mmap, "mmap2" }, /* 222 */
> { 6, TD, sys_fadvise64_64, "fadvise64_64" }, /* 223 */
> { 2, TF, sys_swapon, "swapon" }, /* 224 */
> { 1, TF, sys_swapoff, "swapoff" }, /* 225 */
> - { 3, 0, sys_mprotect, "mprotect" }, /* 226 */
> - { 3, 0, sys_msync, "msync" }, /* 227 */
> - { 2, 0, sys_mlock, "mlock" }, /* 228 */
> - { 2, 0, sys_munlock, "munlock" }, /* 229 */
> - { 1, 0, sys_mlockall, "mlockall" }, /* 230 */
> - { 0, 0, sys_munlockall, "munlockall" }, /* 231 */
> - { 3, 0, sys_mincore, "mincore" }, /* 232 */
> - { 3, 0, sys_madvise, "madvise" }, /* 233 */
> - { 5, 0, sys_remap_file_pages, "remap_file_pages" }, /* 234 */
> - { 6, 0, sys_mbind, "mbind" }, /* 235 */
> - { 5, 0, sys_get_mempolicy, "get_mempolicy" }, /* 236 */
> - { 3, 0, sys_set_mempolicy, "set_mempolicy" }, /* 237 */
> - { 5, 0, sys_migrate_pages, "migrate_pages" }, /* 238 */
> - { 6, 0, sys_move_pages, "move_pages" }, /* 239 */
> + { 3, TM, sys_mprotect, "mprotect" }, /* 226 */
> + { 3, TM, sys_msync, "msync" }, /* 227 */
> + { 2, TM, sys_mlock, "mlock" }, /* 228 */
> + { 2, TM, sys_munlock, "munlock" }, /* 229 */
> + { 1, TM, sys_mlockall, "mlockall" }, /* 230 */
> + { 0, TM, sys_munlockall, "munlockall" }, /* 231 */
> + { 3, TM, sys_mincore, "mincore" }, /* 232 */
> + { 3, TM, sys_madvise, "madvise" }, /* 233 */
> + { 5, TM, sys_remap_file_pages, "remap_file_pages" }, /* 234 */
> + { 6, TM, sys_mbind, "mbind" }, /* 235 */
> + { 5, TM, sys_get_mempolicy, "get_mempolicy" }, /* 236 */
> + { 3, TM, sys_set_mempolicy, "set_mempolicy" }, /* 237 */
> + { 4, TM, sys_migrate_pages, "migrate_pages" }, /* 238 */
> + { 6, TM, sys_move_pages, "move_pages" }, /* 239 */
> { 4, TP|TS, sys_rt_tgsigqueueinfo, "rt_tgsigqueueinfo" }, /* 240 */
> { 5, TD, sys_perf_event_open, "perf_event_open" }, /* 241 */
> { 4, TN, sys_accept4, "accept4" }, /* 242 */
> { 5, TN, sys_recvmmsg, "recvmmsg" }, /* 243 */
> - { 6, NF, sys_or1k_atomic, "or1k_atomic" }, /* 244 */
> -
> - [245 ... 259] = { },
> -
> + { }, /* 244 */
> + { 2, 0, printargs, "metag_setglobalbit" }, /* 245 */
> + { 1, 0, printargs, "metag_set_fpu_flags" }, /* 246 */
> + { 1, 0, printargs, "metag_set_tls" }, /* 247 */
> + { 0, 0, printargs, "metag_get_tls" }, /* 248 */
> + [249 ... 259] = { },
> { 4, TP, sys_wait4, "wait4" }, /* 260 */
> - { 4, 0, sys_prlimit64, "prlimit64" }, /* 261 */
> - { 2, TD, sys_fanotify_init, "fanotify_init" }, /* 262 */
> + { 4, TP, sys_prlimit64, "prlimit64" }, /* 261 */
> + { 2, 0, sys_fanotify_init, "fanotify_init" }, /* 262 */
> { 5, TD|TF, sys_fanotify_mark, "fanotify_mark" }, /* 263 */
> { 5, TD|TF, sys_name_to_handle_at, "name_to_handle_at" }, /* 264 */
> { 3, TD, sys_open_by_handle_at, "open_by_handle_at" }, /* 265 */
> @@ -256,5 +258,6 @@
> { 1, TD, sys_syncfs, "syncfs" }, /* 267 */
> { 2, TD, sys_setns, "setns" }, /* 268 */
> { 4, TN, sys_sendmmsg, "sendmmsg" }, /* 269 */
> - { 6, 0, sys_process_vm_readv, "process_vm_readv" }, /* 270 */
> - { 6, 0, sys_process_vm_writev, "process_vm_writev" }, /* 271 */
> + { 6, TP, sys_process_vm_readv, "process_vm_readv" }, /* 270 */
> + { 6, TP, sys_process_vm_writev, "process_vm_writev" }, /* 271 */
> + { 5, TP, printargs, "kcmp" }, /* 272 */
> diff --git a/process.c b/process.c
> index a1f963e..617b78d 100644
> --- a/process.c
> +++ b/process.c
> @@ -2277,6 +2277,8 @@ const struct xlat struct_user_offsets[] = {
> { sizeof(struct user), "sizeof(struct user)" },
> #elif defined(OR1K)
> /* nothing */
> +#elif defined(METAG)
> + /* nothing */
> #endif
> { 0, NULL },
> };
> diff --git a/syscall.c b/syscall.c
> index 5fce9d8..c35ba57 100644
> --- a/syscall.c
> +++ b/syscall.c
> @@ -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
> @@ -756,6 +761,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
> @@ -891,6 +901,8 @@ printcall(struct tcb *tcp)
> # endif
> #elif defined(OR1K)
> tprintf("[%08lx] ", or1k_regs.pc);
> +#elif defined(METAG)
> + tprintf("[%08lx] ", metag_regs.pc);
> #endif /* architecture */
> }
>
> @@ -1015,6 +1027,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
> @@ -1445,6 +1460,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;
> @@ -1841,6 +1858,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)
> @@ -2035,6 +2056,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;
> }
> @@ -2288,6 +2311,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;
> diff --git a/util.c b/util.c
> index 4c22c5f..d8d35bf 100644
> --- a/util.c
> +++ b/util.c
> @@ -1301,6 +1301,9 @@ change_syscall(struct tcb *tcp, arg_setup_state *state, int new)
> /* microblaze is only supported since about linux-2.6.30 */
> #elif defined(OR1K)
> /* never reached; OR1K is only supported by kernels since 3.1.0. */
> +#elif defined(METAG)
> + /* setbpt/clearbpt never used: */
> + /* Meta is only supported since linux-3.7 */
> #else
> #warning Do not know how to handle change_syscall for this architecture
> #endif /* architecture */
>
More information about the Strace-devel
mailing list