Added support for import-by-name fixup records.
Fixes Watcom C's wlink.exe not loading at all. (...and now it actually links binaries!).
This commit is contained in:
1 parent
cbffb2ff60
commit
2016af81a2
2 files changed
+64
-22
No files matched your search
@@ -284,10 +284,44 @@ static void parseExe(const char *exefname, uint8 *exe, uint32 exelen)
|
||||
printf("Additive: %u\n", (uint) additive);
|
||||
break;
|
||||
|
||||
case 0x2:
|
||||
case 0x2: {
|
||||
printf("Import by name fixup record:\n");
|
||||
printf("WRITE ME\n"); exit(1);
|
||||
if (fixupflags & 0x40) { // 16 bit value
|
||||
const uint16 val = *((uint16 *) fixup); fixup += 2;
|
||||
printf("Module ordinal: %u\n", (uint) val);
|
||||
} else {
|
||||
const uint8 val = *(fixup++);
|
||||
printf("Module ordinal: %u\n", (uint) val);
|
||||
} // else
|
||||
|
||||
uint32 name_offset = 0;
|
||||
if (fixupflags & 0x10) { // 32-bit value
|
||||
name_offset = *((uint32 *) fixup); fixup += 4;
|
||||
} else { // 16-bit value
|
||||
name_offset = *((uint16 *) fixup); fixup += 2;
|
||||
} // else
|
||||
|
||||
const uint8 *import_name = (exe + lx->import_proc_table_offset) + name_offset;
|
||||
char name[128];
|
||||
const uint8 namelen = *(import_name++) & 0x7F;
|
||||
memcpy(name, import_name, namelen);
|
||||
name[namelen] = '\0';
|
||||
printf("Name offset: %u ('%s')\n", (uint) name_offset, name);
|
||||
|
||||
uint32 additive = 0;
|
||||
if (fixupflags & 0x4) { // Has additive.
|
||||
if (fixupflags & 0x20) { // 32-bit value
|
||||
additive = *((uint32 *) fixup);
|
||||
fixup += 4;
|
||||
} else { // 16-bit value
|
||||
additive = *((uint16 *) fixup);
|
||||
fixup += 2;
|
||||
} // else
|
||||
} // if
|
||||
printf("Additive: %u\n", (uint) additive);
|
||||
|
||||
break;
|
||||
} // case
|
||||
|
||||
case 0x3:
|
||||
printf("Internal entry table fixup record:\n");
|
||||
@@ -473,20 +507,6 @@ static void parseExe(const char *exefname, uint8 *exe, uint32 exelen)
|
||||
const uint16 ordinal = *((const uint16 *) name_table); name_table += 2;
|
||||
printf("%u: '%s' (ordinal %u)\n", (uint) i, name, (uint) ordinal);
|
||||
} // for
|
||||
|
||||
#if 0
|
||||
const uint8 *fixup_record_table = exe + fixup_record_table_offset;
|
||||
const uint8 *import_proc_table = exe + lx->import_proc_table_offset;
|
||||
for (uint32 i = 0; i < 1000; i++) {
|
||||
char name[128];
|
||||
const uint8 namelen = *(import_proc_table++) & 0x7F;
|
||||
// !!! FIXME: name can't be more than 127 chars, according to docs. Check this.
|
||||
memcpy(name, import_proc_table, namelen);
|
||||
import_proc_table += namelen;
|
||||
name[namelen] = '\0';
|
||||
printf("PROC: %s\n", name);
|
||||
}
|
||||
#endif
|
||||
} // parseExe
|
||||
|
||||
int main(int argc, char **argv)
|
||||
|
||||
+28
-6
@@ -525,14 +525,13 @@ static void *getModuleProcAddrByOrdinal(const LxModule *module, const uint32 ord
|
||||
|
||||
#if 1
|
||||
char entry[128];
|
||||
snprintf(entry, sizeof (entry), "ORDINAL_%u", (uint) ordinal);
|
||||
snprintf(entry, sizeof (entry), "ordinal #%u", (uint) ordinal);
|
||||
return generateMissingTrampoline(module->name, entry);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
} // getModuleProcAddrByOrdinal
|
||||
|
||||
#if 0
|
||||
static void *getModuleProcAddrByName(const LxModule *module, const char *name)
|
||||
{
|
||||
//printf("lookup module == '%s', name == '%s'\n", module->name, name);
|
||||
@@ -549,7 +548,6 @@ static void *getModuleProcAddrByName(const LxModule *module, const char *name)
|
||||
return NULL;
|
||||
#endif
|
||||
} // getModuleProcAddrByName
|
||||
#endif
|
||||
|
||||
static void doFixup(uint8 *page, const sint16 offset, const uint32 finalval, const uint16 finalval2, const uint32 finalsize)
|
||||
{
|
||||
@@ -677,8 +675,32 @@ static void fixupPage(const uint8 *exe, LxModule *lxmod, const LxObjectTableEntr
|
||||
} // case
|
||||
|
||||
case 0x2: { // Import by name fixup record
|
||||
fprintf(stderr, "FIXUP 0x2 WRITE ME\n");
|
||||
exit(1);
|
||||
uint16 moduleid = 0; // module ordinal
|
||||
if (fixupflags & 0x40) { // 16 bit value
|
||||
moduleid = *((uint16 *) fixup); fixup += 2;
|
||||
} else {
|
||||
moduleid = (uint16) *(fixup++);
|
||||
} // else
|
||||
|
||||
uint32 name_offset = 0;
|
||||
if (fixupflags & 0x10) { // 32-bit value
|
||||
name_offset = *((uint32 *) fixup); fixup += 4;
|
||||
} else { // 16-bit value
|
||||
name_offset = *((uint16 *) fixup); fixup += 2;
|
||||
} // else
|
||||
|
||||
if (moduleid == 0) {
|
||||
fprintf(stderr, "uhoh, looking for module ordinal 0, which is illegal.\n");
|
||||
} 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 {
|
||||
const uint8 *import_name = (exe + lx->import_proc_table_offset) + name_offset;
|
||||
char name[128];
|
||||
const uint8 namelen = *(import_name++) & 0x7F; // the top bit is reserved.
|
||||
memcpy(name, import_name, namelen);
|
||||
name[namelen] = '\0';
|
||||
finalval = (uint32) (size_t) getModuleProcAddrByName(lxmod->dependencies[moduleid-1], name);
|
||||
} // else
|
||||
break;
|
||||
} // case
|
||||
|
||||
@@ -1038,7 +1060,7 @@ static LxModule *loadLxModule(const char *fname, uint8 *exe, uint32 exelen, int
|
||||
} // for
|
||||
|
||||
// !!! FIXME: hack to nop out some 16-bit code in emx.dll startup...
|
||||
if ((i == 1) && (strcmp(modname, "EMX") == 0)) {
|
||||
if (strcmp(modname, "EMX") == 0) {
|
||||
// This is the 16-bit signal handler installer. nop it out.
|
||||
uint8 *ptr = ((uint8 *) retval->mmaps[1].addr) + 28596;
|
||||
for (uint32 i = 0; i < 37; i++)
|
||||
|
||||
Reference in new issue
Block a user