]> git.saurik.com Git - apple/ld64.git/blob - src/ld/HeaderAndLoadCommands.hpp
35daef1de569ce2bba0da10190b3132bef5db4cd
[apple/ld64.git] / src / ld / HeaderAndLoadCommands.hpp
1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-*
2 *
3 * Copyright (c) 2009-2011 Apple Inc. All rights reserved.
4 *
5 * @APPLE_LICENSE_HEADER_START@
6 *
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.
13 *
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.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24
25 #ifndef __HEADER_LOAD_COMMANDS_HPP__
26 #define __HEADER_LOAD_COMMANDS_HPP__
27
28 #include <stdlib.h>
29 #include <limits.h>
30 #include <unistd.h>
31 #include <mach-o/loader.h>
32
33 #include <vector>
34
35 #include "MachOFileAbstraction.hpp"
36 #include "Options.h"
37 #include "ld.hpp"
38
39 namespace ld {
40 namespace tool {
41
42 class HeaderAndLoadCommandsAbtract : public ld::Atom
43 {
44 public:
45 HeaderAndLoadCommandsAbtract(const ld::Section& sect, ld::Atom::Definition d,
46 ld::Atom::Combine c, ld::Atom::Scope s, ld::Atom::ContentType ct,
47 ld::Atom::SymbolTableInclusion i, bool dds, bool thumb, bool al,
48 ld::Atom::Alignment a) : ld::Atom(sect, d, c, s, ct, i, dds, thumb, al, a) { }
49
50 virtual void setUUID(const uint8_t digest[16]) = 0;
51 virtual void recopyUUIDCommand() = 0;
52 };
53
54 template <typename A>
55 class HeaderAndLoadCommandsAtom : public HeaderAndLoadCommandsAbtract
56 {
57 public:
58 HeaderAndLoadCommandsAtom(const Options& opts, ld::Internal& state,
59 OutputFile& writer);
60
61 // overrides of ld::Atom
62 virtual ld::File* file() const { return NULL; }
63 virtual const char* name() const { return "mach-o header and load commands"; }
64 virtual uint64_t size() const;
65 virtual uint64_t objectAddress() const { return _address; }
66 virtual void copyRawContent(uint8_t buffer[]) const;
67
68 // overrides of HeaderAndLoadCommandsAbtract
69 virtual void setUUID(const uint8_t digest[16]) { memcpy(_uuid, digest, 16); }
70 virtual void recopyUUIDCommand();
71
72 private:
73 typedef typename A::P P;
74 typedef typename A::P::E E;
75 typedef typename A::P::uint_t pint_t;
76
77 unsigned int nonHiddenSectionCount() const;
78 unsigned int segmentCount() const;
79 static uint32_t alignedSize(uint32_t x);
80 uint32_t magic() const;
81 uint32_t cpuType() const;
82 uint32_t cpuSubType() const;
83 uint32_t flags() const;
84 uint32_t fileType() const;
85 uint32_t commandsCount() const;
86 uint32_t threadLoadCommandSize() const;
87 uint8_t* copySingleSegmentLoadCommand(uint8_t* p) const;
88 uint8_t* copySegmentLoadCommands(uint8_t* p) const;
89 uint8_t* copyDyldInfoLoadCommand(uint8_t* p) const;
90 uint8_t* copySymbolTableLoadCommand(uint8_t* p) const;
91 uint8_t* copyDynamicSymbolTableLoadCommand(uint8_t* p) const;
92 uint8_t* copyDyldLoadCommand(uint8_t* p) const;
93 uint8_t* copyDylibIDLoadCommand(uint8_t* p) const;
94 uint8_t* copyRoutinesLoadCommand(uint8_t* p) const;
95 uint8_t* copyUUIDLoadCommand(uint8_t* p) const;
96 uint8_t* copyVersionLoadCommand(uint8_t* p) const;
97 uint8_t* copySourceVersionLoadCommand(uint8_t* p) const;
98 uint8_t* copyThreadsLoadCommand(uint8_t* p) const;
99 uint8_t* copyEntryPointLoadCommand(uint8_t* p) const;
100 uint8_t* copyEncryptionLoadCommand(uint8_t* p) const;
101 uint8_t* copySplitSegInfoLoadCommand(uint8_t* p) const;
102 uint8_t* copyDylibLoadCommand(uint8_t* p, const ld::dylib::File*) const;
103 uint8_t* copyRPathLoadCommand(uint8_t* p, const char*) const;
104 uint8_t* copySubFrameworkLoadCommand(uint8_t* p) const;
105 uint8_t* copyAllowableClientLoadCommand(uint8_t* p, const char* client) const;
106 uint8_t* copySubLibraryLoadCommand(uint8_t* p, const char* name) const;
107 uint8_t* copySubUmbrellaLoadCommand(uint8_t* p, const char* name) const;
108 uint8_t* copyFunctionStartsLoadCommand(uint8_t* p) const;
109 uint8_t* copyDataInCodeLoadCommand(uint8_t* p) const;
110 uint8_t* copyDependentDRLoadCommand(uint8_t* p) const;
111 uint8_t* copyDyldEnvLoadCommand(uint8_t* p, const char* env) const;
112 uint8_t* copyLinkerOptionsLoadCommand(uint8_t* p, const std::vector<const char*>&) const;
113
114 uint32_t sectionFlags(ld::Internal::FinalSection* sect) const;
115 bool sectionTakesNoDiskSpace(ld::Internal::FinalSection* sect) const;
116
117
118 const Options& _options;
119 ld::Internal& _state;
120 OutputFile& _writer;
121 pint_t _address;
122 bool _hasDyldInfoLoadCommand;
123 bool _hasDyldLoadCommand;
124 bool _hasDylibIDLoadCommand;
125 bool _hasThreadLoadCommand;
126 bool _hasEntryPointLoadCommand;
127 bool _hasEncryptionLoadCommand;
128 bool _hasSplitSegInfoLoadCommand;
129 bool _hasRoutinesLoadCommand;
130 bool _hasUUIDLoadCommand;
131 bool _hasSymbolTableLoadCommand;
132 bool _hasDynamicSymbolTableLoadCommand;
133 bool _hasRPathLoadCommands;
134 bool _hasSubFrameworkLoadCommand;
135 bool _hasVersionLoadCommand;
136 bool _hasFunctionStartsLoadCommand;
137 bool _hasDataInCodeLoadCommand;
138 bool _hasSourceVersionLoadCommand;
139 bool _hasDependentDRInfo;
140 uint32_t _dylibLoadCommmandsCount;
141 uint32_t _allowableClientLoadCommmandsCount;
142 uint32_t _dyldEnvironExrasCount;
143 std::vector<const char*> _subLibraryNames;
144 std::vector<const char*> _subUmbrellaNames;
145 uint8_t _uuid[16];
146 mutable macho_uuid_command<P>* _uuidCmdInOutputBuffer;
147 std::vector< std::vector<const char*> > _linkerOptions;
148
149 static ld::Section _s_section;
150 static ld::Section _s_preload_section;
151 };
152
153 template <typename A>
154 ld::Section HeaderAndLoadCommandsAtom<A>::_s_section("__TEXT", "__mach_header", ld::Section::typeMachHeader, true);
155 template <typename A>
156 ld::Section HeaderAndLoadCommandsAtom<A>::_s_preload_section("__HEADER", "__mach_header", ld::Section::typeMachHeader, true);
157
158
159 template <typename A>
160 HeaderAndLoadCommandsAtom<A>::HeaderAndLoadCommandsAtom(const Options& opts, ld::Internal& state, OutputFile& writer)
161 : HeaderAndLoadCommandsAbtract((opts.outputKind() == Options::kPreload) ? _s_preload_section : _s_section,
162 ld::Atom::definitionRegular, ld::Atom::combineNever,
163 ld::Atom::scopeTranslationUnit, ld::Atom::typeUnclassified,
164 ld::Atom::symbolTableNotIn, false, false, false,
165 (opts.outputKind() == Options::kPreload) ? ld::Atom::Alignment(0) : ld::Atom::Alignment(12) ),
166 _options(opts), _state(state), _writer(writer), _address(0), _uuidCmdInOutputBuffer(NULL)
167 {
168 bzero(_uuid, 16);
169 _hasDyldInfoLoadCommand = opts.makeCompressedDyldInfo();
170 _hasDyldLoadCommand = ((opts.outputKind() == Options::kDynamicExecutable) || (_options.outputKind() == Options::kDyld));
171 _hasDylibIDLoadCommand = (opts.outputKind() == Options::kDynamicLibrary);
172 _hasThreadLoadCommand = _options.needsThreadLoadCommand();
173 _hasEntryPointLoadCommand = _options.needsEntryPointLoadCommand();
174 _hasEncryptionLoadCommand = opts.makeEncryptable();
175 _hasSplitSegInfoLoadCommand = opts.sharedRegionEligible();
176 _hasRoutinesLoadCommand = (opts.initFunctionName() != NULL);
177 _hasSymbolTableLoadCommand = true;
178 _hasUUIDLoadCommand = (opts.UUIDMode() != Options::kUUIDNone);
179 switch ( opts.outputKind() ) {
180 case Options::kDynamicExecutable:
181 case Options::kDynamicLibrary:
182 case Options::kDynamicBundle:
183 case Options::kDyld:
184 case Options::kKextBundle:
185 _hasDynamicSymbolTableLoadCommand = true;
186 break;
187 case Options::kObjectFile:
188 if ( ! state.someObjectFileHasDwarf )
189 _hasUUIDLoadCommand = false;
190 _hasDynamicSymbolTableLoadCommand = false;
191 for (std::vector<ld::Internal::FinalSection*>::iterator it = _state.sections.begin(); it != _state.sections.end(); ++it) {
192 if ( (*it)->type() == ld::Section::typeNonLazyPointer ) {
193 _hasDynamicSymbolTableLoadCommand = true;
194 break;
195 }
196 }
197 for (CStringSet::const_iterator it = _state.linkerOptionFrameworks.begin(); it != _state.linkerOptionFrameworks.end(); ++it) {
198 const char* frameWorkName = *it;
199 std::vector<const char*>* lo = new std::vector<const char*>();
200 lo->push_back("-framework");
201 lo->push_back(frameWorkName);
202 _linkerOptions.push_back(*lo);
203 };
204 for (CStringSet::const_iterator it = _state.linkerOptionLibraries.begin(); it != _state.linkerOptionLibraries.end(); ++it) {
205 const char* libName = *it;
206 std::vector<const char*>* lo = new std::vector<const char*>();
207 char * s = new char[strlen(libName)+3];
208 strcpy(s, "-l");
209 strcat(s, libName);
210 lo->push_back(s);
211 _linkerOptions.push_back(*lo);
212 };
213 break;
214 case Options::kStaticExecutable:
215 _hasDynamicSymbolTableLoadCommand = opts.positionIndependentExecutable();
216 break;
217 case Options::kPreload:
218 _hasDynamicSymbolTableLoadCommand = opts.positionIndependentExecutable();
219 break;
220 }
221 _hasRPathLoadCommands = (_options.rpaths().size() != 0);
222 _hasSubFrameworkLoadCommand = (_options.umbrellaName() != NULL);
223 _hasVersionLoadCommand = _options.addVersionLoadCommand();
224 _hasFunctionStartsLoadCommand = _options.addFunctionStarts();
225 _hasDataInCodeLoadCommand = _options.addDataInCodeInfo();
226 _hasSourceVersionLoadCommand = _options.needsSourceVersionLoadCommand();
227 _hasDependentDRInfo = _options.needsDependentDRInfo();
228 _dylibLoadCommmandsCount = _writer.dylibCount();
229 _allowableClientLoadCommmandsCount = _options.allowableClients().size();
230 _dyldEnvironExrasCount = _options.dyldEnvironExtras().size();
231
232 if ( ! _options.useSimplifiedDylibReExports() ) {
233 // target OS does not support LC_REEXPORT_DYLIB, so use old complicated load commands
234 for(uint32_t ord=1; ord <= _writer.dylibCount(); ++ord) {
235 const ld::dylib::File* dylib = _writer.dylibByOrdinal(ord);
236 if ( dylib->willBeReExported() ) {
237 // if child says it is an sub-framework of the image being created, then nothing to do here
238 bool isSubFramework = false;
239 const char* childInUmbrella = dylib->parentUmbrella();
240 if ( childInUmbrella != NULL ) {
241 const char* myLeaf = strrchr(_options.installPath(), '/');
242 if ( myLeaf != NULL ) {
243 if ( strcmp(childInUmbrella, &myLeaf[1]) == 0 )
244 isSubFramework = true;
245 }
246 }
247 // LC_SUB_FRAMEWORK is in child, so do nothing in parent
248 if ( ! isSubFramework ) {
249 // this dylib also needs a sub_x load command
250 bool isFrameworkReExport = false;
251 const char* lastSlash = strrchr(dylib->installPath(), '/');
252 if ( lastSlash != NULL ) {
253 char frameworkName[strlen(lastSlash)+20];
254 sprintf(frameworkName, "/%s.framework/", &lastSlash[1]);
255 isFrameworkReExport = (strstr(dylib->installPath(), frameworkName) != NULL);
256 }
257 if ( isFrameworkReExport ) {
258 // needs a LC_SUB_UMBRELLA command
259 _subUmbrellaNames.push_back(&lastSlash[1]);
260 }
261 else {
262 // needs a LC_SUB_LIBRARY command
263 const char* nameStart = &lastSlash[1];
264 if ( lastSlash == NULL )
265 nameStart = dylib->installPath();
266 int len = strlen(nameStart);
267 const char* dot = strchr(nameStart, '.');
268 if ( dot != NULL )
269 len = dot - nameStart;
270 char* subLibName = new char[len+1];
271 strlcpy(subLibName, nameStart, len+1);
272 _subLibraryNames.push_back(subLibName);
273 }
274 }
275 }
276 }
277 }
278 }
279
280 template <typename A>
281 uint32_t HeaderAndLoadCommandsAtom<A>::alignedSize(uint32_t size)
282 {
283 if ( sizeof(pint_t) == 4 )
284 return ((size+3) & (-4)); // 4-byte align all load commands for 32-bit mach-o
285 else
286 return ((size+7) & (-8)); // 8-byte align all load commands for 64-bit mach-o
287 }
288
289
290 template <typename A>
291 unsigned int HeaderAndLoadCommandsAtom<A>::nonHiddenSectionCount() const
292 {
293 unsigned int count = 0;
294 for (std::vector<ld::Internal::FinalSection*>::iterator it = _state.sections.begin(); it != _state.sections.end(); ++it) {
295 if ( ! (*it)->isSectionHidden() && ((*it)->type() != ld::Section::typeTentativeDefs) )
296 ++count;
297 }
298 return count;
299 }
300
301 template <typename A>
302 unsigned int HeaderAndLoadCommandsAtom<A>::segmentCount() const
303 {
304 if ( _options.outputKind() == Options::kObjectFile ) {
305 // .o files have one anonymous segment that contains all sections
306 return 1;
307 }
308
309 unsigned int count = 0;
310 const char* lastSegName = "";
311 for (std::vector<ld::Internal::FinalSection*>::iterator it = _state.sections.begin(); it != _state.sections.end(); ++it) {
312 if ( _options.outputKind() == Options::kPreload ) {
313 if ( (*it)->type() == ld::Section::typeMachHeader )
314 continue; // for -preload, don't put hidden __HEADER segment into output
315 if ( (*it)->type() == ld::Section::typeLinkEdit )
316 continue; // for -preload, don't put hidden __LINKEDIT segment into output
317 }
318 if ( strcmp(lastSegName, (*it)->segmentName()) != 0 ) {
319 lastSegName = (*it)->segmentName();
320 ++count;
321 }
322 }
323 return count;
324 }
325
326
327 template <typename A>
328 uint64_t HeaderAndLoadCommandsAtom<A>::size() const
329 {
330 uint32_t sz = sizeof(macho_header<P>);
331
332 sz += sizeof(macho_segment_command<P>) * this->segmentCount();
333 sz += sizeof(macho_section<P>) * this->nonHiddenSectionCount();
334
335 if ( _hasDylibIDLoadCommand )
336 sz += alignedSize(sizeof(macho_dylib_command<P>) + strlen(_options.installPath()) + 1);
337
338 if ( _hasDyldInfoLoadCommand )
339 sz += sizeof(macho_dyld_info_command<P>);
340
341 if ( _hasSymbolTableLoadCommand )
342 sz += sizeof(macho_symtab_command<P>);
343
344 if ( _hasDynamicSymbolTableLoadCommand )
345 sz += sizeof(macho_dysymtab_command<P>);
346
347 if ( _hasDyldLoadCommand )
348 sz += alignedSize(sizeof(macho_dylinker_command<P>) + strlen(_options.dyldInstallPath()) + 1);
349
350 if ( _hasRoutinesLoadCommand )
351 sz += sizeof(macho_routines_command<P>);
352
353 if ( _hasUUIDLoadCommand )
354 sz += sizeof(macho_uuid_command<P>);
355
356 if ( _hasVersionLoadCommand )
357 sz += sizeof(macho_version_min_command<P>);
358
359 if ( _hasSourceVersionLoadCommand )
360 sz += sizeof(macho_source_version_command<P>);
361
362 if ( _hasThreadLoadCommand )
363 sz += this->threadLoadCommandSize();
364
365 if ( _hasEntryPointLoadCommand )
366 sz += sizeof(macho_entry_point_command<P>);
367
368 if ( _hasEncryptionLoadCommand )
369 sz += sizeof(macho_encryption_info_command<P>);
370
371 if ( _hasSplitSegInfoLoadCommand )
372 sz += sizeof(macho_linkedit_data_command<P>);
373
374 for(uint32_t ord=1; ord <= _writer.dylibCount(); ++ord) {
375 sz += alignedSize(sizeof(macho_dylib_command<P>) + strlen(_writer.dylibByOrdinal(ord)->installPath()) + 1);
376 }
377
378 if ( _hasRPathLoadCommands ) {
379 const std::vector<const char*>& rpaths = _options.rpaths();
380 for (std::vector<const char*>::const_iterator it = rpaths.begin(); it != rpaths.end(); ++it) {
381 sz += alignedSize(sizeof(macho_rpath_command<P>) + strlen(*it) + 1);
382 }
383 }
384
385 if ( _hasSubFrameworkLoadCommand )
386 sz += alignedSize(sizeof(macho_sub_framework_command<P>) + strlen(_options.umbrellaName()) + 1);
387
388 for (std::vector<const char*>::const_iterator it = _subLibraryNames.begin(); it != _subLibraryNames.end(); ++it) {
389 sz += alignedSize(sizeof(macho_sub_library_command<P>) + strlen(*it) + 1);
390 }
391
392 for (std::vector<const char*>::const_iterator it = _subUmbrellaNames.begin(); it != _subUmbrellaNames.end(); ++it) {
393 sz += alignedSize(sizeof(macho_sub_umbrella_command<P>) + strlen(*it) + 1);
394 }
395
396 if ( _allowableClientLoadCommmandsCount != 0 ) {
397 const std::vector<const char*>& clients = _options.allowableClients();
398 for (std::vector<const char*>::const_iterator it = clients.begin(); it != clients.end(); ++it) {
399 sz += alignedSize(sizeof(macho_sub_client_command<P>) + strlen(*it) + 1);
400 }
401 }
402
403 if ( _dyldEnvironExrasCount != 0 ) {
404 const std::vector<const char*>& extras = _options.dyldEnvironExtras();
405 for (std::vector<const char*>::const_iterator it = extras.begin(); it != extras.end(); ++it) {
406 sz += alignedSize(sizeof(macho_dylinker_command<P>) + strlen(*it) + 1);
407 }
408 }
409
410 if ( _hasFunctionStartsLoadCommand )
411 sz += sizeof(macho_linkedit_data_command<P>);
412
413 if ( _hasDataInCodeLoadCommand )
414 sz += sizeof(macho_linkedit_data_command<P>);
415
416 if ( !_linkerOptions.empty() ) {
417 for (ld::relocatable::File::LinkerOptionsList::const_iterator it = _linkerOptions.begin(); it != _linkerOptions.end(); ++it) {
418 uint32_t s = sizeof(macho_linker_option_command<P>);
419 const std::vector<const char*>& options = *it;
420 for (std::vector<const char*>::const_iterator t=options.begin(); t != options.end(); ++t) {
421 s += (strlen(*t) + 1);
422 }
423 sz += alignedSize(s);
424 }
425 }
426
427 if ( _hasDependentDRInfo )
428 sz += sizeof(macho_linkedit_data_command<P>);
429
430 return sz;
431 }
432
433 template <typename A>
434 uint32_t HeaderAndLoadCommandsAtom<A>::commandsCount() const
435 {
436 uint32_t count = this->segmentCount();
437
438 if ( _hasDylibIDLoadCommand )
439 ++count;
440
441 if ( _hasDyldInfoLoadCommand )
442 ++count;
443
444 if ( _hasSymbolTableLoadCommand )
445 ++count;
446
447 if ( _hasDynamicSymbolTableLoadCommand )
448 ++count;
449
450 if ( _hasDyldLoadCommand )
451 ++count;
452
453 if ( _hasRoutinesLoadCommand )
454 ++count;
455
456 if ( _hasUUIDLoadCommand )
457 ++count;
458
459 if ( _hasVersionLoadCommand )
460 ++count;
461
462 if ( _hasSourceVersionLoadCommand )
463 ++count;
464
465 if ( _hasThreadLoadCommand )
466 ++count;
467
468 if ( _hasEntryPointLoadCommand )
469 ++count;
470
471 if ( _hasEncryptionLoadCommand )
472 ++count;
473
474 if ( _hasSplitSegInfoLoadCommand )
475 ++count;
476
477 count += _dylibLoadCommmandsCount;
478
479 count += _options.rpaths().size();
480
481 if ( _hasSubFrameworkLoadCommand )
482 ++count;
483
484 count += _subLibraryNames.size();
485
486 count += _subUmbrellaNames.size();
487
488 count += _allowableClientLoadCommmandsCount;
489
490 count += _dyldEnvironExrasCount;
491
492 if ( _hasFunctionStartsLoadCommand )
493 ++count;
494
495 if ( _hasDataInCodeLoadCommand )
496 ++count;
497
498 if ( !_linkerOptions.empty() ) {
499 for (ld::relocatable::File::LinkerOptionsList::const_iterator it = _linkerOptions.begin(); it != _linkerOptions.end(); ++it) {
500 ++count;
501 }
502 }
503
504 if ( _hasDependentDRInfo )
505 ++count;
506
507 return count;
508 }
509
510 template <typename A>
511 uint32_t HeaderAndLoadCommandsAtom<A>::fileType() const
512 {
513 switch ( _options.outputKind() ) {
514 case Options::kDynamicExecutable:
515 case Options::kStaticExecutable:
516 return MH_EXECUTE;
517 case Options::kDynamicLibrary:
518 return MH_DYLIB;
519 case Options::kDynamicBundle:
520 return MH_BUNDLE;
521 case Options::kObjectFile:
522 return MH_OBJECT;
523 case Options::kDyld:
524 return MH_DYLINKER;
525 case Options::kPreload:
526 return MH_PRELOAD;
527 case Options::kKextBundle:
528 return MH_KEXT_BUNDLE;
529 }
530 throw "unknonwn mach-o file type";
531 }
532
533 template <typename A>
534 uint32_t HeaderAndLoadCommandsAtom<A>::flags() const
535 {
536 uint32_t bits = 0;
537 if ( _options.outputKind() == Options::kObjectFile ) {
538 if ( _state.allObjectFilesScatterable )
539 bits = MH_SUBSECTIONS_VIA_SYMBOLS;
540 }
541 else {
542 if ( _options.outputKind() == Options::kStaticExecutable ) {
543 bits |= MH_NOUNDEFS;
544 if ( _options.positionIndependentExecutable() )
545 bits |= MH_PIE;
546 }
547 else if ( _options.outputKind() == Options::kPreload ) {
548 bits |= MH_NOUNDEFS;
549 if ( _options.positionIndependentExecutable() )
550 bits |= MH_PIE;
551 }
552 else {
553 bits = MH_DYLDLINK;
554 switch ( _options.nameSpace() ) {
555 case Options::kTwoLevelNameSpace:
556 bits |= MH_TWOLEVEL | MH_NOUNDEFS;
557 break;
558 case Options::kFlatNameSpace:
559 break;
560 case Options::kForceFlatNameSpace:
561 bits |= MH_FORCE_FLAT;
562 break;
563 }
564 if ( _writer.hasWeakExternalSymbols || _writer.overridesWeakExternalSymbols )
565 bits |= MH_WEAK_DEFINES;
566 if ( _writer.usesWeakExternalSymbols || _writer.hasWeakExternalSymbols )
567 bits |= MH_BINDS_TO_WEAK;
568 if ( _options.prebind() )
569 bits |= MH_PREBOUND;
570 if ( _options.splitSeg() )
571 bits |= MH_SPLIT_SEGS;
572 if ( (_options.outputKind() == Options::kDynamicLibrary)
573 && _writer._noReExportedDylibs
574 && _options.useSimplifiedDylibReExports() ) {
575 bits |= MH_NO_REEXPORTED_DYLIBS;
576 }
577 if ( _options.positionIndependentExecutable() && ! _writer.pieDisabled )
578 bits |= MH_PIE;
579 if ( _options.markAutoDeadStripDylib() )
580 bits |= MH_DEAD_STRIPPABLE_DYLIB;
581 if ( _writer.hasThreadLocalVariableDefinitions )
582 bits |= MH_HAS_TLV_DESCRIPTORS;
583 if ( _options.hasNonExecutableHeap() )
584 bits |= MH_NO_HEAP_EXECUTION;
585 }
586 if ( _options.hasExecutableStack() )
587 bits |= MH_ALLOW_STACK_EXECUTION;
588 }
589 return bits;
590 }
591
592 template <> uint32_t HeaderAndLoadCommandsAtom<x86>::magic() const { return MH_MAGIC; }
593 template <> uint32_t HeaderAndLoadCommandsAtom<x86_64>::magic() const { return MH_MAGIC_64; }
594 template <> uint32_t HeaderAndLoadCommandsAtom<arm>::magic() const { return MH_MAGIC; }
595 template <> uint32_t HeaderAndLoadCommandsAtom<arm64>::magic() const { return MH_MAGIC_64; }
596
597 template <> uint32_t HeaderAndLoadCommandsAtom<x86>::cpuType() const { return CPU_TYPE_I386; }
598 template <> uint32_t HeaderAndLoadCommandsAtom<x86_64>::cpuType() const { return CPU_TYPE_X86_64; }
599 template <> uint32_t HeaderAndLoadCommandsAtom<arm>::cpuType() const { return CPU_TYPE_ARM; }
600 template <> uint32_t HeaderAndLoadCommandsAtom<arm64>::cpuType() const { return CPU_TYPE_ARM64; }
601
602
603
604 template <>
605 uint32_t HeaderAndLoadCommandsAtom<x86>::cpuSubType() const
606 {
607 return CPU_SUBTYPE_I386_ALL;
608 }
609
610 template <>
611 uint32_t HeaderAndLoadCommandsAtom<x86_64>::cpuSubType() const
612 {
613 if ( (_options.outputKind() == Options::kDynamicExecutable) && (_options.macosxVersionMin() >= ld::mac10_5) )
614 return (CPU_SUBTYPE_X86_64_ALL | 0x80000000);
615 else
616 return CPU_SUBTYPE_X86_64_ALL;
617 }
618
619 template <>
620 uint32_t HeaderAndLoadCommandsAtom<arm>::cpuSubType() const
621 {
622 return _state.cpuSubType;
623 }
624
625 template <>
626 uint32_t HeaderAndLoadCommandsAtom<arm64>::cpuSubType() const
627 {
628 return CPU_SUBTYPE_ARM64_ALL;
629 }
630
631
632
633 template <typename A>
634 uint8_t* HeaderAndLoadCommandsAtom<A>::copySingleSegmentLoadCommand(uint8_t* p) const
635 {
636 // in .o files there is just one segment load command with a blank name
637 // and all sections under it
638 macho_segment_command<P>* cmd = (macho_segment_command<P>*)p;
639 cmd->set_cmd(macho_segment_command<P>::CMD);
640 cmd->set_segname("");
641 cmd->set_vmaddr(_options.baseAddress());
642 cmd->set_vmsize(0); // updated after sections set
643 cmd->set_fileoff(0); // updated after sections set
644 cmd->set_filesize(0); // updated after sections set
645 cmd->set_maxprot(VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE);
646 cmd->set_initprot(VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE);
647 cmd->set_nsects(this->nonHiddenSectionCount());
648 cmd->set_flags(0);
649 // add sections array
650 macho_section<P>* msect = (macho_section<P>*)&p[sizeof(macho_segment_command<P>)];
651 for (std::vector<ld::Internal::FinalSection*>::iterator sit = _state.sections.begin(); sit != _state.sections.end(); ++sit) {
652 ld::Internal::FinalSection* fsect = *sit;
653 if ( fsect->isSectionHidden() )
654 continue;
655 if ( fsect->type() == ld::Section::typeTentativeDefs )
656 continue;
657 msect->set_sectname(fsect->sectionName());
658 msect->set_segname(fsect->segmentName());
659 msect->set_addr(fsect->address);
660 msect->set_size(fsect->size);
661 msect->set_offset(fsect->fileOffset);
662 msect->set_align(fsect->alignment);
663 msect->set_reloff((fsect->relocCount == 0) ? 0 : _writer.sectionRelocationsSection->fileOffset + fsect->relocStart * sizeof(macho_relocation_info<P>));
664 msect->set_nreloc(fsect->relocCount);
665 msect->set_flags(sectionFlags(fsect));
666 msect->set_reserved1(fsect->indirectSymTabStartIndex);
667 msect->set_reserved2(fsect->indirectSymTabElementSize);
668 // update segment info
669 if ( cmd->fileoff() == 0 )
670 cmd->set_fileoff(fsect->fileOffset);
671 cmd->set_vmsize(fsect->address + fsect->size - cmd->vmaddr());
672 if ( (fsect->type() != ld::Section::typeZeroFill) && (fsect->type() != ld::Section::typeTentativeDefs) )
673 cmd->set_filesize(fsect->fileOffset + fsect->size - cmd->fileoff());
674 ++msect;
675 }
676 cmd->set_cmdsize(sizeof(macho_segment_command<P>) + cmd->nsects()*sizeof(macho_section<P>));
677 return p + cmd->cmdsize();
678 }
679
680 struct SegInfo {
681 SegInfo(const char* n, const Options&);
682 const char* segName;
683 uint32_t nonHiddenSectionCount;
684 uint32_t maxProt;
685 uint32_t initProt;
686 std::vector<ld::Internal::FinalSection*> sections;
687 };
688
689
690 SegInfo::SegInfo(const char* n, const Options& opts)
691 : segName(n), nonHiddenSectionCount(0), maxProt(opts.maxSegProtection(n)), initProt(opts.initialSegProtection(n))
692 {
693 }
694
695
696 template <typename A>
697 uint32_t HeaderAndLoadCommandsAtom<A>::sectionFlags(ld::Internal::FinalSection* sect) const
698 {
699 uint32_t bits;
700 switch ( sect->type() ) {
701 case ld::Section::typeUnclassified:
702 if ( strcmp(sect->segmentName(), "__OBJC") == 0 )
703 return S_REGULAR | S_ATTR_NO_DEAD_STRIP;
704 else if ( (strcmp(sect->sectionName(), "__objc_classlist") == 0) && (strcmp(sect->segmentName(), "__DATA") == 0) )
705 return S_REGULAR | S_ATTR_NO_DEAD_STRIP;
706 else if ( (strcmp(sect->sectionName(), "__objc_catlist") == 0) && (strcmp(sect->segmentName(), "__DATA") == 0) )
707 return S_REGULAR | S_ATTR_NO_DEAD_STRIP;
708 else if ( (strncmp(sect->sectionName(), "__objc_superrefs", 16) == 0) && (strcmp(sect->segmentName(), "__DATA") == 0) )
709 return S_REGULAR | S_ATTR_NO_DEAD_STRIP;
710 else if ( (strncmp(sect->sectionName(), "__objc_nlclslist", 16) == 0) && (strcmp(sect->segmentName(), "__DATA") == 0) )
711 return S_REGULAR | S_ATTR_NO_DEAD_STRIP;
712 else if ( (strncmp(sect->sectionName(), "__objc_nlcatlist", 16) == 0) && (strcmp(sect->segmentName(), "__DATA") == 0) )
713 return S_REGULAR | S_ATTR_NO_DEAD_STRIP;
714 else
715 return S_REGULAR;
716 case ld::Section::typeCode:
717 bits = S_REGULAR | S_ATTR_SOME_INSTRUCTIONS | S_ATTR_PURE_INSTRUCTIONS;
718 if ( sect->hasLocalRelocs && ! _writer.pieDisabled )
719 bits |= S_ATTR_LOC_RELOC;
720 if ( sect->hasExternalRelocs )
721 bits |= S_ATTR_EXT_RELOC;
722 return bits;
723 case ld::Section::typePageZero:
724 return S_REGULAR;
725 case ld::Section::typeImportProxies:
726 return S_REGULAR;
727 case ld::Section::typeLinkEdit:
728 return S_REGULAR;
729 case ld::Section::typeMachHeader:
730 return S_REGULAR;
731 case ld::Section::typeStack:
732 return S_REGULAR;
733 case ld::Section::typeLiteral4:
734 return S_4BYTE_LITERALS;
735 case ld::Section::typeLiteral8:
736 return S_8BYTE_LITERALS;
737 case ld::Section::typeLiteral16:
738 return S_16BYTE_LITERALS;
739 case ld::Section::typeConstants:
740 return S_REGULAR;
741 case ld::Section::typeTempLTO:
742 assert(0 && "typeTempLTO should not make it to final linked image");
743 return S_REGULAR;
744 case ld::Section::typeAbsoluteSymbols:
745 assert(0 && "typeAbsoluteSymbols should not make it to final linked image");
746 return S_REGULAR;
747 case ld::Section::typeCString:
748 case ld::Section::typeNonStdCString:
749 return S_CSTRING_LITERALS;
750 case ld::Section::typeCStringPointer:
751 return S_LITERAL_POINTERS | S_ATTR_NO_DEAD_STRIP;
752 case ld::Section::typeUTF16Strings:
753 return S_REGULAR;
754 case ld::Section::typeCFString:
755 return S_REGULAR;
756 case ld::Section::typeObjC1Classes:
757 return S_REGULAR | S_ATTR_NO_DEAD_STRIP;
758 case ld::Section::typeCFI:
759 return S_REGULAR;
760 case ld::Section::typeLSDA:
761 return S_REGULAR;
762 case ld::Section::typeDtraceDOF:
763 return S_DTRACE_DOF;
764 case ld::Section::typeUnwindInfo:
765 return S_REGULAR;
766 case ld::Section::typeObjCClassRefs:
767 case ld::Section::typeObjC2CategoryList:
768 return S_REGULAR | S_ATTR_NO_DEAD_STRIP;
769 case ld::Section::typeZeroFill:
770 if ( _options.optimizeZeroFill() )
771 return S_ZEROFILL;
772 else
773 return S_REGULAR;
774 case ld::Section::typeTentativeDefs:
775 assert(0 && "typeTentativeDefs should not make it to final linked image");
776 return S_REGULAR;
777 case ld::Section::typeLazyPointer:
778 case ld::Section::typeLazyPointerClose:
779 return S_LAZY_SYMBOL_POINTERS;
780 case ld::Section::typeStubClose:
781 case ld::Section::typeStub:
782 if ( sect->hasLocalRelocs )
783 return S_SYMBOL_STUBS | S_ATTR_SOME_INSTRUCTIONS | S_ATTR_PURE_INSTRUCTIONS | S_ATTR_LOC_RELOC;
784 else
785 return S_SYMBOL_STUBS | S_ATTR_SOME_INSTRUCTIONS | S_ATTR_PURE_INSTRUCTIONS;
786 case ld::Section::typeNonLazyPointer:
787 if ( _options.outputKind() == Options::kKextBundle )
788 return S_REGULAR;
789 else if ( (_options.outputKind() == Options::kStaticExecutable) && _options.positionIndependentExecutable() )
790 return S_REGULAR;
791 else
792 return S_NON_LAZY_SYMBOL_POINTERS;
793 case ld::Section::typeDyldInfo:
794 return S_REGULAR;
795 case ld::Section::typeLazyDylibPointer:
796 return S_LAZY_DYLIB_SYMBOL_POINTERS;
797 case ld::Section::typeStubHelper:
798 if ( sect->hasLocalRelocs )
799 return S_REGULAR | S_ATTR_SOME_INSTRUCTIONS | S_ATTR_PURE_INSTRUCTIONS | S_ATTR_LOC_RELOC;
800 else
801 return S_REGULAR | S_ATTR_SOME_INSTRUCTIONS | S_ATTR_PURE_INSTRUCTIONS;
802 case ld::Section::typeInitializerPointers:
803 // <rdar://problem/11456679> i386 kexts need different section type
804 if ( (_options.outputKind() == Options::kObjectFile)
805 && (strcmp(sect->sectionName(), "__constructor") == 0)
806 && (strcmp(sect->segmentName(), "__TEXT") == 0) )
807 return S_REGULAR;
808 else
809 return S_MOD_INIT_FUNC_POINTERS;
810 case ld::Section::typeTerminatorPointers:
811 return S_MOD_TERM_FUNC_POINTERS;
812 case ld::Section::typeTLVInitialValues:
813 return S_THREAD_LOCAL_REGULAR;
814 case ld::Section::typeTLVZeroFill:
815 return S_THREAD_LOCAL_ZEROFILL;
816 case ld::Section::typeTLVDefs:
817 return S_THREAD_LOCAL_VARIABLES;
818 case ld::Section::typeTLVInitializerPointers:
819 return S_THREAD_LOCAL_INIT_FUNCTION_POINTERS;
820 case ld::Section::typeTLVPointers:
821 return S_THREAD_LOCAL_VARIABLE_POINTERS;
822 case ld::Section::typeFirstSection:
823 assert(0 && "typeFirstSection should not make it to final linked image");
824 return S_REGULAR;
825 case ld::Section::typeLastSection:
826 assert(0 && "typeLastSection should not make it to final linked image");
827 return S_REGULAR;
828 case ld::Section::typeDebug:
829 return S_REGULAR | S_ATTR_DEBUG;
830 }
831 return S_REGULAR;
832 }
833
834
835 template <typename A>
836 bool HeaderAndLoadCommandsAtom<A>::sectionTakesNoDiskSpace(ld::Internal::FinalSection* sect) const
837 {
838 switch ( sect->type() ) {
839 case ld::Section::typeZeroFill:
840 case ld::Section::typeTLVZeroFill:
841 return _options.optimizeZeroFill();
842 case ld::Section::typeAbsoluteSymbols:
843 case ld::Section::typeTentativeDefs:
844 case ld::Section::typeLastSection:
845 return true;
846 default:
847 break;
848 }
849 return false;
850 }
851
852
853 template <typename A>
854 uint8_t* HeaderAndLoadCommandsAtom<A>::copySegmentLoadCommands(uint8_t* p) const
855 {
856 // group sections into segments
857 std::vector<SegInfo> segs;
858 const char* lastSegName = "";
859 for (std::vector<ld::Internal::FinalSection*>::iterator it = _state.sections.begin(); it != _state.sections.end(); ++it) {
860 ld::Internal::FinalSection* sect = *it;
861 if ( _options.outputKind() == Options::kPreload ) {
862 if ( (*it)->type() == ld::Section::typeMachHeader )
863 continue; // for -preload, don't put hidden __HEADER segment into output
864 if ( (*it)->type() == ld::Section::typeLinkEdit )
865 continue; // for -preload, don't put hidden __LINKEDIT segment into output
866 }
867 if ( strcmp(lastSegName, sect->segmentName()) != 0 ) {
868 SegInfo si(sect->segmentName(), _options);
869 segs.push_back(si);
870 lastSegName = sect->segmentName();
871 }
872 if ( ! sect->isSectionHidden() )
873 segs.back().nonHiddenSectionCount++;
874 segs.back().sections.push_back(sect);
875 }
876 // write out segment load commands for each section with trailing sections
877 for (std::vector<SegInfo>::iterator it = segs.begin(); it != segs.end(); ++it) {
878 SegInfo& si = *it;
879 ld::Internal::FinalSection* lastNonZeroFillSection = NULL;
880 for (int i=si.sections.size()-1; i >= 0; --i) {
881 if ( !sectionTakesNoDiskSpace(si.sections[i]) ) {
882 lastNonZeroFillSection = si.sections[i];
883 break;
884 }
885 }
886 uint64_t vmsize = si.sections.back()->address + si.sections.back()->size - si.sections.front()->address;
887 vmsize = ((vmsize+_options.segmentAlignment()-1) & (-_options.segmentAlignment()));
888 uint64_t filesize = 0;
889 if ( lastNonZeroFillSection != NULL ) {
890 filesize = lastNonZeroFillSection->address + lastNonZeroFillSection->size - si.sections.front()->address;
891 // round up all segments to page aligned, except __LINKEDIT
892 if ( (si.sections[0]->type() != ld::Section::typeLinkEdit) && (si.sections[0]->type() != ld::Section::typeImportProxies) )
893 filesize = (filesize + _options.segmentAlignment()-1) & (-_options.segmentAlignment());
894 }
895 if ( si.sections.front()->type() == ld::Section::typePageZero )
896 filesize = 0;
897 else if ( si.sections.front()->type() == ld::Section::typeStack )
898 filesize = 0;
899 macho_segment_command<P>* segCmd = (macho_segment_command<P>*)p;
900 segCmd->set_cmd(macho_segment_command<P>::CMD);
901 segCmd->set_cmdsize(sizeof(macho_segment_command<P>) + si.nonHiddenSectionCount*sizeof(macho_section<P>));
902 segCmd->set_segname(si.sections.front()->segmentName());
903 segCmd->set_vmaddr(si.sections.front()->address);
904 segCmd->set_vmsize(vmsize);
905 segCmd->set_fileoff(si.sections.front()->fileOffset);
906 segCmd->set_filesize(filesize);
907 segCmd->set_maxprot(si.maxProt);
908 segCmd->set_initprot(si.initProt);
909 segCmd->set_nsects(si.nonHiddenSectionCount);
910 segCmd->set_flags(0);
911 p += sizeof(macho_segment_command<P>);
912 macho_section<P>* msect = (macho_section<P>*)p;
913 for (std::vector<ld::Internal::FinalSection*>::iterator sit = si.sections.begin(); sit != si.sections.end(); ++sit) {
914 ld::Internal::FinalSection* fsect = *sit;
915 if ( ! fsect->isSectionHidden() ) {
916 msect->set_sectname(fsect->sectionName());
917 msect->set_segname(fsect->segmentName());
918 msect->set_addr(fsect->address);
919 msect->set_size(fsect->size);
920 msect->set_offset(sectionTakesNoDiskSpace(fsect) ? 0 : fsect->fileOffset);
921 msect->set_align(fsect->alignment);
922 msect->set_reloff(0);
923 msect->set_nreloc(0);
924 msect->set_flags(sectionFlags(fsect));
925 msect->set_reserved1(fsect->indirectSymTabStartIndex);
926 msect->set_reserved2(fsect->indirectSymTabElementSize);
927 p += sizeof(macho_section<P>);
928 ++msect;
929 }
930 }
931 }
932
933 return p;
934 }
935
936
937 template <typename A>
938 uint8_t* HeaderAndLoadCommandsAtom<A>::copySymbolTableLoadCommand(uint8_t* p) const
939 {
940 // build LC_SYMTAB command
941 macho_symtab_command<P>* symbolTableCmd = (macho_symtab_command<P>*)p;
942 symbolTableCmd->set_cmd(LC_SYMTAB);
943 symbolTableCmd->set_cmdsize(sizeof(macho_symtab_command<P>));
944 symbolTableCmd->set_nsyms(_writer.symbolTableSection->size/sizeof(macho_nlist<P>));
945 symbolTableCmd->set_symoff(_writer.symbolTableSection->size == 0 ? 0 : _writer.symbolTableSection->fileOffset);
946 symbolTableCmd->set_stroff(_writer.stringPoolSection->size == 0 ? 0 : _writer.stringPoolSection->fileOffset );
947 symbolTableCmd->set_strsize(_writer.stringPoolSection->size);
948 return p + sizeof(macho_symtab_command<P>);
949 }
950
951 template <typename A>
952 uint8_t* HeaderAndLoadCommandsAtom<A>::copyDynamicSymbolTableLoadCommand(uint8_t* p) const
953 {
954 // build LC_SYMTAB command
955 macho_dysymtab_command<P>* dynamicSymbolTableCmd = (macho_dysymtab_command<P>*)p;
956 dynamicSymbolTableCmd->set_cmd(LC_DYSYMTAB);
957 dynamicSymbolTableCmd->set_cmdsize(sizeof(macho_dysymtab_command<P>));
958 dynamicSymbolTableCmd->set_ilocalsym(0);
959 dynamicSymbolTableCmd->set_nlocalsym(_writer._localSymbolsCount);
960 dynamicSymbolTableCmd->set_iextdefsym(dynamicSymbolTableCmd->ilocalsym()+dynamicSymbolTableCmd->nlocalsym());
961 dynamicSymbolTableCmd->set_nextdefsym(_writer._globalSymbolsCount);
962 dynamicSymbolTableCmd->set_iundefsym(dynamicSymbolTableCmd->iextdefsym()+dynamicSymbolTableCmd->nextdefsym());
963 dynamicSymbolTableCmd->set_nundefsym(_writer._importSymbolsCount);
964
965 // FIX ME: support for 10.3 dylibs which need modules
966 //if ( fWriter.fModuleInfoAtom != NULL ) {
967 // dynamicSymbolTableCmd->set_tocoff(fWriter.fModuleInfoAtom->getTableOfContentsFileOffset());
968 // dynamicSymbolTableCmd->set_ntoc(fWriter.fSymbolTableExportCount);
969 // dynamicSymbolTableCmd->set_modtaboff(fWriter.fModuleInfoAtom->getModuleTableFileOffset());
970 // dynamicSymbolTableCmd->set_nmodtab(1);
971 // dynamicSymbolTableCmd->set_extrefsymoff(fWriter.fModuleInfoAtom->getReferencesFileOffset());
972 // dynamicSymbolTableCmd->set_nextrefsyms(fWriter.fModuleInfoAtom->getReferencesCount());
973 //}
974
975 bool hasIndirectSymbols = ( (_writer.indirectSymbolTableSection != NULL) && (_writer.indirectSymbolTableSection->size != 0) );
976 dynamicSymbolTableCmd->set_indirectsymoff(hasIndirectSymbols ? _writer.indirectSymbolTableSection->fileOffset : 0);
977 dynamicSymbolTableCmd->set_nindirectsyms( hasIndirectSymbols ? _writer.indirectSymbolTableSection->size/sizeof(uint32_t) : 0);
978
979 // FIX ME: support for classic relocations
980 if ( _options.outputKind() != Options::kObjectFile ) {
981 bool hasExternalRelocs = ( (_writer.externalRelocationsSection != NULL) && (_writer.externalRelocationsSection->size != 0) );
982 dynamicSymbolTableCmd->set_extreloff(hasExternalRelocs ? _writer.externalRelocationsSection->fileOffset : 0);
983 dynamicSymbolTableCmd->set_nextrel( hasExternalRelocs ? _writer.externalRelocationsSection->size/8 : 0);
984 bool hasLocalRelocs = ( (_writer.localRelocationsSection != NULL) && (_writer.localRelocationsSection->size != 0) );
985 dynamicSymbolTableCmd->set_locreloff(hasLocalRelocs ? _writer.localRelocationsSection->fileOffset : 0);
986 dynamicSymbolTableCmd->set_nlocrel (hasLocalRelocs ? _writer.localRelocationsSection->size/8 : 0);
987 }
988 return p + sizeof(macho_dysymtab_command<P>);
989 }
990
991
992 template <typename A>
993 uint8_t* HeaderAndLoadCommandsAtom<A>::copyDyldInfoLoadCommand(uint8_t* p) const
994 {
995 // build LC_DYLD_INFO command
996 macho_dyld_info_command<P>* cmd = (macho_dyld_info_command<P>*)p;
997
998 cmd->set_cmd(LC_DYLD_INFO_ONLY);
999 cmd->set_cmdsize(sizeof(macho_dyld_info_command<P>));
1000 if ( _writer.rebaseSection->size != 0 ) {
1001 cmd->set_rebase_off(_writer.rebaseSection->fileOffset);
1002 cmd->set_rebase_size(_writer.rebaseSection->size);
1003 }
1004 if ( _writer.bindingSection->size != 0 ) {
1005 cmd->set_bind_off(_writer.bindingSection->fileOffset);
1006 cmd->set_bind_size(_writer.bindingSection->size);
1007 }
1008 if ( _writer.weakBindingSection->size != 0 ) {
1009 cmd->set_weak_bind_off(_writer.weakBindingSection->fileOffset);
1010 cmd->set_weak_bind_size(_writer.weakBindingSection->size);
1011 }
1012 if ( _writer.lazyBindingSection->size != 0 ) {
1013 cmd->set_lazy_bind_off(_writer.lazyBindingSection->fileOffset);
1014 cmd->set_lazy_bind_size(_writer.lazyBindingSection->size);
1015 }
1016 if ( _writer.exportSection->size != 0 ) {
1017 cmd->set_export_off(_writer.exportSection->fileOffset);
1018 cmd->set_export_size(_writer.exportSection->size);
1019 }
1020 return p + sizeof(macho_dyld_info_command<P>);
1021 }
1022
1023
1024 template <typename A>
1025 uint8_t* HeaderAndLoadCommandsAtom<A>::copyDyldLoadCommand(uint8_t* p) const
1026 {
1027 uint32_t sz = alignedSize(sizeof(macho_dylinker_command<P>) + strlen(_options.dyldInstallPath()) + 1);
1028 macho_dylinker_command<P>* cmd = (macho_dylinker_command<P>*)p;
1029 if ( _options.outputKind() == Options::kDyld )
1030 cmd->set_cmd(LC_ID_DYLINKER);
1031 else
1032 cmd->set_cmd(LC_LOAD_DYLINKER);
1033 cmd->set_cmdsize(sz);
1034 cmd->set_name_offset();
1035 strcpy((char*)&p[sizeof(macho_dylinker_command<P>)], _options.dyldInstallPath());
1036 return p + sz;
1037 }
1038
1039
1040 template <typename A>
1041 uint8_t* HeaderAndLoadCommandsAtom<A>::copyDylibIDLoadCommand(uint8_t* p) const
1042 {
1043 uint32_t sz = alignedSize(sizeof(macho_dylib_command<P>) + strlen(_options.installPath()) + 1);
1044 macho_dylib_command<P>* cmd = (macho_dylib_command<P>*)p;
1045 cmd->set_cmd(LC_ID_DYLIB);
1046 cmd->set_cmdsize(sz);
1047 cmd->set_name_offset();
1048 cmd->set_timestamp(1); // needs to be some constant value that is different than DylibLoadCommandsAtom uses
1049 cmd->set_current_version(_options.currentVersion32());
1050 cmd->set_compatibility_version(_options.compatibilityVersion());
1051 strcpy((char*)&p[sizeof(macho_dylib_command<P>)], _options.installPath());
1052 return p + sz;
1053 }
1054
1055 template <typename A>
1056 uint8_t* HeaderAndLoadCommandsAtom<A>::copyRoutinesLoadCommand(uint8_t* p) const
1057 {
1058 pint_t initAddr = _state.entryPoint->finalAddress();
1059 if ( _state.entryPoint->isThumb() )
1060 initAddr |= 1ULL;
1061 macho_routines_command<P>* cmd = (macho_routines_command<P>*)p;
1062 cmd->set_cmd(macho_routines_command<P>::CMD);
1063 cmd->set_cmdsize(sizeof(macho_routines_command<P>));
1064 cmd->set_init_address(initAddr);
1065 return p + sizeof(macho_routines_command<P>);
1066 }
1067
1068
1069 template <typename A>
1070 void HeaderAndLoadCommandsAtom<A>::recopyUUIDCommand()
1071 {
1072 assert(_uuidCmdInOutputBuffer != NULL);
1073 _uuidCmdInOutputBuffer->set_uuid(_uuid);
1074 }
1075
1076
1077 template <typename A>
1078 uint8_t* HeaderAndLoadCommandsAtom<A>::copyUUIDLoadCommand(uint8_t* p) const
1079 {
1080 macho_uuid_command<P>* cmd = (macho_uuid_command<P>*)p;
1081 cmd->set_cmd(LC_UUID);
1082 cmd->set_cmdsize(sizeof(macho_uuid_command<P>));
1083 cmd->set_uuid(_uuid);
1084 _uuidCmdInOutputBuffer = cmd; // save for later re-write by recopyUUIDCommand()
1085 return p + sizeof(macho_uuid_command<P>);
1086 }
1087
1088
1089 template <typename A>
1090 uint8_t* HeaderAndLoadCommandsAtom<A>::copyVersionLoadCommand(uint8_t* p) const
1091 {
1092 macho_version_min_command<P>* cmd = (macho_version_min_command<P>*)p;
1093 ld::MacVersionMin macVersion = _options.macosxVersionMin();
1094 ld::IOSVersionMin iOSVersion = _options.iOSVersionMin();
1095 assert( (macVersion != ld::macVersionUnset) || (iOSVersion != ld::iOSVersionUnset) );
1096 if ( macVersion != ld::macVersionUnset ) {
1097 cmd->set_cmd(LC_VERSION_MIN_MACOSX);
1098 cmd->set_cmdsize(sizeof(macho_version_min_command<P>));
1099 cmd->set_version((uint32_t)macVersion);
1100 cmd->set_sdk(_options.sdkVersion());
1101 }
1102 else {
1103 cmd->set_cmd(LC_VERSION_MIN_IPHONEOS);
1104 cmd->set_cmdsize(sizeof(macho_version_min_command<P>));
1105 cmd->set_version((uint32_t)iOSVersion);
1106 cmd->set_sdk(_options.sdkVersion());
1107 }
1108 return p + sizeof(macho_version_min_command<P>);
1109 }
1110
1111 template <typename A>
1112 uint8_t* HeaderAndLoadCommandsAtom<A>::copySourceVersionLoadCommand(uint8_t* p) const
1113 {
1114 macho_source_version_command<P>* cmd = (macho_source_version_command<P>*)p;
1115 cmd->set_cmd(LC_SOURCE_VERSION);
1116 cmd->set_cmdsize(sizeof(macho_source_version_command<P>));
1117 cmd->set_version(_options.sourceVersion());
1118 return p + sizeof(macho_source_version_command<P>);
1119 }
1120
1121
1122 template <>
1123 uint32_t HeaderAndLoadCommandsAtom<x86>::threadLoadCommandSize() const
1124 {
1125 return this->alignedSize(16 + 16*4); // base size + i386_THREAD_STATE_COUNT * 4
1126 }
1127
1128 template <>
1129 uint8_t* HeaderAndLoadCommandsAtom<x86>::copyThreadsLoadCommand(uint8_t* p) const
1130 {
1131 assert(_state.entryPoint != NULL);
1132 pint_t start = _state.entryPoint->finalAddress();
1133 macho_thread_command<P>* cmd = (macho_thread_command<P>*)p;
1134 cmd->set_cmd(LC_UNIXTHREAD);
1135 cmd->set_cmdsize(threadLoadCommandSize());
1136 cmd->set_flavor(1); // i386_THREAD_STATE
1137 cmd->set_count(16); // i386_THREAD_STATE_COUNT;
1138 cmd->set_thread_register(10, start);
1139 if ( _options.hasCustomStack() )
1140 cmd->set_thread_register(7, _options.customStackAddr()); // r1
1141 return p + threadLoadCommandSize();
1142 }
1143
1144 template <>
1145 uint32_t HeaderAndLoadCommandsAtom<x86_64>::threadLoadCommandSize() const
1146 {
1147 return this->alignedSize(16 + x86_THREAD_STATE64_COUNT * 4);
1148 }
1149
1150 template <>
1151 uint8_t* HeaderAndLoadCommandsAtom<x86_64>::copyThreadsLoadCommand(uint8_t* p) const
1152 {
1153 assert(_state.entryPoint != NULL);
1154 pint_t start = _state.entryPoint->finalAddress();
1155 macho_thread_command<P>* cmd = (macho_thread_command<P>*)p;
1156 cmd->set_cmd(LC_UNIXTHREAD);
1157 cmd->set_cmdsize(threadLoadCommandSize());
1158 cmd->set_flavor(x86_THREAD_STATE64);
1159 cmd->set_count(x86_THREAD_STATE64_COUNT);
1160 cmd->set_thread_register(16, start); // rip
1161 if ( _options.hasCustomStack() )
1162 cmd->set_thread_register(7, _options.customStackAddr()); // r1
1163 return p + threadLoadCommandSize();
1164 }
1165
1166 template <>
1167 uint32_t HeaderAndLoadCommandsAtom<arm>::threadLoadCommandSize() const
1168 {
1169 return this->alignedSize(16 + 17 * 4); // base size + ARM_THREAD_STATE_COUNT * 4
1170 }
1171
1172 template <>
1173 uint8_t* HeaderAndLoadCommandsAtom<arm>::copyThreadsLoadCommand(uint8_t* p) const
1174 {
1175 assert(_state.entryPoint != NULL);
1176 pint_t start = _state.entryPoint->finalAddress();
1177 if ( _state.entryPoint->isThumb() )
1178 start |= 1ULL;
1179 macho_thread_command<P>* cmd = (macho_thread_command<P>*)p;
1180 cmd->set_cmd(LC_UNIXTHREAD);
1181 cmd->set_cmdsize(threadLoadCommandSize());
1182 cmd->set_flavor(1);
1183 cmd->set_count(17);
1184 cmd->set_thread_register(15, start); // pc
1185 if ( _options.hasCustomStack() )
1186 cmd->set_thread_register(13, _options.customStackAddr()); // sp
1187 return p + threadLoadCommandSize();
1188 }
1189
1190
1191 template <>
1192 uint32_t HeaderAndLoadCommandsAtom<arm64>::threadLoadCommandSize() const
1193 {
1194 return this->alignedSize(16 + 34 * 8); // base size + ARM_EXCEPTION_STATE64_COUNT * 4
1195 }
1196
1197 template <>
1198 uint8_t* HeaderAndLoadCommandsAtom<arm64>::copyThreadsLoadCommand(uint8_t* p) const
1199 {
1200 assert(_state.entryPoint != NULL);
1201 pint_t start = _state.entryPoint->finalAddress();
1202 macho_thread_command<P>* cmd = (macho_thread_command<P>*)p;
1203 cmd->set_cmd(LC_UNIXTHREAD);
1204 cmd->set_cmdsize(threadLoadCommandSize());
1205 cmd->set_flavor(6); // ARM_THREAD_STATE64
1206 cmd->set_count(68); // ARM_EXCEPTION_STATE64_COUNT
1207 cmd->set_thread_register(32, start); // pc
1208 if ( _options.hasCustomStack() )
1209 cmd->set_thread_register(31, _options.customStackAddr()); // sp
1210 return p + threadLoadCommandSize();
1211 }
1212
1213
1214 template <typename A>
1215 uint8_t* HeaderAndLoadCommandsAtom<A>::copyEntryPointLoadCommand(uint8_t* p) const
1216 {
1217 macho_entry_point_command<P>* cmd = (macho_entry_point_command<P>*)p;
1218 cmd->set_cmd(LC_MAIN);
1219 cmd->set_cmdsize(sizeof(macho_entry_point_command<P>));
1220 assert(_state.entryPoint != NULL);
1221 pint_t start = _state.entryPoint->finalAddress();
1222 if ( _state.entryPoint->isThumb() )
1223 start |= 1ULL;
1224 cmd->set_entryoff(start - this->finalAddress());
1225 cmd->set_stacksize(_options.hasCustomStack() ? _options.customStackSize() : 0 );
1226 return p + sizeof(macho_entry_point_command<P>);
1227 }
1228
1229
1230 template <typename A>
1231 uint8_t* HeaderAndLoadCommandsAtom<A>::copyEncryptionLoadCommand(uint8_t* p) const
1232 {
1233 macho_encryption_info_command<P>* cmd = (macho_encryption_info_command<P>*)p;
1234 cmd->set_cmd(sizeof(typename A::P::uint_t) == 4 ? LC_ENCRYPTION_INFO : LC_ENCRYPTION_INFO_64);
1235 cmd->set_cmdsize(sizeof(macho_encryption_info_command<P>));
1236 assert(_writer.encryptedTextStartOffset() != 0);
1237 assert(_writer.encryptedTextEndOffset() != 0);
1238 cmd->set_cryptoff(_writer.encryptedTextStartOffset());
1239 cmd->set_cryptsize(_writer.encryptedTextEndOffset()-_writer.encryptedTextStartOffset());
1240 cmd->set_cryptid(0);
1241 return p + sizeof(macho_encryption_info_command<P>);
1242 }
1243
1244
1245 template <typename A>
1246 uint8_t* HeaderAndLoadCommandsAtom<A>::copySplitSegInfoLoadCommand(uint8_t* p) const
1247 {
1248 macho_linkedit_data_command<P>* cmd = (macho_linkedit_data_command<P>*)p;
1249 cmd->set_cmd(LC_SEGMENT_SPLIT_INFO);
1250 cmd->set_cmdsize(sizeof(macho_linkedit_data_command<P>));
1251 cmd->set_dataoff(_writer.splitSegInfoSection->fileOffset);
1252 cmd->set_datasize(_writer.splitSegInfoSection->size);
1253 return p + sizeof(macho_linkedit_data_command<P>);
1254 }
1255
1256
1257 template <typename A>
1258 uint8_t* HeaderAndLoadCommandsAtom<A>::copyDylibLoadCommand(uint8_t* p, const ld::dylib::File* dylib) const
1259 {
1260 uint32_t sz = alignedSize(sizeof(macho_dylib_command<P>) + strlen(dylib->installPath()) + 1);
1261 macho_dylib_command<P>* cmd = (macho_dylib_command<P>*)p;
1262 if ( dylib->willBeLazyLoadedDylib() )
1263 cmd->set_cmd(LC_LAZY_LOAD_DYLIB);
1264 else if ( dylib->forcedWeakLinked() || dylib->allSymbolsAreWeakImported() )
1265 cmd->set_cmd(LC_LOAD_WEAK_DYLIB);
1266 else if ( dylib->willBeReExported() && _options.useSimplifiedDylibReExports() )
1267 cmd->set_cmd(LC_REEXPORT_DYLIB);
1268 else if ( dylib->willBeUpwardDylib() && _options.useUpwardDylibs() )
1269 cmd->set_cmd(LC_LOAD_UPWARD_DYLIB);
1270 else
1271 cmd->set_cmd(LC_LOAD_DYLIB);
1272 cmd->set_cmdsize(sz);
1273 cmd->set_timestamp(2); // needs to be some constant value that is different than DylibIDLoadCommandsAtom uses
1274 cmd->set_current_version(dylib->currentVersion());
1275 cmd->set_compatibility_version(dylib->compatibilityVersion());
1276 cmd->set_name_offset();
1277 strcpy((char*)&p[sizeof(macho_dylib_command<P>)], dylib->installPath());
1278 return p + sz;
1279 }
1280
1281 template <typename A>
1282 uint8_t* HeaderAndLoadCommandsAtom<A>::copyRPathLoadCommand(uint8_t* p, const char* path) const
1283 {
1284 uint32_t sz = alignedSize(sizeof(macho_rpath_command<P>) + strlen(path) + 1);
1285 macho_rpath_command<P>* cmd = (macho_rpath_command<P>*)p;
1286 cmd->set_cmd(LC_RPATH);
1287 cmd->set_cmdsize(sz);
1288 cmd->set_path_offset();
1289 strcpy((char*)&p[sizeof(macho_rpath_command<P>)], path);
1290 return p + sz;
1291 }
1292
1293 template <typename A>
1294 uint8_t* HeaderAndLoadCommandsAtom<A>::copySubFrameworkLoadCommand(uint8_t* p) const
1295 {
1296 const char* umbrellaName = _options.umbrellaName();
1297 uint32_t sz = alignedSize(sizeof(macho_sub_framework_command<P>) + strlen(umbrellaName) + 1);
1298 macho_sub_framework_command<P>* cmd = (macho_sub_framework_command<P>*)p;
1299 cmd->set_cmd(LC_SUB_FRAMEWORK);
1300 cmd->set_cmdsize(sz);
1301 cmd->set_umbrella_offset();
1302 strcpy((char*)&p[sizeof(macho_sub_framework_command<P>)], umbrellaName);
1303 return p + sz;
1304 }
1305
1306
1307 template <typename A>
1308 uint8_t* HeaderAndLoadCommandsAtom<A>::copyAllowableClientLoadCommand(uint8_t* p, const char* client) const
1309 {
1310 uint32_t sz = alignedSize(sizeof(macho_sub_client_command<P>) + strlen(client) + 1);
1311 macho_sub_client_command<P>* cmd = (macho_sub_client_command<P>*)p;
1312 cmd->set_cmd(LC_SUB_CLIENT);
1313 cmd->set_cmdsize(sz);
1314 cmd->set_client_offset();
1315 strcpy((char*)&p[sizeof(macho_sub_client_command<P>)], client);
1316 return p + sz;
1317 }
1318
1319 template <typename A>
1320 uint8_t* HeaderAndLoadCommandsAtom<A>::copyDyldEnvLoadCommand(uint8_t* p, const char* env) const
1321 {
1322 uint32_t sz = alignedSize(sizeof(macho_dylinker_command<P>) + strlen(env) + 1);
1323 macho_dylinker_command<P>* cmd = (macho_dylinker_command<P>*)p;
1324 cmd->set_cmd(LC_DYLD_ENVIRONMENT);
1325 cmd->set_cmdsize(sz);
1326 cmd->set_name_offset();
1327 strcpy((char*)&p[sizeof(macho_dylinker_command<P>)], env);
1328 return p + sz;
1329 }
1330
1331 template <typename A>
1332 uint8_t* HeaderAndLoadCommandsAtom<A>::copySubUmbrellaLoadCommand(uint8_t* p, const char* nm) const
1333 {
1334 uint32_t sz = alignedSize(sizeof(macho_sub_umbrella_command<P>) + strlen(nm) + 1);
1335 macho_sub_umbrella_command<P>* cmd = (macho_sub_umbrella_command<P>*)p;
1336 cmd->set_cmd(LC_SUB_UMBRELLA);
1337 cmd->set_cmdsize(sz);
1338 cmd->set_sub_umbrella_offset();
1339 strcpy((char*)&p[sizeof(macho_sub_umbrella_command<P>)], nm);
1340 return p + sz;
1341 }
1342
1343 template <typename A>
1344 uint8_t* HeaderAndLoadCommandsAtom<A>::copySubLibraryLoadCommand(uint8_t* p, const char* nm) const
1345 {
1346 uint32_t sz = alignedSize(sizeof(macho_sub_library_command<P>) + strlen(nm) + 1);
1347 macho_sub_library_command<P>* cmd = (macho_sub_library_command<P>*)p;
1348 cmd->set_cmd(LC_SUB_LIBRARY);
1349 cmd->set_cmdsize(sz);
1350 cmd->set_sub_library_offset();
1351 strcpy((char*)&p[sizeof(macho_sub_library_command<P>)], nm);
1352 return p + sz;
1353 }
1354
1355 template <typename A>
1356 uint8_t* HeaderAndLoadCommandsAtom<A>::copyFunctionStartsLoadCommand(uint8_t* p) const
1357 {
1358 macho_linkedit_data_command<P>* cmd = (macho_linkedit_data_command<P>*)p;
1359 cmd->set_cmd(LC_FUNCTION_STARTS);
1360 cmd->set_cmdsize(sizeof(macho_linkedit_data_command<P>));
1361 cmd->set_dataoff(_writer.functionStartsSection->fileOffset);
1362 cmd->set_datasize(_writer.functionStartsSection->size);
1363 return p + sizeof(macho_linkedit_data_command<P>);
1364 }
1365
1366
1367 template <typename A>
1368 uint8_t* HeaderAndLoadCommandsAtom<A>::copyDataInCodeLoadCommand(uint8_t* p) const
1369 {
1370 macho_linkedit_data_command<P>* cmd = (macho_linkedit_data_command<P>*)p;
1371 cmd->set_cmd(LC_DATA_IN_CODE);
1372 cmd->set_cmdsize(sizeof(macho_linkedit_data_command<P>));
1373 cmd->set_dataoff(_writer.dataInCodeSection->fileOffset);
1374 cmd->set_datasize(_writer.dataInCodeSection->size);
1375 return p + sizeof(macho_linkedit_data_command<P>);
1376 }
1377
1378
1379 template <typename A>
1380 uint8_t* HeaderAndLoadCommandsAtom<A>::copyLinkerOptionsLoadCommand(uint8_t* p, const std::vector<const char*>& options) const
1381 {
1382 macho_linker_option_command<P>* cmd = (macho_linker_option_command<P>*)p;
1383 cmd->set_cmd(LC_LINKER_OPTION);
1384 cmd->set_count(options.size());
1385 char* buffer = cmd->buffer();
1386 uint32_t sz = sizeof(macho_linker_option_command<P>);
1387 for (std::vector<const char*>::const_iterator it=options.begin(); it != options.end(); ++it) {
1388 const char* opt = *it;
1389 uint32_t len = strlen(opt);
1390 strcpy(buffer, opt);
1391 sz += (len + 1);
1392 buffer += (len + 1);
1393 }
1394 sz = alignedSize(sz);
1395 cmd->set_cmdsize(sz);
1396 return p + sz;
1397 }
1398
1399
1400 template <typename A>
1401 uint8_t* HeaderAndLoadCommandsAtom<A>::copyDependentDRLoadCommand(uint8_t* p) const
1402 {
1403 macho_linkedit_data_command<P>* cmd = (macho_linkedit_data_command<P>*)p;
1404 cmd->set_cmd(LC_DYLIB_CODE_SIGN_DRS);
1405 cmd->set_cmdsize(sizeof(macho_linkedit_data_command<P>));
1406 cmd->set_dataoff(_writer.dependentDRsSection->fileOffset);
1407 cmd->set_datasize(_writer.dependentDRsSection->size);
1408 return p + sizeof(macho_linkedit_data_command<P>);
1409 }
1410
1411
1412 template <typename A>
1413 void HeaderAndLoadCommandsAtom<A>::copyRawContent(uint8_t buffer[]) const
1414 {
1415 macho_header<P>* mh = (macho_header<P>*)buffer;
1416 bzero(buffer, this->size());
1417
1418 // copy mach_header
1419 mh->set_magic(this->magic());
1420 mh->set_cputype(this->cpuType());
1421 mh->set_cpusubtype(this->cpuSubType());
1422 mh->set_filetype(this->fileType());
1423 mh->set_ncmds(this->commandsCount());
1424 mh->set_sizeofcmds(this->size()-sizeof(macho_header<P>));
1425 mh->set_flags(this->flags());
1426
1427 // copy load commands
1428 uint8_t* p = &buffer[sizeof(macho_header<P>)];
1429
1430 if ( _options.outputKind() == Options::kObjectFile )
1431 p = this->copySingleSegmentLoadCommand(p);
1432 else
1433 p = this->copySegmentLoadCommands(p);
1434
1435 if ( _hasDylibIDLoadCommand )
1436 p = this->copyDylibIDLoadCommand(p);
1437
1438 if ( _hasDyldInfoLoadCommand )
1439 p = this->copyDyldInfoLoadCommand(p);
1440
1441 if ( _hasSymbolTableLoadCommand )
1442 p = this->copySymbolTableLoadCommand(p);
1443
1444 if ( _hasDynamicSymbolTableLoadCommand )
1445 p = this->copyDynamicSymbolTableLoadCommand(p);
1446
1447 if ( _hasDyldLoadCommand )
1448 p = this->copyDyldLoadCommand(p);
1449
1450 if ( _hasRoutinesLoadCommand )
1451 p = this->copyRoutinesLoadCommand(p);
1452
1453 if ( _hasUUIDLoadCommand )
1454 p = this->copyUUIDLoadCommand(p);
1455
1456 if ( _hasVersionLoadCommand )
1457 p = this->copyVersionLoadCommand(p);
1458
1459 if ( _hasSourceVersionLoadCommand )
1460 p = this->copySourceVersionLoadCommand(p);
1461
1462 if ( _hasThreadLoadCommand )
1463 p = this->copyThreadsLoadCommand(p);
1464
1465 if ( _hasEntryPointLoadCommand )
1466 p = this->copyEntryPointLoadCommand(p);
1467
1468 if ( _hasEncryptionLoadCommand )
1469 p = this->copyEncryptionLoadCommand(p);
1470
1471 if ( _hasSplitSegInfoLoadCommand )
1472 p = this->copySplitSegInfoLoadCommand(p);
1473
1474 for (uint32_t ord=1; ord <= _writer.dylibCount(); ++ord) {
1475 p = this->copyDylibLoadCommand(p, _writer.dylibByOrdinal(ord));
1476 }
1477
1478 if ( _hasRPathLoadCommands ) {
1479 const std::vector<const char*>& rpaths = _options.rpaths();
1480 for (std::vector<const char*>::const_iterator it = rpaths.begin(); it != rpaths.end(); ++it) {
1481 p = this->copyRPathLoadCommand(p, *it);
1482 }
1483 }
1484
1485 if ( _hasSubFrameworkLoadCommand )
1486 p = this->copySubFrameworkLoadCommand(p);
1487
1488 for (std::vector<const char*>::const_iterator it = _subLibraryNames.begin(); it != _subLibraryNames.end(); ++it) {
1489 p = this->copySubLibraryLoadCommand(p, *it);
1490 }
1491
1492 for (std::vector<const char*>::const_iterator it = _subUmbrellaNames.begin(); it != _subUmbrellaNames.end(); ++it) {
1493 p = this->copySubUmbrellaLoadCommand(p, *it);
1494 }
1495
1496 if ( _allowableClientLoadCommmandsCount != 0 ) {
1497 const std::vector<const char*>& clients = _options.allowableClients();
1498 for (std::vector<const char*>::const_iterator it = clients.begin(); it != clients.end(); ++it) {
1499 p = this->copyAllowableClientLoadCommand(p, *it);
1500 }
1501 }
1502
1503 if ( _dyldEnvironExrasCount != 0 ) {
1504 const std::vector<const char*>& extras = _options.dyldEnvironExtras();
1505 for (std::vector<const char*>::const_iterator it = extras.begin(); it != extras.end(); ++it) {
1506 p = this->copyDyldEnvLoadCommand(p, *it);
1507 }
1508 }
1509
1510 if ( _hasFunctionStartsLoadCommand )
1511 p = this->copyFunctionStartsLoadCommand(p);
1512
1513 if ( _hasDataInCodeLoadCommand )
1514 p = this->copyDataInCodeLoadCommand(p);
1515
1516 if ( !_linkerOptions.empty() ) {
1517 for (ld::relocatable::File::LinkerOptionsList::const_iterator it = _linkerOptions.begin(); it != _linkerOptions.end(); ++it) {
1518 p = this->copyLinkerOptionsLoadCommand(p, *it);
1519 }
1520 }
1521
1522 if ( _hasDependentDRInfo )
1523 p = this->copyDependentDRLoadCommand(p);
1524
1525 }
1526
1527
1528
1529 } // namespace tool
1530 } // namespace ld
1531
1532 #endif // __HEADER_LOAD_COMMANDS_HPP__