Some header changes to fix the build with other compilers.
[darwin-xtools.git] / ld64 / src / ld / HeaderAndLoadCommands.hpp
blob10705ce249d40c6e190a99018ddb3c46f5f44dda
1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-*
3 * Copyright (c) 2009-2011 Apple Inc. All rights reserved.
5 * @APPLE_LICENSE_HEADER_START@
7 * This file contains Original Code and/or Modifications of Original Code
8 * as defined in and that are subject to the Apple Public Source License
9 * Version 2.0 (the 'License'). You may not use this file except in
10 * compliance with the License. Please obtain a copy of the License at
11 * http://www.opensource.apple.com/apsl/ and read it before using this
12 * file.
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
19 * Please see the License for the specific language governing rights and
20 * limitations under the License.
22 * @APPLE_LICENSE_HEADER_END@
25 #ifndef __HEADER_LOAD_COMMANDS_HPP__
26 #define __HEADER_LOAD_COMMANDS_HPP__
28 #include <stdlib.h>
29 #include <limits.h>
30 #include <unistd.h>
31 #include <mach-o/loader.h>
33 #include <mach/i386/thread_status.h>
35 #include <vector>
37 #include "MachOFileAbstraction.hpp"
38 #include "Options.h"
39 #include "ld.hpp"
41 namespace ld {
42 namespace tool {
44 class HeaderAndLoadCommandsAbtract : public ld::Atom
46 public:
47 HeaderAndLoadCommandsAbtract(const ld::Section& sect, ld::Atom::Definition d,
48 ld::Atom::Combine c, ld::Atom::Scope s, ld::Atom::ContentType ct,
49 ld::Atom::SymbolTableInclusion i, bool dds, bool thumb, bool al,
50 ld::Atom::Alignment a) : ld::Atom(sect, d, c, s, ct, i, dds, thumb, al, a) { }
52 virtual void setUUID(const uint8_t digest[16]) = 0;
53 virtual void recopyUUIDCommand() = 0;
54 virtual const uint8_t* getUUID() const = 0;
55 virtual bool bitcodeBundleCommand(uint64_t& cmdOffset, uint64_t& cmdEnd,
56 uint64_t& sectOffset, uint64_t& sectEnd) const = 0;
57 virtual void linkeditCmdInfo(uint64_t& offset, uint64_t& size) const = 0;
58 virtual void symbolTableCmdInfo(uint64_t& offset, uint64_t& size) const = 0;
62 template <typename A>
63 class HeaderAndLoadCommandsAtom : public HeaderAndLoadCommandsAbtract
65 public:
66 HeaderAndLoadCommandsAtom(const Options& opts, ld::Internal& state,
67 OutputFile& writer);
69 // overrides of ld::Atom
70 virtual ld::File* file() const { return NULL; }
71 virtual const char* name() const { return "mach-o header and load commands"; }
72 virtual uint64_t size() const;
73 virtual uint64_t objectAddress() const { return _address; }
74 virtual void copyRawContent(uint8_t buffer[]) const;
76 // overrides of HeaderAndLoadCommandsAbtract
77 virtual void setUUID(const uint8_t digest[16]) { memcpy(_uuid, digest, 16); }
78 virtual void recopyUUIDCommand();
79 virtual const uint8_t* getUUID() const { return &_uuid[0]; }
80 virtual bool bitcodeBundleCommand(uint64_t& cmdOffset, uint64_t& cmdEnd,
81 uint64_t& sectOffset, uint64_t& sectEnd) const;
82 virtual void linkeditCmdInfo(uint64_t& offset, uint64_t& size) const;
83 virtual void symbolTableCmdInfo(uint64_t& offset, uint64_t& size) const;
86 private:
87 typedef typename A::P P;
88 typedef typename A::P::E E;
89 typedef typename A::P::uint_t pint_t;
91 unsigned int nonHiddenSectionCount() const;
92 unsigned int segmentCount() const;
93 static uint32_t alignedSize(uint32_t x);
94 uint32_t magic() const;
95 uint32_t cpuType() const;
96 uint32_t cpuSubType() const;
97 uint32_t flags() const;
98 uint32_t fileType() const;
99 uint32_t commandsCount() const;
100 uint32_t threadLoadCommandSize() const;
101 uint8_t* copySingleSegmentLoadCommand(uint8_t* p) const;
102 uint8_t* copySegmentLoadCommands(uint8_t* p, uint8_t* base) const;
103 uint8_t* copyDyldInfoLoadCommand(uint8_t* p) const;
104 uint8_t* copySymbolTableLoadCommand(uint8_t* p, uint8_t* base) const;
105 uint8_t* copyDynamicSymbolTableLoadCommand(uint8_t* p) const;
106 uint8_t* copyDyldLoadCommand(uint8_t* p) const;
107 uint8_t* copyDylibIDLoadCommand(uint8_t* p) const;
108 uint8_t* copyRoutinesLoadCommand(uint8_t* p) const;
109 uint8_t* copyUUIDLoadCommand(uint8_t* p) const;
110 uint8_t* copyVersionLoadCommand(uint8_t* p) const;
111 uint8_t* copySourceVersionLoadCommand(uint8_t* p) const;
112 uint8_t* copyThreadsLoadCommand(uint8_t* p) const;
113 uint8_t* copyEntryPointLoadCommand(uint8_t* p) const;
114 uint8_t* copyEncryptionLoadCommand(uint8_t* p) const;
115 uint8_t* copySplitSegInfoLoadCommand(uint8_t* p) const;
116 uint8_t* copyDylibLoadCommand(uint8_t* p, const ld::dylib::File*) const;
117 uint8_t* copyRPathLoadCommand(uint8_t* p, const char*) const;
118 uint8_t* copySubFrameworkLoadCommand(uint8_t* p) const;
119 uint8_t* copyAllowableClientLoadCommand(uint8_t* p, const char* client) const;
120 uint8_t* copySubLibraryLoadCommand(uint8_t* p, const char* name) const;
121 uint8_t* copySubUmbrellaLoadCommand(uint8_t* p, const char* name) const;
122 uint8_t* copyFunctionStartsLoadCommand(uint8_t* p) const;
123 uint8_t* copyDataInCodeLoadCommand(uint8_t* p) const;
124 uint8_t* copyDyldEnvLoadCommand(uint8_t* p, const char* env) const;
125 uint8_t* copyLinkerOptionsLoadCommand(uint8_t* p, const std::vector<const char*>&) const;
126 uint8_t* copyOptimizationHintsLoadCommand(uint8_t* p) const;
128 uint32_t sectionFlags(ld::Internal::FinalSection* sect) const;
129 bool sectionTakesNoDiskSpace(ld::Internal::FinalSection* sect) const;
132 const Options& _options;
133 ld::Internal& _state;
134 OutputFile& _writer;
135 pint_t _address;
136 bool _hasDyldInfoLoadCommand;
137 bool _hasDyldLoadCommand;
138 bool _hasDylibIDLoadCommand;
139 bool _hasThreadLoadCommand;
140 bool _hasEntryPointLoadCommand;
141 bool _hasEncryptionLoadCommand;
142 bool _hasSplitSegInfoLoadCommand;
143 bool _hasRoutinesLoadCommand;
144 bool _hasUUIDLoadCommand;
145 bool _hasSymbolTableLoadCommand;
146 bool _hasDynamicSymbolTableLoadCommand;
147 bool _hasRPathLoadCommands;
148 bool _hasSubFrameworkLoadCommand;
149 bool _hasVersionLoadCommand;
150 bool _hasFunctionStartsLoadCommand;
151 bool _hasDataInCodeLoadCommand;
152 bool _hasSourceVersionLoadCommand;
153 bool _hasOptimizationHints;
154 uint32_t _dylibLoadCommmandsCount;
155 uint32_t _allowableClientLoadCommmandsCount;
156 uint32_t _dyldEnvironExrasCount;
157 std::vector<const char*> _subLibraryNames;
158 std::vector<const char*> _subUmbrellaNames;
159 uint8_t _uuid[16];
160 mutable macho_uuid_command<P>* _uuidCmdInOutputBuffer;
161 mutable uint32_t _linkeditCmdOffset;
162 mutable uint32_t _symboltableCmdOffset;
163 std::vector< std::vector<const char*> > _linkerOptions;
165 static ld::Section _s_section;
166 static ld::Section _s_preload_section;
169 template <typename A>
170 ld::Section HeaderAndLoadCommandsAtom<A>::_s_section("__TEXT", "__mach_header", ld::Section::typeMachHeader, true);
171 template <typename A>
172 ld::Section HeaderAndLoadCommandsAtom<A>::_s_preload_section("__HEADER", "__mach_header", ld::Section::typeMachHeader, true);
175 template <typename A>
176 HeaderAndLoadCommandsAtom<A>::HeaderAndLoadCommandsAtom(const Options& opts, ld::Internal& state, OutputFile& writer)
177 : HeaderAndLoadCommandsAbtract((opts.outputKind() == Options::kPreload) ? _s_preload_section : _s_section,
178 ld::Atom::definitionRegular, ld::Atom::combineNever,
179 ld::Atom::scopeTranslationUnit, ld::Atom::typeUnclassified,
180 ld::Atom::symbolTableNotIn, false, false, false,
181 (opts.outputKind() == Options::kPreload) ? ld::Atom::Alignment(0) : ld::Atom::Alignment(12) ),
182 _options(opts), _state(state), _writer(writer), _address(0), _uuidCmdInOutputBuffer(NULL), _linkeditCmdOffset(0), _symboltableCmdOffset(0)
184 bzero(_uuid, 16);
185 _hasDyldInfoLoadCommand = opts.makeCompressedDyldInfo();
186 _hasDyldLoadCommand = ((opts.outputKind() == Options::kDynamicExecutable) || (_options.outputKind() == Options::kDyld));
187 _hasDylibIDLoadCommand = (opts.outputKind() == Options::kDynamicLibrary);
188 _hasThreadLoadCommand = _options.needsThreadLoadCommand();
189 _hasEntryPointLoadCommand = _options.needsEntryPointLoadCommand();
190 _hasEncryptionLoadCommand = opts.makeEncryptable();
191 _hasSplitSegInfoLoadCommand = opts.sharedRegionEligible();
192 _hasRoutinesLoadCommand = (opts.initFunctionName() != NULL);
193 _hasSymbolTableLoadCommand = true;
194 _hasUUIDLoadCommand = (opts.UUIDMode() != Options::kUUIDNone);
195 _hasOptimizationHints = (_state.someObjectHasOptimizationHints && (opts.outputKind() == Options::kObjectFile));
196 switch ( opts.outputKind() ) {
197 case Options::kDynamicExecutable:
198 case Options::kDynamicLibrary:
199 case Options::kDynamicBundle:
200 case Options::kDyld:
201 case Options::kKextBundle:
202 _hasDynamicSymbolTableLoadCommand = true;
203 break;
204 case Options::kObjectFile:
205 if ( ! state.someObjectFileHasDwarf )
206 _hasUUIDLoadCommand = false;
207 _hasDynamicSymbolTableLoadCommand = false;
208 for (std::vector<ld::Internal::FinalSection*>::iterator it = _state.sections.begin(); it != _state.sections.end(); ++it) {
209 if ( (*it)->type() == ld::Section::typeNonLazyPointer ) {
210 _hasDynamicSymbolTableLoadCommand = true;
211 break;
214 for (const char* frameworkName : _state.unprocessedLinkerOptionFrameworks) {
215 std::vector<const char*>* lo = new std::vector<const char*>();
216 lo->push_back("-framework");
217 lo->push_back(frameworkName);
218 _linkerOptions.push_back(*lo);
220 for (const char* libName : _state.unprocessedLinkerOptionLibraries) {
221 std::vector<const char*>* lo = new std::vector<const char*>();
222 char * s = new char[strlen(libName)+3];
223 strcpy(s, "-l");
224 strcat(s, libName);
225 lo->push_back(s);
226 _linkerOptions.push_back(*lo);
228 break;
229 case Options::kStaticExecutable:
230 _hasDynamicSymbolTableLoadCommand = opts.positionIndependentExecutable();
231 break;
232 case Options::kPreload:
233 _hasDynamicSymbolTableLoadCommand = opts.positionIndependentExecutable();
234 break;
236 _hasRPathLoadCommands = (_options.rpaths().size() != 0);
237 _hasSubFrameworkLoadCommand = (_options.umbrellaName() != NULL);
238 _hasVersionLoadCommand = _options.addVersionLoadCommand() ||
239 (!state.objectFileFoundWithNoVersion && (_options.outputKind() == Options::kObjectFile)
240 && ((_options.platform() != Options::kPlatformUnknown) || (state.derivedPlatformLoadCommand != 0)) );
241 _hasFunctionStartsLoadCommand = _options.addFunctionStarts();
242 _hasDataInCodeLoadCommand = _options.addDataInCodeInfo();
243 _hasSourceVersionLoadCommand = _options.needsSourceVersionLoadCommand();
244 _dylibLoadCommmandsCount = _writer.dylibCount();
245 _allowableClientLoadCommmandsCount = _options.allowableClients().size();
246 _dyldEnvironExrasCount = _options.dyldEnvironExtras().size();
248 if ( ! _options.useSimplifiedDylibReExports() ) {
249 // target OS does not support LC_REEXPORT_DYLIB, so use old complicated load commands
250 for(uint32_t ord=1; ord <= _writer.dylibCount(); ++ord) {
251 const ld::dylib::File* dylib = _writer.dylibByOrdinal(ord);
252 if ( dylib->willBeReExported() ) {
253 // if child says it is an sub-framework of the image being created, then nothing to do here
254 bool isSubFramework = false;
255 const char* childInUmbrella = dylib->parentUmbrella();
256 if ( childInUmbrella != NULL ) {
257 const char* myLeaf = strrchr(_options.installPath(), '/');
258 if ( myLeaf != NULL ) {
259 if ( strcmp(childInUmbrella, &myLeaf[1]) == 0 )
260 isSubFramework = true;
263 // LC_SUB_FRAMEWORK is in child, so do nothing in parent
264 if ( ! isSubFramework ) {
265 // this dylib also needs a sub_x load command
266 bool isFrameworkReExport = false;
267 const char* lastSlash = strrchr(dylib->installPath(), '/');
268 if ( lastSlash != NULL ) {
269 char frameworkName[strlen(lastSlash)+20];
270 sprintf(frameworkName, "/%s.framework/", &lastSlash[1]);
271 isFrameworkReExport = (strstr(dylib->installPath(), frameworkName) != NULL);
273 if ( isFrameworkReExport ) {
274 // needs a LC_SUB_UMBRELLA command
275 _subUmbrellaNames.push_back(&lastSlash[1]);
277 else {
278 // needs a LC_SUB_LIBRARY command
279 const char* nameStart = &lastSlash[1];
280 if ( lastSlash == NULL )
281 nameStart = dylib->installPath();
282 int len = strlen(nameStart);
283 const char* dot = strchr(nameStart, '.');
284 if ( dot != NULL )
285 len = dot - nameStart;
286 char* subLibName = new char[len+1];
287 strlcpy(subLibName, nameStart, len+1);
288 _subLibraryNames.push_back(subLibName);
296 template <typename A>
297 uint32_t HeaderAndLoadCommandsAtom<A>::alignedSize(uint32_t size)
299 if ( sizeof(pint_t) == 4 )
300 return ((size+3) & (-4)); // 4-byte align all load commands for 32-bit mach-o
301 else
302 return ((size+7) & (-8)); // 8-byte align all load commands for 64-bit mach-o
306 template <typename A>
307 unsigned int HeaderAndLoadCommandsAtom<A>::nonHiddenSectionCount() const
309 unsigned int count = 0;
310 for (std::vector<ld::Internal::FinalSection*>::iterator it = _state.sections.begin(); it != _state.sections.end(); ++it) {
311 if ( ! (*it)->isSectionHidden() && ((*it)->type() != ld::Section::typeTentativeDefs) )
312 ++count;
314 return count;
317 template <typename A>
318 unsigned int HeaderAndLoadCommandsAtom<A>::segmentCount() const
320 if ( _options.outputKind() == Options::kObjectFile ) {
321 // .o files have one anonymous segment that contains all sections
322 return 1;
325 unsigned int count = 0;
326 const char* lastSegName = "";
327 for (std::vector<ld::Internal::FinalSection*>::iterator it = _state.sections.begin(); it != _state.sections.end(); ++it) {
328 if ( _options.outputKind() == Options::kPreload ) {
329 if ( (*it)->type() == ld::Section::typeMachHeader )
330 continue; // for -preload, don't put hidden __HEADER segment into output
331 if ( (*it)->type() == ld::Section::typeLinkEdit )
332 continue; // for -preload, don't put hidden __LINKEDIT segment into output
334 if ( strcmp(lastSegName, (*it)->segmentName()) != 0 ) {
335 lastSegName = (*it)->segmentName();
336 ++count;
339 return count;
342 template <typename A>
343 bool HeaderAndLoadCommandsAtom<A>::bitcodeBundleCommand(uint64_t &cmdOffset, uint64_t &cmdEnd,
344 uint64_t &sectOffset, uint64_t &sectEnd) const
346 if ( _options.outputKind() == Options::kObjectFile ) {
347 return false;
349 cmdOffset = sizeof(macho_header<P>);
350 const char* lastSegName = "";
351 for (std::vector<ld::Internal::FinalSection*>::iterator it = _state.sections.begin(); it != _state.sections.end(); ++it) {
352 if ( strcmp(lastSegName, (*it)->segmentName()) != 0 ) {
353 lastSegName = (*it)->segmentName();
354 cmdOffset += sizeof(macho_segment_command<P>);
356 if ( strcmp((*it)->segmentName(), "__LLVM") == 0 && strcmp((*it)->sectionName(), "__bundle") == 0 ) {
357 sectOffset = (*it)->fileOffset;
358 sectEnd = (*(it + 1))->fileOffset;
359 cmdEnd = cmdOffset + sizeof(macho_section<P>);
360 return true;
362 if ( ! (*it)->isSectionHidden() )
363 cmdOffset += sizeof(macho_section<P>);
365 return false;
368 template <typename A>
369 void HeaderAndLoadCommandsAtom<A>::linkeditCmdInfo(uint64_t &offset, uint64_t &size) const
371 offset = _linkeditCmdOffset;
372 size = sizeof(macho_segment_command<P>);
375 template <typename A>
376 void HeaderAndLoadCommandsAtom<A>::symbolTableCmdInfo(uint64_t &offset, uint64_t &size) const
378 offset = _symboltableCmdOffset;
379 size = sizeof(macho_symtab_command<P>);
383 template <typename A>
384 uint64_t HeaderAndLoadCommandsAtom<A>::size() const
386 uint32_t sz = sizeof(macho_header<P>);
388 sz += sizeof(macho_segment_command<P>) * this->segmentCount();
389 sz += sizeof(macho_section<P>) * this->nonHiddenSectionCount();
391 if ( _hasDylibIDLoadCommand )
392 sz += alignedSize(sizeof(macho_dylib_command<P>) + strlen(_options.installPath()) + 1);
394 if ( _hasDyldInfoLoadCommand )
395 sz += sizeof(macho_dyld_info_command<P>);
397 if ( _hasSymbolTableLoadCommand )
398 sz += sizeof(macho_symtab_command<P>);
400 if ( _hasDynamicSymbolTableLoadCommand )
401 sz += sizeof(macho_dysymtab_command<P>);
403 if ( _hasDyldLoadCommand )
404 sz += alignedSize(sizeof(macho_dylinker_command<P>) + strlen(_options.dyldInstallPath()) + 1);
406 if ( _hasRoutinesLoadCommand )
407 sz += sizeof(macho_routines_command<P>);
409 if ( _hasUUIDLoadCommand )
410 sz += sizeof(macho_uuid_command<P>);
412 if ( _hasVersionLoadCommand )
413 sz += sizeof(macho_version_min_command<P>);
415 if ( _hasSourceVersionLoadCommand )
416 sz += sizeof(macho_source_version_command<P>);
418 if ( _hasThreadLoadCommand )
419 sz += this->threadLoadCommandSize();
421 if ( _hasEntryPointLoadCommand )
422 sz += sizeof(macho_entry_point_command<P>);
424 if ( _hasEncryptionLoadCommand )
425 sz += sizeof(macho_encryption_info_command<P>);
427 if ( _hasSplitSegInfoLoadCommand )
428 sz += sizeof(macho_linkedit_data_command<P>);
430 for(uint32_t ord=1; ord <= _writer.dylibCount(); ++ord) {
431 sz += alignedSize(sizeof(macho_dylib_command<P>) + strlen(_writer.dylibByOrdinal(ord)->installPath()) + 1);
434 if ( _hasRPathLoadCommands ) {
435 const std::vector<const char*>& rpaths = _options.rpaths();
436 for (std::vector<const char*>::const_iterator it = rpaths.begin(); it != rpaths.end(); ++it) {
437 sz += alignedSize(sizeof(macho_rpath_command<P>) + strlen(*it) + 1);
441 if ( _hasSubFrameworkLoadCommand )
442 sz += alignedSize(sizeof(macho_sub_framework_command<P>) + strlen(_options.umbrellaName()) + 1);
444 for (std::vector<const char*>::const_iterator it = _subLibraryNames.begin(); it != _subLibraryNames.end(); ++it) {
445 sz += alignedSize(sizeof(macho_sub_library_command<P>) + strlen(*it) + 1);
448 for (std::vector<const char*>::const_iterator it = _subUmbrellaNames.begin(); it != _subUmbrellaNames.end(); ++it) {
449 sz += alignedSize(sizeof(macho_sub_umbrella_command<P>) + strlen(*it) + 1);
452 if ( _allowableClientLoadCommmandsCount != 0 ) {
453 const std::vector<const char*>& clients = _options.allowableClients();
454 for (std::vector<const char*>::const_iterator it = clients.begin(); it != clients.end(); ++it) {
455 sz += alignedSize(sizeof(macho_sub_client_command<P>) + strlen(*it) + 1);
459 if ( _dyldEnvironExrasCount != 0 ) {
460 const std::vector<const char*>& extras = _options.dyldEnvironExtras();
461 for (std::vector<const char*>::const_iterator it = extras.begin(); it != extras.end(); ++it) {
462 sz += alignedSize(sizeof(macho_dylinker_command<P>) + strlen(*it) + 1);
466 if ( _hasFunctionStartsLoadCommand )
467 sz += sizeof(macho_linkedit_data_command<P>);
469 if ( _hasDataInCodeLoadCommand )
470 sz += sizeof(macho_linkedit_data_command<P>);
472 if ( !_linkerOptions.empty() ) {
473 for (ld::relocatable::File::LinkerOptionsList::const_iterator it = _linkerOptions.begin(); it != _linkerOptions.end(); ++it) {
474 uint32_t s = sizeof(macho_linker_option_command<P>);
475 const std::vector<const char*>& options = *it;
476 for (std::vector<const char*>::const_iterator t=options.begin(); t != options.end(); ++t) {
477 s += (strlen(*t) + 1);
479 sz += alignedSize(s);
483 if ( _hasOptimizationHints )
484 sz += sizeof(macho_linkedit_data_command<P>);
486 return sz;
489 template <typename A>
490 uint32_t HeaderAndLoadCommandsAtom<A>::commandsCount() const
492 uint32_t count = this->segmentCount();
494 if ( _hasDylibIDLoadCommand )
495 ++count;
497 if ( _hasDyldInfoLoadCommand )
498 ++count;
500 if ( _hasSymbolTableLoadCommand )
501 ++count;
503 if ( _hasDynamicSymbolTableLoadCommand )
504 ++count;
506 if ( _hasDyldLoadCommand )
507 ++count;
509 if ( _hasRoutinesLoadCommand )
510 ++count;
512 if ( _hasUUIDLoadCommand )
513 ++count;
515 if ( _hasVersionLoadCommand )
516 ++count;
518 if ( _hasSourceVersionLoadCommand )
519 ++count;
521 if ( _hasThreadLoadCommand )
522 ++count;
524 if ( _hasEntryPointLoadCommand )
525 ++count;
527 if ( _hasEncryptionLoadCommand )
528 ++count;
530 if ( _hasSplitSegInfoLoadCommand )
531 ++count;
533 count += _dylibLoadCommmandsCount;
535 count += _options.rpaths().size();
537 if ( _hasSubFrameworkLoadCommand )
538 ++count;
540 count += _subLibraryNames.size();
542 count += _subUmbrellaNames.size();
544 count += _allowableClientLoadCommmandsCount;
546 count += _dyldEnvironExrasCount;
548 if ( _hasFunctionStartsLoadCommand )
549 ++count;
551 if ( _hasDataInCodeLoadCommand )
552 ++count;
554 if ( !_linkerOptions.empty() ) {
555 for (ld::relocatable::File::LinkerOptionsList::const_iterator it = _linkerOptions.begin(); it != _linkerOptions.end(); ++it) {
556 ++count;
560 if ( _hasOptimizationHints )
561 ++count;
563 return count;
566 template <typename A>
567 uint32_t HeaderAndLoadCommandsAtom<A>::fileType() const
569 switch ( _options.outputKind() ) {
570 case Options::kDynamicExecutable:
571 case Options::kStaticExecutable:
572 return MH_EXECUTE;
573 case Options::kDynamicLibrary:
574 return MH_DYLIB;
575 case Options::kDynamicBundle:
576 return MH_BUNDLE;
577 case Options::kObjectFile:
578 return MH_OBJECT;
579 case Options::kDyld:
580 return MH_DYLINKER;
581 case Options::kPreload:
582 return MH_PRELOAD;
583 case Options::kKextBundle:
584 return MH_KEXT_BUNDLE;
586 throw "unknonwn mach-o file type";
589 template <typename A>
590 uint32_t HeaderAndLoadCommandsAtom<A>::flags() const
592 uint32_t bits = 0;
593 if ( _options.outputKind() == Options::kObjectFile ) {
594 if ( _state.allObjectFilesScatterable )
595 bits = MH_SUBSECTIONS_VIA_SYMBOLS;
597 else {
598 if ( _options.outputKind() == Options::kStaticExecutable ) {
599 bits |= MH_NOUNDEFS;
600 if ( _options.positionIndependentExecutable() )
601 bits |= MH_PIE;
603 else if ( _options.outputKind() == Options::kPreload ) {
604 bits |= MH_NOUNDEFS;
605 if ( _options.positionIndependentExecutable() )
606 bits |= MH_PIE;
608 else {
609 bits = MH_DYLDLINK;
610 switch ( _options.nameSpace() ) {
611 case Options::kTwoLevelNameSpace:
612 bits |= MH_TWOLEVEL | MH_NOUNDEFS;
613 break;
614 case Options::kFlatNameSpace:
615 break;
616 case Options::kForceFlatNameSpace:
617 bits |= MH_FORCE_FLAT;
618 break;
620 if ( _state.hasWeakExternalSymbols || _writer.overridesWeakExternalSymbols )
621 bits |= MH_WEAK_DEFINES;
622 if ( _writer.usesWeakExternalSymbols || _state.hasWeakExternalSymbols )
623 bits |= MH_BINDS_TO_WEAK;
624 if ( _options.prebind() )
625 bits |= MH_PREBOUND;
626 if ( _options.splitSeg() )
627 bits |= MH_SPLIT_SEGS;
628 if ( (_options.outputKind() == Options::kDynamicLibrary)
629 && _writer._noReExportedDylibs
630 && _options.useSimplifiedDylibReExports() ) {
631 bits |= MH_NO_REEXPORTED_DYLIBS;
633 if ( _options.positionIndependentExecutable() && ! _writer.pieDisabled )
634 bits |= MH_PIE;
635 if ( _options.markAutoDeadStripDylib() )
636 bits |= MH_DEAD_STRIPPABLE_DYLIB;
637 if ( _state.hasThreadLocalVariableDefinitions )
638 bits |= MH_HAS_TLV_DESCRIPTORS;
639 if ( _options.hasNonExecutableHeap() )
640 bits |= MH_NO_HEAP_EXECUTION;
641 if ( _options.markAppExtensionSafe() && (_options.outputKind() == Options::kDynamicLibrary) )
642 bits |= MH_APP_EXTENSION_SAFE;
644 if ( _options.hasExecutableStack() )
645 bits |= MH_ALLOW_STACK_EXECUTION;
647 return bits;
650 template <> uint32_t HeaderAndLoadCommandsAtom<x86>::magic() const { return MH_MAGIC; }
651 template <> uint32_t HeaderAndLoadCommandsAtom<x86_64>::magic() const { return MH_MAGIC_64; }
652 template <> uint32_t HeaderAndLoadCommandsAtom<arm>::magic() const { return MH_MAGIC; }
653 template <> uint32_t HeaderAndLoadCommandsAtom<arm64>::magic() const { return MH_MAGIC_64; }
655 template <> uint32_t HeaderAndLoadCommandsAtom<x86>::cpuType() const { return CPU_TYPE_I386; }
656 template <> uint32_t HeaderAndLoadCommandsAtom<x86_64>::cpuType() const { return CPU_TYPE_X86_64; }
657 template <> uint32_t HeaderAndLoadCommandsAtom<arm>::cpuType() const { return CPU_TYPE_ARM; }
658 template <> uint32_t HeaderAndLoadCommandsAtom<arm64>::cpuType() const { return CPU_TYPE_ARM64; }
661 template <>
662 uint32_t HeaderAndLoadCommandsAtom<x86>::cpuSubType() const
664 return CPU_SUBTYPE_I386_ALL;
667 template <>
668 uint32_t HeaderAndLoadCommandsAtom<x86_64>::cpuSubType() const
670 if ( (_options.outputKind() == Options::kDynamicExecutable) && (_state.cpuSubType == CPU_SUBTYPE_X86_64_ALL) && (_options.macosxVersionMin() >= ld::mac10_5) )
671 return (_state.cpuSubType | 0x80000000);
672 else
673 return _state.cpuSubType;
676 template <>
677 uint32_t HeaderAndLoadCommandsAtom<arm>::cpuSubType() const
679 return _state.cpuSubType;
682 template <>
683 uint32_t HeaderAndLoadCommandsAtom<arm64>::cpuSubType() const
685 return CPU_SUBTYPE_ARM64_ALL;
690 template <typename A>
691 uint8_t* HeaderAndLoadCommandsAtom<A>::copySingleSegmentLoadCommand(uint8_t* p) const
693 // in .o files there is just one segment load command with a blank name
694 // and all sections under it
695 macho_segment_command<P>* cmd = (macho_segment_command<P>*)p;
696 cmd->set_cmd(macho_segment_command<P>::CMD);
697 cmd->set_segname("");
698 cmd->set_vmaddr(_options.baseAddress());
699 cmd->set_vmsize(0); // updated after sections set
700 cmd->set_fileoff(0); // updated after sections set
701 cmd->set_filesize(0); // updated after sections set
702 cmd->set_maxprot(VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE);
703 cmd->set_initprot(VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE);
704 cmd->set_nsects(this->nonHiddenSectionCount());
705 cmd->set_flags(0);
706 // add sections array
707 macho_section<P>* msect = (macho_section<P>*)&p[sizeof(macho_segment_command<P>)];
708 for (std::vector<ld::Internal::FinalSection*>::iterator sit = _state.sections.begin(); sit != _state.sections.end(); ++sit) {
709 ld::Internal::FinalSection* fsect = *sit;
710 if ( fsect->isSectionHidden() )
711 continue;
712 if ( fsect->type() == ld::Section::typeTentativeDefs )
713 continue;
714 msect->set_sectname(fsect->sectionName());
715 msect->set_segname(fsect->segmentName());
716 msect->set_addr(fsect->address);
717 msect->set_size(fsect->size);
718 msect->set_offset(fsect->fileOffset);
719 msect->set_align(fsect->alignment);
720 msect->set_reloff((fsect->relocCount == 0) ? 0 : _writer.sectionRelocationsSection->fileOffset + fsect->relocStart * sizeof(macho_relocation_info<P>));
721 msect->set_nreloc(fsect->relocCount);
722 msect->set_flags(sectionFlags(fsect));
723 msect->set_reserved1(fsect->indirectSymTabStartIndex);
724 msect->set_reserved2(fsect->indirectSymTabElementSize);
725 // update segment info
726 if ( cmd->fileoff() == 0 )
727 cmd->set_fileoff(fsect->fileOffset);
728 cmd->set_vmsize(fsect->address + fsect->size - cmd->vmaddr());
729 if ( (fsect->type() != ld::Section::typeZeroFill) && (fsect->type() != ld::Section::typeTentativeDefs) )
730 cmd->set_filesize(fsect->fileOffset + fsect->size - cmd->fileoff());
731 ++msect;
733 cmd->set_cmdsize(sizeof(macho_segment_command<P>) + cmd->nsects()*sizeof(macho_section<P>));
734 return p + cmd->cmdsize();
737 struct SegInfo {
738 SegInfo(const char* n, const Options&);
739 const char* segName;
740 uint32_t nonHiddenSectionCount;
741 uint32_t nonSectCreateSections;
742 uint32_t maxProt;
743 uint32_t initProt;
744 std::vector<ld::Internal::FinalSection*> sections;
748 SegInfo::SegInfo(const char* n, const Options& opts)
749 : segName(n), nonHiddenSectionCount(0), nonSectCreateSections(0), maxProt(opts.maxSegProtection(n)), initProt(opts.initialSegProtection(n))
754 template <typename A>
755 uint32_t HeaderAndLoadCommandsAtom<A>::sectionFlags(ld::Internal::FinalSection* sect) const
757 uint32_t bits;
758 switch ( sect->type() ) {
759 case ld::Section::typeUnclassified:
760 if ( strcmp(sect->segmentName(), "__OBJC") == 0 )
761 return S_REGULAR | S_ATTR_NO_DEAD_STRIP;
762 else if ( (strcmp(sect->sectionName(), "__objc_classlist") == 0) && (strcmp(sect->segmentName(), "__DATA") == 0) )
763 return S_REGULAR | S_ATTR_NO_DEAD_STRIP;
764 else if ( (strcmp(sect->sectionName(), "__objc_catlist") == 0) && (strcmp(sect->segmentName(), "__DATA") == 0) )
765 return S_REGULAR | S_ATTR_NO_DEAD_STRIP;
766 else if ( (strncmp(sect->sectionName(), "__objc_superrefs", 16) == 0) && (strcmp(sect->segmentName(), "__DATA") == 0) )
767 return S_REGULAR | S_ATTR_NO_DEAD_STRIP;
768 else if ( (strncmp(sect->sectionName(), "__objc_nlclslist", 16) == 0) && (strcmp(sect->segmentName(), "__DATA") == 0) )
769 return S_REGULAR | S_ATTR_NO_DEAD_STRIP;
770 else if ( (strncmp(sect->sectionName(), "__objc_nlcatlist", 16) == 0) && (strcmp(sect->segmentName(), "__DATA") == 0) )
771 return S_REGULAR | S_ATTR_NO_DEAD_STRIP;
772 else if ( (_options.outputKind() == Options::kObjectFile) && !sect->atoms.empty() && sect->atoms.front()->dontDeadStripIfReferencesLive() )
773 return S_REGULAR | S_ATTR_LIVE_SUPPORT;
774 else
775 return S_REGULAR;
776 case ld::Section::typeCode:
777 bits = S_REGULAR | S_ATTR_SOME_INSTRUCTIONS | S_ATTR_PURE_INSTRUCTIONS;
778 if ( sect->hasLocalRelocs && ! _writer.pieDisabled )
779 bits |= S_ATTR_LOC_RELOC;
780 if ( sect->hasExternalRelocs )
781 bits |= S_ATTR_EXT_RELOC;
782 return bits;
783 case ld::Section::typePageZero:
784 return S_REGULAR;
785 case ld::Section::typeImportProxies:
786 return S_REGULAR;
787 case ld::Section::typeLinkEdit:
788 return S_REGULAR;
789 case ld::Section::typeMachHeader:
790 return S_REGULAR;
791 case ld::Section::typeStack:
792 return S_REGULAR;
793 case ld::Section::typeLiteral4:
794 return S_4BYTE_LITERALS;
795 case ld::Section::typeLiteral8:
796 return S_8BYTE_LITERALS;
797 case ld::Section::typeLiteral16:
798 return S_16BYTE_LITERALS;
799 case ld::Section::typeConstants:
800 return S_REGULAR;
801 case ld::Section::typeTempLTO:
802 assert(0 && "typeTempLTO should not make it to final linked image");
803 return S_REGULAR;
804 case ld::Section::typeTempAlias:
805 assert(0 && "typeAlias should not make it to final linked image");
806 return S_REGULAR;
807 case ld::Section::typeAbsoluteSymbols:
808 assert(0 && "typeAbsoluteSymbols should not make it to final linked image");
809 return S_REGULAR;
810 case ld::Section::typeCString:
811 case ld::Section::typeNonStdCString:
812 return S_CSTRING_LITERALS;
813 case ld::Section::typeCStringPointer:
814 return S_LITERAL_POINTERS | S_ATTR_NO_DEAD_STRIP;
815 case ld::Section::typeUTF16Strings:
816 return S_REGULAR;
817 case ld::Section::typeCFString:
818 return S_REGULAR;
819 case ld::Section::typeObjC1Classes:
820 return S_REGULAR | S_ATTR_NO_DEAD_STRIP;
821 case ld::Section::typeCFI:
822 return S_REGULAR;
823 case ld::Section::typeLSDA:
824 return S_REGULAR;
825 case ld::Section::typeDtraceDOF:
826 return S_DTRACE_DOF;
827 case ld::Section::typeUnwindInfo:
828 return S_REGULAR;
829 case ld::Section::typeObjCClassRefs:
830 case ld::Section::typeObjC2CategoryList:
831 return S_REGULAR | S_ATTR_NO_DEAD_STRIP;
832 case ld::Section::typeZeroFill:
833 if ( _options.optimizeZeroFill() )
834 return S_ZEROFILL;
835 else
836 return S_REGULAR;
837 case ld::Section::typeTentativeDefs:
838 assert(0 && "typeTentativeDefs should not make it to final linked image");
839 return S_REGULAR;
840 case ld::Section::typeLazyPointer:
841 case ld::Section::typeLazyPointerClose:
842 return S_LAZY_SYMBOL_POINTERS;
843 case ld::Section::typeStubClose:
844 case ld::Section::typeStub:
845 if ( sect->hasLocalRelocs )
846 return S_SYMBOL_STUBS | S_ATTR_SOME_INSTRUCTIONS | S_ATTR_PURE_INSTRUCTIONS | S_ATTR_LOC_RELOC;
847 else
848 return S_SYMBOL_STUBS | S_ATTR_SOME_INSTRUCTIONS | S_ATTR_PURE_INSTRUCTIONS;
849 case ld::Section::typeNonLazyPointer:
850 if ( _options.outputKind() == Options::kKextBundle )
851 return S_REGULAR;
852 else if ( (_options.outputKind() == Options::kStaticExecutable) && _options.positionIndependentExecutable() )
853 return S_REGULAR;
854 else
855 return S_NON_LAZY_SYMBOL_POINTERS;
856 case ld::Section::typeDyldInfo:
857 return S_REGULAR;
858 case ld::Section::typeLazyDylibPointer:
859 return S_LAZY_DYLIB_SYMBOL_POINTERS;
860 case ld::Section::typeStubHelper:
861 if ( sect->hasLocalRelocs )
862 return S_REGULAR | S_ATTR_SOME_INSTRUCTIONS | S_ATTR_PURE_INSTRUCTIONS | S_ATTR_LOC_RELOC;
863 else
864 return S_REGULAR | S_ATTR_SOME_INSTRUCTIONS | S_ATTR_PURE_INSTRUCTIONS;
865 case ld::Section::typeInitializerPointers:
866 // <rdar://problem/11456679> i386 kexts need different section type
867 if ( (_options.outputKind() == Options::kObjectFile)
868 && (strcmp(sect->sectionName(), "__constructor") == 0)
869 && (strcmp(sect->segmentName(), "__TEXT") == 0) )
870 return S_REGULAR;
871 else
872 return S_MOD_INIT_FUNC_POINTERS;
873 case ld::Section::typeTerminatorPointers:
874 return S_MOD_TERM_FUNC_POINTERS;
875 case ld::Section::typeTLVInitialValues:
876 return S_THREAD_LOCAL_REGULAR;
877 case ld::Section::typeTLVZeroFill:
878 return S_THREAD_LOCAL_ZEROFILL;
879 case ld::Section::typeTLVDefs:
880 return S_THREAD_LOCAL_VARIABLES;
881 case ld::Section::typeTLVInitializerPointers:
882 return S_THREAD_LOCAL_INIT_FUNCTION_POINTERS;
883 case ld::Section::typeTLVPointers:
884 return S_THREAD_LOCAL_VARIABLE_POINTERS;
885 case ld::Section::typeFirstSection:
886 assert(0 && "typeFirstSection should not make it to final linked image");
887 return S_REGULAR;
888 case ld::Section::typeLastSection:
889 assert(0 && "typeLastSection should not make it to final linked image");
890 return S_REGULAR;
891 case ld::Section::typeDebug:
892 return S_REGULAR | S_ATTR_DEBUG;
893 case ld::Section::typeSectCreate:
894 return S_REGULAR;
896 return S_REGULAR;
900 template <typename A>
901 bool HeaderAndLoadCommandsAtom<A>::sectionTakesNoDiskSpace(ld::Internal::FinalSection* sect) const
903 switch ( sect->type() ) {
904 case ld::Section::typeZeroFill:
905 case ld::Section::typeTLVZeroFill:
906 return _options.optimizeZeroFill();
907 case ld::Section::typeAbsoluteSymbols:
908 case ld::Section::typeTentativeDefs:
909 case ld::Section::typeLastSection:
910 return true;
911 default:
912 break;
914 return false;
918 template <typename A>
919 uint8_t* HeaderAndLoadCommandsAtom<A>::copySegmentLoadCommands(uint8_t* p, uint8_t* base) const
921 // group sections into segments
922 std::vector<SegInfo> segs;
923 const char* lastSegName = "";
924 for (std::vector<ld::Internal::FinalSection*>::iterator it = _state.sections.begin(); it != _state.sections.end(); ++it) {
925 ld::Internal::FinalSection* sect = *it;
926 if ( _options.outputKind() == Options::kPreload ) {
927 if ( (*it)->type() == ld::Section::typeMachHeader )
928 continue; // for -preload, don't put hidden __HEADER segment into output
929 if ( (*it)->type() == ld::Section::typeLinkEdit )
930 continue; // for -preload, don't put hidden __LINKEDIT segment into output
932 if ( strcmp(lastSegName, sect->segmentName()) != 0 ) {
933 SegInfo si(sect->segmentName(), _options);
934 segs.push_back(si);
935 lastSegName = sect->segmentName();
937 if ( ! sect->isSectionHidden() )
938 segs.back().nonHiddenSectionCount++;
939 if ( sect->type() != ld::Section::typeSectCreate )
940 segs.back().nonSectCreateSections++;
942 segs.back().sections.push_back(sect);
944 // write out segment load commands for each section with trailing sections
945 for (std::vector<SegInfo>::iterator it = segs.begin(); it != segs.end(); ++it) {
946 SegInfo& si = *it;
947 ld::Internal::FinalSection* lastNonZeroFillSection = NULL;
948 for (int i=si.sections.size()-1; i >= 0; --i) {
949 if ( !sectionTakesNoDiskSpace(si.sections[i]) ) {
950 lastNonZeroFillSection = si.sections[i];
951 break;
954 uint64_t vmsize = si.sections.back()->address + si.sections.back()->size - si.sections.front()->address;
955 vmsize = ((vmsize+_options.segmentAlignment()-1) & (-_options.segmentAlignment()));
956 uint64_t filesize = 0;
957 if ( lastNonZeroFillSection != NULL ) {
958 filesize = lastNonZeroFillSection->address + lastNonZeroFillSection->size - si.sections.front()->address;
959 // round up all segments to page aligned, except __LINKEDIT
960 if ( (si.sections[0]->type() != ld::Section::typeLinkEdit) && (si.sections[0]->type() != ld::Section::typeImportProxies) )
961 filesize = (filesize + _options.segmentAlignment()-1) & (-_options.segmentAlignment());
963 if ( si.sections.front()->type() == ld::Section::typePageZero )
964 filesize = 0;
965 else if ( si.sections.front()->type() == ld::Section::typeStack )
966 filesize = 0;
967 macho_segment_command<P>* segCmd = (macho_segment_command<P>*)p;
968 segCmd->set_cmd(macho_segment_command<P>::CMD);
969 segCmd->set_cmdsize(sizeof(macho_segment_command<P>) + si.nonHiddenSectionCount*sizeof(macho_section<P>));
970 segCmd->set_segname(si.sections.front()->segmentName());
971 segCmd->set_vmaddr(si.sections.front()->address);
972 segCmd->set_vmsize(vmsize);
973 segCmd->set_fileoff(si.sections.front()->fileOffset);
974 segCmd->set_filesize(filesize);
975 segCmd->set_maxprot(si.maxProt);
976 segCmd->set_initprot(si.initProt);
977 segCmd->set_nsects(si.nonHiddenSectionCount);
978 segCmd->set_flags(si.nonSectCreateSections ? 0 : SG_NORELOC); // FIXME, really should check all References
979 if ( strcmp(segCmd->segname(), "__LINKEDIT") == 0 )
980 _linkeditCmdOffset = p - base;
981 p += sizeof(macho_segment_command<P>);
982 macho_section<P>* msect = (macho_section<P>*)p;
983 for (std::vector<ld::Internal::FinalSection*>::iterator sit = si.sections.begin(); sit != si.sections.end(); ++sit) {
984 ld::Internal::FinalSection* fsect = *sit;
985 if ( ! fsect->isSectionHidden() ) {
986 msect->set_sectname(fsect->sectionName());
987 msect->set_segname(fsect->segmentName());
988 msect->set_addr(fsect->address);
989 msect->set_size(fsect->size);
990 msect->set_offset(sectionTakesNoDiskSpace(fsect) ? 0 : fsect->fileOffset);
991 msect->set_align(fsect->alignment);
992 msect->set_reloff(0);
993 msect->set_nreloc(0);
994 msect->set_flags(sectionFlags(fsect));
995 msect->set_reserved1(fsect->indirectSymTabStartIndex);
996 msect->set_reserved2(fsect->indirectSymTabElementSize);
997 p += sizeof(macho_section<P>);
998 ++msect;
1003 return p;
1007 template <typename A>
1008 uint8_t* HeaderAndLoadCommandsAtom<A>::copySymbolTableLoadCommand(uint8_t* p, uint8_t* base) const
1010 _symboltableCmdOffset = p - base;
1011 // build LC_SYMTAB command
1012 macho_symtab_command<P>* symbolTableCmd = (macho_symtab_command<P>*)p;
1013 symbolTableCmd->set_cmd(LC_SYMTAB);
1014 symbolTableCmd->set_cmdsize(sizeof(macho_symtab_command<P>));
1015 symbolTableCmd->set_nsyms(_writer.symbolTableSection->size/sizeof(macho_nlist<P>));
1016 symbolTableCmd->set_symoff(_writer.symbolTableSection->size == 0 ? 0 : _writer.symbolTableSection->fileOffset);
1017 symbolTableCmd->set_stroff(_writer.stringPoolSection->size == 0 ? 0 : _writer.stringPoolSection->fileOffset );
1018 symbolTableCmd->set_strsize(_writer.stringPoolSection->size);
1019 return p + sizeof(macho_symtab_command<P>);
1022 template <typename A>
1023 uint8_t* HeaderAndLoadCommandsAtom<A>::copyDynamicSymbolTableLoadCommand(uint8_t* p) const
1025 // build LC_SYMTAB command
1026 macho_dysymtab_command<P>* dynamicSymbolTableCmd = (macho_dysymtab_command<P>*)p;
1027 dynamicSymbolTableCmd->set_cmd(LC_DYSYMTAB);
1028 dynamicSymbolTableCmd->set_cmdsize(sizeof(macho_dysymtab_command<P>));
1029 dynamicSymbolTableCmd->set_ilocalsym(0);
1030 dynamicSymbolTableCmd->set_nlocalsym(_writer._localSymbolsCount);
1031 dynamicSymbolTableCmd->set_iextdefsym(dynamicSymbolTableCmd->ilocalsym()+dynamicSymbolTableCmd->nlocalsym());
1032 dynamicSymbolTableCmd->set_nextdefsym(_writer._globalSymbolsCount);
1033 dynamicSymbolTableCmd->set_iundefsym(dynamicSymbolTableCmd->iextdefsym()+dynamicSymbolTableCmd->nextdefsym());
1034 dynamicSymbolTableCmd->set_nundefsym(_writer._importSymbolsCount);
1036 // FIX ME: support for 10.3 dylibs which need modules
1037 //if ( fWriter.fModuleInfoAtom != NULL ) {
1038 // dynamicSymbolTableCmd->set_tocoff(fWriter.fModuleInfoAtom->getTableOfContentsFileOffset());
1039 // dynamicSymbolTableCmd->set_ntoc(fWriter.fSymbolTableExportCount);
1040 // dynamicSymbolTableCmd->set_modtaboff(fWriter.fModuleInfoAtom->getModuleTableFileOffset());
1041 // dynamicSymbolTableCmd->set_nmodtab(1);
1042 // dynamicSymbolTableCmd->set_extrefsymoff(fWriter.fModuleInfoAtom->getReferencesFileOffset());
1043 // dynamicSymbolTableCmd->set_nextrefsyms(fWriter.fModuleInfoAtom->getReferencesCount());
1046 bool hasIndirectSymbols = ( (_writer.indirectSymbolTableSection != NULL) && (_writer.indirectSymbolTableSection->size != 0) );
1047 dynamicSymbolTableCmd->set_indirectsymoff(hasIndirectSymbols ? _writer.indirectSymbolTableSection->fileOffset : 0);
1048 dynamicSymbolTableCmd->set_nindirectsyms( hasIndirectSymbols ? _writer.indirectSymbolTableSection->size/sizeof(uint32_t) : 0);
1050 // FIX ME: support for classic relocations
1051 if ( _options.outputKind() != Options::kObjectFile ) {
1052 bool hasExternalRelocs = ( (_writer.externalRelocationsSection != NULL) && (_writer.externalRelocationsSection->size != 0) );
1053 dynamicSymbolTableCmd->set_extreloff(hasExternalRelocs ? _writer.externalRelocationsSection->fileOffset : 0);
1054 dynamicSymbolTableCmd->set_nextrel( hasExternalRelocs ? _writer.externalRelocationsSection->size/8 : 0);
1055 bool hasLocalRelocs = ( (_writer.localRelocationsSection != NULL) && (_writer.localRelocationsSection->size != 0) );
1056 dynamicSymbolTableCmd->set_locreloff(hasLocalRelocs ? _writer.localRelocationsSection->fileOffset : 0);
1057 dynamicSymbolTableCmd->set_nlocrel (hasLocalRelocs ? _writer.localRelocationsSection->size/8 : 0);
1059 return p + sizeof(macho_dysymtab_command<P>);
1063 template <typename A>
1064 uint8_t* HeaderAndLoadCommandsAtom<A>::copyDyldInfoLoadCommand(uint8_t* p) const
1066 // build LC_DYLD_INFO command
1067 macho_dyld_info_command<P>* cmd = (macho_dyld_info_command<P>*)p;
1069 cmd->set_cmd(LC_DYLD_INFO_ONLY);
1070 cmd->set_cmdsize(sizeof(macho_dyld_info_command<P>));
1071 if ( _writer.rebaseSection->size != 0 ) {
1072 cmd->set_rebase_off(_writer.rebaseSection->fileOffset);
1073 cmd->set_rebase_size(_writer.rebaseSection->size);
1075 if ( _writer.bindingSection->size != 0 ) {
1076 cmd->set_bind_off(_writer.bindingSection->fileOffset);
1077 cmd->set_bind_size(_writer.bindingSection->size);
1079 if ( _writer.weakBindingSection->size != 0 ) {
1080 cmd->set_weak_bind_off(_writer.weakBindingSection->fileOffset);
1081 cmd->set_weak_bind_size(_writer.weakBindingSection->size);
1083 if ( _writer.lazyBindingSection->size != 0 ) {
1084 cmd->set_lazy_bind_off(_writer.lazyBindingSection->fileOffset);
1085 cmd->set_lazy_bind_size(_writer.lazyBindingSection->size);
1087 if ( _writer.exportSection->size != 0 ) {
1088 cmd->set_export_off(_writer.exportSection->fileOffset);
1089 cmd->set_export_size(_writer.exportSection->size);
1091 return p + sizeof(macho_dyld_info_command<P>);
1095 template <typename A>
1096 uint8_t* HeaderAndLoadCommandsAtom<A>::copyDyldLoadCommand(uint8_t* p) const
1098 uint32_t sz = alignedSize(sizeof(macho_dylinker_command<P>) + strlen(_options.dyldInstallPath()) + 1);
1099 macho_dylinker_command<P>* cmd = (macho_dylinker_command<P>*)p;
1100 if ( _options.outputKind() == Options::kDyld )
1101 cmd->set_cmd(LC_ID_DYLINKER);
1102 else
1103 cmd->set_cmd(LC_LOAD_DYLINKER);
1104 cmd->set_cmdsize(sz);
1105 cmd->set_name_offset();
1106 strcpy((char*)&p[sizeof(macho_dylinker_command<P>)], _options.dyldInstallPath());
1107 return p + sz;
1111 template <typename A>
1112 uint8_t* HeaderAndLoadCommandsAtom<A>::copyDylibIDLoadCommand(uint8_t* p) const
1114 uint32_t sz = alignedSize(sizeof(macho_dylib_command<P>) + strlen(_options.installPath()) + 1);
1115 macho_dylib_command<P>* cmd = (macho_dylib_command<P>*)p;
1116 cmd->set_cmd(LC_ID_DYLIB);
1117 cmd->set_cmdsize(sz);
1118 cmd->set_name_offset();
1119 cmd->set_timestamp(1); // needs to be some constant value that is different than DylibLoadCommandsAtom uses
1120 cmd->set_current_version(_options.currentVersion32());
1121 cmd->set_compatibility_version(_options.compatibilityVersion());
1122 strcpy((char*)&p[sizeof(macho_dylib_command<P>)], _options.installPath());
1123 return p + sz;
1126 template <typename A>
1127 uint8_t* HeaderAndLoadCommandsAtom<A>::copyRoutinesLoadCommand(uint8_t* p) const
1129 pint_t initAddr = _state.entryPoint->finalAddress();
1130 if ( _state.entryPoint->isThumb() )
1131 initAddr |= 1ULL;
1132 macho_routines_command<P>* cmd = (macho_routines_command<P>*)p;
1133 cmd->set_cmd(macho_routines_command<P>::CMD);
1134 cmd->set_cmdsize(sizeof(macho_routines_command<P>));
1135 cmd->set_init_address(initAddr);
1136 return p + sizeof(macho_routines_command<P>);
1140 template <typename A>
1141 void HeaderAndLoadCommandsAtom<A>::recopyUUIDCommand()
1143 assert(_uuidCmdInOutputBuffer != NULL);
1144 _uuidCmdInOutputBuffer->set_uuid(_uuid);
1148 template <typename A>
1149 uint8_t* HeaderAndLoadCommandsAtom<A>::copyUUIDLoadCommand(uint8_t* p) const
1151 macho_uuid_command<P>* cmd = (macho_uuid_command<P>*)p;
1152 cmd->set_cmd(LC_UUID);
1153 cmd->set_cmdsize(sizeof(macho_uuid_command<P>));
1154 cmd->set_uuid(_uuid);
1155 _uuidCmdInOutputBuffer = cmd; // save for later re-write by recopyUUIDCommand()
1156 return p + sizeof(macho_uuid_command<P>);
1160 template <typename A>
1161 uint8_t* HeaderAndLoadCommandsAtom<A>::copyVersionLoadCommand(uint8_t* p) const
1163 macho_version_min_command<P>* cmd = (macho_version_min_command<P>*)p;
1164 switch (_options.platform()) {
1165 case Options::kPlatformUnknown:
1166 assert(_state.derivedPlatformLoadCommand != 0 && "unknown platform");
1167 cmd->set_cmd(_state.derivedPlatformLoadCommand);
1168 cmd->set_cmdsize(sizeof(macho_version_min_command<P>));
1169 cmd->set_version(_state.minOSVersion);
1170 cmd->set_sdk(0);
1171 break;
1172 case Options::kPlatformOSX:
1173 cmd->set_cmd(LC_VERSION_MIN_MACOSX);
1174 cmd->set_cmdsize(sizeof(macho_version_min_command<P>));
1175 cmd->set_version(_state.minOSVersion);
1176 cmd->set_sdk(_options.sdkVersion());
1177 break;
1178 case Options::kPlatformiOS:
1179 cmd->set_cmd(LC_VERSION_MIN_IPHONEOS);
1180 cmd->set_cmdsize(sizeof(macho_version_min_command<P>));
1181 cmd->set_version(_state.minOSVersion);
1182 cmd->set_sdk(_options.sdkVersion());
1183 break;
1184 case Options::kPlatformWatchOS:
1185 cmd->set_cmd(LC_VERSION_MIN_WATCHOS);
1186 cmd->set_cmdsize(sizeof(macho_version_min_command<P>));
1187 cmd->set_version(_state.minOSVersion);
1188 cmd->set_sdk(_options.sdkVersion());
1189 break;
1190 #if SUPPORT_APPLE_TV
1191 case Options::kPlatform_tvOS:
1192 cmd->set_cmd(LC_VERSION_MIN_TVOS);
1193 cmd->set_cmdsize(sizeof(macho_version_min_command<P>));
1194 cmd->set_version(_state.minOSVersion);
1195 cmd->set_sdk(_options.sdkVersion());
1196 break;
1197 #endif
1199 return p + sizeof(macho_version_min_command<P>);
1202 template <typename A>
1203 uint8_t* HeaderAndLoadCommandsAtom<A>::copySourceVersionLoadCommand(uint8_t* p) const
1205 macho_source_version_command<P>* cmd = (macho_source_version_command<P>*)p;
1206 cmd->set_cmd(LC_SOURCE_VERSION);
1207 cmd->set_cmdsize(sizeof(macho_source_version_command<P>));
1208 cmd->set_version(_options.sourceVersion());
1209 return p + sizeof(macho_source_version_command<P>);
1213 template <>
1214 uint32_t HeaderAndLoadCommandsAtom<x86>::threadLoadCommandSize() const
1216 return this->alignedSize(16 + 16*4); // base size + i386_THREAD_STATE_COUNT * 4
1219 template <>
1220 uint8_t* HeaderAndLoadCommandsAtom<x86>::copyThreadsLoadCommand(uint8_t* p) const
1222 assert(_state.entryPoint != NULL);
1223 pint_t start = _state.entryPoint->finalAddress();
1224 macho_thread_command<P>* cmd = (macho_thread_command<P>*)p;
1225 cmd->set_cmd(LC_UNIXTHREAD);
1226 cmd->set_cmdsize(threadLoadCommandSize());
1227 cmd->set_flavor(1); // i386_THREAD_STATE
1228 cmd->set_count(16); // i386_THREAD_STATE_COUNT;
1229 cmd->set_thread_register(10, start);
1230 if ( _options.hasCustomStack() )
1231 cmd->set_thread_register(7, _options.customStackAddr()); // r1
1232 return p + threadLoadCommandSize();
1235 template <>
1236 uint32_t HeaderAndLoadCommandsAtom<x86_64>::threadLoadCommandSize() const
1238 return this->alignedSize(16 + 42*4); // base size + x86_THREAD_STATE64_COUNT * 4
1241 template <>
1242 uint8_t* HeaderAndLoadCommandsAtom<x86_64>::copyThreadsLoadCommand(uint8_t* p) const
1244 assert(_state.entryPoint != NULL);
1245 pint_t start = _state.entryPoint->finalAddress();
1246 macho_thread_command<P>* cmd = (macho_thread_command<P>*)p;
1247 cmd->set_cmd(LC_UNIXTHREAD);
1248 cmd->set_cmdsize(threadLoadCommandSize());
1249 cmd->set_flavor(4); // x86_THREAD_STATE64
1250 cmd->set_count(42); // x86_THREAD_STATE64_COUNT
1251 cmd->set_thread_register(16, start); // rip
1252 if ( _options.hasCustomStack() )
1253 cmd->set_thread_register(7, _options.customStackAddr()); // r1
1254 return p + threadLoadCommandSize();
1257 template <>
1258 uint32_t HeaderAndLoadCommandsAtom<arm>::threadLoadCommandSize() const
1260 return this->alignedSize(16 + 17 * 4); // base size + ARM_THREAD_STATE_COUNT * 4
1263 template <>
1264 uint8_t* HeaderAndLoadCommandsAtom<arm>::copyThreadsLoadCommand(uint8_t* p) const
1266 assert(_state.entryPoint != NULL);
1267 pint_t start = _state.entryPoint->finalAddress();
1268 if ( _state.entryPoint->isThumb() )
1269 start |= 1ULL;
1270 macho_thread_command<P>* cmd = (macho_thread_command<P>*)p;
1271 cmd->set_cmd(LC_UNIXTHREAD);
1272 cmd->set_cmdsize(threadLoadCommandSize());
1273 cmd->set_flavor(1);
1274 cmd->set_count(17);
1275 cmd->set_thread_register(15, start); // pc
1276 if ( _options.hasCustomStack() )
1277 cmd->set_thread_register(13, _options.customStackAddr()); // sp
1278 return p + threadLoadCommandSize();
1282 template <>
1283 uint32_t HeaderAndLoadCommandsAtom<arm64>::threadLoadCommandSize() const
1285 return this->alignedSize(16 + 34 * 8); // base size + ARM_EXCEPTION_STATE64_COUNT * 4
1288 template <>
1289 uint8_t* HeaderAndLoadCommandsAtom<arm64>::copyThreadsLoadCommand(uint8_t* p) const
1291 assert(_state.entryPoint != NULL);
1292 pint_t start = _state.entryPoint->finalAddress();
1293 macho_thread_command<P>* cmd = (macho_thread_command<P>*)p;
1294 cmd->set_cmd(LC_UNIXTHREAD);
1295 cmd->set_cmdsize(threadLoadCommandSize());
1296 cmd->set_flavor(6); // ARM_THREAD_STATE64
1297 cmd->set_count(68); // ARM_EXCEPTION_STATE64_COUNT
1298 cmd->set_thread_register(32, start); // pc
1299 if ( _options.hasCustomStack() )
1300 cmd->set_thread_register(31, _options.customStackAddr()); // sp
1301 return p + threadLoadCommandSize();
1305 template <typename A>
1306 uint8_t* HeaderAndLoadCommandsAtom<A>::copyEntryPointLoadCommand(uint8_t* p) const
1308 macho_entry_point_command<P>* cmd = (macho_entry_point_command<P>*)p;
1309 cmd->set_cmd(LC_MAIN);
1310 cmd->set_cmdsize(sizeof(macho_entry_point_command<P>));
1311 assert(_state.entryPoint != NULL);
1312 pint_t start = _state.entryPoint->finalAddress();
1313 if ( _state.entryPoint->isThumb() )
1314 start |= 1ULL;
1315 cmd->set_entryoff(start - this->finalAddress());
1316 cmd->set_stacksize(_options.hasCustomStack() ? _options.customStackSize() : 0 );
1317 return p + sizeof(macho_entry_point_command<P>);
1321 template <typename A>
1322 uint8_t* HeaderAndLoadCommandsAtom<A>::copyEncryptionLoadCommand(uint8_t* p) const
1324 macho_encryption_info_command<P>* cmd = (macho_encryption_info_command<P>*)p;
1325 cmd->set_cmd(sizeof(typename A::P::uint_t) == 4 ? LC_ENCRYPTION_INFO : LC_ENCRYPTION_INFO_64);
1326 cmd->set_cmdsize(sizeof(macho_encryption_info_command<P>));
1327 assert(_writer.encryptedTextStartOffset() != 0);
1328 assert(_writer.encryptedTextEndOffset() != 0);
1329 cmd->set_cryptoff(_writer.encryptedTextStartOffset());
1330 cmd->set_cryptsize(_writer.encryptedTextEndOffset()-_writer.encryptedTextStartOffset());
1331 cmd->set_cryptid(0);
1332 return p + sizeof(macho_encryption_info_command<P>);
1336 template <typename A>
1337 uint8_t* HeaderAndLoadCommandsAtom<A>::copySplitSegInfoLoadCommand(uint8_t* p) const
1339 macho_linkedit_data_command<P>* cmd = (macho_linkedit_data_command<P>*)p;
1340 cmd->set_cmd(LC_SEGMENT_SPLIT_INFO);
1341 cmd->set_cmdsize(sizeof(macho_linkedit_data_command<P>));
1342 cmd->set_dataoff(_writer.splitSegInfoSection->fileOffset);
1343 cmd->set_datasize(_writer.splitSegInfoSection->size);
1344 return p + sizeof(macho_linkedit_data_command<P>);
1348 template <typename A>
1349 uint8_t* HeaderAndLoadCommandsAtom<A>::copyDylibLoadCommand(uint8_t* p, const ld::dylib::File* dylib) const
1351 uint32_t sz = alignedSize(sizeof(macho_dylib_command<P>) + strlen(dylib->installPath()) + 1);
1352 macho_dylib_command<P>* cmd = (macho_dylib_command<P>*)p;
1353 if ( dylib->willBeLazyLoadedDylib() )
1354 cmd->set_cmd(LC_LAZY_LOAD_DYLIB);
1355 else if ( dylib->forcedWeakLinked() || dylib->allSymbolsAreWeakImported() )
1356 cmd->set_cmd(LC_LOAD_WEAK_DYLIB);
1357 else if ( dylib->willBeReExported() && _options.useSimplifiedDylibReExports() )
1358 cmd->set_cmd(LC_REEXPORT_DYLIB);
1359 else if ( dylib->willBeUpwardDylib() && _options.useUpwardDylibs() )
1360 cmd->set_cmd(LC_LOAD_UPWARD_DYLIB);
1361 else
1362 cmd->set_cmd(LC_LOAD_DYLIB);
1363 cmd->set_cmdsize(sz);
1364 cmd->set_timestamp(2); // needs to be some constant value that is different than DylibIDLoadCommandsAtom uses
1365 cmd->set_current_version(dylib->currentVersion());
1366 cmd->set_compatibility_version(dylib->compatibilityVersion());
1367 cmd->set_name_offset();
1368 strcpy((char*)&p[sizeof(macho_dylib_command<P>)], dylib->installPath());
1369 return p + sz;
1372 template <typename A>
1373 uint8_t* HeaderAndLoadCommandsAtom<A>::copyRPathLoadCommand(uint8_t* p, const char* path) const
1375 uint32_t sz = alignedSize(sizeof(macho_rpath_command<P>) + strlen(path) + 1);
1376 macho_rpath_command<P>* cmd = (macho_rpath_command<P>*)p;
1377 cmd->set_cmd(LC_RPATH);
1378 cmd->set_cmdsize(sz);
1379 cmd->set_path_offset();
1380 strcpy((char*)&p[sizeof(macho_rpath_command<P>)], path);
1381 return p + sz;
1384 template <typename A>
1385 uint8_t* HeaderAndLoadCommandsAtom<A>::copySubFrameworkLoadCommand(uint8_t* p) const
1387 const char* umbrellaName = _options.umbrellaName();
1388 uint32_t sz = alignedSize(sizeof(macho_sub_framework_command<P>) + strlen(umbrellaName) + 1);
1389 macho_sub_framework_command<P>* cmd = (macho_sub_framework_command<P>*)p;
1390 cmd->set_cmd(LC_SUB_FRAMEWORK);
1391 cmd->set_cmdsize(sz);
1392 cmd->set_umbrella_offset();
1393 strcpy((char*)&p[sizeof(macho_sub_framework_command<P>)], umbrellaName);
1394 return p + sz;
1398 template <typename A>
1399 uint8_t* HeaderAndLoadCommandsAtom<A>::copyAllowableClientLoadCommand(uint8_t* p, const char* client) const
1401 uint32_t sz = alignedSize(sizeof(macho_sub_client_command<P>) + strlen(client) + 1);
1402 macho_sub_client_command<P>* cmd = (macho_sub_client_command<P>*)p;
1403 cmd->set_cmd(LC_SUB_CLIENT);
1404 cmd->set_cmdsize(sz);
1405 cmd->set_client_offset();
1406 strcpy((char*)&p[sizeof(macho_sub_client_command<P>)], client);
1407 return p + sz;
1410 template <typename A>
1411 uint8_t* HeaderAndLoadCommandsAtom<A>::copyDyldEnvLoadCommand(uint8_t* p, const char* env) const
1413 uint32_t sz = alignedSize(sizeof(macho_dylinker_command<P>) + strlen(env) + 1);
1414 macho_dylinker_command<P>* cmd = (macho_dylinker_command<P>*)p;
1415 cmd->set_cmd(LC_DYLD_ENVIRONMENT);
1416 cmd->set_cmdsize(sz);
1417 cmd->set_name_offset();
1418 strcpy((char*)&p[sizeof(macho_dylinker_command<P>)], env);
1419 return p + sz;
1422 template <typename A>
1423 uint8_t* HeaderAndLoadCommandsAtom<A>::copySubUmbrellaLoadCommand(uint8_t* p, const char* nm) const
1425 uint32_t sz = alignedSize(sizeof(macho_sub_umbrella_command<P>) + strlen(nm) + 1);
1426 macho_sub_umbrella_command<P>* cmd = (macho_sub_umbrella_command<P>*)p;
1427 cmd->set_cmd(LC_SUB_UMBRELLA);
1428 cmd->set_cmdsize(sz);
1429 cmd->set_sub_umbrella_offset();
1430 strcpy((char*)&p[sizeof(macho_sub_umbrella_command<P>)], nm);
1431 return p + sz;
1434 template <typename A>
1435 uint8_t* HeaderAndLoadCommandsAtom<A>::copySubLibraryLoadCommand(uint8_t* p, const char* nm) const
1437 uint32_t sz = alignedSize(sizeof(macho_sub_library_command<P>) + strlen(nm) + 1);
1438 macho_sub_library_command<P>* cmd = (macho_sub_library_command<P>*)p;
1439 cmd->set_cmd(LC_SUB_LIBRARY);
1440 cmd->set_cmdsize(sz);
1441 cmd->set_sub_library_offset();
1442 strcpy((char*)&p[sizeof(macho_sub_library_command<P>)], nm);
1443 return p + sz;
1446 template <typename A>
1447 uint8_t* HeaderAndLoadCommandsAtom<A>::copyFunctionStartsLoadCommand(uint8_t* p) const
1449 macho_linkedit_data_command<P>* cmd = (macho_linkedit_data_command<P>*)p;
1450 cmd->set_cmd(LC_FUNCTION_STARTS);
1451 cmd->set_cmdsize(sizeof(macho_linkedit_data_command<P>));
1452 cmd->set_dataoff(_writer.functionStartsSection->fileOffset);
1453 cmd->set_datasize(_writer.functionStartsSection->size);
1454 return p + sizeof(macho_linkedit_data_command<P>);
1458 template <typename A>
1459 uint8_t* HeaderAndLoadCommandsAtom<A>::copyDataInCodeLoadCommand(uint8_t* p) const
1461 macho_linkedit_data_command<P>* cmd = (macho_linkedit_data_command<P>*)p;
1462 cmd->set_cmd(LC_DATA_IN_CODE);
1463 cmd->set_cmdsize(sizeof(macho_linkedit_data_command<P>));
1464 cmd->set_dataoff(_writer.dataInCodeSection->fileOffset);
1465 cmd->set_datasize(_writer.dataInCodeSection->size);
1466 return p + sizeof(macho_linkedit_data_command<P>);
1470 template <typename A>
1471 uint8_t* HeaderAndLoadCommandsAtom<A>::copyLinkerOptionsLoadCommand(uint8_t* p, const std::vector<const char*>& options) const
1473 macho_linker_option_command<P>* cmd = (macho_linker_option_command<P>*)p;
1474 cmd->set_cmd(LC_LINKER_OPTION);
1475 cmd->set_count(options.size());
1476 char* buffer = cmd->buffer();
1477 uint32_t sz = sizeof(macho_linker_option_command<P>);
1478 for (std::vector<const char*>::const_iterator it=options.begin(); it != options.end(); ++it) {
1479 const char* opt = *it;
1480 uint32_t len = strlen(opt);
1481 strcpy(buffer, opt);
1482 sz += (len + 1);
1483 buffer += (len + 1);
1485 sz = alignedSize(sz);
1486 cmd->set_cmdsize(sz);
1487 return p + sz;
1492 template <typename A>
1493 uint8_t* HeaderAndLoadCommandsAtom<A>::copyOptimizationHintsLoadCommand(uint8_t* p) const
1495 macho_linkedit_data_command<P>* cmd = (macho_linkedit_data_command<P>*)p;
1496 cmd->set_cmd(LC_LINKER_OPTIMIZATION_HINTS);
1497 cmd->set_cmdsize(sizeof(macho_linkedit_data_command<P>));
1498 cmd->set_dataoff(_writer.optimizationHintsSection->fileOffset);
1499 cmd->set_datasize(_writer.optimizationHintsSection->size);
1500 return p + sizeof(macho_linkedit_data_command<P>);
1504 template <typename A>
1505 void HeaderAndLoadCommandsAtom<A>::copyRawContent(uint8_t buffer[]) const
1507 macho_header<P>* mh = (macho_header<P>*)buffer;
1508 bzero(buffer, this->size());
1510 // copy mach_header
1511 mh->set_magic(this->magic());
1512 mh->set_cputype(this->cpuType());
1513 mh->set_cpusubtype(this->cpuSubType());
1514 mh->set_filetype(this->fileType());
1515 mh->set_ncmds(this->commandsCount());
1516 mh->set_sizeofcmds(this->size()-sizeof(macho_header<P>));
1517 mh->set_flags(this->flags());
1519 // copy load commands
1520 uint8_t* p = &buffer[sizeof(macho_header<P>)];
1522 if ( _options.outputKind() == Options::kObjectFile )
1523 p = this->copySingleSegmentLoadCommand(p);
1524 else
1525 p = this->copySegmentLoadCommands(p, buffer);
1527 if ( _hasDylibIDLoadCommand )
1528 p = this->copyDylibIDLoadCommand(p);
1530 if ( _hasDyldInfoLoadCommand )
1531 p = this->copyDyldInfoLoadCommand(p);
1533 if ( _hasSymbolTableLoadCommand )
1534 p = this->copySymbolTableLoadCommand(p, buffer);
1536 if ( _hasDynamicSymbolTableLoadCommand )
1537 p = this->copyDynamicSymbolTableLoadCommand(p);
1539 if ( _hasDyldLoadCommand )
1540 p = this->copyDyldLoadCommand(p);
1542 if ( _hasRoutinesLoadCommand )
1543 p = this->copyRoutinesLoadCommand(p);
1545 if ( _hasUUIDLoadCommand )
1546 p = this->copyUUIDLoadCommand(p);
1548 if ( _hasVersionLoadCommand )
1549 p = this->copyVersionLoadCommand(p);
1551 if ( _hasSourceVersionLoadCommand )
1552 p = this->copySourceVersionLoadCommand(p);
1554 if ( _hasThreadLoadCommand )
1555 p = this->copyThreadsLoadCommand(p);
1557 if ( _hasEntryPointLoadCommand )
1558 p = this->copyEntryPointLoadCommand(p);
1560 if ( _hasEncryptionLoadCommand )
1561 p = this->copyEncryptionLoadCommand(p);
1563 if ( _hasSplitSegInfoLoadCommand )
1564 p = this->copySplitSegInfoLoadCommand(p);
1566 for (uint32_t ord=1; ord <= _writer.dylibCount(); ++ord) {
1567 p = this->copyDylibLoadCommand(p, _writer.dylibByOrdinal(ord));
1570 if ( _hasRPathLoadCommands ) {
1571 const std::vector<const char*>& rpaths = _options.rpaths();
1572 for (std::vector<const char*>::const_iterator it = rpaths.begin(); it != rpaths.end(); ++it) {
1573 p = this->copyRPathLoadCommand(p, *it);
1577 if ( _hasSubFrameworkLoadCommand )
1578 p = this->copySubFrameworkLoadCommand(p);
1580 for (std::vector<const char*>::const_iterator it = _subLibraryNames.begin(); it != _subLibraryNames.end(); ++it) {
1581 p = this->copySubLibraryLoadCommand(p, *it);
1584 for (std::vector<const char*>::const_iterator it = _subUmbrellaNames.begin(); it != _subUmbrellaNames.end(); ++it) {
1585 p = this->copySubUmbrellaLoadCommand(p, *it);
1588 if ( _allowableClientLoadCommmandsCount != 0 ) {
1589 const std::vector<const char*>& clients = _options.allowableClients();
1590 for (std::vector<const char*>::const_iterator it = clients.begin(); it != clients.end(); ++it) {
1591 p = this->copyAllowableClientLoadCommand(p, *it);
1595 if ( _dyldEnvironExrasCount != 0 ) {
1596 const std::vector<const char*>& extras = _options.dyldEnvironExtras();
1597 for (std::vector<const char*>::const_iterator it = extras.begin(); it != extras.end(); ++it) {
1598 p = this->copyDyldEnvLoadCommand(p, *it);
1602 if ( _hasFunctionStartsLoadCommand )
1603 p = this->copyFunctionStartsLoadCommand(p);
1605 if ( _hasDataInCodeLoadCommand )
1606 p = this->copyDataInCodeLoadCommand(p);
1608 if ( !_linkerOptions.empty() ) {
1609 for (ld::relocatable::File::LinkerOptionsList::const_iterator it = _linkerOptions.begin(); it != _linkerOptions.end(); ++it) {
1610 p = this->copyLinkerOptionsLoadCommand(p, *it);
1614 if ( _hasOptimizationHints )
1615 p = this->copyOptimizationHintsLoadCommand(p);
1621 } // namespace tool
1622 } // namespace ld
1624 #endif // __HEADER_LOAD_COMMANDS_HPP__