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