16-bit bridging code now protects %es register.
Fixes crash with Info-Zip's unzip.exe blowing up calling into ncurses via VioGetMode().
This commit is contained in:
1 parent
9251abfe4f
commit
2ee12b66a3
3 files changed
+24
-5
No files matched your search
+9
-4
@@ -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 *));
|
||||
@@ -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);
|
||||
|
||||
+2
-1
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
@@ -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; \
|
||||
@@ -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 */ \
|
||||
|
||||
Reference in new issue
Block a user