1 |
commit: 9d08c42993a418be6eafa1ffd4abf9e1c60ddd77 |
2 |
Author: Mike Frysinger <vapier <AT> gentoo <DOT> org> |
3 |
AuthorDate: Sun Dec 20 06:14:28 2015 +0000 |
4 |
Commit: Mike Frysinger <vapier <AT> gentoo <DOT> org> |
5 |
CommitDate: Sun Dec 20 06:14:28 2015 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/sandbox.git/commit/?id=9d08c429 |
7 |
|
8 |
libsandbox: new s390/s390x ptrace port |
9 |
|
10 |
Signed-off-by: Mike Frysinger <vapier <AT> gentoo.org> |
11 |
|
12 |
configure.ac | 4 ++ |
13 |
libsandbox/trace/linux/arch.c | 2 + |
14 |
libsandbox/trace/linux/s390.c | 95 +++++++++++++++++++++++++++++++++++++++++++ |
15 |
3 files changed, 101 insertions(+) |
16 |
|
17 |
diff --git a/configure.ac b/configure.ac |
18 |
index 64089d7..fd783b7 100644 |
19 |
--- a/configure.ac |
20 |
+++ b/configure.ac |
21 |
@@ -80,6 +80,10 @@ if test "x$enable_schizo" != "xno" ; then |
22 |
SB_CHECK_SCHIZO([x86], [-m32]) |
23 |
SB_CHECK_SCHIZO([x32], [-mx32]) |
24 |
;; |
25 |
+ s390*linux*) |
26 |
+ SB_CHECK_SCHIZO([s390x], [-m64]) |
27 |
+ SB_CHECK_SCHIZO([s390], [-m31]) |
28 |
+ ;; |
29 |
esac |
30 |
SB_SCHIZO_SETTINGS=${SB_SCHIZO_SETTINGS# } |
31 |
if test "x$enable_schizo" != "xno" ; then |
32 |
|
33 |
diff --git a/libsandbox/trace/linux/arch.c b/libsandbox/trace/linux/arch.c |
34 |
index 957db3b..53461d6 100644 |
35 |
--- a/libsandbox/trace/linux/arch.c |
36 |
+++ b/libsandbox/trace/linux/arch.c |
37 |
@@ -13,6 +13,8 @@ |
38 |
# include "hppa.c" |
39 |
#elif defined(__i386__) |
40 |
# include "i386.c" |
41 |
+#elif defined(__s390__) |
42 |
+# include "s390.c" |
43 |
#elif defined(__sparc__) |
44 |
# include "sparc.c" |
45 |
#elif defined(__x86_64__) |
46 |
|
47 |
diff --git a/libsandbox/trace/linux/s390.c b/libsandbox/trace/linux/s390.c |
48 |
new file mode 100644 |
49 |
index 0000000..acbf894 |
50 |
--- /dev/null |
51 |
+++ b/libsandbox/trace/linux/s390.c |
52 |
@@ -0,0 +1,95 @@ |
53 |
+#undef _trace_possible |
54 |
+#define _trace_possible _trace_possible |
55 |
+ |
56 |
+#ifdef SB_SCHIZO |
57 |
+ |
58 |
+static const struct syscall_entry syscall_table_32[] = { |
59 |
+#ifdef SB_SCHIZO_s390 |
60 |
+#define S(s) { SB_SYS_s390_##s, SB_NR_##s, #s }, |
61 |
+#include "trace_syscalls_s390.h" |
62 |
+#undef S |
63 |
+#endif |
64 |
+ { SB_NR_UNDEF, SB_NR_UNDEF, NULL }, |
65 |
+}; |
66 |
+static const struct syscall_entry syscall_table_64[] = { |
67 |
+#ifdef SB_SCHIZO_s390x |
68 |
+#define S(s) { SB_SYS_s390x_##s, SB_NR_##s, #s }, |
69 |
+#include "trace_syscalls_s390x.h" |
70 |
+#undef S |
71 |
+#endif |
72 |
+ { SB_NR_UNDEF, SB_NR_UNDEF, NULL }, |
73 |
+}; |
74 |
+ |
75 |
+static bool pers_is_31(trace_regs *regs) |
76 |
+{ |
77 |
+ return regs->psw.mask & 0x100000000ul ? false : true; |
78 |
+} |
79 |
+ |
80 |
+static const struct syscall_entry *trace_check_personality(void *vregs) |
81 |
+{ |
82 |
+ trace_regs *regs = vregs; |
83 |
+ return pers_is_31(regs) ? syscall_table_32 : syscall_table_64; |
84 |
+} |
85 |
+ |
86 |
+static bool _trace_possible(const void *data) |
87 |
+{ |
88 |
+ return true; |
89 |
+} |
90 |
+ |
91 |
+#else |
92 |
+ |
93 |
+static bool _trace_possible(const void *data) |
94 |
+{ |
95 |
+# ifdef __s390x__ |
96 |
+# define ELFCLASS ELFCLASS64 |
97 |
+# else |
98 |
+# define ELFCLASS ELFCLASS32 |
99 |
+# endif |
100 |
+ const Elf64_Ehdr *ehdr = data; |
101 |
+ return (ehdr->e_ident[EI_CLASS] == ELFCLASS) && |
102 |
+ (ehdr->e_machine == EM_S390); |
103 |
+} |
104 |
+ |
105 |
+#endif |
106 |
+ |
107 |
+#undef trace_get_regs |
108 |
+static long trace_get_regs(void *vregs) |
109 |
+{ |
110 |
+ ptrace_area parea = { |
111 |
+ /* Most regs we want are at the start (pswmask, pswaddr, and gpr0...gpr7, |
112 |
+ * but the orig_gpr2 is much further along in the area. */ |
113 |
+ .len = PT_ORIGGPR2 + sizeof(long), |
114 |
+ .kernel_addr = PT_PSWMASK, |
115 |
+ .process_addr = (uintptr_t)vregs, |
116 |
+ }; |
117 |
+ do_ptrace(PTRACE_PEEKUSR_AREA, &parea, NULL); |
118 |
+ return 0; |
119 |
+} |
120 |
+ |
121 |
+#undef trace_set_regs |
122 |
+static long trace_set_regs(void *vregs) |
123 |
+{ |
124 |
+ ptrace_area parea = { |
125 |
+ /* Most regs we want are at the start (pswmask, pswaddr, and gpr0...gpr7, |
126 |
+ * but the orig_gpr2 is much further along in the area. */ |
127 |
+ .len = PT_ORIGGPR2 + sizeof(long), |
128 |
+ .kernel_addr = PT_PSWMASK, |
129 |
+ .process_addr = (uintptr_t)vregs, |
130 |
+ }; |
131 |
+ do_ptrace(PTRACE_POKEUSR_AREA, &parea, NULL); |
132 |
+ return 0; |
133 |
+} |
134 |
+ |
135 |
+#define trace_reg_sysnum gprs[2] |
136 |
+#define trace_reg_ret gprs[2] |
137 |
+ |
138 |
+static unsigned long trace_arg(void *vregs, int num) |
139 |
+{ |
140 |
+ trace_regs *regs = vregs; |
141 |
+ if (num == 1) |
142 |
+ return regs->orig_gpr2; |
143 |
+ else if (num < 7) |
144 |
+ return regs->gprs[2 + num - 1]; |
145 |
+ else |
146 |
+ return -1; |
147 |
+} |