add asm to save regs on x86-32, for gdb
[ust.git] / include / ust / processor.h
CommitLineData
5af57e62
PMF
1#ifndef UST_PROCESSOR_H
2#define UST_PROCESSOR_H
d98a01c6
PMF
3
4#include <stddef.h>
636ca5d6
PMF
5#include <string.h>
6
7extern __thread long ust_reg_stack[500];
8extern volatile __thread long *ust_reg_stack_ptr;
9
e003d6ee 10#ifndef __x86_64
d98a01c6
PMF
11
12struct registers {
7756d65a
PMF
13 short ss;
14 short cs;
d98a01c6 15 long esi;
7756d65a
PMF
16 long ebp;
17 long edx;
18 long ecx;
d98a01c6 19 long edi;
7756d65a
PMF
20 long ebx;
21 long eax;
d98a01c6 22 long eflags;
7756d65a 23 long esp;
d98a01c6
PMF
24};
25
e003d6ee 26#ifdef CONFIG_UST_GDB_INTEGRATION
defa46a7 27
7756d65a
PMF
28//#error "GDB integration not supported for x86-32 yet."
29
30#define save_registers(regsptr) \
31 asm volatile ( \
32 /* save original esp */ \
33 "pushl %%esp\n\t" \
34 /* push original eflags */ \
35 "pushfl\n\t" \
36 /* eax will hold the ptr to the private stack bottom */ \
37 "pushl %%eax\n\t" \
38 /* ebx will be used to temporarily hold the stack bottom addr */ \
39 "pushl %%ebx\n\t" \
40 /* rdi is the input to __tls_get_addr, and also a temp var */ \
41 "pushl %%edi\n\t" \
42 /* Start TLS access of private reg stack pointer */ \
43 "leal ust_reg_stack_ptr@tlsgd(,%%ebx,1),%%eax\n\t" \
44 "call ___tls_get_addr@plt\n\t" \
45 /* --- End TLS access */ \
46 /* check if ust_reg_stack_ptr has been initialized */ \
47 "movl (%%eax),%%ebx\n\t" \
48 "testl %%ebx,%%ebx\n\t" \
49 "jne 1f\n\t" \
50 "movl %%eax,%%ebx\n\t" \
51 /* Start TLS access of private reg stack */ \
52 "leal ust_reg_stack@tlsgd(,%%ebx,1),%%eax\n\t" \
53 "call ___tls_get_addr@plt\n\t" \
54 /* --- End TLS access */ \
55 "addl $500,%%eax\n\t" \
56 "movl %%eax,(%%ebx)\n\t" \
57 "movl %%ebx,%%eax\n\t" \
58 /* now the pointer to the private stack is in eax. \
59 must add stack size so the ptr points to the stack bottom. */ \
60 "1:\n\t" \
61 /* Manually push esp to private stack */ \
62 "addl $-4,(%%eax)\n\t" \
63 "movl 16(%%esp), %%edi\n\t" \
64 "movl (%%eax), %%ebx\n\t" \
65 "movl %%edi, (%%ebx)\n\t" \
66 /* Manually push eflags to private stack */ \
67 "addl $-4,(%%eax)\n\t" \
68 "movl 12(%%esp), %%edi\n\t" \
69 "movl (%%eax), %%ebx\n\t" \
70 "movl %%edi, (%%ebx)\n\t" \
71 /* Manually push eax to private stack */ \
72 "addl $-4,(%%eax)\n\t" \
73 "movl 8(%%esp), %%edi\n\t" \
74 "movl (%%eax), %%ebx\n\t" \
75 "movl %%edi, (%%ebx)\n\t" \
76 /* Manually push ebx to private stack */ \
77 "addl $-4,(%%eax)\n\t" \
78 "movl 4(%%esp), %%edi\n\t" \
79 "movl (%%eax), %%ebx\n\t" \
80 "movl %%edi, (%%ebx)\n\t" \
81 /* Manually push edi to private stack */ \
82 "addl $-4,(%%eax)\n\t" \
83 "movl 0(%%esp), %%edi\n\t" \
84 "movl (%%eax), %%ebx\n\t" \
85 "movl %%edi, (%%ebx)\n\t" \
86 /* now push regs to tls */ \
87 /* -- esp already pushed -- */ \
88 /* -- eax already pushed -- */ \
89 /* -- ebx already pushed -- */ \
90 /* -- edi already pushed -- */ \
91 "addl $-4,(%%eax)\n\t" \
92 "movl (%%eax), %%ebx\n\t" \
93 "movl %%ecx,(%%ebx)\n\t" \
94 "addl $-4,(%%eax)\n\t" \
95 "movl (%%eax), %%ebx\n\t" \
96 "movl %%edx,(%%ebx)\n\t" \
97 "addl $-4,(%%eax)\n\t" \
98 "movl (%%eax), %%ebx\n\t" \
99 "movl %%ebp,(%%ebx)\n\t" \
100 "addl $-4,(%%eax)\n\t" \
101 "movl (%%eax), %%ebx\n\t" \
102 "movl %%esi,(%%ebx)\n\t" \
103 /* push cs */ \
104 "addl $-2,(%%eax)\n\t" \
105 "movl (%%eax), %%ebx\n\t" \
106 "movw %%cs, (%%ebx)\n\t" \
107 /* push ss */ \
108 "addl $-2,(%%eax)\n\t" \
109 "movl (%%eax), %%ebx\n\t" \
110 "movw %%ss, (%%ebx)\n\t" \
111 /* restore original values of regs that were used internally */ \
112 "popl %%edi\n\t" \
113 "popl %%ebx\n\t" \
114 "popl %%eax\n\t" \
115 /* cancel push of rsp */ \
116 "addl $4,%%esp\n\t" \
117 /* cancel push of eflags */ \
118 "addl $4,%%esp\n\t" \
119 ::: "memory"); \
120 memcpy(regsptr, (void *)ust_reg_stack_ptr, sizeof(struct registers)); \
121 ust_reg_stack_ptr = (void *)(((long)ust_reg_stack_ptr) + sizeof(struct registers));
defa46a7 122
fc1f31ab 123#define save_ip(channel,name)
7756d65a 124
defa46a7 125
e003d6ee 126#else /* CONFIG_UST_GDB_INTEGRATION */
defa46a7 127
fc1f31ab 128#define save_ip(channel,name)
defa46a7
PMF
129#define save_registers(a)
130
e003d6ee 131#endif /* CONFIG_UST_GDB_INTEGRATION */
d98a01c6 132
9e8f4f52
PMF
133#define RELATIVE_ADDRESS(__rel_label__) __rel_label__
134
135#define _ASM_PTR ".long "
136
defa46a7 137#else /* below is code for x86-64 */
d98a01c6
PMF
138
139struct registers {
636ca5d6
PMF
140 int padding; /* 4 bytes */
141 short ss;
142 short cs;
636ca5d6
PMF
143 unsigned long r15;
144 unsigned long r14;
145 unsigned long r13;
146 unsigned long r12;
147 unsigned long r11;
148 unsigned long r10;
149 unsigned long r9;
150 unsigned long r8;
d98a01c6 151 unsigned long rsi;
636ca5d6
PMF
152 unsigned long rbp;
153 unsigned long rdx;
154 unsigned long rcx;
d98a01c6 155 unsigned long rdi;
636ca5d6
PMF
156 unsigned long rbx;
157 unsigned long rax;
a5850bc4 158 unsigned long rflags;
636ca5d6 159 unsigned long rsp;
d98a01c6
PMF
160};
161
e003d6ee
PMF
162#ifdef CONFIG_UST_GDB_INTEGRATION
163#define save_ip(channel,name) \
defa46a7
PMF
164 asm (".section __marker_addr,\"aw\",@progbits\n\t" \
165 _ASM_PTR "%c[marker_struct], (1f)\n\t" \
166 ".previous\n\t" \
167 "1:\n\t" \
168 :: [marker_struct] "i" (&__mark_##channel##_##name));\
169
8524c98d 170#define save_registers(regsptr) \
636ca5d6
PMF
171 asm volatile ( \
172 /* save original rsp */ \
173 "pushq %%rsp\n\t" \
a5850bc4
PMF
174 /* push original rflags */ \
175 "pushfq\n\t" \
636ca5d6
PMF
176 /* rax will hold the ptr to the private stack bottom */ \
177 "pushq %%rax\n\t" \
178 /* rbx will be used to temporarily hold the stack bottom addr */ \
179 "pushq %%rbx\n\t" \
180 /* rdi is the input to __tls_get_addr, and also a temp var */ \
181 "pushq %%rdi\n\t" \
a5850bc4 182 /* Start TLS access of private reg stack pointer */ \
636ca5d6
PMF
183 ".byte 0x66\n\t" \
184 "leaq ust_reg_stack_ptr@tlsgd(%%rip), %%rdi\n\t" \
185 ".word 0x6666\n\t" \
186 "rex64\n\t" \
187 "call __tls_get_addr@plt\n\t" \
188 /* --- End TLS access */ \
a5850bc4
PMF
189 /* check if ust_reg_stack_ptr has been initialized */ \
190 "movq (%%rax),%%rbx\n\t" \
191 "testq %%rbx,%%rbx\n\t" \
192 "jne 1f\n\t" \
193 "movq %%rax,%%rbx\n\t" \
194 /* Start TLS access of private reg stack */ \
195 ".byte 0x66\n\t" \
196 "leaq ust_reg_stack@tlsgd(%%rip), %%rdi\n\t" \
197 ".word 0x6666\n\t" \
198 "rex64\n\t" \
199 "call __tls_get_addr@plt\n\t" \
200 /* --- End TLS access */ \
201 "addq $500,%%rax\n\t" \
202 "movq %%rax,(%%rbx)\n\t" \
203 "movq %%rbx,%%rax\n\t" \
204 /* now the pointer to the private stack is in rax.
205 must add stack size so the ptr points to the stack bottom. */ \
206 "1:\n\t" \
636ca5d6
PMF
207 /* Manually push rsp to private stack */ \
208 "addq $-8,(%%rax)\n\t" \
a5850bc4
PMF
209 "movq 32(%%rsp), %%rdi\n\t" \
210 "movq (%%rax), %%rbx\n\t" \
211 "movq %%rdi, (%%rbx)\n\t" \
212 /* Manually push eflags to private stack */ \
213 "addq $-8,(%%rax)\n\t" \
636ca5d6
PMF
214 "movq 24(%%rsp), %%rdi\n\t" \
215 "movq (%%rax), %%rbx\n\t" \
216 "movq %%rdi, (%%rbx)\n\t" \
217 /* Manually push rax to private stack */ \
218 "addq $-8,(%%rax)\n\t" \
219 "movq 16(%%rsp), %%rdi\n\t" \
220 "movq (%%rax), %%rbx\n\t" \
221 "movq %%rdi, (%%rbx)\n\t" \
222 /* Manually push rbx to private stack */ \
223 "addq $-8,(%%rax)\n\t" \
224 "movq 8(%%rsp), %%rdi\n\t" \
225 "movq (%%rax), %%rbx\n\t" \
226 "movq %%rdi, (%%rbx)\n\t" \
227 /* Manually push rdi to private stack */ \
228 "addq $-8,(%%rax)\n\t" \
229 "movq 0(%%rsp), %%rdi\n\t" \
230 "movq (%%rax), %%rbx\n\t" \
231 "movq %%rdi, (%%rbx)\n\t" \
232 /* now push regs to tls */ \
233 /* -- rsp already pushed -- */ \
234 /* -- rax already pushed -- */ \
235 /* -- rbx already pushed -- */ \
236 /* -- rdi already pushed -- */ \
237 "addq $-8,(%%rax)\n\t" \
238 "movq (%%rax), %%rbx\n\t" \
239 "movq %%rcx,(%%rbx)\n\t" \
240 "addq $-8,(%%rax)\n\t" \
241 "movq (%%rax), %%rbx\n\t" \
242 "movq %%rdx,(%%rbx)\n\t" \
243 "addq $-8,(%%rax)\n\t" \
244 "movq (%%rax), %%rbx\n\t" \
245 "movq %%rbp,(%%rbx)\n\t" \
246 "addq $-8,(%%rax)\n\t" \
247 "movq (%%rax), %%rbx\n\t" \
248 "movq %%rsi,(%%rbx)\n\t" \
249 "addq $-8,(%%rax)\n\t" \
250 "movq (%%rax), %%rbx\n\t" \
251 "movq %%r8,(%%rbx)\n\t" \
252 "addq $-8,(%%rax)\n\t" \
253 "movq (%%rax), %%rbx\n\t" \
254 "movq %%r9,(%%rbx)\n\t" \
255 "addq $-8,(%%rax)\n\t" \
256 "movq (%%rax), %%rbx\n\t" \
257 "movq %%r10,(%%rbx)\n\t" \
258 "addq $-8,(%%rax)\n\t" \
259 "movq (%%rax), %%rbx\n\t" \
260 "movq %%r11,(%%rbx)\n\t" \
261 "addq $-8,(%%rax)\n\t" \
262 "movq (%%rax), %%rbx\n\t" \
263 "movq %%r12,(%%rbx)\n\t" \
264 "addq $-8,(%%rax)\n\t" \
265 "movq (%%rax), %%rbx\n\t" \
266 "movq %%r13,(%%rbx)\n\t" \
267 "addq $-8,(%%rax)\n\t" \
268 "movq (%%rax), %%rbx\n\t" \
269 "movq %%r14,(%%rbx)\n\t" \
270 "addq $-8,(%%rax)\n\t" \
271 "movq (%%rax), %%rbx\n\t" \
272 "movq %%r15,(%%rbx)\n\t" \
636ca5d6
PMF
273 /* push cs */ \
274 "addq $-2,(%%rax)\n\t" \
275 "movq (%%rax), %%rbx\n\t" \
276 "movw %%cs, (%%rbx)\n\t" \
277 /* push ss */ \
278 "addq $-2,(%%rax)\n\t" \
279 "movq (%%rax), %%rbx\n\t" \
280 "movw %%ss, (%%rbx)\n\t" \
281 /* add padding for struct registers */ \
282 "addq $-4,(%%rax)\n\t" \
283 /* restore original values of regs that were used internally */ \
284 "popq %%rdi\n\t" \
285 "popq %%rbx\n\t" \
286 "popq %%rax\n\t" \
287 /* cancel push of rsp */ \
288 "addq $8,%%rsp\n\t" \
a5850bc4
PMF
289 /* cancel push of rflags */ \
290 "addq $8,%%rsp\n\t" \
636ca5d6
PMF
291 ::); \
292 memcpy(regsptr, (void *)ust_reg_stack_ptr, sizeof(struct registers)); \
293 ust_reg_stack_ptr = (void *)(((long)ust_reg_stack_ptr) + sizeof(struct registers));
d98a01c6 294
fc1f31ab
PMF
295#else /* CONFIG_UST_GDB_INTEGRATION */
296
297#define save_ip(channel,name)
298#define save_registers(a)
299
e003d6ee 300#endif /* CONFIG_UST_GDB_INTEGRATION */
defa46a7 301
9e8f4f52
PMF
302/* Macro to insert the address of a relative jump in an assembly stub,
303 * in a relocatable way. On x86-64, this uses a special (%rip) notation. */
304#define RELATIVE_ADDRESS(__rel_label__) __rel_label__(%%rip)
305
306#define _ASM_PTR ".quad "
307
d98a01c6
PMF
308#endif
309
5af57e62 310#endif /* UST_PROCESSOR_H */
This page took 0.035636 seconds and 4 git commands to generate.