VirtualBox

Changeset 31802 in vbox for trunk/src/VBox/Runtime


Ignore:
Timestamp:
Aug 19, 2010 6:55:11 PM (14 years ago)
Author:
vboxsync
Message:

tstRTCoreDump: cleanup, eliminate pread.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/testcase/tstRTCoreDump.cpp

    r31801 r31802  
    7373
    7474/**
    75  * Reads a file in a given offset making sure an interruption doesn't cause a failure.
    76  *
    77  * @param hFile         Handle to the file to read.
    78  * @param pv            Where to store the read data.
    79  * @param cb            Size of the data to read.
    80  * @param off           Offset to read from.
    81  *
    82  * @return Number of bytes actually read.
    83  */
    84 static ssize_t ReadFileAt(RTFILE hFile, void *pv, size_t cb, RTFOFF off)
    85 {
    86     while (1)
    87     {
    88         ssize_t cbRead = pread(hFile, pv, cb, off);
    89         if (   cbRead < 0
    90             && errno == EINTR)
    91         {
    92             continue;
    93         }
    94         return cbRead;
    95     }
    96 }
    97 
    98 /**
    9975 * Determines endianness of the system. Just for completeness.
    10076 *
     
    167143 * @return VINF_SUCCESS, if all the given bytes was read in, otherwise VERR_READ_ERROR.
    168144 */
    169 static ssize_t ReadProcAddrSpace(PVBOXPROCESS pVBoxProc, void *pv, size_t cb, RTFOFF off)
    170 {
    171     ssize_t cbRead = ReadFileAt(pVBoxProc->hAs, pv, cb, off);
    172     if (cbRead == (ssize_t)cb)
    173         return VINF_SUCCESS;
    174     else
    175         return VERR_READ_ERROR;
     145static ssize_t ReadProcAddrSpace(PVBOXPROCESS pVBoxProc, RTFOFF off, void *pvBuf, size_t cbToRead)
     146{
     147    while (1)
     148    {
     149        int rc = RTFileReadAt(pVBoxProc->hAs, off, pvBuf, cbToRead, NULL);
     150        if (rc == VERR_INTERRUPTED)
     151            continue;
     152        return rc;
     153    }
    176154}
    177155
     
    369347    else
    370348        CORELOGREL(("ProcReadFileInto: failed to open %s. rc=%Rrc\n", szPath, rc));
    371     return rc;
    372 }
    373 
    374 
    375 /**
    376  * Reads an ELF header from the given offset in a file.
    377  *
    378  * @param hFile         The file to read.
    379  * @param off           The offset where ELF header resides.
    380  * @param pHdr          Where to store the read-in ELF header.
    381  * @param pcSecHdrs     Where to store the number of section headers.
    382  * @param pSecHdrIndex  Where to store the section header index.
    383  * @param pcProgHdrs    Where to store the number of program headers.
    384  *
    385  * @return VBox status code.
    386  */
    387 int ElfReadHdr(RTFILE hFile, RTFOFF off, Ehdr *pHdr, uint32_t *pcSecHdrs, uint32_t *pSecHdrIndex, uint32_t *pcProgHdrs)
    388 {
    389     /*
    390      * Read ELF header from the given position.
    391      */
    392     int rc = ReadFileAt(hFile, pHdr, sizeof(Ehdr), off) != sizeof(Ehdr);
    393     if (RT_FAILURE(rc))
    394     {
    395         CORELOGREL(("ElfReadHdr: pfnRead failed rc=%d\n", rc));
    396         return VERR_READ_ERROR;
    397     }
    398 
    399     /*
    400      * Validate ELF header.
    401      */
    402     if (   pHdr->e_ident[EI_MAG0] != ELFMAG0
    403         || pHdr->e_ident[EI_MAG1] != ELFMAG1
    404         || pHdr->e_ident[EI_MAG2] != ELFMAG2
    405         || pHdr->e_ident[EI_MAG3] != ELFMAG3
    406 #ifdef BIG_ENDIAN
    407         || pHdr->e_ident[EI_DATA] != ELFDATA2MSB
    408 #else
    409         || pHdr->e_ident[EI_DATA] != ELFDATA2LSB
    410 #endif
    411         || pHdr->e_ident[EI_VERSION] != EV_CURRENT)
    412     {
    413         CORELOGREL(("ElfReadHdr: Bad format(1)\n", rc));
    414         return VERR_BAD_EXE_FORMAT;
    415     }
    416 
    417     if (
    418 #ifdef RT_ARCH_AMD64
    419            pHdr->e_ident[EI_CLASS] != ELFCLASS64
    420         || (   pHdr->e_machine != EM_AMD64
    421             && pHdr->e_machine != EM_X86_64)
    422 #else
    423            pHdr->e_ident[EI_CLASS] != ELFCLASS32
    424         || (   pHdr->e_machine != EM_386
    425             && pHdr->e_machine != EM_486)
    426 #endif
    427         )
    428     {
    429         CORELOGREL(("ElfReadHdr: Bad format(2)\n", rc));
    430         return VERR_BAD_EXE_FORMAT;
    431     }
    432 
    433     if (   pHdr->e_type != ET_EXEC
    434         && pHdr->e_type != ET_DYN)
    435     {
    436         CORELOGREL(("ElfReadHdr: Bad format(3)\n", rc));
    437         return VERR_BAD_EXE_FORMAT;
    438     }
    439 
    440     if (   pHdr->e_shoff < pHdr->e_ehsize
    441         && !(pHdr->e_shoff && pHdr->e_shnum))
    442     {
    443         CORELOGREL(("ElfReadHdr: Section headers overlap ELF header!\n"));
    444         return VERR_BAD_EXE_FORMAT;
    445     }
    446 
    447     uint64_t cbFileSize = 0;
    448     rc = RTFileGetSize(hFile, &cbFileSize);
    449     if (   RT_SUCCESS(rc)
    450         && (   pHdr->e_shoff + pHdr->e_shnum * pHdr->e_shentsize > cbFileSize
    451             || pHdr->e_shoff + pHdr->e_shnum * pHdr->e_shentsize < pHdr->e_shoff))
    452     {
    453         CORELOGREL(("ElfReadHdr: Section headers goes beyond file cbFileSize=%u shoff=%u\n", cbFileSize, pHdr->e_shoff));
    454         return VERR_BAD_EXE_FORMAT;
    455     }
    456 
    457     *pcSecHdrs = pHdr->e_shnum;
    458     *pSecHdrIndex = pHdr->e_shstrndx;
    459     *pcProgHdrs = pHdr->e_phnum;
    460 
    461     /*
    462      * If pcSecHdrs, pSecHdrIndex or pcProgHdrs is at it's max value, we need to
    463      * read the section header at index 0 for getting the real values.
    464      */
    465     if (   (*pcSecHdrs == 0 && pHdr->e_shoff != 0)
    466         || *pSecHdrIndex == SHN_XINDEX
    467         || *pcProgHdrs == PN_XNUM)
    468     {
    469         Shdr SecHdr;
    470         if (pHdr->e_shoff == 0)
    471         {
    472             CORELOGREL(("ElfReadHdr: invalid section header offset %d\n", pHdr->e_shoff));
    473             return VERR_ELF_EXE_NOT_SUPPORTED;
    474         }
    475 
    476         rc = ReadFileAt(hFile, &SecHdr, sizeof(SecHdr), pHdr->e_shoff);
    477         if (RT_SUCCESS(rc))
    478         {
    479             if (*pcSecHdrs == 0)
    480                 *pcSecHdrs = SecHdr.sh_size;
    481             if (*pSecHdrIndex == SHN_XINDEX)
    482                 *pSecHdrIndex = SecHdr.sh_link;
    483             if (*pcProgHdrs == PN_XNUM && SecHdr.sh_info != 0)
    484                 *pcProgHdrs = SecHdr.sh_info;
    485         }
    486         else
    487             return rc;
    488     }
    489 
    490     return VINF_SUCCESS;
    491 }
    492 
    493 
    494 /**
    495  * Read a section header from an ELF file.
    496  *
    497  * @param hFile             The file to read.
    498  * @param offElfStart       Offset that represents the start of the ELF header.
    499  * @param pHdr              Pointer to the ELF header.
    500  * @param cSecHdrs          Number of section headers.
    501  * @param SecHdrIndex       Index into the section header table.
    502  * @param ppvSecHdr         Where to store the pointer to the read-in section header.
    503  * @param pcbSecHdr         Where to store the size of the read-in section header.
    504  * @param ppszSecHdrStr     Where to store the section header string table.
    505  * @param pcbSecHdrStr      Where to store the size of the section header string table.
    506  *
    507  * @return VBox status code.
    508  */
    509 int ElfReadSecHdr(PVBOXCORE pVBoxCore, RTFILE hFile, RTFOFF offElfStart, const Ehdr *pHdr, uint32_t cSecHdrs, uint32_t SecHdrIndex,
    510                   void **ppvSecHdr, size_t *pcbSecHdr, char **ppszSecHdrStr, size_t *pcbSecHdrStr)
    511 {
    512     AssertReturn(pVBoxCore, VERR_INVALID_POINTER);
    513     PVBOXPROCESS pVBoxProc = &pVBoxCore->VBoxProc;
    514 
    515     /*
    516      * Since we use e_shentsize to index into the array of section headers, make sure it's 8-byte aligned.
    517      * We use all the members through sh_entsize (on both 32, 64 bit) so e_shentsize must be large enough.
    518      */
    519     Shdr *pSecHdr;
    520     ssize_t cSize = RT_OFFSETOF(Shdr, sh_entsize) + sizeof(pSecHdr->sh_entsize);
    521     if (   pHdr->e_shentsize < cSize
    522         || (pHdr->e_shentsize & 3) != 0
    523         || SecHdrIndex > cSecHdrs)
    524     {
    525         CORELOGREL(("ElfReadSecHdr: invalid format\n"));
    526         return VERR_BAD_EXE_FORMAT;
    527     }
    528 
    529     /*
    530      * Allocate & read in the section header.
    531      */
    532     int rc = VINF_SUCCESS;
    533     *pcbSecHdr = cSecHdrs * pHdr->e_shentsize;
    534     *ppvSecHdr = GetMemoryChunk(pVBoxCore, *pcbSecHdr);
    535     if (!*ppvSecHdr)
    536     {
    537         rc = ReadFileAt(hFile, *ppvSecHdr, *pcbSecHdr, pHdr->e_shoff);
    538         if (RT_SUCCESS(rc))
    539         {
    540             /*
    541              * Allocate & read in the section string table.
    542              */
    543             pSecHdr = (Shdr *)((char *)*ppvSecHdr + SecHdrIndex * pHdr->e_shentsize);
    544             if (pSecHdr->sh_size > 0)
    545             {
    546                 *pcbSecHdrStr = pSecHdr->sh_size;
    547                 *ppszSecHdrStr = (char *)GetMemoryChunk(pVBoxCore, *pcbSecHdrStr);
    548                 if (*ppszSecHdrStr)
    549                 {
    550                     rc = ReadFileAt(hFile, *ppszSecHdrStr, *pcbSecHdrStr, pSecHdr->sh_offset);
    551                     if (RT_SUCCESS(rc))
    552                     {
    553                         (*ppszSecHdrStr)[*pcbSecHdrStr - 1] = '\0';
    554                         return VINF_SUCCESS;
    555                     }
    556                     else
    557                         CORELOGREL(("ElfReadSecHdr: failed to read section header string table at %u\n", pSecHdr->sh_offset));
    558                 }
    559                 else
    560                     rc = VERR_NO_MEMORY;
    561             }
    562             else
    563             {
    564                 CORELOGREL(("ElfReadSecHdr: invalid section header string table size\n"));
    565                 rc = VERR_BAD_EXE_FORMAT;
    566             }
    567         }
    568         else
    569             CORELOGREL(("ElfReadSecHdr: failed to read section header at %u\n", pHdr->e_shoff));
    570 
    571         *ppvSecHdr = NULL;
    572         *pcbSecHdr = 0;
    573     }
    574     else
    575         rc = VERR_NO_MEMORY;
    576 
    577349    return rc;
    578350}
     
    853625                                {
    854626                                    size_t cb = RT_MIN(sizeof(achBuf), pCur->pMap.pr_size - k);
    855                                     int rc2 = ReadProcAddrSpace(pVBoxProc, &achBuf, cb, pCur->pMap.pr_vaddr + k);
     627                                    int rc2 = ReadProcAddrSpace(pVBoxProc, pCur->pMap.pr_vaddr + k, &achBuf, cb);
    856628                                    if (RT_FAILURE(rc2))
    857629                                    {
     
    17081480            {
    17091481                size_t cb = RT_MIN(sizeof(achBuf), pMapInfo->pMap.pr_size - k);
    1710                 int rc2 = ReadProcAddrSpace(pVBoxProc, &achBuf, cb, pMapInfo->pMap.pr_vaddr + k);
     1482                int rc2 = ReadProcAddrSpace(pVBoxProc, pMapInfo->pMap.pr_vaddr + k, &achBuf, cb);
    17111483                if (RT_FAILURE(rc2))
    17121484                {
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