Changeset 59
- Timestamp:
- Oct 13, 2013, 12:53:10 AM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kLdr/kLdrModMachO.c
r58 r59 515 515 * out the module instance. 516 516 * 517 * The conversion that's preformed is format endian to host endian. 518 * The preparsing has to do with segment counting, section counting and string pool sizing. 517 * The conversion that's preformed is format endian to host endian. The 518 * preparsing has to do with segment counting, section counting and string pool 519 * sizing. 520 * 521 * Segment are created in two different ways, depending on the file type. 522 * 523 * For object files there is only one segment command without a given segment 524 * name. The sections inside that segment have different segment names and are 525 * not sorted by their segname attribute. We create one segment for each 526 * section, with the segment name being 'segname.sectname' in order to hopefully 527 * keep the names unique. Debug sections does not get segments. 528 * 529 * For non-object files, one kLdr segment is created for each Mach-O segment. 530 * Debug segments is not exposed by kLdr via the kLdr segment table, but via the 531 * debug enumeration callback API. 519 532 * 520 533 * @returns 0 on success. … … 592 605 KU32 cSectionsLeft = pSrcSeg->nsects; 593 606 KU64 offSect = 0; 594 KBOOL fSkipSeg = !kHlpStrComp(pSrcSeg->segname, "__DWARF")595 || (cSectionsLeft > 0 && (pFirstSect->flags & S_ATTR_DEBUG));596 607 597 608 /* Convert and verify the segment. */ … … 614 625 #define VALIDATE_AND_ADD_SEGMENT(a_cBits) \ 615 626 do { \ 627 KBOOL fSkipSeg = !kHlpStrComp(pSrcSeg->segname, "__DWARF") /* Note: Not for non-object files. */ \ 628 || (cSectionsLeft > 0 && (pFirstSect->flags & S_ATTR_DEBUG)); \ 629 \ 616 630 KLDRMODMACHO_CHECK_RETURN( pSrcSeg->filesize == 0 \ 617 631 || ( pSrcSeg->fileoff <= cbFile \ … … 632 646 cSegmentCommands++; \ 633 647 \ 634 /* add the segment. */ \635 if (!fSkipSeg ) \648 /* Add the segment, if not object file. */ \ 649 if (!fSkipSeg && pHdr->filetype != MH_OBJECT) \ 636 650 { \ 637 651 cbStringPool += kHlpStrNLen(&pSrcSeg->segname[0], sizeof(pSrcSeg->segname)) + 1; \ … … 672 686 \ 673 687 /* validate */ \ 674 KLDRMODMACHO_CHECK_RETURN(!kHlpStrComp(pSect->segname, pSrcSeg->segname),\ 675 KLDR_ERR_MACHO_BAD_SECTION); \ 688 if (pHdr->filetype != MH_OBJECT) \ 689 KLDRMODMACHO_CHECK_RETURN(!kHlpStrComp(pSect->segname, pSrcSeg->segname),\ 690 KLDR_ERR_MACHO_BAD_SECTION); \ 676 691 \ 677 692 switch (pSect->flags & SECTION_TYPE) \ … … 786 801 } \ 787 802 \ 788 /* validate against file type (pointless?) and count the section. */ \803 /* Validate against file type (pointless?) and count the section, for object files add segment. */ \ 789 804 switch (pHdr->filetype) \ 790 805 { \ 791 806 case MH_OBJECT: \ 807 if ( !(pSect->flags & S_ATTR_DEBUG) \ 808 && kHlpStrComp(pSect->segname, "__DWARF")) \ 809 { \ 810 cbStringPool += kHlpStrNLen(&pSect->segname[0], sizeof(pSect->segname)) + 1; \ 811 cbStringPool += kHlpStrNLen(&pSect->sectname[0], sizeof(pSect->sectname)) + 1; \ 812 cSegments++; \ 813 \ 814 /* Link address lower? Very unlikely. */ \ 815 if (*pLinkAddress > pSect->addr) \ 816 *pLinkAddress = pSect->addr; \ 817 } \ 818 /* fall thru */ \ 792 819 case MH_EXECUTE: \ 793 820 case MH_DYLIB: \ … … 819 846 KU32 cSectionsLeft = pSrcSeg->nsects; 820 847 KU64 offSect = 0; 821 KBOOL fSkipSeg = !kHlpStrComp(pSrcSeg->segname, "__DWARF")822 || (cSectionsLeft > 0 && (pFirstSect->flags & S_ATTR_DEBUG));823 848 824 849 /* Convert and verify the segment. */ … … 1072 1097 KU32 cSectionsLeft = pSrcSeg->nsects; 1073 1098 1099 /* Adds a segment, used by the macro below and thus shared with the 64-bit segment variant. */ 1100 #define NEW_SEGMENT(a_cBits, a_achName1, a_fObjFile, a_achName2, a_SegAddr, a_cbSeg, a_fFileBits, a_offFile, a_cbFile) \ 1101 do { \ 1102 pDstSeg->pvUser = NULL; \ 1103 pDstSeg->pchName = pbStringPool; \ 1104 pDstSeg->cchName = (KU32)kHlpStrNLen(a_achName1, sizeof(a_achName1)); \ 1105 kHlpMemCopy(pbStringPool, a_achName1, pDstSeg->cchName); \ 1106 pbStringPool += pDstSeg->cchName; \ 1107 if (a_fObjFile) \ 1108 { /* MH_OBJECT: Add '.sectname' - sections aren't sorted by segments. */ \ 1109 KSIZE cchName2 = kHlpStrNLen(a_achName2, sizeof(a_achName2)); \ 1110 *pbStringPool++ = '.'; \ 1111 kHlpMemCopy(pbStringPool, a_achName2, cchName2); \ 1112 pbStringPool += cchName2; \ 1113 pDstSeg->cchName += cchName2; \ 1114 } \ 1115 *pbStringPool++ = '\0'; \ 1116 pDstSeg->SelFlat = 0; \ 1117 pDstSeg->Sel16bit = 0; \ 1118 pDstSeg->fFlags = 0; \ 1119 pDstSeg->enmProt = KPROT_EXECUTE_WRITECOPY; /** @todo fixme! */ \ 1120 pDstSeg->cb = (a_cbSeg); \ 1121 pDstSeg->Alignment = 1; /* updated while parsing sections. */ \ 1122 pDstSeg->LinkAddress = (a_SegAddr); \ 1123 if (a_fFileBits) \ 1124 { \ 1125 pDstSeg->offFile = (a_offFile) + pModMachO->offImage; \ 1126 pDstSeg->cbFile = (a_cbFile); \ 1127 } \ 1128 else \ 1129 { \ 1130 pDstSeg->offFile = -1; \ 1131 pDstSeg->cbFile = -1; \ 1132 } \ 1133 pDstSeg->RVA = (a_SegAddr) - pModMachO->LinkAddress; \ 1134 pDstSeg->cbMapped = 0; \ 1135 pDstSeg->MapAddress = 0; \ 1136 \ 1137 pSegExtra->iOrgSegNo = pSegExtra - &pModMachO->aSegments[0]; \ 1138 pSegExtra->cSections = 0; \ 1139 pSegExtra->paSections = pSectExtra; \ 1140 } while (0) 1141 1142 /* Closes the new segment - parter of NEW_SEGMENT. */ 1143 #define CLOSE_SEGMENT() \ 1144 do { \ 1145 pSegExtra->cSections = pSectExtra - pSegExtra->paSections; \ 1146 pSegExtra++; \ 1147 pDstSeg++; \ 1148 } while (0) 1149 1150 1074 1151 /* Shared with the 64-bit variant. */ 1075 1152 #define ADD_SEGMENT_AND_ITS_SECTIONS(a_cBits) \ 1076 1153 do { \ 1077 KBOOL fSkipSeg = !kHlpStrComp(pSrcSeg->segname, "__DWARF") \ 1078 || (cSectionsLeft > 0 && (pFirstSect->flags & S_ATTR_DEBUG)); \ 1154 KBOOL fAddSegOuter = K_FALSE; \ 1079 1155 \ 1080 1156 kHlpAssert(pSrcSeg->vmaddr >= pModMachO->LinkAddress); \ … … 1084 1160 * in the preparsing stage. \ 1085 1161 */ \ 1086 for (pSegItr = &pModMachO->pMod->aSegments[0]; pSegItr != pDstSeg; pSegItr++) \ 1087 if (!kHlpStrNComp(pSegItr->pchName, pSrcSeg->segname, sizeof(pSrcSeg->segname))) \ 1088 KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_DUPLICATE_SEGMENT_NAME); \ 1162 if (pModMachO->Hdr.filetype != MH_OBJECT) \ 1163 for (pSegItr = &pModMachO->pMod->aSegments[0]; pSegItr != pDstSeg; pSegItr++) \ 1164 if (!kHlpStrNComp(pSegItr->pchName, pSrcSeg->segname, sizeof(pSrcSeg->segname))) \ 1165 KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_DUPLICATE_SEGMENT_NAME); \ 1089 1166 \ 1090 1167 /* \ 1091 1168 * Create a new segment, unless we're supposed to skip this one. \ 1092 1169 */ \ 1093 if (!fSkipSeg) \ 1170 if ( pModMachO->Hdr.filetype != MH_OBJECT \ 1171 && (cSectionsLeft == 0 || !(pFirstSect->flags & S_ATTR_DEBUG)) \ 1172 && kHlpStrComp(pSrcSeg->segname, "__DWARF") ) \ 1094 1173 { \ 1095 pDstSeg->pvUser = NULL; \ 1096 pDstSeg->pchName = pbStringPool; \ 1097 pDstSeg->cchName = (KU32)kHlpStrNLen(&pSrcSeg->segname[0], sizeof(pSrcSeg->segname)); \ 1098 kHlpMemCopy(pbStringPool, &pSrcSeg->segname[0], pDstSeg->cchName); \ 1099 pbStringPool += pDstSeg->cchName; \ 1100 *pbStringPool++ = '\0'; \ 1101 pDstSeg->SelFlat = 0; \ 1102 pDstSeg->Sel16bit = 0; \ 1103 pDstSeg->fFlags = 0; \ 1104 pDstSeg->enmProt = KPROT_EXECUTE_WRITECOPY; /** @todo fixme! */ \ 1105 pDstSeg->cb = pSrcSeg->vmsize; \ 1106 pDstSeg->Alignment = 1; /* updated while parsing sections. */ \ 1107 pDstSeg->LinkAddress = pSrcSeg->vmaddr; \ 1108 if (pSrcSeg->filesize > 0) \ 1109 { \ 1110 pDstSeg->offFile = pSrcSeg->fileoff + pModMachO->offImage; \ 1111 pDstSeg->cbFile = pSrcSeg->filesize; \ 1112 } \ 1113 else \ 1114 { \ 1115 pDstSeg->offFile = -1; \ 1116 pDstSeg->cbFile = -1; \ 1117 } \ 1118 pDstSeg->RVA = pSrcSeg->vmaddr - pModMachO->LinkAddress; \ 1119 pDstSeg->cbMapped = 0; \ 1120 pDstSeg->MapAddress = 0; \ 1121 \ 1122 pSegExtra->iOrgSegNo = pSegExtra - &pModMachO->aSegments[0]; \ 1123 pSegExtra->cSections = 0; \ 1124 pSegExtra->paSections = pSectExtra; \ 1174 NEW_SEGMENT(a_cBits, pSrcSeg->segname, K_FALSE /*a_fObjFile*/, 0 /*a_achName2*/, \ 1175 pSrcSeg->vmaddr, pSrcSeg->vmsize, \ 1176 pSrcSeg->filesize != 0, pSrcSeg->fileoff, pSrcSeg->filesize); \ 1177 fAddSegOuter = K_TRUE; \ 1125 1178 } \ 1126 1179 \ … … 1130 1183 while (cSectionsLeft-- > 0) \ 1131 1184 { \ 1185 /* New segment if object file. */ \ 1186 KBOOL fAddSegInner = K_FALSE; \ 1187 if ( pModMachO->Hdr.filetype == MH_OBJECT \ 1188 && !(pSect->flags & S_ATTR_DEBUG) \ 1189 && kHlpStrComp(pSrcSeg->segname, "__DWARF") ) \ 1190 { \ 1191 kHlpAssert(!fAddSegOuter); \ 1192 NEW_SEGMENT(a_cBits, pSect->segname, K_TRUE /*a_fObjFile*/, pSect->sectname, \ 1193 pSect->addr, pSect->size, \ 1194 pSect->offset != 0, pSect->offset, pSect->size); \ 1195 fAddSegInner = K_TRUE; \ 1196 } \ 1197 \ 1132 1198 /* Section data extract. */ \ 1133 1199 pSectExtra->cb = pSect->size; \ … … 1149 1215 \ 1150 1216 /* Update the segment alignment, if we're not skipping it. */ \ 1151 if (!fSkipSeg && pDstSeg->Alignment < ((KLDRADDR)1 << pSect->align)) \ 1217 if ( (fAddSegOuter || fAddSegInner) \ 1218 && pDstSeg->Alignment < ((KLDRADDR)1 << pSect->align)) \ 1152 1219 pDstSeg->Alignment = (KLDRADDR)1 << pSect->align; \ 1153 1220 \ 1154 /* Next section . */ \1221 /* Next section, and if object file next segment. */ \ 1155 1222 pSectExtra++; \ 1156 1223 pSect++; \ 1224 if (fAddSegInner) \ 1225 CLOSE_SEGMENT(); \ 1157 1226 } \ 1158 1227 \ 1159 1228 /* Close the segment and advance. */ \ 1160 if (!fSkipSeg) \ 1161 { \ 1162 pSegExtra->cSections = pSectExtra - pSegExtra->paSections; \ 1163 pSegExtra++; \ 1164 pDstSeg++; \ 1165 } \ 1229 if (fAddSegOuter) \ 1230 CLOSE_SEGMENT(); \ 1166 1231 } while (0) /* ADD_SEGMENT_AND_ITS_SECTIONS */ 1167 1232
Note:
See TracChangeset
for help on using the changeset viewer.