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