Skip to content

Commit 14b0c3e

Browse files
avdgrintenno92
authored andcommitted
options/internal: remove and poison __cxa_guard_{acquire,release}
1 parent 749a6cb commit 14b0c3e

1 file changed

Lines changed: 6 additions & 80 deletions

File tree

options/internal/gcc/guard-abi.cpp

Lines changed: 6 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -6,89 +6,15 @@
66
#include <mlibc/debug.hpp>
77
#include <mlibc/tid.hpp>
88

9-
namespace {
10-
11-
// Itanium ABI static initialization guard.
12-
struct Guard {
13-
static constexpr uint32_t waitersBit = 0x80000000;
14-
static constexpr uint32_t ownerMask = 0x3FFFFFFF;
15-
16-
void lock() {
17-
uint32_t tid = mlibc::this_tid();
18-
uint32_t expected = 0;
19-
20-
while (true) {
21-
if (!expected) {
22-
if (__atomic_compare_exchange_n(
23-
&mutex, &expected, tid, false, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE
24-
))
25-
return;
26-
} else {
27-
if ((expected & ownerMask) == tid)
28-
mlibc::panicLogger()
29-
<< "mlibc: __cxa_guard_acquire deadlock detected!" << frg::endlog;
30-
31-
if (expected & waitersBit) {
32-
int e = mlibc::sysdep<FutexWait>((int *)&mutex, expected, nullptr);
33-
if (e && e != EAGAIN && e != EINTR)
34-
mlibc::panicLogger()
35-
<< "sys_futex_wait() failed with error code " << e << frg::endlog;
36-
expected = 0;
37-
} else {
38-
uint32_t desired = expected | waitersBit;
39-
if (__atomic_compare_exchange_n(
40-
&mutex, &expected, desired, false, __ATOMIC_RELAXED, __ATOMIC_RELAXED
41-
))
42-
expected = desired;
43-
}
44-
}
45-
}
46-
}
47-
48-
void unlock() {
49-
uint32_t state = __atomic_exchange_n(&mutex, 0, __ATOMIC_RELEASE);
50-
__ensure((state & ownerMask) == mlibc::this_tid());
51-
if(state & waitersBit)
52-
mlibc::sysdep<FutexWake>((int *)&mutex, true);
53-
}
54-
55-
// the first byte's meaning is fixed by the ABI.
56-
// it indicates whether initialization has already been completed.
57-
uint8_t complete;
58-
// padding to ensure correct alignment on certain platforms.
59-
uint8_t padding[3];
60-
61-
// we use some of the remaining bytes to implement a mutex.
62-
uint32_t mutex;
63-
};
64-
65-
static_assert(sizeof(Guard) == sizeof(int64_t));
66-
67-
} // namespace
68-
699
extern "C" [[ gnu::visibility("hidden") ]] void __cxa_pure_virtual() {
7010
mlibc::panicLogger() << "mlibc: Pure virtual function called from IP "
7111
<< (void *)__builtin_return_address(0) << frg::endlog;
7212
}
7313

74-
extern "C" [[ gnu::visibility("hidden") ]] int __cxa_guard_acquire(int64_t *ptr) {
75-
auto guard = reinterpret_cast<Guard *>(ptr);
76-
guard->lock();
77-
// relaxed ordering is sufficient because
78-
// Guard::complete is only modified while the mutex is held.
79-
if(__atomic_load_n(&guard->complete, __ATOMIC_RELAXED)) {
80-
guard->unlock();
81-
return 0;
82-
}else{
83-
return 1;
84-
}
85-
}
86-
87-
extern "C" [[ gnu::visibility("hidden") ]] void __cxa_guard_release(int64_t *ptr) {
88-
auto guard = reinterpret_cast<Guard *>(ptr);
89-
// do a store-release so that compiler generated code can skip calling
90-
// __cxa_guard_acquire by doing a load-acquire on Guard::complete.
91-
__atomic_store_n(&guard->complete, 1, __ATOMIC_RELEASE);
92-
guard->unlock();
93-
}
14+
static const char __poison_cxa_guard_acquire[]
15+
__attribute__((used, section(".gnu.warning.__cxa_guard_acquire"))) =
16+
"mlibc cannot use static singletons, use lazy_eternal instead";
9417

18+
static const char __poison_cxa_guard_release[]
19+
__attribute__((used, section(".gnu.warning.__cxa_guard_release"))) =
20+
"mlibc cannot use static singletons, use lazy_eternal instead";

0 commit comments

Comments
 (0)