- Timestamp:
- Apr 11, 2012 12:00:12 AM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kLdr/kLdrModMachO.c
r44 r47 209 209 const char *pchStrings, KU32 cchStrings, KLDRADDR BaseAddress, 210 210 KU32 fFlags, PFNKLDRMODENUMSYMS pfnCallback, void *pvUser); 211 static int kldrModMachOObjDoImports(PKLDRMODMACHO pModMachO, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser);211 static int kldrModMachOObjDoImports(PKLDRMODMACHO pModMachO, KLDRADDR BaseAddress, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser); 212 212 static int kldrModMachOObjDoFixups(PKLDRMODMACHO pModMachO, void *pvMapping, KLDRADDR NewBaseAddress); 213 213 static int kldrModMachOFixupSectionGeneric32Bit(PKLDRMODMACHO pModMachO, KU8 *pbSectBits, PKLDRMODMACHOSECT pFixupSect, … … 1540 1540 1541 1541 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 */ 1557 static 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 1542 1687 1543 1688 /** @copydoc kLdrModQuerySymbol */ … … 1583 1728 pModMachO->pchStrings, pModMachO->cchStrings, BaseAddress, iSymbol, pchSymbol, 1584 1729 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); 1585 1748 } 1586 1749 } … … 1964 2127 1965 2128 uValue = paSyms[iSym].n_value - pModMachO->LinkAddress; 1966 if (uValue - pSect->RVA > =pSect->cb)2129 if (uValue - pSect->RVA > pSect->cb) 1967 2130 return KLDR_ERR_MACHO_BAD_SYMBOL; 1968 2131 uValue += BaseAddress; … … 2075 2238 2076 2239 uValue = paSyms[iSym].n_value - pModMachO->LinkAddress; 2077 if (uValue - pSect->RVA > =pSect->cb)2240 if (uValue - pSect->RVA > pSect->cb) 2078 2241 return KLDR_ERR_MACHO_BAD_SYMBOL; 2079 2242 uValue += BaseAddress; … … 2405 2568 * @param pvUser User argument to the callback. 2406 2569 */ 2407 static int kldrModMachOObjDoImports(PKLDRMODMACHO pModMachO, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser)2570 static int kldrModMachOObjDoImports(PKLDRMODMACHO pModMachO, KLDRADDR BaseAddress, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser) 2408 2571 { 2409 2572 const KU32 cSyms = pModMachO->cSymbols; … … 2442 2605 KLDRMODMACHO_CHECK_RETURN(!(paSyms[iSym].n_desc & N_REF_TO_WEAK), KLDR_ERR_TODO); 2443 2606 2444 /* Get the symbol name and try resolve it. */2607 /* Get the symbol name. */ 2445 2608 if ((KU32)paSyms[iSym].n_un.n_strx >= pModMachO->cchStrings) 2446 2609 return KLDR_ERR_MACHO_BAD_SYMBOL; 2447 2610 pszSymbol = &pModMachO->pchStrings[paSyms[iSym].n_un.n_strx]; 2448 2611 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); 2451 2625 if (rc) 2452 2626 { … … 2492 2666 KLDRMODMACHO_CHECK_RETURN(!(paSyms[iSym].n_desc & N_REF_TO_WEAK), KLDR_ERR_TODO); 2493 2667 2494 /* Get the symbol name and try resolve it. */2668 /* Get the symbol name. */ 2495 2669 if (paSyms[iSym].n_un.n_strx >= pModMachO->cchStrings) 2496 2670 return KLDR_ERR_MACHO_BAD_SYMBOL; 2497 2671 pszSymbol = &pModMachO->pchStrings[paSyms[iSym].n_un.n_strx]; 2498 2672 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); 2501 2686 if (rc) 2502 2687 { … … 3339 3524 if (pModMachO->Hdr.filetype == MH_OBJECT) 3340 3525 { 3341 rc = kldrModMachOObjDoImports(pModMachO, pfnGetImport, pvUser);3526 rc = kldrModMachOObjDoImports(pModMachO, NewBaseAddress, pfnGetImport, pvUser); 3342 3527 if (!rc) 3343 3528 rc = kldrModMachOObjDoFixups(pModMachO, pvBits, NewBaseAddress);
Note:
See TracChangeset
for help on using the changeset viewer.