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