X-Git-Url: https://git.saurik.com/apple/ld64.git/blobdiff_plain/afe874b1634377ecb27057ee76deb04915bb34d7..b1f7435d66a93f03b77932b3a9ad8a83ce5e1ebc:/src/ld/HeaderAndLoadCommands.hpp diff --git a/src/ld/HeaderAndLoadCommands.hpp b/src/ld/HeaderAndLoadCommands.hpp index 395fc99..0885715 100644 --- a/src/ld/HeaderAndLoadCommands.hpp +++ b/src/ld/HeaderAndLoadCommands.hpp @@ -1,6 +1,6 @@ /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-* * - * Copyright (c) 2009 Apple Inc. All rights reserved. + * Copyright (c) 2009-2011 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -60,8 +60,6 @@ public: // overrides of ld::Atom virtual ld::File* file() const { return NULL; } - virtual bool translationUnitSource(const char** dir, const char** nm) const - { return false; } virtual const char* name() const { return "mach-o header and load commands"; } virtual uint64_t size() const; virtual uint64_t objectAddress() const { return _address; } @@ -96,7 +94,9 @@ private: uint8_t* copyRoutinesLoadCommand(uint8_t* p) const; uint8_t* copyUUIDLoadCommand(uint8_t* p) const; uint8_t* copyVersionLoadCommand(uint8_t* p) const; + uint8_t* copySourceVersionLoadCommand(uint8_t* p) const; uint8_t* copyThreadsLoadCommand(uint8_t* p) const; + uint8_t* copyEntryPointLoadCommand(uint8_t* p) const; uint8_t* copyEncryptionLoadCommand(uint8_t* p) const; uint8_t* copySplitSegInfoLoadCommand(uint8_t* p) const; uint8_t* copyDylibLoadCommand(uint8_t* p, const ld::dylib::File*) const; @@ -106,6 +106,8 @@ private: uint8_t* copySubLibraryLoadCommand(uint8_t* p, const char* name) const; uint8_t* copySubUmbrellaLoadCommand(uint8_t* p, const char* name) const; uint8_t* copyFunctionStartsLoadCommand(uint8_t* p) const; + uint8_t* copyDataInCodeLoadCommand(uint8_t* p) const; + uint8_t* copyDependentDRLoadCommand(uint8_t* p) const; uint8_t* copyDyldEnvLoadCommand(uint8_t* p, const char* env) const; uint32_t sectionFlags(ld::Internal::FinalSection* sect) const; @@ -120,6 +122,7 @@ private: bool _hasDyldLoadCommand; bool _hasDylibIDLoadCommand; bool _hasThreadLoadCommand; + bool _hasEntryPointLoadCommand; bool _hasEncryptionLoadCommand; bool _hasSplitSegInfoLoadCommand; bool _hasRoutinesLoadCommand; @@ -130,6 +133,9 @@ private: bool _hasSubFrameworkLoadCommand; bool _hasVersionLoadCommand; bool _hasFunctionStartsLoadCommand; + bool _hasDataInCodeLoadCommand; + bool _hasSourceVersionLoadCommand; + bool _hasDependentDRInfo; uint32_t _dylibLoadCommmandsCount; uint32_t _allowableClientLoadCommmandsCount; uint32_t _dyldEnvironExrasCount; @@ -161,9 +167,8 @@ HeaderAndLoadCommandsAtom::HeaderAndLoadCommandsAtom(const Options& opts, ld: _hasDyldInfoLoadCommand = opts.makeCompressedDyldInfo(); _hasDyldLoadCommand = ((opts.outputKind() == Options::kDynamicExecutable) || (_options.outputKind() == Options::kDyld)); _hasDylibIDLoadCommand = (opts.outputKind() == Options::kDynamicLibrary); - _hasThreadLoadCommand = _hasDyldLoadCommand || (opts.outputKind() == Options::kStaticExecutable) - || (opts.outputKind() == Options::kPreload) - || (opts.outputKind() == Options::kDyld); + _hasThreadLoadCommand = _options.needsThreadLoadCommand(); + _hasEntryPointLoadCommand = _options.needsEntryPointLoadCommand(); _hasEncryptionLoadCommand = opts.makeEncryptable(); _hasSplitSegInfoLoadCommand = opts.sharedRegionEligible(); _hasRoutinesLoadCommand = (opts.initFunctionName() != NULL); @@ -189,7 +194,7 @@ HeaderAndLoadCommandsAtom::HeaderAndLoadCommandsAtom(const Options& opts, ld: } break; case Options::kStaticExecutable: - _hasDynamicSymbolTableLoadCommand = false; + _hasDynamicSymbolTableLoadCommand = opts.positionIndependentExecutable(); break; case Options::kPreload: _hasDynamicSymbolTableLoadCommand = opts.positionIndependentExecutable(); @@ -199,6 +204,9 @@ HeaderAndLoadCommandsAtom::HeaderAndLoadCommandsAtom(const Options& opts, ld: _hasSubFrameworkLoadCommand = (_options.umbrellaName() != NULL); _hasVersionLoadCommand = _options.addVersionLoadCommand(); _hasFunctionStartsLoadCommand = _options.addFunctionStarts(); + _hasDataInCodeLoadCommand = _options.addDataInCodeInfo(); + _hasSourceVersionLoadCommand = _options.needsSourceVersionLoadCommand(); + _hasDependentDRInfo = _options.needsDependentDRInfo(); _dylibLoadCommmandsCount = _writer.dylibCount(); _allowableClientLoadCommmandsCount = _options.allowableClients().size(); _dyldEnvironExrasCount = _options.dyldEnvironExtras().size(); @@ -328,9 +336,15 @@ uint64_t HeaderAndLoadCommandsAtom::size() const if ( _hasVersionLoadCommand ) sz += sizeof(macho_version_min_command

); + + if ( _hasSourceVersionLoadCommand ) + sz += sizeof(macho_source_version_command

); if ( _hasThreadLoadCommand ) sz += this->threadLoadCommandSize(); + + if ( _hasEntryPointLoadCommand ) + sz += sizeof(macho_entry_point_command

); if ( _hasEncryptionLoadCommand ) sz += sizeof(macho_encryption_info_command

); @@ -377,6 +391,12 @@ uint64_t HeaderAndLoadCommandsAtom::size() const if ( _hasFunctionStartsLoadCommand ) sz += sizeof(macho_linkedit_data_command

); + if ( _hasDataInCodeLoadCommand ) + sz += sizeof(macho_linkedit_data_command

); + + if ( _hasDependentDRInfo ) + sz += sizeof(macho_linkedit_data_command

); + return sz; } @@ -409,8 +429,14 @@ uint32_t HeaderAndLoadCommandsAtom::commandsCount() const if ( _hasVersionLoadCommand ) ++count; + if ( _hasSourceVersionLoadCommand ) + ++count; + if ( _hasThreadLoadCommand ) ++count; + + if ( _hasEntryPointLoadCommand ) + ++count; if ( _hasEncryptionLoadCommand ) ++count; @@ -436,6 +462,12 @@ uint32_t HeaderAndLoadCommandsAtom::commandsCount() const if ( _hasFunctionStartsLoadCommand ) ++count; + if ( _hasDataInCodeLoadCommand ) + ++count; + + if ( _hasDependentDRInfo ) + ++count; + return count; } @@ -473,6 +505,8 @@ uint32_t HeaderAndLoadCommandsAtom::flags() const else { if ( _options.outputKind() == Options::kStaticExecutable ) { bits |= MH_NOUNDEFS; + if ( _options.positionIndependentExecutable() ) + bits |= MH_PIE; } else if ( _options.outputKind() == Options::kPreload ) { bits |= MH_NOUNDEFS; @@ -519,33 +553,15 @@ uint32_t HeaderAndLoadCommandsAtom::flags() const return bits; } -template <> uint32_t HeaderAndLoadCommandsAtom::magic() const { return MH_MAGIC; } -template <> uint32_t HeaderAndLoadCommandsAtom::magic() const { return MH_MAGIC_64; } template <> uint32_t HeaderAndLoadCommandsAtom::magic() const { return MH_MAGIC; } template <> uint32_t HeaderAndLoadCommandsAtom::magic() const { return MH_MAGIC_64; } template <> uint32_t HeaderAndLoadCommandsAtom::magic() const { return MH_MAGIC; } -template <> uint32_t HeaderAndLoadCommandsAtom::cpuType() const { return CPU_TYPE_POWERPC; } -template <> uint32_t HeaderAndLoadCommandsAtom::cpuType() const { return CPU_TYPE_POWERPC64; } template <> uint32_t HeaderAndLoadCommandsAtom::cpuType() const { return CPU_TYPE_I386; } template <> uint32_t HeaderAndLoadCommandsAtom::cpuType() const { return CPU_TYPE_X86_64; } template <> uint32_t HeaderAndLoadCommandsAtom::cpuType() const { return CPU_TYPE_ARM; } -template <> -uint32_t HeaderAndLoadCommandsAtom::cpuSubType() const -{ - return _state.cpuSubType; -} - -template <> -uint32_t HeaderAndLoadCommandsAtom::cpuSubType() const -{ - if ( (_options.outputKind() == Options::kDynamicExecutable) && (_options.macosxVersionMin() >= ld::mac10_5) ) - return (CPU_SUBTYPE_POWERPC_ALL | 0x80000000); - else - return CPU_SUBTYPE_POWERPC_ALL; -} template <> uint32_t HeaderAndLoadCommandsAtom::cpuSubType() const @@ -649,6 +665,8 @@ uint32_t HeaderAndLoadCommandsAtom::sectionFlags(ld::Internal::FinalSection* return S_REGULAR | S_ATTR_NO_DEAD_STRIP; else if ( (strncmp(sect->sectionName(), "__objc_nlclslist", 16) == 0) && (strcmp(sect->segmentName(), "__DATA") == 0) ) return S_REGULAR | S_ATTR_NO_DEAD_STRIP; + else if ( (strncmp(sect->sectionName(), "__objc_nlcatlist", 16) == 0) && (strcmp(sect->segmentName(), "__DATA") == 0) ) + return S_REGULAR | S_ATTR_NO_DEAD_STRIP; else return S_REGULAR; case ld::Section::typeCode: @@ -722,7 +740,12 @@ uint32_t HeaderAndLoadCommandsAtom::sectionFlags(ld::Internal::FinalSection* else return S_SYMBOL_STUBS | S_ATTR_SOME_INSTRUCTIONS | S_ATTR_PURE_INSTRUCTIONS; case ld::Section::typeNonLazyPointer: - return S_NON_LAZY_SYMBOL_POINTERS; + if ( _options.outputKind() == Options::kKextBundle ) + return S_REGULAR; + else if ( (_options.outputKind() == Options::kStaticExecutable) && _options.positionIndependentExecutable() ) + return S_REGULAR; + else + return S_NON_LAZY_SYMBOL_POINTERS; case ld::Section::typeDyldInfo: return S_REGULAR; case ld::Section::typeLazyDylibPointer: @@ -733,7 +756,13 @@ uint32_t HeaderAndLoadCommandsAtom::sectionFlags(ld::Internal::FinalSection* else return S_REGULAR | S_ATTR_SOME_INSTRUCTIONS | S_ATTR_PURE_INSTRUCTIONS; case ld::Section::typeInitializerPointers: - return S_MOD_INIT_FUNC_POINTERS; + // i386 kexts need different section type + if ( (_options.outputKind() == Options::kObjectFile) + && (strcmp(sect->sectionName(), "__constructor") == 0) + && (strcmp(sect->segmentName(), "__TEXT") == 0) ) + return S_REGULAR; + else + return S_MOD_INIT_FUNC_POINTERS; case ld::Section::typeTerminatorPointers: return S_MOD_TERM_FUNC_POINTERS; case ld::Section::typeTLVInitialValues: @@ -973,7 +1002,7 @@ uint8_t* HeaderAndLoadCommandsAtom::copyDylibIDLoadCommand(uint8_t* p) const cmd->set_cmdsize(sz); cmd->set_name_offset(); cmd->set_timestamp(1); // needs to be some constant value that is different than DylibLoadCommandsAtom uses - cmd->set_current_version(_options.currentVersion()); + cmd->set_current_version(_options.currentVersion32()); cmd->set_compatibility_version(_options.compatibilityVersion()); strcpy((char*)&p[sizeof(macho_dylib_command

)], _options.installPath()); return p + sz; @@ -1024,62 +1053,27 @@ uint8_t* HeaderAndLoadCommandsAtom::copyVersionLoadCommand(uint8_t* p) const cmd->set_cmd(LC_VERSION_MIN_MACOSX); cmd->set_cmdsize(sizeof(macho_version_min_command

)); cmd->set_version((uint32_t)macVersion); - cmd->set_reserved(0); + cmd->set_sdk(_options.sdkVersion()); } else { cmd->set_cmd(LC_VERSION_MIN_IPHONEOS); cmd->set_cmdsize(sizeof(macho_version_min_command

)); cmd->set_version((uint32_t)iOSVersion); - cmd->set_reserved(0); + cmd->set_sdk(_options.sdkVersion()); } return p + sizeof(macho_version_min_command

); } - -template <> -uint32_t HeaderAndLoadCommandsAtom::threadLoadCommandSize() const -{ - return this->alignedSize(16 + 40*4); // base size + PPC_THREAD_STATE_COUNT * 4 -} - - -template <> -uint8_t* HeaderAndLoadCommandsAtom::copyThreadsLoadCommand(uint8_t* p) const -{ - assert(_state.entryPoint != NULL); - pint_t start = _state.entryPoint->finalAddress(); - macho_thread_command* cmd = (macho_thread_command*)p; - cmd->set_cmd(LC_UNIXTHREAD); - cmd->set_cmdsize(threadLoadCommandSize()); - cmd->set_flavor(1); // PPC_THREAD_STATE - cmd->set_count(40); // PPC_THREAD_STATE_COUNT; - cmd->set_thread_register(0, start); - if ( _options.hasCustomStack() ) - cmd->set_thread_register(3, _options.customStackAddr()); // r1 - return p + threadLoadCommandSize(); -} - -template <> -uint32_t HeaderAndLoadCommandsAtom::threadLoadCommandSize() const +template +uint8_t* HeaderAndLoadCommandsAtom::copySourceVersionLoadCommand(uint8_t* p) const { - return this->alignedSize(16 + 76*4); // base size + PPC_THREAD_STATE64_COUNT * 4 + macho_source_version_command

* cmd = (macho_source_version_command

*)p; + cmd->set_cmd(LC_SOURCE_VERSION); + cmd->set_cmdsize(sizeof(macho_source_version_command

)); + cmd->set_version(_options.sourceVersion()); + return p + sizeof(macho_source_version_command

); } -template <> -uint8_t* HeaderAndLoadCommandsAtom::copyThreadsLoadCommand(uint8_t* p) const -{ - assert(_state.entryPoint != NULL); - pint_t start = _state.entryPoint->finalAddress(); - macho_thread_command* cmd = (macho_thread_command*)p; - cmd->set_cmd(LC_UNIXTHREAD); - cmd->set_cmdsize(threadLoadCommandSize()); - cmd->set_flavor(5); // PPC_THREAD_STATE64 - cmd->set_count(76); // PPC_THREAD_STATE64_COUNT; - cmd->set_thread_register(0, start); - if ( _options.hasCustomStack() ) - cmd->set_thread_register(3, _options.customStackAddr()); // r1 - return p + threadLoadCommandSize(); -} template <> uint32_t HeaderAndLoadCommandsAtom::threadLoadCommandSize() const @@ -1149,6 +1143,24 @@ uint8_t* HeaderAndLoadCommandsAtom::copyThreadsLoadCommand(uint8_t* p) cons return p + threadLoadCommandSize(); } + + +template +uint8_t* HeaderAndLoadCommandsAtom::copyEntryPointLoadCommand(uint8_t* p) const +{ + macho_entry_point_command

* cmd = (macho_entry_point_command

*)p; + cmd->set_cmd(LC_MAIN); + cmd->set_cmdsize(sizeof(macho_entry_point_command

)); + assert(_state.entryPoint != NULL); + pint_t start = _state.entryPoint->finalAddress(); + if ( _state.entryPoint->isThumb() ) + start |= 1ULL; + cmd->set_entryoff(start - this->finalAddress()); + cmd->set_stacksize(_options.hasCustomStack() ? _options.customStackSize() : 0 ); + return p + sizeof(macho_entry_point_command

); +} + + template uint8_t* HeaderAndLoadCommandsAtom::copyEncryptionLoadCommand(uint8_t* p) const { @@ -1286,6 +1298,30 @@ uint8_t* HeaderAndLoadCommandsAtom::copyFunctionStartsLoadCommand(uint8_t* p) } +template +uint8_t* HeaderAndLoadCommandsAtom::copyDataInCodeLoadCommand(uint8_t* p) const +{ + macho_linkedit_data_command

* cmd = (macho_linkedit_data_command

*)p; + cmd->set_cmd(LC_DATA_IN_CODE); + cmd->set_cmdsize(sizeof(macho_linkedit_data_command

)); + cmd->set_dataoff(_writer.dataInCodeSection->fileOffset); + cmd->set_datasize(_writer.dataInCodeSection->size); + return p + sizeof(macho_linkedit_data_command

); +} + + +template +uint8_t* HeaderAndLoadCommandsAtom::copyDependentDRLoadCommand(uint8_t* p) const +{ + macho_linkedit_data_command

* cmd = (macho_linkedit_data_command

*)p; + cmd->set_cmd(LC_DYLIB_CODE_SIGN_DRS); + cmd->set_cmdsize(sizeof(macho_linkedit_data_command

)); + cmd->set_dataoff(_writer.dependentDRsSection->fileOffset); + cmd->set_datasize(_writer.dependentDRsSection->size); + return p + sizeof(macho_linkedit_data_command

); +} + + template void HeaderAndLoadCommandsAtom::copyRawContent(uint8_t buffer[]) const { @@ -1333,8 +1369,14 @@ void HeaderAndLoadCommandsAtom::copyRawContent(uint8_t buffer[]) const if ( _hasVersionLoadCommand ) p = this->copyVersionLoadCommand(p); + if ( _hasSourceVersionLoadCommand ) + p = this->copySourceVersionLoadCommand(p); + if ( _hasThreadLoadCommand ) p = this->copyThreadsLoadCommand(p); + + if ( _hasEntryPointLoadCommand ) + p = this->copyEntryPointLoadCommand(p); if ( _hasEncryptionLoadCommand ) p = this->copyEncryptionLoadCommand(p); @@ -1380,7 +1422,13 @@ void HeaderAndLoadCommandsAtom::copyRawContent(uint8_t buffer[]) const if ( _hasFunctionStartsLoadCommand ) p = this->copyFunctionStartsLoadCommand(p); - + + if ( _hasDataInCodeLoadCommand ) + p = this->copyDataInCodeLoadCommand(p); + + if ( _hasDependentDRInfo ) + p = this->copyDependentDRLoadCommand(p); + }