Navigation Menu

Skip to content

Commit

Permalink
16-bit bridging code now protects %es register.
Browse files Browse the repository at this point in the history
Fixes crash with Info-Zip's unzip.exe blowing up calling into ncurses
via VioGetMode().
  • Loading branch information
icculus committed Nov 2, 2016
1 parent 9251abf commit 2ee12b6
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 5 deletions.
13 changes: 9 additions & 4 deletions lx_loader.c
Expand Up @@ -730,8 +730,11 @@ static void *generateMissingTrampoline16(const char *_module, const char *_entry
*(ptr++) = 0x66; /* mov cx,0x8888... */
*(ptr++) = 0xB9; /* ...mov cx,0x8888 */
memcpy(ptr, &GLoaderState->original_ds, 2); ptr += 2;
*(ptr++) = 0x8E; /* mov ds,ecx... */
*(ptr++) = 0xD9; /* ...mov ds,ecx */
*(ptr++) = 0x66; /* mov cx,0x8888... */
*(ptr++) = 0xB9; /* ...mov cx,0x8888 */
memcpy(ptr, &GLoaderState->original_es, 2); ptr += 2;
*(ptr++) = 0x8E; /* mov es,ecx... */ \
*(ptr++) = 0xC1; /* ...mov es,ecx */ \
// okay, CPU is in a sane state again, call the trampoline. Don't bother cleaning up.
*(ptr++) = 0x68; // pushl immediate
memcpy(ptr, &entry, sizeof (char *));
Expand Down Expand Up @@ -2076,10 +2079,12 @@ int main(int argc, char **argv, char **envp)
unsigned int segment = 0;
__asm__ __volatile__ ( "movw %%cs, %%ax \n\t" : "=a" (segment) );
GLoaderState->original_cs = segment;
__asm__ __volatile__ ( "movw %%ss, %%ax \n\t" : "=a" (segment) );
GLoaderState->original_ss = segment;
__asm__ __volatile__ ( "movw %%ds, %%ax \n\t" : "=a" (segment) );
GLoaderState->original_ds = segment;
__asm__ __volatile__ ( "movw %%es, %%ax \n\t" : "=a" (segment) );
GLoaderState->original_es = segment;
__asm__ __volatile__ ( "movw %%ss, %%ax \n\t" : "=a" (segment) );
GLoaderState->original_ss = segment;

const char *envr = getenv("IS_2INE");
GLoaderState->subprocess = (envr != NULL);
Expand Down
3 changes: 2 additions & 1 deletion lx_loader.h
Expand Up @@ -212,8 +212,9 @@ typedef struct LxLoaderState
int running;
int trace_native;
uint16 original_cs;
uint16 original_ss;
uint16 original_ds;
uint16 original_es;
uint16 original_ss;
uint32 ldt[8192];
char *libpath;
uint32 libpathlen;
Expand Down
13 changes: 13 additions & 0 deletions native/os2native16.h
Expand Up @@ -86,15 +86,21 @@ ADD EAX, 4 ; %eax now points to original function arguments on the stack.
PUSH EBX ; save original ss:sp to stack.
PUSH DS ; save off the caller's data segment.
PUSH ES ; save off the caller's %es register.
MOV CX, 0x8888 ; restore our linear data segment.
MOV DS, CX
MOV CX, 0x9999 ; restore %es register.
MOV ES, CX
PUSH EAX ; make this the sole argument to the bridge function.
MOV EAX, 0x55555555 ; absolute address of our 32-bit bridging function in C.
CALL [EAX] ; call our 32-bit bridging function in C.
; don't touch EAX anymore, it has the return value now!
ADD ESP, 4 ; dump our function argument.
POP ES ; get back caller's %es register.
POP DS ; get back our 16-bit data segment.
; Restore 16:16 stack. !!! FIXME: can use LSS if we figure out prefix and DS politics.
Expand Down Expand Up @@ -152,11 +158,17 @@ RETF 0x22 ; ...and back to the (far) caller, clearing the args (Pascal calling
*(ptr++) = 0x04; /* ...add eax,byte +0x4 */ \
*(ptr++) = 0x53; /* push ebx */ \
*(ptr++) = 0x1E; /* push ds */ \
*(ptr++) = 0x06; /* push es */ \
*(ptr++) = 0x66; /* mov cx,0x8888... */ \
*(ptr++) = 0xB9; /* ...mov cx,0x8888 */ \
memcpy(ptr, &GLoaderState->original_ds, 2); ptr += 2; \
*(ptr++) = 0x8E; /* mov ds,ecx... */ \
*(ptr++) = 0xD9; /* ...mov ds,ecx */ \
*(ptr++) = 0x66; /* mov cx,0x9999... */ \
*(ptr++) = 0xB9; /* ...mov cx,0x9999 */ \
memcpy(ptr, &GLoaderState->original_es, 2); ptr += 2; \
*(ptr++) = 0x8E; /* mov es,ecx... */ \
*(ptr++) = 0xC1; /* ...mov es,ecx */ \
*(ptr++) = 0x50; /* push eax */ \
*(ptr++) = 0xB8; /* mov eax,0x55555555... */ \
const uint32 callbridgeaddr = (uint32) bridge16to32_##fn; \
Expand All @@ -166,6 +178,7 @@ RETF 0x22 ; ...and back to the (far) caller, clearing the args (Pascal calling
*(ptr++) = 0x83; /* add esp,byte +0x4... */ \
*(ptr++) = 0xC4; /* ...add esp,byte +0x4 */ \
*(ptr++) = 0x04; /* ...add esp,byte +0x4 */ \
*(ptr++) = 0x07; /* pop es */ \
*(ptr++) = 0x1F; /* pop ds */ \
*(ptr++) = 0x66; /* pop bx... */ \
*(ptr++) = 0x5B; /* ...pop bx */ \
Expand Down

0 comments on commit 2ee12b6

Please sign in to comment.