Index: trunk/include/VBox/vmm/dbgf.h
===================================================================
--- trunk/include/VBox/vmm/dbgf.h	(revision 73459)
+++ trunk/include/VBox/vmm/dbgf.h	(revision 73460)
@@ -1209,79 +1209,4 @@
 #ifdef IN_RING3 /* The stack API only works in ring-3. */
 
-/**
- * Return type.
- */
-typedef enum DBGFRETRUNTYPE
-{
-    /** The usual invalid 0 value. */
-    DBGFRETURNTYPE_INVALID = 0,
-    /** Near 16-bit return. */
-    DBGFRETURNTYPE_NEAR16,
-    /** Near 32-bit return. */
-    DBGFRETURNTYPE_NEAR32,
-    /** Near 64-bit return. */
-    DBGFRETURNTYPE_NEAR64,
-    /** Far 16:16 return. */
-    DBGFRETURNTYPE_FAR16,
-    /** Far 16:32 return. */
-    DBGFRETURNTYPE_FAR32,
-    /** Far 16:64 return. */
-    DBGFRETURNTYPE_FAR64,
-    /** 16-bit iret return (e.g. real or 286 protect mode). */
-    DBGFRETURNTYPE_IRET16,
-    /** 32-bit iret return. */
-    DBGFRETURNTYPE_IRET32,
-    /** 32-bit iret return. */
-    DBGFRETURNTYPE_IRET32_PRIV,
-    /** 32-bit iret return to V86 mode. */
-    DBGFRETURNTYPE_IRET32_V86,
-    /** @todo 64-bit iret return. */
-    DBGFRETURNTYPE_IRET64,
-    /** The end of the valid return types. */
-    DBGFRETURNTYPE_END,
-    /** The usual 32-bit blowup. */
-    DBGFRETURNTYPE_32BIT_HACK = 0x7fffffff
-} DBGFRETURNTYPE;
-
-/**
- * Figures the size of the return state on the stack.
- *
- * @returns number of bytes. 0 if invalid parameter.
- * @param   enmRetType  The type of return.
- */
-DECLINLINE(unsigned) DBGFReturnTypeSize(DBGFRETURNTYPE enmRetType)
-{
-    switch (enmRetType)
-    {
-        case DBGFRETURNTYPE_NEAR16:         return 2;
-        case DBGFRETURNTYPE_NEAR32:         return 4;
-        case DBGFRETURNTYPE_NEAR64:         return 8;
-        case DBGFRETURNTYPE_FAR16:          return 4;
-        case DBGFRETURNTYPE_FAR32:          return 4;
-        case DBGFRETURNTYPE_FAR64:          return 8;
-        case DBGFRETURNTYPE_IRET16:         return 6;
-        case DBGFRETURNTYPE_IRET32:         return 4*3;
-        case DBGFRETURNTYPE_IRET32_PRIV:    return 4*5;
-        case DBGFRETURNTYPE_IRET32_V86:     return 4*9;
-        case DBGFRETURNTYPE_IRET64:
-        default:
-            return 0;
-    }
-}
-
-/**
- * Check if near return.
- *
- * @returns true if near, false if far or iret.
- * @param   enmRetType  The type of return.
- */
-DECLINLINE(bool) DBGFReturnTypeIsNear(DBGFRETURNTYPE enmRetType)
-{
-    return enmRetType == DBGFRETURNTYPE_NEAR32
-        || enmRetType == DBGFRETURNTYPE_NEAR64
-        || enmRetType == DBGFRETURNTYPE_NEAR16;
-}
-
-
 /** Pointer to stack frame info. */
 typedef struct DBGFSTACKFRAME *PDBGFSTACKFRAME;
@@ -1295,5 +1220,5 @@
     /** Frame number. */
     uint32_t        iFrame;
-    /** Frame flags. */
+    /** Frame flags (DBGFSTACKFRAME_FLAGS_XXX). */
     uint32_t        fFlags;
     /** The stack address of the frame.
@@ -1311,9 +1236,9 @@
     DBGFADDRESS     AddrFrame;
     /** The way this frame returns to the next one. */
-    DBGFRETURNTYPE  enmReturnType;
+    RTDBGRETURNTYPE enmReturnType;
 
     /** The way the next frame returns.
      * Only valid when DBGFSTACKFRAME_FLAGS_UNWIND_INFO_RET is set. */
-    DBGFRETURNTYPE  enmReturnFrameReturnType;
+    RTDBGRETURNTYPE enmReturnFrameReturnType;
     /** The return frame address.
      * The off member is [e|r]bp and the Sel member is ss. */
@@ -1358,5 +1283,5 @@
 } DBGFSTACKFRAME;
 
-/** @name DBGFSTACKFRAME Flags.
+/** @name DBGFSTACKFRAME_FLAGS_XXX - DBGFSTACKFRAME Flags.
  * @{ */
 /** This is the last stack frame we can read.
@@ -1375,6 +1300,9 @@
 /** Real mode or V86 frame. */
 # define DBGFSTACKFRAME_FLAGS_REAL_V86          RT_BIT(7)
+/** Is a trap frame (NT term). */
+# define DBGFSTACKFRAME_FLAGS_TRAP_FRAME        RT_BIT(8)
+
 /** Used Odd/even heuristics for far/near return. */
-# define DBGFSTACKFRAME_FLAGS_USED_ODD_EVEN     RT_BIT(8)
+# define DBGFSTACKFRAME_FLAGS_USED_ODD_EVEN     RT_BIT(29)
 /** Set if we used unwind info to construct the frame. (Kind of internal.) */
 # define DBGFSTACKFRAME_FLAGS_USED_UNWIND_INFO  RT_BIT(30)
@@ -1404,5 +1332,5 @@
 VMMR3DECL(int)              DBGFR3StackWalkBeginEx(PUVM pUVM, VMCPUID idCpu, DBGFCODETYPE enmCodeType, PCDBGFADDRESS pAddrFrame,
                                                    PCDBGFADDRESS pAddrStack,PCDBGFADDRESS pAddrPC,
-                                                   DBGFRETURNTYPE enmReturnType, PCDBGFSTACKFRAME *ppFirstFrame);
+                                                   RTDBGRETURNTYPE enmReturnType, PCDBGFSTACKFRAME *ppFirstFrame);
 VMMR3DECL(PCDBGFSTACKFRAME) DBGFR3StackWalkNext(PCDBGFSTACKFRAME pCurrent);
 VMMR3DECL(void)             DBGFR3StackWalkEnd(PCDBGFSTACKFRAME pFirstFrame);
@@ -2124,4 +2052,6 @@
 
 
+#ifdef IN_RING3
+
 /**
  * Guest OS digger interface identifier.
@@ -2256,4 +2186,23 @@
      */
     DECLCALLBACKMEMBER(void *, pfnQueryInterface)(PUVM pUVM, void *pvData, DBGFOSINTERFACE enmIf);
+
+    /**
+     * Stack unwind assist callback.
+     *
+     * This is only called after pfnInit().
+     *
+     * @returns VBox status code (allocation error or something of  similar fatality).
+     * @param   pUVM            The user mode VM handle.
+     * @param   pvData          Pointer to the instance data.
+     * @param   idCpu           The CPU that's unwinding it's stack.
+     * @param   pFrame          The current frame. Okay to modify it a little.
+     * @param   pState          The unwind state.  Okay to modify it.
+     * @param   pInitialCtx     The initial register context.
+     * @param   hAs             The address space being used for the unwind.
+     * @param   puScratch       Scratch area (initialized to zero, no dtor).
+     */
+    DECLCALLBACKMEMBER(int, pfnStackUnwindAssist)(PUVM pUVM, void *pvData, VMCPUID idCpu, PDBGFSTACKFRAME pFrame,
+                                                  PRTDBGUNWINDSTATE pState, PCCPUMCTX pInitialCtx, RTDBGAS hAs,
+                                                  uint64_t *puScratch);
 
     /** Trailing magic (DBGFOSREG_MAGIC). */
@@ -2321,5 +2270,4 @@
 
 
-#ifdef IN_RING3
 
 /** @defgroup grp_dbgf_plug_in      The DBGF Plug-in Interface
Index: trunk/include/iprt/dbg.h
===================================================================
--- trunk/include/iprt/dbg.h	(revision 73459)
+++ trunk/include/iprt/dbg.h	(revision 73460)
@@ -107,4 +107,175 @@
 /** Pointer to a const debug module segment. */
 typedef RTDBGSEGMENT const *PCRTDBGSEGMENT;
+
+
+/**
+ * Return type.
+ */
+typedef enum RTDBGRETURNTYPE
+{
+    /** The usual invalid 0 value. */
+    RTDBGRETURNTYPE_INVALID = 0,
+    /** Near 16-bit return. */
+    RTDBGRETURNTYPE_NEAR16,
+    /** Near 32-bit return. */
+    RTDBGRETURNTYPE_NEAR32,
+    /** Near 64-bit return. */
+    RTDBGRETURNTYPE_NEAR64,
+    /** Far 16:16 return. */
+    RTDBGRETURNTYPE_FAR16,
+    /** Far 16:32 return. */
+    RTDBGRETURNTYPE_FAR32,
+    /** Far 16:64 return. */
+    RTDBGRETURNTYPE_FAR64,
+    /** 16-bit iret return (e.g. real or 286 protect mode). */
+    RTDBGRETURNTYPE_IRET16,
+    /** 32-bit iret return. */
+    RTDBGRETURNTYPE_IRET32,
+    /** 32-bit iret return. */
+    RTDBGRETURNTYPE_IRET32_PRIV,
+    /** 32-bit iret return to V86 mode. */
+    RTDBGRETURNTYPE_IRET32_V86,
+    /** @todo 64-bit iret return. */
+    RTDBGRETURNTYPE_IRET64,
+    /** The end of the valid return types. */
+    RTDBGRETURNTYPE_END,
+    /** The usual 32-bit blowup. */
+    RTDBGRETURNTYPE_32BIT_HACK = 0x7fffffff
+} RTDBGRETURNTYPE;
+
+/**
+ * Figures the size of the return state on the stack.
+ *
+ * @returns number of bytes. 0 if invalid parameter.
+ * @param   enmRetType  The type of return.
+ */
+DECLINLINE(unsigned) RTDbgReturnTypeSize(RTDBGRETURNTYPE enmRetType)
+{
+    switch (enmRetType)
+    {
+        case RTDBGRETURNTYPE_NEAR16:         return 2;
+        case RTDBGRETURNTYPE_NEAR32:         return 4;
+        case RTDBGRETURNTYPE_NEAR64:         return 8;
+        case RTDBGRETURNTYPE_FAR16:          return 4;
+        case RTDBGRETURNTYPE_FAR32:          return 4;
+        case RTDBGRETURNTYPE_FAR64:          return 8;
+        case RTDBGRETURNTYPE_IRET16:         return 6;
+        case RTDBGRETURNTYPE_IRET32:         return 4*3;
+        case RTDBGRETURNTYPE_IRET32_PRIV:    return 4*5;
+        case RTDBGRETURNTYPE_IRET32_V86:     return 4*9;
+        case RTDBGRETURNTYPE_IRET64:         return 5*8;
+
+        case RTDBGRETURNTYPE_INVALID:
+        case RTDBGRETURNTYPE_END:
+        case RTDBGRETURNTYPE_32BIT_HACK:
+            break;
+    }
+    return 0;
+}
+
+/**
+ * Check if near return.
+ *
+ * @returns true if near, false if far or iret.
+ * @param   enmRetType  The type of return.
+ */
+DECLINLINE(bool) RTDbgReturnTypeIsNear(RTDBGRETURNTYPE enmRetType)
+{
+    return enmRetType == RTDBGRETURNTYPE_NEAR32
+        || enmRetType == RTDBGRETURNTYPE_NEAR64
+        || enmRetType == RTDBGRETURNTYPE_NEAR16;
+}
+
+
+
+/** Magic value for RTDBGUNWINDSTATE::u32Magic (James Moody). */
+#define RTDBGUNWINDSTATE_MAGIC          UINT32_C(0x19250326)
+/** Magic value for RTDBGUNWINDSTATE::u32Magic after use. */
+#define RTDBGUNWINDSTATE_MAGIC_DEAD     UINT32_C(0x20101209)
+
+/**
+ * Unwind machine state.
+ */
+typedef struct RTDBGUNWINDSTATE
+{
+    /** Structure magic (RTDBGUNWINDSTATE_MAGIC) */
+    uint32_t            u32Magic;
+    /** The state architecture. */
+    RTLDRARCH           enmArch;
+
+    /** The program counter register.
+     * amd64/x86: RIP/EIP/IP
+     * sparc: PC
+     * arm32: PC / R15
+     */
+    uint64_t            uPc;
+
+    /** Return type. */
+    RTDBGRETURNTYPE     enmRetType;
+
+    /** Register state (see enmArch). */
+    union
+    {
+        /** RTLDRARCH_AMD64, RTLDRARCH_X86_32 and RTLDRARCH_X86_16. */
+        struct
+        {
+            /** General purpose registers indexed by X86_GREG_XXX. */
+            uint64_t    auRegs[16];
+            /** The frame address. */
+            RTFAR64     FrameAddr;
+            /** Set if we're in real or virtual 8086 mode. */
+            bool        fRealOrV86;
+            /** The flags register. */
+            uint64_t    uRFlags;
+            /** Trap error code. */
+            uint64_t    uErrCd;
+            /** Segment registers (indexed by X86_SREG_XXX). */
+            uint16_t    auSegs[6];
+
+            /** Bitmap tracking register we've loaded and which content can possibly be trusted. */
+            union
+            {
+                /** For effective clearing of the bits. */
+                uint32_t    fAll;
+                /** Detailed view. */
+                struct
+                {
+                    /** Bitmap indicating whether a GPR was loaded (parallel to auRegs). */
+                    uint16_t    fRegs;
+                    /** Bitmap indicating whether a segment register was loaded (parallel to auSegs). */
+                    uint8_t     fSegs;
+                    /** Set if uPc was loaded. */
+                    uint8_t     fPc : 1;
+                    /** Set if FrameAddr was loaded. */
+                    uint8_t     fFrameAddr : 1;
+                    /** Set if uRFlags was loaded. */
+                    uint8_t     fRFlags : 1;
+                    /** Set if uErrCd was loaded. */
+                    uint8_t     fErrCd : 1;
+                } s;
+            } Loaded;
+        } x86;
+
+        /** @todo add ARM and others as needed. */
+    } u;
+
+    /**
+     * Stack read callback.
+     *
+     * @returns IPRT status code.
+     * @param   pThis       Pointer to this structure.
+     * @param   uSp         The stack pointer address.
+     * @param   cbToRead    The number of bytes to read.
+     * @param   pvDst       Where to put the bytes we read.
+     */
+    DECLCALLBACKMEMBER(int, pfnReadStack)(struct RTDBGUNWINDSTATE *pThis, RTUINTPTR uSp, size_t cbToRead, void *pvDst);
+    /** User argument (usefule for pfnReadStack). */
+    void               *pvUser;
+
+} RTDBGUNWINDSTATE;
+/** Pointer to an unwind machine state. */
+typedef struct RTDBGUNWINDSTATE *PRTDBGUNWINDSTATE;
+/** Pointer to a const unwind machine state. */
+typedef struct RTDBGUNWINDSTATE const *PCRTDBGUNWINDSTATE;
 
 
