From f681be1b1f12a29733d80c5b7074107e648fd547 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 2 Oct 2016 18:18:31 -0400 Subject: [PATCH] Reworked the native module loading code. --- lx_loader.c | 127 +++++++++++++++++++++++++-------------------- lx_loader.h | 23 ++++---- native/doscalls.c | 44 ++++++++++++++-- native/doscalls.h | 1 + native/kbdcalls.c | 6 +-- native/msg.c | 8 ++- native/nls.c | 15 ++++-- native/nls.h | 9 ++++ native/os2native.h | 52 ++++++------------- native/os2types.h | 8 ++- native/quecalls.c | 6 +-- native/sesmgr.c | 6 +-- native/viocalls.c | 6 +-- 13 files changed, 178 insertions(+), 133 deletions(-) diff --git a/lx_loader.c b/lx_loader.c index c365bf5..031f60f 100644 --- a/lx_loader.c +++ b/lx_loader.c @@ -15,7 +15,6 @@ static LxLoaderState _GLoaderState; static LxLoaderState *GLoaderState = &_GLoaderState; - // !!! FIXME: move this into an lx_common.c file. static int sanityCheckLxModule(uint8 **_exe, uint32 *_exelen) { @@ -215,7 +214,7 @@ static void missingEntryPointCalled(const char *module, const char *entry) _exit(1); } // missing_ordinal_called -static uint32 generateMissingTrampoline(const char *_module, const char *_entry) +static void *generateMissingTrampoline(const char *_module, const char *_entry) { static void *page = NULL; static uint32 pageused = 0; @@ -261,9 +260,9 @@ static uint32 generateMissingTrampoline(const char *_module, const char *_entry) if (pageused % 4) // keep these aligned to 32 bits. pageused += (4 - (pageused % 4)); - printf("Generated trampoline %p for module '%s' export '%s'\n", trampoline, module, entry); + //printf("Generated trampoline %p for module '%s' export '%s'\n", trampoline, module, entry); - return (uint32) (size_t) trampoline; + return trampoline; } // generateMissingTrampoline static __attribute__((noreturn)) void runLxModule(LxModule *lxmod, const int argc, char **argv) @@ -343,7 +342,6 @@ static __attribute__((noreturn)) void runLxModule(LxModule *lxmod, const int arg static void runLxLibraryInitOrTerm(LxModule *lxmod, const int isTermination) { - // ...and you pass it the pointer to argv0. This is (at least as far as the docs suggest) appended to the environment table. printf("jumping into LX land to %s library...! eip=0x%X esp=0x%X\n", isTermination ? "terminate" : "initialize", (uint) lxmod->eip, (uint) GLoaderState->main_module->esp); fflush(stdout); // !!! FIXME: need to set up OS/2 TIB and put it in FS register. @@ -395,8 +393,15 @@ static void freeLxModule(LxModule *lxmod) if (lxmod->refcount > 0) return; // something is still using it. - if (lxmod->initialized) - runLxLibraryTerm(lxmod); + if (lxmod->initialized) { + if (!lxmod->nativelib) { + runLxLibraryTerm(lxmod); + } else { + LxNativeModuleDeinitEntryPoint fn = (LxNativeModuleDeinitEntryPoint) dlsym(lxmod->nativelib, "lxNativeModuleDeinit"); + if (fn) + fn(); + } // else + } // if if (lxmod->next) lxmod->next->prev = lxmod->prev; @@ -419,27 +424,29 @@ static void freeLxModule(LxModule *lxmod) if (lxmod->mmaps[i].addr) munmap(lxmod->mmaps[i].addr, lxmod->mmaps[i].size); } // for - free(lxmod->mmaps); - - free(lxmod->exported_names); - free(lxmod->exported_ordinals); + free(lxmod->mmaps); if (lxmod->nativelib) dlclose(lxmod->nativelib); + else { + for (uint32 i = 0; i < lxmod->num_exports; i++) + free((void *) lxmod->exports[i].name); + free((void *) lxmod->exports); + } // else free(lxmod); } // freeLxModule static LxModule *loadLxModuleByModuleNameInternal(const char *modname, const int dependency_tree_depth); -static uint32 getModuleProcAddrByOrdinal(const LxModule *module, const uint32 ordinal) +static void *getModuleProcAddrByOrdinal(const LxModule *module, const uint32 ordinal) { - printf("lookup module == '%s', ordinal == %u\n", module->name, (uint) ordinal); + //printf("lookup module == '%s', ordinal == %u\n", module->name, (uint) ordinal); - const LxExportedOrdinal *expord = module->exported_ordinals; - for (uint32 i = 0; i < module->num_ordinals; i++, expord++) { - if (expord->ordinal == ordinal) - return expord->addr; + const LxExport *lxexp = module->exports; + for (uint32 i = 0; i < module->num_exports; i++, lxexp++) { + if (lxexp->ordinal == ordinal) + return lxexp->addr; } // for #if 1 @@ -447,25 +454,25 @@ static uint32 getModuleProcAddrByOrdinal(const LxModule *module, const uint32 or snprintf(entry, sizeof (entry), "ORDINAL_%u", (uint) ordinal); return generateMissingTrampoline(module->name, entry); #else - return 0; + return NULL; #endif } // getModuleProcAddrByOrdinal #if 0 -static uint32 getModuleProcAddrByName(const LxModule *module, const char *name) +static void *getModuleProcAddrByName(const LxModule *module, const char *name) { - printf("lookup module == '%s', name == '%s'\n", module->name, name); + //printf("lookup module == '%s', name == '%s'\n", module->name, name); - const LxExportedName *expname = module->exported_names; - for (uint32 i = 0; i < module->num_names; i++, expname++) { - if (strcmp(expname->name, name) == 0) - return expname->addr; + const LxExport *lxexp = module->exports; + for (uint32 i = 0; i < module->num_exports; i++, lxexp++) { + if (strcmp(lxexp->name, name) == 0) + return lxexp->addr; } // for #if 1 return generateMissingTrampoline(module->name, name); #else - return 0; + return NULL; #endif } // getModuleProcAddrByName #endif @@ -501,15 +508,15 @@ static void doFixup(uint8 *page, const sint16 offset, const uint32 finalval, con static void fixupPage(const uint8 *exe, LxModule *lxmod, const LxObjectTableEntry *obj, const uint32 pagenum, uint8 *page) { const LxHeader *lx = &lxmod->lx; -const LxObjectTableEntry *origobj = ((const LxObjectTableEntry *) (exe + lx->object_table_offset)); +//const LxObjectTableEntry *origobj = ((const LxObjectTableEntry *) (exe + lx->object_table_offset)); const uint32 *fixuppage = (((const uint32 *) (exe + lx->fixup_page_table_offset)) + ((obj->page_table_index - 1) + pagenum)); const uint32 fixupoffset = *fixuppage; const uint32 fixuplen = fixuppage[1] - fixuppage[0]; const uint8 *fixup = (exe + lx->fixup_record_table_offset) + fixupoffset; const uint8 *fixupend = fixup + fixuplen; - int record = 0; +// int record = 0; while (fixup < fixupend) { -record++; printf("FIXUP obj #%u page #%u record #: %d\n", (uint) (obj - origobj), (uint) pagenum, record); +//record++; printf("FIXUP obj #%u page #%u record #: %d\n", (uint) (obj - origobj), (uint) pagenum, record); const uint8 srctype = *(fixup++); const uint8 fixupflags = *(fixup++); uint8 srclist_count = 0; @@ -590,7 +597,7 @@ record++; printf("FIXUP obj #%u page #%u record #: %d\n", (uint) (obj - origobj) } else if (moduleid > lx->num_import_mod_entries) { fprintf(stderr, "uhoh, looking for module ordinal %u, but only %u available.\n", (uint) moduleid, (uint) lx->num_import_mod_entries); } else { - finalval = getModuleProcAddrByOrdinal(lxmod->dependencies[moduleid-1], importid); + finalval = (uint32) (size_t) getModuleProcAddrByOrdinal(lxmod->dependencies[moduleid-1], importid); } // else break; } // case @@ -701,7 +708,7 @@ static LxModule *loadLxModule(const char *fname, uint8 *exe, uint32 exelen, int } // else if const char *modname = retval->name; - printf("ref'd new module '%s' to %u\n", modname, 1); + //printf("ref'd new module '%s' to %u\n", modname, 1); // !!! FIXME: apparently OS/2 does 1024, but they're not loading the module into RAM each time. // !!! FIXME: the spec mentions the 1024 thing for "forwarder" records in the entry table, @@ -788,7 +795,7 @@ static LxModule *loadLxModule(const char *fname, uint8 *exe, uint32 exelen, int } // for // All the pages we need from the EXE are loaded into the appropriate spots in memory. - printf("mmap()'d everything we need!\n"); + //printf("mmap()'d everything we need!\n"); retval->eip = lx->eip; if (lx->eip_object != 0) { @@ -818,14 +825,14 @@ static LxModule *loadLxModule(const char *fname, uint8 *exe, uint32 exelen, int } } // while - retval->exported_ordinals = (LxExportedOrdinal *) malloc(sizeof (LxExportedOrdinal) * total_ordinals); - if (!retval->exported_ordinals) { + LxExport *lxexp = (LxExport *) malloc(sizeof (LxExport) * total_ordinals); + if (!lxexp) { fprintf(stderr, "Out of memory!\n"); goto loadlx_failed; } // if - memset(retval->exported_ordinals, '\0', sizeof (LxExportedOrdinal) * total_ordinals); + memset(lxexp, '\0', sizeof (LxExport) * total_ordinals); + retval->exports = lxexp; - LxExportedOrdinal *expord = retval->exported_ordinals; uint32 ordinal = 1; entryptr = exe + lx->entry_table_offset; while (*entryptr) { /* end field has a value of zero. */ @@ -843,9 +850,9 @@ static LxModule *loadLxModule(const char *fname, uint8 *exe, uint32 exelen, int entryptr += 2; for (uint8 i = 0; i < numentries; i++) { entryptr++; - expord->ordinal = ordinal++; - expord->addr = (uint32) (size_t) ((uint8 *) retval->mmaps[objidx].addr) + *((const uint16 *) entryptr); - expord++; + lxexp->ordinal = ordinal++; + lxexp->addr = ((uint8 *) retval->mmaps[objidx].addr) + *((const uint16 *) entryptr); + lxexp++; entryptr += 2; } // for break; @@ -855,9 +862,9 @@ static LxModule *loadLxModule(const char *fname, uint8 *exe, uint32 exelen, int entryptr += 2; for (uint8 i = 0; i < numentries; i++) { entryptr++; - expord->ordinal = ordinal++; - expord->addr = (uint32) (size_t) ((uint8 *) retval->mmaps[objidx].addr) + *((const uint32 *) entryptr); - expord++; + lxexp->ordinal = ordinal++; + lxexp->addr = ((uint8 *) retval->mmaps[objidx].addr) + *((const uint32 *) entryptr); + lxexp++; entryptr += 4; } break; @@ -873,10 +880,10 @@ static LxModule *loadLxModule(const char *fname, uint8 *exe, uint32 exelen, int } // switch } // while - retval->num_ordinals = (uint32) (expord - retval->exported_ordinals); + retval->num_exports = (uint32) (lxexp - retval->exports); // Now load named entry points. - printf("FIXME: load named entry points\n"); + //printf("FIXME: load named entry points\n"); // Load other dependencies of this module. const uint8 *import_modules_table = exe + lx->import_module_table_offset; @@ -1004,40 +1011,50 @@ static inline LxModule *loadLxModuleByPath(const char *fname) return loadLxModuleByPathInternal(fname, 0); } // loadLxModuleByPath -static LxModule *loadNativeReplacement(const char *fname) +static LxModule *loadNativeModule(const char *fname, const char *modname) { - LxModule *retval = NULL; + LxModule *retval = (LxModule *) malloc(sizeof (LxModule)); void *lib = NULL; - LxNativeReplacementEntryPoint fn = NULL; + LxNativeModuleInitEntryPoint fn = NULL; + const LxExport *exports = NULL; + uint32 num_exports = 0; char *os2path = makeOS2Path(fname); - if (!os2path) + if (!retval || !modname || !os2path) goto loadnative_failed; + + memset(retval, '\0', sizeof(*retval)); // !!! FIXME: mutex this. lib = dlopen(fname, RTLD_LOCAL | RTLD_NOW); if (lib == NULL) goto loadnative_failed; - fn = (LxNativeReplacementEntryPoint) dlsym(lib, "loadNativeLxModule"); + fn = (LxNativeModuleInitEntryPoint) dlsym(lib, "lxNativeModuleInit"); if (!fn) goto loadnative_failed; - retval = fn(GLoaderState); - if (!retval) + exports = fn(GLoaderState, &num_exports); + if (!exports) goto loadnative_failed; - - printf("Loaded native replacement library '%s' (%u exports).\n", fname, (uint) retval->num_ordinals); + retval->refcount = 1; + strcpy(retval->name, modname); retval->nativelib = lib; retval->os2path = os2path; + retval->exports = exports; + retval->num_exports = num_exports; + retval->initialized = 1; + + printf("Loaded native module '%s' (%u exports).\n", fname, (uint) num_exports); return retval; loadnative_failed: if (lib) dlclose(lib); free(os2path); + free(retval); return NULL; -} // loadNativeReplacement +} // loadNativeModule static LxModule *loadLxModuleByModuleNameInternal(const char *modname, const int dependency_tree_depth) { @@ -1045,7 +1062,7 @@ static LxModule *loadLxModuleByModuleNameInternal(const char *modname, const int for (LxModule *i = GLoaderState->loaded_modules; i != NULL; i = i->next) { if (strcasecmp(i->name, modname) == 0) { i->refcount++; - printf("ref'd module '%s' to %u\n", i->name, (uint) i->refcount); + //printf("ref'd module '%s' to %u\n", i->name, (uint) i->refcount); return i; } // if } // for @@ -1059,7 +1076,7 @@ static LxModule *loadLxModuleByModuleNameInternal(const char *modname, const int for (char *ptr = fname; *ptr; ptr++) { *ptr = (((*ptr >= 'A') && (*ptr <= 'Z')) ? (*ptr - ('A' - 'a')) : *ptr); } // for - retval = loadNativeReplacement(fname); + retval = loadNativeModule(fname, modname); } // if return retval; } // loadLxModuleByModuleNameInternal diff --git a/lx_loader.h b/lx_loader.h index d22a35b..2bd8277 100644 --- a/lx_loader.h +++ b/lx_loader.h @@ -105,17 +105,12 @@ typedef struct LxMmaps size_t size; } LxMmaps; -typedef struct LxExportedOrdinal +typedef struct LxExport { uint32 ordinal; - uint32 addr; -} LxExportedOrdinal; - -typedef struct LxExportedName -{ - char name[128]; // !!! FIXME: allocate this. - uint32 addr; -} LxExportedName; + const char *name; // can be NULL + void *addr; +} LxExport; struct LxModule; typedef struct LxModule LxModule; @@ -126,10 +121,8 @@ struct LxModule char name[256]; // !!! FIXME: allocate this. LxModule **dependencies; LxMmaps *mmaps; - uint32 num_ordinals; - LxExportedOrdinal *exported_ordinals; - uint32 num_names; - LxExportedName *exported_names; + const LxExport *exports; + uint32 num_exports; void *nativelib; uint32 eip; uint32 esp; @@ -137,6 +130,7 @@ struct LxModule char *env; char *cmd; char *os2path; // absolute path to module, in OS/2 format + // !!! FIXME: put this elsewhere? uint32 signal_exception_focus_count; LxModule *prev; // all loaded modules are in a doubly-linked list. LxModule *next; // all loaded modules are in a doubly-linked list. @@ -148,7 +142,8 @@ typedef struct LxModule *main_module; } LxLoaderState; -typedef LxModule *(*LxNativeReplacementEntryPoint)(LxLoaderState *state); +typedef const LxExport *(*LxNativeModuleInitEntryPoint)(LxLoaderState *lx_state, uint32 *lx_num_exports); +typedef void (*LxNativeModuleDeinitEntryPoint)(void); #endif diff --git a/native/doscalls.c b/native/doscalls.c index 9937397..fabd25a 100644 --- a/native/doscalls.c +++ b/native/doscalls.c @@ -5,11 +5,12 @@ #include #include #include +#include #include "os2native.h" #include "doscalls.h" -NATIVE_MODULE(doscalls); +static LxLoaderState *GLoaderState = NULL; typedef struct ExitListItem { @@ -20,6 +21,43 @@ typedef struct ExitListItem static ExitListItem *GExitList = NULL; +static int *HFiles = NULL; + + +LX_NATIVE_MODULE_DEINIT({ + ExitListItem *next = GExitList; + GExitList = NULL; + for (ExitListItem *item = next; item; item = next) { + next = item->next; + free(item); + } // for + free(HFiles); + HFiles = NULL; + GLoaderState = NULL; +}) + +LX_NATIVE_MODULE_INIT({ GLoaderState = lx_state; }) + LX_NATIVE_EXPORT(DosQueryHType, 224), + LX_NATIVE_EXPORT(DosScanEnv, 227), + LX_NATIVE_EXPORT(DosExit, 234), + LX_NATIVE_EXPORT(DosWrite, 282), + LX_NATIVE_EXPORT(DosExitList, 296), + LX_NATIVE_EXPORT(DosAllocMem, 299), + LX_NATIVE_EXPORT(DosSetMem, 305), + LX_NATIVE_EXPORT(DosGetInfoBlocks, 312), + LX_NATIVE_EXPORT(DosQueryModuleName, 320), + LX_NATIVE_EXPORT(DosCreateEventSem, 324), + LX_NATIVE_EXPORT(DosCreateMutexSem, 331), + LX_NATIVE_EXPORT(DosSubSetMem, 344), + LX_NATIVE_EXPORT(DosSubAllocMem, 345), + LX_NATIVE_EXPORT(DosQuerySysInfo, 348), + LX_NATIVE_EXPORT(DosSetExceptionHandler, 354), + LX_NATIVE_EXPORT(DosSetSignalExceptionFocus, 378), + LX_NATIVE_EXPORT(DosSetRelMaxFH, 382), + LX_NATIVE_EXPORT(DosFlatToSel, 425) +LX_NATIVE_MODULE_INIT_END() + + APIRET DosGetInfoBlocks(PTIB *pptib, PPIB *pppib) { TRACE_NATIVE("DosGetInfoBlocks(%p, %p)", pptib, pppib); @@ -293,13 +331,13 @@ APIRET DosSetExceptionHandler(PEXCEPTIONREGISTRATIONRECORD rec) return NO_ERROR; } // DosSetExceptionHandler -static uint32 DosFlatToSel(void) +ULONG DosFlatToSel(void) { // this actually passes the arg in eax instead of the stack. uint32 eax = 0; __asm__ __volatile__ ("" : "=a" (eax)); TRACE_NATIVE("DosFlatToSel(%p)", (void *) (size_t) eax); - return 0x12345678; // !!! FIXME + return (ULONG) 0x12345678; // !!! FIXME } // DosFlatToSel APIRET DosSetSignalExceptionFocus(BOOL32 flag, PULONG pulTimes) diff --git a/native/doscalls.h b/native/doscalls.h index 0bcf1ce..d086fc0 100644 --- a/native/doscalls.h +++ b/native/doscalls.h @@ -107,6 +107,7 @@ APIRET OS2API DosExitList(ULONG ordercode, PFNEXITLIST pfn); APIRET OS2API DosCreateEventSem(PSZ pszName, PHEV phev, ULONG flAttr, BOOL32 fState); APIRET OS2API DosCreateMutexSem(PSZ pszName, PHMTX phmtx, ULONG flAttr, BOOL32 fState); APIRET OS2API DosSetExceptionHandler(PEXCEPTIONREGISTRATIONRECORD pERegRec); +ULONG OS2API DosFlatToSel(void); APIRET OS2API DosSetSignalExceptionFocus(BOOL32 flag, PULONG pulTimes); #ifdef __cplusplus diff --git a/native/kbdcalls.c b/native/kbdcalls.c index 66f56a8..8d715ca 100644 --- a/native/kbdcalls.c +++ b/native/kbdcalls.c @@ -1,10 +1,8 @@ #include "os2native.h" #include "kbdcalls.h" -NATIVE_MODULE(kdbcalls); - -NATIVE_REPLACEMENT_TABLE("kbdcalls") -END_NATIVE_REPLACEMENT_TABLE() +LX_NATIVE_MODULE_INIT() +LX_NATIVE_MODULE_INIT_END() // end of kbdcalls.c ... diff --git a/native/msg.c b/native/msg.c index 865751c..1793aa1 100644 --- a/native/msg.c +++ b/native/msg.c @@ -3,17 +3,15 @@ #include "os2native.h" #include "msg.h" -NATIVE_MODULE(msg); - APIRET DosPutMessage(HFILE handle, ULONG msglen, PCHAR msg) { write(handle, msg, msglen); return 0; } // DosPutMessage -NATIVE_REPLACEMENT_TABLE("msg") - NATIVE_REPLACEMENT(DosPutMessage, 5) -END_NATIVE_REPLACEMENT_TABLE() +LX_NATIVE_MODULE_INIT() + LX_NATIVE_EXPORT(DosPutMessage, 5) +LX_NATIVE_MODULE_INIT_END() // end of msg.c ... diff --git a/native/nls.c b/native/nls.c index a005476..dc565be 100644 --- a/native/nls.c +++ b/native/nls.c @@ -1,10 +1,19 @@ #include "os2native.h" #include "nls.h" -NATIVE_MODULE(nls); +APIRET DosQueryDBCSEnv(ULONG buflen, PCOUNTRYCODE pcc, PCHAR buf) +{ + // !!! FIXME: implement this for real. + TRACE_NATIVE("DosQueryDBCSEnv(%u, %p, %p)", (uint) buflen, pcc, buf); + if ((pcc->country != 0) || (pcc->codepage != 0)) + return ERROR_CODE_PAGE_NOT_FOUND; + memset(buf, '\0', buflen); + return NO_ERROR; +} // DosQueryDBCSEnv -NATIVE_REPLACEMENT_TABLE("nls") -END_NATIVE_REPLACEMENT_TABLE() +LX_NATIVE_MODULE_INIT() + LX_NATIVE_EXPORT(DosQueryDBCSEnv, 6) +LX_NATIVE_MODULE_INIT_END() // end of nls.c ... diff --git a/native/nls.h b/native/nls.h index 2881cd2..8ded340 100644 --- a/native/nls.h +++ b/native/nls.h @@ -7,6 +7,15 @@ extern "C" { #endif +typedef struct COUNTRYCODE +{ + ULONG country; + ULONG codepage; +} COUNTRYCODE, *PCOUNTRYCODE; + +APIRET OS2API DosQueryDBCSEnv(ULONG cb, PCOUNTRYCODE pcc, PCHAR pBuf); +APIRET OS2API DosSetRelMaxFH(PLONG pcbReqCount, PULONG pcbCurMaxFH); + #ifdef __cplusplus } #endif diff --git a/native/os2native.h b/native/os2native.h index 098f75a..3e584a8 100644 --- a/native/os2native.h +++ b/native/os2native.h @@ -3,6 +3,7 @@ #include #include +#include #include "os2types.h" #include "os2errors.h" @@ -14,45 +15,24 @@ #define TRACE_NATIVE(...) do {} while (0) #endif -// !!! FIXME: this is nasty for several reasons. -#define NATIVE_MODULE(modname) \ - static LxLoaderState *GLoaderState = NULL +OS2EXPORT const LxExport * lxNativeModuleInit(LxLoaderState *lx_state, uint32 *lx_num_exports); +void OS2EXPORT lxNativeModuleDeinit(void); -#define NATIVE_REPLACEMENT_TABLE(modname) \ - LxModule *loadNativeLxModule(LxLoaderState *state) { \ - GLoaderState = state; \ - LxModule *retval = (LxModule *) malloc(sizeof (LxModule)); \ - if (!retval) goto loadnative_failed; \ - memset(retval, '\0', sizeof (LxModule)); \ - retval->refcount = 1; \ - strcpy(retval->name, modname); \ +#define LX_NATIVE_MODULE_DEINIT(deinitcode) \ + void lxNativeModuleDeinit(void) { deinitcode; } -#define NATIVE_REPLACEMENT(fn, ord) { \ - void *ptr = realloc(retval->exported_names, (retval->num_names+1) * sizeof (LxExportedName)); \ - if (!ptr) { goto loadnative_failed; } \ - retval->exported_names = (LxExportedName *) ptr; \ - strcpy(retval->exported_names[retval->num_names].name, #fn); \ - retval->exported_names[retval->num_names].addr = (uint32) ((size_t) fn); \ - retval->num_names++; \ - ptr = realloc(retval->exported_ordinals, (retval->num_ordinals+1) * sizeof (LxExportedOrdinal)); \ - if (!ptr) { goto loadnative_failed; } \ - retval->exported_ordinals = (LxExportedOrdinal *) ptr; \ - retval->exported_ordinals[retval->num_ordinals].ordinal = ord; \ - retval->exported_ordinals[retval->num_ordinals].addr = (uint32) ((size_t) fn); \ - retval->num_ordinals++; \ - } +#define LX_NATIVE_MODULE_INIT(initcode) \ + const LxExport *lxNativeModuleInit(LxLoaderState *lx_state, uint32 *lx_num_exports) { \ + initcode; \ + static const LxExport lx_native_exports[] = { -#define END_NATIVE_REPLACEMENT_TABLE() \ - return retval; \ - \ - loadnative_failed: \ - if (retval) { \ - free(retval->exported_ordinals); \ - free(retval->exported_names); \ - free(retval); \ - } \ - return NULL; \ - } +#define LX_NATIVE_EXPORT(fn, ord) { ord, #fn, fn } + +#define LX_NATIVE_MODULE_INIT_END() \ + }; \ + *lx_num_exports = sizeof (lx_native_exports) / sizeof (lx_native_exports[0]); \ + return lx_native_exports; \ +} #endif diff --git a/native/os2types.h b/native/os2types.h index 105dc87..263859e 100644 --- a/native/os2types.h +++ b/native/os2types.h @@ -11,8 +11,12 @@ extern "C" { #define APIENTRY #endif +#ifndef OS2EXPORT +#define OS2EXPORT __attribute__((visibility("default"))) +#endif + #ifndef OS2API -#define OS2API APIENTRY __attribute__((visibility("default"))) +#define OS2API APIENTRY OS2EXPORT #endif typedef uint32_t APIRET; @@ -21,10 +25,12 @@ typedef uint32_t APIRET32; #define VOID void typedef uint32_t BOOL32; +typedef int32_t LONG, *PLONG; typedef uint32_t ULONG, *PULONG; typedef char CHAR, *PCHAR; typedef PCHAR PSZ; typedef VOID *PVOID; +typedef PVOID *PPVOID; typedef uint32_t HMODULE, *PHMODULE; typedef uint32_t HFILE, *PHFILE; typedef uint32_t HEV, *PHEV; diff --git a/native/quecalls.c b/native/quecalls.c index e685f2d..cf3c241 100644 --- a/native/quecalls.c +++ b/native/quecalls.c @@ -1,10 +1,8 @@ #include "os2native.h" #include "quecalls.h" -NATIVE_MODULE(quecalls); - -NATIVE_REPLACEMENT_TABLE("quecalls") -END_NATIVE_REPLACEMENT_TABLE() +LX_NATIVE_MODULE_INIT() +LX_NATIVE_MODULE_INIT_END() // end of quecalls.c ... diff --git a/native/sesmgr.c b/native/sesmgr.c index 29a2f82..8d66dab 100644 --- a/native/sesmgr.c +++ b/native/sesmgr.c @@ -1,10 +1,8 @@ #include "os2native.h" #include "sesmgr.h" -NATIVE_MODULE(sesmgr); - -NATIVE_REPLACEMENT_TABLE("sesmgr") -END_NATIVE_REPLACEMENT_TABLE() +LX_NATIVE_MODULE_INIT() +LX_NATIVE_MODULE_INIT_END() // end of sesmgr.c ... diff --git a/native/viocalls.c b/native/viocalls.c index 3b54fcc..7d074cc 100644 --- a/native/viocalls.c +++ b/native/viocalls.c @@ -1,10 +1,8 @@ #include "os2native.h" #include "viocalls.h" -NATIVE_MODULE(viocalls); - -NATIVE_REPLACEMENT_TABLE("viocalls") -END_NATIVE_REPLACEMENT_TABLE() +LX_NATIVE_MODULE_INIT() +LX_NATIVE_MODULE_INIT_END() // end of viocalls.c ...