Index: trunk/src/VBox/VMM/VMMAll/IEMAllN8vePython.py
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMAllN8vePython.py	(revision 101504)
+++ trunk/src/VBox/VMM/VMMAll/IEMAllN8vePython.py	(revision 101505)
@@ -51,10 +51,10 @@
     'IEM_MC_DEFER_TO_CIMPL_3_RET_THREADED':                      (None, True,  True,  ),
 
-    'IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC16':               (None, True,  False, ),
+    'IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC16':               (None, True,  True,  ),
     'IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC32':               (None, True,  True,  ),
-    'IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC64':               (None, True,  False, ),
+    'IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC64':               (None, True,  True,  ),
 
     'IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC16_WITH_FLAGS':    (None, True,  False, ),
-    'IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC32_WITH_FLAGS':    (None, True,  False,  ),
+    'IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC32_WITH_FLAGS':    (None, True,  False, ),
     'IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC64_WITH_FLAGS':    (None, True,  False, ),
 
@@ -76,5 +76,5 @@
 
     'IEM_MC_REL_JMP_S8_AND_FINISH_THREADED_PC16':                (None, True,  False, ),
-    'IEM_MC_REL_JMP_S8_AND_FINISH_THREADED_PC32':                (None, True,  False, ),
+    'IEM_MC_REL_JMP_S8_AND_FINISH_THREADED_PC32':                (None, True,  False,  ),
     'IEM_MC_REL_JMP_S8_AND_FINISH_THREADED_PC64':                (None, True,  False, ),
     'IEM_MC_REL_JMP_S16_AND_FINISH_THREADED_PC16':               (None, True,  False, ),
Index: trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp	(revision 101504)
+++ trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp	(revision 101505)
@@ -173,12 +173,13 @@
     Elf64_Shdr          aShdrs[5];
 #  else
-    Elf64_Shdr          aShdrs[6];
-    Elf64_Phdr          aPhdrs[3];
+    Elf64_Shdr          aShdrs[7];
+    Elf64_Phdr          aPhdrs[2];
 #  endif
     /** The dwarf ehframe data for the chunk. */
     uint8_t             abEhFrame[512];
     char                szzStrTab[128];
-    Elf64_Sym           aSymbols[1];
+    Elf64_Sym           aSymbols[3];
 #  ifdef IEMNATIVE_USE_GDB_JIT_ET_DYN
+    Elf64_Sym           aDynSyms[2];
     Elf64_Dyn           aDyn[6];
 #  endif
@@ -353,5 +354,5 @@
 
 
-static int iemExecMemAllocatorGrow(PIEMEXECMEMALLOCATOR pExecMemAllocator);
+static int iemExecMemAllocatorGrow(PVMCPUCC pVCpu, PIEMEXECMEMALLOCATOR pExecMemAllocator);
 
 
@@ -520,5 +521,5 @@
     if (pExecMemAllocator->cChunks < pExecMemAllocator->cMaxChunks)
     {
-        int rc = iemExecMemAllocatorGrow(pExecMemAllocator);
+        int rc = iemExecMemAllocatorGrow(pVCpu, pExecMemAllocator);
         AssertLogRelRCReturn(rc, NULL);
 
@@ -641,6 +642,9 @@
  */
 static int
-iemExecMemAllocatorInitAndRegisterUnwindInfoForChunk(PIEMEXECMEMALLOCATOR pExecMemAllocator, void *pvChunk, uint32_t idxChunk)
-{
+iemExecMemAllocatorInitAndRegisterUnwindInfoForChunk(PVMCPUCC pVCpu, PIEMEXECMEMALLOCATOR pExecMemAllocator,
+                                                     void *pvChunk, uint32_t idxChunk)
+{
+    RT_NOREF(pVCpu);
+
     /*
      * The AMD64 unwind opcodes.
@@ -821,5 +825,6 @@
  */
 static int
-iemExecMemAllocatorInitAndRegisterUnwindInfoForChunk(PIEMEXECMEMALLOCATOR pExecMemAllocator, void *pvChunk, uint32_t idxChunk)
+iemExecMemAllocatorInitAndRegisterUnwindInfoForChunk(PVMCPUCC pVCpu, PIEMEXECMEMALLOCATOR pExecMemAllocator,
+                                                     void *pvChunk, uint32_t idxChunk)
 {
     PIEMEXECMEMCHUNKEHFRAME const pEhFrame = &pExecMemAllocator->paEhFrames[idxChunk];
@@ -951,5 +956,8 @@
 
     RT_ZERO(*pSymFile);
-    /* The ELF header: */
+
+    /*
+     * The ELF header:
+     */
     pSymFile->EHdr.e_ident[0]           = ELFMAG0;
     pSymFile->EHdr.e_ident[1]           = ELFMAG1;
@@ -997,5 +1005,15 @@
         memcpy(&pSymFile->szzStrTab[offStrTab], a_szStr, sizeof(a_szStr)); \
         offStrTab += sizeof(a_szStr); \
+        Assert(offStrTab < sizeof(pSymFile->szzStrTab)); \
     } while (0)
+#define APPEND_STR_FMT(a_szStr, ...) do { \
+        offStrTab += RTStrPrintf(&pSymFile->szzStrTab[offStrTab], sizeof(pSymFile->szzStrTab) - offStrTab, a_szStr, __VA_ARGS__); \
+        offStrTab++; \
+        Assert(offStrTab < sizeof(pSymFile->szzStrTab)); \
+    } while (0)
+
+    /*
+     * Section headers.
+     */
     /* Section header #0: NULL */
     unsigned i = 0;
@@ -1048,11 +1066,6 @@
     /* Section header: .symbols */
     pSymFile->aShdrs[i].sh_name         = offStrTab;
-#   if defined(IEMNATIVE_USE_GDB_JIT_ET_DYN)
-    APPEND_STR(".dynsym");
-    pSymFile->aShdrs[i].sh_type         = SHT_DYNSYM;
-#   else
     APPEND_STR(".symtab");
     pSymFile->aShdrs[i].sh_type         = SHT_SYMTAB;
-#   endif
     pSymFile->aShdrs[i].sh_flags        = SHF_ALLOC;
     pSymFile->aShdrs[i].sh_offset
@@ -1064,4 +1077,20 @@
     pSymFile->aShdrs[i].sh_entsize      = sizeof(pSymFile->aSymbols[0]);
     i++;
+
+#   if defined(IEMNATIVE_USE_GDB_JIT_ET_DYN)
+    /* Section header: .symbols */
+    pSymFile->aShdrs[i].sh_name         = offStrTab;
+    APPEND_STR(".dynsym");
+    pSymFile->aShdrs[i].sh_type         = SHT_DYNSYM;
+    pSymFile->aShdrs[i].sh_flags        = SHF_ALLOC;
+    pSymFile->aShdrs[i].sh_offset
+        = pSymFile->aShdrs[i].sh_addr   = RT_UOFFSETOF(GDBJITSYMFILE, aDynSyms);
+    pSymFile->aShdrs[i].sh_size         = sizeof(pSymFile->aDynSyms);
+    pSymFile->aShdrs[i].sh_link         = iShStrTab;
+    pSymFile->aShdrs[i].sh_info         = RT_ELEMENTS(pSymFile->aDynSyms);
+    pSymFile->aShdrs[i].sh_addralign    = sizeof(pSymFile->aDynSyms[0].st_value);
+    pSymFile->aShdrs[i].sh_entsize      = sizeof(pSymFile->aDynSyms[0]);
+    i++;
+#   endif
 
 #   if defined(IEMNATIVE_USE_GDB_JIT_ET_DYN)
@@ -1082,4 +1111,5 @@
 
     /* Section header: .text */
+    unsigned const iShText = i;
     pSymFile->aShdrs[i].sh_name         = offStrTab;
     APPEND_STR(".text");
@@ -1106,5 +1136,5 @@
      * The program headers:
      */
-    /* Headers and whatnot up to .dynamic: */
+    /* Everything in a single LOAD segment: */
     i = 0;
     pSymFile->aPhdrs[i].p_type          = PT_LOAD;
@@ -1114,8 +1144,8 @@
         = pSymFile->aPhdrs[i].p_paddr   = 0;
     pSymFile->aPhdrs[i].p_filesz         /* Size of segment in file. */
-        = pSymFile->aPhdrs[i].p_memsz   = RT_UOFFSETOF(GDBJITSYMFILE, aDyn);
+        = pSymFile->aPhdrs[i].p_memsz   = pExecMemAllocator->cbChunk - offSymFileInChunk;
     pSymFile->aPhdrs[i].p_align         = HOST_PAGE_SIZE;
     i++;
-    /* .dynamic */
+    /* The .dynamic segment. */
     pSymFile->aPhdrs[i].p_type          = PT_DYNAMIC;
     pSymFile->aPhdrs[i].p_flags         = PF_R;
@@ -1127,22 +1157,14 @@
     pSymFile->aPhdrs[i].p_align         = sizeof(pSymFile->aDyn[0].d_tag);
     i++;
-    /* The rest of the chunk. */
-    pSymFile->aPhdrs[i].p_type          = PT_LOAD;
-    pSymFile->aPhdrs[i].p_flags         = PF_X | PF_R;
-    pSymFile->aPhdrs[i].p_offset
-        = pSymFile->aPhdrs[i].p_vaddr
-        = pSymFile->aPhdrs[i].p_paddr   = sizeof(GDBJITSYMFILE);
-    pSymFile->aPhdrs[i].p_filesz         /* Size of segment in file. */
-        = pSymFile->aPhdrs[i].p_memsz   = pExecMemAllocator->cbChunk - offSymFileInChunk - sizeof(GDBJITSYMFILE);
-    pSymFile->aPhdrs[i].p_align         = 1;
-    i++;
 
     Assert(i == RT_ELEMENTS(pSymFile->aPhdrs));
 
-    /* The dynamic section: */
+    /*
+     * The dynamic section:
+     */
     i = 0;
     pSymFile->aDyn[i].d_tag             = DT_SONAME;
     pSymFile->aDyn[i].d_un.d_val        = offStrTab;
-    APPEND_STR("iem-native.so");
+    APPEND_STR_FMT("iem-exec-chunk-%u-%u", pVCpu->idCpu, idxChunk);
     i++;
     pSymFile->aDyn[i].d_tag             = DT_STRTAB;
@@ -1153,28 +1175,62 @@
     i++;
     pSymFile->aDyn[i].d_tag             = DT_SYMTAB;
-    pSymFile->aDyn[i].d_un.d_ptr        = RT_UOFFSETOF(GDBJITSYMFILE, aSymbols);
+    pSymFile->aDyn[i].d_un.d_ptr        = RT_UOFFSETOF(GDBJITSYMFILE, aDynSyms);
     i++;
     pSymFile->aDyn[i].d_tag             = DT_SYMENT;
-    pSymFile->aDyn[i].d_un.d_val        = sizeof(pSymFile->aSymbols[0]);
+    pSymFile->aDyn[i].d_un.d_val        = sizeof(pSymFile->aDynSyms[0]);
     i++;
     pSymFile->aDyn[i].d_tag             = DT_NULL;
     i++;
     Assert(i == RT_ELEMENTS(pSymFile->aDyn));
+#   endif /* IEMNATIVE_USE_GDB_JIT_ET_DYN */
+
+    /*
+     * Symbol tables:
+     */
+    /** @todo gdb doesn't seem to really like this ...   */
+    i = 0;
+    pSymFile->aSymbols[i].st_name       = 0;
+    pSymFile->aSymbols[i].st_shndx      = SHN_UNDEF;
+    pSymFile->aSymbols[i].st_value      = 0;
+    pSymFile->aSymbols[i].st_size       = 0;
+    pSymFile->aSymbols[i].st_info       = ELF64_ST_INFO(STB_LOCAL, STT_NOTYPE);
+    pSymFile->aSymbols[i].st_other      = 0 /* STV_DEFAULT */;
+#   ifdef IEMNATIVE_USE_GDB_JIT_ET_DYN
+    pSymFile->aDynSyms[0] = pSymFile->aSymbols[i];
 #   endif
-
-    /* Symbol table: */
-    i = 0;
-    pSymFile->aSymbols[i].st_name       = offStrTab;
-    APPEND_STR("iem_exec_chunk");
+    i++;
+
+    pSymFile->aSymbols[i].st_name       = 0;
     pSymFile->aSymbols[i].st_shndx      = SHN_ABS;
-    pSymFile->aSymbols[i].st_value      = (uintptr_t)pvChunk;
-    pSymFile->aSymbols[i].st_size       = pExecMemAllocator->cbChunk;
-    pSymFile->aSymbols[i].st_info       = ELF64_ST_INFO(STB_LOCAL, STT_FUNC);
+    pSymFile->aSymbols[i].st_value      = 0;
+    pSymFile->aSymbols[i].st_size       = 0;
+    pSymFile->aSymbols[i].st_info       = ELF64_ST_INFO(STB_LOCAL, STT_FILE);
     pSymFile->aSymbols[i].st_other      = 0 /* STV_DEFAULT */;
     i++;
+
+    pSymFile->aSymbols[i].st_name       = offStrTab;
+    APPEND_STR_FMT("iem_exec_chunk_%u_%u", pVCpu->idCpu, idxChunk);
+#   if 0
+    pSymFile->aSymbols[i].st_shndx      = iShText;
+    pSymFile->aSymbols[i].st_value      = 0;
+#   else
+    pSymFile->aSymbols[i].st_shndx      = SHN_ABS;
+    pSymFile->aSymbols[i].st_value      = (uintptr_t)(pSymFile + 1);
+#   endif
+    pSymFile->aSymbols[i].st_size       = pSymFile->aShdrs[iShText].sh_size;
+    pSymFile->aSymbols[i].st_info       = ELF64_ST_INFO(STB_GLOBAL, STT_FUNC);
+    pSymFile->aSymbols[i].st_other      = 0 /* STV_DEFAULT */;
+#   ifdef IEMNATIVE_USE_GDB_JIT_ET_DYN
+    pSymFile->aDynSyms[1] = pSymFile->aSymbols[i];
+    pSymFile->aDynSyms[1].st_value      = (uintptr_t)(pSymFile + 1);
+#   endif
+    i++;
+
     Assert(i == RT_ELEMENTS(pSymFile->aSymbols));
     Assert(offStrTab < sizeof(pSymFile->szzStrTab));
 
-    /* The GDB JIT entry: */
+    /*
+     * The GDB JIT entry and informing GDB.
+     */
     pEhFrame->GdbJitEntry.pbSymFile = (uint8_t *)pSymFile;
 #   if 1
@@ -1201,5 +1257,7 @@
     RTCritSectLeave(&g_IemNativeGdbJitLock);
 
-#  endif /* IEMNATIVE_USE_GDB_JIT */
+#  else  /* !IEMNATIVE_USE_GDB_JIT */
+    RT_NOREF(pVCpu);
+#  endif /* !IEMNATIVE_USE_GDB_JIT */
 
     return VINF_SUCCESS;
@@ -1216,5 +1274,5 @@
  * regular allocator function when it's out of memory.
  */
-static int iemExecMemAllocatorGrow(PIEMEXECMEMALLOCATOR pExecMemAllocator)
+static int iemExecMemAllocatorGrow(PVMCPUCC pVCpu, PIEMEXECMEMALLOCATOR pExecMemAllocator)
 {
     /* Check that we've room for growth. */
@@ -1322,5 +1380,5 @@
              * (This sets pvUnwindInfo.)
              */
-            rc = iemExecMemAllocatorInitAndRegisterUnwindInfoForChunk(pExecMemAllocator, pvChunk, idxChunk);
+            rc = iemExecMemAllocatorInitAndRegisterUnwindInfoForChunk(pVCpu, pExecMemAllocator, pvChunk, idxChunk);
             if (RT_SUCCESS(rc))
 #endif
@@ -1344,4 +1402,5 @@
 #endif
     RTMemPageFree(pvChunk, pExecMemAllocator->cbChunk);
+    RT_NOREF(pVCpu);
     return rc;
 }
@@ -1459,5 +1518,5 @@
     while (cbInitial < (uint64_t)pExecMemAllocator->cChunks * pExecMemAllocator->cbChunk)
     {
-        int rc = iemExecMemAllocatorGrow(pExecMemAllocator);
+        int rc = iemExecMemAllocatorGrow(pVCpu, pExecMemAllocator);
         AssertLogRelRCReturn(rc, rc);
     }
@@ -2868,8 +2927,6 @@
                                       uint64_t uParam0, uint64_t uParam1, uint64_t uParam2)
 {
-#ifdef VBOX_STRICT
-    off = iemNativeEmitMarker(pReNative, off);
-    AssertReturn(off != UINT32_MAX, UINT32_MAX);
-#endif
+    iemNativeRegFlushGuestShadows(pReNative, UINT64_MAX); /** @todo optimize this */
+    off = iemNativeRegMoveAndFreeAndFlushAtCall(pReNative, off, 4, false /*fFreeArgVars*/);
 
     /*
@@ -2943,8 +3000,4 @@
 static int32_t iemNativeEmitThreadedCall(PIEMRECOMPILERSTATE pReNative, uint32_t off, PCIEMTHRDEDCALLENTRY pCallEntry)
 {
-#ifdef VBOX_STRICT
-    off = iemNativeEmitMarker(pReNative, off);
-    AssertReturn(off != UINT32_MAX, UINT32_MAX);
-#endif
     iemNativeRegFlushGuestShadows(pReNative, UINT64_MAX); /** @todo optimize this */
     off = iemNativeRegMoveAndFreeAndFlushAtCall(pReNative, off, 4, false /*fFreeArgVars*/);
@@ -3359,10 +3412,25 @@
 
 
+/** Same as iemRegAddToRip64AndFinishingNoFlags. */
+DECLINLINE(uint32_t) iemNativeEmitAddToRip64AndFinishingNoFlags(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t cbInstr)
+{
+    /* Allocate a temporary PC register. */
+    uint8_t const idxPcReg = iemNativeRegAllocTmpForGuestReg(pReNative, &off, kIemNativeGstReg_Pc, kIemNativeGstRegUse_ForUpdate);
+    AssertReturn(idxPcReg != UINT8_MAX, UINT32_MAX);
+
+    /* Perform the addition and store the result. */
+    off = iemNativeEmitAddGprImm8(pReNative, off, idxPcReg, cbInstr);
+    off = iemNativeEmitStoreGprToVCpuU64(pReNative, off, idxPcReg, RT_UOFFSETOF(VMCPU, cpum.GstCtx.rip));
+
+    /* Free but don't flush the PC register. */
+    iemNativeRegFreeTmp(pReNative, idxPcReg);
+
+    return off;
+}
+
 /** Same as iemRegAddToEip32AndFinishingNoFlags. */
 DECLINLINE(uint32_t) iemNativeEmitAddToEip32AndFinishingNoFlags(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t cbInstr)
 {
     /* Allocate a temporary PC register. */
-    /** @todo this is not strictly required on AMD64, we could emit alternative
-     *        code here if we don't get a tmp register... */
     uint8_t const idxPcReg = iemNativeRegAllocTmpForGuestReg(pReNative, &off, kIemNativeGstReg_Pc, kIemNativeGstRegUse_ForUpdate);
     AssertReturn(idxPcReg != UINT8_MAX, UINT32_MAX);
@@ -3377,4 +3445,24 @@
     return off;
 }
+
+
+/** Same as iemRegAddToIp16AndFinishingNoFlags. */
+DECLINLINE(uint32_t) iemNativeEmitAddToIp16AndFinishingNoFlags(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t cbInstr)
+{
+    /* Allocate a temporary PC register. */
+    uint8_t const idxPcReg = iemNativeRegAllocTmpForGuestReg(pReNative, &off, kIemNativeGstReg_Pc, kIemNativeGstRegUse_ForUpdate);
+    AssertReturn(idxPcReg != UINT8_MAX, UINT32_MAX);
+
+    /* Perform the addition and store the result. */
+    off = iemNativeEmitAddGpr32Imm8(pReNative, off, idxPcReg, cbInstr);
+    off = iemNativeEmitClear16UpGpr(pReNative, off, idxPcReg);
+    off = iemNativeEmitStoreGprToVCpuU64(pReNative, off, idxPcReg, RT_UOFFSETOF(VMCPU, cpum.GstCtx.rip));
+
+    /* Free but don't flush the PC register. */
+    iemNativeRegFreeTmp(pReNative, idxPcReg);
+
+    return off;
+}
+
 
 /*
@@ -3474,4 +3562,8 @@
     while (cCallsLeft-- > 0)
     {
+#ifdef VBOX_STRICT
+        off = iemNativeEmitMarker(pReNative, off, RT_MAKE_U32(pTb->Thrd.cCalls - cCallsLeft - 1, pCallEntry->enmFunction));
+        AssertReturn(off != UINT32_MAX, pTb);
+#endif
         PFNIEMNATIVERECOMPFUNC const pfnRecom = g_apfnIemNativeRecompileFunctions[pCallEntry->enmFunction];
         if (pfnRecom) /** @todo stats on this.   */
Index: trunk/src/VBox/VMM/VMMAll/IEMAllThrdPython.py
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMAllThrdPython.py	(revision 101504)
+++ trunk/src/VBox/VMM/VMMAll/IEMAllThrdPython.py	(revision 101505)
@@ -1590,6 +1590,10 @@
 
         if ThrdFnVar.ksVariation_16_Pre386 in dByVari:
+            if not fSimple:
+                aoCases.append(Case('IEMMODE_16BIT | IEM_F_MODE_X86_FLAT_OR_PRE_386_MASK | 16', None)); # fall thru
             aoCases.append(Case('IEMMODE_16BIT | IEM_F_MODE_X86_FLAT_OR_PRE_386_MASK', ThrdFnVar.ksVariation_16_Pre386));
         if ThrdFnVar.ksVariation_16f_Pre386 in dByVari:  # should be nested under previous if, but line too long.
+            if not fSimple:
+                aoCases.append(Case('IEMMODE_16BIT | IEM_F_MODE_X86_FLAT_OR_PRE_386_MASK | 32 | 16', None)); # fall thru
             aoCases.append(Case('IEMMODE_16BIT | IEM_F_MODE_X86_FLAT_OR_PRE_386_MASK | 32', ThrdFnVar.ksVariation_16f_Pre386));
 
