Skip to content

Commit

Permalink
Reworked, again, exit process
Browse files Browse the repository at this point in the history
  • Loading branch information
ptitSeb committed Feb 6, 2024
1 parent 255d5c6 commit ee2580a
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 35 deletions.
2 changes: 2 additions & 0 deletions src/elfs/elfloader.c
Original file line number Diff line number Diff line change
Expand Up @@ -1383,6 +1383,8 @@ void RunElfFini(elfheader_t* h, x64emu_t *emu)
if(!h || h->fini_done || !h->init_done)
return;
h->fini_done = 1;
// Call the registered cxa_atexit functions
CallCleanup(emu, h);
#ifdef ANDROID
// TODO: Fix .fini_array on Android
printf_log(LOG_DEBUG, "Android does not support Fini for %s\n", ElfName(h));
Expand Down
5 changes: 5 additions & 0 deletions src/elfs/elfloader_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ typedef struct library_s library_t;
typedef struct needed_libs_s needed_libs_t;
typedef struct kh_mapsymbols_s kh_mapsymbols_t;
typedef struct kh_defaultversion_s kh_defaultversion_t;
typedef struct cleanup_s cleanup_t;

#include <elf.h>
#include "elfloader.h"
Expand Down Expand Up @@ -112,6 +113,10 @@ typedef struct elfheader_s {
FILE* file;
int fileno;

cleanup_t *cleanups; // atexit functions
int clean_sz;
int clean_cap;

kh_mapsymbols_t *mapsymbols;
kh_mapsymbols_t *weaksymbols;
kh_mapsymbols_t *localsymbols;
Expand Down
44 changes: 22 additions & 22 deletions src/emu/x64emu.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "x64run_private.h"
#include "callback.h"
#include "bridge.h"
#include "elfs/elfloader_private.h"
#ifdef HAVE_TRACE
#include "x64trace.h"
#endif
Expand All @@ -33,7 +34,6 @@ typedef struct cleanup_s {
void* f;
int arg;
void* a;
void* dso;
} cleanup_t;

static uint32_t x86emu_parity_tab[8] =
Expand Down Expand Up @@ -132,7 +132,7 @@ void SetTraceEmu(uintptr_t start, uintptr_t end)
}
#endif

void AddCleanup(x64emu_t *emu, void *p, void* dso_handle)
void AddCleanup(x64emu_t *emu, void *p)
{
(void)emu;

Expand All @@ -142,36 +142,36 @@ void AddCleanup(x64emu_t *emu, void *p, void* dso_handle)
}
my_context->cleanups[my_context->clean_sz].arg = 0;
my_context->cleanups[my_context->clean_sz].a = NULL;
my_context->cleanups[my_context->clean_sz].dso = dso_handle;
my_context->cleanups[my_context->clean_sz++].f = p;
}

void AddCleanup1Arg(x64emu_t *emu, void *p, void* a, void* dso_handle)
void AddCleanup1Arg(x64emu_t *emu, void *p, void* a, elfheader_t* h)
{
(void)emu;
if(!h)
return;

if(my_context->clean_sz == my_context->clean_cap) {
my_context->clean_cap += 32;
my_context->cleanups = (cleanup_t*)box_realloc(my_context->cleanups, sizeof(cleanup_t)*my_context->clean_cap);
if(h->clean_sz == h->clean_cap) {
h->clean_cap += 32;
h->cleanups = (cleanup_t*)box_realloc(h->cleanups, sizeof(cleanup_t)*h->clean_cap);
}
my_context->cleanups[my_context->clean_sz].arg = 1;
my_context->cleanups[my_context->clean_sz].a = a;
my_context->cleanups[my_context->clean_sz].dso = dso_handle;
my_context->cleanups[my_context->clean_sz++].f = p;
h->cleanups[h->clean_sz].arg = 1;
h->cleanups[h->clean_sz].a = a;
h->cleanups[h->clean_sz++].f = p;
}

void CallCleanup(x64emu_t *emu, void* p)
void CallCleanup(x64emu_t *emu, elfheader_t* h)
{
printf_log(LOG_DEBUG, "Calling atexit registered functions for %p mask\n", p);
for(int i=my_context->clean_sz-1; i>=0; --i) {
if(p==my_context->cleanups[i].dso) {
printf_log(LOG_DEBUG, "Call cleanup #%d\n", i);
RunFunctionWithEmu(emu, 0, (uintptr_t)(my_context->cleanups[i].f), my_context->cleanups[i].arg, my_context->cleanups[i].a );
// now remove the cleanup
if(i!=my_context->clean_sz-1)
memmove(my_context->cleanups+i, my_context->cleanups+i+1, (my_context->clean_sz-i-1)*sizeof(cleanup_t));
--my_context->clean_sz;
}
printf_log(LOG_DEBUG, "Calling atexit registered functions for elf: %p/%s\n", h, h?h->name:"(nil)");
if(!h)
return;
for(int i=h->clean_sz-1; i>=0; --i) {
printf_log(LOG_DEBUG, "Call cleanup #%d\n", i);
RunFunctionWithEmu(emu, 0, (uintptr_t)(h->cleanups[i].f), h->cleanups[i].arg, h->cleanups[i].a );
// now remove the cleanup
if(i!=h->clean_sz-1)
memmove(h->cleanups+i, h->cleanups+i+1, (h->clean_sz-i-1)*sizeof(cleanup_t));
--h->clean_sz;
}
}

Expand Down
7 changes: 4 additions & 3 deletions src/include/x64emu.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

typedef struct x64emu_s x64emu_t;
typedef struct box64context_s box64context_t;
typedef struct elfheader_s elfheader_t;

x64emu_t *NewX64Emu(box64context_t *context, uintptr_t start, uintptr_t stack, int stacksize, int ownstack);
x64emu_t *NewX64EmuFromStack(x64emu_t* emu, box64context_t *context, uintptr_t start, uintptr_t stack, int stacksize, int ownstack);
Expand Down Expand Up @@ -45,9 +46,9 @@ const char* DumpCPURegs(x64emu_t* emu, uintptr_t ip, int is32bits);

void StopEmu(x64emu_t* emu, const char* reason, int is32bits);
void EmuCall(x64emu_t* emu, uintptr_t addr);
void AddCleanup(x64emu_t *emu, void *p, void* dso_handle);
void AddCleanup1Arg(x64emu_t *emu, void *p, void* a, void* dso_handle);
void CallCleanup(x64emu_t *emu, void* p);
void AddCleanup(x64emu_t *emu, void *p);
void AddCleanup1Arg(x64emu_t *emu, void *p, void* a, elfheader_t* h);
void CallCleanup(x64emu_t *emu, elfheader_t* h);
void CallAllCleanup(x64emu_t *emu);
void UnimpOpcode(x64emu_t* emu, int is32bits);

Expand Down
2 changes: 2 additions & 0 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1383,6 +1383,8 @@ void endBox64()
box64_quit = 1;
endMallocHook();
x64emu_t* emu = thread_get_emu();
void startTimedExit();
startTimedExit();
// atexit first
printf_log(LOG_DEBUG, "Calling atexit registered functions (exiting box64)\n");
CallAllCleanup(emu);
Expand Down
26 changes: 16 additions & 10 deletions src/wrapped/wrappedlibc.c
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@ void EXPORT my___gmon_start__(x64emu_t *emu)

int EXPORT my___cxa_atexit(x64emu_t* emu, void* p, void* a, void* dso_handle)
{
AddCleanup1Arg(emu, p, a, dso_handle);
AddCleanup1Arg(emu, p, a, FindElfAddress(my_context, (uintptr_t)dso_handle));
return 0;
}
void EXPORT my___cxa_finalize(x64emu_t* emu, void* p)
Expand All @@ -495,11 +495,11 @@ void EXPORT my___cxa_finalize(x64emu_t* emu, void* p)
CallAllCleanup(emu);
return;
}
CallCleanup(emu, p);
CallCleanup(emu, FindElfAddress(my_context, (uintptr_t)p));
}
int EXPORT my_atexit(x64emu_t* emu, void *p)
{
AddCleanup(emu, p, NULL); // should grab current dso_handle?
AddCleanup(emu, p);
return 0;
}

Expand Down Expand Up @@ -2308,7 +2308,7 @@ EXPORT int32_t my___cxa_thread_atexit_impl(x64emu_t* emu, void* dtor, void* obj,
{
(void)emu;
//printf_log(LOG_INFO, "Warning, call to __cxa_thread_atexit_impl(%p, %p, %p) ignored\n", dtor, obj, dso);
AddCleanup1Arg(emu, dtor, obj, dso);
AddCleanup1Arg(emu, dtor, obj, FindElfAddress(my_context, (uintptr_t)dso));
return 0;
}

Expand Down Expand Up @@ -3375,15 +3375,24 @@ EXPORT int my_register_printf_type(x64emu_t* emu, void* f)
extern int box64_quit;
extern int box64_exit_code;
void endBox64();
#if !defined(ANDROID)
static void* timed_exit_thread(void* a)
{
// this is a workaround for some NVidia drivers on ARM64 that may freeze at exit
// waiting on a pthread_cond_destroy
usleep(500000); // wait 1/2 a second
_exit(box64_exit_code); // force exit, something is wrong
}
#endif

void startTimedExit()
{
static int started = 0;
if(started)
exit;
started = 1;
pthread_t exit_thread;
pthread_create(&exit_thread, NULL, timed_exit_thread, NULL);
}

EXPORT void my_exit(x64emu_t* emu, int code)
{
if(emu->flags.quitonexit) {
Expand All @@ -3395,10 +3404,7 @@ EXPORT void my_exit(x64emu_t* emu, int code)
emu->quit = 1;
box64_exit_code = code;
endBox64();
#if !defined(ANDROID)
pthread_t exit_thread;
pthread_create(&exit_thread, NULL, timed_exit_thread, NULL);
#endif
startTimedExit();
exit(code);
}

Expand Down

0 comments on commit ee2580a

Please sign in to comment.