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