diff options
Diffstat (limited to 'coregrind/m_syswrap/syswrap-x86-linux.c')
-rw-r--r-- | coregrind/m_syswrap/syswrap-x86-linux.c | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/coregrind/m_syswrap/syswrap-x86-linux.c b/coregrind/m_syswrap/syswrap-x86-linux.c index e16b84488..af3a61f95 100644 --- a/coregrind/m_syswrap/syswrap-x86-linux.c +++ b/coregrind/m_syswrap/syswrap-x86-linux.c @@ -647,8 +647,11 @@ static SysRes sys_set_thread_area ( ThreadId tid, vki_modify_ldt_t* info ) idx = info->entry_number; if (idx == -1) { - /* Find and use the first free entry. */ - for (idx = 0; idx < VEX_GUEST_X86_GDT_NENT; idx++) { + /* Find and use the first free entry. Don't allocate entry + zero, because the hardware will never do that, and apparently + doing so confuses some code (perhaps stuff running on + Wine). */ + for (idx = 1; idx < VEX_GUEST_X86_GDT_NENT; idx++) { if (gdt[idx].LdtEnt.Words.word1 == 0 && gdt[idx].LdtEnt.Words.word2 == 0) break; @@ -656,7 +659,8 @@ static SysRes sys_set_thread_area ( ThreadId tid, vki_modify_ldt_t* info ) if (idx == VEX_GUEST_X86_GDT_NENT) return VG_(mk_SysRes_Error)( VKI_ESRCH ); - } else if (idx < 0 || idx >= VEX_GUEST_X86_GDT_NENT) { + } else if (idx < 0 || idx == 0 || idx >= VEX_GUEST_X86_GDT_NENT) { + /* Similarly, reject attempts to use GDT[0]. */ return VG_(mk_SysRes_Error)( VKI_EINVAL ); } |