Bunch more work on 16-bit entry points.

Can run testargv16.exe now. This means Watcom C startup code, and Watcom's
printf(), both work.
This commit is contained in:
Ryan C. Gordon committed 2018-06-07 23:48:39 -04:00
1 parent 36dedda17c
commit 37c3cc5a0a
9 files changed
+356 -58

No files matched your search

+10
View File
@@ -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.
@@ -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;
+2
View File
@@ -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);
+45 -33
View File
@@ -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);
@@ -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;
@@ -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;
@@ -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));
@@ -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;
@@ -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);
@@ -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;
+68 -1
View File
@@ -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);
@@ -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);
@@ -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)
@@ -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)
@@ -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),
+173 -17
View File
@@ -127,6 +127,39 @@ static void timespecNowPlusMilliseconds(struct timespec *waittime, const ULONG u
} // if
} // timespecNowPlusMilliseconds
static void initHFileInfoFromUnixFd(const int fd, HFileInfo *info)
{
struct stat statbuf;
if ((fd != -1) && (fstat(fd, &statbuf) == 0)) {
ULONG type = 0;
switch (statbuf.st_mode & S_IFMT) {
case S_IFREG:
type = 0;
break;
case S_IFBLK:
case S_IFCHR:
type = 1;
break;
case S_IFIFO:
case S_IFSOCK:
default:
type = 2;
break;
} // switch
info->fd = fd;
info->type = type;
FIXME("What should this be?");
info->attr = DAW_STDIN | DAW_STDOUT | DAW_LEVEL1 | DAW_CHARACTER;
info->flags = 0;
} else {
info->fd = -1;
info->type = 0;
info->attr = 0;
info->flags = 0;
} // else
} // initHFileInfoFromUnixFd
APIRET DosGetInfoBlocks(PTIB *pptib, PPIB *pppib)
{
TRACE_NATIVE("DosGetInfoBlocks(%p, %p)", pptib, pppib);
@@ -259,11 +292,8 @@ static int getHFileUnixDescriptor(HFILE h)
return fd;
} // getHFileUnixDescriptor
APIRET DosWrite(HFILE h, PVOID buf, ULONG buflen, PULONG actual)
static APIRET DosWrite_implementation(HFILE h, PVOID buf, ULONG buflen, PULONG actual)
{
TRACE_NATIVE("DosWrite(%u, %p, %u, %p)", (uint) h, buf, (uint) buflen, actual);
const int fd = getHFileUnixDescriptor(h);
if (fd == -1)
return ERROR_INVALID_HANDLE;
@@ -277,6 +307,12 @@ APIRET DosWrite(HFILE h, PVOID buf, ULONG buflen, PULONG actual)
*actual = (uint32) rc;
return NO_ERROR;
} // DosWrite_implementation
APIRET DosWrite(HFILE h, PVOID buf, ULONG buflen, PULONG actual)
{
TRACE_NATIVE("DosWrite(%u, %p, %u, %p)", (uint) h, buf, (uint) buflen, actual);
return DosWrite_implementation(h, buf, buflen, actual);
} // DosWrite
static void runDosExitList(const uint32 why)
@@ -555,6 +591,7 @@ APIRET DosSetRelMaxFH(PLONG pincr, PULONG pcurrent)
HFileInfo *info = (HFileInfo *) realloc(HFiles, sizeof (HFileInfo) * (MaxHFiles + incr));
if (info != NULL) {
HFiles = info;
FIXME("this needs to initialize the end of the array, not the front");
for (LONG i = 0; i < incr; i++, info++) {
info->fd = -1;
info->type = 0;
@@ -605,10 +642,8 @@ APIRET DosSubAllocMem(PVOID pbBase, PPVOID ppb, ULONG cb)
return NO_ERROR;
} // DosSubAllocMem
APIRET DosQueryHType(HFILE hFile, PULONG pType, PULONG pAttr)
static APIRET DosQueryHType_implementation(HFILE hFile, PULONG pType, PULONG pAttr)
{
TRACE_NATIVE("DosQueryHType(%u, %p, %p)", (uint) hFile, pType, pAttr);
APIRET retval = NO_ERROR;
grabLock(&GMutexDosCalls);
@@ -622,6 +657,12 @@ APIRET DosQueryHType(HFILE hFile, PULONG pType, PULONG pAttr)
ungrabLock(&GMutexDosCalls);
return retval;
} // DosQueryHType_implementation
APIRET DosQueryHType(HFILE hFile, PULONG pType, PULONG pAttr)
{
TRACE_NATIVE("DosQueryHType(%u, %p, %p)", (uint) hFile, pType, pAttr);
return DosQueryHType_implementation(hFile, pType, pAttr);
} // DosQueryHType
APIRET DosSetMem(PVOID pb, ULONG cb, ULONG flag)
@@ -809,7 +850,7 @@ static APIRET doDosOpen(PSZ pszFileName, PHFILE pHf, PULONG pulAction, LONGLONG
FIXME("Replacing a file should delete all its EAs, too");
} // if
info->fd = fd;
initHFileInfoFromUnixFd(fd, info);
if (fd == -1) {
switch (errno) {
@@ -1998,7 +2039,7 @@ APIRET DosQueryCp(ULONG cb, PULONG arCP, PULONG pcCP)
FIXME("This is mostly a stub");
if (cb < sizeof (ULONG) * 2)
if (cb < sizeof (*arCP) * 2)
return ERROR_CPLIST_TOO_SMALL;
// 437 == United States codepage.
@@ -2006,7 +2047,7 @@ APIRET DosQueryCp(ULONG cb, PULONG arCP, PULONG pcCP)
arCP[1] = 437; // prepared system codepage
if (pcCP)
*pcCP = sizeof (ULONG) * 2;
*pcCP = sizeof (*arCP) * 2;
return NO_ERROR;
} // DosQueryCp
@@ -2890,13 +2931,21 @@ APIRET16 Dos16GetHugeShift(PUSHORT pcount)
return NO_ERROR;
} // Dos16GetHugeShift
APIRET16 Dos16GetPID(PPIDINFO ppidinfo)
APIRET16 Dos16GetPID(PPIDINFO16 ppidinfo)
{
TRACE_NATIVE("Dos16GetPID(%p)", ppidinfo);
PTIB2 tib2 = (PTIB2) LX_GETTIB2();
ppidinfo->pid = GLoaderState.pib.pib_ulpid;
ppidinfo->tid = tib2->tib2_ultid;
ppidinfo->pidParent = GLoaderState.pib.pib_ulppid;
// note that these happen to fit Linux default PID ranges in 2018, which
// tend to be 32768, but can be much higher by writing to
// /proc/sys/kernel/pid_max
assert(GLoaderState.pib.pib_ulpid <= 0xFFFF);
assert(GLoaderState.pib.pib_ulppid <= 0xFFFF);
assert(tib2->tib2_ultid <= 0xFFFF);
ppidinfo->pid = (USHORT) GLoaderState.pib.pib_ulpid;
ppidinfo->tid = (USHORT) tib2->tib2_ultid;
ppidinfo->pidParent = (USHORT) GLoaderState.pib.pib_ulppid;
return NO_ERROR;
} // Dos16GetPID
@@ -2906,6 +2955,114 @@ VOID Dos16Exit(USHORT action, USHORT exitcode)
DosExit_implementation(action, exitcode);
} // Dos16Exit
APIRET16 Dos16QHandType(USHORT handle, PUSHORT ptype, PUSHORT pflags)
{
TRACE_NATIVE("Dos16QHandType(%u, %p, %p)", (uint) handle, ptype, pflags);
ULONG ultype, ulattr;
const APIRET rc = DosQueryHType_implementation((HFILE) handle, &ultype, &ulattr);
if (rc == NO_ERROR) {
if (ptype) *ptype = (USHORT) ultype;
if (pflags) *pflags = (USHORT) ulattr;
} // if
return (APIRET16) rc;
} // Dos16QHandType
APIRET16 Dos16AllocSeg(USHORT size, PUSHORT psel, USHORT flags)
{
TRACE_NATIVE("Dos16AllocSeg(%u, %p, %u)", (uint) size, psel, (uint) flags);
if (psel == NULL) {
return ERROR_INVALID_PARAMETER;
} else if ((flags & 0xFFF0) != 0) { // these bits are reserved and must be zero.
return ERROR_INVALID_PARAMETER;
}
// we don't care about the size, we just allocate a whole 64k segment. Oh well.
uint16 sel = 0xFFFF;
//void *addr = GLoaderState.allocSegment(&sel, 1); // we mark these as code in case they want to do self-modifying magic, etc.
void *addr = GLoaderState.allocSegment(&sel, 0);
if (!addr) {
assert(sel == 0xFFFF);
return ERROR_NOT_ENOUGH_MEMORY;
}
assert(sel != 0xFFFF);
if (flags & (1 << 0)) {
FIXME("segment is meant to be shareable through Dos16GiveSeg");
}
if (flags & (1 << 1)) {
FIXME("segment is meant to be shareable through Dos16GetSeg");
}
// documentation says this is a selector (specifically: a segment only on
// DOS in the family mode API), but it looks like OS/2 wants a segment too.
//*psel = (USHORT) sel;
*psel = (USHORT) ((sel << 3) | 7);
return NO_ERROR;
} // Dos16AllocSeg
APIRET16 Dos16ReallocSeg(USHORT size, USHORT sel)
{
TRACE_NATIVE("Dos16ReallocSeg(%u, %u)", (uint) size, (uint) sel);
// we don't ever discard segments, and we always allocate the full 64k,
// so we don't have to worry about resizing an existing segment.
// But there are sharing concerns, etc.
FIXME("this implementation is severely lacking");
// (we should probably make sure the selector is valid...)
return NO_ERROR;
} // Dos16ReallocSeg
APIRET16 Dos16FreeSeg(USHORT sel)
{
TRACE_NATIVE("Dos16FreeSeg(%u)", (uint) sel);
FIXME("this needs to deal with reference counting and shared segments");
// documentation says this is a selector (specifically: a segment only on
// DOS in the family mode API), but it looks like OS/2 wants a segment too.
GLoaderState.freeSegment(sel >> 3);
return NO_ERROR;
} // Dos16FreeSeg
APIRET16 Dos16GetCp(USHORT cb, PUSHORT arCP, PUSHORT pcCP)
{
TRACE_NATIVE("Dos16GetCp(%u, %p, %p)", (uint) cb, arCP, pcCP);
FIXME("This is mostly a stub");
FIXME("...and mostly copy/paste from DosQueryCp()...");
if (cb < sizeof (*arCP) * 2)
return ERROR_CPLIST_TOO_SMALL;
// 437 == United States codepage.
arCP[0] = 437; // current process codepage
arCP[1] = 437; // prepared system codepage
if (pcCP)
*pcCP = sizeof (*arCP) * 2;
return NO_ERROR;
} // Dos16GetCp
APIRET16 Dos16GetEnv(PUSHORT psel, PUSHORT pcmdoffset)
{
TRACE_NATIVE("Dos16GetEnv(%p, %p)", psel, pcmdoffset);
const uint32 cmd1616 = GLoaderState.convert32to1616(GLoaderState.pib.pib_pchcmd);
if (pcmdoffset) *pcmdoffset = (USHORT) (cmd1616 & 0xFFFF);
if (psel) *psel = (USHORT) ((cmd1616 >> 16) & 0xFFFF);
return NO_ERROR;
} // Dos16GetEnv
APIRET16 Dos16Write(USHORT h, PVOID buf, USHORT buflen, PUSHORT actual)
{
TRACE_NATIVE("DosWrite(%u, %p, %u, %p)", (uint) h, buf, (uint) buflen, actual);
ULONG ulactual = actual ? *actual : 0;
APIRET rc = DosWrite_implementation(h, buf, buflen, &ulactual);
if (actual) *actual = (USHORT) ulactual;
return (APIRET16) rc;
} // Dos16Write
LX_NATIVE_CONSTRUCTOR(doscalls)
{
@@ -2942,10 +3099,9 @@ LX_NATIVE_CONSTRUCTOR(doscalls)
// inherited from CMD.EXE or supplied by OS/2 for whatever purpose.
// For now, we just wire up stdio.
FIXME("We can iterate /proc/self/fd to get all currently-open files");
for (int i = 0; i <= 2; i++) {
HFiles[i].fd = i;
HFiles[i].type = 1; // !!! FIXME: could be a pipe or file.
HFiles[i].attr = DAW_STDIN | DAW_STDOUT | DAW_LEVEL1 | DAW_CHARACTER;
initHFileInfoFromUnixFd(i, &HFiles[i]);
} // for
}
+14 -5
View File
@@ -435,13 +435,22 @@ OS2EXPORT APIRET16 OS2API16 Dos16GetVersion(PUSHORT pver) OS2APIINFO(92);
OS2EXPORT APIRET16 OS2API16 Dos16GetMachineMode(PBYTE pmode) OS2APIINFO(49);
OS2EXPORT APIRET16 OS2API16 Dos16GetHugeShift(PUSHORT pcount) OS2APIINFO(41);
OS2EXPORT VOID OS2API16 Dos16Exit(USHORT action, USHORT result) OS2APIINFO(5);
OS2EXPORT APIRET16 OS2API16 Dos16QHandType(USHORT handle, PUSHORT ptype, PUSHORT pflags) OS2APIINFO(77);
OS2EXPORT APIRET16 OS2API16 Dos16AllocSeg(USHORT size, PUSHORT psel, USHORT flags) OS2APIINFO(34);
OS2EXPORT APIRET16 OS2API16 Dos16ReallocSeg(USHORT size, USHORT sel) OS2APIINFO(38);
OS2EXPORT APIRET16 OS2API16 Dos16FreeSeg(USHORT sel) OS2APIINFO(39);
typedef struct {
PID pid;
TID tid;
PID pidParent;
} PIDINFO, *PPIDINFO;
OS2EXPORT APIRET16 OS2API16 Dos16GetPID(PPIDINFO ppidinfo) OS2APIINFO(94);
USHORT pid;
USHORT tid;
USHORT pidParent;
} PIDINFO16, *PPIDINFO16;
OS2EXPORT APIRET16 OS2API16 Dos16GetPID(PPIDINFO16 ppidinfo) OS2APIINFO(94);
OS2EXPORT APIRET16 OS2API16 Dos16GetCp(USHORT cb, PUSHORT arCP, PUSHORT pcCP) OS2APIINFO(130);
OS2EXPORT APIRET16 OS2API16 Dos16GetEnv(PUSHORT psel, PUSHORT pcmdoffset) OS2APIINFO(91);
OS2EXPORT APIRET16 OS2API16 Dos16Write(USHORT h, PVOID buf, USHORT buflen, PUSHORT actual) OS2APIINFO(138);
// !!! FIXME: these should probably get sorted alphabetically and/or grouped
+24 -1
View File
@@ -9,7 +9,30 @@
/* This is glue code for OS/2 binaries. Native binaries don't need this. */
#if LX_LEGACY
LX_NATIVE_MODULE_INIT()
static APIRET16 bridge16to32_Dos16GetDBCSEv(uint8 *args) {
LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PCHAR, buf);
LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PCOUNTRYCODE16, pcc);
LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, buflen);
return Dos16GetDBCSEv(buflen, pcc, buf);
}
LX_NATIVE_MODULE_16BIT_SUPPORT()
LX_NATIVE_MODULE_16BIT_API(Dos16GetDBCSEv)
LX_NATIVE_MODULE_16BIT_SUPPORT_END()
LX_NATIVE_MODULE_DEINIT({
LX_NATIVE_MODULE_DEINIT_16BIT_SUPPORT();
})
static int init16_nls(void) {
LX_NATIVE_MODULE_INIT_16BIT_SUPPORT()
LX_NATIVE_INIT_16BIT_BRIDGE(Dos16GetDBCSEv, 10)
LX_NATIVE_MODULE_INIT_16BIT_SUPPORT_END()
return 1;
}
LX_NATIVE_MODULE_INIT({ if (!init16_nls()) return 0; })
LX_NATIVE_EXPORT16(Dos16GetDBCSEv, 4),
LX_NATIVE_EXPORT(DosQueryCtryInfo, 5),
LX_NATIVE_EXPORT(DosQueryDBCSEnv, 6),
LX_NATIVE_EXPORT(DosMapCase, 7)
+11 -1
View File
@@ -6,11 +6,21 @@
* This file written by Ryan C. Gordon.
*/
#include "os2native.h"
#include "os2native16.h"
#include "nls.h"
#include "nls-lx.h"
APIRET16 Dos16GetDBCSEv(USHORT buflen, PCOUNTRYCODE16 pcc, PCHAR buf)
{
// !!! FIXME: implement this for real.
TRACE_NATIVE("Dos16GetDBCSEv(%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;
} // Dos16GetDBCSEv
APIRET DosQueryDBCSEnv(ULONG buflen, PCOUNTRYCODE pcc, PCHAR buf)
{
// !!! FIXME: implement this for real.
+9
View File
@@ -43,6 +43,15 @@ OS2EXPORT APIRET OS2API DosQueryDBCSEnv(ULONG cb, PCOUNTRYCODE pcc, PCHAR pBuf)
OS2EXPORT APIRET OS2API DosMapCase(ULONG cb, PCOUNTRYCODE pcc, PCHAR pch) OS2APIINFO(7);
OS2EXPORT APIRET OS2API DosQueryCtryInfo(ULONG cb, PCOUNTRYCODE pcc, PCOUNTRYINFO pci, PULONG pcbActual) OS2APIINFO(5);
typedef struct
{
USHORT country;
USHORT codepage;
} COUNTRYCODE16, *PCOUNTRYCODE16;
OS2EXPORT APIRET16 OS2API16 Dos16GetDBCSEv(USHORT buflen, PCOUNTRYCODE16 pcc, PCHAR buf) OS2APIINFO(4);
#ifdef __cplusplus
}
#endif