VirtualBox

Changeset 105536 in vbox


Ignore:
Timestamp:
Jul 30, 2024 1:08:28 AM (4 months ago)
Author:
vboxsync
Message:

VBoxDbg: Added a ntrbtree command for dumping the red-black trees in Windows 8 and later. bugref:10727

Location:
trunk/src/VBox/Debugger
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Debugger/DBGCCommands.cpp

    r103433 r105536  
    6464static FNDBGCCMD dbgcCmdDetect;
    6565static FNDBGCCMD dbgcCmdDmesg;
    66 extern FNDBGCCMD dbgcCmdDumpImage;
    6766static FNDBGCCMD dbgcCmdCpu;
    6867static FNDBGCCMD dbgcCmdInfo;
     
    137136{
    138137    /* cTimesMin,   cTimesMax,  enmCategory,            fFlags,                         pszName,        pszDescription */
     138    {  0,           ~0U,        DBGCVAR_CAT_OPTION_STRING, 0,                           "options",      "Options." },
    139139    {  1,           ~0U,        DBGCVAR_CAT_POINTER,    0,                              "address",      "Address of image to dump." },
    140140};
     
    231231};
    232232
     233/** ntrbtree arguments. */
     234static const DBGCVARDESC    g_aArgNtRbTree[] =
     235{
     236    /* cTimesMin,   cTimesMax,  enmCategory,            fFlags,                         pszName,        pszDescription */
     237    {  1,           1,          DBGCVAR_CAT_GC_POINTER, 0,                              "rootaddr",     "The address of _RTL_RB_TREE" },
     238};
    233239
    234240/** loadplugin, unloadplugin. */
     
    327333    { "logflags",   0,        1,        &g_aArgLogFlags[0],  RT_ELEMENTS(g_aArgLogFlags),  0, dbgcCmdLogFlags,  "[flags string]",       "Displays or modifies the logging flags (VBOX_LOG_FLAGS)." },
    328334    { "logflush",   0,        0,        NULL,                0,                            0, dbgcCmdLogFlush,  "",                     "Flushes the log buffers." },
    329     { "multistep",  0,        2,        &g_aArgMultiStep[0], RT_ELEMENTS(g_aArgMultiStep), 0, dbgcCmdMultiStep, "[count [stride]",              "Performs the specified number of step-into operations. Stops early if non-step event occurs." },
     335    { "multistep",  0,        2,        &g_aArgMultiStep[0], RT_ELEMENTS(g_aArgMultiStep), 0, dbgcCmdMultiStep, "[count [stride]",      "Performs the specified number of step-into operations. Stops early if non-step event occurs." },
     336    { "ntrbtree",   1,        1,        &g_aArgNtRbTree[0],  RT_ELEMENTS(g_aArgNtRbTree),  0, dbgcCmdNtRbTree,  "<rb-tree-address>",    "Windows: Dumps a red-black tree." },
    330337    { "quit",       0,        0,        NULL,                0,                            0, dbgcCmdQuit,      "",                     "Exits the debugger." },
    331338    { "runscript",  1,        1,        &g_aArgFilename[0],  RT_ELEMENTS(g_aArgFilename),  0, dbgcCmdRunScript, "<filename>",           "Runs the command listed in the script. Lines starting with '#' "
  • trunk/src/VBox/Debugger/DBGCDumpImage.cpp

    r105531 r105536  
    9292
    9393
     94
    9495/*********************************************************************************************************************************
    95 *   Internal Functions                                                                                                           *
     96*   DebugImageCmd                                                                                                                *
    9697*********************************************************************************************************************************/
    97 #ifndef DBGC_DUMP_IMAGE_TOOL
    98 extern FNDBGCCMD dbgcCmdDumpImage; /* See DBGCCommands.cpp. */
    99 #endif
    100 
    101 
    102 /** Stringifies a 32-bit flag value. */
    103 static void dbgcDumpImageFlags32(PDBGCCMDHLP pCmdHlp, uint32_t fFlags, DBGCDUMPFLAGENTRY const *paEntries, size_t cEntries)
    104 {
    105     for (size_t i = 0; i < cEntries; i++)
    106         if (fFlags & paEntries[i].fFlag)
    107             DBGCCmdHlpPrintf(pCmdHlp, " %s", paEntries[i].pszNm);
    108 }
    109 
    110 
    111 /**
    112  * Early read function.
    113  *
    114  * @todo refactor/abstract this somehow...
    115  */
    116 static int dumpReadAt(PDBGCCMDHLP pCmdHlp, PCDBGCCMD pCmd, PCDBGCVAR pImageBase, const char *pszName,
    117                       size_t off, void *pvDst, size_t cbToRead, size_t *pcbRead)
    118 {
    119     RT_BZERO(pvDst, cbToRead);
    120     if (pcbRead)
    121         *pcbRead = 0;
    122 
    123 #ifndef DBGC_DUMP_IMAGE_TOOL
    124     DBGCVAR AddrToReadAt;
    125     int rc = DBGCCmdHlpEval(pCmdHlp, &AddrToReadAt, "%DV + %#zx", pImageBase, off);
    126     if (RT_SUCCESS(rc))
    127     {
    128         rc = DBGCCmdHlpMemRead(pCmdHlp, pvDst, cbToRead, &AddrToReadAt, pcbRead);
    129         if (RT_SUCCESS(rc))
    130             return VINF_SUCCESS;
    131         return DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc, "%s: Failed to read %zu bytes at offset %Dv", pszName, cbToRead, &AddrToReadAt);
    132     }
    133     return DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc, "%s: Failed to calculate address %Dv + #%zx for %#zx byte read",
    134                             pszName, pImageBase, off, cbToRead);
    135 
    136 #else  /* DBGC_DUMP_IMAGE_TOOL */
    137     CMDHLPSTATE * const pToolState = RT_FROM_MEMBER(pCmdHlp, CMDHLPSTATE, Core);
    138     int rc = RTVfsFileReadAt(pToolState->hVfsFile, off, pvDst, cbToRead, pcbRead);
    139     if (RT_SUCCESS(rc))
    140         return VINF_SUCCESS;
    141     RT_NOREF(pImageBase);
    142     return DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc, "%s: Failed to read %zu bytes at offset %#zx", pszName, cbToRead, off);
    143 #endif /* DBGC_DUMP_IMAGE_TOOL */
    144 }
    145 
    146 
    147 /*********************************************************************************************************************************
    148 *   DumpImageBase                                                                                                                *
    149 *********************************************************************************************************************************/
    150 class DumpImageBase
     98
     99#define DUMPIMAGE_SELECT_HEADERS     RT_BIT_64(0)
     100#define DUMPIMAGE_SELECT_SECTIONS    RT_BIT_64(1)
     101#define DUMPIMAGE_SELECT_EXPORTS     RT_BIT_64(2)
     102#define DUMPIMAGE_SELECT_IMPORTS     RT_BIT_64(3)
     103#define DUMPIMAGE_SELECT_TLS         RT_BIT_64(4)
     104#define DUMPIMAGE_SELECT_LOAD_CONFIG RT_BIT_64(5)
     105#define DUMPIMAGE_SELECT_RESOURCES   RT_BIT_64(6)
     106#define DUMPIMAGE_SELECT_FIXUP       RT_BIT_64(7)
     107#define DUMPIMAGE_SELECT_DEBUG       RT_BIT_64(8)
     108#define DUMPIMAGE_SELECT_EVERYTHING  UINT64_MAX
     109#define DUMPIMAGE_SELECT_DEFAULT     DUMPIMAGE_SELECT_EVERYTHING
     110
     111class DumpImageCmd
    151112{
    152113public:
    153     /** The name of what's being dumped (for error messages). */
    154     const char * const  m_pszName;
    155     /** Pointer to the image base address variable. */
    156     PCDBGCVAR const     m_pImageBase;
    157114    /** Pointer to the command helpers. */
    158115    PDBGCCMDHLP const   m_pCmdHlp;
    159116    /** The command descriptor (for failing the command). */
    160117    PCDBGCCMD const     m_pCmd;
     118    /** The command exit code. */
     119    RTEXITCODE          m_rcExit;
     120    /** The first failure code.   */
     121    int                 m_rc;
     122
     123    /** Current number of targets. */
     124    unsigned            m_cTargets;
     125    /** The name of what's being dumped (for error messages). */
     126    const char         *m_pszName;
     127#ifndef DBGC_DUMP_IMAGE_TOOL
     128    /** Debugger: Pointer to the image base address variable. */
     129    PCDBGCVAR           m_pImageBase;
     130#else
     131    /** Command line tool: The file we're dumping. */
     132    RTVFSFILE           m_hVfsFile;
     133#endif
     134
     135public:
     136    /** What to dump (DUMPIMAGE_SELECT_XXX). */
     137    uint64_t            m_fSelection;
     138
     139private:
     140    DumpImageCmd();
     141
     142public:
     143    DumpImageCmd(PDBGCCMDHLP a_pCmdHlp, PCDBGCCMD a_pCmd)
     144        : m_pCmdHlp(a_pCmdHlp)
     145        , m_pCmd(a_pCmd)
     146        , m_rcExit(RTEXITCODE_SUCCESS)
     147        , m_rc(VINF_SUCCESS)
     148        , m_cTargets(0)
     149        , m_pszName(NULL)
     150#ifndef DBGC_DUMP_IMAGE_TOOL
     151        , m_pImageBase(NULL)
     152#else
     153        , m_hVfsFile(NIL_RTVFSFILE)
     154#endif
     155        , m_fSelection(DUMPIMAGE_SELECT_DEFAULT)
     156    {
     157    }
     158
     159    ~DumpImageCmd()
     160    {
     161        clearTarget();
     162    }
     163
     164    /** @name Methods not requiring any target.
     165     * @{ */
     166
     167    void myPrintfV(const char *pszFormat, va_list va) const RT_NOEXCEPT
     168    {
     169#ifndef DBGC_DUMP_IMAGE_TOOL
     170        m_pCmdHlp->pfnPrintfV(m_pCmdHlp, NULL, pszFormat, va);
     171#else
     172        RTPrintfV(pszFormat, va);
     173#endif
     174    }
     175
     176    void myPrintf(const char *pszFormat, ...) const RT_NOEXCEPT
     177    {
     178        va_list va;
     179        va_start(va, pszFormat);
     180#ifndef DBGC_DUMP_IMAGE_TOOL
     181        m_pCmdHlp->pfnPrintfV(m_pCmdHlp, NULL, pszFormat, va);
     182#else
     183        RTPrintfV(pszFormat, va);
     184#endif
     185        va_end(va);
     186    }
     187
     188    int myErrorV(const char *pszFormat, va_list va) RT_NOEXCEPT
     189    {
     190        int rc;
     191        if (m_pszName)
     192        {
     193            va_list vaCopy;
     194            va_copy(vaCopy, va);
     195#ifndef DBGC_DUMP_IMAGE_TOOL
     196            rc = DBGCCmdHlpFail(m_pCmdHlp, m_pCmd, "%s: %N", m_pszName, pszFormat, &vaCopy);
     197#else
     198            RTMsgError("%s: %N", m_pszName, pszFormat, &vaCopy);
     199#endif
     200            va_end(va);
     201        }
     202        else
     203#ifndef DBGC_DUMP_IMAGE_TOOL
     204            rc = m_pCmdHlp->pfnFailV(m_pCmdHlp, m_pCmd, pszFormat, va);
     205#else
     206            RTMsgErrorV(pszFormat, va);
     207        rc = VERR_GENERAL_FAILURE;
     208#endif
     209
     210        m_rcExit = RTEXITCODE_FAILURE;
     211        if (m_rc == VINF_SUCCESS)
     212            m_rc = rc;
     213        return rc;
     214    }
     215
     216    int myError(const char *pszFormat, ...) RT_NOEXCEPT
     217    {
     218        va_list va;
     219        va_start(va, pszFormat);
     220        int rc = myErrorV(pszFormat, va);
     221        va_end(va);
     222        return rc;
     223    }
     224
     225    int myErrorV(int rc, const char *pszFormat, va_list va) RT_NOEXCEPT
     226    {
     227        if (m_pszName)
     228        {
     229            va_list vaCopy;
     230            va_copy(vaCopy, va);
     231#ifndef DBGC_DUMP_IMAGE_TOOL
     232            rc = DBGCCmdHlpFailRc(m_pCmdHlp, m_pCmd, rc, "%s: %N", m_pszName, pszFormat, &vaCopy);
     233#else
     234            RTMsgError("%s: %N: %Rrc", m_pszName, pszFormat, &vaCopy, rc);
     235#endif
     236            va_end(vaCopy);
     237        }
     238        else
     239        {
     240#ifndef DBGC_DUMP_IMAGE_TOOL
     241            rc = m_pCmdHlp->pfnFailRcV(m_pCmdHlp, m_pCmd, rc, pszFormat, va);
     242#else
     243            va_list vaCopy;
     244            va_copy(vaCopy, va);
     245            RTMsgError("%N: %Rrc", pszFormat, &vaCopy, rc);
     246            va_end(vaCopy);
     247#endif
     248        }
     249
     250        m_rcExit = RTEXITCODE_FAILURE;
     251        if (m_rc == VINF_SUCCESS)
     252            m_rc = rc;
     253        return rc;
     254    }
     255
     256    int myError(int rc, const char *pszFormat, ...) RT_NOEXCEPT
     257    {
     258        va_list va;
     259        va_start(va, pszFormat);
     260        rc = myErrorV(rc, pszFormat, va);
     261        va_end(va);
     262        return rc;
     263    }
     264
     265    int mySyntax(const char *pszFormat, ...) RT_NOEXCEPT
     266    {
     267        m_rcExit = RTEXITCODE_SYNTAX;
     268        va_list va;
     269        va_start(va, pszFormat);
     270#ifndef DBGC_DUMP_IMAGE_TOOL
     271        int rc = DBGCCmdHlpFail(m_pCmdHlp, m_pCmd, "syntax: %N", pszFormat, &va);
     272#else
     273        RTMsgSyntaxV(pszFormat, va);
     274        int const rc = VERR_GENERAL_FAILURE;
     275#endif
     276        va_end(va);
     277
     278        m_rcExit = RTEXITCODE_SYNTAX;
     279        if (m_rc == VINF_SUCCESS)
     280            m_rc = rc;
     281        return rc;
     282    }
     283
     284    void setFailure(int rc) RT_NOEXCEPT
     285    {
     286        m_rcExit = RTEXITCODE_FAILURE;
     287        if (m_rc == VINF_SUCCESS)
     288            m_rc = rc;
     289    }
     290
     291    RTEXITCODE getExitCode() const RT_NOEXCEPT
     292    {
     293        return m_rcExit;
     294    }
     295
     296    int getStatus() const RT_NOEXCEPT
     297    {
     298        return m_rc;
     299    }
     300
     301private:
     302    int parseSelection(const char *pszSelection, uint64_t *pfSel)
     303    {
     304        static const struct { const char *psz; size_t cch; uint64_t fSel; } s_aMnemonics[] =
     305        {
     306            { RT_STR_TUPLE("h"),            DUMPIMAGE_SELECT_HEADERS     },
     307            { RT_STR_TUPLE("hd"),           DUMPIMAGE_SELECT_HEADERS     },
     308            { RT_STR_TUPLE("hdr"),          DUMPIMAGE_SELECT_HEADERS     },
     309            { RT_STR_TUPLE("header"),       DUMPIMAGE_SELECT_HEADERS     },
     310            { RT_STR_TUPLE("headers"),      DUMPIMAGE_SELECT_HEADERS     },
     311            { RT_STR_TUPLE("s"),            DUMPIMAGE_SELECT_SECTIONS    },
     312            { RT_STR_TUPLE("se"),           DUMPIMAGE_SELECT_SECTIONS    },
     313            { RT_STR_TUPLE("sec"),          DUMPIMAGE_SELECT_SECTIONS    },
     314            { RT_STR_TUPLE("section"),      DUMPIMAGE_SELECT_SECTIONS    },
     315            { RT_STR_TUPLE("sections"),     DUMPIMAGE_SELECT_SECTIONS    },
     316            { RT_STR_TUPLE("d"),            DUMPIMAGE_SELECT_DEBUG       },
     317            { RT_STR_TUPLE("db"),           DUMPIMAGE_SELECT_DEBUG       },
     318            { RT_STR_TUPLE("dg"),           DUMPIMAGE_SELECT_DEBUG       },
     319            { RT_STR_TUPLE("dbg"),          DUMPIMAGE_SELECT_DEBUG       },
     320            { RT_STR_TUPLE("dbginfo"),      DUMPIMAGE_SELECT_DEBUG       },
     321            { RT_STR_TUPLE("debug"),        DUMPIMAGE_SELECT_DEBUG       },
     322            { RT_STR_TUPLE("f"),            DUMPIMAGE_SELECT_FIXUP       },
     323            { RT_STR_TUPLE("fx"),           DUMPIMAGE_SELECT_FIXUP       },
     324            { RT_STR_TUPLE("fix"),          DUMPIMAGE_SELECT_FIXUP       },
     325            { RT_STR_TUPLE("fixup"),        DUMPIMAGE_SELECT_FIXUP       },
     326            { RT_STR_TUPLE("fixups"),       DUMPIMAGE_SELECT_FIXUP       },
     327            { RT_STR_TUPLE("e"),            DUMPIMAGE_SELECT_EXPORTS     },
     328            { RT_STR_TUPLE("ex"),           DUMPIMAGE_SELECT_EXPORTS     },
     329            { RT_STR_TUPLE("exp"),          DUMPIMAGE_SELECT_EXPORTS     },
     330            { RT_STR_TUPLE("export"),       DUMPIMAGE_SELECT_EXPORTS     },
     331            { RT_STR_TUPLE("exports"),      DUMPIMAGE_SELECT_EXPORTS     },
     332            { RT_STR_TUPLE("i"),            DUMPIMAGE_SELECT_IMPORTS     },
     333            { RT_STR_TUPLE("im"),           DUMPIMAGE_SELECT_IMPORTS     },
     334            { RT_STR_TUPLE("imp"),          DUMPIMAGE_SELECT_IMPORTS     },
     335            { RT_STR_TUPLE("import"),       DUMPIMAGE_SELECT_IMPORTS     },
     336            { RT_STR_TUPLE("imports"),      DUMPIMAGE_SELECT_IMPORTS     },
     337            { RT_STR_TUPLE("l"),            DUMPIMAGE_SELECT_LOAD_CONFIG },
     338            { RT_STR_TUPLE("lc"),           DUMPIMAGE_SELECT_LOAD_CONFIG },
     339            { RT_STR_TUPLE("lcfg"),         DUMPIMAGE_SELECT_LOAD_CONFIG },
     340            { RT_STR_TUPLE("loadcfg"),      DUMPIMAGE_SELECT_LOAD_CONFIG },
     341            { RT_STR_TUPLE("rc"),           DUMPIMAGE_SELECT_RESOURCES   },
     342            { RT_STR_TUPLE("rcs"),          DUMPIMAGE_SELECT_RESOURCES   },
     343            { RT_STR_TUPLE("rcsrc"),        DUMPIMAGE_SELECT_RESOURCES   },
     344            { RT_STR_TUPLE("resource"),     DUMPIMAGE_SELECT_RESOURCES   },
     345            { RT_STR_TUPLE("resources"),    DUMPIMAGE_SELECT_RESOURCES   },
     346            { RT_STR_TUPLE("t"),            DUMPIMAGE_SELECT_TLS         },
     347            { RT_STR_TUPLE("tls"),          DUMPIMAGE_SELECT_TLS         },
     348            /* masks: */
     349            { RT_STR_TUPLE("all"),          DUMPIMAGE_SELECT_EVERYTHING  },
     350            { RT_STR_TUPLE("everything"),   DUMPIMAGE_SELECT_EVERYTHING  },
     351            { RT_STR_TUPLE("def"),          DUMPIMAGE_SELECT_DEFAULT     },
     352            { RT_STR_TUPLE("default"),      DUMPIMAGE_SELECT_DEFAULT     },
     353        };
     354
     355        *pfSel = 0;
     356        char ch;
     357        do
     358        {
     359            /* Skip leading spaces and commas. */
     360            while ((ch = *pszSelection) != '\0' && (RT_C_IS_BLANK(ch) || ch == ','))
     361                pszSelection++;
     362
     363            /* Find the end of the selection mnemonic. */
     364            size_t cch = 0;
     365            while (ch != '\0' && ch != ',' && !RT_C_IS_BLANK(ch))
     366                ch = pszSelection[++cch];
     367            if (!cch)
     368            {
     369                if (*pfSel)
     370                    break;
     371                mySyntax("No selection");
     372                return VERR_INVALID_PARAMETER;
     373            }
     374
     375            /* Look it up. */
     376            uint32_t i;
     377            for (i = 0; i < RT_ELEMENTS(s_aMnemonics); i++)
     378                if (cch == s_aMnemonics[i].cch && memcmp(s_aMnemonics[i].psz, pszSelection, cch) == 0)
     379                {
     380                    *pfSel = s_aMnemonics[i].fSel;
     381                    break;
     382                }
     383            if (i >= RT_ELEMENTS(s_aMnemonics))
     384            {
     385                mySyntax("Unknown selection '%.*s'", cch, pszSelection);
     386                return VERR_INVALID_PARAMETER;
     387            }
     388        } while (ch != '\0');
     389        return VINF_SUCCESS;
     390    }
     391
     392public:
     393    int optSelectionInclude(const char *pszSelection) RT_NOEXCEPT
     394    {
     395        uint64_t fSel = 0;
     396        int rc = parseSelection(pszSelection, &fSel);
     397        if (RT_SUCCESS(rc))
     398            m_fSelection |= fSel;
     399        return rc;
     400    }
     401
     402    int optSelectionOnly(const char *pszSelection) RT_NOEXCEPT
     403    {
     404        uint64_t fSel = 0;
     405        int rc = parseSelection(pszSelection, &fSel);
     406        if (RT_SUCCESS(rc))
     407        {
     408            if (m_fSelection == DUMPIMAGE_SELECT_DEFAULT)
     409                m_fSelection = 0;
     410            m_fSelection |= fSel;
     411        }
     412        return rc;
     413    }
     414
     415    int optSelectionSkip(const char *pszSelection) RT_NOEXCEPT
     416    {
     417        uint64_t fSel = 0;
     418        int rc = parseSelection(pszSelection, &fSel);
     419        if (RT_SUCCESS(rc))
     420            m_fSelection &= ~fSel;
     421        return rc;
     422
     423    }
     424
     425    /** @} */
     426
     427
     428    /** @name Methods working on a target.
     429     * @{ */
     430
     431#ifndef DBGC_DUMP_IMAGE_TOOL
     432    void setTarget(const char *a_pszName, PCDBGCVAR a_pImageBase) RT_NOEXCEPT
     433#else
     434    void setTarget(const char *a_pszName, RTVFSFILE a_hVfsFile) RT_NOEXCEPT
     435#endif
     436    {
     437        m_cTargets  += 1;
     438        m_pszName    = a_pszName;
     439#ifndef DBGC_DUMP_IMAGE_TOOL
     440        m_pImageBase = a_pImageBase;
     441#else
     442        m_hVfsFile   = a_hVfsFile;
     443#endif
     444    }
     445
     446    void clearTarget() RT_NOEXCEPT
     447    {
     448        m_pszName    = NULL;
     449#ifndef DBGC_DUMP_IMAGE_TOOL
     450        m_pImageBase = NULL;
     451#else
     452        RTVfsFileRelease(m_hVfsFile);
     453        m_hVfsFile = NIL_RTVFSFILE;
     454#endif
     455    }
     456
     457    bool isFirstTarget() const RT_NOEXCEPT
     458    {
     459        return m_cTargets == 1;
     460    }
     461
     462    /**
     463     * Early read function.
     464     *
     465     * This kind of works on file offsets, though we all knows that it really
     466     * depends on whether the stuff being dumped is in-memory or a file.  However,
     467     * in the latter case we do not have the ability to do any RVA translation, thus
     468     * the input is treated as file offsets.
     469     */
     470    int readAt(size_t off, void *pvDst, size_t cbToRead, size_t *pcbRead) RT_NOEXCEPT
     471    {
     472        RT_BZERO(pvDst, cbToRead);
     473        if (pcbRead)
     474            *pcbRead = 0;
     475/** @todo introduce a buffer here? */
     476#ifndef DBGC_DUMP_IMAGE_TOOL
     477        DBGCVAR AddrToReadAt;
     478        int rc = DBGCCmdHlpEval(m_pCmdHlp, &AddrToReadAt, "%DV + %#zx", m_pImageBase, off);
     479        if (RT_SUCCESS(rc))
     480        {
     481            rc = DBGCCmdHlpMemRead(m_pCmdHlp, pvDst, cbToRead, &AddrToReadAt, pcbRead);
     482            if (RT_SUCCESS(rc))
     483                return VINF_SUCCESS;
     484            return myError(rc, "Failed to read %zu bytes at offset %Dv", cbToRead, &AddrToReadAt);
     485        }
     486        return myError(rc, "Failed to calculate address %Dv + #%zx for %#zx byte read", m_pImageBase, off, cbToRead);
     487
     488#else  /* DBGC_DUMP_IMAGE_TOOL */
     489        int rc = RTVfsFileReadAt(m_hVfsFile, off, pvDst, cbToRead, pcbRead);
     490        if (RT_SUCCESS(rc))
     491            return VINF_SUCCESS;
     492        return myError(rc, "Failed to read %zu bytes at offset %#zx", cbToRead, off);
     493#endif /* DBGC_DUMP_IMAGE_TOOL */
     494    }
     495
     496    int dumpImage(const char *pszImageBaseAddr) RT_NOEXCEPT;
     497
     498    /** @} */
     499};
     500
     501
     502/** Stringifies a 32-bit flag value. */
     503static void dbgcDumpImageFlags32(DumpImageCmd *pCmd, uint32_t fFlags, DBGCDUMPFLAGENTRY const *paEntries, size_t cEntries)
     504{
     505    for (size_t i = 0; i < cEntries; i++)
     506        if (fFlags & paEntries[i].fFlag)
     507            pCmd->myPrintf(" %s", paEntries[i].pszNm);
     508}
     509
     510
     511/*********************************************************************************************************************************
     512*   DumpImageBase                                                                                                                *
     513*********************************************************************************************************************************/
     514/**
     515 * Base class for the dumpers.
     516 */
     517class DumpImageBase
     518{
     519protected:
     520    DumpImageCmd       *m_pCmd;
    161521
    162522private:
     
    177537    DumpImageBase();
    178538
    179     void setupAddrFormatting(const char *a_pszImageBaseAddr)
     539    void setupAddrFormatting(const char *a_pszImageBaseAddr) RT_NOEXCEPT
    180540    {
    181541        /*
     
    210570
    211571public:
    212     DumpImageBase(PDBGCCMDHLP a_pCmdHlp, PCDBGCCMD a_pCmd, PCDBGCVAR a_pImageBase,
    213                   const char *a_pszImageBaseAddr, const char *a_pszName)
    214         : m_pszName(a_pszName)
    215         , m_pImageBase(a_pImageBase)
    216         , m_pCmdHlp(a_pCmdHlp)
    217         , m_pCmd(a_pCmd)
     572    DumpImageBase(DumpImageCmd *a_pCmd, const char *a_pszImageBaseAddr) RT_NOEXCEPT
     573        : m_pCmd(a_pCmd)
    218574        , m_uImageBaseAddr(0)
    219575        , m_cchAddr(0)
     
    227583    virtual ~DumpImageBase() { }
    228584
    229     virtual size_t rvaToFileOffset(size_t uRva) const = 0;
    230     virtual size_t getEndRva(bool a_fAligned = true) const = 0;
    231 
    232     char *rvaToStringWithAddr(size_t uRva, char *pszDst, size_t cbDst, bool fWide = false)
     585    virtual size_t rvaToFileOffset(size_t uRva) const RT_NOEXCEPT = 0;
     586    virtual size_t getEndRva(bool a_fAligned = true) const RT_NOEXCEPT = 0;
     587
     588    char *rvaToStringWithAddr(size_t uRva, char *pszDst, size_t cbDst, bool fWide = false) const RT_NOEXCEPT
    233589    {
    234590        if (!fWide)
     
    239595    }
    240596
    241     virtual void myPrintf(const char *pszFormat, ...)
     597    void myPrintf(const char *pszFormat, ...) const RT_NOEXCEPT
    242598    {
    243599        va_list va;
    244600        va_start(va, pszFormat);
    245         m_pCmdHlp->pfnPrintfV(m_pCmdHlp, NULL, pszFormat, va);
     601        m_pCmd->myPrintfV(pszFormat, va);
    246602        va_end(va);
    247603    }
    248604
    249     void myPrintHeader(size_t uRva, const char *pszFormat, ...)
     605    void myPrintHeader(size_t uRva, const char *pszFormat, ...) const RT_NOEXCEPT
    250606    {
    251607        char    szTmp[64];
     
    263619    }
    264620
    265     virtual int myError(const char *pszFormat, ...)
     621    int myError(const char *pszFormat, ...) const RT_NOEXCEPT
    266622    {
    267623        va_list va;
    268624        va_start(va, pszFormat);
    269         int rc = DBGCCmdHlpFail(m_pCmdHlp, m_pCmd, "%s: %N", m_pszName, pszFormat, &va);
     625        int rc = m_pCmd->myErrorV(pszFormat, va);
    270626        va_end(va);
    271627        return rc;
    272628    }
    273629
    274     virtual int myError(int rc, const char *pszFormat, ...)
     630    int myError(int rc, const char *pszFormat, ...) const RT_NOEXCEPT
    275631    {
    276632        va_list va;
    277633        va_start(va, pszFormat);
    278         rc = DBGCCmdHlpFailRc(m_pCmdHlp, m_pCmd, rc, "%s: %N", m_pszName, pszFormat, &va);
     634        rc = m_pCmd->myErrorV(rc, pszFormat, va);
    279635        va_end(va);
    280636        return rc;
    281637    }
    282638
    283     int readBytesAtRva(size_t uRva, void *pvBuf, size_t cbToRead, size_t *pcbRead = NULL)
    284     {
    285         /* Ensure buffer and return size is zero before we do anything. */
    286         if (pcbRead)
    287             *pcbRead = 0;
    288         RT_BZERO(pvBuf, cbToRead);
    289 
     639    int readBytesAtRva(size_t uRva, void *pvBuf, size_t cbToRead, size_t *pcbRead = NULL) RT_NOEXCEPT
     640    {
    290641#ifndef DBGC_DUMP_IMAGE_TOOL
    291         /* Calc the read address. */
    292         DBGCVAR AddrToReadAt;
    293         int rc = DBGCCmdHlpEval(m_pCmdHlp, &AddrToReadAt, "%DV + %#zx", m_pImageBase, uRva);
    294         if (RT_SUCCESS(rc))
    295         {
    296             rc = DBGCCmdHlpMemRead(m_pCmdHlp, pvBuf, cbToRead, &AddrToReadAt, pcbRead);
    297             if (RT_FAILURE(rc))
    298                 rc = myError(rc, "Failed to read %zu bytes at %Dv", cbToRead, &AddrToReadAt);
    299         }
    300 #else  /* DBGC_DUMP_IMAGE_TOOL */
    301         int rc;
     642        /* RVA and offset is the same in this context. */
     643        return m_pCmd->readAt(uRva, pvBuf, cbToRead, pcbRead);
     644#else
    302645        size_t const offFile = rvaToFileOffset(uRva);
    303646        if (offFile != ~(size_t)0)
    304         {
    305             CMDHLPSTATE * const pToolState = RT_FROM_MEMBER(m_pCmdHlp, CMDHLPSTATE, Core);
    306             rc = RTVfsFileReadAt(pToolState->hVfsFile, offFile, pvBuf, cbToRead, pcbRead);
    307             if (RT_FAILURE(rc))
    308                 rc = myError(rc, "Failed to read %zu bytes at %#zx (RVA %#zx)", cbToRead, offFile, uRva);
    309         }
    310         else
    311             rc = myError(VERR_READ_ERROR, "Failed to convert RVA %#zx to file offset for %zu byte read!", uRva, cbToRead);
    312 #endif /* DBGC_DUMP_IMAGE_TOOL */
    313         return rc;
     647            return m_pCmd->readAt(offFile, pvBuf, cbToRead, pcbRead);
     648        return myError(VERR_READ_ERROR, "Failed to convert RVA %#zx to file offset for %zu byte read!", uRva, cbToRead);
     649#endif
    314650    }
    315651};
     
    335671    DumpImageBase  *m_pImage;
    336672
    337     int loadBuffer(size_t uRva)
     673    int loadBuffer(size_t uRva) RT_NOEXCEPT
    338674    {
    339675        /* Check that the RVA is within the image. */
     
    353689
    354690    /** Resizes the buffer if the current one can't hold @a cbNeeded bytes. */
    355     int ensureBufferSpace(size_t cbNeeded)
     691    int ensureBufferSpace(size_t cbNeeded) RT_NOEXCEPT
    356692    {
    357693        if (cbNeeded > m_cbBufAlloc)
     
    360696            void *pvNew = RTMemTmpAllocZ(cbNeeded);
    361697            if (!pvNew)
    362                 return DBGCCmdHlpFailRc(m_pImage->m_pCmdHlp, m_pImage->m_pCmd, VERR_NO_TMP_MEMORY,
    363                                         "Failed to allocate %zu (%#zx) bytes", cbNeeded, cbNeeded);
     698                return m_pImage->myError(VERR_NO_TMP_MEMORY, "Failed to allocate %zu (%#zx) bytes", cbNeeded, cbNeeded);
    364699            memcpy(pvNew, m_pbBuf, RT_MIN(m_cbBuf, m_cbBufAlloc));
    365700
     
    375710
    376711public:
    377     DumpImageBufferedReader(DumpImageBase *a_pImage)
     712    DumpImageBufferedReader(DumpImageBase *a_pImage) RT_NOEXCEPT
    378713        : m_pbBuf(&m_abBufFixed[0])
    379714        , m_cbBufAlloc(sizeof(m_abBufFixed))
     
    386721
    387722    /** Copy constructor. */
    388     DumpImageBufferedReader(DumpImageBufferedReader const &a_rThat)
     723    DumpImageBufferedReader(DumpImageBufferedReader const &a_rThat) RT_NOEXCEPT
    389724        : m_pbBuf(&m_abBufFixed[0])
    390725        , m_cbBufAlloc(sizeof(m_abBufFixed))
     
    398733    }
    399734
    400     ~DumpImageBufferedReader()
     735    ~DumpImageBufferedReader() RT_NOEXCEPT
    401736    {
    402737        if (m_pbBuf != &m_abBufFixed[0])
     
    411746     * the status code.
    412747     */
    413     int readBytes(size_t uRva, void *pvDst, size_t cbToRead)
     748    int readBytes(size_t uRva, void *pvDst, size_t cbToRead) RT_NOEXCEPT
    414749    {
    415750        RT_BZERO(pvDst, cbToRead);
     
    454789     *          internal buffer.
    455790     */
    456     uint8_t const *bufferedBytes(size_t uRva, size_t cbItem)
     791    uint8_t const *bufferedBytes(size_t uRva, size_t cbItem) RT_NOEXCEPT
    457792    {
    458793        /* Do we need to load the item into the buffer? */
     
    478813     *       buffer size.
    479814     */
    480     const char *bufferedString(size_t uRva)
     815    const char *bufferedString(size_t uRva) RT_NOEXCEPT
    481816    {
    482817        /* Do we need to reload the buffer? */
     
    503838     */
    504839    template<typename IntType>
    505     IntType bufferedInt(size_t uRva, IntType Default = 0)
     840    IntType bufferedInt(size_t uRva, IntType Default = 0) RT_NOEXCEPT
    506841    {
    507842        AssertCompile(sizeof(IntType) <= 8);
     
    527862*   PE                                                                                                                           *
    528863*********************************************************************************************************************************/
    529 
    530 static const char *dbgcPeMachineName(uint16_t uMachine)
    531 {
    532     switch (uMachine)
    533     {
    534         case IMAGE_FILE_MACHINE_I386         : return "I386";
    535         case IMAGE_FILE_MACHINE_AMD64        : return "AMD64";
    536         case IMAGE_FILE_MACHINE_UNKNOWN      : return "UNKNOWN";
    537         case IMAGE_FILE_MACHINE_BASIC_16     : return "BASIC_16";
    538         case IMAGE_FILE_MACHINE_BASIC_16_TV  : return "BASIC_16_TV";
    539         case IMAGE_FILE_MACHINE_IAPX16       : return "IAPX16";
    540         case IMAGE_FILE_MACHINE_IAPX16_TV    : return "IAPX16_TV";
    541         //case IMAGE_FILE_MACHINE_IAPX20       : return "IAPX20";
    542         //case IMAGE_FILE_MACHINE_IAPX20_TV    : return "IAPX20_TV";
    543         case IMAGE_FILE_MACHINE_I8086        : return "I8086";
    544         case IMAGE_FILE_MACHINE_I8086_TV     : return "I8086_TV";
    545         case IMAGE_FILE_MACHINE_I286_SMALL   : return "I286_SMALL";
    546         case IMAGE_FILE_MACHINE_MC68         : return "MC68";
    547         //case IMAGE_FILE_MACHINE_MC68_WR      : return "MC68_WR";
    548         case IMAGE_FILE_MACHINE_MC68_TV      : return "MC68_TV";
    549         case IMAGE_FILE_MACHINE_MC68_PG      : return "MC68_PG";
    550         //case IMAGE_FILE_MACHINE_I286_LARGE   : return "I286_LARGE";
    551         case IMAGE_FILE_MACHINE_U370_WR      : return "U370_WR";
    552         case IMAGE_FILE_MACHINE_AMDAHL_470_WR: return "AMDAHL_470_WR";
    553         case IMAGE_FILE_MACHINE_AMDAHL_470_RO: return "AMDAHL_470_RO";
    554         case IMAGE_FILE_MACHINE_U370_RO      : return "U370_RO";
    555         case IMAGE_FILE_MACHINE_R4000        : return "R4000";
    556         case IMAGE_FILE_MACHINE_WCEMIPSV2    : return "WCEMIPSV2";
    557         case IMAGE_FILE_MACHINE_VAX_WR       : return "VAX_WR";
    558         case IMAGE_FILE_MACHINE_VAX_RO       : return "VAX_RO";
    559         case IMAGE_FILE_MACHINE_SH3          : return "SH3";
    560         case IMAGE_FILE_MACHINE_SH3DSP       : return "SH3DSP";
    561         case IMAGE_FILE_MACHINE_SH4          : return "SH4";
    562         case IMAGE_FILE_MACHINE_SH5          : return "SH5";
    563         case IMAGE_FILE_MACHINE_ARM          : return "ARM";
    564         case IMAGE_FILE_MACHINE_THUMB        : return "THUMB";
    565         case IMAGE_FILE_MACHINE_ARMNT        : return "ARMNT";
    566         case IMAGE_FILE_MACHINE_AM33         : return "AM33";
    567         case IMAGE_FILE_MACHINE_POWERPC      : return "POWERPC";
    568         case IMAGE_FILE_MACHINE_POWERPCFP    : return "POWERPCFP";
    569         case IMAGE_FILE_MACHINE_IA64         : return "IA64";
    570         case IMAGE_FILE_MACHINE_MIPS16       : return "MIPS16";
    571         case IMAGE_FILE_MACHINE_MIPSFPU      : return "MIPSFPU";
    572         case IMAGE_FILE_MACHINE_MIPSFPU16    : return "MIPSFPU16";
    573         case IMAGE_FILE_MACHINE_EBC          : return "EBC";
    574         case IMAGE_FILE_MACHINE_M32R         : return "M32R";
    575         case IMAGE_FILE_MACHINE_ARM64        : return "ARM64";
    576     }
    577     return "??";
    578 }
    579 
    580 
    581 static const char *dbgcPeDataDirName(unsigned iDir)
    582 {
    583     switch (iDir)
    584     {
    585         case IMAGE_DIRECTORY_ENTRY_EXPORT:          return "EXPORT";
    586         case IMAGE_DIRECTORY_ENTRY_IMPORT:          return "IMPORT";
    587         case IMAGE_DIRECTORY_ENTRY_RESOURCE:        return "RESOURCE";
    588         case IMAGE_DIRECTORY_ENTRY_EXCEPTION:       return "EXCEPTION";
    589         case IMAGE_DIRECTORY_ENTRY_SECURITY:        return "SECURITY";
    590         case IMAGE_DIRECTORY_ENTRY_BASERELOC:       return "BASERELOC";
    591         case IMAGE_DIRECTORY_ENTRY_DEBUG:           return "DEBUG";
    592         case IMAGE_DIRECTORY_ENTRY_ARCHITECTURE:    return "ARCHITECTURE";
    593         case IMAGE_DIRECTORY_ENTRY_GLOBALPTR:       return "GLOBALPTR";
    594         case IMAGE_DIRECTORY_ENTRY_TLS:             return "TLS";
    595         case IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG:     return "LOAD_CONFIG";
    596         case IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT:    return "BOUND_IMPORT";
    597         case IMAGE_DIRECTORY_ENTRY_IAT:             return "IAT";
    598         case IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT:    return "DELAY_IMPORT";
    599         case IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR:  return "COM_DESCRIPTOR";
    600     }
    601     return "??";
    602 }
    603 
    604 
    605 static const char *dbgPeDebugTypeName(uint32_t uType, char *pszTmp, size_t cchTmp)
    606 {
    607     switch (uType)
    608     {
    609         case IMAGE_DEBUG_TYPE_UNKNOWN:       return "UNKNOWN";
    610         case IMAGE_DEBUG_TYPE_COFF:          return "COFF";
    611         case IMAGE_DEBUG_TYPE_CODEVIEW:      return "CODEVIEW";
    612         case IMAGE_DEBUG_TYPE_FPO:           return "FPO";
    613         case IMAGE_DEBUG_TYPE_MISC:          return "MISC";
    614         case IMAGE_DEBUG_TYPE_EXCEPTION:     return "EXCEPTION";
    615         case IMAGE_DEBUG_TYPE_FIXUP:         return "FIXUP";
    616         case IMAGE_DEBUG_TYPE_OMAP_TO_SRC:   return "OMAP_TO_SRC";
    617         case IMAGE_DEBUG_TYPE_OMAP_FROM_SRC: return "OMAP_FROM_SRC";
    618         case IMAGE_DEBUG_TYPE_BORLAND:       return "BORLAND";
    619         case IMAGE_DEBUG_TYPE_RESERVED10:    return "RESERVED10";
    620         case IMAGE_DEBUG_TYPE_CLSID:         return "CLSID";
    621         case IMAGE_DEBUG_TYPE_VC_FEATURE:    return "VC_FEATURE";
    622         case IMAGE_DEBUG_TYPE_POGO:          return "POGO";
    623         case IMAGE_DEBUG_TYPE_ILTCG:         return "ILTCG";
    624         case IMAGE_DEBUG_TYPE_MPX:           return "MPX";
    625         case IMAGE_DEBUG_TYPE_REPRO:         return "REPRO";
    626     }
    627     RTStrPrintf(pszTmp, cchTmp, "%#RX32", uType);
    628     return pszTmp;
    629 }
    630 
    631864
    632865/**
     
    659892
    660893public:
    661     DumpImagePe(PDBGCCMDHLP a_pCmdHlp, PCDBGCCMD a_pCmd, PCDBGCVAR a_pImageBase,
    662                 const char *a_pszImageBaseAddr, const char *a_pszName,
     894    DumpImagePe(DumpImageCmd *a_pCmd, const char *a_pszImageBaseAddr,
    663895                uint32_t a_offPeHdr, PCIMAGE_FILE_HEADER a_pFileHdr, void *a_pvNtHdrs,
    664                 uint32_t a_offShdrs, unsigned a_cShdrs, PCIMAGE_SECTION_HEADER a_paShdrs)
    665         : DumpImageBase(a_pCmdHlp, a_pCmd, a_pImageBase, a_pszImageBaseAddr, a_pszName)
     896                uint32_t a_offShdrs, unsigned a_cShdrs, PCIMAGE_SECTION_HEADER a_paShdrs) RT_NOEXCEPT
     897        : DumpImageBase(a_pCmd, a_pszImageBaseAddr)
    666898        , m_pFileHdr(a_pFileHdr)
    667899        , m_offPeHdr(a_offPeHdr)
     
    685917    }
    686918
    687     virtual size_t rvaToFileOffset(size_t uRva) const RT_OVERRIDE
     919    virtual size_t rvaToFileOffset(size_t uRva) const RT_NOEXCEPT RT_OVERRIDE
    688920    {
    689921        AssertReturn(m_paShdrs, uRva);
     
    691923        if (uRva < m_paShdrs[0].VirtualAddress)
    692924            return uRva;
     925        /** @todo handle uninitialized data. needs different return code or smth. */
    693926        unsigned iSh = m_cShdrs;
    694927        while (iSh-- > 0)
     
    705938    }
    706939
    707     virtual size_t getEndRva(bool a_fAligned = true) const RT_OVERRIDE
     940    virtual size_t getEndRva(bool a_fAligned = true) const RT_NOEXCEPT RT_OVERRIDE
    708941    {
    709942        AssertCompileMembersAtSameOffset(IMAGE_NT_HEADERS32, OptionalHeader.SizeOfImage,
     
    735968    /** @} */
    736969
     970    /** @name Constants naming
     971     * @{ */
     972
     973    static const char *machineToString(uint16_t uMachine) RT_NOEXCEPT
     974    {
     975        switch (uMachine)
     976        {
     977            case IMAGE_FILE_MACHINE_I386         : return "I386";
     978            case IMAGE_FILE_MACHINE_AMD64        : return "AMD64";
     979            case IMAGE_FILE_MACHINE_UNKNOWN      : return "UNKNOWN";
     980            case IMAGE_FILE_MACHINE_BASIC_16     : return "BASIC_16";
     981            case IMAGE_FILE_MACHINE_BASIC_16_TV  : return "BASIC_16_TV";
     982            case IMAGE_FILE_MACHINE_IAPX16       : return "IAPX16";
     983            case IMAGE_FILE_MACHINE_IAPX16_TV    : return "IAPX16_TV";
     984            //case IMAGE_FILE_MACHINE_IAPX20       : return "IAPX20";
     985            //case IMAGE_FILE_MACHINE_IAPX20_TV    : return "IAPX20_TV";
     986            case IMAGE_FILE_MACHINE_I8086        : return "I8086";
     987            case IMAGE_FILE_MACHINE_I8086_TV     : return "I8086_TV";
     988            case IMAGE_FILE_MACHINE_I286_SMALL   : return "I286_SMALL";
     989            case IMAGE_FILE_MACHINE_MC68         : return "MC68";
     990            //case IMAGE_FILE_MACHINE_MC68_WR      : return "MC68_WR";
     991            case IMAGE_FILE_MACHINE_MC68_TV      : return "MC68_TV";
     992            case IMAGE_FILE_MACHINE_MC68_PG      : return "MC68_PG";
     993            //case IMAGE_FILE_MACHINE_I286_LARGE   : return "I286_LARGE";
     994            case IMAGE_FILE_MACHINE_U370_WR      : return "U370_WR";
     995            case IMAGE_FILE_MACHINE_AMDAHL_470_WR: return "AMDAHL_470_WR";
     996            case IMAGE_FILE_MACHINE_AMDAHL_470_RO: return "AMDAHL_470_RO";
     997            case IMAGE_FILE_MACHINE_U370_RO      : return "U370_RO";
     998            case IMAGE_FILE_MACHINE_R4000        : return "R4000";
     999            case IMAGE_FILE_MACHINE_WCEMIPSV2    : return "WCEMIPSV2";
     1000            case IMAGE_FILE_MACHINE_VAX_WR       : return "VAX_WR";
     1001            case IMAGE_FILE_MACHINE_VAX_RO       : return "VAX_RO";
     1002            case IMAGE_FILE_MACHINE_SH3          : return "SH3";
     1003            case IMAGE_FILE_MACHINE_SH3DSP       : return "SH3DSP";
     1004            case IMAGE_FILE_MACHINE_SH4          : return "SH4";
     1005            case IMAGE_FILE_MACHINE_SH5          : return "SH5";
     1006            case IMAGE_FILE_MACHINE_ARM          : return "ARM";
     1007            case IMAGE_FILE_MACHINE_THUMB        : return "THUMB";
     1008            case IMAGE_FILE_MACHINE_ARMNT        : return "ARMNT";
     1009            case IMAGE_FILE_MACHINE_AM33         : return "AM33";
     1010            case IMAGE_FILE_MACHINE_POWERPC      : return "POWERPC";
     1011            case IMAGE_FILE_MACHINE_POWERPCFP    : return "POWERPCFP";
     1012            case IMAGE_FILE_MACHINE_IA64         : return "IA64";
     1013            case IMAGE_FILE_MACHINE_MIPS16       : return "MIPS16";
     1014            case IMAGE_FILE_MACHINE_MIPSFPU      : return "MIPSFPU";
     1015            case IMAGE_FILE_MACHINE_MIPSFPU16    : return "MIPSFPU16";
     1016            case IMAGE_FILE_MACHINE_EBC          : return "EBC";
     1017            case IMAGE_FILE_MACHINE_M32R         : return "M32R";
     1018            case IMAGE_FILE_MACHINE_ARM64        : return "ARM64";
     1019        }
     1020        return "??";
     1021    }
     1022
     1023    static const char *dataDirectoryToString(unsigned iDir) RT_NOEXCEPT
     1024    {
     1025        switch (iDir)
     1026        {
     1027            case IMAGE_DIRECTORY_ENTRY_EXPORT:          return "EXPORT";
     1028            case IMAGE_DIRECTORY_ENTRY_IMPORT:          return "IMPORT";
     1029            case IMAGE_DIRECTORY_ENTRY_RESOURCE:        return "RESOURCE";
     1030            case IMAGE_DIRECTORY_ENTRY_EXCEPTION:       return "EXCEPTION";
     1031            case IMAGE_DIRECTORY_ENTRY_SECURITY:        return "SECURITY";
     1032            case IMAGE_DIRECTORY_ENTRY_BASERELOC:       return "BASERELOC";
     1033            case IMAGE_DIRECTORY_ENTRY_DEBUG:           return "DEBUG";
     1034            case IMAGE_DIRECTORY_ENTRY_ARCHITECTURE:    return "ARCHITECTURE";
     1035            case IMAGE_DIRECTORY_ENTRY_GLOBALPTR:       return "GLOBALPTR";
     1036            case IMAGE_DIRECTORY_ENTRY_TLS:             return "TLS";
     1037            case IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG:     return "LOAD_CONFIG";
     1038            case IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT:    return "BOUND_IMPORT";
     1039            case IMAGE_DIRECTORY_ENTRY_IAT:             return "IAT";
     1040            case IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT:    return "DELAY_IMPORT";
     1041            case IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR:  return "COM_DESCRIPTOR";
     1042        }
     1043        return "??";
     1044    }
     1045
     1046    static const char *debugTypeToString(uint32_t uType, char *pszTmp, size_t cchTmp) RT_NOEXCEPT
     1047    {
     1048        switch (uType)
     1049        {
     1050            case IMAGE_DEBUG_TYPE_UNKNOWN:       return "UNKNOWN";
     1051            case IMAGE_DEBUG_TYPE_COFF:          return "COFF";
     1052            case IMAGE_DEBUG_TYPE_CODEVIEW:      return "CODEVIEW";
     1053            case IMAGE_DEBUG_TYPE_FPO:           return "FPO";
     1054            case IMAGE_DEBUG_TYPE_MISC:          return "MISC";
     1055            case IMAGE_DEBUG_TYPE_EXCEPTION:     return "EXCEPTION";
     1056            case IMAGE_DEBUG_TYPE_FIXUP:         return "FIXUP";
     1057            case IMAGE_DEBUG_TYPE_OMAP_TO_SRC:   return "OMAP_TO_SRC";
     1058            case IMAGE_DEBUG_TYPE_OMAP_FROM_SRC: return "OMAP_FROM_SRC";
     1059            case IMAGE_DEBUG_TYPE_BORLAND:       return "BORLAND";
     1060            case IMAGE_DEBUG_TYPE_RESERVED10:    return "RESERVED10";
     1061            case IMAGE_DEBUG_TYPE_CLSID:         return "CLSID";
     1062            case IMAGE_DEBUG_TYPE_VC_FEATURE:    return "VC_FEATURE";
     1063            case IMAGE_DEBUG_TYPE_POGO:          return "POGO";
     1064            case IMAGE_DEBUG_TYPE_ILTCG:         return "ILTCG";
     1065            case IMAGE_DEBUG_TYPE_MPX:           return "MPX";
     1066            case IMAGE_DEBUG_TYPE_REPRO:         return "REPRO";
     1067        }
     1068        RTStrPrintf(pszTmp, cchTmp, "%#RX32", uType);
     1069        return pszTmp;
     1070    }
     1071
     1072    /** @} */
     1073
     1074
    7371075    /** @name Dumpers
    7381076     * @{
    7391077     */
    7401078
    741     int dumpPeHdr(void)
    742     {
     1079    int dumpPeHdr(void) RT_NOEXCEPT
     1080    {
     1081        if (!(m_pCmd->m_fSelection & DUMPIMAGE_SELECT_HEADERS))
     1082            return VINF_SUCCESS;
     1083        myPrintHeader(m_offPeHdr, "PE & File Header - %s", m_pCmd->m_pszName);
     1084
    7431085        char szTmp[64];
    744         myPrintHeader(m_offPeHdr, "PE & File Header - %s", m_pszName);
    7451086        myPrintf("Signature:                    %#010RX32\n", u.pNt32->Signature);
    7461087        PCIMAGE_FILE_HEADER const pFileHdr = &u.pNt32->FileHeader;
    747         myPrintf("Machine:                      %s (%#06RX16)\n", dbgcPeMachineName(pFileHdr->Machine), pFileHdr->Machine);
     1088        myPrintf("Machine:                      %s (%#06RX16)\n", machineToString(pFileHdr->Machine), pFileHdr->Machine);
    7481089        myPrintf("Number of sections:           %#06RX16\n", pFileHdr->NumberOfSections);
    7491090        myPrintf("Timestamp:                    %#010RX32\n",
     
    7761117
    7771118    template<typename OptHdrType, bool const a_f32Bit>
    778     int dumpOptHdr(OptHdrType const *pOptHdr, uint32_t uBaseOfData = 0)
    779     {
     1119    int dumpOptHdr(OptHdrType const *pOptHdr, uint32_t uBaseOfData = 0) RT_NOEXCEPT
     1120    {
     1121        if (!(m_pCmd->m_fSelection & DUMPIMAGE_SELECT_HEADERS))
     1122            return VINF_SUCCESS;
    7801123        myPrintHeader(m_offPeHdr + RT_UOFFSETOF(IMAGE_NT_HEADERS32, OptionalHeader), "Optional Header");
     1124
    7811125        char szTmp[64];
    7821126        myPrintf("Optional header magic:        %#06RX16\n", pOptHdr->Magic);
     
    8371181            if (pOptHdr->DataDirectory[i].Size || pOptHdr->DataDirectory[i].VirtualAddress)
    8381182            {
    839                 const char * const pszName = dbgcPeDataDirName(i);
     1183                const char * const pszName = dataDirectoryToString(i);
    8401184                rvaToStringWithAddr(pOptHdr->DataDirectory[i].VirtualAddress, szTmp, sizeof(szTmp));
    8411185                if (i == IMAGE_DIRECTORY_ENTRY_SECURITY)
     
    8551199    int dumpSectionHdrs(void) RT_NOEXCEPT
    8561200    {
     1201        if (!(m_pCmd->m_fSelection & DUMPIMAGE_SELECT_SECTIONS))
     1202            return VINF_SUCCESS;
    8571203        myPrintHeader(m_offShdrs, "Section Table");
     1204
    8581205        for (unsigned i = 0; i < m_cShdrs; i++)
    8591206        {
     
    8661213    }
    8671214
    868     int dumpExportDir(DumpImageBufferedReader *pBufRdr, uint32_t uRvaData, uint32_t cbData)
    869     {
     1215    int dumpExportDir(DumpImageBufferedReader *pBufRdr, uint32_t uRvaData, uint32_t cbData) RT_NOEXCEPT
     1216    {
     1217        if (!(m_pCmd->m_fSelection & DUMPIMAGE_SELECT_EXPORTS))
     1218            return VINF_SUCCESS;
    8701219        myPrintHeader(uRvaData, "Export Table");
     1220
    8711221        RT_NOREF(cbData);
    8721222        char szTmp[64];
     
    10121362
    10131363    template<typename ThunkType, bool const a_f32Bit, ThunkType const a_fOrdinalConst>
    1014     int dumpImportDir(DumpImageBufferedReader *pBufRdr, uint32_t uRvaData, uint32_t cbData)
    1015     {
     1364    int dumpImportDir(DumpImageBufferedReader *pBufRdr, uint32_t uRvaData, uint32_t cbData) RT_NOEXCEPT
     1365    {
     1366        if (!(m_pCmd->m_fSelection & DUMPIMAGE_SELECT_IMPORTS))
     1367            return VINF_SUCCESS;
     1368        myPrintHeader(uRvaData, "Import table");
     1369
    10161370        char         szTmp[64];
    10171371        char         szTmp2[64];
     
    10211375        DumpImageBufferedReader NameRdr(*pBufRdr), Thunk1stRdr(*pBufRdr), ThunkOrgRdr(*pBufRdr);
    10221376
    1023         myPrintHeader(uRvaData, "Import table");
    10241377        int            rcRet    = VINF_SUCCESS;
    10251378        uint32_t const cEntries = cbData / sizeof(IMAGE_IMPORT_DESCRIPTOR);
     
    11171470    }
    11181471
    1119     int dumpDebugDir(DumpImageBufferedReader *pBufRdr, uint32_t uRvaData, uint32_t cbData)
    1120     {
     1472    int dumpDebugDir(DumpImageBufferedReader *pBufRdr, uint32_t uRvaData, uint32_t cbData) RT_NOEXCEPT
     1473    {
     1474        if (!(m_pCmd->m_fSelection & DUMPIMAGE_SELECT_DEBUG))
     1475            return VINF_SUCCESS;
    11211476        myPrintHeader(uRvaData, "Debug Directory");
     1477
    11221478        int            rcRet    = VINF_SUCCESS;
    11231479        uint32_t const cEntries = cbData / sizeof(IMAGE_DEBUG_DIRECTORY);
     
    11411497                     i, rvaToStringWithAddr(DbgDir.AddressOfRawData, szTmp, sizeof(szTmp)), DbgDir.SizeOfData,
    11421498                     DbgDir.PointerToRawData,
    1143                      dbgPeDebugTypeName(DbgDir.Type, szTmp2, sizeof(szTmp2)));
     1499                     debugTypeToString(DbgDir.Type, szTmp2, sizeof(szTmp2)));
    11441500            if (DbgDir.MajorVersion || DbgDir.MinorVersion)
    11451501                myPrintf("  v%u.%u", DbgDir.MajorVersion, DbgDir.MinorVersion);
     
    12091565    }
    12101566
    1211     int dumpDataDirs(DumpImageBufferedReader *pBufRdr, unsigned cDataDirs, PCIMAGE_DATA_DIRECTORY paDataDirs)
     1567    int dumpDataDirs(DumpImageBufferedReader *pBufRdr, unsigned cDataDirs, PCIMAGE_DATA_DIRECTORY paDataDirs) RT_NOEXCEPT
    12121568    {
    12131569        int rcRet = VINF_SUCCESS;
     
    12411597
    12421598    /** @} */
     1599
     1600    static int dumpImage(DumpImageCmd *pCmd, const char *pszImageBaseAddr,
     1601                         uint32_t offPeHdr, PCIMAGE_FILE_HEADER pFileHdr) RT_NOEXCEPT
     1602    {
     1603        pCmd->myPrintf("%s: PE image - %#x (%s), %u sections\n", pCmd->m_pszName, pFileHdr->Machine,
     1604                       machineToString(pFileHdr->Machine), pFileHdr->NumberOfSections);
     1605
     1606        /* Is it a supported optional header size? */
     1607        uint8_t cBits;
     1608        if (pFileHdr->SizeOfOptionalHeader == sizeof(IMAGE_OPTIONAL_HEADER32))
     1609            cBits = 32;
     1610        else if (pFileHdr->SizeOfOptionalHeader == sizeof(IMAGE_OPTIONAL_HEADER64))
     1611            cBits = 64;
     1612        else
     1613            return pCmd->myError("Unsupported optional header size: %#x", pFileHdr->SizeOfOptionalHeader);
     1614
     1615        /*
     1616         * Allocate memory for all the headers, including section headers, and read them into memory.
     1617         */
     1618        size_t const offShdrs = pFileHdr->SizeOfOptionalHeader + sizeof(*pFileHdr) + sizeof(uint32_t);
     1619        size_t const cbHdrs   = offShdrs + pFileHdr->NumberOfSections * sizeof(IMAGE_SECTION_HEADER);
     1620        if (cbHdrs > _2M)
     1621            return pCmd->myError("headers too big: %zu.\n", cbHdrs);
     1622
     1623        void *pvBuf = RTMemTmpAllocZ(cbHdrs);
     1624        if (!pvBuf)
     1625            return pCmd->myError("failed to allocate %zu bytes for headers.", cbHdrs);
     1626
     1627        int rc = pCmd->readAt(offPeHdr, pvBuf, cbHdrs, NULL);
     1628        if (RT_SUCCESS(rc))
     1629        {
     1630            /* Format the image base value from the header if one isn't specified. */
     1631            char szTmp[32];
     1632            if (!pszImageBaseAddr)
     1633            {
     1634                if (cBits == 32)
     1635                    RTStrPrintf(szTmp, sizeof(szTmp), "%#010RX32", ((PIMAGE_NT_HEADERS32)pvBuf)->OptionalHeader.ImageBase);
     1636                else
     1637                    RTStrPrintf(szTmp, sizeof(szTmp), "%#018RX64", ((PIMAGE_NT_HEADERS64)pvBuf)->OptionalHeader.ImageBase);
     1638                pszImageBaseAddr = szTmp;
     1639            }
     1640
     1641            /* Finally, instantiate dumper now that we've got the section table
     1642               loaded, and let it contiue. */
     1643            DumpImagePe This(pCmd, pszImageBaseAddr, offPeHdr, pFileHdr, pvBuf, (uint32_t)offShdrs,
     1644                             pFileHdr->NumberOfSections, (PCIMAGE_SECTION_HEADER)((uintptr_t)pvBuf + offShdrs));
     1645
     1646            This.dumpPeHdr();
     1647            if (cBits == 32)
     1648                rc = This.dumpOptHdr<IMAGE_OPTIONAL_HEADER32, true>(&This.u.pNt32->OptionalHeader,
     1649                                                                    This.u.pNt32->OptionalHeader.BaseOfData);
     1650            else
     1651                rc = This.dumpOptHdr<IMAGE_OPTIONAL_HEADER64, false>(&This.u.pNt64->OptionalHeader);
     1652
     1653            int rc2 = This.dumpSectionHdrs();
     1654            if (RT_FAILURE(rc2) && RT_SUCCESS(rc))
     1655                rc = rc2;
     1656
     1657            DumpImageBufferedReader BufRdr(&This);
     1658            rc2 = This.dumpDataDirs(&BufRdr, This.cDataDir, This.paDataDir);
     1659            if (RT_FAILURE(rc2) && RT_SUCCESS(rc))
     1660                rc = rc2;
     1661        }
     1662        RTMemTmpFree(pvBuf);
     1663        return rc;
     1664    }
     1665
    12431666};
    1244 
    1245 
    1246 static int dbgcDumpImagePe(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PCDBGCVAR pImageBase, const char *pszImageBaseAddr,
    1247                            const char *pszName, uint32_t offPeHdr, PCIMAGE_FILE_HEADER pFileHdr)
    1248 {
    1249     DBGCCmdHlpPrintf(pCmdHlp, "%s: PE image - %#x (%s), %u sections\n", pszName, pFileHdr->Machine,
    1250                      dbgcPeMachineName(pFileHdr->Machine), pFileHdr->NumberOfSections);
    1251 
    1252     /* Is it a supported optional header size? */
    1253     uint8_t cBits;
    1254     if (pFileHdr->SizeOfOptionalHeader == sizeof(IMAGE_OPTIONAL_HEADER32))
    1255         cBits = 32;
    1256     else if (pFileHdr->SizeOfOptionalHeader == sizeof(IMAGE_OPTIONAL_HEADER64))
    1257         cBits = 64;
    1258     else
    1259         return DBGCCmdHlpFail(pCmdHlp, pCmd, "%s: Unsupported optional header size: %#x\n",
    1260                               pszName, pFileHdr->SizeOfOptionalHeader);
    1261 
    1262     /*
    1263      * Allocate memory for all the headers, including section headers, and read them into memory.
    1264      */
    1265     size_t const offShdrs = pFileHdr->SizeOfOptionalHeader + sizeof(*pFileHdr) + sizeof(uint32_t);
    1266     size_t const cbHdrs   = offShdrs + pFileHdr->NumberOfSections * sizeof(IMAGE_SECTION_HEADER);
    1267     if (cbHdrs > _2M)
    1268         return DBGCCmdHlpFail(pCmdHlp, pCmd, "%s: headers too big: %zu.\n", pszName, cbHdrs);
    1269 
    1270     void *pvBuf = RTMemTmpAllocZ(cbHdrs);
    1271     if (!pvBuf)
    1272         return DBGCCmdHlpFail(pCmdHlp, pCmd, "%s: failed to allocate %zu bytes for headers.\n", pszName, cbHdrs);
    1273 
    1274     int rc = dumpReadAt(pCmdHlp, pCmd, pImageBase, pszName, offPeHdr, pvBuf, cbHdrs, NULL);
    1275     if (RT_SUCCESS(rc))
    1276     {
    1277         /* Format the image base value from the header if one isn't specified. */
    1278         char szTmp[32];
    1279         if (!pszImageBaseAddr)
    1280         {
    1281             if (cBits == 32)
    1282                 RTStrPrintf(szTmp, sizeof(szTmp), "%#010RX32", ((PIMAGE_NT_HEADERS32)pvBuf)->OptionalHeader.ImageBase);
    1283             else
    1284                 RTStrPrintf(szTmp, sizeof(szTmp), "%#018RX64", ((PIMAGE_NT_HEADERS64)pvBuf)->OptionalHeader.ImageBase);
    1285             pszImageBaseAddr = szTmp;
    1286         }
    1287 
    1288         /* Finally, instantiate dumper now that we've got the section table
    1289            loaded, and let it contiue. */
    1290         DumpImagePe This(pCmdHlp, pCmd, pImageBase, pszImageBaseAddr, pszName,
    1291                          offPeHdr, pFileHdr, pvBuf,
    1292                          (uint32_t)offShdrs, pFileHdr->NumberOfSections, (PCIMAGE_SECTION_HEADER)((uintptr_t)pvBuf + offShdrs));
    1293 
    1294         This.dumpPeHdr();
    1295         if (cBits == 32)
    1296             rc = This.dumpOptHdr<IMAGE_OPTIONAL_HEADER32, true>(&This.u.pNt32->OptionalHeader,
    1297                                                                 This.u.pNt32->OptionalHeader.BaseOfData);
    1298         else
    1299             rc = This.dumpOptHdr<IMAGE_OPTIONAL_HEADER64, false>(&This.u.pNt64->OptionalHeader);
    1300 
    1301         int rc2 = This.dumpSectionHdrs();
    1302         if (RT_FAILURE(rc2) && RT_SUCCESS(rc))
    1303             rc = rc2;
    1304 
    1305         DumpImageBufferedReader BufRdr(&This);
    1306         rc2 = This.dumpDataDirs(&BufRdr, This.cDataDir, This.paDataDir);
    1307         if (RT_FAILURE(rc2) && RT_SUCCESS(rc))
    1308             rc = rc2;
    1309     }
    1310     RTMemTmpFree(pvBuf);
    1311     return rc;
    1312 }
    13131667
    13141668
     
    13171671*********************************************************************************************************************************/
    13181672
    1319 static int dbgcDumpImageElf(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PCDBGCVAR pImageBase, const char *pszName)
     1673static int dbgcDumpImageElf(DumpImageCmd *pCmd)
    13201674{
    1321     RT_NOREF(pCmd, pImageBase);
    1322     DBGCCmdHlpPrintf(pCmdHlp, "%s: ELF image dumping not implemented yet.\n", pszName);
     1675    pCmd->myPrintf("%s: ELF image dumping not implemented yet.\n", pCmd->m_pszName);
    13231676    return VINF_SUCCESS;
    13241677}
     
    14531806
    14541807
    1455 static int dbgcDumpImageMachO(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PCDBGCVAR pImageBase, const char *pszName,
    1456                               mach_header_64_t const *pHdr)
     1808static int dbgcDumpImageMachO(DumpImageCmd *pCmd, mach_header_64_t const *pHdr)
    14571809{
    14581810#define ENTRY(a_Define)  { a_Define, #a_Define }
     
    14621814     * Header:
    14631815     */
    1464     DBGCCmdHlpPrintf(pCmdHlp, "%s: Mach-O image (%s bit) - %s (%u) - %s (%#x / %#x)\n",
    1465                      pszName, pHdr->magic == IMAGE_MACHO64_SIGNATURE ? "64" : "32",
    1466                      dbgcMachoFileType(pHdr->filetype), pHdr->filetype,
    1467                      dbgcMachoCpuType(pHdr->cputype, pHdr->cpusubtype), pHdr->cputype, pHdr->cpusubtype);
    1468 
    1469     DBGCCmdHlpPrintf(pCmdHlp, "%s: Flags: %#x", pszName, pHdr->flags);
     1816    pCmd->myPrintf("%s: Mach-O image (%s bit) - %s (%u) - %s (%#x / %#x)\n",
     1817                   pCmd->m_pszName, pHdr->magic == IMAGE_MACHO64_SIGNATURE ? "64" : "32",
     1818                   dbgcMachoFileType(pHdr->filetype), pHdr->filetype,
     1819                   dbgcMachoCpuType(pHdr->cputype, pHdr->cpusubtype), pHdr->cputype, pHdr->cpusubtype);
     1820
     1821    pCmd->myPrintf("%s: Flags: %#x", pCmd->m_pszName, pHdr->flags);
    14701822    static DBGCDUMPFLAGENTRY const s_aHdrFlags[] =
    14711823    {
     
    14841836        FLENT(MH_NO_HEAP_EXECUTION),
    14851837    };
    1486     dbgcDumpImageFlags32(pCmdHlp, pHdr->flags, s_aHdrFlags, RT_ELEMENTS(s_aHdrFlags));
    1487     DBGCCmdHlpPrintf(pCmdHlp, "\n");
     1838    dbgcDumpImageFlags32(pCmd, pHdr->flags, s_aHdrFlags, RT_ELEMENTS(s_aHdrFlags));
     1839    pCmd->myPrintf("\n");
    14881840    if (pHdr->reserved != 0 && pHdr->magic == IMAGE_MACHO64_SIGNATURE)
    1489         DBGCCmdHlpPrintf(pCmdHlp, "%s: Reserved header field: %#x\n", pszName, pHdr->reserved);
     1841        pCmd->myPrintf("%s: Reserved header field: %#x\n", pCmd->m_pszName, pHdr->reserved);
    14901842
    14911843    /*
     
    14941846    const uint32_t cCmds  = pHdr->ncmds;
    14951847    const uint32_t cbCmds = pHdr->sizeofcmds;
    1496     DBGCCmdHlpPrintf(pCmdHlp, "%s: %u load commands covering %#x bytes:\n", pszName, cCmds, cbCmds);
     1848    pCmd->myPrintf("%s: %u load commands covering %#x bytes:\n", pCmd->m_pszName, cCmds, cbCmds);
    14971849    if (cbCmds > _16M)
    1498         return DBGCCmdHlpFailRc(pCmdHlp, pCmd, VERR_OUT_OF_RANGE,
    1499                                 "%s: Commands too big: %#x bytes, max 16MiB\n", pszName, cbCmds);
     1850        return pCmd->myError(VERR_OUT_OF_RANGE, "%s: Commands too big: %#x bytes, max 16MiB", pCmd->m_pszName, cbCmds);
    15001851
    15011852
     
    15061857        return VERR_NO_TMP_MEMORY;
    15071858
    1508     int rc = dumpReadAt(pCmdHlp, pCmd, pImageBase, pszName, cbHdr, pbCmds, cbCmds, NULL);
     1859    int rc = pCmd->readAt(cbHdr, pbCmds, cbCmds, NULL);
    15091860    if (RT_SUCCESS(rc))
    15101861    {
     
    15221873            if (offCmd + cbCurCmd > cbCmds)
    15231874            {
    1524                 rc = DBGCCmdHlpFailRc(pCmdHlp, pCmd, VERR_OUT_OF_RANGE,
    1525                                       "%s: Load command #%u (offset %#x + %#x) is out of bounds! cmdsize=%u (%#x) cmd=%u\n",
    1526                                       pszName, iCmd, offCmd, cbHdr, cbCurCmd, cbCurCmd,
    1527                                       offCmd + RT_UOFFSET_AFTER(load_command_t, cmd) <= cbCmds ? pCurCmd->cmd : UINT32_MAX);
     1875                rc = pCmd->myError(VERR_OUT_OF_RANGE,
     1876                                   "%s: Load command #%u (offset %#x + %#x) is out of bounds! cmdsize=%u (%#x) cmd=%u\n",
     1877                                   pCmd->m_pszName, iCmd, offCmd, cbHdr, cbCurCmd, cbCurCmd,
     1878                                   offCmd + RT_UOFFSET_AFTER(load_command_t, cmd) <= cbCmds ? pCurCmd->cmd : UINT32_MAX);
    15281879                break;
    15291880            }
    15301881
    1531             DBGCCmdHlpPrintf(pCmdHlp, "%s: Load command #%u (offset %#x + %#x): %s (%u) LB %u\n",
    1532                              pszName, iCmd, offCmd, cbHdr, dbgcMachoLoadCommand(pCurCmd->cmd), pCurCmd->cmd, cbCurCmd);
     1882            pCmd->myPrintf("%s: Load command #%u (offset %#x + %#x): %s (%u) LB %u\n",
     1883                           pCmd->m_pszName, iCmd, offCmd, cbHdr, dbgcMachoLoadCommand(pCurCmd->cmd), pCurCmd->cmd, cbCurCmd);
    15331884            switch (pCurCmd->cmd)
    15341885            {
    15351886                case LC_SEGMENT_64:
    15361887                    if (cbCurCmd < sizeof(segment_command_64_t))
    1537                         rc = DBGCCmdHlpFailRc(pCmdHlp, pCmd, VERR_LDRMACHO_BAD_LOAD_COMMAND,
    1538                                               "%s: LC_SEGMENT64 is too short!\n", pszName);
     1888                        rc = pCmd->myError(VERR_LDRMACHO_BAD_LOAD_COMMAND, "LC_SEGMENT64 is too short!");
    15391889                    else
    15401890                    {
    15411891                        segment_command_64_t const *pSeg = (segment_command_64_t const *)pCurCmd;
    1542                         DBGCCmdHlpPrintf(pCmdHlp, "%s:   vmaddr: %016RX64 LB %08RX64  prot: %s(%x)  maxprot: %s(%x)  name: %.16s\n",
    1543                                          pszName, pSeg->vmaddr, pSeg->vmsize, dbgcMachoProt(pSeg->initprot), pSeg->initprot,
    1544                                          dbgcMachoProt(pSeg->maxprot), pSeg->maxprot, pSeg->segname);
    1545                         DBGCCmdHlpPrintf(pCmdHlp, "%s:   file:   %016RX64 LB %08RX64  sections: %2u  flags: %#x",
    1546                                          pszName, pSeg->fileoff, pSeg->filesize, pSeg->nsects, pSeg->flags);
    1547                         dbgcDumpImageFlags32(pCmdHlp, pSeg->flags, s_aSegFlags, RT_ELEMENTS(s_aSegFlags));
    1548                         DBGCCmdHlpPrintf(pCmdHlp, "\n");
     1892                        pCmd->myPrintf("%s:   vmaddr: %016RX64 LB %08RX64  prot: %s(%x)  maxprot: %s(%x)  name: %.16s\n",
     1893                                       pCmd->m_pszName, pSeg->vmaddr, pSeg->vmsize, dbgcMachoProt(pSeg->initprot), pSeg->initprot,
     1894                                       dbgcMachoProt(pSeg->maxprot), pSeg->maxprot, pSeg->segname);
     1895                        pCmd->myPrintf("%s:   file:   %016RX64 LB %08RX64  sections: %2u  flags: %#x",
     1896                                       pCmd->m_pszName, pSeg->fileoff, pSeg->filesize, pSeg->nsects, pSeg->flags);
     1897                        dbgcDumpImageFlags32(pCmd, pSeg->flags, s_aSegFlags, RT_ELEMENTS(s_aSegFlags));
     1898                        pCmd->myPrintf("\n");
    15491899                        if (   pSeg->nsects > _64K
    15501900                            || pSeg->nsects * sizeof(section_64_t) + sizeof(pSeg) > cbCurCmd)
    1551                             rc = DBGCCmdHlpFailRc(pCmdHlp, pCmd, VERR_LDRMACHO_BAD_LOAD_COMMAND,
    1552                                                   "%s: LC_SEGMENT64 is too short for all the sections!\n", pszName);
     1901                            rc = pCmd->myError(VERR_LDRMACHO_BAD_LOAD_COMMAND, "LC_SEGMENT64 is too short for all the sections!");
    15531902                        else
    15541903                        {
     
    15561905                            for (uint32_t iSec = 0; iSec < pSeg->nsects; iSec++)
    15571906                            {
    1558                                 DBGCCmdHlpPrintf(pCmdHlp,
    1559                                                  "%s:   Section #%u: %016RX64 LB %08RX64  align: 2**%-2u  name: %.16s",
    1560                                                  pszName, iSec, paSec[iSec].addr, paSec[iSec].size, paSec[iSec].align,
    1561                                                  paSec[iSec].sectname);
     1907                                pCmd->myPrintf("%s:   Section #%u: %016RX64 LB %08RX64  align: 2**%-2u  name: %.16s",
     1908                                               pCmd->m_pszName, iSec, paSec[iSec].addr, paSec[iSec].size, paSec[iSec].align,
     1909                                               paSec[iSec].sectname);
    15621910                                if (strncmp(pSeg->segname, paSec[iSec].segname, sizeof(pSeg->segname)))
    1563                                     DBGCCmdHlpPrintf(pCmdHlp, "(in %.16s)", paSec[iSec].segname);
    1564                                 DBGCCmdHlpPrintf(pCmdHlp, "\n");
     1911                                    pCmd->myPrintf("(in %.16s)", paSec[iSec].segname);
     1912                                pCmd->myPrintf("\n");
    15651913
    15661914                                /// @todo Good night!
     
    15941942 * Common worker for the dumpimage command and the VBoxDumpImage tool.
    15951943 */
    1596 static int dumpImageCommon(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PCDBGCVAR pImageBase, const char *pszImageBaseAddr,
    1597                            const char *pszName)
     1944int DumpImageCmd::dumpImage(const char *pszImageBaseAddr) RT_NOEXCEPT
    15981945{
     1946    if (!isFirstTarget())
     1947        myPrintf("===================================================================\n"
     1948                 "\n"
     1949                 "\n");
    15991950    union
    16001951    {
     
    16081959        mach_header_64_t    MachO64;
    16091960    } uBuf;
    1610     int rc = dumpReadAt(pCmdHlp, pCmd, pImageBase, pszName, 0, &uBuf.DosHdr, sizeof(uBuf.DosHdr), NULL);
     1961    int rc = readAt(0, &uBuf.DosHdr, sizeof(uBuf.DosHdr), NULL);
    16111962    if (RT_SUCCESS(rc))
    16121963    {
     
    16201971            {
    16211972                /* Look for new header. */
    1622                 rc = dumpReadAt(pCmdHlp, pCmd, pImageBase, pszName, offNewHdr, &uBuf.Nt, sizeof(uBuf.Nt), NULL);
     1973                rc = readAt(offNewHdr, &uBuf.Nt, sizeof(uBuf.Nt), NULL);
    16231974                if (RT_SUCCESS(rc))
    16241975                {
    16251976                    /* PE: */
    16261977                    if (uBuf.Nt.u32Magic == IMAGE_NT_SIGNATURE)
    1627                         rc = dbgcDumpImagePe(pCmd, pCmdHlp, pImageBase, pszImageBaseAddr, pszName, offNewHdr, &uBuf.Nt.FileHdr);
     1978                        rc = DumpImagePe::dumpImage(this, pszImageBaseAddr, offNewHdr, &uBuf.Nt.FileHdr);
    16281979                    else
    1629                         rc = DBGCCmdHlpFail(pCmdHlp, pCmd, "%s: Unknown new header magic: %.8Rhxs\n", pszName, uBuf.ab);
     1980                        return myError(rc, "Unknown new header magic: %.8Rhxs", uBuf.ab);
    16301981                }
    16311982            }
    16321983            else
    1633                 rc = DBGCCmdHlpFail(pCmdHlp, pCmd, "%s: MZ header but e_lfanew=%#RX32 is out of bounds (16..256K).\n",
    1634                                     pszName, offNewHdr);
     1984                return myError(rc, "e_lfanew=%#RX32 is out of bounds (16..256K).", offNewHdr);
    16351985        }
    16361986        /*
     
    16381988         */
    16391989        else if (uBuf.ab[0] == ELFMAG0 && uBuf.ab[1] == ELFMAG1 && uBuf.ab[2] == ELFMAG2 && uBuf.ab[3] == ELFMAG3)
    1640             rc = dbgcDumpImageElf(pCmd, pCmdHlp, pImageBase, pszImageBaseAddr);
     1990            rc = dbgcDumpImageElf(this);
    16411991        /*
    16421992         * Mach-O.
    16431993         */
    16441994        else if (   uBuf.MachO64.magic == IMAGE_MACHO64_SIGNATURE
    1645                  || uBuf.MachO64.magic == IMAGE_MACHO32_SIGNATURE )
    1646             rc = dbgcDumpImageMachO(pCmd, pCmdHlp, pImageBase, pszImageBaseAddr, &uBuf.MachO64);
     1995                 || uBuf.MachO64.magic == IMAGE_MACHO32_SIGNATURE)
     1996            rc = dbgcDumpImageMachO(this, &uBuf.MachO64);
    16471997        /*
    16481998         * Dunno.
    16491999         */
    16502000        else
    1651             rc = DBGCCmdHlpFail(pCmdHlp, pCmd, "%s: Unknown magic: %.8Rhxs\n", pszName, uBuf.ab);
     2001            return myError(rc, "Unknown magic: %.8Rhxs", uBuf.ab);
     2002
     2003        /* Make 100% sure the failure status is signalled. */
     2004        if (RT_FAILURE(rc))
     2005            setFailure(rc);
    16522006    }
    16532007    else
    1654         rc = DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc, "%s: Failed to read %zu", pszName, sizeof(uBuf.DosHdr));
     2008        rc = myError(rc, "Failed to read %zu", sizeof(uBuf.DosHdr));
    16552009    return rc;
    16562010}
     
    16642018DECLCALLBACK(int) dbgcCmdDumpImage(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PUVM pUVM, PCDBGCVAR paArgs, unsigned cArgs)
    16652019{
    1666     int rcRet = VINF_SUCCESS;
     2020    DumpImageCmd Cmd(pCmdHlp, pCmd);
    16672021    for (unsigned iArg = 0; iArg < cArgs; iArg++)
    16682022    {
     
    16702024        char          szImageBaseAddr[64];
    16712025        DBGCCmdHlpStrPrintf(pCmdHlp, szImageBaseAddr, sizeof(szImageBaseAddr), "%Dv", &ImageBase);
    1672         int rc = dumpImageCommon(pCmd, pCmdHlp, &ImageBase, szImageBaseAddr, szImageBaseAddr);
    1673         if (RT_FAILURE(rc) && RT_SUCCESS(rcRet))
    1674             rcRet = rc;
     2026        Cmd.setTarget(szImageBaseAddr, &ImageBase);
     2027        Cmd.dumpImage(szImageBaseAddr);
     2028        Cmd.clearTarget();
    16752029    }
    16762030    RT_NOREF(pUVM);
    1677     return rcRet;
     2031    return Cmd.getStatus();
    16782032}
    16792033
    16802034#else /* DBGC_DUMP_IMAGE_TOOL */
    1681 
    1682 
    1683 /**
    1684  * @interface_member_impl{DBGCCMDHLP,pfnPrintfV}
    1685  */
    1686 static DECLCALLBACK(int) toolPrintfV(PDBGCCMDHLP pCmdHlp, size_t *pcbWritten, const char *pszFormat, va_list args)
    1687 {
    1688     int rc = RTPrintfV(pszFormat, args);
    1689     if (rc >= 0)
    1690     {
    1691         if (pcbWritten)
    1692             *pcbWritten = (unsigned)rc;
    1693         return VINF_SUCCESS;
    1694     }
    1695     if (pcbWritten)
    1696         *pcbWritten = 0;
    1697     RT_NOREF(pCmdHlp);
    1698     return VERR_IO_GEN_FAILURE;
    1699 }
    1700 
    1701 
    1702 /**
    1703  * @interface_member_impl{DBGCCMDHLP,pfnFailV}
    1704  */
    1705 static DECLCALLBACK(int) toolFailV(PDBGCCMDHLP pCmdHlp, PCDBGCCMD pCmd, const char *pszFormat, va_list va)
    1706 {
    1707     CMDHLPSTATE * const pCmdHlpState = RT_FROM_MEMBER(pCmdHlp, CMDHLPSTATE, Core);
    1708     pCmdHlpState->rcExit = RTEXITCODE_FAILURE;
    1709     RTMsgErrorV(pszFormat, va);
    1710     RT_NOREF(pCmd);
    1711     return VERR_GENERAL_FAILURE;
    1712 }
    1713 
    1714 
    1715 /**
    1716  * @interface_member_impl{DBGCCMDHLP,pfnFailRcV}
    1717  */
    1718 static DECLCALLBACK(int) toolFailRcV(PDBGCCMDHLP pCmdHlp, PCDBGCCMD pCmd, int rc, const char *pszFormat, va_list va)
    1719 {
    1720     CMDHLPSTATE * const pCmdHlpState = RT_FROM_MEMBER(pCmdHlp, CMDHLPSTATE, Core);
    1721     pCmdHlpState->rcExit = RTEXITCODE_FAILURE;
    1722 
    1723     va_list vaCopy;
    1724     va_copy(vaCopy, va);
    1725     RTMsgError("%N: %Rrc", pszFormat, &vaCopy, rc);
    1726     va_end(vaCopy);
    1727 
    1728     RT_NOREF(pCmd);
    1729     return rc;
    1730 }
    1731 
    17322035
    17332036int main(int argc, char **argv)
     
    17402043     * Setup image helper code.
    17412044     */
    1742     CMDHLPSTATE ToolState;
    1743     RT_ZERO(ToolState);
    1744     ToolState.Core.pfnPrintfV = toolPrintfV;
    1745     ToolState.Core.pfnFailV   = toolFailV;
    1746     ToolState.Core.pfnFailRcV = toolFailRcV;
    1747     ToolState.hVfsFile        = NIL_RTVFSFILE;
    1748     ToolState.rcExit          = RTEXITCODE_SUCCESS;
    1749 
    1750     char szImageBaseAddr[32] = {0};
     2045    DumpImageCmd Cmd(NULL, NULL);
     2046    char        szImageBaseAddr[32] = {0};
     2047    //uint64_t    fSelect             = DUMPIMAGE_SELECT_DEFAULT;
    17512048
    17522049    static const RTGETOPTDEF s_aOptions[] =
    17532050    {
    17542051        { "--image-base", 'b', RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_HEX },
     2052        { "--include",    'i', RTGETOPT_REQ_STRING },
     2053        { "--only",       'o', RTGETOPT_REQ_STRING },
     2054        { "--only",       'O', RTGETOPT_REQ_STRING },
     2055        { "--skip",       's', RTGETOPT_REQ_STRING },
     2056        { "--skip",       'S', RTGETOPT_REQ_STRING },
    17552057    };
    17562058
     
    17722074                break;
    17732075
     2076            case 'i':
     2077                rc = Cmd.optSelectionInclude(ValueUnion.psz);
     2078                if (RT_FAILURE(rc))
     2079                    return RTEXITCODE_SYNTAX;
     2080                break;
     2081
     2082            case 'o':
     2083            case 'O':
     2084                rc = Cmd.optSelectionOnly(ValueUnion.psz);
     2085                if (RT_FAILURE(rc))
     2086                    return RTEXITCODE_SYNTAX;
     2087                break;
     2088
     2089            case 's':
     2090            case 'S':
     2091                rc = Cmd.optSelectionSkip(ValueUnion.psz);
     2092                if (RT_FAILURE(rc))
     2093                    return RTEXITCODE_SYNTAX;
     2094                break;
     2095
    17742096            case 'V':
    17752097                RTPrintf("%s\n", RTBldCfgRevision());
     
    17842106                RTERRINFOSTATIC ErrInfo;
    17852107                uint32_t        offError = 0;
     2108                RTVFSFILE       hVfsFile = NIL_RTVFSFILE;
    17862109                rc = RTVfsChainOpenFile(ValueUnion.psz, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE,
    1787                                         &ToolState.hVfsFile, &offError, RTErrInfoInitStatic(&ErrInfo));
     2110                                        &hVfsFile, &offError, RTErrInfoInitStatic(&ErrInfo));
    17882111                if (RT_SUCCESS(rc))
    17892112                {
    1790                     rc = dumpImageCommon(NULL, &ToolState.Core, NULL, szImageBaseAddr[0] ? szImageBaseAddr : NULL, ValueUnion.psz);
    1791                     if (RT_FAILURE(rc) && ToolState.rcExit == RTEXITCODE_SUCCESS)
    1792                         ToolState.rcExit = RTEXITCODE_FAILURE;
    1793                     RTVfsFileRelease(ToolState.hVfsFile);
     2113                    Cmd.setTarget(ValueUnion.psz, hVfsFile);
     2114                    Cmd.dumpImage(szImageBaseAddr[0] ? szImageBaseAddr : NULL);
     2115                    Cmd.clearTarget();
    17942116                }
    17952117                else
    1796                     ToolState.rcExit = RTVfsChainMsgErrorExitFailure("RTVfsChainOpenFile", ValueUnion.psz,
    1797                                                                      rc, offError, &ErrInfo.Core);
    1798                 ToolState.hVfsFile = NIL_RTVFSFILE;
     2118                {
     2119                    RTVfsChainMsgErrorExitFailure("RTVfsChainOpenFile", ValueUnion.psz, rc, offError, &ErrInfo.Core);
     2120                    Cmd.setFailure(rc);
     2121                }
    17992122                break;
    18002123            }
     
    18052128    }
    18062129
    1807     return ToolState.rcExit;
    1808 
     2130    return Cmd.getExitCode();
    18092131}
     2132
    18102133#endif /* !DBGC_DUMP_IMAGE_TOOL */
    18112134
  • trunk/src/VBox/Debugger/DBGCInternal.h

    r98103 r105536  
    528528/** Pointer to control flow graph branch table state. */
    529529typedef DBGCFLOWBRANCHTBLDUMP *PDBGCFLOWBRANCHTBLDUMP;
     530
    530531
    531532/*******************************************************************************
     
    644645
    645646
     647extern FNDBGCCMD dbgcCmdDumpImage;
     648extern FNDBGCCMD dbgcCmdNtRbTree;
     649
     650
    646651/*******************************************************************************
    647652*   Global Variables                                                           *
  • trunk/src/VBox/Debugger/Makefile.kmk

    r105531 r105536  
    5656        DBGCCommands.cpp \
    5757        DBGCDumpImage.cpp \
     58        DBGCNtCommands.cpp \
    5859        DBGCFunctions.cpp \
    5960        DBGCEmulateCodeView.cpp \
     
    8889        DBGCCommands.cpp \
    8990        DBGCDumpImage.cpp \
     91        DBGCNtCommands.cpp \
    9092        DBGCFunctions.cpp \
    9193        DBGCEmulateCodeView.cpp \
Note: See TracChangeset for help on using the changeset viewer.

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