/* -*- 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@
*
// 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; }
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;
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;
-
+ uint8_t* copyLinkerOptionsLoadCommand(uint8_t* p, const std::vector<const char*>&) const;
+ uint8_t* copyOptimizationHintsLoadCommand(uint8_t* p) const;
+
uint32_t sectionFlags(ld::Internal::FinalSection* sect) const;
bool sectionTakesNoDiskSpace(ld::Internal::FinalSection* sect) const;
bool _hasDyldLoadCommand;
bool _hasDylibIDLoadCommand;
bool _hasThreadLoadCommand;
+ bool _hasEntryPointLoadCommand;
bool _hasEncryptionLoadCommand;
bool _hasSplitSegInfoLoadCommand;
bool _hasRoutinesLoadCommand;
bool _hasSubFrameworkLoadCommand;
bool _hasVersionLoadCommand;
bool _hasFunctionStartsLoadCommand;
+ bool _hasDataInCodeLoadCommand;
+ bool _hasSourceVersionLoadCommand;
+ bool _hasDependentDRInfo;
+ bool _hasOptimizationHints;
uint32_t _dylibLoadCommmandsCount;
uint32_t _allowableClientLoadCommmandsCount;
uint32_t _dyldEnvironExrasCount;
std::vector<const char*> _subUmbrellaNames;
uint8_t _uuid[16];
mutable macho_uuid_command<P>* _uuidCmdInOutputBuffer;
+ std::vector< std::vector<const char*> > _linkerOptions;
static ld::Section _s_section;
static ld::Section _s_preload_section;
_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);
_hasSymbolTableLoadCommand = true;
_hasUUIDLoadCommand = (opts.UUIDMode() != Options::kUUIDNone);
+ _hasOptimizationHints = (_state.someObjectHasOptimizationHints && (opts.outputKind() == Options::kObjectFile));
switch ( opts.outputKind() ) {
case Options::kDynamicExecutable:
case Options::kDynamicLibrary:
break;
}
}
+ for (CStringSet::const_iterator it = _state.linkerOptionFrameworks.begin(); it != _state.linkerOptionFrameworks.end(); ++it) {
+ const char* frameWorkName = *it;
+ std::vector<const char*>* lo = new std::vector<const char*>();
+ lo->push_back("-framework");
+ lo->push_back(frameWorkName);
+ _linkerOptions.push_back(*lo);
+ };
+ for (CStringSet::const_iterator it = _state.linkerOptionLibraries.begin(); it != _state.linkerOptionLibraries.end(); ++it) {
+ const char* libName = *it;
+ std::vector<const char*>* lo = new std::vector<const char*>();
+ char * s = new char[strlen(libName)+3];
+ strcpy(s, "-l");
+ strcat(s, libName);
+ lo->push_back(s);
+ _linkerOptions.push_back(*lo);
+ };
break;
case Options::kStaticExecutable:
- _hasDynamicSymbolTableLoadCommand = false;
+ _hasDynamicSymbolTableLoadCommand = opts.positionIndependentExecutable();
break;
case Options::kPreload:
_hasDynamicSymbolTableLoadCommand = opts.positionIndependentExecutable();
_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();
+
if ( ! _options.useSimplifiedDylibReExports() ) {
// target OS does not support LC_REEXPORT_DYLIB, so use old complicated load commands
for(uint32_t ord=1; ord <= _writer.dylibCount(); ++ord) {
if ( _hasVersionLoadCommand )
sz += sizeof(macho_version_min_command<P>);
+
+ if ( _hasSourceVersionLoadCommand )
+ sz += sizeof(macho_source_version_command<P>);
if ( _hasThreadLoadCommand )
sz += this->threadLoadCommandSize();
+
+ if ( _hasEntryPointLoadCommand )
+ sz += sizeof(macho_entry_point_command<P>);
if ( _hasEncryptionLoadCommand )
sz += sizeof(macho_encryption_info_command<P>);
if ( _hasFunctionStartsLoadCommand )
sz += sizeof(macho_linkedit_data_command<P>);
+ if ( _hasDataInCodeLoadCommand )
+ sz += sizeof(macho_linkedit_data_command<P>);
+
+ if ( !_linkerOptions.empty() ) {
+ for (ld::relocatable::File::LinkerOptionsList::const_iterator it = _linkerOptions.begin(); it != _linkerOptions.end(); ++it) {
+ uint32_t s = sizeof(macho_linker_option_command<P>);
+ const std::vector<const char*>& options = *it;
+ for (std::vector<const char*>::const_iterator t=options.begin(); t != options.end(); ++t) {
+ s += (strlen(*t) + 1);
+ }
+ sz += alignedSize(s);
+ }
+ }
+
+ if ( _hasDependentDRInfo )
+ sz += sizeof(macho_linkedit_data_command<P>);
+
+ if ( _hasOptimizationHints )
+ sz += sizeof(macho_linkedit_data_command<P>);
+
return sz;
}
if ( _hasVersionLoadCommand )
++count;
+ if ( _hasSourceVersionLoadCommand )
+ ++count;
+
if ( _hasThreadLoadCommand )
++count;
+
+ if ( _hasEntryPointLoadCommand )
+ ++count;
if ( _hasEncryptionLoadCommand )
++count;
if ( _hasFunctionStartsLoadCommand )
++count;
+ if ( _hasDataInCodeLoadCommand )
+ ++count;
+
+ if ( !_linkerOptions.empty() ) {
+ for (ld::relocatable::File::LinkerOptionsList::const_iterator it = _linkerOptions.begin(); it != _linkerOptions.end(); ++it) {
+ ++count;
+ }
+ }
+
+ if ( _hasDependentDRInfo )
+ ++count;
+
+ if ( _hasOptimizationHints )
+ ++count;
+
return count;
}
else {
if ( _options.outputKind() == Options::kStaticExecutable ) {
bits |= MH_NOUNDEFS;
+ if ( _options.positionIndependentExecutable() )
+ bits |= MH_PIE;
}
else if ( _options.outputKind() == Options::kPreload ) {
bits |= MH_NOUNDEFS;
bits |= MH_FORCE_FLAT;
break;
}
- if ( _writer.hasWeakExternalSymbols || _writer.overridesWeakExternalSymbols )
+ if ( _state.hasWeakExternalSymbols || _writer.overridesWeakExternalSymbols )
bits |= MH_WEAK_DEFINES;
- if ( _writer.usesWeakExternalSymbols || _writer.hasWeakExternalSymbols )
+ if ( _writer.usesWeakExternalSymbols || _state.hasWeakExternalSymbols )
bits |= MH_BINDS_TO_WEAK;
if ( _options.prebind() )
bits |= MH_PREBOUND;
bits |= MH_PIE;
if ( _options.markAutoDeadStripDylib() )
bits |= MH_DEAD_STRIPPABLE_DYLIB;
- if ( _writer.hasThreadLocalVariableDefinitions )
+ if ( _state.hasThreadLocalVariableDefinitions )
bits |= MH_HAS_TLV_DESCRIPTORS;
if ( _options.hasNonExecutableHeap() )
bits |= MH_NO_HEAP_EXECUTION;
return bits;
}
-template <> uint32_t HeaderAndLoadCommandsAtom<ppc>::magic() const { return MH_MAGIC; }
-template <> uint32_t HeaderAndLoadCommandsAtom<ppc64>::magic() const { return MH_MAGIC_64; }
template <> uint32_t HeaderAndLoadCommandsAtom<x86>::magic() const { return MH_MAGIC; }
template <> uint32_t HeaderAndLoadCommandsAtom<x86_64>::magic() const { return MH_MAGIC_64; }
template <> uint32_t HeaderAndLoadCommandsAtom<arm>::magic() const { return MH_MAGIC; }
+template <> uint32_t HeaderAndLoadCommandsAtom<arm64>::magic() const { return MH_MAGIC_64; }
-template <> uint32_t HeaderAndLoadCommandsAtom<ppc>::cpuType() const { return CPU_TYPE_POWERPC; }
-template <> uint32_t HeaderAndLoadCommandsAtom<ppc64>::cpuType() const { return CPU_TYPE_POWERPC64; }
template <> uint32_t HeaderAndLoadCommandsAtom<x86>::cpuType() const { return CPU_TYPE_I386; }
template <> uint32_t HeaderAndLoadCommandsAtom<x86_64>::cpuType() const { return CPU_TYPE_X86_64; }
template <> uint32_t HeaderAndLoadCommandsAtom<arm>::cpuType() const { return CPU_TYPE_ARM; }
+template <> uint32_t HeaderAndLoadCommandsAtom<arm64>::cpuType() const { return CPU_TYPE_ARM64; }
-template <>
-uint32_t HeaderAndLoadCommandsAtom<ppc>::cpuSubType() const
-{
- return _state.cpuSubType;
-}
-
-template <>
-uint32_t HeaderAndLoadCommandsAtom<ppc64>::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<x86>::cpuSubType() const
template <>
uint32_t HeaderAndLoadCommandsAtom<x86_64>::cpuSubType() const
{
- if ( (_options.outputKind() == Options::kDynamicExecutable) && (_options.macosxVersionMin() >= ld::mac10_5) )
- return (CPU_SUBTYPE_X86_64_ALL | 0x80000000);
+ if ( (_options.outputKind() == Options::kDynamicExecutable) && (_state.cpuSubType == CPU_SUBTYPE_X86_64_ALL) && (_options.macosxVersionMin() >= ld::mac10_5) )
+ return (_state.cpuSubType | 0x80000000);
else
- return CPU_SUBTYPE_X86_64_ALL;
+ return _state.cpuSubType;
}
template <>
return _state.cpuSubType;
}
+template <>
+uint32_t HeaderAndLoadCommandsAtom<arm64>::cpuSubType() const
+{
+ return CPU_SUBTYPE_ARM64_ALL;
+}
+
template <typename A>
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:
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:
else
return S_REGULAR | S_ATTR_SOME_INSTRUCTIONS | S_ATTR_PURE_INSTRUCTIONS;
case ld::Section::typeInitializerPointers:
- return S_MOD_INIT_FUNC_POINTERS;
+ // <rdar://problem/11456679> 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:
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<P>)], _options.installPath());
return p + sz;
cmd->set_cmd(LC_VERSION_MIN_MACOSX);
cmd->set_cmdsize(sizeof(macho_version_min_command<P>));
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<P>));
cmd->set_version((uint32_t)iOSVersion);
- cmd->set_reserved(0);
+ cmd->set_sdk(_options.sdkVersion());
}
return p + sizeof(macho_version_min_command<P>);
}
-
-template <>
-uint32_t HeaderAndLoadCommandsAtom<ppc>::threadLoadCommandSize() const
-{
- return this->alignedSize(16 + 40*4); // base size + PPC_THREAD_STATE_COUNT * 4
-}
-
-
-template <>
-uint8_t* HeaderAndLoadCommandsAtom<ppc>::copyThreadsLoadCommand(uint8_t* p) const
-{
- assert(_state.entryPoint != NULL);
- pint_t start = _state.entryPoint->finalAddress();
- macho_thread_command<ppc::P>* cmd = (macho_thread_command<ppc::P>*)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<ppc64>::threadLoadCommandSize() const
+template <typename A>
+uint8_t* HeaderAndLoadCommandsAtom<A>::copySourceVersionLoadCommand(uint8_t* p) const
{
- return this->alignedSize(16 + 76*4); // base size + PPC_THREAD_STATE64_COUNT * 4
+ macho_source_version_command<P>* cmd = (macho_source_version_command<P>*)p;
+ cmd->set_cmd(LC_SOURCE_VERSION);
+ cmd->set_cmdsize(sizeof(macho_source_version_command<P>));
+ cmd->set_version(_options.sourceVersion());
+ return p + sizeof(macho_source_version_command<P>);
}
-template <>
-uint8_t* HeaderAndLoadCommandsAtom<ppc64>::copyThreadsLoadCommand(uint8_t* p) const
-{
- assert(_state.entryPoint != NULL);
- pint_t start = _state.entryPoint->finalAddress();
- macho_thread_command<ppc::P>* cmd = (macho_thread_command<ppc::P>*)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<x86>::threadLoadCommandSize() const
return p + threadLoadCommandSize();
}
+
+template <>
+uint32_t HeaderAndLoadCommandsAtom<arm64>::threadLoadCommandSize() const
+{
+ return this->alignedSize(16 + 34 * 8); // base size + ARM_EXCEPTION_STATE64_COUNT * 4
+}
+
+template <>
+uint8_t* HeaderAndLoadCommandsAtom<arm64>::copyThreadsLoadCommand(uint8_t* p) const
+{
+ assert(_state.entryPoint != NULL);
+ pint_t start = _state.entryPoint->finalAddress();
+ macho_thread_command<P>* cmd = (macho_thread_command<P>*)p;
+ cmd->set_cmd(LC_UNIXTHREAD);
+ cmd->set_cmdsize(threadLoadCommandSize());
+ cmd->set_flavor(6); // ARM_THREAD_STATE64
+ cmd->set_count(68); // ARM_EXCEPTION_STATE64_COUNT
+ cmd->set_thread_register(32, start); // pc
+ if ( _options.hasCustomStack() )
+ cmd->set_thread_register(31, _options.customStackAddr()); // sp
+ return p + threadLoadCommandSize();
+}
+
+
+template <typename A>
+uint8_t* HeaderAndLoadCommandsAtom<A>::copyEntryPointLoadCommand(uint8_t* p) const
+{
+ macho_entry_point_command<P>* cmd = (macho_entry_point_command<P>*)p;
+ cmd->set_cmd(LC_MAIN);
+ cmd->set_cmdsize(sizeof(macho_entry_point_command<P>));
+ 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<P>);
+}
+
+
template <typename A>
uint8_t* HeaderAndLoadCommandsAtom<A>::copyEncryptionLoadCommand(uint8_t* p) const
{
macho_encryption_info_command<P>* cmd = (macho_encryption_info_command<P>*)p;
- cmd->set_cmd(LC_ENCRYPTION_INFO);
+ cmd->set_cmd(sizeof(typename A::P::uint_t) == 4 ? LC_ENCRYPTION_INFO : LC_ENCRYPTION_INFO_64);
cmd->set_cmdsize(sizeof(macho_encryption_info_command<P>));
assert(_writer.encryptedTextStartOffset() != 0);
assert(_writer.encryptedTextEndOffset() != 0);
}
+template <typename A>
+uint8_t* HeaderAndLoadCommandsAtom<A>::copyDataInCodeLoadCommand(uint8_t* p) const
+{
+ macho_linkedit_data_command<P>* cmd = (macho_linkedit_data_command<P>*)p;
+ cmd->set_cmd(LC_DATA_IN_CODE);
+ cmd->set_cmdsize(sizeof(macho_linkedit_data_command<P>));
+ cmd->set_dataoff(_writer.dataInCodeSection->fileOffset);
+ cmd->set_datasize(_writer.dataInCodeSection->size);
+ return p + sizeof(macho_linkedit_data_command<P>);
+}
+
+
+template <typename A>
+uint8_t* HeaderAndLoadCommandsAtom<A>::copyLinkerOptionsLoadCommand(uint8_t* p, const std::vector<const char*>& options) const
+{
+ macho_linker_option_command<P>* cmd = (macho_linker_option_command<P>*)p;
+ cmd->set_cmd(LC_LINKER_OPTION);
+ cmd->set_count(options.size());
+ char* buffer = cmd->buffer();
+ uint32_t sz = sizeof(macho_linker_option_command<P>);
+ for (std::vector<const char*>::const_iterator it=options.begin(); it != options.end(); ++it) {
+ const char* opt = *it;
+ uint32_t len = strlen(opt);
+ strcpy(buffer, opt);
+ sz += (len + 1);
+ buffer += (len + 1);
+ }
+ sz = alignedSize(sz);
+ cmd->set_cmdsize(sz);
+ return p + sz;
+}
+
+
+template <typename A>
+uint8_t* HeaderAndLoadCommandsAtom<A>::copyDependentDRLoadCommand(uint8_t* p) const
+{
+ macho_linkedit_data_command<P>* cmd = (macho_linkedit_data_command<P>*)p;
+ cmd->set_cmd(LC_DYLIB_CODE_SIGN_DRS);
+ cmd->set_cmdsize(sizeof(macho_linkedit_data_command<P>));
+ cmd->set_dataoff(_writer.dependentDRsSection->fileOffset);
+ cmd->set_datasize(_writer.dependentDRsSection->size);
+ return p + sizeof(macho_linkedit_data_command<P>);
+}
+
+
+
+template <typename A>
+uint8_t* HeaderAndLoadCommandsAtom<A>::copyOptimizationHintsLoadCommand(uint8_t* p) const
+{
+ macho_linkedit_data_command<P>* cmd = (macho_linkedit_data_command<P>*)p;
+ cmd->set_cmd(LC_LINKER_OPTIMIZATION_HINTS);
+ cmd->set_cmdsize(sizeof(macho_linkedit_data_command<P>));
+ cmd->set_dataoff(_writer.optimizationHintsSection->fileOffset);
+ cmd->set_datasize(_writer.optimizationHintsSection->size);
+ return p + sizeof(macho_linkedit_data_command<P>);
+}
+
+
template <typename A>
void HeaderAndLoadCommandsAtom<A>::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);
if ( _hasSplitSegInfoLoadCommand )
p = this->copySplitSegInfoLoadCommand(p);
- for(uint32_t ord=1; ord <= _writer.dylibCount(); ++ord) {
+ for (uint32_t ord=1; ord <= _writer.dylibCount(); ++ord) {
p = this->copyDylibLoadCommand(p, _writer.dylibByOrdinal(ord));
}
if ( _hasFunctionStartsLoadCommand )
p = this->copyFunctionStartsLoadCommand(p);
-
+
+ if ( _hasDataInCodeLoadCommand )
+ p = this->copyDataInCodeLoadCommand(p);
+
+ if ( !_linkerOptions.empty() ) {
+ for (ld::relocatable::File::LinkerOptionsList::const_iterator it = _linkerOptions.begin(); it != _linkerOptions.end(); ++it) {
+ p = this->copyLinkerOptionsLoadCommand(p, *it);
+ }
+ }
+
+ if ( _hasDependentDRInfo )
+ p = this->copyDependentDRLoadCommand(p);
+
+ if ( _hasOptimizationHints )
+ p = this->copyOptimizationHintsLoadCommand(p);
+
}