Extremely initial work on dealing with external modules.

This commit is contained in:
Ryan C. Gordon committed 2016-09-20 00:48:56 -04:00
1 parent 45eebeaa3f
commit 1d8ad0ce35
1 file changed
+43 -12
+43 -12
View File
@@ -167,11 +167,11 @@ static int decompressExePack2(uint8 *dst, const uint32 dstlen, const uint8 *src,
return 1;
} // decompressExePack2
void missing_ordinal_called(const uint32 ordinal)
void missing_ordinal_called(const char *module, const uint32 ordinal)
{
fflush(stdout);
fflush(stderr);
fprintf(stderr, "\n\nMissing ordinal '%u' called!\n", ordinal);
fprintf(stderr, "\n\nMissing ordinal '%u' in module '%s' called!\n", ordinal, module);
fprintf(stderr, "Aborting.\n\n\n");
//STUBBED("output backtrace");
fflush(stderr);
@@ -186,13 +186,15 @@ static uint32 DosPutMessage(uint32 handle, uint32 msglen, const char *msg)
return 0;
} // DosPutMessage
static uint32 getModuleProcAddrByOrdinal(const uint16 moduleid, const uint32 importid)
static uint32 getModuleProcAddrByOrdinal(const LxHeader *lx, const char * const * const modules, const uint16 moduleid, const uint32 importid)
{
// !!! FIXME: write me for real.
if (moduleid != 1) { // this is MSG in hello.exe, for testing purposes.
fprintf(stderr, "uhoh, looking for module ordinal that isn't #1.\n");
if (moduleid == 0) {
fprintf(stderr, "uhoh, looking for module ordinal 0, which is illegal.\n");
return 0;
} // if
} else if (moduleid > lx->num_import_mod_entries) {
fprintf(stderr, "uhoh, looking for module ordinal %u, but only %u available.\n", (unsigned int) moduleid, (unsigned int) lx->num_import_mod_entries);
return 0;
} // else if
//fprintf(stderr, "importid == %u\n", (unsigned int) importid);
@@ -211,8 +213,12 @@ static uint32 getModuleProcAddrByOrdinal(const uint16 moduleid, const uint32 imp
pageused = 0;
} // if
if (importid == 5) // !!! FIXME: this is DosPutMessage in the MSG module.
return (uint32) (size_t) DosPutMessage;
// !!! FIXME: obviously, this is going to have to be more robust.
if (strcmp(modules[moduleid-1], "MSG") == 0)
{
if (importid == 5)
return (uint32) (size_t) DosPutMessage;
} // if
void *trampoline = page + pageused;
char *ptr = (char *) trampoline;
@@ -224,6 +230,9 @@ static uint32 getModuleProcAddrByOrdinal(const uint16 moduleid, const uint32 imp
*(ptr++) = 0x68; // pushl immediate
memcpy(ptr, &ordinal, sizeof (uint32));
ptr += sizeof (uint32);
*(ptr++) = 0x68; // pushl immediate
memcpy(ptr, &modules[moduleid-1], sizeof (uint32));
ptr += sizeof (uint32);
*(ptr++) = 0xB8; // movl immediate to %eax
const void *fn = missing_ordinal_called;
memcpy(ptr, &fn, sizeof (void *));
@@ -270,7 +279,7 @@ static void doFixup(uint8 *page, const uint16 offset, const uint32 finalval, con
} // switch
} // doFixup
static void fixupPage(const LxHeader *lx, const LxObjectTableEntry *obj, uint8 *page)
static void fixupPage(const LxHeader *lx, const char * const * const modules, const LxObjectTableEntry *obj, uint8 *page)
{
const uint8 *exe = (const uint8 *) lx; // this is the start of the LX EXE (past the DOS stub, etc).
const uint32 *fixuppage = (((const uint32 *) (exe + lx->fixup_page_table_offset)) + (obj->page_table_index - 1));
@@ -363,7 +372,7 @@ static void fixupPage(const LxHeader *lx, const LxObjectTableEntry *obj, uint8 *
importid = (uint32) *((uint16 *) fixup); fixup += 2;
} // else
finalval = getModuleProcAddrByOrdinal(moduleid, importid);
finalval = getModuleProcAddrByOrdinal(lx, modules, moduleid, importid);
break;
} // case
@@ -422,6 +431,28 @@ static __attribute__((noreturn)) void loadExe(const char *exefname, uint8 *exe,
const LxHeader *lx = (const LxHeader *) exe;
// !!! FIXME: recursively load all external dependencies from lx->import_module_table_offset, here.
char **modules = malloc(sizeof (char *) * lx->num_import_mod_entries);
if (!modules) {
fprintf(stderr, "Out of memory!\n");
exit(1);
}
const uint8 *import_modules_table = exe + lx->import_module_table_offset;
for (uint32 i = 0; i < lx->num_import_mod_entries; i++) {
const uint8 namelen = *(import_modules_table++);
// !!! FIXME: name can't be more than 127 chars, according to docs. Check this.
char *str = (char *) malloc(namelen + 1);
if (!str) {
fprintf(stderr, "Out of memory!\n");
exit(1);
}
memcpy(str, import_modules_table, namelen);
import_modules_table += namelen;
str[namelen] = '\0';
modules[i] = str;
} // for
const LxObjectTableEntry *obj = ((const LxObjectTableEntry *) (exe + lx->object_table_offset));
for (uint32 i = 0; i < lx->module_num_objects; i++, obj++) {
@@ -488,7 +519,7 @@ static __attribute__((noreturn)) void loadExe(const char *exefname, uint8 *exe,
} // switch
// Now run any fixups for the page...
fixupPage(lx, obj, dst);
fixupPage(lx, modules, obj, dst);
dst += lx->page_size;
} // for