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