]> git.saurik.com Git - apple/ld64.git/blame - src/ld/HeaderAndLoadCommands.hpp
ld64-241.9.tar.gz
[apple/ld64.git] / src / ld / HeaderAndLoadCommands.hpp
CommitLineData
a645023d
A
1/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-*
2 *
ebf6f434 3 * Copyright (c) 2009-2011 Apple Inc. All rights reserved.
a645023d
A
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};
53
54template <typename A>
55class HeaderAndLoadCommandsAtom : public HeaderAndLoadCommandsAbtract
56{
57public:
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; }
a645023d
A
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
72private:
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;
ebf6f434 97 uint8_t* copySourceVersionLoadCommand(uint8_t* p) const;
a645023d 98 uint8_t* copyThreadsLoadCommand(uint8_t* p) const;
ebf6f434 99 uint8_t* copyEntryPointLoadCommand(uint8_t* p) const;
a645023d
A
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;
ebf6f434
A
109 uint8_t* copyDataInCodeLoadCommand(uint8_t* p) const;
110 uint8_t* copyDependentDRLoadCommand(uint8_t* p) const;
a645023d 111 uint8_t* copyDyldEnvLoadCommand(uint8_t* p, const char* env) const;
f80fe69f 112 uint8_t* copyLinkerOptionsLoadCommand(uint8_t* p, const std::vector<const char*>&) const;
9543cb2f 113 uint8_t* copyOptimizationHintsLoadCommand(uint8_t* p) const;
f80fe69f 114
a645023d
A
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;
ebf6f434 127 bool _hasEntryPointLoadCommand;
a645023d
A
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;
ebf6f434
A
138 bool _hasDataInCodeLoadCommand;
139 bool _hasSourceVersionLoadCommand;
140 bool _hasDependentDRInfo;
9543cb2f 141 bool _hasOptimizationHints;
a645023d
A
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;
f80fe69f 149 std::vector< std::vector<const char*> > _linkerOptions;
a645023d
A
150
151 static ld::Section _s_section;
152 static ld::Section _s_preload_section;
153};
154
155template <typename A>
156ld::Section HeaderAndLoadCommandsAtom<A>::_s_section("__TEXT", "__mach_header", ld::Section::typeMachHeader, true);
157template <typename A>
158ld::Section HeaderAndLoadCommandsAtom<A>::_s_preload_section("__HEADER", "__mach_header", ld::Section::typeMachHeader, true);
159
160
161template <typename A>
162HeaderAndLoadCommandsAtom<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);
ebf6f434
A
174 _hasThreadLoadCommand = _options.needsThreadLoadCommand();
175 _hasEntryPointLoadCommand = _options.needsEntryPointLoadCommand();
a645023d
A
176 _hasEncryptionLoadCommand = opts.makeEncryptable();
177 _hasSplitSegInfoLoadCommand = opts.sharedRegionEligible();
178 _hasRoutinesLoadCommand = (opts.initFunctionName() != NULL);
179 _hasSymbolTableLoadCommand = true;
180 _hasUUIDLoadCommand = (opts.UUIDMode() != Options::kUUIDNone);
9543cb2f 181 _hasOptimizationHints = (_state.someObjectHasOptimizationHints && (opts.outputKind() == Options::kObjectFile));
a645023d
A
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 }
f80fe69f
A
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 };
a645023d
A
216 break;
217 case Options::kStaticExecutable:
ebf6f434 218 _hasDynamicSymbolTableLoadCommand = opts.positionIndependentExecutable();
a645023d
A
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();
ebf6f434
A
228 _hasDataInCodeLoadCommand = _options.addDataInCodeInfo();
229 _hasSourceVersionLoadCommand = _options.needsSourceVersionLoadCommand();
230 _hasDependentDRInfo = _options.needsDependentDRInfo();
a645023d
A
231 _dylibLoadCommmandsCount = _writer.dylibCount();
232 _allowableClientLoadCommmandsCount = _options.allowableClients().size();
233 _dyldEnvironExrasCount = _options.dyldEnvironExtras().size();
f80fe69f 234
a645023d
A
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
283template <typename A>
284uint32_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
293template <typename A>
294unsigned 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
304template <typename A>
305unsigned 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
330template <typename A>
331uint64_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>);
ebf6f434
A
361
362 if ( _hasSourceVersionLoadCommand )
363 sz += sizeof(macho_source_version_command<P>);
a645023d
A
364
365 if ( _hasThreadLoadCommand )
366 sz += this->threadLoadCommandSize();
ebf6f434
A
367
368 if ( _hasEntryPointLoadCommand )
369 sz += sizeof(macho_entry_point_command<P>);
a645023d
A
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
ebf6f434
A
416 if ( _hasDataInCodeLoadCommand )
417 sz += sizeof(macho_linkedit_data_command<P>);
418
f80fe69f
A
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
ebf6f434
A
430 if ( _hasDependentDRInfo )
431 sz += sizeof(macho_linkedit_data_command<P>);
9543cb2f
A
432
433 if ( _hasOptimizationHints )
434 sz += sizeof(macho_linkedit_data_command<P>);
ebf6f434 435
a645023d
A
436 return sz;
437}
438
439template <typename A>
440uint32_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
ebf6f434
A
468 if ( _hasSourceVersionLoadCommand )
469 ++count;
470
a645023d
A
471 if ( _hasThreadLoadCommand )
472 ++count;
ebf6f434
A
473
474 if ( _hasEntryPointLoadCommand )
475 ++count;
a645023d
A
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
ebf6f434
A
501 if ( _hasDataInCodeLoadCommand )
502 ++count;
503
f80fe69f
A
504 if ( !_linkerOptions.empty() ) {
505 for (ld::relocatable::File::LinkerOptionsList::const_iterator it = _linkerOptions.begin(); it != _linkerOptions.end(); ++it) {
506 ++count;
507 }
508 }
509
ebf6f434
A
510 if ( _hasDependentDRInfo )
511 ++count;
9543cb2f
A
512
513 if ( _hasOptimizationHints )
514 ++count;
ebf6f434 515
a645023d
A
516 return count;
517}
518
519template <typename A>
520uint32_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
542template <typename A>
543uint32_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;
ebf6f434
A
553 if ( _options.positionIndependentExecutable() )
554 bits |= MH_PIE;
a645023d
A
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 }
9543cb2f 573 if ( _state.hasWeakExternalSymbols || _writer.overridesWeakExternalSymbols )
a645023d 574 bits |= MH_WEAK_DEFINES;
9543cb2f 575 if ( _writer.usesWeakExternalSymbols || _state.hasWeakExternalSymbols )
a645023d
A
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;
9543cb2f 590 if ( _state.hasThreadLocalVariableDefinitions )
a645023d
A
591 bits |= MH_HAS_TLV_DESCRIPTORS;
592 if ( _options.hasNonExecutableHeap() )
593 bits |= MH_NO_HEAP_EXECUTION;
599556ff
A
594 if ( _options.markAppExtensionSafe() && (_options.outputKind() == Options::kDynamicLibrary) )
595 bits |= MH_APP_EXTENSION_SAFE;
a645023d
A
596 }
597 if ( _options.hasExecutableStack() )
598 bits |= MH_ALLOW_STACK_EXECUTION;
599 }
600 return bits;
601}
602
a645023d
A
603template <> uint32_t HeaderAndLoadCommandsAtom<x86>::magic() const { return MH_MAGIC; }
604template <> uint32_t HeaderAndLoadCommandsAtom<x86_64>::magic() const { return MH_MAGIC_64; }
605template <> uint32_t HeaderAndLoadCommandsAtom<arm>::magic() const { return MH_MAGIC; }
f80fe69f 606template <> uint32_t HeaderAndLoadCommandsAtom<arm64>::magic() const { return MH_MAGIC_64; }
a645023d 607
a645023d
A
608template <> uint32_t HeaderAndLoadCommandsAtom<x86>::cpuType() const { return CPU_TYPE_I386; }
609template <> uint32_t HeaderAndLoadCommandsAtom<x86_64>::cpuType() const { return CPU_TYPE_X86_64; }
610template <> uint32_t HeaderAndLoadCommandsAtom<arm>::cpuType() const { return CPU_TYPE_ARM; }
f80fe69f 611template <> uint32_t HeaderAndLoadCommandsAtom<arm64>::cpuType() const { return CPU_TYPE_ARM64; }
a645023d
A
612
613
a645023d
A
614
615template <>
616uint32_t HeaderAndLoadCommandsAtom<x86>::cpuSubType() const
617{
618 return CPU_SUBTYPE_I386_ALL;
619}
620
621template <>
622uint32_t HeaderAndLoadCommandsAtom<x86_64>::cpuSubType() const
623{
9543cb2f
A
624 if ( (_options.outputKind() == Options::kDynamicExecutable) && (_state.cpuSubType == CPU_SUBTYPE_X86_64_ALL) && (_options.macosxVersionMin() >= ld::mac10_5) )
625 return (_state.cpuSubType | 0x80000000);
a645023d 626 else
9543cb2f 627 return _state.cpuSubType;
a645023d
A
628}
629
630template <>
631uint32_t HeaderAndLoadCommandsAtom<arm>::cpuSubType() const
632{
633 return _state.cpuSubType;
634}
635
f80fe69f
A
636template <>
637uint32_t HeaderAndLoadCommandsAtom<arm64>::cpuSubType() const
638{
639 return CPU_SUBTYPE_ARM64_ALL;
640}
641
a645023d
A
642
643
644template <typename A>
645uint8_t* HeaderAndLoadCommandsAtom<A>::copySingleSegmentLoadCommand(uint8_t* p) const
646{
647 // in .o files there is just one segment load command with a blank name
648 // and all sections under it
649 macho_segment_command<P>* cmd = (macho_segment_command<P>*)p;
650 cmd->set_cmd(macho_segment_command<P>::CMD);
651 cmd->set_segname("");
652 cmd->set_vmaddr(_options.baseAddress());
653 cmd->set_vmsize(0); // updated after sections set
654 cmd->set_fileoff(0); // updated after sections set
655 cmd->set_filesize(0); // updated after sections set
656 cmd->set_maxprot(VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE);
657 cmd->set_initprot(VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE);
658 cmd->set_nsects(this->nonHiddenSectionCount());
659 cmd->set_flags(0);
660 // add sections array
661 macho_section<P>* msect = (macho_section<P>*)&p[sizeof(macho_segment_command<P>)];
662 for (std::vector<ld::Internal::FinalSection*>::iterator sit = _state.sections.begin(); sit != _state.sections.end(); ++sit) {
663 ld::Internal::FinalSection* fsect = *sit;
664 if ( fsect->isSectionHidden() )
665 continue;
666 if ( fsect->type() == ld::Section::typeTentativeDefs )
667 continue;
668 msect->set_sectname(fsect->sectionName());
669 msect->set_segname(fsect->segmentName());
670 msect->set_addr(fsect->address);
671 msect->set_size(fsect->size);
672 msect->set_offset(fsect->fileOffset);
673 msect->set_align(fsect->alignment);
674 msect->set_reloff((fsect->relocCount == 0) ? 0 : _writer.sectionRelocationsSection->fileOffset + fsect->relocStart * sizeof(macho_relocation_info<P>));
675 msect->set_nreloc(fsect->relocCount);
676 msect->set_flags(sectionFlags(fsect));
677 msect->set_reserved1(fsect->indirectSymTabStartIndex);
678 msect->set_reserved2(fsect->indirectSymTabElementSize);
679 // update segment info
680 if ( cmd->fileoff() == 0 )
681 cmd->set_fileoff(fsect->fileOffset);
682 cmd->set_vmsize(fsect->address + fsect->size - cmd->vmaddr());
683 if ( (fsect->type() != ld::Section::typeZeroFill) && (fsect->type() != ld::Section::typeTentativeDefs) )
684 cmd->set_filesize(fsect->fileOffset + fsect->size - cmd->fileoff());
685 ++msect;
686 }
687 cmd->set_cmdsize(sizeof(macho_segment_command<P>) + cmd->nsects()*sizeof(macho_section<P>));
688 return p + cmd->cmdsize();
689}
690
691struct SegInfo {
692 SegInfo(const char* n, const Options&);
693 const char* segName;
694 uint32_t nonHiddenSectionCount;
695 uint32_t maxProt;
696 uint32_t initProt;
697 std::vector<ld::Internal::FinalSection*> sections;
698};
699
700
701SegInfo::SegInfo(const char* n, const Options& opts)
702 : segName(n), nonHiddenSectionCount(0), maxProt(opts.maxSegProtection(n)), initProt(opts.initialSegProtection(n))
703{
704}
705
706
707template <typename A>
708uint32_t HeaderAndLoadCommandsAtom<A>::sectionFlags(ld::Internal::FinalSection* sect) const
709{
710 uint32_t bits;
711 switch ( sect->type() ) {
712 case ld::Section::typeUnclassified:
713 if ( strcmp(sect->segmentName(), "__OBJC") == 0 )
714 return S_REGULAR | S_ATTR_NO_DEAD_STRIP;
715 else if ( (strcmp(sect->sectionName(), "__objc_classlist") == 0) && (strcmp(sect->segmentName(), "__DATA") == 0) )
716 return S_REGULAR | S_ATTR_NO_DEAD_STRIP;
717 else if ( (strcmp(sect->sectionName(), "__objc_catlist") == 0) && (strcmp(sect->segmentName(), "__DATA") == 0) )
718 return S_REGULAR | S_ATTR_NO_DEAD_STRIP;
719 else if ( (strncmp(sect->sectionName(), "__objc_superrefs", 16) == 0) && (strcmp(sect->segmentName(), "__DATA") == 0) )
720 return S_REGULAR | S_ATTR_NO_DEAD_STRIP;
afe874b1
A
721 else if ( (strncmp(sect->sectionName(), "__objc_nlclslist", 16) == 0) && (strcmp(sect->segmentName(), "__DATA") == 0) )
722 return S_REGULAR | S_ATTR_NO_DEAD_STRIP;
b1f7435d
A
723 else if ( (strncmp(sect->sectionName(), "__objc_nlcatlist", 16) == 0) && (strcmp(sect->segmentName(), "__DATA") == 0) )
724 return S_REGULAR | S_ATTR_NO_DEAD_STRIP;
a645023d
A
725 else
726 return S_REGULAR;
727 case ld::Section::typeCode:
728 bits = S_REGULAR | S_ATTR_SOME_INSTRUCTIONS | S_ATTR_PURE_INSTRUCTIONS;
729 if ( sect->hasLocalRelocs && ! _writer.pieDisabled )
730 bits |= S_ATTR_LOC_RELOC;
731 if ( sect->hasExternalRelocs )
732 bits |= S_ATTR_EXT_RELOC;
733 return bits;
734 case ld::Section::typePageZero:
735 return S_REGULAR;
736 case ld::Section::typeImportProxies:
737 return S_REGULAR;
738 case ld::Section::typeLinkEdit:
739 return S_REGULAR;
740 case ld::Section::typeMachHeader:
741 return S_REGULAR;
742 case ld::Section::typeStack:
743 return S_REGULAR;
744 case ld::Section::typeLiteral4:
745 return S_4BYTE_LITERALS;
746 case ld::Section::typeLiteral8:
747 return S_8BYTE_LITERALS;
748 case ld::Section::typeLiteral16:
749 return S_16BYTE_LITERALS;
750 case ld::Section::typeConstants:
751 return S_REGULAR;
752 case ld::Section::typeTempLTO:
753 assert(0 && "typeTempLTO should not make it to final linked image");
754 return S_REGULAR;
599556ff
A
755 case ld::Section::typeTempAlias:
756 assert(0 && "typeAlias should not make it to final linked image");
757 return S_REGULAR;
a645023d
A
758 case ld::Section::typeAbsoluteSymbols:
759 assert(0 && "typeAbsoluteSymbols should not make it to final linked image");
760 return S_REGULAR;
761 case ld::Section::typeCString:
762 case ld::Section::typeNonStdCString:
763 return S_CSTRING_LITERALS;
764 case ld::Section::typeCStringPointer:
765 return S_LITERAL_POINTERS | S_ATTR_NO_DEAD_STRIP;
766 case ld::Section::typeUTF16Strings:
767 return S_REGULAR;
768 case ld::Section::typeCFString:
769 return S_REGULAR;
770 case ld::Section::typeObjC1Classes:
771 return S_REGULAR | S_ATTR_NO_DEAD_STRIP;
772 case ld::Section::typeCFI:
773 return S_REGULAR;
774 case ld::Section::typeLSDA:
775 return S_REGULAR;
776 case ld::Section::typeDtraceDOF:
777 return S_DTRACE_DOF;
778 case ld::Section::typeUnwindInfo:
779 return S_REGULAR;
780 case ld::Section::typeObjCClassRefs:
781 case ld::Section::typeObjC2CategoryList:
782 return S_REGULAR | S_ATTR_NO_DEAD_STRIP;
783 case ld::Section::typeZeroFill:
784 if ( _options.optimizeZeroFill() )
785 return S_ZEROFILL;
786 else
787 return S_REGULAR;
788 case ld::Section::typeTentativeDefs:
789 assert(0 && "typeTentativeDefs should not make it to final linked image");
790 return S_REGULAR;
791 case ld::Section::typeLazyPointer:
792 case ld::Section::typeLazyPointerClose:
793 return S_LAZY_SYMBOL_POINTERS;
794 case ld::Section::typeStubClose:
795 case ld::Section::typeStub:
796 if ( sect->hasLocalRelocs )
797 return S_SYMBOL_STUBS | S_ATTR_SOME_INSTRUCTIONS | S_ATTR_PURE_INSTRUCTIONS | S_ATTR_LOC_RELOC;
798 else
799 return S_SYMBOL_STUBS | S_ATTR_SOME_INSTRUCTIONS | S_ATTR_PURE_INSTRUCTIONS;
800 case ld::Section::typeNonLazyPointer:
ebf6f434
A
801 if ( _options.outputKind() == Options::kKextBundle )
802 return S_REGULAR;
803 else if ( (_options.outputKind() == Options::kStaticExecutable) && _options.positionIndependentExecutable() )
804 return S_REGULAR;
805 else
806 return S_NON_LAZY_SYMBOL_POINTERS;
a645023d
A
807 case ld::Section::typeDyldInfo:
808 return S_REGULAR;
809 case ld::Section::typeLazyDylibPointer:
810 return S_LAZY_DYLIB_SYMBOL_POINTERS;
811 case ld::Section::typeStubHelper:
812 if ( sect->hasLocalRelocs )
813 return S_REGULAR | S_ATTR_SOME_INSTRUCTIONS | S_ATTR_PURE_INSTRUCTIONS | S_ATTR_LOC_RELOC;
814 else
815 return S_REGULAR | S_ATTR_SOME_INSTRUCTIONS | S_ATTR_PURE_INSTRUCTIONS;
816 case ld::Section::typeInitializerPointers:
ebf6f434
A
817 // <rdar://problem/11456679> i386 kexts need different section type
818 if ( (_options.outputKind() == Options::kObjectFile)
819 && (strcmp(sect->sectionName(), "__constructor") == 0)
820 && (strcmp(sect->segmentName(), "__TEXT") == 0) )
821 return S_REGULAR;
822 else
823 return S_MOD_INIT_FUNC_POINTERS;
a645023d
A
824 case ld::Section::typeTerminatorPointers:
825 return S_MOD_TERM_FUNC_POINTERS;
826 case ld::Section::typeTLVInitialValues:
827 return S_THREAD_LOCAL_REGULAR;
828 case ld::Section::typeTLVZeroFill:
829 return S_THREAD_LOCAL_ZEROFILL;
830 case ld::Section::typeTLVDefs:
831 return S_THREAD_LOCAL_VARIABLES;
832 case ld::Section::typeTLVInitializerPointers:
833 return S_THREAD_LOCAL_INIT_FUNCTION_POINTERS;
834 case ld::Section::typeTLVPointers:
835 return S_THREAD_LOCAL_VARIABLE_POINTERS;
836 case ld::Section::typeFirstSection:
837 assert(0 && "typeFirstSection should not make it to final linked image");
838 return S_REGULAR;
839 case ld::Section::typeLastSection:
840 assert(0 && "typeLastSection should not make it to final linked image");
841 return S_REGULAR;
afe874b1
A
842 case ld::Section::typeDebug:
843 return S_REGULAR | S_ATTR_DEBUG;
a645023d
A
844 }
845 return S_REGULAR;
846}
847
848
849template <typename A>
850bool HeaderAndLoadCommandsAtom<A>::sectionTakesNoDiskSpace(ld::Internal::FinalSection* sect) const
851{
852 switch ( sect->type() ) {
853 case ld::Section::typeZeroFill:
854 case ld::Section::typeTLVZeroFill:
855 return _options.optimizeZeroFill();
856 case ld::Section::typeAbsoluteSymbols:
857 case ld::Section::typeTentativeDefs:
858 case ld::Section::typeLastSection:
859 return true;
860 default:
861 break;
862 }
863 return false;
864}
865
866
867template <typename A>
868uint8_t* HeaderAndLoadCommandsAtom<A>::copySegmentLoadCommands(uint8_t* p) const
869{
870 // group sections into segments
871 std::vector<SegInfo> segs;
872 const char* lastSegName = "";
873 for (std::vector<ld::Internal::FinalSection*>::iterator it = _state.sections.begin(); it != _state.sections.end(); ++it) {
874 ld::Internal::FinalSection* sect = *it;
875 if ( _options.outputKind() == Options::kPreload ) {
876 if ( (*it)->type() == ld::Section::typeMachHeader )
877 continue; // for -preload, don't put hidden __HEADER segment into output
878 if ( (*it)->type() == ld::Section::typeLinkEdit )
879 continue; // for -preload, don't put hidden __LINKEDIT segment into output
880 }
881 if ( strcmp(lastSegName, sect->segmentName()) != 0 ) {
882 SegInfo si(sect->segmentName(), _options);
883 segs.push_back(si);
884 lastSegName = sect->segmentName();
885 }
886 if ( ! sect->isSectionHidden() )
887 segs.back().nonHiddenSectionCount++;
888 segs.back().sections.push_back(sect);
889 }
890 // write out segment load commands for each section with trailing sections
891 for (std::vector<SegInfo>::iterator it = segs.begin(); it != segs.end(); ++it) {
892 SegInfo& si = *it;
893 ld::Internal::FinalSection* lastNonZeroFillSection = NULL;
894 for (int i=si.sections.size()-1; i >= 0; --i) {
895 if ( !sectionTakesNoDiskSpace(si.sections[i]) ) {
896 lastNonZeroFillSection = si.sections[i];
897 break;
898 }
899 }
900 uint64_t vmsize = si.sections.back()->address + si.sections.back()->size - si.sections.front()->address;
901 vmsize = ((vmsize+_options.segmentAlignment()-1) & (-_options.segmentAlignment()));
902 uint64_t filesize = 0;
903 if ( lastNonZeroFillSection != NULL ) {
904 filesize = lastNonZeroFillSection->address + lastNonZeroFillSection->size - si.sections.front()->address;
905 // round up all segments to page aligned, except __LINKEDIT
906 if ( (si.sections[0]->type() != ld::Section::typeLinkEdit) && (si.sections[0]->type() != ld::Section::typeImportProxies) )
907 filesize = (filesize + _options.segmentAlignment()-1) & (-_options.segmentAlignment());
908 }
909 if ( si.sections.front()->type() == ld::Section::typePageZero )
910 filesize = 0;
911 else if ( si.sections.front()->type() == ld::Section::typeStack )
912 filesize = 0;
913 macho_segment_command<P>* segCmd = (macho_segment_command<P>*)p;
914 segCmd->set_cmd(macho_segment_command<P>::CMD);
915 segCmd->set_cmdsize(sizeof(macho_segment_command<P>) + si.nonHiddenSectionCount*sizeof(macho_section<P>));
916 segCmd->set_segname(si.sections.front()->segmentName());
917 segCmd->set_vmaddr(si.sections.front()->address);
918 segCmd->set_vmsize(vmsize);
919 segCmd->set_fileoff(si.sections.front()->fileOffset);
920 segCmd->set_filesize(filesize);
921 segCmd->set_maxprot(si.maxProt);
922 segCmd->set_initprot(si.initProt);
923 segCmd->set_nsects(si.nonHiddenSectionCount);
924 segCmd->set_flags(0);
925 p += sizeof(macho_segment_command<P>);
926 macho_section<P>* msect = (macho_section<P>*)p;
927 for (std::vector<ld::Internal::FinalSection*>::iterator sit = si.sections.begin(); sit != si.sections.end(); ++sit) {
928 ld::Internal::FinalSection* fsect = *sit;
929 if ( ! fsect->isSectionHidden() ) {
930 msect->set_sectname(fsect->sectionName());
931 msect->set_segname(fsect->segmentName());
932 msect->set_addr(fsect->address);
933 msect->set_size(fsect->size);
934 msect->set_offset(sectionTakesNoDiskSpace(fsect) ? 0 : fsect->fileOffset);
935 msect->set_align(fsect->alignment);
936 msect->set_reloff(0);
937 msect->set_nreloc(0);
938 msect->set_flags(sectionFlags(fsect));
939 msect->set_reserved1(fsect->indirectSymTabStartIndex);
940 msect->set_reserved2(fsect->indirectSymTabElementSize);
941 p += sizeof(macho_section<P>);
942 ++msect;
943 }
944 }
945 }
946
947 return p;
948}
949
950
951template <typename A>
952uint8_t* HeaderAndLoadCommandsAtom<A>::copySymbolTableLoadCommand(uint8_t* p) const
953{
954 // build LC_SYMTAB command
955 macho_symtab_command<P>* symbolTableCmd = (macho_symtab_command<P>*)p;
956 symbolTableCmd->set_cmd(LC_SYMTAB);
957 symbolTableCmd->set_cmdsize(sizeof(macho_symtab_command<P>));
958 symbolTableCmd->set_nsyms(_writer.symbolTableSection->size/sizeof(macho_nlist<P>));
959 symbolTableCmd->set_symoff(_writer.symbolTableSection->size == 0 ? 0 : _writer.symbolTableSection->fileOffset);
960 symbolTableCmd->set_stroff(_writer.stringPoolSection->size == 0 ? 0 : _writer.stringPoolSection->fileOffset );
961 symbolTableCmd->set_strsize(_writer.stringPoolSection->size);
962 return p + sizeof(macho_symtab_command<P>);
963}
964
965template <typename A>
966uint8_t* HeaderAndLoadCommandsAtom<A>::copyDynamicSymbolTableLoadCommand(uint8_t* p) const
967{
968 // build LC_SYMTAB command
969 macho_dysymtab_command<P>* dynamicSymbolTableCmd = (macho_dysymtab_command<P>*)p;
970 dynamicSymbolTableCmd->set_cmd(LC_DYSYMTAB);
971 dynamicSymbolTableCmd->set_cmdsize(sizeof(macho_dysymtab_command<P>));
972 dynamicSymbolTableCmd->set_ilocalsym(0);
973 dynamicSymbolTableCmd->set_nlocalsym(_writer._localSymbolsCount);
974 dynamicSymbolTableCmd->set_iextdefsym(dynamicSymbolTableCmd->ilocalsym()+dynamicSymbolTableCmd->nlocalsym());
975 dynamicSymbolTableCmd->set_nextdefsym(_writer._globalSymbolsCount);
976 dynamicSymbolTableCmd->set_iundefsym(dynamicSymbolTableCmd->iextdefsym()+dynamicSymbolTableCmd->nextdefsym());
977 dynamicSymbolTableCmd->set_nundefsym(_writer._importSymbolsCount);
978
979 // FIX ME: support for 10.3 dylibs which need modules
980 //if ( fWriter.fModuleInfoAtom != NULL ) {
981 // dynamicSymbolTableCmd->set_tocoff(fWriter.fModuleInfoAtom->getTableOfContentsFileOffset());
982 // dynamicSymbolTableCmd->set_ntoc(fWriter.fSymbolTableExportCount);
983 // dynamicSymbolTableCmd->set_modtaboff(fWriter.fModuleInfoAtom->getModuleTableFileOffset());
984 // dynamicSymbolTableCmd->set_nmodtab(1);
985 // dynamicSymbolTableCmd->set_extrefsymoff(fWriter.fModuleInfoAtom->getReferencesFileOffset());
986 // dynamicSymbolTableCmd->set_nextrefsyms(fWriter.fModuleInfoAtom->getReferencesCount());
987 //}
988
989 bool hasIndirectSymbols = ( (_writer.indirectSymbolTableSection != NULL) && (_writer.indirectSymbolTableSection->size != 0) );
990 dynamicSymbolTableCmd->set_indirectsymoff(hasIndirectSymbols ? _writer.indirectSymbolTableSection->fileOffset : 0);
991 dynamicSymbolTableCmd->set_nindirectsyms( hasIndirectSymbols ? _writer.indirectSymbolTableSection->size/sizeof(uint32_t) : 0);
992
993 // FIX ME: support for classic relocations
994 if ( _options.outputKind() != Options::kObjectFile ) {
995 bool hasExternalRelocs = ( (_writer.externalRelocationsSection != NULL) && (_writer.externalRelocationsSection->size != 0) );
996 dynamicSymbolTableCmd->set_extreloff(hasExternalRelocs ? _writer.externalRelocationsSection->fileOffset : 0);
997 dynamicSymbolTableCmd->set_nextrel( hasExternalRelocs ? _writer.externalRelocationsSection->size/8 : 0);
998 bool hasLocalRelocs = ( (_writer.localRelocationsSection != NULL) && (_writer.localRelocationsSection->size != 0) );
999 dynamicSymbolTableCmd->set_locreloff(hasLocalRelocs ? _writer.localRelocationsSection->fileOffset : 0);
1000 dynamicSymbolTableCmd->set_nlocrel (hasLocalRelocs ? _writer.localRelocationsSection->size/8 : 0);
1001 }
1002 return p + sizeof(macho_dysymtab_command<P>);
1003}
1004
1005
1006template <typename A>
1007uint8_t* HeaderAndLoadCommandsAtom<A>::copyDyldInfoLoadCommand(uint8_t* p) const
1008{
1009 // build LC_DYLD_INFO command
1010 macho_dyld_info_command<P>* cmd = (macho_dyld_info_command<P>*)p;
1011
1012 cmd->set_cmd(LC_DYLD_INFO_ONLY);
1013 cmd->set_cmdsize(sizeof(macho_dyld_info_command<P>));
1014 if ( _writer.rebaseSection->size != 0 ) {
1015 cmd->set_rebase_off(_writer.rebaseSection->fileOffset);
1016 cmd->set_rebase_size(_writer.rebaseSection->size);
1017 }
1018 if ( _writer.bindingSection->size != 0 ) {
1019 cmd->set_bind_off(_writer.bindingSection->fileOffset);
1020 cmd->set_bind_size(_writer.bindingSection->size);
1021 }
1022 if ( _writer.weakBindingSection->size != 0 ) {
1023 cmd->set_weak_bind_off(_writer.weakBindingSection->fileOffset);
1024 cmd->set_weak_bind_size(_writer.weakBindingSection->size);
1025 }
1026 if ( _writer.lazyBindingSection->size != 0 ) {
1027 cmd->set_lazy_bind_off(_writer.lazyBindingSection->fileOffset);
1028 cmd->set_lazy_bind_size(_writer.lazyBindingSection->size);
1029 }
1030 if ( _writer.exportSection->size != 0 ) {
1031 cmd->set_export_off(_writer.exportSection->fileOffset);
1032 cmd->set_export_size(_writer.exportSection->size);
1033 }
1034 return p + sizeof(macho_dyld_info_command<P>);
1035}
1036
1037
1038template <typename A>
1039uint8_t* HeaderAndLoadCommandsAtom<A>::copyDyldLoadCommand(uint8_t* p) const
1040{
1041 uint32_t sz = alignedSize(sizeof(macho_dylinker_command<P>) + strlen(_options.dyldInstallPath()) + 1);
1042 macho_dylinker_command<P>* cmd = (macho_dylinker_command<P>*)p;
1043 if ( _options.outputKind() == Options::kDyld )
1044 cmd->set_cmd(LC_ID_DYLINKER);
1045 else
1046 cmd->set_cmd(LC_LOAD_DYLINKER);
1047 cmd->set_cmdsize(sz);
1048 cmd->set_name_offset();
1049 strcpy((char*)&p[sizeof(macho_dylinker_command<P>)], _options.dyldInstallPath());
1050 return p + sz;
1051}
1052
1053
1054template <typename A>
1055uint8_t* HeaderAndLoadCommandsAtom<A>::copyDylibIDLoadCommand(uint8_t* p) const
1056{
1057 uint32_t sz = alignedSize(sizeof(macho_dylib_command<P>) + strlen(_options.installPath()) + 1);
1058 macho_dylib_command<P>* cmd = (macho_dylib_command<P>*)p;
1059 cmd->set_cmd(LC_ID_DYLIB);
1060 cmd->set_cmdsize(sz);
1061 cmd->set_name_offset();
1062 cmd->set_timestamp(1); // needs to be some constant value that is different than DylibLoadCommandsAtom uses
b2fa67a8 1063 cmd->set_current_version(_options.currentVersion32());
a645023d
A
1064 cmd->set_compatibility_version(_options.compatibilityVersion());
1065 strcpy((char*)&p[sizeof(macho_dylib_command<P>)], _options.installPath());
1066 return p + sz;
1067}
1068
1069template <typename A>
1070uint8_t* HeaderAndLoadCommandsAtom<A>::copyRoutinesLoadCommand(uint8_t* p) const
1071{
1072 pint_t initAddr = _state.entryPoint->finalAddress();
1073 if ( _state.entryPoint->isThumb() )
1074 initAddr |= 1ULL;
1075 macho_routines_command<P>* cmd = (macho_routines_command<P>*)p;
1076 cmd->set_cmd(macho_routines_command<P>::CMD);
1077 cmd->set_cmdsize(sizeof(macho_routines_command<P>));
1078 cmd->set_init_address(initAddr);
1079 return p + sizeof(macho_routines_command<P>);
1080}
1081
1082
1083template <typename A>
1084void HeaderAndLoadCommandsAtom<A>::recopyUUIDCommand()
1085{
1086 assert(_uuidCmdInOutputBuffer != NULL);
1087 _uuidCmdInOutputBuffer->set_uuid(_uuid);
1088}
1089
1090
1091template <typename A>
1092uint8_t* HeaderAndLoadCommandsAtom<A>::copyUUIDLoadCommand(uint8_t* p) const
1093{
1094 macho_uuid_command<P>* cmd = (macho_uuid_command<P>*)p;
1095 cmd->set_cmd(LC_UUID);
1096 cmd->set_cmdsize(sizeof(macho_uuid_command<P>));
1097 cmd->set_uuid(_uuid);
1098 _uuidCmdInOutputBuffer = cmd; // save for later re-write by recopyUUIDCommand()
1099 return p + sizeof(macho_uuid_command<P>);
1100}
1101
1102
1103template <typename A>
1104uint8_t* HeaderAndLoadCommandsAtom<A>::copyVersionLoadCommand(uint8_t* p) const
1105{
1106 macho_version_min_command<P>* cmd = (macho_version_min_command<P>*)p;
afe874b1
A
1107 ld::MacVersionMin macVersion = _options.macosxVersionMin();
1108 ld::IOSVersionMin iOSVersion = _options.iOSVersionMin();
1109 assert( (macVersion != ld::macVersionUnset) || (iOSVersion != ld::iOSVersionUnset) );
a645023d
A
1110 if ( macVersion != ld::macVersionUnset ) {
1111 cmd->set_cmd(LC_VERSION_MIN_MACOSX);
1112 cmd->set_cmdsize(sizeof(macho_version_min_command<P>));
1113 cmd->set_version((uint32_t)macVersion);
ebf6f434 1114 cmd->set_sdk(_options.sdkVersion());
a645023d
A
1115 }
1116 else {
1117 cmd->set_cmd(LC_VERSION_MIN_IPHONEOS);
1118 cmd->set_cmdsize(sizeof(macho_version_min_command<P>));
afe874b1 1119 cmd->set_version((uint32_t)iOSVersion);
ebf6f434 1120 cmd->set_sdk(_options.sdkVersion());
a645023d
A
1121 }
1122 return p + sizeof(macho_version_min_command<P>);
1123}
1124
ebf6f434
A
1125template <typename A>
1126uint8_t* HeaderAndLoadCommandsAtom<A>::copySourceVersionLoadCommand(uint8_t* p) const
1127{
1128 macho_source_version_command<P>* cmd = (macho_source_version_command<P>*)p;
1129 cmd->set_cmd(LC_SOURCE_VERSION);
1130 cmd->set_cmdsize(sizeof(macho_source_version_command<P>));
1131 cmd->set_version(_options.sourceVersion());
1132 return p + sizeof(macho_source_version_command<P>);
1133}
a645023d 1134
a645023d
A
1135
1136template <>
1137uint32_t HeaderAndLoadCommandsAtom<x86>::threadLoadCommandSize() const
1138{
1139 return this->alignedSize(16 + 16*4); // base size + i386_THREAD_STATE_COUNT * 4
1140}
1141
1142template <>
1143uint8_t* HeaderAndLoadCommandsAtom<x86>::copyThreadsLoadCommand(uint8_t* p) const
1144{
1145 assert(_state.entryPoint != NULL);
1146 pint_t start = _state.entryPoint->finalAddress();
1147 macho_thread_command<P>* cmd = (macho_thread_command<P>*)p;
1148 cmd->set_cmd(LC_UNIXTHREAD);
1149 cmd->set_cmdsize(threadLoadCommandSize());
1150 cmd->set_flavor(1); // i386_THREAD_STATE
1151 cmd->set_count(16); // i386_THREAD_STATE_COUNT;
1152 cmd->set_thread_register(10, start);
1153 if ( _options.hasCustomStack() )
1154 cmd->set_thread_register(7, _options.customStackAddr()); // r1
1155 return p + threadLoadCommandSize();
1156}
1157
1158template <>
1159uint32_t HeaderAndLoadCommandsAtom<x86_64>::threadLoadCommandSize() const
1160{
1161 return this->alignedSize(16 + x86_THREAD_STATE64_COUNT * 4);
1162}
1163
1164template <>
1165uint8_t* HeaderAndLoadCommandsAtom<x86_64>::copyThreadsLoadCommand(uint8_t* p) const
1166{
1167 assert(_state.entryPoint != NULL);
1168 pint_t start = _state.entryPoint->finalAddress();
1169 macho_thread_command<P>* cmd = (macho_thread_command<P>*)p;
1170 cmd->set_cmd(LC_UNIXTHREAD);
1171 cmd->set_cmdsize(threadLoadCommandSize());
1172 cmd->set_flavor(x86_THREAD_STATE64);
1173 cmd->set_count(x86_THREAD_STATE64_COUNT);
1174 cmd->set_thread_register(16, start); // rip
1175 if ( _options.hasCustomStack() )
1176 cmd->set_thread_register(7, _options.customStackAddr()); // r1
1177 return p + threadLoadCommandSize();
1178}
1179
1180template <>
1181uint32_t HeaderAndLoadCommandsAtom<arm>::threadLoadCommandSize() const
1182{
1183 return this->alignedSize(16 + 17 * 4); // base size + ARM_THREAD_STATE_COUNT * 4
1184}
1185
1186template <>
1187uint8_t* HeaderAndLoadCommandsAtom<arm>::copyThreadsLoadCommand(uint8_t* p) const
1188{
1189 assert(_state.entryPoint != NULL);
1190 pint_t start = _state.entryPoint->finalAddress();
1191 if ( _state.entryPoint->isThumb() )
1192 start |= 1ULL;
1193 macho_thread_command<P>* cmd = (macho_thread_command<P>*)p;
1194 cmd->set_cmd(LC_UNIXTHREAD);
1195 cmd->set_cmdsize(threadLoadCommandSize());
1196 cmd->set_flavor(1);
1197 cmd->set_count(17);
1198 cmd->set_thread_register(15, start); // pc
1199 if ( _options.hasCustomStack() )
1200 cmd->set_thread_register(13, _options.customStackAddr()); // sp
1201 return p + threadLoadCommandSize();
1202}
1203
ebf6f434 1204
f80fe69f
A
1205template <>
1206uint32_t HeaderAndLoadCommandsAtom<arm64>::threadLoadCommandSize() const
1207{
1208 return this->alignedSize(16 + 34 * 8); // base size + ARM_EXCEPTION_STATE64_COUNT * 4
1209}
1210
1211template <>
1212uint8_t* HeaderAndLoadCommandsAtom<arm64>::copyThreadsLoadCommand(uint8_t* p) const
1213{
1214 assert(_state.entryPoint != NULL);
1215 pint_t start = _state.entryPoint->finalAddress();
1216 macho_thread_command<P>* cmd = (macho_thread_command<P>*)p;
1217 cmd->set_cmd(LC_UNIXTHREAD);
1218 cmd->set_cmdsize(threadLoadCommandSize());
1219 cmd->set_flavor(6); // ARM_THREAD_STATE64
1220 cmd->set_count(68); // ARM_EXCEPTION_STATE64_COUNT
1221 cmd->set_thread_register(32, start); // pc
1222 if ( _options.hasCustomStack() )
1223 cmd->set_thread_register(31, _options.customStackAddr()); // sp
1224 return p + threadLoadCommandSize();
1225}
1226
ebf6f434
A
1227
1228template <typename A>
1229uint8_t* HeaderAndLoadCommandsAtom<A>::copyEntryPointLoadCommand(uint8_t* p) const
1230{
1231 macho_entry_point_command<P>* cmd = (macho_entry_point_command<P>*)p;
1232 cmd->set_cmd(LC_MAIN);
1233 cmd->set_cmdsize(sizeof(macho_entry_point_command<P>));
1234 assert(_state.entryPoint != NULL);
1235 pint_t start = _state.entryPoint->finalAddress();
1236 if ( _state.entryPoint->isThumb() )
1237 start |= 1ULL;
1238 cmd->set_entryoff(start - this->finalAddress());
1239 cmd->set_stacksize(_options.hasCustomStack() ? _options.customStackSize() : 0 );
1240 return p + sizeof(macho_entry_point_command<P>);
1241}
1242
1243
a645023d
A
1244template <typename A>
1245uint8_t* HeaderAndLoadCommandsAtom<A>::copyEncryptionLoadCommand(uint8_t* p) const
1246{
1247 macho_encryption_info_command<P>* cmd = (macho_encryption_info_command<P>*)p;
f80fe69f 1248 cmd->set_cmd(sizeof(typename A::P::uint_t) == 4 ? LC_ENCRYPTION_INFO : LC_ENCRYPTION_INFO_64);
a645023d
A
1249 cmd->set_cmdsize(sizeof(macho_encryption_info_command<P>));
1250 assert(_writer.encryptedTextStartOffset() != 0);
1251 assert(_writer.encryptedTextEndOffset() != 0);
1252 cmd->set_cryptoff(_writer.encryptedTextStartOffset());
1253 cmd->set_cryptsize(_writer.encryptedTextEndOffset()-_writer.encryptedTextStartOffset());
1254 cmd->set_cryptid(0);
1255 return p + sizeof(macho_encryption_info_command<P>);
1256}
1257
1258
1259template <typename A>
1260uint8_t* HeaderAndLoadCommandsAtom<A>::copySplitSegInfoLoadCommand(uint8_t* p) const
1261{
1262 macho_linkedit_data_command<P>* cmd = (macho_linkedit_data_command<P>*)p;
1263 cmd->set_cmd(LC_SEGMENT_SPLIT_INFO);
1264 cmd->set_cmdsize(sizeof(macho_linkedit_data_command<P>));
1265 cmd->set_dataoff(_writer.splitSegInfoSection->fileOffset);
1266 cmd->set_datasize(_writer.splitSegInfoSection->size);
1267 return p + sizeof(macho_linkedit_data_command<P>);
1268}
1269
1270
1271template <typename A>
1272uint8_t* HeaderAndLoadCommandsAtom<A>::copyDylibLoadCommand(uint8_t* p, const ld::dylib::File* dylib) const
1273{
1274 uint32_t sz = alignedSize(sizeof(macho_dylib_command<P>) + strlen(dylib->installPath()) + 1);
1275 macho_dylib_command<P>* cmd = (macho_dylib_command<P>*)p;
a645023d
A
1276 if ( dylib->willBeLazyLoadedDylib() )
1277 cmd->set_cmd(LC_LAZY_LOAD_DYLIB);
afe874b1 1278 else if ( dylib->forcedWeakLinked() || dylib->allSymbolsAreWeakImported() )
a645023d
A
1279 cmd->set_cmd(LC_LOAD_WEAK_DYLIB);
1280 else if ( dylib->willBeReExported() && _options.useSimplifiedDylibReExports() )
1281 cmd->set_cmd(LC_REEXPORT_DYLIB);
1282 else if ( dylib->willBeUpwardDylib() && _options.useUpwardDylibs() )
1283 cmd->set_cmd(LC_LOAD_UPWARD_DYLIB);
1284 else
1285 cmd->set_cmd(LC_LOAD_DYLIB);
1286 cmd->set_cmdsize(sz);
1287 cmd->set_timestamp(2); // needs to be some constant value that is different than DylibIDLoadCommandsAtom uses
1288 cmd->set_current_version(dylib->currentVersion());
1289 cmd->set_compatibility_version(dylib->compatibilityVersion());
1290 cmd->set_name_offset();
1291 strcpy((char*)&p[sizeof(macho_dylib_command<P>)], dylib->installPath());
1292 return p + sz;
1293}
1294
1295template <typename A>
1296uint8_t* HeaderAndLoadCommandsAtom<A>::copyRPathLoadCommand(uint8_t* p, const char* path) const
1297{
1298 uint32_t sz = alignedSize(sizeof(macho_rpath_command<P>) + strlen(path) + 1);
1299 macho_rpath_command<P>* cmd = (macho_rpath_command<P>*)p;
1300 cmd->set_cmd(LC_RPATH);
1301 cmd->set_cmdsize(sz);
1302 cmd->set_path_offset();
1303 strcpy((char*)&p[sizeof(macho_rpath_command<P>)], path);
1304 return p + sz;
1305}
1306
1307template <typename A>
1308uint8_t* HeaderAndLoadCommandsAtom<A>::copySubFrameworkLoadCommand(uint8_t* p) const
1309{
1310 const char* umbrellaName = _options.umbrellaName();
1311 uint32_t sz = alignedSize(sizeof(macho_sub_framework_command<P>) + strlen(umbrellaName) + 1);
1312 macho_sub_framework_command<P>* cmd = (macho_sub_framework_command<P>*)p;
1313 cmd->set_cmd(LC_SUB_FRAMEWORK);
1314 cmd->set_cmdsize(sz);
1315 cmd->set_umbrella_offset();
1316 strcpy((char*)&p[sizeof(macho_sub_framework_command<P>)], umbrellaName);
1317 return p + sz;
1318}
1319
1320
1321template <typename A>
1322uint8_t* HeaderAndLoadCommandsAtom<A>::copyAllowableClientLoadCommand(uint8_t* p, const char* client) const
1323{
1324 uint32_t sz = alignedSize(sizeof(macho_sub_client_command<P>) + strlen(client) + 1);
1325 macho_sub_client_command<P>* cmd = (macho_sub_client_command<P>*)p;
1326 cmd->set_cmd(LC_SUB_CLIENT);
1327 cmd->set_cmdsize(sz);
1328 cmd->set_client_offset();
1329 strcpy((char*)&p[sizeof(macho_sub_client_command<P>)], client);
1330 return p + sz;
1331}
1332
1333template <typename A>
1334uint8_t* HeaderAndLoadCommandsAtom<A>::copyDyldEnvLoadCommand(uint8_t* p, const char* env) const
1335{
1336 uint32_t sz = alignedSize(sizeof(macho_dylinker_command<P>) + strlen(env) + 1);
1337 macho_dylinker_command<P>* cmd = (macho_dylinker_command<P>*)p;
1338 cmd->set_cmd(LC_DYLD_ENVIRONMENT);
1339 cmd->set_cmdsize(sz);
1340 cmd->set_name_offset();
1341 strcpy((char*)&p[sizeof(macho_dylinker_command<P>)], env);
1342 return p + sz;
1343}
1344
1345template <typename A>
1346uint8_t* HeaderAndLoadCommandsAtom<A>::copySubUmbrellaLoadCommand(uint8_t* p, const char* nm) const
1347{
1348 uint32_t sz = alignedSize(sizeof(macho_sub_umbrella_command<P>) + strlen(nm) + 1);
1349 macho_sub_umbrella_command<P>* cmd = (macho_sub_umbrella_command<P>*)p;
1350 cmd->set_cmd(LC_SUB_UMBRELLA);
1351 cmd->set_cmdsize(sz);
1352 cmd->set_sub_umbrella_offset();
1353 strcpy((char*)&p[sizeof(macho_sub_umbrella_command<P>)], nm);
1354 return p + sz;
1355}
1356
1357template <typename A>
1358uint8_t* HeaderAndLoadCommandsAtom<A>::copySubLibraryLoadCommand(uint8_t* p, const char* nm) const
1359{
1360 uint32_t sz = alignedSize(sizeof(macho_sub_library_command<P>) + strlen(nm) + 1);
1361 macho_sub_library_command<P>* cmd = (macho_sub_library_command<P>*)p;
1362 cmd->set_cmd(LC_SUB_LIBRARY);
1363 cmd->set_cmdsize(sz);
1364 cmd->set_sub_library_offset();
1365 strcpy((char*)&p[sizeof(macho_sub_library_command<P>)], nm);
1366 return p + sz;
1367}
1368
1369template <typename A>
1370uint8_t* HeaderAndLoadCommandsAtom<A>::copyFunctionStartsLoadCommand(uint8_t* p) const
1371{
1372 macho_linkedit_data_command<P>* cmd = (macho_linkedit_data_command<P>*)p;
1373 cmd->set_cmd(LC_FUNCTION_STARTS);
1374 cmd->set_cmdsize(sizeof(macho_linkedit_data_command<P>));
1375 cmd->set_dataoff(_writer.functionStartsSection->fileOffset);
1376 cmd->set_datasize(_writer.functionStartsSection->size);
1377 return p + sizeof(macho_linkedit_data_command<P>);
1378}
1379
1380
ebf6f434
A
1381template <typename A>
1382uint8_t* HeaderAndLoadCommandsAtom<A>::copyDataInCodeLoadCommand(uint8_t* p) const
1383{
1384 macho_linkedit_data_command<P>* cmd = (macho_linkedit_data_command<P>*)p;
1385 cmd->set_cmd(LC_DATA_IN_CODE);
1386 cmd->set_cmdsize(sizeof(macho_linkedit_data_command<P>));
1387 cmd->set_dataoff(_writer.dataInCodeSection->fileOffset);
1388 cmd->set_datasize(_writer.dataInCodeSection->size);
1389 return p + sizeof(macho_linkedit_data_command<P>);
1390}
1391
1392
f80fe69f
A
1393template <typename A>
1394uint8_t* HeaderAndLoadCommandsAtom<A>::copyLinkerOptionsLoadCommand(uint8_t* p, const std::vector<const char*>& options) const
1395{
1396 macho_linker_option_command<P>* cmd = (macho_linker_option_command<P>*)p;
1397 cmd->set_cmd(LC_LINKER_OPTION);
1398 cmd->set_count(options.size());
1399 char* buffer = cmd->buffer();
1400 uint32_t sz = sizeof(macho_linker_option_command<P>);
1401 for (std::vector<const char*>::const_iterator it=options.begin(); it != options.end(); ++it) {
1402 const char* opt = *it;
1403 uint32_t len = strlen(opt);
1404 strcpy(buffer, opt);
1405 sz += (len + 1);
1406 buffer += (len + 1);
1407 }
1408 sz = alignedSize(sz);
1409 cmd->set_cmdsize(sz);
1410 return p + sz;
1411}
1412
1413
ebf6f434
A
1414template <typename A>
1415uint8_t* HeaderAndLoadCommandsAtom<A>::copyDependentDRLoadCommand(uint8_t* p) const
1416{
1417 macho_linkedit_data_command<P>* cmd = (macho_linkedit_data_command<P>*)p;
1418 cmd->set_cmd(LC_DYLIB_CODE_SIGN_DRS);
1419 cmd->set_cmdsize(sizeof(macho_linkedit_data_command<P>));
1420 cmd->set_dataoff(_writer.dependentDRsSection->fileOffset);
1421 cmd->set_datasize(_writer.dependentDRsSection->size);
1422 return p + sizeof(macho_linkedit_data_command<P>);
1423}
1424
1425
9543cb2f
A
1426
1427template <typename A>
1428uint8_t* HeaderAndLoadCommandsAtom<A>::copyOptimizationHintsLoadCommand(uint8_t* p) const
1429{
1430 macho_linkedit_data_command<P>* cmd = (macho_linkedit_data_command<P>*)p;
1431 cmd->set_cmd(LC_LINKER_OPTIMIZATION_HINTS);
1432 cmd->set_cmdsize(sizeof(macho_linkedit_data_command<P>));
1433 cmd->set_dataoff(_writer.optimizationHintsSection->fileOffset);
1434 cmd->set_datasize(_writer.optimizationHintsSection->size);
1435 return p + sizeof(macho_linkedit_data_command<P>);
1436}
1437
1438
a645023d
A
1439template <typename A>
1440void HeaderAndLoadCommandsAtom<A>::copyRawContent(uint8_t buffer[]) const
1441{
1442 macho_header<P>* mh = (macho_header<P>*)buffer;
1443 bzero(buffer, this->size());
1444
1445 // copy mach_header
1446 mh->set_magic(this->magic());
1447 mh->set_cputype(this->cpuType());
1448 mh->set_cpusubtype(this->cpuSubType());
1449 mh->set_filetype(this->fileType());
1450 mh->set_ncmds(this->commandsCount());
1451 mh->set_sizeofcmds(this->size()-sizeof(macho_header<P>));
1452 mh->set_flags(this->flags());
1453
1454 // copy load commands
1455 uint8_t* p = &buffer[sizeof(macho_header<P>)];
1456
1457 if ( _options.outputKind() == Options::kObjectFile )
1458 p = this->copySingleSegmentLoadCommand(p);
1459 else
1460 p = this->copySegmentLoadCommands(p);
1461
1462 if ( _hasDylibIDLoadCommand )
1463 p = this->copyDylibIDLoadCommand(p);
1464
1465 if ( _hasDyldInfoLoadCommand )
1466 p = this->copyDyldInfoLoadCommand(p);
1467
1468 if ( _hasSymbolTableLoadCommand )
1469 p = this->copySymbolTableLoadCommand(p);
1470
1471 if ( _hasDynamicSymbolTableLoadCommand )
1472 p = this->copyDynamicSymbolTableLoadCommand(p);
1473
1474 if ( _hasDyldLoadCommand )
1475 p = this->copyDyldLoadCommand(p);
1476
1477 if ( _hasRoutinesLoadCommand )
1478 p = this->copyRoutinesLoadCommand(p);
1479
1480 if ( _hasUUIDLoadCommand )
1481 p = this->copyUUIDLoadCommand(p);
1482
1483 if ( _hasVersionLoadCommand )
1484 p = this->copyVersionLoadCommand(p);
1485
ebf6f434
A
1486 if ( _hasSourceVersionLoadCommand )
1487 p = this->copySourceVersionLoadCommand(p);
1488
a645023d
A
1489 if ( _hasThreadLoadCommand )
1490 p = this->copyThreadsLoadCommand(p);
ebf6f434
A
1491
1492 if ( _hasEntryPointLoadCommand )
1493 p = this->copyEntryPointLoadCommand(p);
a645023d
A
1494
1495 if ( _hasEncryptionLoadCommand )
1496 p = this->copyEncryptionLoadCommand(p);
1497
1498 if ( _hasSplitSegInfoLoadCommand )
1499 p = this->copySplitSegInfoLoadCommand(p);
1500
f80fe69f 1501 for (uint32_t ord=1; ord <= _writer.dylibCount(); ++ord) {
a645023d
A
1502 p = this->copyDylibLoadCommand(p, _writer.dylibByOrdinal(ord));
1503 }
1504
1505 if ( _hasRPathLoadCommands ) {
1506 const std::vector<const char*>& rpaths = _options.rpaths();
1507 for (std::vector<const char*>::const_iterator it = rpaths.begin(); it != rpaths.end(); ++it) {
1508 p = this->copyRPathLoadCommand(p, *it);
1509 }
1510 }
1511
1512 if ( _hasSubFrameworkLoadCommand )
1513 p = this->copySubFrameworkLoadCommand(p);
1514
1515 for (std::vector<const char*>::const_iterator it = _subLibraryNames.begin(); it != _subLibraryNames.end(); ++it) {
1516 p = this->copySubLibraryLoadCommand(p, *it);
1517 }
1518
1519 for (std::vector<const char*>::const_iterator it = _subUmbrellaNames.begin(); it != _subUmbrellaNames.end(); ++it) {
1520 p = this->copySubUmbrellaLoadCommand(p, *it);
1521 }
1522
1523 if ( _allowableClientLoadCommmandsCount != 0 ) {
1524 const std::vector<const char*>& clients = _options.allowableClients();
1525 for (std::vector<const char*>::const_iterator it = clients.begin(); it != clients.end(); ++it) {
1526 p = this->copyAllowableClientLoadCommand(p, *it);
1527 }
1528 }
1529
1530 if ( _dyldEnvironExrasCount != 0 ) {
1531 const std::vector<const char*>& extras = _options.dyldEnvironExtras();
1532 for (std::vector<const char*>::const_iterator it = extras.begin(); it != extras.end(); ++it) {
1533 p = this->copyDyldEnvLoadCommand(p, *it);
1534 }
1535 }
1536
1537 if ( _hasFunctionStartsLoadCommand )
1538 p = this->copyFunctionStartsLoadCommand(p);
ebf6f434
A
1539
1540 if ( _hasDataInCodeLoadCommand )
1541 p = this->copyDataInCodeLoadCommand(p);
f80fe69f
A
1542
1543 if ( !_linkerOptions.empty() ) {
1544 for (ld::relocatable::File::LinkerOptionsList::const_iterator it = _linkerOptions.begin(); it != _linkerOptions.end(); ++it) {
1545 p = this->copyLinkerOptionsLoadCommand(p, *it);
1546 }
1547 }
ebf6f434
A
1548
1549 if ( _hasDependentDRInfo )
1550 p = this->copyDependentDRLoadCommand(p);
1551
9543cb2f
A
1552 if ( _hasOptimizationHints )
1553 p = this->copyOptimizationHintsLoadCommand(p);
1554
a645023d
A
1555}
1556
1557
1558
1559} // namespace tool
1560} // namespace ld
1561
1562#endif // __HEADER_LOAD_COMMANDS_HPP__