VirtualBox

Changeset 34135 in vbox


Ignore:
Timestamp:
Nov 17, 2010 10:25:25 AM (14 years ago)
Author:
vboxsync
Message:

DBGFCoreWrite.cpp: Untested fix for the core file layout bug.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/DBGFCoreWrite.cpp

    r34134 r34135  
    9898 * @param cProgHdrs         Number of program headers.
    9999 * @param cSecHdrs          Number of section headers.
    100  * @param pcbElfHdr         Where to store the size of written header to file,
    101  *                          can be NULL.
    102100 *
    103101 * @return IPRT status code.
    104102 */
    105 static int Elf64WriteElfHdr(RTFILE hFile, uint16_t cProgHdrs, uint16_t cSecHdrs, uint64_t *pcbElfHdr)
     103static int Elf64WriteElfHdr(RTFILE hFile, uint16_t cProgHdrs, uint16_t cSecHdrs)
    106104{
    107105    Elf64_Ehdr ElfHdr;
     
    128126    ElfHdr.e_shentsize       = sizeof(Elf64_Shdr);
    129127
    130     int rc = RTFileWrite(hFile, &ElfHdr, sizeof(ElfHdr), NULL /* all */);
    131     if (RT_SUCCESS(rc) && pcbElfHdr)
    132         *pcbElfHdr = sizeof(ElfHdr);
    133     return rc;
     128    return RTFileWrite(hFile, &ElfHdr, sizeof(ElfHdr), NULL /* all */);
    134129}
    135130
     
    145140 * @param cbMemData         Size of contents in memory.
    146141 * @param Phys              Physical address, pass zero if not applicable.
    147  * @param pcbProgHdr        Where to store the size of written header to file,
    148  *                          can be NULL.
    149142 *
    150143 * @return IPRT status code.
    151144 */
    152145static int Elf64WriteProgHdr(RTFILE hFile, uint32_t Type, uint32_t fFlags, uint64_t offFileData, uint64_t cbFileData,
    153                              uint64_t cbMemData, RTGCPHYS Phys, uint64_t *pcbProgHdr)
     146                             uint64_t cbMemData, RTGCPHYS Phys)
    154147{
    155148    Elf64_Phdr ProgHdr;
     
    162155    ProgHdr.p_paddr         = Phys;
    163156
    164     int rc = RTFileWrite(hFile, &ProgHdr, sizeof(ProgHdr), NULL /* all */);
    165     if (RT_SUCCESS(rc) && pcbProgHdr)
    166         *pcbProgHdr = sizeof(ProgHdr);
    167     return rc;
     157    return RTFileWrite(hFile, &ProgHdr, sizeof(ProgHdr), NULL /* all */);
    168158}
    169159
     
    177167 * @return The size of the NOTE section as rounded to the file alignment.
    178168 */
    179 static inline uint64_t Elf64NoteSectionSize(const char *pszName, uint64_t cbData)
     169static uint64_t Elf64NoteSectionSize(const char *pszName, uint64_t cbData)
    180170{
    181171    uint64_t cbNote = sizeof(Elf64_Nhdr);
     
    198188 * @param pcv               Opaque pointer to the data, if NULL only computes size.
    199189 * @param cbData            Size of the data.
    200  * @param pcbNoteHdr        Where to store the size of written header to file,
    201  *                          can be NULL.
    202190 *
    203191 * @return IPRT status code.
    204192 */
    205 static int Elf64WriteNoteHdr(RTFILE hFile, uint16_t Type, const char *pszName, const void *pcvData, uint64_t cbData, uint64_t *pcbNoteHdr)
     193static int Elf64WriteNoteHdr(RTFILE hFile, uint16_t Type, const char *pszName, const void *pcvData, uint64_t cbData)
    206194{
    207195    AssertReturn(pcvData, VERR_INVALID_POINTER);
     
    319307     * Collect core information.
    320308     */
    321     uint32_t u32MemRanges = dbgfR3GetRamRangeCount(pVM);
    322     uint16_t cMemRanges   = u32MemRanges < UINT16_MAX - 1 ? u32MemRanges : UINT16_MAX - 1;    /* One PT_NOTE Program header */
    323     uint16_t cProgHdrs    = cMemRanges + 1;
     309    uint32_t const cu32MemRanges = dbgfR3GetRamRangeCount(pVM);
     310    uint16_t const cMemRanges    = cu32MemRanges < UINT16_MAX - 1 ? cu32MemRanges : UINT16_MAX - 1; /* One PT_NOTE Program header */
     311    uint16_t const cProgHdrs     = cMemRanges + 1;
    324312
    325313    DBGFCOREDESCRIPTOR CoreDescriptor;
     
    335323
    336324    /*
    337      * Compute total size of the note section.
    338      */
    339     uint64_t cbNoteSection =   Elf64NoteSectionSize(s_pcszCoreVBoxCore, sizeof(CoreDescriptor))
    340                              + pVM->cCpus * Elf64NoteSectionSize(s_pcszCoreVBoxCpu, sizeof(CPUMCTX));
    341     uint64_t off = 0;
     325     * Compute the file layout (see pg_dbgf_vmcore).
     326     */
     327    uint64_t const offElfHdr        = RTFileTell(hFile);
     328    uint64_t const offNoteSection   = offElfHdr         + sizeof(Elf64_Ehdr);
     329    uint64_t const offLoadSections  = offNoteSection    + sizeof(Elf64_Phdr);
     330    uint64_t const cbLoadSections   = cMemRanges * sizeof(Elf64_Phdr);
     331    uint64_t const offCoreDescriptor= offLoadSections   + cbLoadSections;
     332    uint64_t const cbCoreDescriptor = Elf64NoteSectionSize(s_pcszCoreVBoxCore, sizeof(CoreDescriptor));
     333    uint64_t const offCpuDumps      = offCoreDescriptor + cbCoreDescriptor;
     334    uint64_t const cbCpuDumps       = pVM->cCpus * Elf64NoteSectionSize(s_pcszCoreVBoxCpu, sizeof(CPUMCTX));
     335    uint64_t const offMemory        = offCpuDumps       + cbCpuDumps;
     336
     337    uint64_t const offNoteSectionData = offCoreDescriptor;
     338    uint64_t const cbNoteSectionData  = cbCoreDescriptor + cbCpuDumps;
    342339
    343340    /*
    344341     * Write ELF header.
    345342     */
    346     uint64_t cbElfHdr = 0;
    347     uint64_t cbProgHdr = 0;
    348     uint64_t offMemRange = 0;
    349     int rc = Elf64WriteElfHdr(hFile, cProgHdrs, 0 /* cSecHdrs */, &cbElfHdr);
    350     off += cbElfHdr;
     343    int rc = Elf64WriteElfHdr(hFile, cProgHdrs, 0 /* cSecHdrs */);
    351344    if (RT_FAILURE(rc))
    352345    {
     
    358351     * Write PT_NOTE program header.
    359352     */
     353    Assert(RTFileTell(hFile) == offNoteSection);
    360354    rc = Elf64WriteProgHdr(hFile, PT_NOTE, PF_R,
    361                            cbElfHdr + cProgHdrs * sizeof(Elf64_Phdr),   /* file offset to contents */
    362                            cbNoteSection,                               /* size in core file */
    363                            cbNoteSection,                               /* size in memory */
    364                            0,                                           /* physical address */
    365                            &cbProgHdr);
    366     Assert(cbProgHdr == sizeof(Elf64_Phdr));
    367     off += cbProgHdr;
    368 
     355                           offNoteSectionData,  /* file offset to contents */
     356                           cbNoteSectionData,   /* size in core file */
     357                           cbNoteSectionData,   /* size in memory */
     358                           0);                  /* physical address */
    369359    if (RT_FAILURE(rc))
    370360    {
     
    376366     * Write PT_LOAD program header for each memory range.
    377367     */
    378     offMemRange = off + cbNoteSection;  /** @todo this isn't taking the cmemRanges of prog hdrs into account. */
     368    Assert(RTFileTell(hFile) == offLoadSections);
     369    uint64_t offMemRange = offMemory;
    379370    for (uint16_t iRange = 0; iRange < cMemRanges; iRange++)
    380371    {
    381         RTGCPHYS GCPhysStart;
    382         RTGCPHYS GCPhysEnd;
    383 
    384         bool fIsMmio;
     372        RTGCPHYS    GCPhysStart;
     373        RTGCPHYS    GCPhysEnd;
     374        bool        fIsMmio;
    385375        rc = PGMR3PhysGetRange(pVM, iRange, &GCPhysStart, &GCPhysEnd, NULL /* pszDesc */, &fIsMmio);
    386376        if (RT_FAILURE(rc))
     
    400390                               cbFileRange,                         /* size in core file */
    401391                               cbMemRange,                          /* size in memory */
    402                                GCPhysStart,                         /* physical address */
    403                                &cbProgHdr);
    404         Assert(cbProgHdr == sizeof(Elf64_Phdr));
     392                               GCPhysStart);                        /* physical address */
    405393        if (RT_FAILURE(rc))
    406394        {
    407             LogRel((DBGFLOG_NAME ": Elf64WriteProgHdr failed for memory range(%u) cbFileRange=%u cbMemRange=%u rc=%Rrc\n", iRange,
    408                     cbFileRange, cbMemRange, rc));
     395            LogRel((DBGFLOG_NAME ": Elf64WriteProgHdr failed for memory range(%u) cbFileRange=%u cbMemRange=%u rc=%Rrc\n",
     396                    iRange, cbFileRange, cbMemRange, rc));
    409397            return rc;
    410398        }
     
    416404     * Write the Core descriptor note header and data.
    417405     */
    418     rc = Elf64WriteNoteHdr(hFile, NT_VBOXCORE, s_pcszCoreVBoxCore, &CoreDescriptor, sizeof(CoreDescriptor),
    419                            NULL /* pcbNoteHdr */);
     406    Assert(RTFileTell(hFile) == offCoreDescriptor);
     407    rc = Elf64WriteNoteHdr(hFile, NT_VBOXCORE, s_pcszCoreVBoxCore, &CoreDescriptor, sizeof(CoreDescriptor));
    420408    if (RT_FAILURE(rc))
    421409    {
     
    427415     * Write the CPU context note headers and data.
    428416     */
     417    Assert(RTFileTell(hFile) == offCpuDumps);
    429418    for (uint32_t iCpu = 0; iCpu < pVM->cCpus; iCpu++)
    430419    {
    431420        PCPUMCTX pCpuCtx = &pVM->aCpus[iCpu].cpum.s.Guest;
    432         rc = Elf64WriteNoteHdr(hFile, NT_VBOXCPU, s_pcszCoreVBoxCpu, pCpuCtx, sizeof(CPUMCTX), NULL /* pcbNoteHdr */);
     421        rc = Elf64WriteNoteHdr(hFile, NT_VBOXCPU, s_pcszCoreVBoxCpu, pCpuCtx, sizeof(CPUMCTX));
    433422        if (RT_FAILURE(rc))
    434423        {
     
    441430     * Write memory ranges.
    442431     */
     432    Assert(RTFileTell(hFile) == offMemory);
    443433    for (uint16_t iRange = 0; iRange < cMemRanges; iRange++)
    444434    {
    445435        RTGCPHYS GCPhysStart;
    446436        RTGCPHYS GCPhysEnd;
    447         bool fIsMmio;
     437        bool     fIsMmio;
    448438        rc = PGMR3PhysGetRange(pVM, iRange, &GCPhysStart, &GCPhysEnd, NULL /* pszDesc */, &fIsMmio);
    449439        if (RT_FAILURE(rc))
     
    460450         */
    461451        uint64_t cbMemRange  = GCPhysEnd - GCPhysStart + 1;
    462         uint64_t cPages = cbMemRange >> PAGE_SHIFT;
     452        uint64_t cPages      = cbMemRange >> PAGE_SHIFT;
    463453        for (uint64_t iPage = 0; iPage < cPages; iPage++)
    464454        {
    465             const int cbBuf = PAGE_SIZE;
    466             void *pvBuf     = MMR3HeapAlloc(pVM, MM_TAG_DBGF_CORE_WRITE, cbBuf);
    467             if (RT_UNLIKELY(!pvBuf))
    468             {
    469                 LogRel((DBGFLOG_NAME ": MMR3HeapAlloc failed. iRange=%u iPage=%u\n", iRange, iPage));
    470                 return rc;
    471             }
    472 
    473             rc = PGMPhysRead(pVM, GCPhysStart, pvBuf, cbBuf);
     455            uint8_t abPage[PAGE_SIZE];
     456            rc = PGMPhysRead(pVM, GCPhysStart, abPage, sizeof(abPage));
    474457            if (RT_FAILURE(rc))
    475458            {
     
    477460                 * For some reason this failed, write out a zero page instead.
    478461                 */
    479                 LogRel((DBGFLOG_NAME ": PGMPhysRead failed for iRange=%u iPage=%u. rc=%Rrc. Ignoring...\n", iRange,
    480                         iPage, rc));
    481                 memset(pvBuf, 0, cbBuf);
     462                LogRel((DBGFLOG_NAME ": PGMPhysRead failed for iRange=%u iPage=%u. rc=%Rrc. Ignoring...\n", iRange, iPage, rc));
     463                RT_ZERO(abPage);
    482464            }
    483465
    484             rc = RTFileWrite(hFile, pvBuf, cbBuf, NULL /* all */);
     466            rc = RTFileWrite(hFile, abPage, sizeof(abPage), NULL /* all */);
    485467            if (RT_FAILURE(rc))
    486468            {
    487469                LogRel((DBGFLOG_NAME ": RTFileWrite failed. iRange=%u iPage=%u rc=%Rrc\n", iRange, iPage, rc));
    488                 MMR3HeapFree(pvBuf);
    489470                return rc;
    490471            }
    491 
    492             MMR3HeapFree(pvBuf);
    493472        }
    494473    }
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