VirtualBox

Changeset 73460 in vbox for trunk/include


Ignore:
Timestamp:
Aug 2, 2018 9:06:59 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
124087
Message:

IPRT,DBGF,Diggers: Moved DBGFRETURNTYPE and the unwind state structure to IPRT (dbg.h) in prep for debug module interface and more. Added stack unwind assist callback for the OS diggers so they can identify special stack frames and supply more info via the sure-register-value array and frame flags. Identify and decode NT/AMD64 trap frames.

Location:
trunk/include
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/dbgf.h

    r73444 r73460  
    12091209#ifdef IN_RING3 /* The stack API only works in ring-3. */
    12101210
    1211 /**
    1212  * Return type.
    1213  */
    1214 typedef enum DBGFRETRUNTYPE
    1215 {
    1216     /** The usual invalid 0 value. */
    1217     DBGFRETURNTYPE_INVALID = 0,
    1218     /** Near 16-bit return. */
    1219     DBGFRETURNTYPE_NEAR16,
    1220     /** Near 32-bit return. */
    1221     DBGFRETURNTYPE_NEAR32,
    1222     /** Near 64-bit return. */
    1223     DBGFRETURNTYPE_NEAR64,
    1224     /** Far 16:16 return. */
    1225     DBGFRETURNTYPE_FAR16,
    1226     /** Far 16:32 return. */
    1227     DBGFRETURNTYPE_FAR32,
    1228     /** Far 16:64 return. */
    1229     DBGFRETURNTYPE_FAR64,
    1230     /** 16-bit iret return (e.g. real or 286 protect mode). */
    1231     DBGFRETURNTYPE_IRET16,
    1232     /** 32-bit iret return. */
    1233     DBGFRETURNTYPE_IRET32,
    1234     /** 32-bit iret return. */
    1235     DBGFRETURNTYPE_IRET32_PRIV,
    1236     /** 32-bit iret return to V86 mode. */
    1237     DBGFRETURNTYPE_IRET32_V86,
    1238     /** @todo 64-bit iret return. */
    1239     DBGFRETURNTYPE_IRET64,
    1240     /** The end of the valid return types. */
    1241     DBGFRETURNTYPE_END,
    1242     /** The usual 32-bit blowup. */
    1243     DBGFRETURNTYPE_32BIT_HACK = 0x7fffffff
    1244 } DBGFRETURNTYPE;
    1245 
    1246 /**
    1247  * Figures the size of the return state on the stack.
    1248  *
    1249  * @returns number of bytes. 0 if invalid parameter.
    1250  * @param   enmRetType  The type of return.
    1251  */
    1252 DECLINLINE(unsigned) DBGFReturnTypeSize(DBGFRETURNTYPE enmRetType)
    1253 {
    1254     switch (enmRetType)
    1255     {
    1256         case DBGFRETURNTYPE_NEAR16:         return 2;
    1257         case DBGFRETURNTYPE_NEAR32:         return 4;
    1258         case DBGFRETURNTYPE_NEAR64:         return 8;
    1259         case DBGFRETURNTYPE_FAR16:          return 4;
    1260         case DBGFRETURNTYPE_FAR32:          return 4;
    1261         case DBGFRETURNTYPE_FAR64:          return 8;
    1262         case DBGFRETURNTYPE_IRET16:         return 6;
    1263         case DBGFRETURNTYPE_IRET32:         return 4*3;
    1264         case DBGFRETURNTYPE_IRET32_PRIV:    return 4*5;
    1265         case DBGFRETURNTYPE_IRET32_V86:     return 4*9;
    1266         case DBGFRETURNTYPE_IRET64:
    1267         default:
    1268             return 0;
    1269     }
    1270 }
    1271 
    1272 /**
    1273  * Check if near return.
    1274  *
    1275  * @returns true if near, false if far or iret.
    1276  * @param   enmRetType  The type of return.
    1277  */
    1278 DECLINLINE(bool) DBGFReturnTypeIsNear(DBGFRETURNTYPE enmRetType)
    1279 {
    1280     return enmRetType == DBGFRETURNTYPE_NEAR32
    1281         || enmRetType == DBGFRETURNTYPE_NEAR64
    1282         || enmRetType == DBGFRETURNTYPE_NEAR16;
    1283 }
    1284 
    1285 
    12861211/** Pointer to stack frame info. */
    12871212typedef struct DBGFSTACKFRAME *PDBGFSTACKFRAME;
     
    12951220    /** Frame number. */
    12961221    uint32_t        iFrame;
    1297     /** Frame flags. */
     1222    /** Frame flags (DBGFSTACKFRAME_FLAGS_XXX). */
    12981223    uint32_t        fFlags;
    12991224    /** The stack address of the frame.
     
    13111236    DBGFADDRESS     AddrFrame;
    13121237    /** The way this frame returns to the next one. */
    1313     DBGFRETURNTYPE enmReturnType;
     1238    RTDBGRETURNTYPE enmReturnType;
    13141239
    13151240    /** The way the next frame returns.
    13161241     * Only valid when DBGFSTACKFRAME_FLAGS_UNWIND_INFO_RET is set. */
    1317     DBGFRETURNTYPE enmReturnFrameReturnType;
     1242    RTDBGRETURNTYPE enmReturnFrameReturnType;
    13181243    /** The return frame address.
    13191244     * The off member is [e|r]bp and the Sel member is ss. */
     
    13581283} DBGFSTACKFRAME;
    13591284
    1360 /** @name DBGFSTACKFRAME Flags.
     1285/** @name DBGFSTACKFRAME_FLAGS_XXX - DBGFSTACKFRAME Flags.
    13611286 * @{ */
    13621287/** This is the last stack frame we can read.
     
    13751300/** Real mode or V86 frame. */
    13761301# define DBGFSTACKFRAME_FLAGS_REAL_V86          RT_BIT(7)
     1302/** Is a trap frame (NT term). */
     1303# define DBGFSTACKFRAME_FLAGS_TRAP_FRAME        RT_BIT(8)
     1304
    13771305/** Used Odd/even heuristics for far/near return. */
    1378 # define DBGFSTACKFRAME_FLAGS_USED_ODD_EVEN     RT_BIT(8)
     1306# define DBGFSTACKFRAME_FLAGS_USED_ODD_EVEN     RT_BIT(29)
    13791307/** Set if we used unwind info to construct the frame. (Kind of internal.) */
    13801308# define DBGFSTACKFRAME_FLAGS_USED_UNWIND_INFO  RT_BIT(30)
     
    14041332VMMR3DECL(int)              DBGFR3StackWalkBeginEx(PUVM pUVM, VMCPUID idCpu, DBGFCODETYPE enmCodeType, PCDBGFADDRESS pAddrFrame,
    14051333                                                   PCDBGFADDRESS pAddrStack,PCDBGFADDRESS pAddrPC,
    1406                                                    DBGFRETURNTYPE enmReturnType, PCDBGFSTACKFRAME *ppFirstFrame);
     1334                                                   RTDBGRETURNTYPE enmReturnType, PCDBGFSTACKFRAME *ppFirstFrame);
    14071335VMMR3DECL(PCDBGFSTACKFRAME) DBGFR3StackWalkNext(PCDBGFSTACKFRAME pCurrent);
    14081336VMMR3DECL(void)             DBGFR3StackWalkEnd(PCDBGFSTACKFRAME pFirstFrame);
     
    21242052
    21252053
     2054#ifdef IN_RING3
     2055
    21262056/**
    21272057 * Guest OS digger interface identifier.
     
    22562186     */
    22572187    DECLCALLBACKMEMBER(void *, pfnQueryInterface)(PUVM pUVM, void *pvData, DBGFOSINTERFACE enmIf);
     2188
     2189    /**
     2190     * Stack unwind assist callback.
     2191     *
     2192     * This is only called after pfnInit().
     2193     *
     2194     * @returns VBox status code (allocation error or something of  similar fatality).
     2195     * @param   pUVM            The user mode VM handle.
     2196     * @param   pvData          Pointer to the instance data.
     2197     * @param   idCpu           The CPU that's unwinding it's stack.
     2198     * @param   pFrame          The current frame. Okay to modify it a little.
     2199     * @param   pState          The unwind state.  Okay to modify it.
     2200     * @param   pInitialCtx     The initial register context.
     2201     * @param   hAs             The address space being used for the unwind.
     2202     * @param   puScratch       Scratch area (initialized to zero, no dtor).
     2203     */
     2204    DECLCALLBACKMEMBER(int, pfnStackUnwindAssist)(PUVM pUVM, void *pvData, VMCPUID idCpu, PDBGFSTACKFRAME pFrame,
     2205                                                  PRTDBGUNWINDSTATE pState, PCCPUMCTX pInitialCtx, RTDBGAS hAs,
     2206                                                  uint64_t *puScratch);
    22582207
    22592208    /** Trailing magic (DBGFOSREG_MAGIC). */
     
    23212270
    23222271
    2323 #ifdef IN_RING3
    23242272
    23252273/** @defgroup grp_dbgf_plug_in      The DBGF Plug-in Interface
  • trunk/include/iprt/dbg.h

    r73375 r73460  
    107107/** Pointer to a const debug module segment. */
    108108typedef RTDBGSEGMENT const *PCRTDBGSEGMENT;
     109
     110
     111/**
     112 * Return type.
     113 */
     114typedef enum RTDBGRETURNTYPE
     115{
     116    /** The usual invalid 0 value. */
     117    RTDBGRETURNTYPE_INVALID = 0,
     118    /** Near 16-bit return. */
     119    RTDBGRETURNTYPE_NEAR16,
     120    /** Near 32-bit return. */
     121    RTDBGRETURNTYPE_NEAR32,
     122    /** Near 64-bit return. */
     123    RTDBGRETURNTYPE_NEAR64,
     124    /** Far 16:16 return. */
     125    RTDBGRETURNTYPE_FAR16,
     126    /** Far 16:32 return. */
     127    RTDBGRETURNTYPE_FAR32,
     128    /** Far 16:64 return. */
     129    RTDBGRETURNTYPE_FAR64,
     130    /** 16-bit iret return (e.g. real or 286 protect mode). */
     131    RTDBGRETURNTYPE_IRET16,
     132    /** 32-bit iret return. */
     133    RTDBGRETURNTYPE_IRET32,
     134    /** 32-bit iret return. */
     135    RTDBGRETURNTYPE_IRET32_PRIV,
     136    /** 32-bit iret return to V86 mode. */
     137    RTDBGRETURNTYPE_IRET32_V86,
     138    /** @todo 64-bit iret return. */
     139    RTDBGRETURNTYPE_IRET64,
     140    /** The end of the valid return types. */
     141    RTDBGRETURNTYPE_END,
     142    /** The usual 32-bit blowup. */
     143    RTDBGRETURNTYPE_32BIT_HACK = 0x7fffffff
     144} RTDBGRETURNTYPE;
     145
     146/**
     147 * Figures the size of the return state on the stack.
     148 *
     149 * @returns number of bytes. 0 if invalid parameter.
     150 * @param   enmRetType  The type of return.
     151 */
     152DECLINLINE(unsigned) RTDbgReturnTypeSize(RTDBGRETURNTYPE enmRetType)
     153{
     154    switch (enmRetType)
     155    {
     156        case RTDBGRETURNTYPE_NEAR16:         return 2;
     157        case RTDBGRETURNTYPE_NEAR32:         return 4;
     158        case RTDBGRETURNTYPE_NEAR64:         return 8;
     159        case RTDBGRETURNTYPE_FAR16:          return 4;
     160        case RTDBGRETURNTYPE_FAR32:          return 4;
     161        case RTDBGRETURNTYPE_FAR64:          return 8;
     162        case RTDBGRETURNTYPE_IRET16:         return 6;
     163        case RTDBGRETURNTYPE_IRET32:         return 4*3;
     164        case RTDBGRETURNTYPE_IRET32_PRIV:    return 4*5;
     165        case RTDBGRETURNTYPE_IRET32_V86:     return 4*9;
     166        case RTDBGRETURNTYPE_IRET64:         return 5*8;
     167
     168        case RTDBGRETURNTYPE_INVALID:
     169        case RTDBGRETURNTYPE_END:
     170        case RTDBGRETURNTYPE_32BIT_HACK:
     171            break;
     172    }
     173    return 0;
     174}
     175
     176/**
     177 * Check if near return.
     178 *
     179 * @returns true if near, false if far or iret.
     180 * @param   enmRetType  The type of return.
     181 */
     182DECLINLINE(bool) RTDbgReturnTypeIsNear(RTDBGRETURNTYPE enmRetType)
     183{
     184    return enmRetType == RTDBGRETURNTYPE_NEAR32
     185        || enmRetType == RTDBGRETURNTYPE_NEAR64
     186        || enmRetType == RTDBGRETURNTYPE_NEAR16;
     187}
     188
     189
     190
     191/** Magic value for RTDBGUNWINDSTATE::u32Magic (James Moody). */
     192#define RTDBGUNWINDSTATE_MAGIC          UINT32_C(0x19250326)
     193/** Magic value for RTDBGUNWINDSTATE::u32Magic after use. */
     194#define RTDBGUNWINDSTATE_MAGIC_DEAD     UINT32_C(0x20101209)
     195
     196/**
     197 * Unwind machine state.
     198 */
     199typedef struct RTDBGUNWINDSTATE
     200{
     201    /** Structure magic (RTDBGUNWINDSTATE_MAGIC) */
     202    uint32_t            u32Magic;
     203    /** The state architecture. */
     204    RTLDRARCH           enmArch;
     205
     206    /** The program counter register.
     207     * amd64/x86: RIP/EIP/IP
     208     * sparc: PC
     209     * arm32: PC / R15
     210     */
     211    uint64_t            uPc;
     212
     213    /** Return type. */
     214    RTDBGRETURNTYPE     enmRetType;
     215
     216    /** Register state (see enmArch). */
     217    union
     218    {
     219        /** RTLDRARCH_AMD64, RTLDRARCH_X86_32 and RTLDRARCH_X86_16. */
     220        struct
     221        {
     222            /** General purpose registers indexed by X86_GREG_XXX. */
     223            uint64_t    auRegs[16];
     224            /** The frame address. */
     225            RTFAR64     FrameAddr;
     226            /** Set if we're in real or virtual 8086 mode. */
     227            bool        fRealOrV86;
     228            /** The flags register. */
     229            uint64_t    uRFlags;
     230            /** Trap error code. */
     231            uint64_t    uErrCd;
     232            /** Segment registers (indexed by X86_SREG_XXX). */
     233            uint16_t    auSegs[6];
     234
     235            /** Bitmap tracking register we've loaded and which content can possibly be trusted. */
     236            union
     237            {
     238                /** For effective clearing of the bits. */
     239                uint32_t    fAll;
     240                /** Detailed view. */
     241                struct
     242                {
     243                    /** Bitmap indicating whether a GPR was loaded (parallel to auRegs). */
     244                    uint16_t    fRegs;
     245                    /** Bitmap indicating whether a segment register was loaded (parallel to auSegs). */
     246                    uint8_t     fSegs;
     247                    /** Set if uPc was loaded. */
     248                    uint8_t     fPc : 1;
     249                    /** Set if FrameAddr was loaded. */
     250                    uint8_t     fFrameAddr : 1;
     251                    /** Set if uRFlags was loaded. */
     252                    uint8_t     fRFlags : 1;
     253                    /** Set if uErrCd was loaded. */
     254                    uint8_t     fErrCd : 1;
     255                } s;
     256            } Loaded;
     257        } x86;
     258
     259        /** @todo add ARM and others as needed. */
     260    } u;
     261
     262    /**
     263     * Stack read callback.
     264     *
     265     * @returns IPRT status code.
     266     * @param   pThis       Pointer to this structure.
     267     * @param   uSp         The stack pointer address.
     268     * @param   cbToRead    The number of bytes to read.
     269     * @param   pvDst       Where to put the bytes we read.
     270     */
     271    DECLCALLBACKMEMBER(int, pfnReadStack)(struct RTDBGUNWINDSTATE *pThis, RTUINTPTR uSp, size_t cbToRead, void *pvDst);
     272    /** User argument (usefule for pfnReadStack). */
     273    void               *pvUser;
     274
     275} RTDBGUNWINDSTATE;
     276/** Pointer to an unwind machine state. */
     277typedef struct RTDBGUNWINDSTATE *PRTDBGUNWINDSTATE;
     278/** Pointer to a const unwind machine state. */
     279typedef struct RTDBGUNWINDSTATE const *PCRTDBGUNWINDSTATE;
    109280
    110281
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette