Skip to content
Permalink
Browse files
lx_loader: Load 16-bit NE binaries!
This currently only works with a simple Hello World program, but this is the
bulk of the work to 16-bit program support.

Still need some minor effort to get 16-bit DLLs working, and of course we
need to implement a ton of missing 16-bit API calls.
  • Loading branch information
icculus committed Jun 6, 2018
1 parent bdc2857 commit 0148811a0c5d68378e5e3d73985c722c80c65c01
Showing with 747 additions and 118 deletions.
  1. +7 −3 lib2ine.c
  2. +12 −1 lib2ine.h
  3. +5 −5 lx_dump.c
  4. +723 −109 lx_loader.c
@@ -164,8 +164,12 @@ static void initPib(void)

len += 4; // null terminators.

char *env = (char *) malloc(len);
if (!env) {
// align this to 64k, because it has to be at the start of a segment
// for 16-bit code.
// !!! FIXME: ...which is to say: you can't have more than 64k
// !!! FIXME: worth of environment and command line.
char *env = NULL;
if (posix_memalign((void **) &env, 0x10000, len) != 0) {
fprintf(stderr, "Out of memory\n");
abort();
} // if
@@ -237,7 +241,7 @@ static void initPib(void)
pib->pib_ulppid = (uint32) getppid();
pib->pib_pchcmd = cmd;
pib->pib_pchenv = env;
//pib->pib_hmte is filled in later during loadLxModule()
//pib->pib_hmte is filled in later during loadModule()
// !!! FIXME: uint32 pib_flstatus;
// !!! FIXME: uint32 pib_ultype;

@@ -202,17 +202,28 @@ struct LxModule;
typedef struct LxModule LxModule;
struct LxModule
{
LxHeader lx;
uint32 refcount;
int is_lx; // 1 if an LX module, 0 if NE.
union
{
LxHeader lx;
NeHeader ne;
} header;

char name[256]; // !!! FIXME: allocate this.

LxModule **dependencies;
uint32 num_dependencies;

LxMmaps *mmaps;
uint32 num_mmaps;

const LxExport *exports;
uint32 num_exports;
void *nativelib;
uint32 eip;
uint32 esp;
uint16 autodatasize; // only used for NE binaries.
int initialized;
char *os2path; // absolute path to module, in OS/2 format
// !!! FIXME: put this elsewhere?
@@ -572,12 +572,12 @@ static int parseNeExe(const uint8 *origexe, const uint8 *exe)
printf("Imported names table offset: %u\n", (uint) ne->imported_names_table_offset);
printf("Non-resident name table offset: %u\n", (uint) ne->non_resident_name_table_offset);
printf("Number of movable entries: %u\n", (uint) ne->num_movable_entries);
printf("Sector alignment shift count: %u (%u bytes)\n", (uint) ne->sector_alignment_shift_count, (uint) (1 << ne->sector_alignment_shift_count));
printf("Sector alignment shift count: %u\n", (uint) ne->sector_alignment_shift_count);
printf("Number of resource entries: %u\n", (uint) ne->num_resource_entries);
printf("Executable type: %u\n", (uint) ne->exe_type);
printf("\n");

const uint32 sector_size = 1 << ne->sector_alignment_shift_count;
const uint32 sector_shift = ne->sector_alignment_shift_count;

if (ne->num_segment_table_entries > 0) {
const uint32 total = (uint32) ne->num_segment_table_entries;
@@ -589,7 +589,7 @@ static int parseNeExe(const uint8 *origexe, const uint8 *exe)
if (seg->offset == 0) {
printf(" (no file data)\n");
} else {
printf(" (byte position %u)\n", (uint) (seg->offset * sector_size));
printf(" (byte position %u)\n", (uint) (((uint32) seg->offset) << sector_shift));
}
printf(" Size: %u\n", (seg->size == 0) ? (uint) 0x10000 : (uint) seg->size);
printf(" Segment flags:");
@@ -606,7 +606,7 @@ static int parseNeExe(const uint8 *origexe, const uint8 *exe)
printf(" Minimum allocation: %u\n", (seg->minimum_allocation == 0) ? (uint) 0x10000 : (uint) seg->minimum_allocation);

if (seg->segment_flags & 0x100) { // has relocations (fixups)
const uint8 *segptr = origexe + (seg->offset * sector_size);
const uint8 *segptr = origexe + (((uint32) seg->offset) << sector_shift);
const uint8 *fixupptr = segptr + (seg->size ? seg->size : 0xFFFF);
const uint32 num_fixups = (uint32) *((const uint16 *) fixupptr); fixupptr += 2;
printf(" Fixup records (%u entries):\n", (uint) num_fixups);
@@ -668,7 +668,7 @@ static int parseNeExe(const uint8 *origexe, const uint8 *exe)
} else {
printf(" Source chain:");
do {
printf(" %u", (uint) srcchain_offset);
printf(" %X", (uint) srcchain_offset);
srcchain_offset = *((const uint16 *) (segptr + srcchain_offset));
} while (srcchain_offset < seg->size);
}

0 comments on commit 0148811

Please sign in to comment.