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