VirtualBox

Ignore:
Timestamp:
Sep 25, 2020 1:02:31 PM (5 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
140566
Message:

Runtime/r0drv/dbgfkrnlinfo-r0drv-darwin: Starting with BigSur, each segment can have a different load displacement. Account for that, bugref:9836

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r0drv/darwin/dbgkrnlinfo-r0drv-darwin.cpp

    r85341 r86290  
    182182    /** Size of the text segment. */
    183183    uintptr_t           cbTextSeg;
    184     /** Offset between link address and actual load address. */
     184    /** Offset between link address and actual load address of the text segment. */
    185185    uintptr_t           offLoad;
    186186    /** The minimum OS version (A.B.C; A is 16 bits, B & C each 8 bits). */
     
    212212    /** Section pointer table (points into the load commands). */
    213213    MY_SEGMENT_COMMAND const *apSegments[MACHO_MAX_SECT / 2];
     214    /** Load displacement table for each segment. */
     215    uintptr_t          aoffLoadSegments[MACHO_MAX_SECT / 2];
    214216    /** Section pointer table (points into the load commands). */
    215217    MY_SECTION const   *apSections[MACHO_MAX_SECT];
     218    /** Mapping table to quickly get to a segment from MY_NLIST::n_sect. */
     219    uint8_t            auSections2Segment[MACHO_MAX_SECT];
    216220    /** @} */
    217221
     
    249253
    250254/**
     255 * Looks up a kernel symbol record.
     256 *
     257 * @returns Pointer to the symbol record or NULL if not found.
     258 * @param   pThis               The internal scratch data.
     259 * @param   pszSymbol           The symbol to resolve.  Automatically prefixed
     260 *                              with an underscore.
     261 */
     262static MY_NLIST const *rtR0DbgKrnlDarwinLookupSym(RTDBGKRNLINFOINT *pThis, const char *pszSymbol)
     263{
     264    uint32_t const  cSyms = pThis->cSyms;
     265    MY_NLIST const *pSym = pThis->paSyms;
     266
     267#if 1
     268    /* linear search. */
     269    for (uint32_t iSym = 0; iSym < cSyms; iSym++, pSym++)
     270    {
     271        if (pSym->n_type & MACHO_N_STAB)
     272            continue;
     273
     274        const char *pszTabName= &pThis->pachStrTab[(uint32_t)pSym->n_un.n_strx];
     275        if (   *pszTabName == '_'
     276            && strcmp(pszTabName + 1, pszSymbol) == 0)
     277            return pSym;
     278    }
     279#else
     280    /** @todo binary search. */
     281#endif
     282
     283    return NULL;
     284}
     285
     286
     287/**
    251288 * Looks up a kernel symbol.
    252289 *
     
    258295static uintptr_t rtR0DbgKrnlDarwinLookup(RTDBGKRNLINFOINT *pThis, const char *pszSymbol)
    259296{
    260     uint32_t const  cSyms = pThis->cSyms;
    261     MY_NLIST const *pSym = pThis->paSyms;
    262 
    263 #if 1
    264     /* linear search. */
    265     for (uint32_t iSym = 0; iSym < cSyms; iSym++, pSym++)
    266     {
    267         if (pSym->n_type & MACHO_N_STAB)
    268             continue;
    269 
    270         const char *pszTabName= &pThis->pachStrTab[(uint32_t)pSym->n_un.n_strx];
    271         if (   *pszTabName == '_'
    272             && strcmp(pszTabName + 1, pszSymbol) == 0)
    273             return pSym->n_value + pThis->offLoad;
    274     }
    275 #else
    276     /** @todo binary search. */
    277 
    278 #endif
     297    MY_NLIST const *pSym = rtR0DbgKrnlDarwinLookupSym(pThis, pszSymbol);
     298    if (pSym)
     299    {
     300        uint8_t idxSeg = pThis->auSections2Segment[pSym->n_sect];
     301        if (pThis->aoffLoadSegments[idxSeg] != UINTPTR_MAX)
     302            return pSym->n_value + pThis->aoffLoadSegments[idxSeg];
     303    }
     304
    279305    return 0;
    280306}
     
    751777                    if (pThis->cSections >= RT_ELEMENTS(pThis->apSections))
    752778                        RETURN_VERR_BAD_EXE_FORMAT;
     779                    pThis->auSections2Segment[pThis->cSections] = pThis->cSegments;
    753780                    pThis->apSections[pThis->cSections++] = &paSects[i];
    754781                }
     
    798825            case LC_VERSION_MIN_WATCHOS:
    799826            case LC_NOTE:
     827            case LC_SEGMENT_SPLIT_INFO:
    800828                break;
    801829
     
    834862            case LC_TWOLEVEL_HINTS:
    835863            case LC_PREBIND_CKSUM:
    836             case LC_SEGMENT_SPLIT_INFO:
    837864            case LC_ENCRYPTION_INFO:
    838865                RETURN_VERR_LDR_UNEXPECTED;
     
    11111138    pThis->hFile = NIL_RTFILE;
    11121139
     1140    for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aoffLoadSegments); i++)
     1141        pThis->aoffLoadSegments[i] = UINTPTR_MAX;
     1142
    11131143    int rc = RTFileOpen(&pThis->hFile, pszKernelFile, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
    11141144    if (RT_SUCCESS(rc))
     
    11231153        /*
    11241154         * Determine the load displacement (10.8 kernels are PIE).
     1155         *
     1156         * Starting with 11.0 (BigSur) all segments can have different load displacements
     1157         * so determine the displacements from known symbols.
    11251158         */
    1126         uintptr_t uLinkAddr = rtR0DbgKrnlDarwinLookup(pThis, "kernel_map");
    1127         if (uLinkAddr != 0)
    1128             pThis->offLoad = (uintptr_t)&kernel_map - uLinkAddr;
     1159        /* __TEXT */
     1160        MY_NLIST const *pSym = rtR0DbgKrnlDarwinLookupSym(pThis, "vm_map_unwire");
     1161        if (pSym)
     1162        {
     1163            uint8_t idxSeg = pThis->auSections2Segment[pSym->n_sect];
     1164            pThis->aoffLoadSegments[idxSeg] = (uintptr_t)&vm_map_unwire - pSym->n_value;
     1165        }
     1166
     1167        /* __HIB */
     1168        pSym = rtR0DbgKrnlDarwinLookupSym(pThis, "kernel_map");
     1169        if (pSym)
     1170        {
     1171            uint8_t idxSeg = pThis->auSections2Segment[pSym->n_sect];
     1172            pThis->aoffLoadSegments[idxSeg] = (uintptr_t)&kernel_map - pSym->n_value;
     1173        }
     1174
     1175        /* __DATA */
     1176        pSym = rtR0DbgKrnlDarwinLookupSym(pThis, "gIOServicePlane");
     1177        if (pSym)
     1178        {
     1179            uint8_t idxSeg = pThis->auSections2Segment[pSym->n_sect];
     1180            pThis->aoffLoadSegments[idxSeg] = (uintptr_t)&gIOServicePlane - pSym->n_value;
     1181        }
    11291182#endif
    11301183        rc = rtR0DbgKrnlDarwinCheckStandardSymbols(pThis, pszKernelFile);
     
    12041257    pThis->hFile    = NIL_RTFILE;
    12051258    pThis->fIsInMem = true;
     1259
     1260    for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aoffLoadSegments); i++)
     1261        pThis->aoffLoadSegments[i] = UINTPTR_MAX;
    12061262
    12071263    /*
Note: See TracChangeset for help on using the changeset viewer.

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