Skip to content

Commit

Permalink
Bunch more work on 16-bit entry points.
Browse files Browse the repository at this point in the history
Can run testargv16.exe now. This means Watcom C startup code, and Watcom's
printf(), both work.
  • Loading branch information
icculus committed Jun 8, 2018
1 parent 36dedda commit 37c3cc5
Show file tree
Hide file tree
Showing 9 changed files with 356 additions and 58 deletions.
10 changes: 10 additions & 0 deletions lib2ine.c
Expand Up @@ -329,6 +329,14 @@ static char *makeUnixPath_lib2ine(const char *os2path, uint32 *err)
return retval;
}

static void *allocSegment_lib2ine(uint16 *selector, const int iscode)
{
if (selector) *selector = 0xFFFF;
return NULL;
}

static void freeSegment_lib2ine(const uint16 selector) {}

static void __attribute__((noreturn)) terminate_lib2ine(const uint32 exitcode)
{
exit((int) exitcode); // let static constructors and atexit() run.
Expand All @@ -348,6 +356,8 @@ LX_NATIVE_CONSTRUCTOR(lib2ine)
GLoaderState.setOs2Tib = setOs2Tib_lib2ine;
GLoaderState.getOs2Tib = getOs2Tib_lib2ine;
GLoaderState.deinitOs2Tib = deinitOs2Tib_lib2ine;
GLoaderState.allocSegment = allocSegment_lib2ine;
GLoaderState.freeSegment = freeSegment_lib2ine;
GLoaderState.findSelector = findSelector_lib2ine;
GLoaderState.freeSelector = freeSelector_lib2ine;
GLoaderState.convert1616to32 = convert1616to32_lib2ine;
Expand Down
2 changes: 2 additions & 0 deletions lib2ine.h
Expand Up @@ -304,6 +304,8 @@ typedef struct LxLoaderState
uint16 (*setOs2Tib)(uint8 *tibspace);
LxTIB *(*getOs2Tib)(void);
void (*deinitOs2Tib)(const uint16 selector);
void *(*allocSegment)(uint16 *selector, const int iscode);
void (*freeSegment)(const uint16 selector);
int (*findSelector)(const uint32 addr, uint16 *outselector, uint16 *outoffset, int iscode);
void (*freeSelector)(const uint16 selector);
void *(*convert1616to32)(const uint32 addr1616);
Expand Down
78 changes: 45 additions & 33 deletions lx_loader.c
Expand Up @@ -672,6 +672,41 @@ static __attribute__((noreturn)) void endLxProcess(const uint32 exitcode)
lxTerminate(exitcode); // just in case.
} // endLxProcess

static void *lxAllocSegment(uint16 *selector, const int iscode)
{
// These are meant to be 64k segments mapped for use by 16-bit code, which means we
// need them under 512 megabytes so their segments can convert directly to a linear
// address with some bit twiddling.
static size_t baseaddr = 136 * 1024 * 1024; // just start at a random low address that (hopefully) doesn't overlap anything.
const uint32 segmentsize = 0x10000;
void *segment = mmap((void *) baseaddr, segmentsize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (segment == ((void *) MAP_FAILED)) {
FIXME("This could be more robust.");
fprintf(stderr, "Failed to mmap a 16-bit friendly memory segment.\n");
return NULL;
}

baseaddr += segmentsize;
uint16 offset = 0xFFFF;
*selector = 0xFFFF;
lxFindSelector((uint32) segment, selector, &offset, iscode);
assert(*selector != 0xFFFF);
assert(offset == 0);
//printf("lxAllocSegment: addr=%p, selector=%x\n", segment, (uint) *selector);
return segment;
} // lxAllocSegment

static void lxFreeSegment(const uint16 selector)
{
const uint32 addr32 = GLoaderState.ldt[selector];
if (addr32) {
void *addr = (void *) ((size_t) addr32);
//printf("lxFreeSegment: addr=%p, selector=%x\n", addr, (uint) selector);
munmap(addr, 0x10000);
lxFreeSelector(selector);
} // if
} // lxFreeSegment

static void missingEntryPointCalled(const char *module, const char *entry)
{
fflush(stdout);
Expand Down Expand Up @@ -732,31 +767,6 @@ static void *generateMissingTrampoline(const char *_module, const char *_entry)
return trampoline;
} // generateMissingTrampoline


static void *mmapSegment(uint16 *selector, const int iscode)
{
// These are meant to be 64k segments mapped for use by 16-bit code, which means we
// need them under 512 megabytes so their segments can convert directly to a linear
// address with some bit twiddling.
static size_t baseaddr = 136 * 1024 * 1024; // just start at a random low address that (hopefully) doesn't overlap anything.
const uint32 segmentsize = 0x10000;
void *segment = mmap((void *) baseaddr, segmentsize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (segment == ((void *) MAP_FAILED)) {
FIXME("This could be more robust.");
fprintf(stderr, "Failed to mmap a 16-bit friendly memory segment.\n");
return NULL;
}

baseaddr += segmentsize;
uint16 offset = 0xFFFF;
*selector = 0xFFFF;
lxFindSelector((uint32) segment, selector, &offset, iscode);
assert(*selector != 0xFFFF);
assert(offset == 0);
return segment;
} // mmapSegment


static void *generateMissingTrampoline16(const char *_module, const char *_entry, const LxExport **_lxexp)
{
static void *segment = NULL;
Expand All @@ -768,7 +778,7 @@ static void *generateMissingTrampoline16(const char *_module, const char *_entry
{
if (segment)
mprotect(segment, segmentsize, PROT_READ | PROT_EXEC);
segment = mmapSegment(&selector, 1);
segment = lxAllocSegment(&selector, 1);
assert(segment != NULL);
assert(selector != 0xFFFF);
segmentused = 0;
Expand Down Expand Up @@ -918,9 +928,9 @@ static __attribute__((noreturn)) void runNeModule(LxModule *lxmod)
// so we do both.
const uint16 stacksize = (uint16) GLoaderState.mainstacksize;
const uint16 ss = (lxmod->esp >> 16) & 0xFFFF; // stack segment
const uint32 env1616 = lxConvert32to1616(GLoaderState.pib.pib_pchenv); // this is meant to be aligned to a segment.
const uint16 cmdlineoffset = env1616 & 0xFFFF;
const uint16 envseg = (env1616 >> 16) & 0xFFFF;
const uint32 cmd1616 = lxConvert32to1616(GLoaderState.pib.pib_pchcmd);
const uint16 cmdlineoffset = cmd1616 & 0xFFFF;
const uint16 envseg = (cmd1616 >> 16) & 0xFFFF;

uint8 *stack = (uint8 *) lxConvert1616to32(lxmod->esp);
//printf("stack is at 32=%p 16=%x:%x\n", stack, (uint) ss, (uint) (lxmod->esp & 0xFFFF));
Expand All @@ -932,7 +942,7 @@ static __attribute__((noreturn)) void runNeModule(LxModule *lxmod)
stack -= 2; *((uint16 *) stack) = ss; // bottom of stack

uint16 selector = 0xFFFF;
void *segment = mmapSegment(&selector, 1);
void *segment = lxAllocSegment(&selector, 1);
assert(segment != NULL);
assert(selector != 0xFFFF);
char *ptr = (char *) segment;
Expand Down Expand Up @@ -2180,11 +2190,11 @@ static LxModule *loadNeModule(const char *fname, const uint8 *origexe, uint8 *ex
//const int movable = (seg->segment_flags & 0x10) != 0;
const int iscode = ((seg->segment_flags & 0x7) == 0) ? 1 : 0;
uint16 selector = 0xFFFF;
void *mmapaddr = mmapSegment(&selector, iscode);
//printf("%s neobj #%u mmapSegment(%d) == %p (selector=0x%X)\n", retval->name, (uint) i, iscode, mmapaddr, (uint) selector);
void *mmapaddr = lxAllocSegment(&selector, iscode);
//printf("%s neobj #%u lxAllocSegment(%d) == %p (selector=0x%X)\n", retval->name, (uint) i, iscode, mmapaddr, (uint) selector);

if (mmapaddr == NULL) {
fprintf(stderr, "mmapSegment(%d) failed\n", iscode);
fprintf(stderr, "lxAllocSegment(%d) failed\n", iscode);
goto loadne_failed;
} else if (selector == 0xFFFF) {
munmap(mmapaddr, vsize);
Expand Down Expand Up @@ -2709,6 +2719,8 @@ int main(int argc, char **argv, char **envp)
GLoaderState.setOs2Tib = lxSetOs2Tib;
GLoaderState.getOs2Tib = lxGetOs2Tib;
GLoaderState.deinitOs2Tib = lxDeinitOs2Tib;
GLoaderState.allocSegment = lxAllocSegment;
GLoaderState.freeSegment = lxFreeSegment;
GLoaderState.findSelector = lxFindSelector;
GLoaderState.freeSelector = lxFreeSelector;
GLoaderState.convert1616to32 = lxConvert1616to32;
Expand Down
69 changes: 68 additions & 1 deletion native/doscalls-lx.h
Expand Up @@ -15,6 +15,24 @@ static VOID bridge16to32_Dos16Exit(uint8 *args) {
Dos16Exit(action, result);
}

static APIRET16 bridge16to32_Dos16AllocSeg(uint8 *args) {
LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, flags);
LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, psel);
LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, size);
return Dos16AllocSeg(size, psel, flags);
}

static APIRET16 bridge16to32_Dos16ReallocSeg(uint8 *args) {
LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, sel);
LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, size);
return Dos16ReallocSeg(size, sel);
}

static APIRET16 bridge16to32_Dos16FreeSeg(uint8 *args) {
LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, sel);
return Dos16FreeSeg(sel);
}

static APIRET16 bridge16to32_Dos16GetHugeShift(uint8 *args) {
LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, pcount);
return Dos16GetHugeShift(pcount);
Expand All @@ -25,16 +43,44 @@ static APIRET16 bridge16to32_Dos16GetMachineMode(uint8 *args) {
return Dos16GetMachineMode(pmode);
}

static APIRET16 bridge16to32_Dos16QHandType(uint8 *args) {
LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, pflags);
LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, ptype);
LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, handle);
return Dos16QHandType(handle, ptype, pflags);
}

static APIRET16 bridge16to32_Dos16GetEnv(uint8 *args) {
LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, pcmdoffset);
LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, psel);
return Dos16GetEnv(psel, pcmdoffset);
}

static APIRET16 bridge16to32_Dos16GetVersion(uint8 *args) {
LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, pver);
return Dos16GetVersion(pver);
}

static APIRET16 bridge16to32_Dos16GetPID(uint8 *args) {
LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PPIDINFO, ppidinfo);
LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PPIDINFO16, ppidinfo);
return Dos16GetPID(ppidinfo);
}

static APIRET16 bridge16to32_Dos16GetCp(uint8 *args) {
LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, pcCP);
LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, arCP);
LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, cb);
return Dos16GetCp(cb, arCP, pcCP);
}

static APIRET16 bridge16to32_Dos16Write(uint8 *args) {
LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, actual);
LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, buflen);
LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PVOID, buf);
LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, h);
return Dos16Write(h, buf, buflen, actual);
}

static APIRET16 bridge16to32_DosSemRequest(uint8 *args) {
LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(LONG, ms);
LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PHSEM16, sem);
Expand All @@ -59,10 +105,17 @@ static APIRET16 bridge16to32_DosSemSet(uint8 *args) {

LX_NATIVE_MODULE_16BIT_SUPPORT()
LX_NATIVE_MODULE_16BIT_API(Dos16Exit)
LX_NATIVE_MODULE_16BIT_API(Dos16AllocSeg)
LX_NATIVE_MODULE_16BIT_API(Dos16ReallocSeg)
LX_NATIVE_MODULE_16BIT_API(Dos16FreeSeg)
LX_NATIVE_MODULE_16BIT_API(Dos16GetHugeShift)
LX_NATIVE_MODULE_16BIT_API(Dos16GetMachineMode)
LX_NATIVE_MODULE_16BIT_API(Dos16QHandType)
LX_NATIVE_MODULE_16BIT_API(Dos16GetEnv)
LX_NATIVE_MODULE_16BIT_API(Dos16GetVersion)
LX_NATIVE_MODULE_16BIT_API(Dos16GetPID)
LX_NATIVE_MODULE_16BIT_API(Dos16GetCp)
LX_NATIVE_MODULE_16BIT_API(Dos16Write)
LX_NATIVE_MODULE_16BIT_API(DosSemRequest)
LX_NATIVE_MODULE_16BIT_API(DosSemClear)
LX_NATIVE_MODULE_16BIT_API(DosSemWait)
Expand All @@ -76,10 +129,17 @@ LX_NATIVE_MODULE_DEINIT({
static int init16_doscalls(void) {
LX_NATIVE_MODULE_INIT_16BIT_SUPPORT()
LX_NATIVE_INIT_16BIT_BRIDGE(Dos16Exit, 4)
LX_NATIVE_INIT_16BIT_BRIDGE(Dos16AllocSeg, 8)
LX_NATIVE_INIT_16BIT_BRIDGE(Dos16ReallocSeg, 4)
LX_NATIVE_INIT_16BIT_BRIDGE(Dos16FreeSeg, 2)
LX_NATIVE_INIT_16BIT_BRIDGE(Dos16GetHugeShift, 4)
LX_NATIVE_INIT_16BIT_BRIDGE(Dos16GetMachineMode, 4)
LX_NATIVE_INIT_16BIT_BRIDGE(Dos16QHandType, 10)
LX_NATIVE_INIT_16BIT_BRIDGE(Dos16GetEnv, 8)
LX_NATIVE_INIT_16BIT_BRIDGE(Dos16GetVersion, 4)
LX_NATIVE_INIT_16BIT_BRIDGE(Dos16GetPID, 4)
LX_NATIVE_INIT_16BIT_BRIDGE(Dos16GetCp, 10)
LX_NATIVE_INIT_16BIT_BRIDGE(Dos16Write, 12)
LX_NATIVE_INIT_16BIT_BRIDGE(DosSemRequest, 8)
LX_NATIVE_INIT_16BIT_BRIDGE(DosSemClear, 4)
LX_NATIVE_INIT_16BIT_BRIDGE(DosSemWait, 8)
Expand All @@ -90,10 +150,17 @@ static int init16_doscalls(void) {

LX_NATIVE_MODULE_INIT({ if (!init16_doscalls()) return 0; })
LX_NATIVE_EXPORT16(Dos16Exit, 5),
LX_NATIVE_EXPORT16(Dos16AllocSeg, 34),
LX_NATIVE_EXPORT16(Dos16ReallocSeg, 38),
LX_NATIVE_EXPORT16(Dos16FreeSeg, 39),
LX_NATIVE_EXPORT16(Dos16GetHugeShift, 41),
LX_NATIVE_EXPORT16(Dos16GetMachineMode, 49),
LX_NATIVE_EXPORT16(Dos16QHandType, 77),
LX_NATIVE_EXPORT16(Dos16GetEnv, 91),
LX_NATIVE_EXPORT16(Dos16GetVersion, 92),
LX_NATIVE_EXPORT16(Dos16GetPID, 94),
LX_NATIVE_EXPORT16(Dos16GetCp, 130),
LX_NATIVE_EXPORT16(Dos16Write, 138),
LX_NATIVE_EXPORT16(DosSemRequest, 140),
LX_NATIVE_EXPORT16(DosSemClear, 141),
LX_NATIVE_EXPORT16(DosSemWait, 142),
Expand Down

0 comments on commit 37c3cc5

Please sign in to comment.