1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-*
3 * Copyright (c) 2005-2011 Apple Inc. All rights reserved.
5 * @APPLE_LICENSE_HEADER_START@
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
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.
22 * @APPLE_LICENSE_HEADER_END@
25 // start temp HACK for cross builds
26 extern "C" double log2 ( double );
28 // end temp HACK for cross builds
32 #include <sys/types.h>
35 #include <sys/sysctl.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>
46 #include <mach-o/dyld.h>
48 #include <AvailabilityMacros.h>
57 #include <unordered_map>
62 #include "MachOFileAbstraction.hpp"
63 #include "Architectures.hpp"
66 #include "InputFiles.h"
68 #include "OutputFile.h"
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"
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"
92 struct PerformanceStatistics
{
94 uint64_t startInputFileProcessing
;
95 uint64_t startResolver
;
100 vm_statistics_data_t vmStart
;
101 vm_statistics_data_t vmEnd
;
105 class InternalState
: public ld::Internal
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
);
113 uint64_t assignFileOffsets();
114 void setSectionSizesAndAlignments();
116 void markAtomsOrdered() { _atomsOrderedInSections
= true; }
117 bool hasReferenceToWeakExternal(const ld::Atom
& atom
);
119 virtual ~InternalState() {}
122 class FinalSection
: public ld::Internal::FinalSection
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
&);
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
;
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
;
148 bool hasZeroForFileOffset(const ld::Section
* sect
);
149 uint64_t pageAlign(uint64_t addr
);
150 uint64_t pageAlign(uint64_t addr
, uint64_t pageSize
);
153 size_t operator()(const ld::Section
*) const;
155 struct SectionEquals
{
156 bool operator()(const ld::Section
* left
, const ld::Section
* right
) const;
158 typedef std::unordered_map
<const ld::Section
*, FinalSection
*, SectionHash
, SectionEquals
> SectionInToOut
;
161 SectionInToOut _sectionInToFinalMap
;
162 const Options
& _options
;
163 bool _atomsOrderedInSections
;
166 ld::Section
InternalState::FinalSection::_s_DATA_data( "__DATA", "__data", ld::Section::typeUnclassified
);
167 ld::Section
InternalState::FinalSection::_s_DATA_const("__DATA", "__const", ld::Section::typeUnclassified
);
168 ld::Section
InternalState::FinalSection::_s_TEXT_text( "__TEXT", "__text", ld::Section::typeCode
);
169 ld::Section
InternalState::FinalSection::_s_TEXT_const("__TEXT", "__const", ld::Section::typeUnclassified
);
170 ld::Section
InternalState::FinalSection::_s_DATA_nl_symbol_ptr("__DATA", "__nl_symbol_ptr", ld::Section::typeNonLazyPointer
);
171 ld::Section
InternalState::FinalSection::_s_DATA_common("__DATA", "__common", ld::Section::typeZeroFill
);
172 ld::Section
InternalState::FinalSection::_s_DATA_zerofill("__DATA", "__zerofill", ld::Section::typeZeroFill
);
173 ld::Section
InternalState::FinalSection::_s_DATA_DIRTY_data( "__DATA_DIRTY", "__data", ld::Section::typeUnclassified
);
174 ld::Section
InternalState::FinalSection::_s_DATA_CONST_const( "__DATA_CONST", "__const", ld::Section::typeUnclassified
);
176 std::vector
<const char*> InternalState::FinalSection::_s_segmentsSeen
;
179 size_t InternalState::SectionHash::operator()(const ld::Section
* sect
) const
182 ld::CStringHash temp
;
183 hash
+= temp
.operator()(sect
->segmentName());
184 hash
+= temp
.operator()(sect
->sectionName());
188 bool InternalState::SectionEquals::operator()(const ld::Section
* left
, const ld::Section
* right
) const
190 return (*left
== *right
);
194 InternalState::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
))
199 //fprintf(stderr, "FinalSection(%s, %s) _segmentOrder=%d, _sectionOrder=%d\n",
200 // this->segmentName(), this->sectionName(), _segmentOrder, _sectionOrder);
203 const ld::Section
& InternalState::FinalSection::outputSection(const ld::Section
& sect
, bool mergeZeroFill
)
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
;
213 case ld::Section::typeUnclassified
:
214 if ( strcmp(sect
.segmentName(), "__DATA") == 0 ) {
215 if ( strcmp(sect
.sectionName(), "__datacoal_nt") == 0 )
217 if ( strcmp(sect
.sectionName(), "__const_coal") == 0 )
218 return _s_DATA_const
;
220 else if ( strcmp(sect
.segmentName(), "__TEXT") == 0 ) {
221 if ( strcmp(sect
.sectionName(), "__const_coal") == 0 )
222 return _s_TEXT_const
;
224 else if ( strcmp(sect
.segmentName(), "__DATA_DIRTY") == 0 ) {
225 if ( strcmp(sect
.sectionName(), "__datacoal_nt") == 0 )
226 return _s_DATA_DIRTY_data
;
228 else if ( strcmp(sect
.segmentName(), "__DATA_CONST") == 0 ) {
229 if ( strcmp(sect
.sectionName(), "__const_coal") == 0 )
230 return _s_DATA_CONST_const
;
233 case ld::Section::typeZeroFill
:
235 return _s_DATA_zerofill
;
237 case ld::Section::typeCode
:
238 if ( strcmp(sect
.segmentName(), "__TEXT") == 0 ) {
239 if ( strcmp(sect
.sectionName(), "__textcoal_nt") == 0 )
241 else if ( strcmp(sect
.sectionName(), "__StaticInit") == 0 )
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
;
250 else if ( strcmp(sect
.segmentName(), "__IMPORT") == 0 ) {
251 if ( strcmp(sect
.sectionName(), "__pointers") == 0 )
252 return _s_DATA_nl_symbol_ptr
;
255 case ld::Section::typeTentativeDefs
:
256 if ( (strcmp(sect
.segmentName(), "__DATA") == 0) && (strcmp(sect
.sectionName(), "__comm/tent") == 0) ) {
258 return _s_DATA_zerofill
;
260 return _s_DATA_common
;
270 const ld::Section
& InternalState::FinalSection::objectOutputSection(const ld::Section
& sect
, const Options
& options
)
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
;
278 uint32_t InternalState::FinalSection::segmentOrder(const ld::Section
& sect
, const Options
& options
)
280 if ( options
.outputKind() == Options::kPreload
) {
281 if ( strcmp(sect
.segmentName(), "__HEADER") == 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 )
288 if ( strcmp(sect
.segmentName(), "__TEXT") == 0 )
289 return order
.size()+1;
290 if ( strcmp(sect
.segmentName(), "__DATA") == 0 )
291 return order
.size()+2;
294 if ( strcmp(sect
.segmentName(), "__PAGEZERO") == 0 )
296 if ( strcmp(sect
.segmentName(), "__TEXT") == 0 )
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 )
303 if ( strcmp(sect
.segmentName(), "__IMPORT") == 0 )
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 )
311 _s_segmentsSeen
.push_back(sect
.segmentName());
312 return _s_segmentsSeen
.size()-1+100;
315 uint32_t InternalState::FinalSection::sectionOrder(const ld::Section
& sect
, uint32_t sectionsSeen
, const Options
& options
)
317 if ( sect
.type() == ld::Section::typeFirstSection
)
319 if ( sect
.type() == ld::Section::typeMachHeader
)
321 if ( sect
.type() == ld::Section::typeLastSection
)
323 const std::vector
<const char*>* sectionList
= options
.sectionOrder(sect
.segmentName());
324 if ( ((options
.outputKind() == Options::kPreload
) || (options
.outputKind() == Options::kDyld
)) && (sectionList
!= NULL
) ) {
326 for (std::vector
<const char*>::const_iterator it
=sectionList
->begin(); it
!= sectionList
->end(); ++it
, ++count
) {
327 if ( strcmp(*it
, sect
.sectionName()) == 0 )
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 )
339 case ld::Section::typeStub
:
341 case ld::Section::typeStubHelper
:
343 case ld::Section::typeLSDA
:
345 case ld::Section::typeUnwindInfo
:
347 case ld::Section::typeCFI
:
349 case ld::Section::typeStubClose
:
352 return sectionsSeen
+20;
355 else if ( strncmp(sect
.segmentName(), "__DATA", 6) == 0 ) {
356 switch ( sect
.type() ) {
357 case ld::Section::typeLazyPointerClose
:
359 case ld::Section::typeDyldInfo
:
361 case ld::Section::typeNonLazyPointer
:
363 case ld::Section::typeLazyPointer
:
365 case ld::Section::typeInitializerPointers
:
367 case ld::Section::typeTerminatorPointers
:
369 case ld::Section::typeTLVInitialValues
:
370 return INT_MAX
-4; // need TLV zero-fill to follow TLV init values
371 case ld::Section::typeTLVZeroFill
:
373 case ld::Section::typeZeroFill
:
374 // make sure __huge is always last zerofill section
375 if ( strcmp(sect
.sectionName(), "__huge") == 0 )
380 // <rdar://problem/14348664> __DATA,__const section should be near __mod_init_func not __data
381 if ( strcmp(sect
.sectionName(), "__const") == 0 )
383 // <rdar://problem/17125893> Linker should put __cfstring near __const
384 if ( strcmp(sect
.sectionName(), "__cfstring") == 0 )
386 // <rdar://problem/7435296> Reorder sections to reduce page faults in object files
387 else if ( strcmp(sect
.sectionName(), "__objc_classlist") == 0 )
389 else if ( strcmp(sect
.sectionName(), "__objc_nlclslist") == 0 )
391 else if ( strcmp(sect
.sectionName(), "__objc_catlist") == 0 )
393 else if ( strcmp(sect
.sectionName(), "__objc_nlcatlist") == 0 )
395 else if ( strcmp(sect
.sectionName(), "__objc_protolist") == 0 )
397 else if ( strcmp(sect
.sectionName(), "__objc_imageinfo") == 0 )
399 else if ( strcmp(sect
.sectionName(), "__objc_const") == 0 )
401 else if ( strcmp(sect
.sectionName(), "__objc_selrefs") == 0 )
403 else if ( strcmp(sect
.sectionName(), "__objc_msgrefs") == 0 )
405 else if ( strcmp(sect
.sectionName(), "__objc_protorefs") == 0 )
407 else if ( strcmp(sect
.sectionName(), "__objc_classrefs") == 0 )
409 else if ( strcmp(sect
.sectionName(), "__objc_superrefs") == 0 )
411 else if ( strcmp(sect
.sectionName(), "__objc_ivar") == 0 )
413 else if ( strcmp(sect
.sectionName(), "__objc_data") == 0 )
416 return sectionsSeen
+40;
419 // make sure zerofill in any other section is at end of segment
420 if ( sect
.type() == ld::Section::typeZeroFill
)
422 return sectionsSeen
+20;
426 static void validateFixups(const ld::Atom
& atom
)
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
);
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;
451 case ld::Fixup::k2of2
:
452 assert(lastClusterSize
= ld::Fixup::k1of2
);
453 lastWasClusterEnd
= true;
455 case ld::Fixup::k2of3
:
456 assert(lastClusterSize
= ld::Fixup::k1of3
);
457 lastWasClusterEnd
= false;
459 case ld::Fixup::k2of4
:
460 assert(lastClusterSize
= ld::Fixup::k1of4
);
461 lastWasClusterEnd
= false;
463 case ld::Fixup::k2of5
:
464 assert(lastClusterSize
= ld::Fixup::k1of5
);
465 lastWasClusterEnd
= false;
467 case ld::Fixup::k3of3
:
468 assert(lastClusterSize
= ld::Fixup::k2of3
);
469 lastWasClusterEnd
= true;
471 case ld::Fixup::k3of4
:
472 assert(lastClusterSize
= ld::Fixup::k2of4
);
473 lastWasClusterEnd
= false;
475 case ld::Fixup::k3of5
:
476 assert(lastClusterSize
= ld::Fixup::k2of5
);
477 lastWasClusterEnd
= false;
479 case ld::Fixup::k4of4
:
480 assert(lastClusterSize
= ld::Fixup::k3of4
);
481 lastWasClusterEnd
= true;
483 case ld::Fixup::k4of5
:
484 assert(lastClusterSize
= ld::Fixup::k3of5
);
485 lastWasClusterEnd
= false;
487 case ld::Fixup::k5of5
:
488 assert(lastClusterSize
= ld::Fixup::k4of5
);
489 lastWasClusterEnd
= true;
493 lastClusterSize
= fit
->clusterSize
;
494 if ( fit
->binding
== ld::Fixup::bindingDirectlyBound
) {
495 assert(fit
->u
.target
!= NULL
);
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
:
506 assert(0 && "last fixup was not end of cluster");
512 bool InternalState::hasReferenceToWeakExternal(const ld::Atom
& atom
)
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() ) {
520 switch ( fit
->binding
) {
521 case ld::Fixup::bindingNone
:
522 case ld::Fixup::bindingByNameUnbound
:
524 case ld::Fixup::bindingByContentBound
:
525 case ld::Fixup::bindingDirectlyBound
:
526 target
= fit
->u
.target
;
528 case ld::Fixup::bindingsIndirectlyBound
:
529 target
= indirectBindingTable
[fit
->u
.bindingIndex
];
532 if ( (target
!= NULL
) && (target
->definition() == ld::Atom::definitionRegular
)
533 && (target
->combine() == ld::Atom::combineByName
) && (target
->scope() == ld::Atom::scopeGlobal
) ) {
540 ld::Internal::FinalSection
* InternalState::addAtom(const ld::Atom
& atom
)
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();
553 sectName
= FinalSection::_s_DATA_common
.sectionName();
555 // Support for -move_to_r._segment
556 if ( atom
.symbolTableInclusion() == ld::Atom::symbolTableIn
) {
558 //fprintf(stderr, "%s\n", atom.name());
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
);
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
);
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
);
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
);
587 // support for -rename_section and -rename_segment
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());
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());
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());
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
);
624 // if no override, use default location
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());
631 //fprintf(stderr, "InternalState::doAtom(%p), name=%s, sect=%s, finalsect=%p\n", &atom, atom.name(), atom.section().sectionName(), fs);
633 validateFixups(atom
);
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
);
645 // not end atom, just append new atom
646 fs
->atoms
.push_back(&atom
);
651 fs
->atoms
.push_back(&atom
);
653 this->atomToSection
[&atom
] = fs
;
659 ld::Internal::FinalSection
* InternalState::getFinalSection(const char* seg
, const char* sect
, ld::Section::Type type
)
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) )
665 return this->getFinalSection(*new ld::Section(seg
, sect
, type
, false));
668 ld::Internal::FinalSection
* InternalState::getFinalSection(const ld::Section
& inputSection
)
670 const ld::Section
* baseForFinalSection
= &inputSection
;
672 // see if input section already has a FinalSection
673 SectionInToOut::iterator pos
= _sectionInToFinalMap
.find(&inputSection
);
674 if ( pos
!= _sectionInToFinalMap
.end() ) {
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
:
685 case Options::kKextBundle
:
686 case Options::kPreload
:
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);
696 else if ( outSect
!= inputSection
) {
697 // new output section created, but not in map
698 baseForFinalSection
= &outSect
;
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);
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
);
722 int InternalState::FinalSection::sectionComparer(const void* l
, const void* r
)
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
);
731 void InternalState::sortSections()
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());
737 qsort(§ions
[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());
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
)) );
750 bool InternalState::hasZeroForFileOffset(const ld::Section
* sect
)
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
:
766 uint64_t InternalState::pageAlign(uint64_t addr
)
768 const uint64_t alignment
= _options
.segmentAlignment();
769 return ((addr
+alignment
-1) & (-alignment
));
772 uint64_t InternalState::pageAlign(uint64_t addr
, uint64_t pageSize
)
774 return ((addr
+pageSize
-1) & (-pageSize
));
777 void InternalState::setSectionSizesAndAlignments()
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());
789 uint16_t maxAlignment
= 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
)
810 if ( atomAlignmentPowerOf2
< 12 ) {
811 atomAlignmentPowerOf2
= 12;
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
;
829 offset
+= requiredModulus
+alignment
-currentModulus
;
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();
836 offset
= (offset
+ 4095) & (-4096); // round up to end of page
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());
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
)
860 if ( sect
->type() == ld::Section::typeTLVDefs
)
861 this->hasThreadLocalVariableDefinitions
= true;
866 uint64_t InternalState::assignFileOffsets()
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
);
873 uint64_t address
= 0;
874 const char* lastSegName
= "";
875 uint64_t floatingAddressStart
= _options
.baseAddress();
876 bool haveFixedSegments
= false;
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
;
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()) )
891 haveFixedSegments
= true;
892 if ( segmentsArePageAligned
) {
893 if ( strcmp(lastSegName
, sect
->segmentName()) != 0 ) {
894 address
= _options
.customSegmentAddress(sect
->segmentName());
895 lastSegName
= sect
->segmentName();
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
) );
903 // update section info
904 sect
->address
= address
;
905 sect
->alignmentPaddingBytes
= (address
- unalignedAddress
);
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
);
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
;
919 // if TEXT segment address is fixed, then flow other segments after it
920 if ( strcmp(sect
->segmentName(), "__TEXT") == 0 ) {
921 floatingAddressStart
= address
;
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");
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
));
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
;
950 lastSegName
= sect
->segmentName();
955 // last pass, assign addresses to remaining sections
956 address
= floatingAddressStart
;
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
)
966 if ( (_options
.outputKind() == Options::kPreload
) && (sect
->type() == ld::Section::typeMachHeader
) ) {
967 sect
->alignmentPaddingBytes
= 0;
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
));
976 // set segment address based on end of last segment
977 address
= pageAlign(address
);
978 lastSegName
= sect
->segmentName();
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
) );
987 // update section info
988 sect
->address
= address
;
989 sect
->alignmentPaddingBytes
= (address
- unalignedAddress
);
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
;
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
);
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()) )
1011 if ( otherSect
->size
== 0 )
1013 if ( sect
->size
== 0 )
1015 if ( sect
->address
> otherSect
->address
) {
1016 if ( (otherSect
->address
+otherSect
->size
) > sect
->address
) {
1017 overlappingFixedSection
= otherSect
;
1018 overlappingFlowSection
= sect
;
1022 if ( (sect
->address
+sect
->size
) > otherSect
->address
) {
1023 overlappingFixedSection
= otherSect
;
1024 overlappingFlowSection
= sect
;
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
;
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() )
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());
1048 throwf("Section (%s/%s) overlaps fixed address section (%s/%s)",
1049 overlappingFlowSection
->segmentName(), overlappingFlowSection
->sectionName(),
1050 overlappingFixedSection
->segmentName(), overlappingFixedSection
->sectionName());
1054 // third pass, assign section file offsets
1055 uint64_t fileOffset
= 0;
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;
1064 // <rdar://problem/10445047> align file offset with address layout
1065 fileOffset
+= sect
->alignmentPaddingBytes
;
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
));
1072 lastSegName
= sect
->segmentName();
1074 // align file offset with address layout
1075 fileOffset
+= sect
->alignmentPaddingBytes
;
1077 // update section info
1078 sect
->fileOffset
= fileOffset
;
1080 // update running total
1081 fileOffset
+= sect
->size
;
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());
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
);
1102 // return total file size
1106 static char* commatize(uint64_t in
, char* out
)
1110 sprintf(rawNum
, "%llu", in
);
1111 const int rawNumLen
= strlen(rawNum
);
1112 for(int i
=0; i
< rawNumLen
-1; ++i
) {
1114 if ( ((rawNumLen
-i
) % 3) == 1 )
1117 *out
++ = rawNum
[rawNumLen
-1];
1122 static void printTime(const char* msg
, uint64_t partTime
, uint64_t totalTime
)
1124 static uint64_t sUnitsPerSecond
= 0;
1125 if ( sUnitsPerSecond
== 0 ) {
1126 struct mach_timebase_info timeBaseInfo
;
1127 if ( mach_timebase_info(&timeBaseInfo
) != KERN_SUCCESS
)
1129 sUnitsPerSecond
= 1000000000ULL * timeBaseInfo
.denom
/ timeBaseInfo
.numer
;
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);
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);
1148 static void getVMInfo(vm_statistics_data_t
& info
)
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
));
1160 static const char* sOverridePathlibLTO
= NULL
;
1163 // This is magic glue that overrides the default behaviour
1164 // of lazydylib1.o which is used to lazily load libLTO.dylib.
1166 extern "C" const char* dyld_lazy_dylib_path_fix(const char* path
);
1167 const char* dyld_lazy_dylib_path_fix(const char* path
)
1169 if ( sOverridePathlibLTO
!= NULL
)
1170 return sOverridePathlibLTO
;
1177 int main(int argc
, const char* argv
[])
1179 const char* archName
= NULL
;
1180 bool showArch
= false;
1181 bool archInferred
= false;
1183 PerformanceStatistics statistics
;
1184 statistics
.startTool
= mach_absolute_time();
1186 // create object to track command line arguments
1187 Options
options(argc
, argv
);
1188 InternalState
state(options
);
1190 // allow libLTO to be overridden by command line -lto_library
1191 sOverridePathlibLTO
= options
.overridePathlibLTO();
1194 if ( options
.printStatistics() )
1195 getVMInfo(statistics
.vmStart
);
1197 // update strings for error messages
1198 showArch
= options
.printArchPrefix();
1199 archName
= options
.architectureName();
1200 archInferred
= (options
.architecture() == 0);
1202 // open and parse input files
1203 statistics
.startInputFileProcessing
= mach_absolute_time();
1204 ld::tool::InputFiles
inputFiles(options
, &archName
);
1206 // load and resolve all references
1207 statistics
.startResolver
= mach_absolute_time();
1208 ld::tool::Resolver
resolver(options
, inputFiles
, state
);
1212 statistics
.startDylibs
= mach_absolute_time();
1213 inputFiles
.dylibs(state
);
1215 // do initial section sorting so passes have rough idea of the layout
1216 state
.sortSections();
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
1235 // sort final sections
1236 state
.sortSections();
1238 // write output file
1239 statistics
.startOutput
= mach_absolute_time();
1240 ld::tool::OutputFile
out(options
);
1242 statistics
.startDone
= mach_absolute_time();
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
);
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
));
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");
1272 catch (const char* msg
) {
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
);
1278 fprintf(stderr
, "ld: %s\n", msg
);
1287 // implement assert() function to print out a backtrace before aborting
1288 void __assert_rtn(const char* func
, const char* file
, int line
, const char* failedexpr
)
1290 Snapshot
*snapshot
= Snapshot::globalSnapshot
;
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
);
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
) {
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;
1306 char* unmangled
= abi::__cxa_demangle(symboName
, buffer
, &bufLen
, &result
);
1307 if ( unmangled
!= NULL
)
1308 symboName
= unmangled
;
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
);
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
);