diff options
author | Mike Frysinger <vapier@gentoo.org> | 2015-12-20 01:14:28 -0500 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2015-12-20 01:14:28 -0500 |
commit | 9d08c42993a418be6eafa1ffd4abf9e1c60ddd77 (patch) | |
tree | 9e40eb03f4f0fd7dbe61f1c2ec8252daa4d7a80e /libsandbox/trace | |
parent | libsandbox: improve sparc trace code a bit more (diff) | |
download | sandbox-9d08c42993a418be6eafa1ffd4abf9e1c60ddd77.tar.gz sandbox-9d08c42993a418be6eafa1ffd4abf9e1c60ddd77.tar.bz2 sandbox-9d08c42993a418be6eafa1ffd4abf9e1c60ddd77.zip |
libsandbox: new s390/s390x ptrace port
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'libsandbox/trace')
-rw-r--r-- | libsandbox/trace/linux/arch.c | 2 | ||||
-rw-r--r-- | libsandbox/trace/linux/s390.c | 95 |
2 files changed, 97 insertions, 0 deletions
diff --git a/libsandbox/trace/linux/arch.c b/libsandbox/trace/linux/arch.c index 957db3b..53461d6 100644 --- a/libsandbox/trace/linux/arch.c +++ b/libsandbox/trace/linux/arch.c @@ -13,6 +13,8 @@ # include "hppa.c" #elif defined(__i386__) # include "i386.c" +#elif defined(__s390__) +# include "s390.c" #elif defined(__sparc__) # include "sparc.c" #elif defined(__x86_64__) diff --git a/libsandbox/trace/linux/s390.c b/libsandbox/trace/linux/s390.c new file mode 100644 index 0000000..acbf894 --- /dev/null +++ b/libsandbox/trace/linux/s390.c @@ -0,0 +1,95 @@ +#undef _trace_possible +#define _trace_possible _trace_possible + +#ifdef SB_SCHIZO + +static const struct syscall_entry syscall_table_32[] = { +#ifdef SB_SCHIZO_s390 +#define S(s) { SB_SYS_s390_##s, SB_NR_##s, #s }, +#include "trace_syscalls_s390.h" +#undef S +#endif + { SB_NR_UNDEF, SB_NR_UNDEF, NULL }, +}; +static const struct syscall_entry syscall_table_64[] = { +#ifdef SB_SCHIZO_s390x +#define S(s) { SB_SYS_s390x_##s, SB_NR_##s, #s }, +#include "trace_syscalls_s390x.h" +#undef S +#endif + { SB_NR_UNDEF, SB_NR_UNDEF, NULL }, +}; + +static bool pers_is_31(trace_regs *regs) +{ + return regs->psw.mask & 0x100000000ul ? false : true; +} + +static const struct syscall_entry *trace_check_personality(void *vregs) +{ + trace_regs *regs = vregs; + return pers_is_31(regs) ? syscall_table_32 : syscall_table_64; +} + +static bool _trace_possible(const void *data) +{ + return true; +} + +#else + +static bool _trace_possible(const void *data) +{ +# ifdef __s390x__ +# define ELFCLASS ELFCLASS64 +# else +# define ELFCLASS ELFCLASS32 +# endif + const Elf64_Ehdr *ehdr = data; + return (ehdr->e_ident[EI_CLASS] == ELFCLASS) && + (ehdr->e_machine == EM_S390); +} + +#endif + +#undef trace_get_regs +static long trace_get_regs(void *vregs) +{ + ptrace_area parea = { + /* Most regs we want are at the start (pswmask, pswaddr, and gpr0...gpr7, + * but the orig_gpr2 is much further along in the area. */ + .len = PT_ORIGGPR2 + sizeof(long), + .kernel_addr = PT_PSWMASK, + .process_addr = (uintptr_t)vregs, + }; + do_ptrace(PTRACE_PEEKUSR_AREA, &parea, NULL); + return 0; +} + +#undef trace_set_regs +static long trace_set_regs(void *vregs) +{ + ptrace_area parea = { + /* Most regs we want are at the start (pswmask, pswaddr, and gpr0...gpr7, + * but the orig_gpr2 is much further along in the area. */ + .len = PT_ORIGGPR2 + sizeof(long), + .kernel_addr = PT_PSWMASK, + .process_addr = (uintptr_t)vregs, + }; + do_ptrace(PTRACE_POKEUSR_AREA, &parea, NULL); + return 0; +} + +#define trace_reg_sysnum gprs[2] +#define trace_reg_ret gprs[2] + +static unsigned long trace_arg(void *vregs, int num) +{ + trace_regs *regs = vregs; + if (num == 1) + return regs->orig_gpr2; + else if (num < 7) + return regs->gprs[2 + num - 1]; + else + return -1; +} |