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