[PATCH v2 1/2] ntdll: Add emulation for UMIP instructions.

Brendan Shanks bshanks at codeweavers.com
Thu Nov 21 15:01:49 CST 2019


> On Nov 13, 2019, at 7:51 PM, Andrew Wesie <awesie at gmail.com> wrote:
> 
> On Thu, Nov 14, 2019 at 7:29 AM Brendan Shanks <bshanks at codeweavers.com> wrote:
>> ...
>> +/***********************************************************************
>> + *           INSTR_GetOperandAddr
>> + *
>> + * Return the address of an instruction operand (from the mod/rm byte).
>> + */
>> +static int INSTR_GetOperandAddr( CONTEXT *context, BYTE *instr, unsigned int instr_len,
>> +                                 int long_addr, int segprefix, int *len, void **addr )
>> +{
>> ...
>> +    /* FIXME: we assume that all segments have a base of 0 */
>> +    *addr = (void *)(base + (index << ss));
>> +    return 1;
> 
> Does this FIXME need to be resolved? I don't have an easy way to test
> UMIP but would the code example below give the correct output with
> this patch? (This is not based on any real program, so it may be a
> moot point.)
> 
> #include <stdio.h>
> #include <stdlib.h>
> 
> int main()
> {
>    unsigned int ldt = 0x4141;
>    unsigned short ldt2 = 0x4141;
>    unsigned short ldt3 = 0x4141;
>    asm volatile ("sldt %0" : "=a" (ldt));
>    asm volatile ("sldt (%0)" : : "r" (&ldt2));
> #if defined(__x86_64__) || defined(__amd64__)
>    asm volatile ("sldt %%gs:(%0)" :: "r" (0x1250));
>    asm volatile ("movw %%gs:0x1250, %0" : "=r" (ldt3));
> #elif defined(__i386__)
>    asm volatile ("sldt %%fs:(%0)" :: "r" (0xBF4));
>    asm volatile ("movw %%fs:0xBF4, %0" : "=r" (ldt3));
> #endif
>    printf("ldt = %x\n", ldt);
>    printf("ldt2 = %x\n", ldt2);
>    printf("ldt3 = %x\n", ldt3);
>    return 0;
> }

Thanks for spotting that, I tried out your test app and it does crash when run with the emulation. I believe you’re right that this usage won’t show up in real programs though, especially on x86_64. I’m inclined to leave the FIXME unresolved.

I also investigated the history: I copied INSTR_GetOperandAddr() from ntoskrnl.exe/instr.c, and the FIXME has been present there since it was copied out of krnl386.exe16/instr.c 10 years ago. The original copy in krnl386.exe/instr.c still contains the segment code which could probably be re-used if necessary.

Brendan


More information about the wine-devel mailing list