Changeset 2955 for trunk/kLdr/kLdrModMachO.c
- Timestamp:
- Feb 7, 2007, 8:07:16 AM (19 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kLdr/kLdrModMachO.c
r2954 r2955 99 99 /** The link address. */ 100 100 KLDRADDR LinkAddress; 101 /** The size of the mapped image. */ 102 KLDRADDR cbImage; 103 /** When set the load commands will be used when mapping / loading the bits. 104 * This is the case when segments are made up of sections that doesn't have 105 * proper ordering and/or aligning in the file alignment. */ 106 int fMapUsingLoadCommands; 101 107 102 108 /** Pointer to the load commands. (endian converted) */ … … 353 359 pModMachO->Hdr.reserved = 0; 354 360 pModMachO->LinkAddress = 0; 361 pModMachO->cbImage = 0; 362 pModMachO->fMapUsingLoadCommands = 0; 355 363 pModMachO->offSymbols = 0; 356 364 pModMachO->cSymbols = 0; … … 408 416 uint32_t cbLeft = pHdr->sizeofcmds; 409 417 uint8_t *pb = pbLoadCommands; 418 int cSegmentCommands = 0; 410 419 int fConvertEndian = pHdr->magic == IMAGE_MACHO32_SIGNATURE_OE 411 420 || pHdr->magic == IMAGE_MACHO64_SIGNATURE_OE; … … 447 456 if (u.pLoadCmd->cmdsize < sizeof(segment_command_32_t)) 448 457 return KLDR_ERR_MACHO_BAD_LOAD_COMMAND; 458 if ( pHdr->magic != IMAGE_MACHO32_SIGNATURE_OE 459 && pHdr->magic != IMAGE_MACHO32_SIGNATURE) 460 return KLDR_ERR_MACHO_BIT_MIX; 449 461 if (fConvertEndian) 450 462 { … … 473 485 if (u.pSeg32->nsects * sizeof(section_32_t) > u.pLoadCmd->cmdsize - sizeof(segment_command_32_t)) 474 486 return KLDR_ERR_MACHO_BAD_LOAD_COMMAND; 487 if ( pHdr->filetype == MH_OBJECT 488 && cSegmentCommands > 0) 489 return KLDR_ERR_MACHO_BAD_OBJECT_FILE; 490 cSegmentCommands++; 475 491 476 492 /* … … 566 582 567 583 /* a new segment? */ 568 if ( pSect == pFirstSect584 if ( !cSegments 569 585 || kLdrHlpStrNComp(pSect->segname, (pSect - 1)->segname, sizeof(pSect->segname))) 570 586 { … … 580 596 /* ok. count it and the string. */ 581 597 cSegments++; 582 cbStringPool += kLdrHlpStr Len(pSect->segname) + 1;598 cbStringPool += kLdrHlpStrNLen(&pSect->segname[0], sizeof(pSect->segname)) + 1; 583 599 } 584 600 break; … … 595 611 } 596 612 597 case LC_SEGMENT_64:598 /* copy 32-bit code */613 /*case LC_SEGMENT_64: 614 copy 32-bit code 599 615 break; 616 */ 600 617 601 618 case LC_SYMTAB: … … 656 673 break; 657 674 675 case LC_SEGMENT_64: 658 676 case LC_LOADFVMLIB: 659 677 case LC_IDFVMLIB: … … 684 702 } 685 703 686 /* be strict (for now). */704 /* be strict. */ 687 705 if (cbLeft) 688 706 return KLDR_ERR_MACHO_BAD_LOAD_COMMAND; 689 707 708 switch (pHdr->filetype) 709 { 710 case MH_OBJECT: 711 if (!cSegments) 712 return KLDR_ERR_MACHO_BAD_OBJECT_FILE; 713 break; 714 } 715 690 716 *pcSegments = cSegments; 691 *pcbStringPool = c Left;717 *pcbStringPool = cbStringPool; 692 718 693 719 return 0; … … 708 734 static int kldrModMachOParseLoadCommands(PKLDRMODMACHO pModMachO, char *pbStringPool, uint32_t cbStringPool) 709 735 { 736 union 737 { 738 const uint8_t *pb; 739 const load_command_t *pLoadCmd; 740 const segment_command_32_t *pSeg32; 741 const segment_command_64_t *pSeg64; 742 const symtab_command_t *pSymTab; 743 } u; 744 uint32_t cLeft = pModMachO->Hdr.ncmds; 745 uint32_t cbLeft = pModMachO->Hdr.sizeofcmds; 746 const uint8_t *pb = pModMachO->pbLoadCommands; 747 int fFirstSegment = 1; 748 PKLDRSEG pSeg = &pModMachO->pMod->aSegments[0]; 749 const uint32_t cSegments = pModMachO->pMod->cSegments; 750 uint32_t i; 751 752 while (cLeft-- > 0) 753 { 754 u.pb = pb; 755 cbLeft -= u.pLoadCmd->cmdsize; 756 pb += u.pLoadCmd->cmdsize; 757 758 /* 759 * Convert endian if needed, parse and validate the command. 760 */ 761 switch (u.pLoadCmd->cmd) 762 { 763 case LC_SEGMENT_32: 764 { 765 section_32_t *pSect; 766 section_32_t *pFirstSect; 767 uint32_t cSectionsLeft; 768 769 pModMachO->LinkAddress = u.pSeg32->vmaddr; 770 771 /* 772 * convert, validate and parse the sections. 773 */ 774 cSectionsLeft = u.pSeg32->nsects; 775 pFirstSect = pSect = (section_32_t *)(u.pSeg32 + 1); 776 while (cSectionsLeft-- > 0) 777 { 778 switch (pModMachO->Hdr.filetype) 779 { 780 case MH_OBJECT: 781 { 782 /* Don't load debug symbols. (test this) */ 783 if (pSect->flags & S_ATTR_DEBUG) 784 break; 785 786 if ( fFirstSegment 787 || kLdrHlpStrNComp(pSect->segname, (pSect - 1)->segname, sizeof(pSect->segname))) 788 { 789 /* new segment. */ 790 pSeg->pvUser = NULL; 791 pSeg->pchName = pbStringPool; 792 pSeg->cchName = (uint32_t)kLdrHlpStrNLen(&pSect->segname[0], sizeof(pSect->sectname)); 793 kLdrHlpMemCopy(pbStringPool, &pSect->segname[0], pSeg->cchName); 794 pbStringPool += pSeg->cchName; 795 *pbStringPool++ = '\0'; 796 pSeg->SelFlat = 0; 797 pSeg->Sel16bit = 0; 798 pSeg->fFlags = 0; 799 pSeg->enmProt = KLDRPROT_EXECUTE_WRITECOPY; /** @todo fixme! */ 800 pSeg->cb = pSect->size; 801 pSeg->Alignment = (1 << pSect->align); 802 pSeg->LinkAddress = pSect->addr; 803 pSeg->offFile = pSect->offset ? pSect->offset : -1; 804 pSeg->cbFile = pSect->offset ? pSect->size : -1; 805 pSeg->RVA = pSect->addr - pModMachO->LinkAddress; 806 pSeg->cbMapped = 0; 807 pSeg->MapAddress = 0; 808 809 pSeg++; 810 fFirstSegment = 0; 811 } 812 else if (!fFirstSegment) 813 { 814 /* update exiting segment */ 815 if (pSeg[-1].Alignment < (1 << pSect->align)) 816 pSeg[-1].Alignment = (1 << pSect->align); 817 if (pSect->addr < pSeg[-1].LinkAddress) 818 return KLDR_ERR_MACHO_BAD_SECTION; /** @todo move up! */ 819 820 if ( pSect->offset 821 && pSeg[-1].cbFile == pSeg[-1].cb) 822 { 823 if ( pSeg[-1].offFile + pSeg[-1].cbFile == pSect->offset 824 && pSeg[-1].cbFile == pSect->addr - pSeg[-1].LinkAddress) 825 pSeg[-1].cbFile = (off_t)(pSect->addr - pSeg[-1].LinkAddress) + pSect->size; 826 else 827 { 828 pSeg[-1].cbFile = pSeg[-1].offFile = -1; 829 pModMachO->fMapUsingLoadCommands = 1; 830 } 831 } 832 pSeg[-1].cb = pSect->addr - pSeg[-1].LinkAddress + pSect->size; 833 834 /** @todo update the protection... */ 835 } 836 break; 837 } 838 839 default: 840 return KLDR_ERR_INVALID_PARAMETER; 841 } 842 843 /* next */ 844 pSect++; 845 } 846 break; 847 } 848 849 default: 850 break; 851 } 852 } 853 854 /* 855 * Adjust mapping addresses calculating the image size. 856 */ 857 pSeg = &pModMachO->pMod->aSegments[0]; 858 switch (pModMachO->Hdr.filetype) 859 { 860 case MH_OBJECT: 861 { 862 KLDRADDR cb1; 863 size_t cb2; 864 865 for (i = 0; i < cSegments - 1; i++) 866 { 867 cb1 = pSeg[i + 1].LinkAddress - pSeg[i].LinkAddress; 868 cb2 = (size_t)cb1; 869 pSeg[i].cbMapped = cb2 == cb1 ? cb2 : ~(size_t)0; 870 } 871 cb1 = KLDR_ALIGN_ADDR(pSeg[i].cb, pSeg[i].Alignment); 872 cb2 = (size_t)cb1; 873 pSeg[i].cbMapped = cb2 == cb1 ? cb2 : ~(size_t)0; 874 875 pModMachO->cbImage = pSeg[i].RVA + cb1; 876 break; 877 } 878 } 879 710 880 return 0; 711 881 } … … 1978 2148 static KLDRADDR kldrModMachOSize(PKLDRMOD pMod) 1979 2149 { 1980 #if 01981 2150 PKLDRMODMACHO pModMachO = (PKLDRMODMACHO)pMod->pvData; 1982 return pModMachO->Hdrs.OptionalHeader.SizeOfImage; 1983 #else 1984 return 0; 1985 #endif 2151 return pModMachO->cbImage; 1986 2152 } 1987 2153
Note:
See TracChangeset
for help on using the changeset viewer.