Andreas Mohr wrote:
when running Win98 explorer.exe, I finally get this crash:
...
Backtrace: 0 0x406cb9a3 (DOSVM_GetRMHandler+0x7(intnum=0x21) [interrupts.c:455] in winedos.dll.so) (ebp=41052560) 1 0x406c7b8c (DOSVM_CallRMInt+0x28(context=0x4105290c) [int31.c:462] in winedos.dll.so) (ebp=41052850) =>2 0x406c9b63 (DOSVM_Int31Handler+0x15f7(context=0x4105290c) [int31.c:1067] in winedos.dll.so) (ebp=410528dc) 3 0x406cafc5 (DOSVM_IntProcRelay+0x9(context=0x4105290c, data=0x406c856c) [interrupts.c:121] in winedos.dll.so) (ebp=410528e8) 4 0x406cd1ca (RELAY_RelayStub+0xe(proc=0x406cafbc, args=0x4038fcae, context=0x4105290c) [relay.c:116] in winedos.dll.so) (ebp=410528f8) 5 0x400b57f0 (KERNEL32.DLL.__wine_call_from_16_regs+0x144 in libntdll.dll.so)
...
I assume it's because the DOS memory area hasn't been unprotected/set up (grrr, this kind of problem *again*!)
Where should this call sequence have activated the DOS memory area properly?
Well, I was expecting this kind of problems, nice to finally have a test program. If we assume that we want to keep the lowest 64k protected for as long as possible, the first fix is to make DOSVM_GetRMHandler and DOSVM_SetRMHandler update interrupt vector in upper memory if DOS memory has not been unprotected. However, either DOSVM_CallRMInt or DOSVM_Int31Handler must unprotect memory because we are about to enter VM86.
I have actually had some plans to keep the lowest 1 megabyte protected when process starts up and only unprotect and initialize DOS/BIOS stuff if it really is needed (and unprotect low 64k only after first access to it from VM86 mode). In this case we could push initialization code to winedos and we really would keep null pointer protection active for as long as possible.
But, anyway, simple solution would be to add unprotect call to DOSVM_Int31Handler just before calling to DOSVM_CallRMInt. This would also fix DOSVM_GetRMHandler call in DOSVM_CallRMInt. Nice comment about why this is needed would also be fine.