]> git.saurik.com Git - apple/ld64.git/blobdiff - src/other/machochecker.cpp
ld64-351.8.tar.gz
[apple/ld64.git] / src / other / machochecker.cpp
index 0465cd579c9f68a0718dc3ac37e8c0b6cf0d1f3d..ef6ba486e1ae9b55164d8ece518d58a351972299 100644 (file)
@@ -258,13 +258,15 @@ bool MachOChecker<arm64>::validFile(const uint8_t* fileContent)
 }
 #endif
 
+
+template <> uint8_t MachOChecker<ppc>::loadCommandSizeMask()   { return 0x03; }
+template <> uint8_t MachOChecker<ppc64>::loadCommandSizeMask() { return 0x07; }
 template <> uint8_t MachOChecker<x86>::loadCommandSizeMask()   { return 0x03; }
 template <> uint8_t MachOChecker<x86_64>::loadCommandSizeMask() { return 0x07; }
 template <> uint8_t MachOChecker<arm>::loadCommandSizeMask()   { return 0x03; }
 template <> uint8_t MachOChecker<arm64>::loadCommandSizeMask() { return 0x07; }
 
 
-
 template <>
 x86::P::uint_t MachOChecker<x86>::getInitialStackPointer(const macho_thread_command<x86::P>* threadInfo)
 {
@@ -290,6 +292,13 @@ arm64::P::uint_t MachOChecker<arm64>::getInitialStackPointer(const macho_thread_
 }
 
 
+template <>
+ppc::P::uint_t MachOChecker<ppc>::getEntryPoint(const macho_thread_command<ppc::P>* threadInfo)
+{
+       return threadInfo->thread_register(0);
+}
+
+
 template <>
 x86::P::uint_t MachOChecker<x86>::getEntryPoint(const macho_thread_command<x86::P>* threadInfo)
 {
@@ -343,7 +352,6 @@ const char* MachOChecker<A>::archName()
 }
 
 
-
 template <typename A>
 MachOChecker<A>::MachOChecker(const uint8_t* fileContent, uint32_t fileLength, const char* path, const char* verifierDstRoot)
  : fHeader(NULL), fLength(fileLength), fInstallName(NULL), fStrings(NULL), fSymbols(NULL), fSymbolCount(0), fDynamicSymbolTable(NULL), fIndirectTableCount(0),
@@ -385,7 +393,7 @@ void MachOChecker<A>::checkMachHeader()
                throw "sizeofcmds in mach_header is larger than file";
        
        uint32_t flags = fHeader->flags();
-       const uint32_t invalidBits = MH_INCRLINK | MH_LAZY_INIT | 0xFC000000;
+       const uint32_t invalidBits = MH_INCRLINK | MH_LAZY_INIT | 0xF8000000;
        if ( flags & invalidBits )
                throw "invalid bits in mach_header flags";
        if ( (flags & MH_NO_REEXPORTED_DYLIBS) && (fHeader->filetype() != MH_DYLIB) ) 
@@ -447,11 +455,15 @@ void MachOChecker<A>::checkLoadCommands()
                        case LC_LOAD_UPWARD_DYLIB:
                        case LC_VERSION_MIN_MACOSX:
                        case LC_VERSION_MIN_IPHONEOS:
+                       case LC_VERSION_MIN_TVOS:
+                       case LC_VERSION_MIN_WATCHOS:
                        case LC_FUNCTION_STARTS:
                        case LC_DYLD_ENVIRONMENT:
                        case LC_DATA_IN_CODE:
                        case LC_DYLIB_CODE_SIGN_DRS:
                        case LC_SOURCE_VERSION:
+                       case LC_NOTE:
+                       case LC_BUILD_VERSION:
                                break;
                        case LC_RPATH:
                                fHasLC_RPATH = true;
@@ -661,8 +673,12 @@ void MachOChecker<A>::checkLoadCommands()
 
        // verify encryption info
        if ( encryption_info != NULL ) {
-               if ( fHeader->filetype() != MH_EXECUTE )
-                       throw "LC_ENCRYPTION_INFO load command is only legal in main executables";
+               switch ( fHeader->filetype() ) {
+                       case MH_EXECUTE: case MH_DYLIB: case MH_BUNDLE: 
+                               break;  // okay
+                       default: 
+                               throw "LC_ENCRYPTION_INFO load command is not allowed in this file type";
+               }
                if ( encryption_info->cryptoff() <  (sizeof(macho_header<P>) + fHeader->sizeofcmds()) )
                        throw "LC_ENCRYPTION_INFO load command has cryptoff covers some load commands";
                if ( (encryption_info->cryptoff() % 4096) != 0 )
@@ -712,8 +728,6 @@ void MachOChecker<A>::checkLoadCommands()
                                                throw "string pool extends beyond __LINKEDIT";
                                        if ( (symtab->stroff() % 4) != 0 ) // work around until rdar://problem/4737991 is fixed
                                                throw "string pool start not pointer aligned";
-                                       if ( (symtab->strsize() % sizeof(pint_t)) != 0 )        
-                                               throw "string pool size not a multiple of pointer size";
                                }
                                break;
                        case LC_DYSYMTAB:
@@ -727,7 +741,7 @@ void MachOChecker<A>::checkLoadCommands()
                                        if ( fIndirectTableCount != 0  ) {
                                                if ( fDynamicSymbolTable->indirectsymoff() < linkEditSegment->fileoff() )
                                                        throw "indirect symbol table not in __LINKEDIT";
-                                               if ( (fDynamicSymbolTable->indirectsymoff()+fIndirectTableCount*8) > (linkEditSegment->fileoff()+linkEditSegment->filesize()) )
+                                               if ( (fDynamicSymbolTable->indirectsymoff()+fIndirectTableCount*4) > (linkEditSegment->fileoff()+linkEditSegment->filesize()) )
                                                        throw "indirect symbol table not in __LINKEDIT";
                                                if ( (fDynamicSymbolTable->indirectsymoff() % sizeof(pint_t)) != 0 )
                                                        throw "indirect symbol table not pointer aligned";
@@ -1131,6 +1145,7 @@ arm64::P::uint_t MachOChecker<arm64>::relocBase()
        return fFirstWritableSegment->vmaddr();
 }
 
+
 template <typename A>
 bool MachOChecker<A>::addressInWritableSegment(pint_t address)
 {
@@ -1274,6 +1289,7 @@ void MachOChecker<arm64>::checkLocalReloation(const macho_relocation_info<P>* re
 }
 #endif
 
+
 template <typename A>
 void MachOChecker<A>::checkRelocations()
 {
@@ -1530,13 +1546,11 @@ bool MachOChecker<A>::addressIsBindingSite(pint_t targetAddr)
                uint64_t segOffset = 0;
                uint32_t count;
                uint32_t skip;
-               uint8_t flags;
                const char* symbolName = NULL;
                int libraryOrdinal = 0;
                int segIndex;
                int64_t addend = 0;
                pint_t segStartAddr = 0;
-               pint_t addr;
                bool done = false;
                while ( !done && (p < end) ) {
                        uint8_t immediate = *p & BIND_IMMEDIATE_MASK;