}
#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)
{
}
+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)
{
}
-
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),
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) )
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;
// 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 )
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:
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";
return fFirstWritableSegment->vmaddr();
}
+
template <typename A>
bool MachOChecker<A>::addressInWritableSegment(pint_t address)
{
}
#endif
+
template <typename A>
void MachOChecker<A>::checkRelocations()
{
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;