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