Changeset 51 for trunk/kLdr/kLdrModMachO.c
- Timestamp:
- Jul 9, 2013, 6:16:31 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kLdr/kLdrModMachO.c
r49 r51 103 103 typedef struct KLDRMODMACHOSEG 104 104 { 105 /** The orignal segment number (in case we had to resort it). */ 106 KU32 iOrgSegNo; 105 107 /** The number of sections in the segment. */ 106 108 KU32 cSections; … … 188 190 static int kldrModMachODoCreate(PKRDR pRdr, KLDRFOFF offImage, PKLDRMODMACHO *ppMod); 189 191 static int kldrModMachOPreParseLoadCommands(KU8 *pbLoadCommands, const mach_header_32_t *pHdr, PKRDR pRdr, KLDRFOFF offImage, 190 KU32 *pcSegments, KU32 *pcSections, KU32 *pcbStringPool, PKBOOL pfCanLoad); 192 KU32 *pcSegments, KU32 *pcSections, KU32 *pcbStringPool, PKBOOL pfCanLoad, 193 PKLDRADDR pLinkAddress); 191 194 static int kldrModMachOParseLoadCommands(PKLDRMODMACHO pModMachO, char *pbStringPool, KU32 cbStringPool); 192 195 static int kldrModMachOAdjustBaseAddress(PKLDRMODMACHO pModMachO, PKLDRADDR pBaseAddress); … … 292 295 KBOOL fMakeGot; 293 296 KBOOL fCanLoad = K_TRUE; 297 KLDRADDR LinkAddress; 294 298 KU8 cbJmpStub; 295 299 int rc; … … 352 356 if (!rc) 353 357 rc = kldrModMachOPreParseLoadCommands(pbLoadCommands, &s.Hdr32, pRdr, offImage, 354 &cSegments, &cSections, &cbStringPool, &fCanLoad );358 &cSegments, &cSections, &cbStringPool, &fCanLoad, &LinkAddress); 355 359 if (rc) 356 360 { … … 456 460 || s.Hdr32.magic == IMAGE_MACHO32_SIGNATURE_OE) 457 461 pModMachO->Hdr.reserved = 0; 458 pModMachO->LinkAddress = 0;462 pModMachO->LinkAddress = LinkAddress; 459 463 pModMachO->cbImage = 0; 460 464 pModMachO->fCanLoad = fCanLoad; … … 504 508 * @param pcbStringPool Where to store the string pool size. 505 509 * @param pfCanLoad Where to store the can-load-image indicator. 510 * @param pLinkAddress Where to store the image link address (i.e. the 511 * lowest segment address). 506 512 */ 507 513 static int kldrModMachOPreParseLoadCommands(KU8 *pbLoadCommands, const mach_header_32_t *pHdr, PKRDR pRdr, KLDRFOFF offImage, 508 KU32 *pcSegments, KU32 *pcSections, KU32 *pcbStringPool, PKBOOL pfCanLoad) 514 KU32 *pcSegments, KU32 *pcSections, KU32 *pcbStringPool, PKBOOL pfCanLoad, 515 PKLDRADDR pLinkAddress) 509 516 { 510 517 union … … 534 541 *pcbStringPool = 0; 535 542 *pfCanLoad = K_TRUE; 543 *pLinkAddress = ~(KLDRADDR)0; 536 544 537 545 while (cLeft-- > 0) … … 696 704 697 705 698 /* count segments and strings */706 /* count segments and strings, calculate image link address. */ 699 707 switch (pHdr->filetype) 700 708 { … … 712 720 713 721 /* a new segment? */ 714 if ( !cSegments722 if ( cSections == 1 715 723 || kHlpStrNComp(pSect->segname, (pSect - 1)->segname, sizeof(pSect->segname))) 716 724 { … … 729 737 cSegments++; 730 738 cbStringPool += kHlpStrNLen(&pSect->segname[0], sizeof(pSect->segname)) + 1; 739 740 /* Link address lower? */ 741 if (*pLinkAddress > u.pSeg32->vmaddr) 742 *pLinkAddress = u.pSeg32->vmaddr; 731 743 } 732 744 break; … … 888 900 889 901 890 /* count segments and strings */902 /* count segments and strings, calculate image link address. */ 891 903 switch (pHdr->filetype) 892 904 { … … 904 916 905 917 /* a new segment? */ 906 if ( !cSe gments918 if ( !cSections == 1 907 919 || kHlpStrNComp(pSect->segname, (pSect - 1)->segname, sizeof(pSect->segname))) 908 920 { … … 921 933 cSegments++; 922 934 cbStringPool += kHlpStrNLen(&pSect->segname[0], sizeof(pSect->segname)) + 1; 935 936 /* Link address lower? */ 937 if (*pLinkAddress > u.pSeg64->vmaddr) 938 *pLinkAddress = u.pSeg64->vmaddr; 923 939 } 924 940 break; … … 1100 1116 PKLDRMODMACHOSECT pSectExtra = pModMachO->paSections; 1101 1117 const KU32 cSegments = pModMachO->pMod->cSegments; 1102 KU32 i ;1118 KU32 i, c; 1103 1119 1104 1120 while (cLeft-- > 0) … … 1119 1135 KU32 cSectionsLeft; 1120 1136 1121 pModMachO->LinkAddress = u.pSeg32->vmaddr;1137 kHlpAssert(u.pSeg32->vmaddr >= pModMachO->LinkAddress); 1122 1138 1123 1139 /* … … 1254 1270 KU32 cSectionsLeft; 1255 1271 1256 pModMachO->LinkAddress = u.pSeg64->vmaddr;1272 kHlpAssert(u.pSeg64->vmaddr >= pModMachO->LinkAddress); 1257 1273 1258 1274 /* … … 1332 1348 pSeg->MapAddress = 0; 1333 1349 1350 pSegExtra->iOrgSegNo = pSegExtra - &pModMachO->aSegments[0]; 1334 1351 pSegExtra->cSections = 0; 1335 1352 pSegExtra->paSections = pSectExtra; … … 1408 1425 if (pSegExtra != &pModMachO->aSegments[0]) 1409 1426 pSegExtra[-1].cSections = pSectExtra - pSegExtra[-1].paSections; 1427 1428 /* 1429 * Make sure the segments are sorted, or we'll get screwed further down. 1430 */ 1431 c = pSeg - &pModMachO->pMod->aSegments[0]; 1432 pSeg = &pModMachO->pMod->aSegments[0]; 1433 for (i = 0; i < c - 1; i++) 1434 { 1435 KLDRADDR LinkAddress = pSeg[i + 1].LinkAddress; 1436 if (LinkAddress < pSeg[i].LinkAddress) 1437 { 1438 /* Gotta move the next segment, find the correct location. */ 1439 KLDRMODMACHOSEG TmpSegExtra; 1440 KLDRSEG TmpSeg; 1441 KU32 j = i; 1442 KU32 cShift = 1; 1443 1444 while (j > 0 && LinkAddress < pSeg[j - 1].LinkAddress) 1445 j--, cShift++; 1446 1447 TmpSegExtra = pModMachO->aSegments[i + 1]; 1448 kHlpMemMove(&pModMachO->aSegments[j + 1], &pModMachO->aSegments[j], 1449 cShift * sizeof(pModMachO->aSegments[0])); 1450 pModMachO->aSegments[j] = TmpSegExtra; 1451 1452 TmpSeg = pSeg[i + 1]; 1453 kHlpMemMove(&pSeg[j + 1], &pSeg[j], cShift * sizeof(pSeg[0])); 1454 pSeg[j] = TmpSeg; 1455 } 1456 } 1457 pSeg = &pModMachO->pMod->aSegments[c]; 1410 1458 1411 1459 /* … … 1454 1502 pSeg->MapAddress = 0; 1455 1503 1504 pSegExtra->iOrgSegNo = KU32_MAX; 1456 1505 pSegExtra->cSections = 0; 1457 1506 pSegExtra->paSections = NULL;
Note:
See TracChangeset
for help on using the changeset viewer.