Skip to content

Commit

Permalink
16-bit support!
Browse files Browse the repository at this point in the history
This gets us everything we need (I hope!) to support 16-bit code in LX
binaries and call into 16-bit OS/2 APIs. This is just enough to call
into VioGetMode() (which isn't otherwise implemented yet) as an example.

If this is ever used Winelib-style to provide an OS/2 API to native Linux
binaries, the 16-bit system APIs are 32-bit clean and C callable, as one
might expect them to be. All the tapdancing is to support existing LX
binaries in the loader and bridge between the 32-bit clean APIs and
existing 16-bit code that expects to call 16-bit APIs.

This was a staggering amount of effort, but yay!

Other fixes and improvements probably leaked into this commit, as a
lot of code got touched and a lot of research and debugging took place.
  • Loading branch information
icculus committed Oct 27, 2016
1 parent 29696db commit 26a5298
Show file tree
Hide file tree
Showing 10 changed files with 694 additions and 57 deletions.
25 changes: 25 additions & 0 deletions cvtasm.pl
@@ -0,0 +1,25 @@
#!/usr/bin/perl -w

# run this on the output from ndisasm.

use warnings;
use strict;

while (<>) {
chomp;
my ($bytes, $asm) = /\A.*?\s+(.*?)\s+(.*)\Z/;
my $first = 1;
while ($bytes ne '') {
$bytes =~ s/\A(..)//;
my $hex = $1;
if ($first and ($bytes eq '')) {
print(" *(ptr++) = 0x$hex; /* $asm */\n");
} elsif ($first) {
print(" *(ptr++) = 0x$hex; /* $asm... */\n");
} else {
print(" *(ptr++) = 0x$hex; /* ...$asm */\n");
}
$first = 0;
}
}

357 changes: 318 additions & 39 deletions lx_loader.c

Large diffs are not rendered by default.

13 changes: 13 additions & 0 deletions lx_loader.h
Expand Up @@ -129,15 +129,18 @@ typedef struct LxResourceTableEntry

typedef struct LxMmaps
{
void *mapped;
void *addr;
size_t size;
uint16 alias; // 16:16 alias, if one.
} LxMmaps;

typedef struct LxExport
{
uint32 ordinal;
const char *name; // can be NULL
void *addr;
const LxMmaps *object;
} LxExport;

struct LxModule;
Expand All @@ -149,6 +152,7 @@ struct LxModule
char name[256]; // !!! FIXME: allocate this.
LxModule **dependencies;
LxMmaps *mmaps;

const LxExport *exports;
uint32 num_exports;
void *nativelib;
Expand Down Expand Up @@ -202,14 +206,23 @@ typedef struct LxLoaderState
{
LxModule *loaded_modules;
LxModule *main_module;
uint8 main_tibspace[LXTIBSIZE];
LxPIB pib;
int subprocess;
int running;
int trace_native;
uint16 original_cs;
uint16 original_ss;
uint16 original_ds;
uint32 ldt[8192];
uint32 *tlspage;
uint32 tlsmask; // one bit for each TLS slot in use.
uint8 tlsallocs[32]; // number of TLS slots allocated in one block, indexed by starting block (zero if not the starting block).
uint16 (*initOs2Tib)(uint8 *tibspace, void *_topOfStack, const size_t stacklen, const uint32 tid);
void (*deinitOs2Tib)(const uint16 selector);
int (*findSelector)(const uint32 addr, uint16 *outselector, uint16 *outoffset);
void (*freeSelector)(const uint16 selector);
void *(*convert1616to32)(const uint32 addr1616);
LxModule *(*loadModule)(const char *modname);
int (*locatePathCaseInsensitive)(char *buf);
char *(*makeUnixPath)(const char *os2path, uint32 *err);
Expand Down
43 changes: 32 additions & 11 deletions native/doscalls.c
@@ -1,23 +1,18 @@
#define _POSIX_C_SOURCE 199309
#define _BSD_SOURCE
#define _GNU_SOURCE
#include "os2native.h"
#include "doscalls.h"

#include <unistd.h>
#include <limits.h>
#include <time.h>
#include <dirent.h>
#include <fcntl.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/sysinfo.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/mman.h>

#include "os2native.h"
#include "doscalls.h"

static LxLoaderState *GLoaderState = NULL;

Expand Down Expand Up @@ -100,6 +95,11 @@ typedef struct
static DirFinder GHDir1;


// !!! FIXME:
#undef TRACE_NATIVE
#define TRACE_NATIVE(...) do { if (GLoaderState->trace_native) { fprintf(stderr, "2INE TRACE [%lu]: ", (unsigned long) pthread_self()); fprintf(stderr, __VA_ARGS__); fprintf(stderr, ";\n"); } } while (0)


LX_NATIVE_MODULE_DEINIT({
ExitListItem *next = GExitList;
GExitList = NULL;
Expand Down Expand Up @@ -599,11 +599,32 @@ APIRET DosSetExceptionHandler(PEXCEPTIONREGISTRATIONRECORD rec)
return NO_ERROR;
} // DosSetExceptionHandler

ULONG DosFlatToSel(PVOID ptr)
ULONG _DosFlatToSel(PVOID ptr)
{
TRACE_NATIVE("DosFlatToSel(%p)", ptr);
return ((ULONG) ((size_t)ptr)) >> 16; // !!! FIXME
} // DosFlatToSel

uint16 selector = 0;
uint16 offset = 0;
if (!GLoaderState->findSelector((uint32) ptr, &selector, &offset)) {
fprintf(stderr, "Uhoh, ran out of LDT entries?!\n");
return 0; // oh well, crash.
} // if

selector = (selector << 3) | 7;
return (((uint32)selector) << 16) | ((uint32) offset);
} // _DosFlatToSel

// DosFlatToSel() passes its argument in %eax, so a little asm to bridge that...
__asm__ (
".globl DosFlatToSel \n\t"
".type DosFlatToSel, @function \n\t"
"DosFlatToSel: \n\t"
" pushl %eax \n\t"
" call _DosFlatToSel \n\t"
" addl $4, %esp \n\t"
" ret \n\t"
".size _DosFlatToSel, .-_DosFlatToSel \n\t"
);

APIRET DosSetSignalExceptionFocus(BOOL32 flag, PULONG pulTimes)
{
Expand Down
2 changes: 1 addition & 1 deletion native/doscalls.h
Expand Up @@ -386,7 +386,7 @@ APIRET OS2API DosExitList(ULONG ordercode, PFNEXITLIST pfn);
APIRET OS2API DosCreateEventSem(PSZ pszName, PHEV phev, ULONG flAttr, BOOL32 fState);
APIRET OS2API DosCreateMutexSem(PSZ pszName, PHMTX phmtx, ULONG flAttr, BOOL32 fState);
APIRET OS2API DosSetExceptionHandler(PEXCEPTIONREGISTRATIONRECORD pERegRec);
ULONG OS2API DosFlatToSel(PVOID ptr);
ULONG OS2API DosFlatToSel(VOID);
APIRET OS2API DosSetSignalExceptionFocus(BOOL32 flag, PULONG pulTimes);
APIRET OS2API DosSetRelMaxFH(PLONG pcbReqCount, PULONG pcbCurMaxFH);
APIRET OS2API DosAllocMem(PPVOID ppb, ULONG cb, ULONG flag);
Expand Down
13 changes: 9 additions & 4 deletions native/os2native.h
@@ -1,11 +1,16 @@
#ifndef _INCL_NATIVE_H_
#define _INCL_NATIVE_H_
#ifndef _INCL_OS2NATIVE_H_
#define _INCL_OS2NATIVE_H_

#define _POSIX_C_SOURCE 199309
#define _BSD_SOURCE
#define _GNU_SOURCE
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <pthread.h>
#include <errno.h>
#include <sys/mman.h>

#include "os2types.h"
#include "os2errors.h"
Expand All @@ -28,7 +33,7 @@ void OS2EXPORT lxNativeModuleDeinit(void);
initcode; \
static const LxExport lx_native_exports[] = {

#define LX_NATIVE_EXPORT(fn, ord) { ord, #fn, fn }
#define LX_NATIVE_EXPORT(fn, ord) { ord, #fn, fn, NULL }

#define LX_NATIVE_MODULE_INIT_END() \
}; \
Expand All @@ -38,5 +43,5 @@ void OS2EXPORT lxNativeModuleDeinit(void);

#endif

// end of native.h ...
// end of os2native.h ...

0 comments on commit 26a5298

Please sign in to comment.