Brendan Shanks bshanks@codeweavers.com writes:
On Nov 13, 2019, at 7:51 PM, Andrew Wesie awesie@gmail.com wrote:
On Thu, Nov 14, 2019 at 7:29 AM Brendan Shanks bshanks@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.
Outside of 16-bit code, these would in general be GDT selectors, and there's no easy way of getting their base address. Hopefully it won't become necessary.