All arch: use rseq_unqual_scalar_typeof in load-acquire
[librseq.git] / include / rseq / rseq-ppc.h
index 52630c9f42be2998f04a77a9cba702cb72bd16b6..81c8586b6af4d27ba57c7b15986f9dceb641fa3c 100644 (file)
@@ -1,12 +1,20 @@
-/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
+/* SPDX-License-Identifier: MIT */
+/* SPDX-FileCopyrightText: 2016-2018 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> */
+/* SPDX-FileCopyrightText: 2016-2018 Boqun Feng <boqun.feng@gmail.com> */
+
 /*
  * rseq-ppc.h
+ */
+
+/*
+ * RSEQ_SIG is used with the following trap instruction:
  *
- * (C) Copyright 2016-2018 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- * (C) Copyright 2016-2018 - Boqun Feng <boqun.feng@gmail.com>
+ * powerpc-be:    0f e5 00 0b           twui   r5,11
+ * powerpc64-le:  0b 00 e5 0f           twui   r5,11
+ * powerpc64-be:  0f e5 00 0b           twui   r5,11
  */
 
-#define RSEQ_SIG       0x53053053
+#define RSEQ_SIG       0x0fe5000b
 
 #define rseq_smp_mb()          __asm__ __volatile__ ("sync"    ::: "memory", "cc")
 #define rseq_smp_lwsync()      __asm__ __volatile__ ("lwsync"  ::: "memory", "cc")
@@ -15,7 +23,7 @@
 
 #define rseq_smp_load_acquire(p)                                       \
 __extension__ ({                                                       \
-       __typeof(*p) ____p1 = RSEQ_READ_ONCE(*p);                       \
+       rseq_unqual_scalar_typeof(*(p)) ____p1 = RSEQ_READ_ONCE(*(p));  \
        rseq_smp_lwsync();                                              \
        ____p1;                                                         \
 })
@@ -25,7 +33,7 @@ __extension__ ({                                                      \
 #define rseq_smp_store_release(p, v)                                   \
 do {                                                                   \
        rseq_smp_lwsync();                                              \
-       RSEQ_WRITE_ONCE(*p, v);                                         \
+       RSEQ_WRITE_ONCE(*(p), v);                                       \
 } while (0)
 
 #ifdef RSEQ_SKIP_FASTPATH
@@ -33,24 +41,30 @@ do {                                                                        \
 #else /* !RSEQ_SKIP_FASTPATH */
 
 /*
- * The __rseq_table section can be used by debuggers to better handle
- * single-stepping through the restartable critical sections.
+ * The __rseq_cs_ptr_array and __rseq_cs sections can be used by debuggers to
+ * better handle single-stepping through the restartable critical sections.
  */
 
 #ifdef __PPC64__
 
-#define STORE_WORD     "std "
-#define LOAD_WORD      "ld "
-#define LOADX_WORD     "ldx "
-#define CMP_WORD       "cmpd "
+#define RSEQ_STORE_LONG(arg)   "std%U[" __rseq_str(arg) "]%X[" __rseq_str(arg) "] "    /* To memory ("m" constraint) */
+#define RSEQ_STORE_INT(arg)    "stw%U[" __rseq_str(arg) "]%X[" __rseq_str(arg) "] "    /* To memory ("m" constraint) */
+#define RSEQ_LOAD_LONG(arg)    "ld%U[" __rseq_str(arg) "]%X[" __rseq_str(arg) "] "     /* From memory ("m" constraint) */
+#define RSEQ_LOAD_INT(arg)     "lwz%U[" __rseq_str(arg) "]%X[" __rseq_str(arg) "] "    /* From memory ("m" constraint) */
+#define RSEQ_LOADX_LONG                "ldx "                                                  /* From base register ("b" constraint) */
+#define RSEQ_CMP_LONG          "cmpd "
+#define RSEQ_CMP_LONG_INT      "cmpdi "
 
 #define __RSEQ_ASM_DEFINE_TABLE(label, version, flags,                         \
                        start_ip, post_commit_offset, abort_ip)                 \
-               ".pushsection __rseq_table, \"aw\"\n\t"                         \
+               ".pushsection __rseq_cs, \"aw\"\n\t"                            \
                ".balign 32\n\t"                                                \
                __rseq_str(label) ":\n\t"                                       \
                ".long " __rseq_str(version) ", " __rseq_str(flags) "\n\t"      \
                ".quad " __rseq_str(start_ip) ", " __rseq_str(post_commit_offset) ", " __rseq_str(abort_ip) "\n\t" \
+               ".popsection\n\t"                                               \
+               ".pushsection __rseq_cs_ptr_array, \"aw\"\n\t"                  \
+               ".quad " __rseq_str(label) "b\n\t"                              \
                ".popsection\n\t"
 
 #define RSEQ_ASM_STORE_RSEQ_CS(label, cs_label, rseq_cs)                       \
@@ -63,28 +77,61 @@ do {                                                                        \
                "std %%r17, %[" __rseq_str(rseq_cs) "]\n\t"                     \
                __rseq_str(label) ":\n\t"
 
+/*
+ * Exit points of a rseq critical section consist of all instructions outside
+ * of the critical section where a critical section can either branch to or
+ * reach through the normal course of its execution. The abort IP and the
+ * post-commit IP are already part of the __rseq_cs section and should not be
+ * explicitly defined as additional exit points. Knowing all exit points is
+ * useful to assist debuggers stepping over the critical section.
+ */
+#define RSEQ_ASM_DEFINE_EXIT_POINT(start_ip, exit_ip)                  \
+               ".pushsection __rseq_exit_point_array, \"aw\"\n\t"      \
+               ".quad " __rseq_str(start_ip) ", " __rseq_str(exit_ip) "\n\t" \
+               ".popsection\n\t"
+
 #else /* #ifdef __PPC64__ */
 
-#define STORE_WORD     "stw "
-#define LOAD_WORD      "lwz "
-#define LOADX_WORD     "lwzx "
-#define CMP_WORD       "cmpw "
+#define RSEQ_STORE_LONG(arg)   "stw%U[" __rseq_str(arg) "]%X[" __rseq_str(arg) "] "    /* To memory ("m" constraint) */
+#define RSEQ_STORE_INT(arg)    RSEQ_STORE_LONG(arg)                                    /* To memory ("m" constraint) */
+#define RSEQ_LOAD_LONG(arg)    "lwz%U[" __rseq_str(arg) "]%X[" __rseq_str(arg) "] "    /* From memory ("m" constraint) */
+#define RSEQ_LOAD_INT(arg)     RSEQ_LOAD_LONG(arg)                                     /* From memory ("m" constraint) */
+#define RSEQ_LOADX_LONG                "lwzx "                                                 /* From base register ("b" constraint) */
+#define RSEQ_CMP_LONG          "cmpw "
+#define RSEQ_CMP_LONG_INT      "cmpwi "
 
 #define __RSEQ_ASM_DEFINE_TABLE(label, version, flags,                         \
                        start_ip, post_commit_offset, abort_ip)                 \
-               ".pushsection __rseq_table, \"aw\"\n\t"                         \
+               ".pushsection __rseq_cs, \"aw\"\n\t"                            \
                ".balign 32\n\t"                                                \
                __rseq_str(label) ":\n\t"                                       \
                ".long " __rseq_str(version) ", " __rseq_str(flags) "\n\t"      \
                /* 32-bit only supported on BE */                               \
                ".long 0x0, " __rseq_str(start_ip) ", 0x0, " __rseq_str(post_commit_offset) ", 0x0, " __rseq_str(abort_ip) "\n\t" \
+               ".popsection\n\t"                                       \
+               ".pushsection __rseq_cs_ptr_array, \"aw\"\n\t"          \
+               ".long 0x0, " __rseq_str(label) "b\n\t"                 \
+               ".popsection\n\t"
+
+/*
+ * Exit points of a rseq critical section consist of all instructions outside
+ * of the critical section where a critical section can either branch to or
+ * reach through the normal course of its execution. The abort IP and the
+ * post-commit IP are already part of the __rseq_cs section and should not be
+ * explicitly defined as additional exit points. Knowing all exit points is
+ * useful to assist debuggers stepping over the critical section.
+ */
+#define RSEQ_ASM_DEFINE_EXIT_POINT(start_ip, exit_ip)                          \
+               ".pushsection __rseq_exit_point_array, \"aw\"\n\t"              \
+               /* 32-bit only supported on BE */                               \
+               ".long 0x0, " __rseq_str(start_ip) ", 0x0, " __rseq_str(exit_ip) "\n\t" \
                ".popsection\n\t"
 
 #define RSEQ_ASM_STORE_RSEQ_CS(label, cs_label, rseq_cs)                       \
                RSEQ_INJECT_ASM(1)                                              \
                "lis %%r17, (" __rseq_str(cs_label) ")@ha\n\t"                  \
                "addi %%r17, %%r17, (" __rseq_str(cs_label) ")@l\n\t"           \
-               "stw %%r17, %[" __rseq_str(rseq_cs) "]\n\t"                     \
+               RSEQ_STORE_INT(rseq_cs) "%%r17, %[" __rseq_str(rseq_cs) "]\n\t" \
                __rseq_str(label) ":\n\t"
 
 #endif /* #ifdef __PPC64__ */
@@ -95,7 +142,7 @@ do {                                                                 \
 
 #define RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, label)                     \
                RSEQ_INJECT_ASM(2)                                              \
-               "lwz %%r17, %[" __rseq_str(current_cpu_id) "]\n\t"              \
+               RSEQ_LOAD_INT(current_cpu_id) "%%r17, %[" __rseq_str(current_cpu_id) "]\n\t" \
                "cmpw cr7, %[" __rseq_str(cpu_id) "], %%r17\n\t"                \
                "bne- cr7, " __rseq_str(label) "\n\t"
 
@@ -112,25 +159,25 @@ do {                                                                      \
  *     RSEQ_ASM_OP_* (else): doesn't have hard-code registers(unless cr7)
  */
 #define RSEQ_ASM_OP_CMPEQ(var, expect, label)                                  \
-               LOAD_WORD "%%r17, %[" __rseq_str(var) "]\n\t"                   \
-               CMP_WORD "cr7, %%r17, %[" __rseq_str(expect) "]\n\t"            \
+               RSEQ_LOAD_LONG(var) "%%r17, %[" __rseq_str(var) "]\n\t"         \
+               RSEQ_CMP_LONG "cr7, %%r17, %[" __rseq_str(expect) "]\n\t"               \
                "bne- cr7, " __rseq_str(label) "\n\t"
 
 #define RSEQ_ASM_OP_CMPNE(var, expectnot, label)                               \
-               LOAD_WORD "%%r17, %[" __rseq_str(var) "]\n\t"                   \
-               CMP_WORD "cr7, %%r17, %[" __rseq_str(expectnot) "]\n\t"         \
+               RSEQ_LOAD_LONG(var) "%%r17, %[" __rseq_str(var) "]\n\t"         \
+               RSEQ_CMP_LONG "cr7, %%r17, %[" __rseq_str(expectnot) "]\n\t"            \
                "beq- cr7, " __rseq_str(label) "\n\t"
 
 #define RSEQ_ASM_OP_STORE(value, var)                                          \
-               STORE_WORD "%[" __rseq_str(value) "], %[" __rseq_str(var) "]\n\t"
+               RSEQ_STORE_LONG(var) "%[" __rseq_str(value) "], %[" __rseq_str(var) "]\n\t"
 
 /* Load @var to r17 */
 #define RSEQ_ASM_OP_R_LOAD(var)                                                        \
-               LOAD_WORD "%%r17, %[" __rseq_str(var) "]\n\t"
+               RSEQ_LOAD_LONG(var) "%%r17, %[" __rseq_str(var) "]\n\t"
 
 /* Store r17 to @var */
 #define RSEQ_ASM_OP_R_STORE(var)                                               \
-               STORE_WORD "%%r17, %[" __rseq_str(var) "]\n\t"
+               RSEQ_STORE_LONG(var) "%%r17, %[" __rseq_str(var) "]\n\t"
 
 /* Add @count to r17 */
 #define RSEQ_ASM_OP_R_ADD(count)                                               \
@@ -138,11 +185,11 @@ do {                                                                      \
 
 /* Load (r17 + voffp) to r17 */
 #define RSEQ_ASM_OP_R_LOADX(voffp)                                             \
-               LOADX_WORD "%%r17, %[" __rseq_str(voffp) "], %%r17\n\t"
+               RSEQ_LOADX_LONG "%%r17, %[" __rseq_str(voffp) "], %%r17\n\t"
 
 /* TODO: implement a faster memcpy. */
 #define RSEQ_ASM_OP_R_MEMCPY() \
-               "cmpdi %%r19, 0\n\t" \
+               RSEQ_CMP_LONG_INT "%%r19, 0\n\t" \
                "beq 333f\n\t" \
                "addi %%r20, %%r20, -1\n\t" \
                "addi %%r21, %%r21, -1\n\t" \
@@ -150,16 +197,16 @@ do {                                                                      \
                "lbzu %%r18, 1(%%r20)\n\t" \
                "stbu %%r18, 1(%%r21)\n\t" \
                "addi %%r19, %%r19, -1\n\t" \
-               "cmpdi %%r19, 0\n\t" \
+               RSEQ_CMP_LONG_INT "%%r19, 0\n\t" \
                "bne 222b\n\t" \
                "333:\n\t" \
 
 #define RSEQ_ASM_OP_R_FINAL_STORE(var, post_commit_label)                      \
-               STORE_WORD "%%r17, %[" __rseq_str(var) "]\n\t"                  \
+               RSEQ_STORE_LONG(var) "%%r17, %[" __rseq_str(var) "]\n\t"                        \
                __rseq_str(post_commit_label) ":\n\t"
 
 #define RSEQ_ASM_OP_FINAL_STORE(value, var, post_commit_label)                 \
-               STORE_WORD "%[" __rseq_str(value) "], %[" __rseq_str(var) "]\n\t" \
+               RSEQ_STORE_LONG(var) "%[" __rseq_str(value) "], %[" __rseq_str(var) "]\n\t" \
                __rseq_str(post_commit_label) ":\n\t"
 
 static inline __attribute__((always_inline))
@@ -169,6 +216,11 @@ int rseq_cmpeqv_storev(intptr_t *v, intptr_t expect, intptr_t newv, int cpu)
 
        __asm__ __volatile__ goto (
                RSEQ_ASM_DEFINE_TABLE(3, 1f, 2f, 4f) /* start, commit, abort */
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
+#ifdef RSEQ_COMPARE_TWICE
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1])
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2])
+#endif
                /* Start rseq by storing table entry pointer into rseq_cs. */
                RSEQ_ASM_STORE_RSEQ_CS(1, 3b, rseq_cs)
                /* cmp cpuid */
@@ -189,8 +241,8 @@ int rseq_cmpeqv_storev(intptr_t *v, intptr_t expect, intptr_t newv, int cpu)
                RSEQ_ASM_DEFINE_ABORT(4, abort)
                : /* gcc asm goto does not allow outputs */
                : [cpu_id]              "r" (cpu),
-                 [current_cpu_id]      "m" (__rseq_abi.cpu_id),
-                 [rseq_cs]             "m" (__rseq_abi.rseq_cs),
+                 [current_cpu_id]      "m" (rseq_get_abi()->cpu_id),
+                 [rseq_cs]             "m" (rseq_get_abi()->rseq_cs.arch.ptr),
                  [v]                   "m" (*v),
                  [expect]              "r" (expect),
                  [newv]                "r" (newv)
@@ -202,28 +254,38 @@ int rseq_cmpeqv_storev(intptr_t *v, intptr_t expect, intptr_t newv, int cpu)
                  , error1, error2
 #endif
        );
+       rseq_after_asm_goto();
        return 0;
 abort:
+       rseq_after_asm_goto();
        RSEQ_INJECT_FAILED
        return -1;
 cmpfail:
+       rseq_after_asm_goto();
        return 1;
 #ifdef RSEQ_COMPARE_TWICE
 error1:
+       rseq_after_asm_goto();
        rseq_bug("cpu_id comparison failed");
 error2:
+       rseq_after_asm_goto();
        rseq_bug("expected value comparison failed");
 #endif
 }
 
 static inline __attribute__((always_inline))
 int rseq_cmpnev_storeoffp_load(intptr_t *v, intptr_t expectnot,
-                              off_t voffp, intptr_t *load, int cpu)
+                              long voffp, intptr_t *load, int cpu)
 {
        RSEQ_INJECT_C(9)
 
        __asm__ __volatile__ goto (
                RSEQ_ASM_DEFINE_TABLE(3, 1f, 2f, 4f) /* start, commit, abort */
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
+#ifdef RSEQ_COMPARE_TWICE
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1])
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2])
+#endif
                /* Start rseq by storing table entry pointer into rseq_cs. */
                RSEQ_ASM_STORE_RSEQ_CS(1, 3b, rseq_cs)
                /* cmp cpuid */
@@ -250,8 +312,8 @@ int rseq_cmpnev_storeoffp_load(intptr_t *v, intptr_t expectnot,
                RSEQ_ASM_DEFINE_ABORT(4, abort)
                : /* gcc asm goto does not allow outputs */
                : [cpu_id]              "r" (cpu),
-                 [current_cpu_id]      "m" (__rseq_abi.cpu_id),
-                 [rseq_cs]             "m" (__rseq_abi.rseq_cs),
+                 [current_cpu_id]      "m" (rseq_get_abi()->cpu_id),
+                 [rseq_cs]             "m" (rseq_get_abi()->rseq_cs.arch.ptr),
                  /* final store input */
                  [v]                   "m" (*v),
                  [expectnot]           "r" (expectnot),
@@ -265,16 +327,21 @@ int rseq_cmpnev_storeoffp_load(intptr_t *v, intptr_t expectnot,
                  , error1, error2
 #endif
        );
+       rseq_after_asm_goto();
        return 0;
 abort:
+       rseq_after_asm_goto();
        RSEQ_INJECT_FAILED
        return -1;
 cmpfail:
+       rseq_after_asm_goto();
        return 1;
 #ifdef RSEQ_COMPARE_TWICE
 error1:
+       rseq_after_asm_goto();
        rseq_bug("cpu_id comparison failed");
 error2:
+       rseq_after_asm_goto();
        rseq_bug("expected value comparison failed");
 #endif
 }
@@ -286,6 +353,9 @@ int rseq_addv(intptr_t *v, intptr_t count, int cpu)
 
        __asm__ __volatile__ goto (
                RSEQ_ASM_DEFINE_TABLE(3, 1f, 2f, 4f) /* start, commit, abort */
+#ifdef RSEQ_COMPARE_TWICE
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1])
+#endif
                /* Start rseq by storing table entry pointer into rseq_cs. */
                RSEQ_ASM_STORE_RSEQ_CS(1, 3b, rseq_cs)
                /* cmp cpuid */
@@ -305,8 +375,8 @@ int rseq_addv(intptr_t *v, intptr_t count, int cpu)
                RSEQ_ASM_DEFINE_ABORT(4, abort)
                : /* gcc asm goto does not allow outputs */
                : [cpu_id]              "r" (cpu),
-                 [current_cpu_id]      "m" (__rseq_abi.cpu_id),
-                 [rseq_cs]             "m" (__rseq_abi.rseq_cs),
+                 [current_cpu_id]      "m" (rseq_get_abi()->cpu_id),
+                 [rseq_cs]             "m" (rseq_get_abi()->rseq_cs.arch.ptr),
                  /* final store input */
                  [v]                   "m" (*v),
                  [count]               "r" (count)
@@ -318,12 +388,15 @@ int rseq_addv(intptr_t *v, intptr_t count, int cpu)
                  , error1
 #endif
        );
+       rseq_after_asm_goto();
        return 0;
 abort:
+       rseq_after_asm_goto();
        RSEQ_INJECT_FAILED
        return -1;
 #ifdef RSEQ_COMPARE_TWICE
 error1:
+       rseq_after_asm_goto();
        rseq_bug("cpu_id comparison failed");
 #endif
 }
@@ -337,6 +410,11 @@ int rseq_cmpeqv_trystorev_storev(intptr_t *v, intptr_t expect,
 
        __asm__ __volatile__ goto (
                RSEQ_ASM_DEFINE_TABLE(3, 1f, 2f, 4f) /* start, commit, abort */
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
+#ifdef RSEQ_COMPARE_TWICE
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1])
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2])
+#endif
                /* Start rseq by storing table entry pointer into rseq_cs. */
                RSEQ_ASM_STORE_RSEQ_CS(1, 3b, rseq_cs)
                /* cmp cpuid */
@@ -360,8 +438,8 @@ int rseq_cmpeqv_trystorev_storev(intptr_t *v, intptr_t expect,
                RSEQ_ASM_DEFINE_ABORT(4, abort)
                : /* gcc asm goto does not allow outputs */
                : [cpu_id]              "r" (cpu),
-                 [current_cpu_id]      "m" (__rseq_abi.cpu_id),
-                 [rseq_cs]             "m" (__rseq_abi.rseq_cs),
+                 [current_cpu_id]      "m" (rseq_get_abi()->cpu_id),
+                 [rseq_cs]             "m" (rseq_get_abi()->rseq_cs.arch.ptr),
                  /* try store input */
                  [v2]                  "m" (*v2),
                  [newv2]               "r" (newv2),
@@ -377,16 +455,21 @@ int rseq_cmpeqv_trystorev_storev(intptr_t *v, intptr_t expect,
                  , error1, error2
 #endif
        );
+       rseq_after_asm_goto();
        return 0;
 abort:
+       rseq_after_asm_goto();
        RSEQ_INJECT_FAILED
        return -1;
 cmpfail:
+       rseq_after_asm_goto();
        return 1;
 #ifdef RSEQ_COMPARE_TWICE
 error1:
+       rseq_after_asm_goto();
        rseq_bug("cpu_id comparison failed");
 error2:
+       rseq_after_asm_goto();
        rseq_bug("expected value comparison failed");
 #endif
 }
@@ -400,6 +483,11 @@ int rseq_cmpeqv_trystorev_storev_release(intptr_t *v, intptr_t expect,
 
        __asm__ __volatile__ goto (
                RSEQ_ASM_DEFINE_TABLE(3, 1f, 2f, 4f) /* start, commit, abort */
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
+#ifdef RSEQ_COMPARE_TWICE
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1])
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2])
+#endif
                /* Start rseq by storing table entry pointer into rseq_cs. */
                RSEQ_ASM_STORE_RSEQ_CS(1, 3b, rseq_cs)
                /* cmp cpuid */
@@ -425,8 +513,8 @@ int rseq_cmpeqv_trystorev_storev_release(intptr_t *v, intptr_t expect,
                RSEQ_ASM_DEFINE_ABORT(4, abort)
                : /* gcc asm goto does not allow outputs */
                : [cpu_id]              "r" (cpu),
-                 [current_cpu_id]      "m" (__rseq_abi.cpu_id),
-                 [rseq_cs]             "m" (__rseq_abi.rseq_cs),
+                 [current_cpu_id]      "m" (rseq_get_abi()->cpu_id),
+                 [rseq_cs]             "m" (rseq_get_abi()->rseq_cs.arch.ptr),
                  /* try store input */
                  [v2]                  "m" (*v2),
                  [newv2]               "r" (newv2),
@@ -442,16 +530,21 @@ int rseq_cmpeqv_trystorev_storev_release(intptr_t *v, intptr_t expect,
                  , error1, error2
 #endif
        );
+       rseq_after_asm_goto();
        return 0;
 abort:
+       rseq_after_asm_goto();
        RSEQ_INJECT_FAILED
        return -1;
 cmpfail:
+       rseq_after_asm_goto();
        return 1;
 #ifdef RSEQ_COMPARE_TWICE
 error1:
+       rseq_after_asm_goto();
        rseq_bug("cpu_id comparison failed");
 error2:
+       rseq_after_asm_goto();
        rseq_bug("expected value comparison failed");
 #endif
 }
@@ -465,6 +558,12 @@ int rseq_cmpeqv_cmpeqv_storev(intptr_t *v, intptr_t expect,
 
        __asm__ __volatile__ goto (
                RSEQ_ASM_DEFINE_TABLE(3, 1f, 2f, 4f) /* start, commit, abort */
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
+#ifdef RSEQ_COMPARE_TWICE
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1])
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2])
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error3])
+#endif
                /* Start rseq by storing table entry pointer into rseq_cs. */
                RSEQ_ASM_STORE_RSEQ_CS(1, 3b, rseq_cs)
                /* cmp cpuid */
@@ -490,8 +589,8 @@ int rseq_cmpeqv_cmpeqv_storev(intptr_t *v, intptr_t expect,
                RSEQ_ASM_DEFINE_ABORT(4, abort)
                : /* gcc asm goto does not allow outputs */
                : [cpu_id]              "r" (cpu),
-                 [current_cpu_id]      "m" (__rseq_abi.cpu_id),
-                 [rseq_cs]             "m" (__rseq_abi.rseq_cs),
+                 [current_cpu_id]      "m" (rseq_get_abi()->cpu_id),
+                 [rseq_cs]             "m" (rseq_get_abi()->rseq_cs.arch.ptr),
                  /* cmp2 input */
                  [v2]                  "m" (*v2),
                  [expect2]             "r" (expect2),
@@ -507,18 +606,24 @@ int rseq_cmpeqv_cmpeqv_storev(intptr_t *v, intptr_t expect,
                  , error1, error2, error3
 #endif
        );
+       rseq_after_asm_goto();
        return 0;
 abort:
+       rseq_after_asm_goto();
        RSEQ_INJECT_FAILED
        return -1;
 cmpfail:
+       rseq_after_asm_goto();
        return 1;
 #ifdef RSEQ_COMPARE_TWICE
 error1:
+       rseq_after_asm_goto();
        rseq_bug("cpu_id comparison failed");
 error2:
+       rseq_after_asm_goto();
        rseq_bug("1st expected value comparison failed");
 error3:
+       rseq_after_asm_goto();
        rseq_bug("2nd expected value comparison failed");
 #endif
 }
@@ -532,6 +637,11 @@ int rseq_cmpeqv_trymemcpy_storev(intptr_t *v, intptr_t expect,
 
        __asm__ __volatile__ goto (
                RSEQ_ASM_DEFINE_TABLE(3, 1f, 2f, 4f) /* start, commit, abort */
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
+#ifdef RSEQ_COMPARE_TWICE
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1])
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2])
+#endif
                /* setup for mempcy */
                "mr %%r19, %[len]\n\t"
                "mr %%r20, %[src]\n\t"
@@ -560,8 +670,8 @@ int rseq_cmpeqv_trymemcpy_storev(intptr_t *v, intptr_t expect,
                RSEQ_ASM_DEFINE_ABORT(4, abort)
                : /* gcc asm goto does not allow outputs */
                : [cpu_id]              "r" (cpu),
-                 [current_cpu_id]      "m" (__rseq_abi.cpu_id),
-                 [rseq_cs]             "m" (__rseq_abi.rseq_cs),
+                 [current_cpu_id]      "m" (rseq_get_abi()->cpu_id),
+                 [rseq_cs]             "m" (rseq_get_abi()->rseq_cs.arch.ptr),
                  /* final store input */
                  [v]                   "m" (*v),
                  [expect]              "r" (expect),
@@ -578,16 +688,21 @@ int rseq_cmpeqv_trymemcpy_storev(intptr_t *v, intptr_t expect,
                  , error1, error2
 #endif
        );
+       rseq_after_asm_goto();
        return 0;
 abort:
+       rseq_after_asm_goto();
        RSEQ_INJECT_FAILED
        return -1;
 cmpfail:
+       rseq_after_asm_goto();
        return 1;
 #ifdef RSEQ_COMPARE_TWICE
 error1:
+       rseq_after_asm_goto();
        rseq_bug("cpu_id comparison failed");
 error2:
+       rseq_after_asm_goto();
        rseq_bug("expected value comparison failed");
 #endif
 }
@@ -601,6 +716,11 @@ int rseq_cmpeqv_trymemcpy_storev_release(intptr_t *v, intptr_t expect,
 
        __asm__ __volatile__ goto (
                RSEQ_ASM_DEFINE_TABLE(3, 1f, 2f, 4f) /* start, commit, abort */
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
+#ifdef RSEQ_COMPARE_TWICE
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1])
+               RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2])
+#endif
                /* setup for mempcy */
                "mr %%r19, %[len]\n\t"
                "mr %%r20, %[src]\n\t"
@@ -631,8 +751,8 @@ int rseq_cmpeqv_trymemcpy_storev_release(intptr_t *v, intptr_t expect,
                RSEQ_ASM_DEFINE_ABORT(4, abort)
                : /* gcc asm goto does not allow outputs */
                : [cpu_id]              "r" (cpu),
-                 [current_cpu_id]      "m" (__rseq_abi.cpu_id),
-                 [rseq_cs]             "m" (__rseq_abi.rseq_cs),
+                 [current_cpu_id]      "m" (rseq_get_abi()->cpu_id),
+                 [rseq_cs]             "m" (rseq_get_abi()->rseq_cs.arch.ptr),
                  /* final store input */
                  [v]                   "m" (*v),
                  [expect]              "r" (expect),
@@ -649,23 +769,23 @@ int rseq_cmpeqv_trymemcpy_storev_release(intptr_t *v, intptr_t expect,
                  , error1, error2
 #endif
        );
+       rseq_after_asm_goto();
        return 0;
 abort:
+       rseq_after_asm_goto();
        RSEQ_INJECT_FAILED
        return -1;
 cmpfail:
+       rseq_after_asm_goto();
        return 1;
 #ifdef RSEQ_COMPARE_TWICE
 error1:
+       rseq_after_asm_goto();
        rseq_bug("cpu_id comparison failed");
 error2:
+       rseq_after_asm_goto();
        rseq_bug("expected value comparison failed");
 #endif
 }
 
-#undef STORE_WORD
-#undef LOAD_WORD
-#undef LOADX_WORD
-#undef CMP_WORD
-
 #endif /* !RSEQ_SKIP_FASTPATH */
This page took 0.031866 seconds and 4 git commands to generate.