aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorRoland McGrath <roland@redhat.com>2008-04-18 20:08:44 -0400
committerRoland McGrath <roland@redhat.com>2008-07-26 17:38:01 -0400
commit68bd0f4ef7750fc277e1268bf40f443898382409 (patch)
tree8db4ce3a3e54e07deeb4a3616f02bbdb338e93fd /include
parenteeea3c3ff8af7f6960a0515d46dff6479bdb91f9 (diff)
x86: tracehook: asm/syscall.h
Add asm/syscall.h for x86 with all the required entry points. This will allow arch-independent tracing code for system calls. Signed-off-by: Roland McGrath <roland@redhat.com>
Diffstat (limited to 'include')
-rw-r--r--include/asm-x86/ptrace.h5
-rw-r--r--include/asm-x86/syscall.h210
2 files changed, 215 insertions, 0 deletions
diff --git a/include/asm-x86/ptrace.h b/include/asm-x86/ptrace.h
index 8a71db803da6..91a77f5c4678 100644
--- a/include/asm-x86/ptrace.h
+++ b/include/asm-x86/ptrace.h
@@ -213,6 +213,11 @@ static inline unsigned long frame_pointer(struct pt_regs *regs)
213 return regs->bp; 213 return regs->bp;
214} 214}
215 215
216static inline unsigned long user_stack_pointer(struct pt_regs *regs)
217{
218 return regs->sp;
219}
220
216/* 221/*
217 * These are defined as per linux/ptrace.h, which see. 222 * These are defined as per linux/ptrace.h, which see.
218 */ 223 */
diff --git a/include/asm-x86/syscall.h b/include/asm-x86/syscall.h
new file mode 100644
index 000000000000..6f293892895a
--- /dev/null
+++ b/include/asm-x86/syscall.h
@@ -0,0 +1,210 @@
1/*
2 * Access to user system call parameters and results
3 *
4 * Copyright (C) 2008 Red Hat, Inc. All rights reserved.
5 *
6 * This copyrighted material is made available to anyone wishing to use,
7 * modify, copy, or redistribute it subject to the terms and conditions
8 * of the GNU General Public License v.2.
9 *
10 * See asm-generic/syscall.h for descriptions of what we must do here.
11 */
12
13#ifndef _ASM_SYSCALL_H
14#define _ASM_SYSCALL_H 1
15
16#include <linux/sched.h>
17
18static inline long syscall_get_nr(struct task_struct *task,
19 struct pt_regs *regs)
20{
21 /*
22 * We always sign-extend a -1 value being set here,
23 * so this is always either -1L or a syscall number.
24 */
25 return regs->orig_ax;
26}
27
28static inline void syscall_rollback(struct task_struct *task,
29 struct pt_regs *regs)
30{
31 regs->ax = regs->orig_ax;
32}
33
34static inline long syscall_get_error(struct task_struct *task,
35 struct pt_regs *regs)
36{
37 unsigned long error = regs->ax;
38#ifdef CONFIG_IA32_EMULATION
39 /*
40 * TS_COMPAT is set for 32-bit syscall entries and then
41 * remains set until we return to user mode.
42 */
43 if (task_thread_info(task)->status & TS_COMPAT)
44 /*
45 * Sign-extend the value so (int)-EFOO becomes (long)-EFOO
46 * and will match correctly in comparisons.
47 */
48 error = (long) (int) error;
49#endif
50 return error >= -4095L ? error : 0;
51}
52
53static inline long syscall_get_return_value(struct task_struct *task,
54 struct pt_regs *regs)
55{
56 return regs->ax;
57}
58
59static inline void syscall_set_return_value(struct task_struct *task,
60 struct pt_regs *regs,
61 int error, long val)
62{
63 regs->ax = (long) error ?: val;
64}
65
66#ifdef CONFIG_X86_32
67
68static inline void syscall_get_arguments(struct task_struct *task,
69 struct pt_regs *regs,
70 unsigned int i, unsigned int n,
71 unsigned long *args)
72{
73 BUG_ON(i + n > 6);
74 memcpy(args, &regs->bx + i, n * sizeof(args[0]));
75}
76
77static inline void syscall_set_arguments(struct task_struct *task,
78 struct pt_regs *regs,
79 unsigned int i, unsigned int n,
80 const unsigned long *args)
81{
82 BUG_ON(i + n > 6);
83 memcpy(&regs->bx + i, args, n * sizeof(args[0]));
84}
85
86#else /* CONFIG_X86_64 */
87
88static inline void syscall_get_arguments(struct task_struct *task,
89 struct pt_regs *regs,
90 unsigned int i, unsigned int n,
91 unsigned long *args)
92{
93# ifdef CONFIG_IA32_EMULATION
94 if (task_thread_info(task)->status & TS_COMPAT)
95 switch (i + n) {
96 case 6:
97 if (!n--) break;
98 *args++ = regs->bp;
99 case 5:
100 if (!n--) break;
101 *args++ = regs->di;
102 case 4:
103 if (!n--) break;
104 *args++ = regs->si;
105 case 3:
106 if (!n--) break;
107 *args++ = regs->dx;
108 case 2:
109 if (!n--) break;
110 *args++ = regs->cx;
111 case 1:
112 if (!n--) break;
113 *args++ = regs->bx;
114 case 0:
115 if (!n--) break;
116 default:
117 BUG();
118 break;
119 }
120 else
121# endif
122 switch (i + n) {
123 case 6:
124 if (!n--) break;
125 *args++ = regs->r9;
126 case 5:
127 if (!n--) break;
128 *args++ = regs->r8;
129 case 4:
130 if (!n--) break;
131 *args++ = regs->r10;
132 case 3:
133 if (!n--) break;
134 *args++ = regs->dx;
135 case 2:
136 if (!n--) break;
137 *args++ = regs->si;
138 case 1:
139 if (!n--) break;
140 *args++ = regs->di;
141 case 0:
142 if (!n--) break;
143 default:
144 BUG();
145 break;
146 }
147}
148
149static inline void syscall_set_arguments(struct task_struct *task,
150 struct pt_regs *regs,
151 unsigned int i, unsigned int n,
152 const unsigned long *args)
153{
154# ifdef CONFIG_IA32_EMULATION
155 if (task_thread_info(task)->status & TS_COMPAT)
156 switch (i + n) {
157 case 6:
158 if (!n--) break;
159 regs->bp = *args++;
160 case 5:
161 if (!n--) break;
162 regs->di = *args++;
163 case 4:
164 if (!n--) break;
165 regs->si = *args++;
166 case 3:
167 if (!n--) break;
168 regs->dx = *args++;
169 case 2:
170 if (!n--) break;
171 regs->cx = *args++;
172 case 1:
173 if (!n--) break;
174 regs->bx = *args++;
175 case 0:
176 if (!n--) break;
177 default:
178 BUG();
179 }
180 else
181# endif
182 switch (i + n) {
183 case 6:
184 if (!n--) break;
185 regs->r9 = *args++;
186 case 5:
187 if (!n--) break;
188 regs->r8 = *args++;
189 case 4:
190 if (!n--) break;
191 regs->r10 = *args++;
192 case 3:
193 if (!n--) break;
194 regs->dx = *args++;
195 case 2:
196 if (!n--) break;
197 regs->si = *args++;
198 case 1:
199 if (!n--) break;
200 regs->di = *args++;
201 case 0:
202 if (!n--) break;
203 default:
204 BUG();
205 }
206}
207
208#endif /* CONFIG_X86_32 */
209
210#endif /* _ASM_SYSCALL_H */