.. | .. |
---|
7 | 7 | * (C) Copyright 2016-2018 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com> |
---|
8 | 8 | */ |
---|
9 | 9 | |
---|
10 | | -#define RSEQ_SIG 0x53053053 |
---|
| 10 | +/* |
---|
| 11 | + * RSEQ_SIG uses the break instruction. The instruction pattern is: |
---|
| 12 | + * |
---|
| 13 | + * On MIPS: |
---|
| 14 | + * 0350000d break 0x350 |
---|
| 15 | + * |
---|
| 16 | + * On nanoMIPS: |
---|
| 17 | + * 00100350 break 0x350 |
---|
| 18 | + * |
---|
| 19 | + * On microMIPS: |
---|
| 20 | + * 0000d407 break 0x350 |
---|
| 21 | + * |
---|
| 22 | + * For nanoMIPS32 and microMIPS, the instruction stream is encoded as 16-bit |
---|
| 23 | + * halfwords, so the signature halfwords need to be swapped accordingly for |
---|
| 24 | + * little-endian. |
---|
| 25 | + */ |
---|
| 26 | +#if defined(__nanomips__) |
---|
| 27 | +# ifdef __MIPSEL__ |
---|
| 28 | +# define RSEQ_SIG 0x03500010 |
---|
| 29 | +# else |
---|
| 30 | +# define RSEQ_SIG 0x00100350 |
---|
| 31 | +# endif |
---|
| 32 | +#elif defined(__mips_micromips) |
---|
| 33 | +# ifdef __MIPSEL__ |
---|
| 34 | +# define RSEQ_SIG 0xd4070000 |
---|
| 35 | +# else |
---|
| 36 | +# define RSEQ_SIG 0x0000d407 |
---|
| 37 | +# endif |
---|
| 38 | +#elif defined(__mips__) |
---|
| 39 | +# define RSEQ_SIG 0x0350000d |
---|
| 40 | +#else |
---|
| 41 | +/* Unknown MIPS architecture. */ |
---|
| 42 | +#endif |
---|
11 | 43 | |
---|
12 | 44 | #define rseq_smp_mb() __asm__ __volatile__ ("sync" ::: "memory") |
---|
13 | 45 | #define rseq_smp_rmb() rseq_smp_mb() |
---|
.. | .. |
---|
54 | 86 | # error unsupported _MIPS_SZLONG |
---|
55 | 87 | #endif |
---|
56 | 88 | |
---|
57 | | -#define __RSEQ_ASM_DEFINE_TABLE(version, flags, start_ip, \ |
---|
| 89 | +#define __RSEQ_ASM_DEFINE_TABLE(label, version, flags, start_ip, \ |
---|
58 | 90 | post_commit_offset, abort_ip) \ |
---|
59 | | - ".pushsection __rseq_table, \"aw\"\n\t" \ |
---|
| 91 | + ".pushsection __rseq_cs, \"aw\"\n\t" \ |
---|
60 | 92 | ".balign 32\n\t" \ |
---|
| 93 | + __rseq_str(label) ":\n\t" \ |
---|
61 | 94 | ".word " __rseq_str(version) ", " __rseq_str(flags) "\n\t" \ |
---|
62 | 95 | LONG " " U32_U64_PAD(__rseq_str(start_ip)) "\n\t" \ |
---|
63 | 96 | LONG " " U32_U64_PAD(__rseq_str(post_commit_offset)) "\n\t" \ |
---|
64 | 97 | LONG " " U32_U64_PAD(__rseq_str(abort_ip)) "\n\t" \ |
---|
| 98 | + ".popsection\n\t" \ |
---|
| 99 | + ".pushsection __rseq_cs_ptr_array, \"aw\"\n\t" \ |
---|
| 100 | + LONG " " U32_U64_PAD(__rseq_str(label) "b") "\n\t" \ |
---|
65 | 101 | ".popsection\n\t" |
---|
66 | 102 | |
---|
67 | | -#define RSEQ_ASM_DEFINE_TABLE(start_ip, post_commit_ip, abort_ip) \ |
---|
68 | | - __RSEQ_ASM_DEFINE_TABLE(0x0, 0x0, start_ip, \ |
---|
| 103 | +#define RSEQ_ASM_DEFINE_TABLE(label, start_ip, post_commit_ip, abort_ip) \ |
---|
| 104 | + __RSEQ_ASM_DEFINE_TABLE(label, 0x0, 0x0, start_ip, \ |
---|
69 | 105 | (post_commit_ip - start_ip), abort_ip) |
---|
| 106 | + |
---|
| 107 | +/* |
---|
| 108 | + * Exit points of a rseq critical section consist of all instructions outside |
---|
| 109 | + * of the critical section where a critical section can either branch to or |
---|
| 110 | + * reach through the normal course of its execution. The abort IP and the |
---|
| 111 | + * post-commit IP are already part of the __rseq_cs section and should not be |
---|
| 112 | + * explicitly defined as additional exit points. Knowing all exit points is |
---|
| 113 | + * useful to assist debuggers stepping over the critical section. |
---|
| 114 | + */ |
---|
| 115 | +#define RSEQ_ASM_DEFINE_EXIT_POINT(start_ip, exit_ip) \ |
---|
| 116 | + ".pushsection __rseq_exit_point_array, \"aw\"\n\t" \ |
---|
| 117 | + LONG " " U32_U64_PAD(__rseq_str(start_ip)) "\n\t" \ |
---|
| 118 | + LONG " " U32_U64_PAD(__rseq_str(exit_ip)) "\n\t" \ |
---|
| 119 | + ".popsection\n\t" |
---|
70 | 120 | |
---|
71 | 121 | #define RSEQ_ASM_STORE_RSEQ_CS(label, cs_label, rseq_cs) \ |
---|
72 | 122 | RSEQ_INJECT_ASM(1) \ |
---|
.. | .. |
---|
104 | 154 | teardown \ |
---|
105 | 155 | "b %l[" __rseq_str(cmpfail_label) "]\n\t" |
---|
106 | 156 | |
---|
107 | | -#define rseq_workaround_gcc_asm_size_guess() __asm__ __volatile__("") |
---|
108 | | - |
---|
109 | 157 | static inline __attribute__((always_inline)) |
---|
110 | 158 | int rseq_cmpeqv_storev(intptr_t *v, intptr_t expect, intptr_t newv, int cpu) |
---|
111 | 159 | { |
---|
112 | 160 | RSEQ_INJECT_C(9) |
---|
113 | 161 | |
---|
114 | | - rseq_workaround_gcc_asm_size_guess(); |
---|
115 | 162 | __asm__ __volatile__ goto ( |
---|
116 | | - RSEQ_ASM_DEFINE_TABLE(1f, 2f, 4f) /* start, commit, abort */ |
---|
| 163 | + RSEQ_ASM_DEFINE_TABLE(9, 1f, 2f, 4f) /* start, commit, abort */ |
---|
| 164 | + RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail]) |
---|
| 165 | +#ifdef RSEQ_COMPARE_TWICE |
---|
| 166 | + RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1]) |
---|
| 167 | + RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2]) |
---|
| 168 | +#endif |
---|
117 | 169 | /* Start rseq by storing table entry pointer into rseq_cs. */ |
---|
118 | 170 | RSEQ_ASM_STORE_RSEQ_CS(1, 3f, rseq_cs) |
---|
119 | 171 | RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f) |
---|
.. | .. |
---|
135 | 187 | "5:\n\t" |
---|
136 | 188 | : /* gcc asm goto does not allow outputs */ |
---|
137 | 189 | : [cpu_id] "r" (cpu), |
---|
138 | | - [current_cpu_id] "m" (__rseq_abi.cpu_id), |
---|
139 | | - [rseq_cs] "m" (__rseq_abi.rseq_cs), |
---|
| 190 | + [current_cpu_id] "m" (rseq_get_abi()->cpu_id), |
---|
| 191 | + [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr), |
---|
140 | 192 | [v] "m" (*v), |
---|
141 | 193 | [expect] "r" (expect), |
---|
142 | 194 | [newv] "r" (newv) |
---|
.. | .. |
---|
148 | 200 | , error1, error2 |
---|
149 | 201 | #endif |
---|
150 | 202 | ); |
---|
151 | | - rseq_workaround_gcc_asm_size_guess(); |
---|
152 | 203 | return 0; |
---|
153 | 204 | abort: |
---|
154 | | - rseq_workaround_gcc_asm_size_guess(); |
---|
155 | 205 | RSEQ_INJECT_FAILED |
---|
156 | 206 | return -1; |
---|
157 | 207 | cmpfail: |
---|
158 | | - rseq_workaround_gcc_asm_size_guess(); |
---|
159 | 208 | return 1; |
---|
160 | 209 | #ifdef RSEQ_COMPARE_TWICE |
---|
161 | 210 | error1: |
---|
.. | .. |
---|
167 | 216 | |
---|
168 | 217 | static inline __attribute__((always_inline)) |
---|
169 | 218 | int rseq_cmpnev_storeoffp_load(intptr_t *v, intptr_t expectnot, |
---|
170 | | - off_t voffp, intptr_t *load, int cpu) |
---|
| 219 | + long voffp, intptr_t *load, int cpu) |
---|
171 | 220 | { |
---|
172 | 221 | RSEQ_INJECT_C(9) |
---|
173 | 222 | |
---|
174 | | - rseq_workaround_gcc_asm_size_guess(); |
---|
175 | 223 | __asm__ __volatile__ goto ( |
---|
176 | | - RSEQ_ASM_DEFINE_TABLE(1f, 2f, 4f) /* start, commit, abort */ |
---|
| 224 | + RSEQ_ASM_DEFINE_TABLE(9, 1f, 2f, 4f) /* start, commit, abort */ |
---|
| 225 | + RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail]) |
---|
| 226 | +#ifdef RSEQ_COMPARE_TWICE |
---|
| 227 | + RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1]) |
---|
| 228 | + RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2]) |
---|
| 229 | +#endif |
---|
177 | 230 | /* Start rseq by storing table entry pointer into rseq_cs. */ |
---|
178 | 231 | RSEQ_ASM_STORE_RSEQ_CS(1, 3f, rseq_cs) |
---|
179 | 232 | RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f) |
---|
.. | .. |
---|
198 | 251 | "5:\n\t" |
---|
199 | 252 | : /* gcc asm goto does not allow outputs */ |
---|
200 | 253 | : [cpu_id] "r" (cpu), |
---|
201 | | - [current_cpu_id] "m" (__rseq_abi.cpu_id), |
---|
202 | | - [rseq_cs] "m" (__rseq_abi.rseq_cs), |
---|
| 254 | + [current_cpu_id] "m" (rseq_get_abi()->cpu_id), |
---|
| 255 | + [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr), |
---|
203 | 256 | /* final store input */ |
---|
204 | 257 | [v] "m" (*v), |
---|
205 | 258 | [expectnot] "r" (expectnot), |
---|
.. | .. |
---|
213 | 266 | , error1, error2 |
---|
214 | 267 | #endif |
---|
215 | 268 | ); |
---|
216 | | - rseq_workaround_gcc_asm_size_guess(); |
---|
217 | 269 | return 0; |
---|
218 | 270 | abort: |
---|
219 | | - rseq_workaround_gcc_asm_size_guess(); |
---|
220 | 271 | RSEQ_INJECT_FAILED |
---|
221 | 272 | return -1; |
---|
222 | 273 | cmpfail: |
---|
223 | | - rseq_workaround_gcc_asm_size_guess(); |
---|
224 | 274 | return 1; |
---|
225 | 275 | #ifdef RSEQ_COMPARE_TWICE |
---|
226 | 276 | error1: |
---|
.. | .. |
---|
235 | 285 | { |
---|
236 | 286 | RSEQ_INJECT_C(9) |
---|
237 | 287 | |
---|
238 | | - rseq_workaround_gcc_asm_size_guess(); |
---|
239 | 288 | __asm__ __volatile__ goto ( |
---|
240 | | - RSEQ_ASM_DEFINE_TABLE(1f, 2f, 4f) /* start, commit, abort */ |
---|
| 289 | + RSEQ_ASM_DEFINE_TABLE(9, 1f, 2f, 4f) /* start, commit, abort */ |
---|
| 290 | +#ifdef RSEQ_COMPARE_TWICE |
---|
| 291 | + RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1]) |
---|
| 292 | +#endif |
---|
241 | 293 | /* Start rseq by storing table entry pointer into rseq_cs. */ |
---|
242 | 294 | RSEQ_ASM_STORE_RSEQ_CS(1, 3f, rseq_cs) |
---|
243 | 295 | RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f) |
---|
.. | .. |
---|
256 | 308 | "5:\n\t" |
---|
257 | 309 | : /* gcc asm goto does not allow outputs */ |
---|
258 | 310 | : [cpu_id] "r" (cpu), |
---|
259 | | - [current_cpu_id] "m" (__rseq_abi.cpu_id), |
---|
260 | | - [rseq_cs] "m" (__rseq_abi.rseq_cs), |
---|
| 311 | + [current_cpu_id] "m" (rseq_get_abi()->cpu_id), |
---|
| 312 | + [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr), |
---|
261 | 313 | [v] "m" (*v), |
---|
262 | 314 | [count] "Ir" (count) |
---|
263 | 315 | RSEQ_INJECT_INPUT |
---|
.. | .. |
---|
268 | 320 | , error1 |
---|
269 | 321 | #endif |
---|
270 | 322 | ); |
---|
271 | | - rseq_workaround_gcc_asm_size_guess(); |
---|
272 | 323 | return 0; |
---|
273 | 324 | abort: |
---|
274 | | - rseq_workaround_gcc_asm_size_guess(); |
---|
275 | 325 | RSEQ_INJECT_FAILED |
---|
276 | 326 | return -1; |
---|
277 | 327 | #ifdef RSEQ_COMPARE_TWICE |
---|
.. | .. |
---|
287 | 337 | { |
---|
288 | 338 | RSEQ_INJECT_C(9) |
---|
289 | 339 | |
---|
290 | | - rseq_workaround_gcc_asm_size_guess(); |
---|
291 | 340 | __asm__ __volatile__ goto ( |
---|
292 | | - RSEQ_ASM_DEFINE_TABLE(1f, 2f, 4f) /* start, commit, abort */ |
---|
| 341 | + RSEQ_ASM_DEFINE_TABLE(9, 1f, 2f, 4f) /* start, commit, abort */ |
---|
| 342 | + RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail]) |
---|
| 343 | +#ifdef RSEQ_COMPARE_TWICE |
---|
| 344 | + RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1]) |
---|
| 345 | + RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2]) |
---|
| 346 | +#endif |
---|
293 | 347 | /* Start rseq by storing table entry pointer into rseq_cs. */ |
---|
294 | 348 | RSEQ_ASM_STORE_RSEQ_CS(1, 3f, rseq_cs) |
---|
295 | 349 | RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f) |
---|
.. | .. |
---|
314 | 368 | "5:\n\t" |
---|
315 | 369 | : /* gcc asm goto does not allow outputs */ |
---|
316 | 370 | : [cpu_id] "r" (cpu), |
---|
317 | | - [current_cpu_id] "m" (__rseq_abi.cpu_id), |
---|
318 | | - [rseq_cs] "m" (__rseq_abi.rseq_cs), |
---|
| 371 | + [current_cpu_id] "m" (rseq_get_abi()->cpu_id), |
---|
| 372 | + [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr), |
---|
319 | 373 | /* try store input */ |
---|
320 | 374 | [v2] "m" (*v2), |
---|
321 | 375 | [newv2] "r" (newv2), |
---|
.. | .. |
---|
331 | 385 | , error1, error2 |
---|
332 | 386 | #endif |
---|
333 | 387 | ); |
---|
334 | | - rseq_workaround_gcc_asm_size_guess(); |
---|
335 | 388 | return 0; |
---|
336 | 389 | abort: |
---|
337 | | - rseq_workaround_gcc_asm_size_guess(); |
---|
338 | 390 | RSEQ_INJECT_FAILED |
---|
339 | 391 | return -1; |
---|
340 | 392 | cmpfail: |
---|
341 | | - rseq_workaround_gcc_asm_size_guess(); |
---|
342 | 393 | return 1; |
---|
343 | 394 | #ifdef RSEQ_COMPARE_TWICE |
---|
344 | 395 | error1: |
---|
.. | .. |
---|
355 | 406 | { |
---|
356 | 407 | RSEQ_INJECT_C(9) |
---|
357 | 408 | |
---|
358 | | - rseq_workaround_gcc_asm_size_guess(); |
---|
359 | 409 | __asm__ __volatile__ goto ( |
---|
360 | | - RSEQ_ASM_DEFINE_TABLE(1f, 2f, 4f) /* start, commit, abort */ |
---|
| 410 | + RSEQ_ASM_DEFINE_TABLE(9, 1f, 2f, 4f) /* start, commit, abort */ |
---|
| 411 | + RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail]) |
---|
| 412 | +#ifdef RSEQ_COMPARE_TWICE |
---|
| 413 | + RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1]) |
---|
| 414 | + RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2]) |
---|
| 415 | +#endif |
---|
361 | 416 | /* Start rseq by storing table entry pointer into rseq_cs. */ |
---|
362 | 417 | RSEQ_ASM_STORE_RSEQ_CS(1, 3f, rseq_cs) |
---|
363 | 418 | RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f) |
---|
.. | .. |
---|
383 | 438 | "5:\n\t" |
---|
384 | 439 | : /* gcc asm goto does not allow outputs */ |
---|
385 | 440 | : [cpu_id] "r" (cpu), |
---|
386 | | - [current_cpu_id] "m" (__rseq_abi.cpu_id), |
---|
387 | | - [rseq_cs] "m" (__rseq_abi.rseq_cs), |
---|
| 441 | + [current_cpu_id] "m" (rseq_get_abi()->cpu_id), |
---|
| 442 | + [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr), |
---|
388 | 443 | /* try store input */ |
---|
389 | 444 | [v2] "m" (*v2), |
---|
390 | 445 | [newv2] "r" (newv2), |
---|
.. | .. |
---|
400 | 455 | , error1, error2 |
---|
401 | 456 | #endif |
---|
402 | 457 | ); |
---|
403 | | - rseq_workaround_gcc_asm_size_guess(); |
---|
404 | 458 | return 0; |
---|
405 | 459 | abort: |
---|
406 | | - rseq_workaround_gcc_asm_size_guess(); |
---|
407 | 460 | RSEQ_INJECT_FAILED |
---|
408 | 461 | return -1; |
---|
409 | 462 | cmpfail: |
---|
410 | | - rseq_workaround_gcc_asm_size_guess(); |
---|
411 | 463 | return 1; |
---|
412 | 464 | #ifdef RSEQ_COMPARE_TWICE |
---|
413 | 465 | error1: |
---|
.. | .. |
---|
424 | 476 | { |
---|
425 | 477 | RSEQ_INJECT_C(9) |
---|
426 | 478 | |
---|
427 | | - rseq_workaround_gcc_asm_size_guess(); |
---|
428 | 479 | __asm__ __volatile__ goto ( |
---|
429 | | - RSEQ_ASM_DEFINE_TABLE(1f, 2f, 4f) /* start, commit, abort */ |
---|
| 480 | + RSEQ_ASM_DEFINE_TABLE(9, 1f, 2f, 4f) /* start, commit, abort */ |
---|
| 481 | + RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail]) |
---|
| 482 | +#ifdef RSEQ_COMPARE_TWICE |
---|
| 483 | + RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1]) |
---|
| 484 | + RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2]) |
---|
| 485 | + RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error3]) |
---|
| 486 | +#endif |
---|
430 | 487 | /* Start rseq by storing table entry pointer into rseq_cs. */ |
---|
431 | 488 | RSEQ_ASM_STORE_RSEQ_CS(1, 3f, rseq_cs) |
---|
432 | 489 | RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f) |
---|
.. | .. |
---|
453 | 510 | "5:\n\t" |
---|
454 | 511 | : /* gcc asm goto does not allow outputs */ |
---|
455 | 512 | : [cpu_id] "r" (cpu), |
---|
456 | | - [current_cpu_id] "m" (__rseq_abi.cpu_id), |
---|
457 | | - [rseq_cs] "m" (__rseq_abi.rseq_cs), |
---|
| 513 | + [current_cpu_id] "m" (rseq_get_abi()->cpu_id), |
---|
| 514 | + [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr), |
---|
458 | 515 | /* cmp2 input */ |
---|
459 | 516 | [v2] "m" (*v2), |
---|
460 | 517 | [expect2] "r" (expect2), |
---|
.. | .. |
---|
470 | 527 | , error1, error2, error3 |
---|
471 | 528 | #endif |
---|
472 | 529 | ); |
---|
473 | | - rseq_workaround_gcc_asm_size_guess(); |
---|
474 | 530 | return 0; |
---|
475 | 531 | abort: |
---|
476 | | - rseq_workaround_gcc_asm_size_guess(); |
---|
477 | 532 | RSEQ_INJECT_FAILED |
---|
478 | 533 | return -1; |
---|
479 | 534 | cmpfail: |
---|
480 | | - rseq_workaround_gcc_asm_size_guess(); |
---|
481 | 535 | return 1; |
---|
482 | 536 | #ifdef RSEQ_COMPARE_TWICE |
---|
483 | 537 | error1: |
---|
.. | .. |
---|
498 | 552 | |
---|
499 | 553 | RSEQ_INJECT_C(9) |
---|
500 | 554 | |
---|
501 | | - rseq_workaround_gcc_asm_size_guess(); |
---|
502 | 555 | __asm__ __volatile__ goto ( |
---|
503 | | - RSEQ_ASM_DEFINE_TABLE(1f, 2f, 4f) /* start, commit, abort */ |
---|
| 556 | + RSEQ_ASM_DEFINE_TABLE(9, 1f, 2f, 4f) /* start, commit, abort */ |
---|
| 557 | + RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail]) |
---|
| 558 | +#ifdef RSEQ_COMPARE_TWICE |
---|
| 559 | + RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1]) |
---|
| 560 | + RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2]) |
---|
| 561 | +#endif |
---|
504 | 562 | LONG_S " %[src], %[rseq_scratch0]\n\t" |
---|
505 | 563 | LONG_S " %[dst], %[rseq_scratch1]\n\t" |
---|
506 | 564 | LONG_S " %[len], %[rseq_scratch2]\n\t" |
---|
.. | .. |
---|
565 | 623 | "8:\n\t" |
---|
566 | 624 | : /* gcc asm goto does not allow outputs */ |
---|
567 | 625 | : [cpu_id] "r" (cpu), |
---|
568 | | - [current_cpu_id] "m" (__rseq_abi.cpu_id), |
---|
569 | | - [rseq_cs] "m" (__rseq_abi.rseq_cs), |
---|
| 626 | + [current_cpu_id] "m" (rseq_get_abi()->cpu_id), |
---|
| 627 | + [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr), |
---|
570 | 628 | /* final store input */ |
---|
571 | 629 | [v] "m" (*v), |
---|
572 | 630 | [expect] "r" (expect), |
---|
.. | .. |
---|
586 | 644 | , error1, error2 |
---|
587 | 645 | #endif |
---|
588 | 646 | ); |
---|
589 | | - rseq_workaround_gcc_asm_size_guess(); |
---|
590 | 647 | return 0; |
---|
591 | 648 | abort: |
---|
592 | | - rseq_workaround_gcc_asm_size_guess(); |
---|
593 | 649 | RSEQ_INJECT_FAILED |
---|
594 | 650 | return -1; |
---|
595 | 651 | cmpfail: |
---|
596 | | - rseq_workaround_gcc_asm_size_guess(); |
---|
597 | 652 | return 1; |
---|
598 | 653 | #ifdef RSEQ_COMPARE_TWICE |
---|
599 | 654 | error1: |
---|
600 | | - rseq_workaround_gcc_asm_size_guess(); |
---|
601 | 655 | rseq_bug("cpu_id comparison failed"); |
---|
602 | 656 | error2: |
---|
603 | | - rseq_workaround_gcc_asm_size_guess(); |
---|
604 | 657 | rseq_bug("expected value comparison failed"); |
---|
605 | 658 | #endif |
---|
606 | 659 | } |
---|
.. | .. |
---|
614 | 667 | |
---|
615 | 668 | RSEQ_INJECT_C(9) |
---|
616 | 669 | |
---|
617 | | - rseq_workaround_gcc_asm_size_guess(); |
---|
618 | 670 | __asm__ __volatile__ goto ( |
---|
619 | | - RSEQ_ASM_DEFINE_TABLE(1f, 2f, 4f) /* start, commit, abort */ |
---|
| 671 | + RSEQ_ASM_DEFINE_TABLE(9, 1f, 2f, 4f) /* start, commit, abort */ |
---|
| 672 | + RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail]) |
---|
| 673 | +#ifdef RSEQ_COMPARE_TWICE |
---|
| 674 | + RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1]) |
---|
| 675 | + RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2]) |
---|
| 676 | +#endif |
---|
620 | 677 | LONG_S " %[src], %[rseq_scratch0]\n\t" |
---|
621 | 678 | LONG_S " %[dst], %[rseq_scratch1]\n\t" |
---|
622 | 679 | LONG_S " %[len], %[rseq_scratch2]\n\t" |
---|
.. | .. |
---|
682 | 739 | "8:\n\t" |
---|
683 | 740 | : /* gcc asm goto does not allow outputs */ |
---|
684 | 741 | : [cpu_id] "r" (cpu), |
---|
685 | | - [current_cpu_id] "m" (__rseq_abi.cpu_id), |
---|
686 | | - [rseq_cs] "m" (__rseq_abi.rseq_cs), |
---|
| 742 | + [current_cpu_id] "m" (rseq_get_abi()->cpu_id), |
---|
| 743 | + [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr), |
---|
687 | 744 | /* final store input */ |
---|
688 | 745 | [v] "m" (*v), |
---|
689 | 746 | [expect] "r" (expect), |
---|
.. | .. |
---|
703 | 760 | , error1, error2 |
---|
704 | 761 | #endif |
---|
705 | 762 | ); |
---|
706 | | - rseq_workaround_gcc_asm_size_guess(); |
---|
707 | 763 | return 0; |
---|
708 | 764 | abort: |
---|
709 | | - rseq_workaround_gcc_asm_size_guess(); |
---|
710 | 765 | RSEQ_INJECT_FAILED |
---|
711 | 766 | return -1; |
---|
712 | 767 | cmpfail: |
---|
713 | | - rseq_workaround_gcc_asm_size_guess(); |
---|
714 | 768 | return 1; |
---|
715 | 769 | #ifdef RSEQ_COMPARE_TWICE |
---|
716 | 770 | error1: |
---|
717 | | - rseq_workaround_gcc_asm_size_guess(); |
---|
718 | 771 | rseq_bug("cpu_id comparison failed"); |
---|
719 | 772 | error2: |
---|
720 | | - rseq_workaround_gcc_asm_size_guess(); |
---|
721 | 773 | rseq_bug("expected value comparison failed"); |
---|
722 | 774 | #endif |
---|
723 | 775 | } |
---|