From 3120b75e003dde5c8ee9e2ad1767c6b1593fadc1 Mon Sep 17 00:00:00 2001 From: Aaron Culliney Date: Mon, 22 Feb 2016 21:36:08 -0800 Subject: [PATCH] Enforce module ctor priorities --- Android/jni/jnihooks.c | 8 ----- src/audio/soundcore-openal.c | 5 ++- src/audio/soundcore-opensles.c | 5 ++- src/breakpad.C | 3 +- src/common.h | 4 --- src/darwin-shim.c | 7 ++-- src/disk.c | 5 ++- src/display.c | 5 ++- src/meta/debugger.c | 5 ++- src/meta/lintrace.c | 6 +++- src/misc.c | 61 ++++++++++++++++++++++++++++++---- src/misc.h | 11 ++++++ src/timing.c | 7 ---- src/video/glalert.c | 5 ++- src/video/glnode.c | 6 +++- src/video/gltouchjoy.c | 6 ++-- src/video/gltouchjoy_joy.c | 5 ++- src/video/gltouchjoy_kpad.c | 5 ++- src/video/gltouchkbd.c | 5 ++- src/video/gltouchmenu.c | 5 ++- src/video/glvideo.c | 5 ++- src/video/xvideo.c | 5 ++- 22 files changed, 134 insertions(+), 45 deletions(-) diff --git a/Android/jni/jnihooks.c b/Android/jni/jnihooks.c index aaec480e..fe18abb1 100644 --- a/Android/jni/jnihooks.c +++ b/Android/jni/jnihooks.c @@ -413,11 +413,3 @@ jstring Java_org_deadc0de_apple2ix_Apple2Activity_nativeLoadState(JNIEnv *env, j return jstr; } -// ---------------------------------------------------------------------------- -// Constructor - -__attribute__((constructor(CTOR_PRIORITY_LATE))) -static void _init_jnihooks(void) { - // ... -} - diff --git a/src/audio/soundcore-openal.c b/src/audio/soundcore-openal.c index 71ce6fa0..eb0d31e8 100644 --- a/src/audio/soundcore-openal.c +++ b/src/audio/soundcore-openal.c @@ -623,7 +623,6 @@ static long openal_systemResume(AudioContext_s *audio_context) { return 0; } -__attribute__((constructor(CTOR_PRIORITY_EARLY))) static void _init_openal(void) { LOG("Initializing OpenAL sound system"); @@ -637,3 +636,7 @@ static void _init_openal(void) { audio_backend = &openal_audio_backend; } +static __attribute__((constructor)) void __init_openal(void) { + emulator_registerStartupCallback(CTOR_PRIORITY_EARLY, &_init_openal); +} + diff --git a/src/audio/soundcore-opensles.c b/src/audio/soundcore-opensles.c index e96901f7..b51b957c 100644 --- a/src/audio/soundcore-opensles.c +++ b/src/audio/soundcore-opensles.c @@ -758,7 +758,6 @@ static long opensles_systemResume(AudioContext_s *audio_context) { return result; } -__attribute__((constructor(CTOR_PRIORITY_EARLY))) static void _init_opensl(void) { LOG("Initializing OpenSLES sound system"); @@ -772,3 +771,7 @@ static void _init_opensl(void) { audio_backend = &opensles_audio_backend; } +static __attribute__((constructor)) void __init_opensl(void) { + emulator_registerStartupCallback(CTOR_PRIORITY_EARLY, &_init_opensl); +} + diff --git a/src/breakpad.C b/src/breakpad.C index b880d2f9..2461e11c 100644 --- a/src/breakpad.C +++ b/src/breakpad.C @@ -60,8 +60,7 @@ extern "C" { #endif } - __attribute__((constructor(CTOR_PRIORITY_EARLY))) - static void _breakpad_registration(void) { + static void __attribute__((constructor)) _breakpad_registration(void) { LOG("Registering Breakpad as native crash handler"); breakpadHandler.init = &initBreakpadHandler; breakpadHandler.shutdown = &shutdownBreakpadHandler; diff --git a/src/common.h b/src/common.h index d4af2d63..033ca9a4 100644 --- a/src/common.h +++ b/src/common.h @@ -86,10 +86,6 @@ #import #endif -#define CTOR_PRIORITY_FIRST 101 -#define CTOR_PRIORITY_EARLY 111 -#define CTOR_PRIORITY_LATE 201 - #if VIDEO_OPENGL #include "video_util/glUtil.h" // 2015/04/01 ... early calls to glGetError()--before a context exists--causes segfaults on MacOS X diff --git a/src/darwin-shim.c b/src/darwin-shim.c index 4db91fed..89d48b57 100644 --- a/src/darwin-shim.c +++ b/src/darwin-shim.c @@ -21,8 +21,7 @@ static double orwl_timebase = 0.0; static uint64_t orwl_timestart = 0; -__attribute__((constructor(CTOR_PRIORITY_LATE))) -static void __init_darwin_shim() { +static void _init_darwin_shim(void) { LOG("Initializing Darwin Shim"); mach_timebase_info_data_t tb = { 0 }; mach_timebase_info(&tb); @@ -31,6 +30,10 @@ static void __init_darwin_shim() { orwl_timestart = mach_absolute_time(); } +static __attribute__((constructor)) void __init_darwin_shim(void) { + emulator_registerStartupCallback(CTOR_PRIORITY_LATE, &_init_darwin_shim); +} + int clock_gettime(int clk_id, struct timespec *tp) { double diff = (mach_absolute_time() - orwl_timestart) * orwl_timebase; tp->tv_sec = diff * ORWL_NANO; diff --git a/src/disk.c b/src/disk.c index afff469c..84e2e517 100644 --- a/src/disk.c +++ b/src/disk.c @@ -78,7 +78,6 @@ static uint8_t translate_table_6[0x40] = { static uint8_t rev_translate_table_6[0x80] = { 0x01 }; -__attribute__((constructor(CTOR_PRIORITY_LATE))) static void _init_disk6(void) { LOG("Disk ][ emulation module early setup"); memset(&disk6, 0x0, sizeof(disk6)); @@ -92,6 +91,10 @@ static void _init_disk6(void) { } } +static __attribute__((constructor)) void __init_disk6(void) { + emulator_registerStartupCallback(CTOR_PRIORITY_LATE, &_init_disk6); +} + static inline bool is_nib(const char * const name) { size_t len = strlen(name); if (len <= _NIBLEN) { diff --git a/src/display.c b/src/display.c index 1a51586a..27df9892 100644 --- a/src/display.c +++ b/src/display.c @@ -1524,7 +1524,6 @@ uint8_t floating_bus_hibit(const bool hibit) { return (b & ~0x80) | (hibit ? 0x80 : 0); } -__attribute__((constructor(CTOR_PRIORITY_LATE))) static void _init_interface(void) { LOG("Initializing display subsystem"); _initialize_interface_fonts(); @@ -1534,3 +1533,7 @@ static void _init_interface(void) { _initialize_color(); } +static __attribute__((constructor)) void __init_interface(void) { + emulator_registerStartupCallback(CTOR_PRIORITY_LATE, &_init_interface); +} + diff --git a/src/meta/debugger.c b/src/meta/debugger.c index 0d79225b..af7c6d2a 100644 --- a/src/meta/debugger.c +++ b/src/meta/debugger.c @@ -1313,7 +1313,6 @@ void display_help() { num_buffer_lines = i; } -__attribute__((constructor(CTOR_PRIORITY_LATE))) static void _init_debugger(void) { LOG("Initializing virtual machine debugger subsystem"); @@ -1330,6 +1329,10 @@ static void _init_debugger(void) { } } +static __attribute__((constructor)) void __init_debugger(void) { + emulator_registerStartupCallback(CTOR_PRIORITY_LATE, &_init_debugger); +} + #ifdef INTERFACE_CLASSIC /* ------------------------------------------------------------------------- do_debug_command () diff --git a/src/meta/lintrace.c b/src/meta/lintrace.c index 037b460f..f8433aa7 100644 --- a/src/meta/lintrace.c +++ b/src/meta/lintrace.c @@ -27,7 +27,6 @@ static int trace_fd = -1; static int trace_pid = -1; -__attribute__((constructor(CTOR_PRIORITY_LATE))) static void _trace_init(void) { TEMP_FAILURE_RETRY(trace_fd = open(TRACING_FILE, O_WRONLY)); if (trace_fd == -1) { @@ -38,6 +37,11 @@ static void _trace_init(void) { trace_pid = getpid(); } + +static __attribute__((constructor)) void __trace_init(void) { + emulator_registerStartupCallback(CTOR_PRIORITY_LATE, &_trace_init); +} + __attribute__((destructor(255))) static void _trace_shutdown(void) { if (trace_fd != -1) { diff --git a/src/misc.c b/src/misc.c index 88cb6046..45a47b5f 100644 --- a/src/misc.c +++ b/src/misc.c @@ -18,6 +18,14 @@ #define SAVE_MAGICK "A2VM" #define SAVE_MAGICK_LEN sizeof(SAVE_MAGICK) +typedef struct module_ctor_node_s { + struct module_ctor_node_s *next; + long order; + startup_callback_f ctor; +} module_ctor_node_s; + +static module_ctor_node_s *head = NULL; + bool do_logging = true; // also controlled by NDEBUG FILE *error_log = NULL; int sound_volume = 2; @@ -27,17 +35,20 @@ char **argv = NULL; int argc = 0; CrashHandler_s *crashHandler = NULL; -__attribute__((constructor(CTOR_PRIORITY_FIRST))) +#if defined(CONFIG_DATADIR) static void _init_common(void) { LOG("Initializing common..."); -#if defined(CONFIG_DATADIR) data_dir = strdup(CONFIG_DATADIR PATH_SEPARATOR PACKAGE_NAME); -#elif defined(ANDROID) - // data_dir is set up in JNI -#elif !defined(__APPLE__) +} + +static __attribute__((constructor)) void __init_common(void) { + emulator_registerStartupCallback(CTOR_PRIORITY_FIRST, &_init_common); +} +#elif defined(ANDROID) || defined(__APPLE__) + // data_dir is set up elsewhere +#else # error "Specify a CONFIG_DATADIR and PACKAGE_NAME" #endif -} static bool _save_state(int fd, const uint8_t * outbuf, ssize_t outmax) { ssize_t outlen = 0; @@ -227,7 +238,45 @@ static void _shutdown_threads(void) { #endif } +void emulator_registerStartupCallback(long order, startup_callback_f ctor) { + + static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + pthread_mutex_lock(&mutex); + + module_ctor_node_s *node = MALLOC(sizeof(module_ctor_node_s)); + assert(node); + node->next = NULL; + node->order = order; + node->ctor = ctor; + + module_ctor_node_s *p0 = NULL; + module_ctor_node_s *p = head; + while (p && (order > p->order)) { + p0 = p; + p = p->next; + } + if (p0) { + p0->next = node; + } else { + head = node; + } + node->next = p; + + pthread_mutex_unlock(&mutex); +} + void emulator_start(void) { + + module_ctor_node_s *p = head; + head = NULL; + while (p) { + p->ctor(); + module_ctor_node_s *next = p->next; + FREE(p); + p = next; + } + head = NULL; + #ifdef INTERFACE_CLASSIC load_settings(); // user prefs c_keys_set_key(kF8); // show credits before emulation start diff --git a/src/misc.h b/src/misc.h index 44bdd274..fb482314 100644 --- a/src/misc.h +++ b/src/misc.h @@ -16,6 +16,14 @@ #ifndef _MISC_H_ #define _MISC_H_ +enum { + CTOR_PRIORITY_FIRST = 101, + CTOR_PRIORITY_EARLY = 111, + CTOR_PRIORITY_LATE = 201, +}; + +typedef void (*startup_callback_f)(void); + // top installation directory extern const char *data_dir; @@ -23,6 +31,9 @@ extern const char *data_dir; extern char **argv; extern int argc; +// register a startup function +void emulator_registerStartupCallback(long order, startup_callback_f callback); + // start emulator (CPU, audio, and video) void emulator_start(void); diff --git a/src/timing.c b/src/timing.c index 825ecbe4..62d83471 100644 --- a/src/timing.c +++ b/src/timing.c @@ -84,13 +84,6 @@ pthread_cond_t cpu_thread_cond = PTHREAD_COND_INITIALIZER; // ----------------------------------------------------------------------------- -__attribute__((constructor(CTOR_PRIORITY_LATE))) -static void _init_timing(void) { - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - pthread_mutex_init(&interface_mutex, &attr); -} - struct timespec timespec_diff(struct timespec start, struct timespec end, bool *negative) { struct timespec t; diff --git a/src/video/glalert.c b/src/video/glalert.c index 9ea462ba..4cf8773b 100644 --- a/src/video/glalert.c +++ b/src/video/glalert.c @@ -369,7 +369,6 @@ static void _animation_setEnableShowTrackSector(bool enabled) { } } -__attribute__((constructor(CTOR_PRIORITY_LATE))) static void _init_glalert(void) { LOG("Initializing message animation subsystem"); @@ -393,3 +392,7 @@ static void _init_glalert(void) { }); } +static __attribute__((constructor)) void __init_glalert(void) { + emulator_registerStartupCallback(CTOR_PRIORITY_LATE, &_init_glalert); +} + diff --git a/src/video/glnode.c b/src/video/glnode.c index 96b4666d..fbf33c4e 100644 --- a/src/video/glnode.c +++ b/src/video/glnode.c @@ -252,7 +252,6 @@ static void glnode_mainLoop(void) { //---------------------------------------------------------------------------- -__attribute__((constructor(CTOR_PRIORITY_EARLY))) static void _init_glnode_manager(void) { LOG("Initializing GLNode manager subsystem"); @@ -273,3 +272,8 @@ static void _init_glnode_manager(void) { interface_getModelDataSetter = &glnode_getModelDataSetter; #endif } + +static __attribute__((constructor)) void __init_glnode_manager(void) { + emulator_registerStartupCallback(CTOR_PRIORITY_EARLY, &_init_glnode_manager); +} + diff --git a/src/video/gltouchjoy.c b/src/video/gltouchjoy.c index 8697bea7..564b016b 100644 --- a/src/video/gltouchjoy.c +++ b/src/video/gltouchjoy.c @@ -955,7 +955,6 @@ static bool gltouchjoy_isCalibrating(void) { return joyglobals.isCalibrating; } -__attribute__((constructor(CTOR_PRIORITY_LATE))) static void _init_gltouchjoy(void) { LOG("Registering OpenGL software touch joystick"); @@ -1040,6 +1039,10 @@ static void _init_gltouchjoy(void) { }); } +static __attribute__((constructor)) void __init_gltouchjoy(void) { + emulator_registerStartupCallback(CTOR_PRIORITY_LATE, &_init_gltouchjoy); +} + void gltouchjoy_registerVariant(touchjoy_variant_t variantType, GLTouchJoyVariant *touchJoyVariant) { switch (variantType) { case EMULATED_JOYSTICK: @@ -1058,7 +1061,6 @@ void gltouchjoy_registerVariant(touchjoy_variant_t variantType, GLTouchJoyVarian } } - void gldriver_joystick_reset(void) { #warning FIXME TODO expunge this olde API ... } diff --git a/src/video/gltouchjoy_joy.c b/src/video/gltouchjoy_joy.c index b3a1ffab..42965086 100644 --- a/src/video/gltouchjoy_joy.c +++ b/src/video/gltouchjoy_joy.c @@ -256,7 +256,6 @@ static void gltouchjoy_setTapDelay(float secs) { // ---------------------------------------------------------------------------- -__attribute__((constructor(CTOR_PRIORITY_EARLY))) static void _init_gltouchjoy_joy(void) { LOG("Registering OpenGL software touch joystick (joystick variant)"); @@ -282,3 +281,7 @@ static void _init_gltouchjoy_joy(void) { gltouchjoy_registerVariant(EMULATED_JOYSTICK, &happyHappyJoyJoy); } +static __attribute__((constructor)) void __init_gltouchjoy_joy(void) { + emulator_registerStartupCallback(CTOR_PRIORITY_EARLY, &_init_gltouchjoy_joy); +} + diff --git a/src/video/gltouchjoy_kpad.c b/src/video/gltouchjoy_kpad.c index fa024a10..c9dfda1f 100644 --- a/src/video/gltouchjoy_kpad.c +++ b/src/video/gltouchjoy_kpad.c @@ -473,7 +473,6 @@ static void touchkpad_setKeyRepeatThreshold(float repeatThresholdSecs) { // ---------------------------------------------------------------------------- -__attribute__((constructor(CTOR_PRIORITY_EARLY))) static void _init_gltouchjoy_kpad(void) { LOG("Registering OpenGL software touch joystick (keypad variant)"); @@ -503,3 +502,7 @@ static void _init_gltouchjoy_kpad(void) { gltouchjoy_registerVariant(EMULATED_KEYPAD, &kpadJoy); } +static __attribute__((constructor)) void __init_gltouchjoy_kpad(void) { + emulator_registerStartupCallback(CTOR_PRIORITY_EARLY, &_init_gltouchjoy_kpad); +} + diff --git a/src/video/gltouchkbd.c b/src/video/gltouchkbd.c index bff6fbb2..d24d2ec1 100644 --- a/src/video/gltouchkbd.c +++ b/src/video/gltouchkbd.c @@ -1039,7 +1039,6 @@ static void _initialize_keyboard_templates(void) { kbdTemplateAlt [MAINROW+3][9] = ICONTEXT_RETURN_R; } -__attribute__((constructor(CTOR_PRIORITY_LATE))) static void _init_gltouchkbd(void) { LOG("Registering OpenGL software touch keyboard"); @@ -1081,3 +1080,7 @@ static void _init_gltouchkbd(void) { }); } +static __attribute__((constructor)) void __init_gltouchkbd(void) { + emulator_registerStartupCallback(CTOR_PRIORITY_LATE, &_init_gltouchkbd); +} + diff --git a/src/video/gltouchmenu.c b/src/video/gltouchmenu.c index bdcfd763..66df1418 100644 --- a/src/video/gltouchmenu.c +++ b/src/video/gltouchmenu.c @@ -553,7 +553,6 @@ static void gltouchmenu_setGlyphScale(int glyphScale) { // ---------------------------------------------------------------------------- // Constructor -__attribute__((constructor(CTOR_PRIORITY_LATE))) static void _init_gltouchmenu(void) { LOG("Registering OpenGL software touch menu"); @@ -580,3 +579,7 @@ static void _init_gltouchmenu(void) { }); } +static __attribute__((constructor)) void __init_gltouchmenu(void) { + emulator_registerStartupCallback(CTOR_PRIORITY_LATE, &_init_gltouchmenu); +} + diff --git a/src/video/glvideo.c b/src/video/glvideo.c index 6b7f2929..07d4255d 100644 --- a/src/video/glvideo.c +++ b/src/video/glvideo.c @@ -449,7 +449,6 @@ static int64_t glvideo_onTouchEvent(interface_touch_event_t action, int pointer_ //---------------------------------------------------------------------------- -__attribute__((constructor(CTOR_PRIORITY_LATE))) static void _init_glvideo(void) { LOG("Initializing OpenGL renderer"); @@ -466,3 +465,7 @@ static void _init_glvideo(void) { }); } +static __attribute__((constructor)) void __init_glvideo(void) { + emulator_registerStartupCallback(CTOR_PRIORITY_LATE, &_init_glvideo); +} + diff --git a/src/video/xvideo.c b/src/video/xvideo.c index 2b93b57d..79be07d5 100644 --- a/src/video/xvideo.c +++ b/src/video/xvideo.c @@ -874,7 +874,6 @@ static void xdriver_render(void) { // no-op } -__attribute__((constructor(CTOR_PRIORITY_EARLY))) static void _init_xvideo(void) { LOG("Initializing X11 renderer"); @@ -889,3 +888,7 @@ static void _init_xvideo(void) { video_backend = &xvideo_backend; } +static __attribute__((constructor)) void __init_xvideo(void) { + emulator_registerStartupCallback(CTOR_PRIORITY_EARLY, &_init_xvideo); +} +