Skip to content

Commit

Permalink
cxa: Remove transparent_union hack
Browse files Browse the repository at this point in the history
Actual calls to `__cdecl` functions are only emitted by the compiler, so it
is not necessary to maintain compatibility at source level. I would like the
headers to be usable with MSVC.
  • Loading branch information
lhmouse committed Jan 14, 2024
1 parent eea208c commit 84b3470
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 46 deletions.
6 changes: 3 additions & 3 deletions mcfgthread/cxa.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ __MCF_cxa_atexit(__MCF_cxa_dtor_union dtor, void* this, void* dso)
{
/* Push the element to the global queue. */
_MCF_mutex_lock(__MCF_g->__cxa_atexit_mtx, NULL);
__MCF_dtor_element elem = { dtor.__cdecl_ptr, this, dso };
__MCF_dtor_element elem = { dtor, this, dso };
int err = __MCF_dtor_queue_push(__MCF_g->__cxa_atexit_queue, &elem);
_MCF_mutex_unlock(__MCF_g->__cxa_atexit_mtx);
return err;
Expand All @@ -61,7 +61,7 @@ __MCF_cxa_at_quick_exit(__MCF_cxa_dtor_union dtor, void* this, void* dso)
{
/* Push the element to the global queue. */
_MCF_mutex_lock(__MCF_g->__cxa_at_quick_exit_mtx, NULL);
__MCF_dtor_element elem = { dtor.__cdecl_ptr, this, dso };
__MCF_dtor_element elem = { dtor, this, dso };
int err = __MCF_dtor_queue_push(__MCF_g->__cxa_at_quick_exit_queue, &elem);
_MCF_mutex_unlock(__MCF_g->__cxa_at_quick_exit_mtx);
return err;
Expand All @@ -83,7 +83,7 @@ __MCF_cxa_thread_atexit(__MCF_cxa_dtor_union dtor, void* this, void* dso)
return -1;

/* Push the element to the thread-specific queue. */
__MCF_dtor_element elem = { dtor.__cdecl_ptr, this, dso };
__MCF_dtor_element elem = { dtor, this, dso };
int err = __MCF_dtor_queue_push(self->__atexit_queue, &elem);
return err;
}
Expand Down
20 changes: 0 additions & 20 deletions mcfgthread/cxa.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,6 @@ __MCF_C_DECLARATIONS_BEGIN
/* See <https://itanium-cxx-abi.github.io/cxx-abi/abi.html> for details about
* individual functions. */

union __attribute__((__transparent_union__)) __MCF_cxa_dtor_union
{
__MCF_cxa_dtor_cdecl* __cdecl_ptr;
__MCF_cxa_dtor_thiscall* __thiscall_ptr;

#ifdef __cplusplus
/* GCC ignores `__transparent_union__` attribute so mimic it. */
__MCF_CXX11(constexpr)
__MCF_cxa_dtor_union(__MCF_cxa_dtor_cdecl* __arg) __MCF_NOEXCEPT
: __cdecl_ptr(__arg) { }

# ifdef __i386__
__MCF_CXX11(constexpr)
__MCF_cxa_dtor_union(__MCF_cxa_dtor_thiscall* __arg) __MCF_NOEXCEPT
: __thiscall_ptr(__arg) { }
# endif
#endif /* __cplusplus */
};

/* Declare 'real' functions here. */
__MCF_CXA_IMPORT
int
__MCF_cxa_guard_acquire(int64_t* __guard) __MCF_NOEXCEPT;
Expand Down
5 changes: 2 additions & 3 deletions mcfgthread/fwd.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,6 @@ typedef struct __MCF_dtor_element __MCF_dtor_element;
typedef struct __MCF_dtor_queue __MCF_dtor_queue;
typedef struct __MCF_tls_table __MCF_tls_table;
typedef struct __MCF_tls_element __MCF_tls_element;
typedef union __MCF_cxa_dtor_union __MCF_cxa_dtor_union;

typedef struct __MCF_cond _MCF_cond;
typedef struct __MCF_mutex _MCF_mutex;
Expand All @@ -172,8 +171,8 @@ typedef void _MCF_tls_dtor(void* __ptr);
/* Note: In the case of i386, the argument is passed both via the ECX register
* and on the stack, to allow both `__cdecl` and `__thiscall` functions to work
* properly. The function prototype is declared for compatibility with GCC. */
typedef void __cdecl __MCF_cxa_dtor_cdecl(void* __arg);
typedef void __thiscall __MCF_cxa_dtor_thiscall(void* __arg);
typedef void __MCF_cxa_dtor_cdecl(void* __arg);
typedef __MCF_cxa_dtor_cdecl __MCF_cxa_dtor_union;

/* Define the prototype for `atexit()` and `at_quick_exit()`. */
typedef void __MCF_atexit_callback(void);
Expand Down
22 changes: 12 additions & 10 deletions test/cxa_atexit_all.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,16 @@ static char buffer[1000];
static int dso_1, dso_2;

static
void __cdecl
void
__cdecl
cleanup_1(void* ptr)
{
strcat(buffer, ptr);
}

static
void __thiscall
void
__thiscall
cleanup_2(void* ptr)
{
strcat(buffer, ptr);
Expand All @@ -38,13 +40,13 @@ main(void)
assert(r == 0);
r = __MCF_cxa_atexit(cleanup_1, (void*) "dN", NULL);
assert(r == 0);
r = __MCF_cxa_atexit(cleanup_2, (void*) "e2", &dso_2);
r = __MCF_cxa_atexit((__MCF_cxa_dtor_cdecl*) cleanup_2, (void*) "e2", &dso_2);
assert(r == 0);
r = __MCF_cxa_atexit(cleanup_2, (void*) "f1", &dso_1);
r = __MCF_cxa_atexit((__MCF_cxa_dtor_cdecl*) cleanup_2, (void*) "f1", &dso_1);
assert(r == 0);
r = __MCF_cxa_atexit(cleanup_2, (void*) "g1", &dso_1);
r = __MCF_cxa_atexit((__MCF_cxa_dtor_cdecl*) cleanup_2, (void*) "g1", &dso_1);
assert(r == 0);
r = __MCF_cxa_atexit(cleanup_2, (void*) "hN", NULL);
r = __MCF_cxa_atexit((__MCF_cxa_dtor_cdecl*) cleanup_2, (void*) "hN", NULL);
assert(r == 0);
r = __MCF_cxa_atexit(cleanup_1, (void*) "i1", &dso_1);
assert(r == 0);
Expand All @@ -54,13 +56,13 @@ main(void)
assert(r == 0);
r = __MCF_cxa_atexit(cleanup_1, (void*) "lN", NULL);
assert(r == 0);
r = __MCF_cxa_atexit(cleanup_2, (void*) "m1", &dso_1);
r = __MCF_cxa_atexit((__MCF_cxa_dtor_cdecl*) cleanup_2, (void*) "m1", &dso_1);
assert(r == 0);
r = __MCF_cxa_atexit(cleanup_2, (void*) "n2", &dso_2);
r = __MCF_cxa_atexit((__MCF_cxa_dtor_cdecl*) cleanup_2, (void*) "n2", &dso_2);
assert(r == 0);
r = __MCF_cxa_atexit(cleanup_2, (void*) "o2", &dso_2);
r = __MCF_cxa_atexit((__MCF_cxa_dtor_cdecl*) cleanup_2, (void*) "o2", &dso_2);
assert(r == 0);
r = __MCF_cxa_atexit(cleanup_2, (void*) "pN", NULL);
r = __MCF_cxa_atexit((__MCF_cxa_dtor_cdecl*) cleanup_2, (void*) "pN", NULL);
assert(r == 0);

assert(strcmp(buffer, "") == 0);
Expand Down
22 changes: 12 additions & 10 deletions test/cxa_atexit_dso.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,16 @@ static char buffer[1000];
static int dso_1, dso_2;

static
void __cdecl
void
__cdecl
cleanup_1(void* ptr)
{
strcat(buffer, ptr);
}

static
void __thiscall
void
__thiscall
cleanup_2(void* ptr)
{
strcat(buffer, ptr);
Expand All @@ -38,13 +40,13 @@ main(void)
assert(r == 0);
r = __MCF_cxa_atexit(cleanup_1, (void*) "dN", NULL);
assert(r == 0);
r = __MCF_cxa_atexit(cleanup_2, (void*) "e2", &dso_2);
r = __MCF_cxa_atexit((__MCF_cxa_dtor_cdecl*) cleanup_2, (void*) "e2", &dso_2);
assert(r == 0);
r = __MCF_cxa_atexit(cleanup_2, (void*) "f1", &dso_1);
r = __MCF_cxa_atexit((__MCF_cxa_dtor_cdecl*) cleanup_2, (void*) "f1", &dso_1);
assert(r == 0);
r = __MCF_cxa_atexit(cleanup_2, (void*) "g1", &dso_1);
r = __MCF_cxa_atexit((__MCF_cxa_dtor_cdecl*) cleanup_2, (void*) "g1", &dso_1);
assert(r == 0);
r = __MCF_cxa_atexit(cleanup_2, (void*) "hN", NULL);
r = __MCF_cxa_atexit((__MCF_cxa_dtor_cdecl*) cleanup_2, (void*) "hN", NULL);
assert(r == 0);
r = __MCF_cxa_atexit(cleanup_1, (void*) "i1", &dso_1);
assert(r == 0);
Expand All @@ -54,13 +56,13 @@ main(void)
assert(r == 0);
r = __MCF_cxa_atexit(cleanup_1, (void*) "lN", NULL);
assert(r == 0);
r = __MCF_cxa_atexit(cleanup_2, (void*) "m1", &dso_1);
r = __MCF_cxa_atexit((__MCF_cxa_dtor_cdecl*) cleanup_2, (void*) "m1", &dso_1);
assert(r == 0);
r = __MCF_cxa_atexit(cleanup_2, (void*) "n2", &dso_2);
r = __MCF_cxa_atexit((__MCF_cxa_dtor_cdecl*) cleanup_2, (void*) "n2", &dso_2);
assert(r == 0);
r = __MCF_cxa_atexit(cleanup_2, (void*) "o2", &dso_2);
r = __MCF_cxa_atexit((__MCF_cxa_dtor_cdecl*) cleanup_2, (void*) "o2", &dso_2);
assert(r == 0);
r = __MCF_cxa_atexit(cleanup_2, (void*) "pN", NULL);
r = __MCF_cxa_atexit((__MCF_cxa_dtor_cdecl*) cleanup_2, (void*) "pN", NULL);
assert(r == 0);

assert(strcmp(buffer, "") == 0);
Expand Down

0 comments on commit 84b3470

Please sign in to comment.