]> git.saurik.com Git - apple/ld64.git/blame - src/ld/ld.cpp
ld64-241.9.tar.gz
[apple/ld64.git] / src / ld / ld.cpp
CommitLineData
a61fdf0a 1/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-*
a645023d 2 *
b2fa67a8 3 * Copyright (c) 2005-2011 Apple Inc. All rights reserved.
c2646906
A
4 *
5 * @APPLE_LICENSE_HEADER_START@
d696c285 6 *
c2646906
A
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.
d696c285 13 *
c2646906
A
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.
d696c285 21 *
c2646906
A
22 * @APPLE_LICENSE_HEADER_END@
23 */
2f2f92e4
A
24
25// start temp HACK for cross builds
26extern "C" double log2 ( double );
a645023d 27//#define __MATH__
2f2f92e4
A
28// end temp HACK for cross builds
29
30
c2646906
A
31#include <stdlib.h>
32#include <sys/types.h>
33#include <sys/stat.h>
34#include <sys/mman.h>
d696c285 35#include <sys/sysctl.h>
c2646906 36#include <fcntl.h>
6e880c60 37#include <errno.h>
69a49097 38#include <limits.h>
d696c285 39#include <unistd.h>
a645023d 40#include <execinfo.h>
d696c285
A
41#include <mach/mach_time.h>
42#include <mach/vm_statistics.h>
43#include <mach/mach_init.h>
44#include <mach/mach_host.h>
a61fdf0a 45#include <dlfcn.h>
a645023d
A
46#include <mach-o/dyld.h>
47#include <dlfcn.h>
48#include <AvailabilityMacros.h>
d696c285 49
c2646906 50#include <string>
74cfe461 51#include <map>
c2646906
A
52#include <set>
53#include <string>
54#include <vector>
55#include <list>
56#include <algorithm>
d425e388 57#include <unordered_map>
a645023d 58#include <cxxabi.h>
c2646906
A
59
60#include "Options.h"
61
a645023d
A
62#include "MachOFileAbstraction.hpp"
63#include "Architectures.hpp"
64#include "ld.hpp"
d696c285 65
a645023d
A
66#include "InputFiles.h"
67#include "Resolver.h"
68#include "OutputFile.h"
ebf6f434 69#include "Snapshot.h"
d696c285 70
a645023d
A
71#include "passes/stubs/make_stubs.h"
72#include "passes/dtrace_dof.h"
73#include "passes/got.h"
74#include "passes/tlvp.h"
75#include "passes/huge.h"
76#include "passes/compact_unwind.h"
b2fa67a8 77#include "passes/order.h"
a645023d
A
78#include "passes/branch_island.h"
79#include "passes/branch_shim.h"
80#include "passes/objc.h"
81#include "passes/dylibs.h"
c2646906 82
a645023d
A
83#include "parsers/archive_file.h"
84#include "parsers/macho_relocatable_file.h"
85#include "parsers/macho_dylib_file.h"
86#include "parsers/lto_file.h"
87#include "parsers/opaque_section_file.h"
c2646906 88
c2646906 89
b2fa67a8
A
90struct PerformanceStatistics {
91 uint64_t startTool;
92 uint64_t startInputFileProcessing;
93 uint64_t startResolver;
94 uint64_t startDylibs;
95 uint64_t startPasses;
96 uint64_t startOutput;
97 uint64_t startDone;
98 vm_statistics_data_t vmStart;
99 vm_statistics_data_t vmEnd;
100};
101
102
a645023d 103class InternalState : public ld::Internal
c2646906
A
104{
105public:
b2fa67a8 106 InternalState(const Options& opts) : _options(opts), _atomsOrderedInSections(false) { }
a645023d
A
107 virtual ld::Internal::FinalSection* addAtom(const ld::Atom& atom);
108 virtual ld::Internal::FinalSection* getFinalSection(const ld::Section&);
599556ff 109 ld::Internal::FinalSection* getFinalSection(const char* seg, const char* sect, ld::Section::Type type);
a645023d 110
9543cb2f
A
111 uint64_t assignFileOffsets();
112 void setSectionSizesAndAlignments();
a645023d 113 void sortSections();
b2fa67a8 114 void markAtomsOrdered() { _atomsOrderedInSections = true; }
a645023d 115 virtual ~InternalState() {}
c2646906 116private:
c2646906 117
a645023d
A
118 class FinalSection : public ld::Internal::FinalSection
119 {
120 public:
599556ff 121 FinalSection(const ld::Section& sect, uint32_t sectionsSeen, const Options&);
a645023d 122 static int sectionComparer(const void* l, const void* r);
afe874b1 123 static const ld::Section& outputSection(const ld::Section& sect, bool mergeZeroFill);
9543cb2f 124 static const ld::Section& objectOutputSection(const ld::Section& sect, const Options&);
a645023d
A
125 private:
126 friend class InternalState;
599556ff
A
127 static uint32_t sectionOrder(const ld::Section& sect, uint32_t sectionsSeen, const Options& options);
128 static uint32_t segmentOrder(const ld::Section& sect, const Options& options);
a645023d
A
129 uint32_t _segmentOrder;
130 uint32_t _sectionOrder;
131
132 static std::vector<const char*> _s_segmentsSeen;
133 static ld::Section _s_DATA_data;
134 static ld::Section _s_DATA_const;
135 static ld::Section _s_TEXT_text;
136 static ld::Section _s_TEXT_const;
137 static ld::Section _s_DATA_nl_symbol_ptr;
138 static ld::Section _s_DATA_common;
afe874b1 139 static ld::Section _s_DATA_zerofill;
c2646906 140 };
55e3d2f6 141
9543cb2f
A
142 bool hasZeroForFileOffset(const ld::Section* sect);
143 uint64_t pageAlign(uint64_t addr);
144 uint64_t pageAlign(uint64_t addr, uint64_t pageSize);
55e3d2f6 145
a645023d
A
146 struct SectionHash {
147 size_t operator()(const ld::Section*) const;
148 };
149 struct SectionEquals {
150 bool operator()(const ld::Section* left, const ld::Section* right) const;
151 };
d425e388 152 typedef std::unordered_map<const ld::Section*, FinalSection*, SectionHash, SectionEquals> SectionInToOut;
55e3d2f6 153
d696c285 154
a645023d
A
155 SectionInToOut _sectionInToFinalMap;
156 const Options& _options;
b2fa67a8 157 bool _atomsOrderedInSections;
a645023d 158};
d696c285 159
a645023d
A
160ld::Section InternalState::FinalSection::_s_DATA_data( "__DATA", "__data", ld::Section::typeUnclassified);
161ld::Section InternalState::FinalSection::_s_DATA_const("__DATA", "__const", ld::Section::typeUnclassified);
162ld::Section InternalState::FinalSection::_s_TEXT_text( "__TEXT", "__text", ld::Section::typeCode);
163ld::Section InternalState::FinalSection::_s_TEXT_const("__TEXT", "__const", ld::Section::typeUnclassified);
164ld::Section InternalState::FinalSection::_s_DATA_nl_symbol_ptr("__DATA", "__nl_symbol_ptr", ld::Section::typeNonLazyPointer);
165ld::Section InternalState::FinalSection::_s_DATA_common("__DATA", "__common", ld::Section::typeZeroFill);
afe874b1 166ld::Section InternalState::FinalSection::_s_DATA_zerofill("__DATA", "__zerofill", ld::Section::typeZeroFill);
a645023d 167std::vector<const char*> InternalState::FinalSection::_s_segmentsSeen;
a61fdf0a 168
c2646906 169
a645023d 170size_t InternalState::SectionHash::operator()(const ld::Section* sect) const
c2646906 171{
a645023d 172 size_t hash = 0;
d425e388 173 ld::CStringHash temp;
a645023d
A
174 hash += temp.operator()(sect->segmentName());
175 hash += temp.operator()(sect->sectionName());
176 return hash;
c2646906
A
177}
178
a645023d 179bool InternalState::SectionEquals::operator()(const ld::Section* left, const ld::Section* right) const
c2646906 180{
a645023d 181 return (*left == *right);
c2646906
A
182}
183
d696c285 184
599556ff 185InternalState::FinalSection::FinalSection(const ld::Section& sect, uint32_t sectionsSeen, const Options& opts)
a645023d 186 : ld::Internal::FinalSection(sect),
599556ff
A
187 _segmentOrder(segmentOrder(sect, opts)),
188 _sectionOrder(sectionOrder(sect, sectionsSeen, opts))
a645023d
A
189{
190 //fprintf(stderr, "FinalSection(%s, %s) _segmentOrder=%d, _sectionOrder=%d\n",
191 // this->segmentName(), this->sectionName(), _segmentOrder, _sectionOrder);
c2646906
A
192}
193
afe874b1 194const ld::Section& InternalState::FinalSection::outputSection(const ld::Section& sect, bool mergeZeroFill)
c2646906 195{
a645023d
A
196 // merge sections in final linked image
197 switch ( sect.type() ) {
198 case ld::Section::typeLiteral4:
199 case ld::Section::typeLiteral8:
200 case ld::Section::typeLiteral16:
599556ff
A
201 if ( strcmp(sect.segmentName(), "__TEXT") == 0 )
202 return _s_TEXT_const;
203 break;
a645023d
A
204 case ld::Section::typeUnclassified:
205 if ( strcmp(sect.segmentName(), "__DATA") == 0 ) {
206 if ( strcmp(sect.sectionName(), "__datacoal_nt") == 0 )
207 return _s_DATA_data;
208 if ( strcmp(sect.sectionName(), "__const_coal") == 0 )
209 return _s_DATA_const;
210 }
211 else if ( strcmp(sect.segmentName(), "__TEXT") == 0 ) {
212 if ( strcmp(sect.sectionName(), "__const_coal") == 0 )
213 return _s_TEXT_const;
214 }
69a49097 215 break;
afe874b1
A
216 case ld::Section::typeZeroFill:
217 if ( mergeZeroFill )
218 return _s_DATA_zerofill;
219 break;
a645023d
A
220 case ld::Section::typeCode:
221 if ( strcmp(sect.segmentName(), "__TEXT") == 0 ) {
222 if ( strcmp(sect.sectionName(), "__textcoal_nt") == 0 )
223 return _s_TEXT_text;
224 else if ( strcmp(sect.sectionName(), "__StaticInit") == 0 )
225 return _s_TEXT_text;
226 }
69a49097 227 break;
a645023d
A
228 case ld::Section::typeNonLazyPointer:
229 if ( strcmp(sect.segmentName(), "__DATA") == 0 ) {
230 if ( strcmp(sect.sectionName(), "__nl_symbol_ptr") == 0 )
231 return _s_DATA_nl_symbol_ptr;
232 }
233 else if ( strcmp(sect.segmentName(), "__IMPORT") == 0 ) {
234 if ( strcmp(sect.sectionName(), "__pointers") == 0 )
235 return _s_DATA_nl_symbol_ptr;
c211e7c9 236 }
2f2f92e4 237 break;
a645023d 238 case ld::Section::typeTentativeDefs:
599556ff
A
239 if ( (strcmp(sect.segmentName(), "__DATA") == 0) && (strcmp(sect.sectionName(), "__comm/tent") == 0) ) {
240 if ( mergeZeroFill )
241 return _s_DATA_zerofill;
242 else
243 return _s_DATA_common;
244 }
a645023d
A
245 break;
246 // FIX ME: more
69a49097 247 default:
69a49097 248 break;
d696c285 249 }
a645023d 250 return sect;
c2646906
A
251}
252
9543cb2f 253const ld::Section& InternalState::FinalSection::objectOutputSection(const ld::Section& sect, const Options& options)
69a49097 254{
a645023d 255 // in -r mode the only section that ever changes is __tenative -> __common with -d option
9543cb2f 256 if ( (sect.type() == ld::Section::typeTentativeDefs) && options.makeTentativeDefinitionsReal())
a645023d
A
257 return _s_DATA_common;
258 return sect;
69a49097
A
259}
260
599556ff 261uint32_t InternalState::FinalSection::segmentOrder(const ld::Section& sect, const Options& options)
69a49097 262{
599556ff
A
263 if ( options.outputKind() == Options::kPreload ) {
264 if ( strcmp(sect.segmentName(), "__HEADER") == 0 )
265 return 0;
266 const std::vector<const char*>& order = options.segmentOrder();
267 for (size_t i=0; i != order.size(); ++i) {
268 if ( strcmp(sect.segmentName(), order[i]) == 0 )
269 return i+1;
270 }
271 if ( strcmp(sect.segmentName(), "__TEXT") == 0 )
272 return order.size()+1;
273 if ( strcmp(sect.segmentName(), "__DATA") == 0 )
274 return order.size()+2;
275 }
276 else {
277 if ( strcmp(sect.segmentName(), "__PAGEZERO") == 0 )
278 return 0;
279 if ( strcmp(sect.segmentName(), "__TEXT") == 0 )
280 return 1;
281 // in -r mode, want __DATA last so zerofill sections are at end
282 if ( strcmp(sect.segmentName(), "__DATA") == 0 )
283 return (options.outputKind() == Options::kObjectFile) ? 5 : 2;
284 if ( strcmp(sect.segmentName(), "__OBJC") == 0 )
285 return 3;
286 if ( strcmp(sect.segmentName(), "__IMPORT") == 0 )
287 return 4;
288 }
289 // layout non-standard segments in order seen (+100 to shift beyond standard segments)
a645023d
A
290 for (uint32_t i=0; i < _s_segmentsSeen.size(); ++i) {
291 if ( strcmp(_s_segmentsSeen[i], sect.segmentName()) == 0 )
599556ff 292 return i+100;
a645023d
A
293 }
294 _s_segmentsSeen.push_back(sect.segmentName());
599556ff 295 return _s_segmentsSeen.size()-1+100;
69a49097
A
296}
297
599556ff 298uint32_t InternalState::FinalSection::sectionOrder(const ld::Section& sect, uint32_t sectionsSeen, const Options& options)
d696c285 299{
a645023d
A
300 if ( sect.type() == ld::Section::typeFirstSection )
301 return 0;
302 if ( sect.type() == ld::Section::typeMachHeader )
303 return 1;
304 if ( sect.type() == ld::Section::typeLastSection )
305 return INT_MAX;
599556ff
A
306 const std::vector<const char*>* sectionList = options.sectionOrder(sect.segmentName());
307 if ( (options.outputKind() == Options::kPreload) && (sectionList != NULL) ) {
308 uint32_t count = 10;
309 for (std::vector<const char*>::const_iterator it=sectionList->begin(); it != sectionList->end(); ++it, ++count) {
310 if ( strcmp(*it, sect.sectionName()) == 0 )
311 return count;
312 }
313 }
a645023d
A
314 if ( strcmp(sect.segmentName(), "__TEXT") == 0 ) {
315 switch ( sect.type() ) {
316 case ld::Section::typeCode:
317 // <rdar://problem/8346444> make __text always be first "code" section
318 if ( strcmp(sect.sectionName(), "__text") == 0 )
319 return 10;
320 else
321 return 11;
322 case ld::Section::typeStub:
323 return 12;
324 case ld::Section::typeStubHelper:
325 return 13;
326 case ld::Section::typeLSDA:
327 return INT_MAX-3;
328 case ld::Section::typeUnwindInfo:
329 return INT_MAX-2;
330 case ld::Section::typeCFI:
331 return INT_MAX-1;
332 case ld::Section::typeStubClose:
333 return INT_MAX;
334 default:
335 return sectionsSeen+20;
336 }
337 }
338 else if ( strcmp(sect.segmentName(), "__DATA") == 0 ) {
339 switch ( sect.type() ) {
340 case ld::Section::typeLazyPointerClose:
341 return 8;
342 case ld::Section::typeDyldInfo:
343 return 9;
344 case ld::Section::typeNonLazyPointer:
345 return 10;
346 case ld::Section::typeLazyPointer:
347 return 11;
348 case ld::Section::typeInitializerPointers:
349 return 12;
350 case ld::Section::typeTerminatorPointers:
351 return 13;
352 case ld::Section::typeTLVInitialValues:
353 return INT_MAX-4; // need TLV zero-fill to follow TLV init values
354 case ld::Section::typeTLVZeroFill:
355 return INT_MAX-3;
356 case ld::Section::typeZeroFill:
357 // make sure __huge is always last zerofill section
358 if ( strcmp(sect.sectionName(), "__huge") == 0 )
359 return INT_MAX-1;
360 else
361 return INT_MAX-2;
362 default:
f80fe69f
A
363 // <rdar://problem/14348664> __DATA,__const section should be near __mod_init_func not __data
364 if ( strcmp(sect.sectionName(), "__const") == 0 )
365 return 14;
599556ff
A
366 // <rdar://problem/17125893> Linker should put __cfstring near __const
367 if ( strcmp(sect.sectionName(), "__cfstring") == 0 )
368 return 15;
a645023d 369 // <rdar://problem/7435296> Reorder sections to reduce page faults in object files
f80fe69f 370 else if ( strcmp(sect.sectionName(), "__objc_classlist") == 0 )
a645023d
A
371 return 20;
372 else if ( strcmp(sect.sectionName(), "__objc_nlclslist") == 0 )
373 return 21;
374 else if ( strcmp(sect.sectionName(), "__objc_catlist") == 0 )
375 return 22;
599556ff 376 else if ( strcmp(sect.sectionName(), "__objc_nlcatlist") == 0 )
a645023d 377 return 23;
599556ff 378 else if ( strcmp(sect.sectionName(), "__objc_protolist") == 0 )
a645023d 379 return 24;
599556ff 380 else if ( strcmp(sect.sectionName(), "__objc_imageinfo") == 0 )
a645023d 381 return 25;
599556ff 382 else if ( strcmp(sect.sectionName(), "__objc_const") == 0 )
a645023d 383 return 26;
599556ff 384 else if ( strcmp(sect.sectionName(), "__objc_selrefs") == 0 )
a645023d 385 return 27;
599556ff 386 else if ( strcmp(sect.sectionName(), "__objc_msgrefs") == 0 )
a645023d 387 return 28;
599556ff 388 else if ( strcmp(sect.sectionName(), "__objc_protorefs") == 0 )
a645023d 389 return 29;
599556ff 390 else if ( strcmp(sect.sectionName(), "__objc_classrefs") == 0 )
a645023d 391 return 30;
599556ff 392 else if ( strcmp(sect.sectionName(), "__objc_superrefs") == 0 )
a645023d 393 return 31;
599556ff
A
394 else if ( strcmp(sect.sectionName(), "__objc_ivar") == 0 )
395 return 32;
396 else if ( strcmp(sect.sectionName(), "__objc_data") == 0 )
397 return 33;
a645023d
A
398 else
399 return sectionsSeen+40;
400 }
401 }
402 // make sure zerofill in any other section is at end of segment
403 if ( sect.type() == ld::Section::typeZeroFill )
404 return INT_MAX-1;
405 return sectionsSeen+20;
406}
407
408#ifndef NDEBUG
409static void validateFixups(const ld::Atom& atom)
410{
411 //fprintf(stderr, "validateFixups %s\n", atom.name());
412 bool lastWasClusterEnd = true;
413 ld::Fixup::Cluster lastClusterSize = ld::Fixup::k1of1;
414 uint32_t curClusterOffsetInAtom = 0;
415 for (ld::Fixup::iterator fit=atom.fixupsBegin(); fit != atom.fixupsEnd(); ++fit) {
416 //fprintf(stderr, " fixup offset=%d, cluster=%d\n", fit->offsetInAtom, fit->clusterSize);
b1f7435d 417 assert((fit->offsetInAtom <= atom.size()) || (fit->offsetInAtom == 0));
a645023d
A
418 if ( fit->firstInCluster() ) {
419 assert(lastWasClusterEnd);
420 curClusterOffsetInAtom = fit->offsetInAtom;
421 lastWasClusterEnd = (fit->clusterSize == ld::Fixup::k1of1);
422 }
423 else {
424 assert(!lastWasClusterEnd);
425 assert(fit->offsetInAtom == curClusterOffsetInAtom);
426 switch ((ld::Fixup::Cluster)fit->clusterSize) {
427 case ld::Fixup::k1of1:
428 case ld::Fixup::k1of2:
429 case ld::Fixup::k1of3:
430 case ld::Fixup::k1of4:
431 case ld::Fixup::k1of5:
432 lastWasClusterEnd = false;
433 break;
434 case ld::Fixup::k2of2:
435 assert(lastClusterSize = ld::Fixup::k1of2);
436 lastWasClusterEnd = true;
437 break;
438 case ld::Fixup::k2of3:
439 assert(lastClusterSize = ld::Fixup::k1of3);
440 lastWasClusterEnd = false;
441 break;
442 case ld::Fixup::k2of4:
443 assert(lastClusterSize = ld::Fixup::k1of4);
444 lastWasClusterEnd = false;
445 break;
446 case ld::Fixup::k2of5:
447 assert(lastClusterSize = ld::Fixup::k1of5);
448 lastWasClusterEnd = false;
449 break;
450 case ld::Fixup::k3of3:
451 assert(lastClusterSize = ld::Fixup::k2of3);
452 lastWasClusterEnd = true;
453 break;
454 case ld::Fixup::k3of4:
455 assert(lastClusterSize = ld::Fixup::k2of4);
456 lastWasClusterEnd = false;
457 break;
458 case ld::Fixup::k3of5:
459 assert(lastClusterSize = ld::Fixup::k2of5);
460 lastWasClusterEnd = false;
461 break;
462 case ld::Fixup::k4of4:
463 assert(lastClusterSize = ld::Fixup::k3of4);
464 lastWasClusterEnd = true;
465 break;
466 case ld::Fixup::k4of5:
467 assert(lastClusterSize = ld::Fixup::k3of5);
468 lastWasClusterEnd = false;
469 break;
470 case ld::Fixup::k5of5:
471 assert(lastClusterSize = ld::Fixup::k4of5);
472 lastWasClusterEnd = true;
473 break;
d696c285
A
474 }
475 }
a645023d
A
476 lastClusterSize = fit->clusterSize;
477 if ( fit->binding == ld::Fixup::bindingDirectlyBound ) {
478 assert(fit->u.target != NULL);
479 }
d696c285 480 }
a645023d
A
481 switch (lastClusterSize) {
482 case ld::Fixup::k1of1:
483 case ld::Fixup::k2of2:
484 case ld::Fixup::k3of3:
485 case ld::Fixup::k4of4:
486 case ld::Fixup::k5of5:
487 break;
488 default:
489 assert(0 && "last fixup was not end of cluster");
490 break;
69a49097
A
491 }
492}
a645023d 493#endif
69a49097 494
a645023d
A
495ld::Internal::FinalSection* InternalState::addAtom(const ld::Atom& atom)
496{
599556ff
A
497 ld::Internal::FinalSection* fs = NULL;
498 const char* sectName = atom.section().sectionName();
499 ld::Section::Type sectType = atom.section().type();
500 const ld::File* f = atom.file();
501 const char* path = (f != NULL) ? f->path() : NULL;
502 if ( atom.section().type() == ld::Section::typeTentativeDefs ) {
503 // tentative defintions don't have a real section name yet
504 sectType = ld::Section::typeZeroFill;
505 if ( _options.mergeZeroFill() )
506 sectName = FinalSection::_s_DATA_zerofill.sectionName();
507 else
508 sectName = FinalSection::_s_DATA_common.sectionName();
509 }
510 // Support for -move_to_r._segment
511 if ( atom.symbolTableInclusion() == ld::Atom::symbolTableIn ) {
512 const char* dstSeg;
513 //fprintf(stderr, "%s\n", atom.name());
514 bool wildCardMatch;
515 if ( _options.moveRwSymbol(atom.name(), path, dstSeg, wildCardMatch) ) {
516 if ( (sectType != ld::Section::typeZeroFill)
517 && (sectType != ld::Section::typeUnclassified)
518 && (sectType != ld::Section::typeTentativeDefs) ) {
519 if ( !wildCardMatch )
520 warning("cannot move symbol '%s' from file %s to segment '%s' because symbol is not data (is %d)", atom.name(), path, dstSeg, sectType);
521 }
522 else {
523 if ( _options.traceSymbolLayout() )
524 printf("symbol '%s', -move_to_rw_segment mapped it to %s/%s\n", atom.name(), dstSeg, sectName);
525 fs = this->getFinalSection(dstSeg, sectName, sectType);
526 }
527 }
528 if ( (fs == NULL) && _options.moveRoSymbol(atom.name(), path, dstSeg, wildCardMatch) ) {
529 if ( atom.section().type() != ld::Section::typeCode ) {
530 if ( !wildCardMatch )
531 warning("cannot move symbol '%s' from file %s to segment '%s' because symbol is not code (is %d)", atom.name(), path, dstSeg, sectType);
532 }
533 else {
534 if ( _options.traceSymbolLayout() )
535 printf("symbol '%s', -move_to_ro_segment mapped it to %s/%s\n", atom.name(), dstSeg, sectName);
536 fs = this->getFinalSection(dstSeg, sectName, ld::Section::typeCode);
537 }
538 }
539 }
540 // support for -rename_section and -rename_segment
541 if ( fs == NULL ) {
542 const std::vector<Options::SectionRename>& sectRenames = _options.sectionRenames();
543 const std::vector<Options::SegmentRename>& segRenames = _options.segmentRenames();
544 for ( std::vector<Options::SectionRename>::const_iterator it=sectRenames.begin(); it != sectRenames.end(); ++it) {
545 if ( (strcmp(sectName, it->fromSection) == 0) && (strcmp(atom.section().segmentName(), it->fromSegment) == 0) ) {
546 if ( _options.traceSymbolLayout() )
547 printf("symbol '%s', -rename_section mapped it to %s/%s\n", atom.name(), it->toSegment, it->toSection);
548 fs = this->getFinalSection(it->toSegment, it->toSection, sectType);
549 }
550 }
551 if ( fs == NULL ) {
552 for ( std::vector<Options::SegmentRename>::const_iterator it=segRenames.begin(); it != segRenames.end(); ++it) {
553 if ( strcmp(atom.section().segmentName(), it->fromSegment) == 0 ) {
554 if ( _options.traceSymbolLayout() )
555 printf("symbol '%s', -rename_segment mapped it to %s/%s\n", atom.name(), it->toSegment, sectName);
556 fs = this->getFinalSection(it->toSegment, sectName, sectType);
557 }
558 }
559 }
560 }
561
562
563 // if no override, use default location
564 if ( fs == NULL ) {
565 fs = this->getFinalSection(atom.section());
566 if ( _options.traceSymbolLayout() && (atom.symbolTableInclusion() == ld::Atom::symbolTableIn) )
567 printf("symbol '%s', use default mapping to %s/%s\n", atom.name(), fs->segmentName(), fs->sectionName());
568 }
569
a645023d
A
570 //fprintf(stderr, "InternalState::doAtom(%p), name=%s, sect=%s, finalsect=%p\n", &atom, atom.name(), atom.section().sectionName(), fs);
571#ifndef NDEBUG
572 validateFixups(atom);
573#endif
b2fa67a8
A
574 if ( _atomsOrderedInSections ) {
575 // make sure this atom is placed before any trailing section$end$ atom
576 if ( (fs->atoms.size() > 1) && (fs->atoms.back()->contentType() == ld::Atom::typeSectionEnd) ) {
577 // last atom in section$end$ atom, insert before it
578 const ld::Atom* endAtom = fs->atoms.back();
579 fs->atoms.pop_back();
580 fs->atoms.push_back(&atom);
581 fs->atoms.push_back(endAtom);
582 }
583 else {
584 // not end atom, just append new atom
585 fs->atoms.push_back(&atom);
586 }
587 }
588 else {
589 // normal case
590 fs->atoms.push_back(&atom);
591 }
a645023d 592 return fs;
55e3d2f6 593}
2f2f92e4 594
599556ff
A
595
596
597ld::Internal::FinalSection* InternalState::getFinalSection(const char* seg, const char* sect, ld::Section::Type type)
598{
599 for (std::vector<ld::Internal::FinalSection*>::iterator it=sections.begin(); it != sections.end(); ++it) {
600 if ( (strcmp((*it)->segmentName(),seg) == 0) && (strcmp((*it)->sectionName(),sect) == 0) )
601 return *it;
602 }
603 return this->getFinalSection(*new ld::Section(seg, sect, type, false));
604}
605
a645023d
A
606ld::Internal::FinalSection* InternalState::getFinalSection(const ld::Section& inputSection)
607{
608 const ld::Section* baseForFinalSection = &inputSection;
609
610 // see if input section already has a FinalSection
611 SectionInToOut::iterator pos = _sectionInToFinalMap.find(&inputSection);
612 if ( pos != _sectionInToFinalMap.end() ) {
613 return pos->second;
614 }
55e3d2f6 615
a645023d 616 // otherwise, create a new final section
a645023d
A
617 switch ( _options.outputKind() ) {
618 case Options::kStaticExecutable:
619 case Options::kDynamicExecutable:
620 case Options::kDynamicLibrary:
621 case Options::kDynamicBundle:
622 case Options::kDyld:
623 case Options::kKextBundle:
624 case Options::kPreload:
625 {
626 // coalesce some sections
afe874b1 627 const ld::Section& outSect = FinalSection::outputSection(inputSection, _options.mergeZeroFill());
a645023d
A
628 pos = _sectionInToFinalMap.find(&outSect);
629 if ( pos != _sectionInToFinalMap.end() ) {
630 _sectionInToFinalMap[&inputSection] = pos->second;
631 //fprintf(stderr, "_sectionInToFinalMap[%p] = %p\n", &inputSection, pos->second);
632 return pos->second;
55e3d2f6 633 }
a645023d
A
634 else if ( outSect != inputSection ) {
635 // new output section created, but not in map
636 baseForFinalSection = &outSect;
55e3d2f6
A
637 }
638 }
a645023d
A
639 break;
640 case Options::kObjectFile:
9543cb2f 641 baseForFinalSection = &FinalSection::objectOutputSection(inputSection, _options);
a645023d
A
642 pos = _sectionInToFinalMap.find(baseForFinalSection);
643 if ( pos != _sectionInToFinalMap.end() ) {
644 _sectionInToFinalMap[&inputSection] = pos->second;
645 //fprintf(stderr, "_sectionInToFinalMap[%p] = %p\n", &inputSection, pos->second);
646 return pos->second;
55e3d2f6 647 }
a645023d 648 break;
2f2f92e4 649 }
d696c285 650
a645023d 651 InternalState::FinalSection* result = new InternalState::FinalSection(*baseForFinalSection,
599556ff 652 _sectionInToFinalMap.size(), _options);
a645023d 653 _sectionInToFinalMap[baseForFinalSection] = result;
599556ff 654 //fprintf(stderr, "_sectionInToFinalMap[%p(%s)] = %p\n", baseForFinalSection, baseForFinalSection->sectionName(), result);
a645023d
A
655 sections.push_back(result);
656 return result;
d696c285
A
657}
658
a645023d
A
659
660int InternalState::FinalSection::sectionComparer(const void* l, const void* r)
d696c285 661{
a645023d
A
662 const FinalSection* left = *(FinalSection**)l;
663 const FinalSection* right = *(FinalSection**)r;
664 if ( left->_segmentOrder != right->_segmentOrder )
665 return (left->_segmentOrder - right->_segmentOrder);
666 return (left->_sectionOrder - right->_sectionOrder);
d696c285
A
667}
668
a645023d 669void InternalState::sortSections()
d696c285 670{
a645023d
A
671 //fprintf(stderr, "UNSORTED final sections:\n");
672 //for (std::vector<ld::Internal::FinalSection*>::iterator it = sections.begin(); it != sections.end(); ++it) {
673 // fprintf(stderr, "final section %p %s/%s\n", (*it), (*it)->segmentName(), (*it)->sectionName());
674 //}
675 qsort(&sections[0], sections.size(), sizeof(FinalSection*), &InternalState::FinalSection::sectionComparer);
676 //fprintf(stderr, "SORTED final sections:\n");
677 //for (std::vector<ld::Internal::FinalSection*>::iterator it = sections.begin(); it != sections.end(); ++it) {
678 // fprintf(stderr, "final section %p %s/%s\n", (*it), (*it)->segmentName(), (*it)->sectionName());
679 //}
680 assert((sections[0]->type() == ld::Section::typeMachHeader)
681 || ((sections[0]->type() == ld::Section::typeFirstSection) && (sections[1]->type() == ld::Section::typeMachHeader))
682 || ((sections[0]->type() == ld::Section::typePageZero) && (sections[1]->type() == ld::Section::typeMachHeader))
683 || ((sections[0]->type() == ld::Section::typePageZero) && (sections[1]->type() == ld::Section::typeFirstSection) && (sections[2]->type() == ld::Section::typeMachHeader)) );
684
d696c285
A
685}
686
9543cb2f
A
687
688bool InternalState::hasZeroForFileOffset(const ld::Section* sect)
689{
690 switch ( sect->type() ) {
691 case ld::Section::typeZeroFill:
692 case ld::Section::typeTLVZeroFill:
693 return _options.optimizeZeroFill();
694 case ld::Section::typePageZero:
695 case ld::Section::typeStack:
696 case ld::Section::typeTentativeDefs:
697 return true;
698 default:
699 break;
700 }
701 return false;
702}
703
704uint64_t InternalState::pageAlign(uint64_t addr)
705{
706 const uint64_t alignment = _options.segmentAlignment();
707 return ((addr+alignment-1) & (-alignment));
708}
709
710uint64_t InternalState::pageAlign(uint64_t addr, uint64_t pageSize)
711{
712 return ((addr+pageSize-1) & (-pageSize));
713}
714
715void InternalState::setSectionSizesAndAlignments()
716{
717 for (std::vector<ld::Internal::FinalSection*>::iterator sit = sections.begin(); sit != sections.end(); ++sit) {
718 ld::Internal::FinalSection* sect = *sit;
719 if ( sect->type() == ld::Section::typeAbsoluteSymbols ) {
720 // absolute symbols need their finalAddress() to their value
721 for (std::vector<const ld::Atom*>::iterator ait = sect->atoms.begin(); ait != sect->atoms.end(); ++ait) {
722 const ld::Atom* atom = *ait;
723 (const_cast<ld::Atom*>(atom))->setSectionOffset(atom->objectAddress());
724 }
725 }
726 else {
727 uint16_t maxAlignment = 0;
728 uint64_t offset = 0;
729 for (std::vector<const ld::Atom*>::iterator ait = sect->atoms.begin(); ait != sect->atoms.end(); ++ait) {
730 const ld::Atom* atom = *ait;
731 bool pagePerAtom = false;
732 uint32_t atomAlignmentPowerOf2 = atom->alignment().powerOf2;
733 uint32_t atomModulus = atom->alignment().modulus;
734 if ( _options.pageAlignDataAtoms() && ( strcmp(atom->section().segmentName(), "__DATA") == 0) ) {
735 // most objc sections cannot be padded
736 bool contiguousObjCSection = ( strncmp(atom->section().sectionName(), "__objc_", 7) == 0 );
737 if ( strcmp(atom->section().sectionName(), "__objc_const") == 0 )
738 contiguousObjCSection = false;
739 if ( strcmp(atom->section().sectionName(), "__objc_data") == 0 )
740 contiguousObjCSection = false;
741 switch ( atom->section().type() ) {
742 case ld::Section::typeUnclassified:
743 case ld::Section::typeTentativeDefs:
744 case ld::Section::typeZeroFill:
745 if ( contiguousObjCSection )
746 break;
747 pagePerAtom = true;
748 if ( atomAlignmentPowerOf2 < 12 ) {
749 atomAlignmentPowerOf2 = 12;
750 atomModulus = 0;
751 }
752 break;
753 default:
754 break;
755 }
756 }
757 if ( atomAlignmentPowerOf2 > maxAlignment )
758 maxAlignment = atomAlignmentPowerOf2;
759 // calculate section offset for this atom
760 uint64_t alignment = 1 << atomAlignmentPowerOf2;
761 uint64_t currentModulus = (offset % alignment);
762 uint64_t requiredModulus = atomModulus;
763 if ( currentModulus != requiredModulus ) {
764 if ( requiredModulus > currentModulus )
765 offset += requiredModulus-currentModulus;
766 else
767 offset += requiredModulus+alignment-currentModulus;
768 }
769 // LINKEDIT atoms are laid out later
770 if ( sect->type() != ld::Section::typeLinkEdit ) {
771 (const_cast<ld::Atom*>(atom))->setSectionOffset(offset);
772 offset += atom->size();
773 if ( pagePerAtom ) {
774 offset = (offset + 4095) & (-4096); // round up to end of page
775 }
776 }
777 if ( (atom->scope() == ld::Atom::scopeGlobal)
778 && (atom->definition() == ld::Atom::definitionRegular)
779 && (atom->combine() == ld::Atom::combineByName)
780 && ((atom->symbolTableInclusion() == ld::Atom::symbolTableIn)
781 || (atom->symbolTableInclusion() == ld::Atom::symbolTableInAndNeverStrip)) ) {
782 this->hasWeakExternalSymbols = true;
783 if ( _options.warnWeakExports() )
784 warning("weak external symbol: %s", atom->name());
785 }
786 }
787 sect->size = offset;
788 // section alignment is that of a contained atom with the greatest alignment
789 sect->alignment = maxAlignment;
790 // unless -sectalign command line option overrides
791 if ( _options.hasCustomSectionAlignment(sect->segmentName(), sect->sectionName()) )
792 sect->alignment = _options.customSectionAlignment(sect->segmentName(), sect->sectionName());
793 // each atom in __eh_frame has zero alignment to assure they pack together,
794 // but compilers usually make the CFIs pointer sized, so we want whole section
795 // to start on pointer sized boundary.
796 if ( sect->type() == ld::Section::typeCFI )
797 sect->alignment = 3;
798 if ( sect->type() == ld::Section::typeTLVDefs )
799 this->hasThreadLocalVariableDefinitions = true;
800 }
801 }
802}
803
804uint64_t InternalState::assignFileOffsets()
805{
806 const bool log = false;
807 const bool hiddenSectionsOccupyAddressSpace = ((_options.outputKind() != Options::kObjectFile)
808 && (_options.outputKind() != Options::kPreload));
809 const bool segmentsArePageAligned = (_options.outputKind() != Options::kObjectFile);
810
811 uint64_t address = 0;
812 const char* lastSegName = "";
813 uint64_t floatingAddressStart = _options.baseAddress();
814
815 // first pass, assign addresses to sections in segments with fixed start addresses
816 if ( log ) fprintf(stderr, "Fixed address segments:\n");
817 for (std::vector<ld::Internal::FinalSection*>::iterator it = sections.begin(); it != sections.end(); ++it) {
818 ld::Internal::FinalSection* sect = *it;
819 if ( ! _options.hasCustomSegmentAddress(sect->segmentName()) )
820 continue;
821 if ( segmentsArePageAligned ) {
822 if ( strcmp(lastSegName, sect->segmentName()) != 0 ) {
823 address = _options.customSegmentAddress(sect->segmentName());
824 lastSegName = sect->segmentName();
825 }
826 }
827 // adjust section address based on alignment
828 uint64_t unalignedAddress = address;
829 uint64_t alignment = (1 << sect->alignment);
830 address = ( (unalignedAddress+alignment-1) & (-alignment) );
831
832 // update section info
833 sect->address = address;
834 sect->alignmentPaddingBytes = (address - unalignedAddress);
835
836 // sanity check size
837 if ( ((address + sect->size) > _options.maxAddress()) && (_options.outputKind() != Options::kObjectFile)
838 && (_options.outputKind() != Options::kStaticExecutable) )
839 throwf("section %s (address=0x%08llX, size=%llu) would make the output executable exceed available address range",
840 sect->sectionName(), address, sect->size);
841
842 if ( log ) fprintf(stderr, " address=0x%08llX, hidden=%d, alignment=%02d, section=%s,%s\n",
843 sect->address, sect->isSectionHidden(), sect->alignment, sect->segmentName(), sect->sectionName());
844 // update running totals
845 if ( !sect->isSectionHidden() || hiddenSectionsOccupyAddressSpace )
846 address += sect->size;
847
848 // if TEXT segment address is fixed, then flow other segments after it
849 if ( strcmp(sect->segmentName(), "__TEXT") == 0 ) {
850 floatingAddressStart = address;
851 }
852 }
853
854 // second pass, assign section address to sections in segments that are contiguous with previous segment
855 address = floatingAddressStart;
856 lastSegName = "";
857 ld::Internal::FinalSection* overlappingFixedSection = NULL;
858 ld::Internal::FinalSection* overlappingFlowSection = NULL;
859 if ( log ) fprintf(stderr, "Regular layout segments:\n");
860 for (std::vector<ld::Internal::FinalSection*>::iterator it = sections.begin(); it != sections.end(); ++it) {
861 ld::Internal::FinalSection* sect = *it;
862 if ( _options.hasCustomSegmentAddress(sect->segmentName()) )
863 continue;
864 if ( (_options.outputKind() == Options::kPreload) && (sect->type() == ld::Section::typeMachHeader) ) {
865 sect->alignmentPaddingBytes = 0;
866 continue;
867 }
868 if ( segmentsArePageAligned ) {
869 if ( strcmp(lastSegName, sect->segmentName()) != 0 ) {
870 // round up size of last segment if needed
871 if ( *lastSegName != '\0' ) {
872 address = pageAlign(address, _options.segPageSize(lastSegName));
873 }
874 // set segment address based on end of last segment
875 address = pageAlign(address);
876 lastSegName = sect->segmentName();
877 }
878 }
879 // adjust section address based on alignment
880 uint64_t unalignedAddress = address;
881 uint64_t alignment = (1 << sect->alignment);
882 address = ( (unalignedAddress+alignment-1) & (-alignment) );
883
884 // update section info
885 sect->address = address;
886 sect->alignmentPaddingBytes = (address - unalignedAddress);
887
888 // sanity check size
889 if ( ((address + sect->size) > _options.maxAddress()) && (_options.outputKind() != Options::kObjectFile)
890 && (_options.outputKind() != Options::kStaticExecutable) )
891 throwf("section %s (address=0x%08llX, size=%llu) would make the output executable exceed available address range",
892 sect->sectionName(), address, sect->size);
893
894 // sanity check it does not overlap a fixed address segment
895 for (std::vector<ld::Internal::FinalSection*>::iterator sit = sections.begin(); sit != sections.end(); ++sit) {
896 ld::Internal::FinalSection* otherSect = *sit;
897 if ( ! _options.hasCustomSegmentAddress(otherSect->segmentName()) )
898 continue;
599556ff
A
899 if ( otherSect->size == 0 )
900 continue;
901 if ( sect->size == 0 )
902 continue;
9543cb2f
A
903 if ( sect->address > otherSect->address ) {
904 if ( (otherSect->address+otherSect->size) > sect->address ) {
905 overlappingFixedSection = otherSect;
906 overlappingFlowSection = sect;
907 }
908 }
909 else {
910 if ( (sect->address+sect->size) > otherSect->address ) {
911 overlappingFixedSection = otherSect;
912 overlappingFlowSection = sect;
913 }
914 }
915 }
916
917 if ( log ) fprintf(stderr, " address=0x%08llX, size=0x%08llX, hidden=%d, alignment=%02d, padBytes=%d, section=%s,%s\n",
918 sect->address, sect->size, sect->isSectionHidden(), sect->alignment, sect->alignmentPaddingBytes,
919 sect->segmentName(), sect->sectionName());
920 // update running totals
921 if ( !sect->isSectionHidden() || hiddenSectionsOccupyAddressSpace )
922 address += sect->size;
923 }
924 if ( overlappingFixedSection != NULL ) {
925 fprintf(stderr, "Section layout:\n");
926 for (std::vector<ld::Internal::FinalSection*>::iterator it = sections.begin(); it != sections.end(); ++it) {
927 ld::Internal::FinalSection* sect = *it;
599556ff
A
928 //if ( sect->isSectionHidden() )
929 // continue;
9543cb2f
A
930 fprintf(stderr, " address:0x%08llX, alignment:2^%d, size:0x%08llX, padBytes:%d, section:%s/%s\n",
931 sect->address, sect->alignment, sect->size, sect->alignmentPaddingBytes,
932 sect->segmentName(), sect->sectionName());
933
934 }
935 throwf("Section (%s/%s) overlaps fixed address section (%s/%s)",
936 overlappingFlowSection->segmentName(), overlappingFlowSection->sectionName(),
937 overlappingFixedSection->segmentName(), overlappingFixedSection->sectionName());
938 }
939
940
941 // third pass, assign section file offsets
942 uint64_t fileOffset = 0;
943 lastSegName = "";
944 if ( log ) fprintf(stderr, "All segments with file offsets:\n");
945 for (std::vector<ld::Internal::FinalSection*>::iterator it = sections.begin(); it != sections.end(); ++it) {
946 ld::Internal::FinalSection* sect = *it;
947 if ( hasZeroForFileOffset(sect) ) {
948 // fileoff of zerofill sections is moot, but historically it is set to zero
949 sect->fileOffset = 0;
950
951 // <rdar://problem/10445047> align file offset with address layout
952 fileOffset += sect->alignmentPaddingBytes;
953 }
954 else {
955 // page align file offset at start of each segment
956 if ( segmentsArePageAligned && (*lastSegName != '\0') && (strcmp(lastSegName, sect->segmentName()) != 0) ) {
957 fileOffset = pageAlign(fileOffset, _options.segPageSize(lastSegName));
958 }
959 lastSegName = sect->segmentName();
960
961 // align file offset with address layout
962 fileOffset += sect->alignmentPaddingBytes;
963
964 // update section info
965 sect->fileOffset = fileOffset;
966
967 // update running total
968 fileOffset += sect->size;
969 }
970
971 if ( log ) fprintf(stderr, " fileoffset=0x%08llX, address=0x%08llX, hidden=%d, size=%lld, alignment=%02d, section=%s,%s\n",
972 sect->fileOffset, sect->address, sect->isSectionHidden(), sect->size, sect->alignment,
973 sect->segmentName(), sect->sectionName());
974 }
975
976#if 0
977 // for encrypted iPhoneOS apps
978 if ( _options.makeEncryptable() ) {
979 // remember end of __TEXT for later use by load command
980 for (std::vector<ld::Internal::FinalSection*>::iterator it = state.sections.begin(); it != state.sections.end(); ++it) {
981 ld::Internal::FinalSection* sect = *it;
982 if ( strcmp(sect->segmentName(), "__TEXT") == 0 ) {
983 _encryptedTEXTendOffset = pageAlign(sect->fileOffset + sect->size);
984 }
985 }
986 }
987#endif
988
989 // return total file size
990 return fileOffset;
991}
992
b2fa67a8
A
993static char* commatize(uint64_t in, char* out)
994{
995 char* result = out;
996 char rawNum[30];
997 sprintf(rawNum, "%llu", in);
998 const int rawNumLen = strlen(rawNum);
999 for(int i=0; i < rawNumLen-1; ++i) {
1000 *out++ = rawNum[i];
1001 if ( ((rawNumLen-i) % 3) == 1 )
1002 *out++ = ',';
1003 }
1004 *out++ = rawNum[rawNumLen-1];
1005 *out = '\0';
1006 return result;
1007}
1008
1009static void printTime(const char* msg, uint64_t partTime, uint64_t totalTime)
1010{
1011 static uint64_t sUnitsPerSecond = 0;
1012 if ( sUnitsPerSecond == 0 ) {
1013 struct mach_timebase_info timeBaseInfo;
f80fe69f
A
1014 if ( mach_timebase_info(&timeBaseInfo) != KERN_SUCCESS )
1015 return;
1016 sUnitsPerSecond = 1000000000ULL * timeBaseInfo.denom / timeBaseInfo.numer;
b2fa67a8
A
1017 }
1018 if ( partTime < sUnitsPerSecond ) {
1019 uint32_t milliSecondsTimeTen = (partTime*10000)/sUnitsPerSecond;
1020 uint32_t milliSeconds = milliSecondsTimeTen/10;
1021 uint32_t percentTimesTen = (partTime*1000)/totalTime;
1022 uint32_t percent = percentTimesTen/10;
1023 fprintf(stderr, "%24s: % 4d.%d milliseconds (% 4d.%d%%)\n", msg, milliSeconds, milliSecondsTimeTen-milliSeconds*10, percent, percentTimesTen-percent*10);
1024 }
1025 else {
1026 uint32_t secondsTimeTen = (partTime*10)/sUnitsPerSecond;
1027 uint32_t seconds = secondsTimeTen/10;
1028 uint32_t percentTimesTen = (partTime*1000)/totalTime;
1029 uint32_t percent = percentTimesTen/10;
1030 fprintf(stderr, "%24s: % 4d.%d seconds (% 4d.%d%%)\n", msg, seconds, secondsTimeTen-seconds*10, percent, percentTimesTen-percent*10);
1031 }
1032}
1033
1034
a645023d 1035static void getVMInfo(vm_statistics_data_t& info)
d696c285
A
1036{
1037 mach_msg_type_number_t count = sizeof(vm_statistics_data_t) / sizeof(natural_t);
1038 kern_return_t error = host_statistics(mach_host_self(), HOST_VM_INFO,
1039 (host_info_t)&info, &count);
1040 if (error != KERN_SUCCESS) {
1041 bzero(&info, sizeof(vm_statistics_data_t));
1042 }
1043}
1044
ebf6f434
A
1045
1046
1047static const char* sOverridePathlibLTO = NULL;
1048
1049//
1050// This is magic glue that overrides the default behaviour
1051// of lazydylib1.o which is used to lazily load libLTO.dylib.
1052//
1053extern "C" const char* dyld_lazy_dylib_path_fix(const char* path);
1054const char* dyld_lazy_dylib_path_fix(const char* path)
1055{
1056 if ( sOverridePathlibLTO != NULL )
1057 return sOverridePathlibLTO;
1058 else
1059 return path;
1060}
1061
1062
1063
a645023d 1064int main(int argc, const char* argv[])
d696c285 1065{
a645023d
A
1066 const char* archName = NULL;
1067 bool showArch = false;
1068 bool archInferred = false;
1069 try {
b2fa67a8
A
1070 PerformanceStatistics statistics;
1071 statistics.startTool = mach_absolute_time();
1072
a645023d
A
1073 // create object to track command line arguments
1074 Options options(argc, argv);
b2fa67a8 1075 InternalState state(options);
a645023d 1076
ebf6f434
A
1077 // allow libLTO to be overridden by command line -lto_library
1078 sOverridePathlibLTO = options.overridePathlibLTO();
1079
b2fa67a8 1080 // gather vm stats
a645023d 1081 if ( options.printStatistics() )
b2fa67a8 1082 getVMInfo(statistics.vmStart);
a645023d
A
1083
1084 // update strings for error messages
1085 showArch = options.printArchPrefix();
1086 archName = options.architectureName();
1087 archInferred = (options.architecture() == 0);
1088
1089 // open and parse input files
b2fa67a8 1090 statistics.startInputFileProcessing = mach_absolute_time();
a645023d
A
1091 ld::tool::InputFiles inputFiles(options, &archName);
1092
1093 // load and resolve all references
b2fa67a8 1094 statistics.startResolver = mach_absolute_time();
a645023d
A
1095 ld::tool::Resolver resolver(options, inputFiles, state);
1096 resolver.resolve();
ebf6f434 1097
a645023d 1098 // add dylibs used
b2fa67a8 1099 statistics.startDylibs = mach_absolute_time();
a645023d
A
1100 inputFiles.dylibs(state);
1101
1102 // do initial section sorting so passes have rough idea of the layout
1103 state.sortSections();
1104
1105 // run passes
b2fa67a8 1106 statistics.startPasses = mach_absolute_time();
a645023d
A
1107 ld::passes::objc::doPass(options, state);
1108 ld::passes::stubs::doPass(options, state);
1109 ld::passes::huge::doPass(options, state);
1110 ld::passes::got::doPass(options, state);
1111 ld::passes::tlvp::doPass(options, state);
1112 ld::passes::dylibs::doPass(options, state); // must be after stubs and GOT passes
b2fa67a8
A
1113 ld::passes::order::doPass(options, state);
1114 state.markAtomsOrdered();
a645023d 1115 ld::passes::branch_shim::doPass(options, state); // must be after stubs
b2fa67a8 1116 ld::passes::branch_island::doPass(options, state); // must be after stubs and order pass
a645023d 1117 ld::passes::dtrace::doPass(options, state);
b2fa67a8 1118 ld::passes::compact_unwind::doPass(options, state); // must be after order pass
a645023d
A
1119
1120 // sort final sections
1121 state.sortSections();
1122
1123 // write output file
b2fa67a8 1124 statistics.startOutput = mach_absolute_time();
a645023d
A
1125 ld::tool::OutputFile out(options);
1126 out.write(state);
b2fa67a8 1127 statistics.startDone = mach_absolute_time();
a645023d
A
1128
1129 // print statistics
1130 //mach_o::relocatable::printCounts();
1131 if ( options.printStatistics() ) {
b2fa67a8
A
1132 getVMInfo(statistics.vmEnd);
1133 uint64_t totalTime = statistics.startDone - statistics.startTool;
1134 printTime("ld total time", totalTime, totalTime);
1135 printTime(" option parsing time", statistics.startInputFileProcessing - statistics.startTool, totalTime);
1136 printTime(" object file processing", statistics.startResolver - statistics.startInputFileProcessing,totalTime);
1137 printTime(" resolve symbols", statistics.startDylibs - statistics.startResolver, totalTime);
1138 printTime(" build atom list", statistics.startPasses - statistics.startDylibs, totalTime);
1139 printTime(" passess", statistics.startOutput - statistics.startPasses, totalTime);
1140 printTime(" write output", statistics.startDone - statistics.startOutput, totalTime);
1141 fprintf(stderr, "pageins=%u, pageouts=%u, faults=%u\n",
1142 statistics.vmEnd.pageins-statistics.vmStart.pageins,
1143 statistics.vmEnd.pageouts-statistics.vmStart.pageouts,
1144 statistics.vmEnd.faults-statistics.vmStart.faults);
1145 char temp[40];
1146 fprintf(stderr, "processed %3u object files, totaling %15s bytes\n", inputFiles._totalObjectLoaded, commatize(inputFiles._totalObjectSize, temp));
1147 fprintf(stderr, "processed %3u archive files, totaling %15s bytes\n", inputFiles._totalArchivesLoaded, commatize(inputFiles._totalArchiveSize, temp));
1148 fprintf(stderr, "processed %3u dylib files\n", inputFiles._totalDylibsLoaded);
1149 fprintf(stderr, "wrote output file totaling %15s bytes\n", commatize(out.fileSize(), temp));
1150 }
1151 // <rdar://problem/6780050> Would like linker warning to be build error.
1152 if ( options.errorBecauseOfWarnings() ) {
1153 fprintf(stderr, "ld: fatal warning(s) induced error (-fatal_warnings)\n");
1154 return 1;
a645023d
A
1155 }
1156 }
1157 catch (const char* msg) {
1158 if ( archInferred )
1159 fprintf(stderr, "ld: %s for inferred architecture %s\n", msg, archName);
1160 else if ( showArch )
1161 fprintf(stderr, "ld: %s for architecture %s\n", msg, archName);
1162 else
1163 fprintf(stderr, "ld: %s\n", msg);
1164 return 1;
d696c285 1165 }
a645023d
A
1166
1167 return 0;
c2646906
A
1168}
1169
a645023d
A
1170
1171#ifndef NDEBUG
1172// implement assert() function to print out a backtrace before aborting
1173void __assert_rtn(const char* func, const char* file, int line, const char* failedexpr)
c2646906 1174{
ebf6f434
A
1175 Snapshot *snapshot = Snapshot::globalSnapshot;
1176
1177 snapshot->setSnapshotMode(Snapshot::SNAPSHOT_DEBUG);
1178 snapshot->createSnapshot();
1179 snapshot->recordAssertionMessage("Assertion failed: (%s), function %s, file %s, line %d.\n", failedexpr, func, file, line);
d696c285 1180
a645023d
A
1181 void* callStack[128];
1182 int depth = ::backtrace(callStack, 128);
1183 char* buffer = (char*)malloc(1024);
1184 for(int i=0; i < depth-1; ++i) {
1185 Dl_info info;
1186 dladdr(callStack[i], &info);
1187 const char* symboName = info.dli_sname;
1188 if ( (symboName != NULL) && (strncmp(symboName, "_Z", 2) == 0) ) {
1189 size_t bufLen = 1024;
1190 int result;
1191 char* unmangled = abi::__cxa_demangle(symboName, buffer, &bufLen, &result);
1192 if ( unmangled != NULL )
1193 symboName = unmangled;
c2646906 1194 }
a645023d
A
1195 long offset = (uintptr_t)callStack[i] - (uintptr_t)info.dli_saddr;
1196 fprintf(stderr, "%d %p %s + %ld\n", i, callStack[i], symboName, offset);
ebf6f434 1197 snapshot->recordAssertionMessage("%d %p %s + %ld\n", i, callStack[i], symboName, offset);
69a49097 1198 }
ebf6f434
A
1199 fprintf(stderr, "A linker snapshot was created at:\n\t%s\n", snapshot->rootDir());
1200 fprintf(stderr, "ld: Assertion failed: (%s), function %s, file %s, line %d.\n", failedexpr, func, file, line);
a645023d
A
1201 exit(1);
1202}
1203#endif
d696c285 1204
d696c285 1205