Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/Makefile.kmk
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/Makefile.kmk	(revision 58813)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/Makefile.kmk	(revision 58814)
@@ -123,5 +123,5 @@
 TOOL_Bs3Vcc64_CXX = $(TOOL_$(VBOX_VCC_TOOL_STEM)AMD64_CXX)
 TOOL_Bs3Vcc64_COBJSUFF                 = $(TOOL_$(VBOX_VCC_TOOL_STEM)AMD64_COBJSUFF)
-TOOL_Bs3Vcc64_CFLAGS                   = $(TOOL_$(VBOX_VCC_TOOL_STEM)AMD64_CFLAGS)
+TOOL_Bs3Vcc64_CFLAGS                   = $(filter-out -TC,$(TOOL_$(VBOX_VCC_TOOL_STEM)AMD64_CFLAGS)) -TP # compile as C++
 TOOL_Bs3Vcc64_CFLAGS.debug             =
 TOOL_Bs3Vcc64_CFLAGS.dbgopt            = -O1
@@ -327,4 +327,6 @@
  	output raw offset=0x10000 \
  	order \
+ 	 clname BS3FLAT segaddr=0x0000 \
+ 	   segment BS3FLAT segaddr=0x0000 \
  	 clname BS3CODE16 segaddr=0x1000 \
  	  segment BS3TEXT16 \
@@ -354,5 +356,8 @@
 	  segment BS3DATA64 \
  	  segment DATA64 \
- 	  segment .data
+ 	  segment .data \
+ 	  segment .pdata \
+ 	  segment .xdata \
+
 TEMPLATE_VBoxBS3KitImg_DEPS = \
 	$(bs3-bootsector_1_TARGET) \
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/VBoxBs3ObjConverter.cpp
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/VBoxBs3ObjConverter.cpp	(revision 58813)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/VBoxBs3ObjConverter.cpp	(revision 58814)
@@ -348,4 +348,5 @@
      * Work the section table.
      */
+    bool fRet = true;
     PCIMAGE_SECTION_HEADER paShdrs   = (PCIMAGE_SECTION_HEADER)(pHdr + 1);
     for (uint32_t i = 0; i < pHdr->NumberOfSections; i++)
@@ -374,4 +375,9 @@
                 return error(pszFile, "Raw data beyond the end of the file or overlapping the headers (section #%u)\n", i);
             uint8_t *pbRawData = &pbFile[paShdrs[i].PointerToRawData];
+
+            /* Is this a section which ends up in the binary? */
+            bool const fInBinary = !(paShdrs[i].Characteristics & (IMAGE_SCN_LNK_REMOVE | IMAGE_SCN_LNK_INFO));
+            bool const fIsPData  = fInBinary
+                                && memcmp(paShdrs[i].Name, RT_STR_TUPLE(".pdata\0")) == 0;
 
             /*
@@ -425,4 +431,5 @@
 
                 /* Convert it. */
+                uint8_t uDir = IMAGE_REL_AMD64_ABSOLUTE;
                 switch (paRelocs[j].Type)
                 {
@@ -441,4 +448,5 @@
                                          uAddend, paRelocs[j].u.VirtualAddress, i, paShdrs[i].Name);
                         paRelocs[j].Type = IMAGE_REL_I386_DIR32;
+                        uDir = IMAGE_REL_AMD64_ADDR64;
                         break;
                     }
@@ -462,7 +470,9 @@
                     case IMAGE_REL_AMD64_ADDR32:
                         paRelocs[j].Type = IMAGE_REL_I386_DIR32;
+                        uDir = IMAGE_REL_AMD64_ADDR32;
                         break;
                     case IMAGE_REL_AMD64_ADDR32NB:
                         paRelocs[j].Type = IMAGE_REL_I386_DIR32NB;
+                        uDir = IMAGE_REL_AMD64_ADDR32NB;
                         break;
                     case IMAGE_REL_AMD64_REL32:
@@ -489,8 +499,21 @@
                                      paRelocs[j].u.VirtualAddress, i, paShdrs[i].Name);
                 }
+
+                /*
+                 * Error no absolute fixup that we care about. We continue so
+                 * the developer can get the full story before failing.
+                 */
+                if (   fInBinary
+                    && !fIsPData
+                    && uDir != IMAGE_REL_AMD64_ABSOLUTE)
+                {
+                    error(pszFile, "%s at %#x in section %u '%-8.8s': wlink won't get this right\n",
+                          g_apszCoffAmd64RelTypes[uDir], paRelocs[j].u.VirtualAddress, i, paShdrs[i].Name);
+                    fRet = false;
+                }
             }
         }
     }
-    return true;
+    return fRet;
 }
 
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-MemAlloc.c
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-MemAlloc.c	(revision 58813)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-MemAlloc.c	(revision 58814)
@@ -43,8 +43,8 @@
          */
         PBS3SLABHEAD pHead = enmKind == BS3MEMKIND_REAL
-                           ? &BS3_DATA_NM(g_aBs3LowSlabLists)[idxSlabList]
-                           : &BS3_DATA_NM(g_aBs3UpperTiledSlabLists)[idxSlabList];
+                           ? &BS3_MSC64_FIXUP_HACK(BS3SLABHEAD, BS3_DATA_NM(g_aBs3LowSlabLists))[idxSlabList]
+                           : &BS3_MSC64_FIXUP_HACK(BS3SLABHEAD, BS3_DATA_NM(g_aBs3UpperTiledSlabLists))[idxSlabList];
 
-        BS3_ASSERT(BS3_DATA_NM(g_aBs3LowSlabLists)[idxSlabList].cbChunk >= cb);
+        BS3_ASSERT(BS3_MSC64_FIXUP_HACK(BS3SLABHEAD, BS3_DATA_NM(g_aBs3LowSlabLists))[idxSlabList].cbChunk >= cb);
         pvRet = Bs3SlabListAlloc(pHead);
         if (pvRet)
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-memory.h
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-memory.h	(revision 58813)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-memory.h	(revision 58814)
@@ -70,5 +70,8 @@
 {
     if (cbRequest <= BS3_DATA_NM(g_acbBs3SlabLists)[BS3_MEM_SLAB_LIST_COUNT - 1])
-        return BS3_DATA_NM(g_aiBs3SlabListsByPowerOfTwo)[cbRequest ? ASMBitLastSetU16((uint16_t)(cbRequest - 1)) : 0];
+    {
+        unsigned idx = cbRequest ? ASMBitLastSetU16((uint16_t)(cbRequest - 1)) : 0;
+        return BS3_MSC64_FIXUP_HACK(uint8_t const, BS3_DATA_NM(g_aiBs3SlabListsByPowerOfTwo))[idx];
+    }
     return UINT8_MAX;
 }
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-first-common.mac
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-first-common.mac	(revision 58813)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-first-common.mac	(revision 58814)
@@ -120,4 +120,11 @@
     db      10,13,'eye-catcher: BS3TEXT64',10,13
 
+%ifdef ASM_FORMAT_OMF
+section TEXT64 align=4 CLASS=CODE PUBLIC USE32
+;section .text  align=4 CLASS=CODE PUBLIC USE32 - nasm doesn't do '.' at the start of segments in OMF mode. Not that this helps anyways...
+;section .rdata align=4 CLASS=CODE PUBLIC USE32
+;GROUP CODE64 TEXT64 _text _rdata
+%endif
+
 %ifdef ASM_FORMAT_ELF
 section BS3TEXT64_END   align=1 progbits alloc exec nowrite
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-first-pe16.asm
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-first-pe16.asm	(revision 58813)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-first-pe16.asm	(revision 58814)
@@ -54,4 +54,5 @@
 
 extern _Bs3Printf_c32
+extern Bs3Printf_c64
 
 BS3_BEGIN_TEXT16
@@ -65,9 +66,8 @@
     call    NAME(Bs3SwitchToPE32_rm)
     BS3_SET_BITS 32
+.halt: hlt
+jmp .halt
     call    NAME(Bs3SwitchToRM_pe32)
     BS3_SET_BITS 16
-
-.halt: hlt
-jmp .halt
 
 
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-SwitchToPE32.asm
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-SwitchToPE32.asm	(revision 58813)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-SwitchToPE32.asm	(revision 58814)
@@ -85,5 +85,4 @@
         mov     cr0, eax
         jmp     BS3_SEL_R0_CS32:dword .thirty_two_bit wrt FLAT
-extern TODO_CONVINCE_WATCOM_TO_DO_FLAT_RELOCS
 BS3_BEGIN_TEXT32
 .thirty_two_bit:
@@ -104,6 +103,6 @@
         mov     [esp + 8], eax          ; Store it in the place right for 32-bit returns.
  %endif
-        pop     esp
         popfd
+        pop     eax
         ret
 
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.h
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.h	(revision 58813)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.h	(revision 58814)
@@ -372,4 +372,24 @@
 #else
 # define BS3_DATA_NM(a_Name)  a_Name
+#endif
+
+/** @def BS3_MSC64_FIXUP_HACK
+ * Used to avoid IMAGE_REL_AMD64_ADDR32NB fixups where the compiler tries to
+ * make use of __ImageBase as a base pointer instead of emitting rip relative
+ * accesses.  Happens when there are a bunch of global data accesses in the same
+ * function, probably to save space.
+ *
+ * The volatile variable in the lambda fixes it.
+ */
+#if _MSC_VER && ARCH_BITS == 64
+# define BS3_MSC64_FIXUP_HACK(a_BaseType, a_Data) \
+    ([]() -> a_BaseType * \
+     { \
+        a_BaseType * volatile x = a_Data; \
+        return x; \
+     }())
+
+#else
+# define BS3_MSC64_FIXUP_HACK(a_BaseType, a_Data) (a_Data)
 #endif
 
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.mac
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.mac	(revision 58813)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.mac	(revision 58814)
@@ -126,4 +126,22 @@
 ;; @name Segment definitions.
 ;; @{
+
+%ifdef ASM_FORMAT_OMF
+; !!HACK ALERT!!
+;
+;   To make FLAT actually be flat, i.e. have a base of 0 rather than the same as
+;   the target (?) segment, we tweak it a little bit here.  We associate a segment
+;   with it so that we can get at it in the class/segment ordering directives
+;   we pass to the linker.  The segment does not contain any data or anything, it
+;   is just an empty one which we assign the address of zero.
+;
+;   Look for 'clname BS3FLAT segaddr=0x0000' and 'segment BS3FLAT segaddr=0x0000'
+;   in the makefile.
+;
+; !!HACK ALERT!!
+segment BS3FLAT use32 class=BS3FLAT
+GROUP FLAT BS3FLAT
+%endif
+
 %macro BS3_BEGIN_TEXT16 0
  %ifndef  BS3_BEGIN_TEXT16_NOT_FIRST
