Truncated pointers in memory/instr.c

Jukka Heinonen jhei at iki.fi
Sat May 11 10:02:19 CDT 2002


While playing around with handling interrupts from 32 bit code,
I noticed that Wine failed to catch interrupts if instruction
pointer was over 0xffff. Little looking around made it clear
that every MapSL call in memory/instr.c used MAKESEGPTR to
convert segment-address pairs into SEGPTRs. However, MAKESEGPTR
converts its arguments into WORDs which means that 32-bit
addresses are truncated. This means that emulating privileged
instructions in 32-bit code does not work properly.

All three fixes should work properly both with 16-bit addresses and
with 32-bit addresses. It is likely that at least files msdos/*.c are 
full of similar bugs which makes supporting 32-bit DPMI mode even more
difficult.


Changelog:
  When using MapSL, 32-bit addresses are no longer truncated into 16-bit addresses.


Index: memory/instr.c
===================================================================
RCS file: /home/wine/wine/memory/instr.c,v
retrieving revision 1.14
diff -u -r1.14 instr.c
--- memory/instr.c      10 Mar 2002 00:18:34 -0000      1.14
+++ memory/instr.c      11 May 2002 14:36:14 -0000
@@ -44,7 +44,7 @@
     if (ISV86(context)) return PTR_REAL_TO_LIN( seg, off );
     if (IS_SELECTOR_SYSTEM(seg)) return (void *)off;
     if (!long_addr) off = LOWORD(off);
-    return MapSL( MAKESEGPTR( seg, off ) );
+    return MapSL( MAKESEGPTR( seg, 0 ) ) + off;
 }
 
 inline static void *get_stack( CONTEXT86 *context )
@@ -54,7 +54,7 @@
     if (IS_SELECTOR_SYSTEM(context->SegSs))
         return (void *)context->Esp;
     if (IS_SELECTOR_32BIT(context->SegSs))
-        return MapSL( MAKESEGPTR( context->SegSs, context->Esp ) );
+        return MapSL( MAKESEGPTR( context->SegSs, 0 ) ) + context->Esp;
     return MapSL( MAKESEGPTR( context->SegSs, LOWORD(context->Esp) ) );
 }
 
@@ -249,7 +249,7 @@
     if (IS_SELECTOR_SYSTEM(seg)) return (BYTE *)(base + (index << ss));
     if (((seg & 7) != 7) || IS_SELECTOR_FREE(seg)) return NULL;
     if (wine_ldt_copy.limit[seg >> 3] < (base + (index << ss))) return NULL;
-    return MapSL( MAKESEGPTR( seg, (base + (index << ss))) );
+    return MapSL( MAKESEGPTR( seg, 0 ) ) + base + (index << ss);
 #undef GET_VAL
 }



-- 
Jukka Heinonen <http://www.iki.fi/jhei/>



More information about the wine-patches mailing list