]> git.saurik.com Git - apple/ld64.git/blob - src/ld/ld.cpp
4ef1f146177526c4865791bf44df728cf1e91ba6
[apple/ld64.git] / src / ld / ld.cpp
1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-*
2 *
3 * Copyright (c) 2005-2011 Apple Inc. All rights reserved.
4 *
5 * @APPLE_LICENSE_HEADER_START@
6 *
7 * This file contains Original Code and/or Modifications of Original Code
8 * as defined in and that are subject to the Apple Public Source License
9 * Version 2.0 (the 'License'). You may not use this file except in
10 * compliance with the License. Please obtain a copy of the License at
11 * http://www.opensource.apple.com/apsl/ and read it before using this
12 * file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
19 * Please see the License for the specific language governing rights and
20 * limitations under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24
25 // start temp HACK for cross builds
26 extern "C" double log2 ( double );
27 //#define __MATH__
28 // end temp HACK for cross builds
29
30
31 #include <stdlib.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <sys/mman.h>
35 #include <sys/sysctl.h>
36 #include <fcntl.h>
37 #include <errno.h>
38 #include <limits.h>
39 #include <unistd.h>
40 #include <execinfo.h>
41 #include <mach/mach_time.h>
42 #include <mach/vm_statistics.h>
43 #include <mach/mach_init.h>
44 #include <mach/mach_host.h>
45 #include <dlfcn.h>
46 #include <mach-o/dyld.h>
47 #include <dlfcn.h>
48 #include <AvailabilityMacros.h>
49
50 #include <string>
51 #include <map>
52 #include <set>
53 #include <string>
54 #include <vector>
55 #include <list>
56 #include <algorithm>
57 #include <unordered_map>
58 #include <cxxabi.h>
59
60 #include "Options.h"
61
62 #include "MachOFileAbstraction.hpp"
63 #include "Architectures.hpp"
64 #include "ld.hpp"
65
66 #include "InputFiles.h"
67 #include "Resolver.h"
68 #include "OutputFile.h"
69 #include "Snapshot.h"
70
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"
77 #include "passes/order.h"
78 #include "passes/branch_island.h"
79 #include "passes/branch_shim.h"
80 #include "passes/objc.h"
81 #include "passes/dylibs.h"
82
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"
88
89
90 struct 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
103 class InternalState : public ld::Internal
104 {
105 public:
106 InternalState(const Options& opts) : _options(opts), _atomsOrderedInSections(false) { }
107 virtual ld::Internal::FinalSection* addAtom(const ld::Atom& atom);
108 virtual ld::Internal::FinalSection* getFinalSection(const ld::Section&);
109 ld::Internal::FinalSection* getFinalSection(const char* seg, const char* sect, ld::Section::Type type);
110
111 uint64_t assignFileOffsets();
112 void setSectionSizesAndAlignments();
113 void sortSections();
114 void markAtomsOrdered() { _atomsOrderedInSections = true; }
115 virtual ~InternalState() {}
116 private:
117
118 class FinalSection : public ld::Internal::FinalSection
119 {
120 public:
121 FinalSection(const ld::Section& sect, uint32_t sectionsSeen, const Options&);
122 static int sectionComparer(const void* l, const void* r);
123 static const ld::Section& outputSection(const ld::Section& sect, bool mergeZeroFill);
124 static const ld::Section& objectOutputSection(const ld::Section& sect, const Options&);
125 private:
126 friend class InternalState;
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);
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;
139 static ld::Section _s_DATA_zerofill;
140 };
141
142 bool hasZeroForFileOffset(const ld::Section* sect);
143 uint64_t pageAlign(uint64_t addr);
144 uint64_t pageAlign(uint64_t addr, uint64_t pageSize);
145
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 };
152 typedef std::unordered_map<const ld::Section*, FinalSection*, SectionHash, SectionEquals> SectionInToOut;
153
154
155 SectionInToOut _sectionInToFinalMap;
156 const Options& _options;
157 bool _atomsOrderedInSections;
158 };
159
160 ld::Section InternalState::FinalSection::_s_DATA_data( "__DATA", "__data", ld::Section::typeUnclassified);
161 ld::Section InternalState::FinalSection::_s_DATA_const("__DATA", "__const", ld::Section::typeUnclassified);
162 ld::Section InternalState::FinalSection::_s_TEXT_text( "__TEXT", "__text", ld::Section::typeCode);
163 ld::Section InternalState::FinalSection::_s_TEXT_const("__TEXT", "__const", ld::Section::typeUnclassified);
164 ld::Section InternalState::FinalSection::_s_DATA_nl_symbol_ptr("__DATA", "__nl_symbol_ptr", ld::Section::typeNonLazyPointer);
165 ld::Section InternalState::FinalSection::_s_DATA_common("__DATA", "__common", ld::Section::typeZeroFill);
166 ld::Section InternalState::FinalSection::_s_DATA_zerofill("__DATA", "__zerofill", ld::Section::typeZeroFill);
167 std::vector<const char*> InternalState::FinalSection::_s_segmentsSeen;
168
169
170 size_t InternalState::SectionHash::operator()(const ld::Section* sect) const
171 {
172 size_t hash = 0;
173 ld::CStringHash temp;
174 hash += temp.operator()(sect->segmentName());
175 hash += temp.operator()(sect->sectionName());
176 return hash;
177 }
178
179 bool InternalState::SectionEquals::operator()(const ld::Section* left, const ld::Section* right) const
180 {
181 return (*left == *right);
182 }
183
184
185 InternalState::FinalSection::FinalSection(const ld::Section& sect, uint32_t sectionsSeen, const Options& opts)
186 : ld::Internal::FinalSection(sect),
187 _segmentOrder(segmentOrder(sect, opts)),
188 _sectionOrder(sectionOrder(sect, sectionsSeen, opts))
189 {
190 //fprintf(stderr, "FinalSection(%s, %s) _segmentOrder=%d, _sectionOrder=%d\n",
191 // this->segmentName(), this->sectionName(), _segmentOrder, _sectionOrder);
192 }
193
194 const ld::Section& InternalState::FinalSection::outputSection(const ld::Section& sect, bool mergeZeroFill)
195 {
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:
201 if ( strcmp(sect.segmentName(), "__TEXT") == 0 )
202 return _s_TEXT_const;
203 break;
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 }
215 break;
216 case ld::Section::typeZeroFill:
217 if ( mergeZeroFill )
218 return _s_DATA_zerofill;
219 break;
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 }
227 break;
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;
236 }
237 break;
238 case ld::Section::typeTentativeDefs:
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 }
245 break;
246 // FIX ME: more
247 default:
248 break;
249 }
250 return sect;
251 }
252
253 const ld::Section& InternalState::FinalSection::objectOutputSection(const ld::Section& sect, const Options& options)
254 {
255 // in -r mode the only section that ever changes is __tenative -> __common with -d option
256 if ( (sect.type() == ld::Section::typeTentativeDefs) && options.makeTentativeDefinitionsReal())
257 return _s_DATA_common;
258 return sect;
259 }
260
261 uint32_t InternalState::FinalSection::segmentOrder(const ld::Section& sect, const Options& options)
262 {
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)
290 for (uint32_t i=0; i < _s_segmentsSeen.size(); ++i) {
291 if ( strcmp(_s_segmentsSeen[i], sect.segmentName()) == 0 )
292 return i+100;
293 }
294 _s_segmentsSeen.push_back(sect.segmentName());
295 return _s_segmentsSeen.size()-1+100;
296 }
297
298 uint32_t InternalState::FinalSection::sectionOrder(const ld::Section& sect, uint32_t sectionsSeen, const Options& options)
299 {
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;
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 }
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:
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;
366 // <rdar://problem/17125893> Linker should put __cfstring near __const
367 if ( strcmp(sect.sectionName(), "__cfstring") == 0 )
368 return 15;
369 // <rdar://problem/7435296> Reorder sections to reduce page faults in object files
370 else if ( strcmp(sect.sectionName(), "__objc_classlist") == 0 )
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;
376 else if ( strcmp(sect.sectionName(), "__objc_nlcatlist") == 0 )
377 return 23;
378 else if ( strcmp(sect.sectionName(), "__objc_protolist") == 0 )
379 return 24;
380 else if ( strcmp(sect.sectionName(), "__objc_imageinfo") == 0 )
381 return 25;
382 else if ( strcmp(sect.sectionName(), "__objc_const") == 0 )
383 return 26;
384 else if ( strcmp(sect.sectionName(), "__objc_selrefs") == 0 )
385 return 27;
386 else if ( strcmp(sect.sectionName(), "__objc_msgrefs") == 0 )
387 return 28;
388 else if ( strcmp(sect.sectionName(), "__objc_protorefs") == 0 )
389 return 29;
390 else if ( strcmp(sect.sectionName(), "__objc_classrefs") == 0 )
391 return 30;
392 else if ( strcmp(sect.sectionName(), "__objc_superrefs") == 0 )
393 return 31;
394 else if ( strcmp(sect.sectionName(), "__objc_ivar") == 0 )
395 return 32;
396 else if ( strcmp(sect.sectionName(), "__objc_data") == 0 )
397 return 33;
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
409 static 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);
417 assert((fit->offsetInAtom <= atom.size()) || (fit->offsetInAtom == 0));
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;
474 }
475 }
476 lastClusterSize = fit->clusterSize;
477 if ( fit->binding == ld::Fixup::bindingDirectlyBound ) {
478 assert(fit->u.target != NULL);
479 }
480 }
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;
491 }
492 }
493 #endif
494
495 ld::Internal::FinalSection* InternalState::addAtom(const ld::Atom& atom)
496 {
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
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
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 }
592 return fs;
593 }
594
595
596
597 ld::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
606 ld::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 }
615
616 // otherwise, create a new final section
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
627 const ld::Section& outSect = FinalSection::outputSection(inputSection, _options.mergeZeroFill());
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;
633 }
634 else if ( outSect != inputSection ) {
635 // new output section created, but not in map
636 baseForFinalSection = &outSect;
637 }
638 }
639 break;
640 case Options::kObjectFile:
641 baseForFinalSection = &FinalSection::objectOutputSection(inputSection, _options);
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;
647 }
648 break;
649 }
650
651 InternalState::FinalSection* result = new InternalState::FinalSection(*baseForFinalSection,
652 _sectionInToFinalMap.size(), _options);
653 _sectionInToFinalMap[baseForFinalSection] = result;
654 //fprintf(stderr, "_sectionInToFinalMap[%p(%s)] = %p\n", baseForFinalSection, baseForFinalSection->sectionName(), result);
655 sections.push_back(result);
656 return result;
657 }
658
659
660 int InternalState::FinalSection::sectionComparer(const void* l, const void* r)
661 {
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);
667 }
668
669 void InternalState::sortSections()
670 {
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
685 }
686
687
688 bool 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
704 uint64_t InternalState::pageAlign(uint64_t addr)
705 {
706 const uint64_t alignment = _options.segmentAlignment();
707 return ((addr+alignment-1) & (-alignment));
708 }
709
710 uint64_t InternalState::pageAlign(uint64_t addr, uint64_t pageSize)
711 {
712 return ((addr+pageSize-1) & (-pageSize));
713 }
714
715 void 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
804 uint64_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;
899 if ( otherSect->size == 0 )
900 continue;
901 if ( sect->size == 0 )
902 continue;
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;
928 //if ( sect->isSectionHidden() )
929 // continue;
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
993 static 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
1009 static 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;
1014 if ( mach_timebase_info(&timeBaseInfo) != KERN_SUCCESS )
1015 return;
1016 sUnitsPerSecond = 1000000000ULL * timeBaseInfo.denom / timeBaseInfo.numer;
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
1035 static void getVMInfo(vm_statistics_data_t& info)
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
1045
1046
1047 static 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 //
1053 extern "C" const char* dyld_lazy_dylib_path_fix(const char* path);
1054 const 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
1064 int main(int argc, const char* argv[])
1065 {
1066 const char* archName = NULL;
1067 bool showArch = false;
1068 bool archInferred = false;
1069 try {
1070 PerformanceStatistics statistics;
1071 statistics.startTool = mach_absolute_time();
1072
1073 // create object to track command line arguments
1074 Options options(argc, argv);
1075 InternalState state(options);
1076
1077 // allow libLTO to be overridden by command line -lto_library
1078 sOverridePathlibLTO = options.overridePathlibLTO();
1079
1080 // gather vm stats
1081 if ( options.printStatistics() )
1082 getVMInfo(statistics.vmStart);
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
1090 statistics.startInputFileProcessing = mach_absolute_time();
1091 ld::tool::InputFiles inputFiles(options, &archName);
1092
1093 // load and resolve all references
1094 statistics.startResolver = mach_absolute_time();
1095 ld::tool::Resolver resolver(options, inputFiles, state);
1096 resolver.resolve();
1097
1098 // add dylibs used
1099 statistics.startDylibs = mach_absolute_time();
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
1106 statistics.startPasses = mach_absolute_time();
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
1113 ld::passes::order::doPass(options, state);
1114 state.markAtomsOrdered();
1115 ld::passes::branch_shim::doPass(options, state); // must be after stubs
1116 ld::passes::branch_island::doPass(options, state); // must be after stubs and order pass
1117 ld::passes::dtrace::doPass(options, state);
1118 ld::passes::compact_unwind::doPass(options, state); // must be after order pass
1119
1120 // sort final sections
1121 state.sortSections();
1122
1123 // write output file
1124 statistics.startOutput = mach_absolute_time();
1125 ld::tool::OutputFile out(options);
1126 out.write(state);
1127 statistics.startDone = mach_absolute_time();
1128
1129 // print statistics
1130 //mach_o::relocatable::printCounts();
1131 if ( options.printStatistics() ) {
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;
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;
1165 }
1166
1167 return 0;
1168 }
1169
1170
1171 #ifndef NDEBUG
1172 // implement assert() function to print out a backtrace before aborting
1173 void __assert_rtn(const char* func, const char* file, int line, const char* failedexpr)
1174 {
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);
1180
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;
1194 }
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);
1197 snapshot->recordAssertionMessage("%d %p %s + %ld\n", i, callStack[i], symboName, offset);
1198 }
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);
1201 exit(1);
1202 }
1203 #endif
1204
1205