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