VirtualBox

Changeset 47 in kStuff for trunk


Ignore:
Timestamp:
Apr 11, 2012 12:00:12 AM (13 years ago)
Author:
bird
Message:

kLdrModMachO.c: Symbols with an address at the very end of the section/segment is fine. Implemented linker s the standard linker generated symbols.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/kLdr/kLdrModMachO.c

    r44 r47  
    209209                                           const char *pchStrings, KU32 cchStrings, KLDRADDR BaseAddress,
    210210                                           KU32 fFlags, PFNKLDRMODENUMSYMS pfnCallback, void *pvUser);
    211 static int  kldrModMachOObjDoImports(PKLDRMODMACHO pModMachO, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser);
     211static int  kldrModMachOObjDoImports(PKLDRMODMACHO pModMachO, KLDRADDR BaseAddress, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser);
    212212static int  kldrModMachOObjDoFixups(PKLDRMODMACHO pModMachO, void *pvMapping, KLDRADDR NewBaseAddress);
    213213static int  kldrModMachOFixupSectionGeneric32Bit(PKLDRMODMACHO pModMachO, KU8 *pbSectBits, PKLDRMODMACHOSECT pFixupSect,
     
    15401540
    15411541
     1542/**
     1543 * Resolves a linker generated symbol.
     1544 *
     1545 * The Apple linker generates symbols indicating the start and end of sections
     1546 * and segments.  This function checks for these and returns the right value.
     1547 *
     1548 * @returns 0 or KLDR_ERR_SYMBOL_NOT_FOUND.
     1549 * @param   pModMachO           The interpreter module instance.
     1550 * @param   pMod                The generic module instance.
     1551 * @param   pchSymbol           The symbol.
     1552 * @param   cchSymbol           The length of the symbol.
     1553 * @param   BaseAddress         The base address to apply when calculating the
     1554 *                              value.
     1555 * @param   puValue             Where to return the symbol value.
     1556 */
     1557static int kldrModMachOQueryLinkerSymbol(PKLDRMODMACHO pModMachO, PKLDRMOD pMod, const char *pchSymbol, KSIZE cchSymbol,
     1558                                         KLDRADDR BaseAddress, PKLDRADDR puValue)
     1559{
     1560    /*
     1561     * Match possible name prefixes.
     1562     */
     1563    static const struct
     1564    {
     1565        const char *pszPrefix;
     1566        KU8         cchPrefix;
     1567        KBOOL       fSection;
     1568        KBOOL       fStart;
     1569    }   s_aPrefixes[] =
     1570    {
     1571        { "section$start$",  (KU8)sizeof("section$start$") - 1,   K_TRUE,  K_TRUE },
     1572        { "section$end$",    (KU8)sizeof("section$end$") - 1,     K_TRUE,  K_FALSE},
     1573        { "segment$start$",  (KU8)sizeof("segment$start$") - 1,   K_FALSE, K_TRUE },
     1574        { "segment$end$",    (KU8)sizeof("segment$end$") - 1,     K_FALSE, K_FALSE},
     1575    };
     1576    KSIZE       cchSectName = 0;
     1577    const char *pchSectName = "";
     1578    KSIZE       cchSegName  = 0;
     1579    const char *pchSegName  = NULL;
     1580    KU32        iPrefix     = K_ELEMENTS(s_aPrefixes) - 1;
     1581    KU32        iSeg;
     1582    KLDRADDR    uValue;
     1583
     1584    for (;;)
     1585    {
     1586        KU8 const cchPrefix = s_aPrefixes[iPrefix].cchPrefix;
     1587        if (   cchSymbol > cchPrefix
     1588            && kHlpStrNComp(pchSymbol, s_aPrefixes[iPrefix].pszPrefix, cchPrefix) == 0)
     1589        {
     1590            pchSegName = pchSymbol + cchPrefix;
     1591            cchSegName = cchSymbol - cchPrefix;
     1592            break;
     1593        }
     1594
     1595        /* next */
     1596        if (!iPrefix)
     1597            return KLDR_ERR_SYMBOL_NOT_FOUND;
     1598        iPrefix--;
     1599    }
     1600
     1601    /*
     1602     * Split the remainder into segment and section name, if necessary.
     1603     */
     1604    if (s_aPrefixes[iPrefix].fSection)
     1605    {
     1606        pchSectName = kHlpMemChr(pchSegName, '$', cchSegName);
     1607        if (!pchSectName)
     1608            return KLDR_ERR_SYMBOL_NOT_FOUND;
     1609        cchSegName  = pchSectName - pchSegName;
     1610        pchSectName++;
     1611        cchSectName = cchSymbol - (pchSectName - pchSymbol);
     1612    }
     1613
     1614    /*
     1615     * Locate the segment.
     1616     */
     1617    iSeg = pMod->cSegments;
     1618    if (!iSeg)
     1619        return KLDR_ERR_SYMBOL_NOT_FOUND;
     1620    while (   pMod->aSegments[iSeg].cchName != cchSegName
     1621           || kHlpMemComp(pMod->aSegments[iSeg].pchName, pchSegName, cchSegName) != 0)
     1622    {
     1623        if (!iSeg)
     1624            return KLDR_ERR_SYMBOL_NOT_FOUND;
     1625        iSeg--;
     1626    }
     1627
     1628    if (!s_aPrefixes[iPrefix].fSection)
     1629    {
     1630        /*
     1631         * Calculate the segment start/end address.
     1632         */
     1633        uValue = pMod->aSegments[iSeg].LinkAddress;
     1634        if (!s_aPrefixes[iPrefix].fStart)
     1635            uValue += pMod->aSegments[iSeg].cb;
     1636    }
     1637    else
     1638    {
     1639        /*
     1640         * Locate the section.
     1641         */
     1642        KU32 iSect = pModMachO->aSegments[iSeg].cSections;
     1643        if (!iSect)
     1644            return KLDR_ERR_SYMBOL_NOT_FOUND;
     1645        for (;;)
     1646        {
     1647            section_32_t *pSect = (section_32_t *)pModMachO->aSegments[iSeg].paSections[iSect].pvMachoSection;
     1648            if (   cchSectName <= sizeof(pSect->sectname)
     1649                && kHlpMemComp(pSect->sectname, pchSectName, cchSectName) == 0
     1650                && (   cchSectName == sizeof(pSect->sectname)
     1651                    || pSect->sectname[cchSectName] == '\0') )
     1652                break;
     1653            /* next */
     1654            if (!iSect)
     1655                return KLDR_ERR_SYMBOL_NOT_FOUND;
     1656            iSect--;
     1657        }
     1658
     1659        if (   pModMachO->Hdr.magic == IMAGE_MACHO32_SIGNATURE
     1660            || pModMachO->Hdr.magic == IMAGE_MACHO32_SIGNATURE_OE)
     1661        {
     1662            section_64_t *pSect = (section_64_t *)pModMachO->aSegments[iSeg].paSections[iSect].pvMachoSection;
     1663            uValue = pSect->addr;
     1664            if (!s_aPrefixes[iPrefix].fStart)
     1665                uValue += pSect->size;
     1666        }
     1667        else
     1668        {
     1669            section_64_t *pSect = (section_64_t *)pModMachO->aSegments[iSeg].paSections[iSect].pvMachoSection;
     1670            uValue = pSect->addr;
     1671            if (!s_aPrefixes[iPrefix].fStart)
     1672                uValue += pSect->size;
     1673        }
     1674    }
     1675
     1676    /*
     1677     * Adjust the value from link to rva + base.
     1678     */
     1679    uValue -= pMod->aSegments[iSeg].LinkAddress - pMod->aSegments[iSeg].RVA;
     1680    uValue += BaseAddress;
     1681    if (puValue)
     1682        *puValue = uValue;
     1683
     1684    return 0;
     1685}
     1686
    15421687
    15431688/** @copydoc kLdrModQuerySymbol */
     
    15831728                                                    pModMachO->pchStrings, pModMachO->cchStrings, BaseAddress, iSymbol, pchSymbol,
    15841729                                                    cchSymbol, puValue, pfKind);
     1730        }
     1731
     1732        /*
     1733         * Check for link-editor generated symbols and supply what we can.
     1734         *
     1735         * As small service to clients that insists on adding a '_' prefix
     1736         * before querying symbols, we will ignore the prefix.
     1737         */
     1738        if (  rc == KLDR_ERR_SYMBOL_NOT_FOUND
     1739            && cchSymbol > sizeof("section$end$") - 1
     1740            && (    pchSymbol[0] == 's'
     1741                || (pchSymbol[1] == 's' && pchSymbol[0] == '_') )
     1742            && kHlpMemChr(pchSymbol, '$', cchSymbol) )
     1743        {
     1744            if (pchSymbol[0] == '_')
     1745                rc = kldrModMachOQueryLinkerSymbol(pModMachO, pMod, pchSymbol + 1, cchSymbol - 1, BaseAddress, puValue);
     1746            else
     1747                rc = kldrModMachOQueryLinkerSymbol(pModMachO, pMod, pchSymbol, cchSymbol, BaseAddress, puValue);
    15851748        }
    15861749    }
     
    19642127
    19652128                uValue = paSyms[iSym].n_value - pModMachO->LinkAddress;
    1966                 if (uValue - pSect->RVA >= pSect->cb)
     2129                if (uValue - pSect->RVA > pSect->cb)
    19672130                    return KLDR_ERR_MACHO_BAD_SYMBOL;
    19682131                uValue += BaseAddress;
     
    20752238
    20762239                uValue = paSyms[iSym].n_value - pModMachO->LinkAddress;
    2077                 if (uValue - pSect->RVA >= pSect->cb)
     2240                if (uValue - pSect->RVA > pSect->cb)
    20782241                    return KLDR_ERR_MACHO_BAD_SYMBOL;
    20792242                uValue += BaseAddress;
     
    24052568 * @param   pvUser          User argument to the callback.
    24062569 */
    2407 static int  kldrModMachOObjDoImports(PKLDRMODMACHO pModMachO, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser)
     2570static int  kldrModMachOObjDoImports(PKLDRMODMACHO pModMachO, KLDRADDR BaseAddress, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser)
    24082571{
    24092572    const KU32 cSyms = pModMachO->cSymbols;
     
    24422605                KLDRMODMACHO_CHECK_RETURN(!(paSyms[iSym].n_desc & N_REF_TO_WEAK), KLDR_ERR_TODO);
    24432606
    2444                 /* Get the symbol name and try resolve it. */
     2607                /* Get the symbol name. */
    24452608                if ((KU32)paSyms[iSym].n_un.n_strx >= pModMachO->cchStrings)
    24462609                    return KLDR_ERR_MACHO_BAD_SYMBOL;
    24472610                pszSymbol = &pModMachO->pchStrings[paSyms[iSym].n_un.n_strx];
    24482611                cchSymbol = kHlpStrLen(pszSymbol);
    2449                 rc = pfnGetImport(pModMachO->pMod, NIL_KLDRMOD_IMPORT, iSym, pszSymbol, cchSymbol, NULL,
    2450                                   &Value, &fKind, pvUser);
     2612
     2613                /* Check for linker defined symbols relating to sections and segments. */
     2614                if (   cchSymbol > sizeof("section$end$") - 1
     2615                    && *pszSymbol == 's'
     2616                    && kHlpMemChr(pszSymbol, '$', cchSymbol))
     2617                    rc = kldrModMachOQueryLinkerSymbol(pModMachO, pModMachO->pMod, pszSymbol, cchSymbol, BaseAddress, &Value);
     2618                else
     2619                    rc = KLDR_ERR_SYMBOL_NOT_FOUND;
     2620
     2621                /* Ask the user for an address to the symbol. */
     2622                if (rc)
     2623                    rc = pfnGetImport(pModMachO->pMod, NIL_KLDRMOD_IMPORT, iSym, pszSymbol, cchSymbol, NULL,
     2624                                      &Value, &fKind, pvUser);
    24512625                if (rc)
    24522626                {
     
    24922666                KLDRMODMACHO_CHECK_RETURN(!(paSyms[iSym].n_desc & N_REF_TO_WEAK), KLDR_ERR_TODO);
    24932667
    2494                  /* Get the symbol name and try resolve it. */
     2668                 /* Get the symbol name. */
    24952669                if (paSyms[iSym].n_un.n_strx >= pModMachO->cchStrings)
    24962670                    return KLDR_ERR_MACHO_BAD_SYMBOL;
    24972671                pszSymbol = &pModMachO->pchStrings[paSyms[iSym].n_un.n_strx];
    24982672                cchSymbol = kHlpStrLen(pszSymbol);
    2499                 rc = pfnGetImport(pModMachO->pMod, NIL_KLDRMOD_IMPORT, iSym, pszSymbol, cchSymbol, NULL,
    2500                                   &Value, &fKind, pvUser);
     2673
     2674                /* Check for linker defined symbols relating to sections and segments. */
     2675                if (   cchSymbol > sizeof("section$end$") - 1
     2676                    && *pszSymbol == 's'
     2677                    && kHlpMemChr(pszSymbol, '$', cchSymbol))
     2678                    rc = kldrModMachOQueryLinkerSymbol(pModMachO, pModMachO->pMod, pszSymbol, cchSymbol, BaseAddress, &Value);
     2679                else
     2680                    rc = KLDR_ERR_SYMBOL_NOT_FOUND;
     2681
     2682                /* Ask the user for an address to the symbol. */
     2683                if (rc)
     2684                    rc = pfnGetImport(pModMachO->pMod, NIL_KLDRMOD_IMPORT, iSym, pszSymbol, cchSymbol, NULL,
     2685                                      &Value, &fKind, pvUser);
    25012686                if (rc)
    25022687                {
     
    33393524    if (pModMachO->Hdr.filetype == MH_OBJECT)
    33403525    {
    3341         rc = kldrModMachOObjDoImports(pModMachO, pfnGetImport, pvUser);
     3526        rc = kldrModMachOObjDoImports(pModMachO, NewBaseAddress, pfnGetImport, pvUser);
    33423527        if (!rc)
    33433528            rc = kldrModMachOObjDoFixups(pModMachO, pvBits, NewBaseAddress);
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