Introduce __rseq_handled and rseq_ownership
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 25 Mar 2019 02:43:22 +0000 (22:43 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 25 Mar 2019 02:43:22 +0000 (22:43 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
include/rseq/rseq.h
src/rseq.c

index ed49019e2fba5f550871889cf205389fa122c4ad..a365ac8c78b61fc67ba441dd78253867ebeb5a19 100644 (file)
@@ -45,7 +45,7 @@
 #endif
 
 extern __thread volatile struct rseq __rseq_abi;
-extern __thread volatile uint32_t __rseq_refcount;
+extern int __rseq_handled;
 
 #define rseq_likely(x)         __builtin_expect(!!(x), 1)
 #define rseq_unlikely(x)       __builtin_expect(!!(x), 0)
index da6fcddd1870422dc466868a01a4f4b2ddffed56..e4c09b5c4ce07228debf2aa38de6b32b74a98fe9 100644 (file)
 
 #define ARRAY_SIZE(arr)        (sizeof(arr) / sizeof((arr)[0]))
 
-__thread
-volatile struct rseq __rseq_abi = {
+__thread volatile struct rseq __rseq_abi = {
        .cpu_id = RSEQ_CPU_ID_UNINITIALIZED,
 };
 
-__thread
-volatile uint32_t __rseq_refcount;
+/*
+ * Shared with other libraries. This library may take rseq ownership if it is
+ * still 0 when executing the library constructor. Set to 1 by library
+ * constructor when handling rseq. Set to 0 in destructor if handling rseq.
+ */
+int __rseq_handled;
+
+/* Whether this library have ownership of rseq registration. */
+static int rseq_ownership;
+
+static __thread volatile uint32_t __rseq_refcount;
 
 static int sys_rseq(volatile struct rseq *rseq_abi, uint32_t rseq_len,
                    int flags, uint32_t sig)
@@ -88,6 +96,8 @@ int rseq_register_current_thread(void)
        int rc, ret = 0;
        sigset_t oldset;
 
+       if (!rseq_ownership)
+               return 0;
        signal_off_save(&oldset);
        if (__rseq_refcount == UINT_MAX) {
                ret = -1;
@@ -114,6 +124,8 @@ int rseq_unregister_current_thread(void)
        int rc, ret = 0;
        sigset_t oldset;
 
+       if (!rseq_ownership)
+               return 0;
        signal_off_save(&oldset);
        if (!__rseq_refcount) {
                ret = -1;
@@ -142,3 +154,20 @@ int32_t rseq_fallback_current_cpu(void)
        }
        return cpu;
 }
+
+void __attribute__((constructor)) rseq_init(void)
+{
+       /* Check whether rseq is handled by another library. */
+       if (__rseq_handled)
+               return;
+       __rseq_handled = 1;
+       rseq_ownership = 1;
+}
+
+void __attribute__((destructor)) rseq_fini(void)
+{
+       if (!rseq_ownership)
+               return;
+       __rseq_handled = 0;
+       rseq_ownership = 0;
+}
This page took 0.027144 seconds and 4 git commands to generate.