1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-*
3 * Copyright (c) 2009-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@
27 #include <sys/types.h>
30 #include <sys/sysctl.h>
35 #include <mach/mach_time.h>
36 #include <mach/vm_statistics.h>
37 #include <mach/mach_init.h>
38 #include <mach/mach_host.h>
39 #include <uuid/uuid.h>
41 #include <mach-o/dyld.h>
42 #include <mach-o/fat.h>
51 #include <ext/hash_map>
52 #include <ext/hash_set>
54 #include <CommonCrypto/CommonDigest.h>
55 #include <AvailabilityMacros.h>
57 #include "MachOTrie.hpp"
61 #include "OutputFile.h"
62 #include "Architectures.hpp"
63 #include "HeaderAndLoadCommands.hpp"
64 #include "LinkEdit.hpp"
65 #include "LinkEditClassic.hpp"
72 OutputFile::OutputFile(const Options
& opts
)
74 hasWeakExternalSymbols(false), usesWeakExternalSymbols(false), overridesWeakExternalSymbols(false),
75 _noReExportedDylibs(false), hasThreadLocalVariableDefinitions(false), pieDisabled(false), hasDataInCode(false),
76 headerAndLoadCommandsSection(NULL
),
77 rebaseSection(NULL
), bindingSection(NULL
), weakBindingSection(NULL
),
78 lazyBindingSection(NULL
), exportSection(NULL
),
79 splitSegInfoSection(NULL
), functionStartsSection(NULL
),
80 dataInCodeSection(NULL
), dependentDRsSection(NULL
),
81 symbolTableSection(NULL
), stringPoolSection(NULL
),
82 localRelocationsSection(NULL
), externalRelocationsSection(NULL
),
83 sectionRelocationsSection(NULL
),
84 indirectSymbolTableSection(NULL
),
86 _hasDyldInfo(opts
.makeCompressedDyldInfo()),
87 _hasSymbolTable(true),
88 _hasSectionRelocations(opts
.outputKind() == Options::kObjectFile
),
89 _hasSplitSegInfo(opts
.sharedRegionEligible()),
90 _hasFunctionStartsInfo(opts
.addFunctionStarts()),
91 _hasDataInCodeInfo(opts
.addDataInCodeInfo()),
92 _hasDependentDRInfo(opts
.needsDependentDRInfo()),
93 _hasDynamicSymbolTable(true),
94 _hasLocalRelocations(!opts
.makeCompressedDyldInfo()),
95 _hasExternalRelocations(!opts
.makeCompressedDyldInfo()),
96 _encryptedTEXTstartOffset(0),
97 _encryptedTEXTendOffset(0),
98 _localSymbolsStartIndex(0),
99 _localSymbolsCount(0),
100 _globalSymbolsStartIndex(0),
101 _globalSymbolsCount(0),
102 _importSymbolsStartIndex(0),
103 _importSymbolsCount(0),
104 _sectionsRelocationsAtom(NULL
),
105 _localRelocsAtom(NULL
),
106 _externalRelocsAtom(NULL
),
107 _symbolTableAtom(NULL
),
108 _indirectSymbolTableAtom(NULL
),
109 _rebasingInfoAtom(NULL
),
110 _bindingInfoAtom(NULL
),
111 _lazyBindingInfoAtom(NULL
),
112 _weakBindingInfoAtom(NULL
),
113 _exportInfoAtom(NULL
),
114 _splitSegInfoAtom(NULL
),
115 _functionStartsAtom(NULL
),
116 _dataInCodeAtom(NULL
),
117 _dependentDRInfoAtom(NULL
)
121 void OutputFile::dumpAtomsBySection(ld::Internal
& state
, bool printAtoms
)
123 fprintf(stderr
, "SORTED:\n");
124 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
125 fprintf(stderr
, "final section %p %s/%s %s start addr=0x%08llX, size=0x%08llX, alignment=%02d, fileOffset=0x%08llX\n",
126 (*it
), (*it
)->segmentName(), (*it
)->sectionName(), (*it
)->isSectionHidden() ? "(hidden)" : "",
127 (*it
)->address
, (*it
)->size
, (*it
)->alignment
, (*it
)->fileOffset
);
129 std::vector
<const ld::Atom
*>& atoms
= (*it
)->atoms
;
130 for (std::vector
<const ld::Atom
*>::iterator ait
= atoms
.begin(); ait
!= atoms
.end(); ++ait
) {
131 fprintf(stderr
, " %p (0x%04llX) %s\n", *ait
, (*ait
)->size(), (*ait
)->name());
135 fprintf(stderr
, "DYLIBS:\n");
136 for (std::vector
<ld::dylib::File
*>::iterator it
=state
.dylibs
.begin(); it
!= state
.dylibs
.end(); ++it
)
137 fprintf(stderr
, " %s\n", (*it
)->installPath());
140 void OutputFile::write(ld::Internal
& state
)
142 this->buildDylibOrdinalMapping(state
);
143 this->addLoadCommands(state
);
144 this->addLinkEdit(state
);
145 this->setSectionSizesAndAlignments(state
);
146 this->setLoadCommandsPadding(state
);
147 this->assignFileOffsets(state
);
148 this->assignAtomAddresses(state
);
149 this->synthesizeDebugNotes(state
);
150 this->buildSymbolTable(state
);
151 this->generateLinkEditInfo(state
);
152 this->makeSplitSegInfo(state
);
153 this->updateLINKEDITAddresses(state
);
154 //this->dumpAtomsBySection(state, false);
155 this->writeOutputFile(state
);
156 this->writeMapFile(state
);
159 bool OutputFile::findSegment(ld::Internal
& state
, uint64_t addr
, uint64_t* start
, uint64_t* end
, uint32_t* index
)
161 uint32_t segIndex
= 0;
162 ld::Internal::FinalSection
* segFirstSection
= NULL
;
163 ld::Internal::FinalSection
* lastSection
= NULL
;
164 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
165 ld::Internal::FinalSection
* sect
= *it
;
166 if ( (segFirstSection
== NULL
) || strcmp(segFirstSection
->segmentName(), sect
->segmentName()) != 0 ) {
167 if ( segFirstSection
!= NULL
) {
168 //fprintf(stderr, "findSegment(0x%llX) seg changed to %s\n", addr, sect->segmentName());
169 if ( (addr
>= segFirstSection
->address
) && (addr
< lastSection
->address
+lastSection
->size
) ) {
170 *start
= segFirstSection
->address
;
171 *end
= lastSection
->address
+lastSection
->size
;
177 segFirstSection
= sect
;
185 void OutputFile::assignAtomAddresses(ld::Internal
& state
)
187 const bool log
= false;
188 if ( log
) fprintf(stderr
, "assignAtomAddresses()\n");
189 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
190 ld::Internal::FinalSection
* sect
= *sit
;
191 if ( log
) fprintf(stderr
, " section=%s/%s\n", sect
->segmentName(), sect
->sectionName());
192 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
193 const ld::Atom
* atom
= *ait
;
194 if ( log
) fprintf(stderr
, " atom=%p, name=%s\n", atom
, atom
->name());
195 switch ( sect
-> type() ) {
196 case ld::Section::typeImportProxies
:
197 // want finalAddress() of all proxy atoms to be zero
198 (const_cast<ld::Atom
*>(atom
))->setSectionStartAddress(0);
200 case ld::Section::typeAbsoluteSymbols
:
201 // want finalAddress() of all absolute atoms to be value of abs symbol
202 (const_cast<ld::Atom
*>(atom
))->setSectionStartAddress(0);
204 case ld::Section::typeLinkEdit
:
205 // linkedit layout is assigned later
208 (const_cast<ld::Atom
*>(atom
))->setSectionStartAddress(sect
->address
);
215 void OutputFile::updateLINKEDITAddresses(ld::Internal
& state
)
217 if ( _options
.makeCompressedDyldInfo() ) {
218 // build dylb rebasing info
219 assert(_rebasingInfoAtom
!= NULL
);
220 _rebasingInfoAtom
->encode();
222 // build dyld binding info
223 assert(_bindingInfoAtom
!= NULL
);
224 _bindingInfoAtom
->encode();
226 // build dyld lazy binding info
227 assert(_lazyBindingInfoAtom
!= NULL
);
228 _lazyBindingInfoAtom
->encode();
230 // build dyld weak binding info
231 assert(_weakBindingInfoAtom
!= NULL
);
232 _weakBindingInfoAtom
->encode();
234 // build dyld export info
235 assert(_exportInfoAtom
!= NULL
);
236 _exportInfoAtom
->encode();
239 if ( _options
.sharedRegionEligible() ) {
240 // build split seg info
241 assert(_splitSegInfoAtom
!= NULL
);
242 _splitSegInfoAtom
->encode();
245 if ( _options
.addFunctionStarts() ) {
246 // build function starts info
247 assert(_functionStartsAtom
!= NULL
);
248 _functionStartsAtom
->encode();
251 if ( _options
.addDataInCodeInfo() ) {
252 // build data-in-code info
253 assert(_dataInCodeAtom
!= NULL
);
254 _dataInCodeAtom
->encode();
257 if ( _options
.needsDependentDRInfo() ) {
258 // build dependent dylib DR info
259 assert(_dependentDRInfoAtom
!= NULL
);
260 _dependentDRInfoAtom
->encode();
263 // build classic symbol table
264 assert(_symbolTableAtom
!= NULL
);
265 _symbolTableAtom
->encode();
266 assert(_indirectSymbolTableAtom
!= NULL
);
267 _indirectSymbolTableAtom
->encode();
269 // add relocations to .o files
270 if ( _options
.outputKind() == Options::kObjectFile
) {
271 assert(_sectionsRelocationsAtom
!= NULL
);
272 _sectionsRelocationsAtom
->encode();
275 if ( ! _options
.makeCompressedDyldInfo() ) {
276 // build external relocations
277 assert(_externalRelocsAtom
!= NULL
);
278 _externalRelocsAtom
->encode();
279 // build local relocations
280 assert(_localRelocsAtom
!= NULL
);
281 _localRelocsAtom
->encode();
284 // update address and file offsets now that linkedit content has been generated
285 uint64_t curLinkEditAddress
= 0;
286 uint64_t curLinkEditfileOffset
= 0;
287 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
288 ld::Internal::FinalSection
* sect
= *sit
;
289 if ( sect
->type() != ld::Section::typeLinkEdit
)
291 if ( curLinkEditAddress
== 0 ) {
292 curLinkEditAddress
= sect
->address
;
293 curLinkEditfileOffset
= sect
->fileOffset
;
295 uint16_t maxAlignment
= 0;
297 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
298 const ld::Atom
* atom
= *ait
;
299 //fprintf(stderr, "setting linkedit atom offset for %s\n", atom->name());
300 if ( atom
->alignment().powerOf2
> maxAlignment
)
301 maxAlignment
= atom
->alignment().powerOf2
;
302 // calculate section offset for this atom
303 uint64_t alignment
= 1 << atom
->alignment().powerOf2
;
304 uint64_t currentModulus
= (offset
% alignment
);
305 uint64_t requiredModulus
= atom
->alignment().modulus
;
306 if ( currentModulus
!= requiredModulus
) {
307 if ( requiredModulus
> currentModulus
)
308 offset
+= requiredModulus
-currentModulus
;
310 offset
+= requiredModulus
+alignment
-currentModulus
;
312 (const_cast<ld::Atom
*>(atom
))->setSectionOffset(offset
);
313 (const_cast<ld::Atom
*>(atom
))->setSectionStartAddress(curLinkEditAddress
);
314 offset
+= atom
->size();
317 // section alignment is that of a contained atom with the greatest alignment
318 sect
->alignment
= maxAlignment
;
319 sect
->address
= curLinkEditAddress
;
320 sect
->fileOffset
= curLinkEditfileOffset
;
321 curLinkEditAddress
+= sect
->size
;
322 curLinkEditfileOffset
+= sect
->size
;
325 _fileSize
= state
.sections
.back()->fileOffset
+ state
.sections
.back()->size
;
328 void OutputFile::setSectionSizesAndAlignments(ld::Internal
& state
)
330 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
331 ld::Internal::FinalSection
* sect
= *sit
;
332 if ( sect
->type() == ld::Section::typeAbsoluteSymbols
) {
333 // absolute symbols need their finalAddress() to their value
334 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
335 const ld::Atom
* atom
= *ait
;
336 (const_cast<ld::Atom
*>(atom
))->setSectionOffset(atom
->objectAddress());
340 uint16_t maxAlignment
= 0;
342 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
343 const ld::Atom
* atom
= *ait
;
344 bool pagePerAtom
= false;
345 uint32_t atomAlignmentPowerOf2
= atom
->alignment().powerOf2
;
346 if ( _options
.pageAlignDataAtoms() && ( strcmp(atom
->section().segmentName(), "__DATA") == 0) ) {
347 switch ( atom
->section().type() ) {
348 case ld::Section::typeUnclassified
:
349 case ld::Section::typeTentativeDefs
:
350 case ld::Section::typeZeroFill
:
352 if ( atomAlignmentPowerOf2
< 12 )
353 atomAlignmentPowerOf2
= 12;
359 if ( atomAlignmentPowerOf2
> maxAlignment
)
360 maxAlignment
= atomAlignmentPowerOf2
;
361 // calculate section offset for this atom
362 uint64_t alignment
= 1 << atomAlignmentPowerOf2
;
363 uint64_t currentModulus
= (offset
% alignment
);
364 uint64_t requiredModulus
= atom
->alignment().modulus
;
365 if ( currentModulus
!= requiredModulus
) {
366 if ( requiredModulus
> currentModulus
)
367 offset
+= requiredModulus
-currentModulus
;
369 offset
+= requiredModulus
+alignment
-currentModulus
;
371 // LINKEDIT atoms are laid out later
372 if ( sect
->type() != ld::Section::typeLinkEdit
) {
373 (const_cast<ld::Atom
*>(atom
))->setSectionOffset(offset
);
374 offset
+= atom
->size();
376 offset
= (offset
+ 4095) & (-4096); // round up to end of page
379 if ( (atom
->scope() == ld::Atom::scopeGlobal
)
380 && (atom
->definition() == ld::Atom::definitionRegular
)
381 && (atom
->combine() == ld::Atom::combineByName
)
382 && ((atom
->symbolTableInclusion() == ld::Atom::symbolTableIn
)
383 || (atom
->symbolTableInclusion() == ld::Atom::symbolTableInAndNeverStrip
)) ) {
384 this->hasWeakExternalSymbols
= true;
385 if ( _options
.warnWeakExports() )
386 warning("weak external symbol: %s", atom
->name());
390 // section alignment is that of a contained atom with the greatest alignment
391 sect
->alignment
= maxAlignment
;
392 // unless -sectalign command line option overrides
393 if ( _options
.hasCustomSectionAlignment(sect
->segmentName(), sect
->sectionName()) )
394 sect
->alignment
= _options
.customSectionAlignment(sect
->segmentName(), sect
->sectionName());
395 // each atom in __eh_frame has zero alignment to assure they pack together,
396 // but compilers usually make the CFIs pointer sized, so we want whole section
397 // to start on pointer sized boundary.
398 if ( sect
->type() == ld::Section::typeCFI
)
400 if ( sect
->type() == ld::Section::typeTLVDefs
)
401 this->hasThreadLocalVariableDefinitions
= true;
406 void OutputFile::setLoadCommandsPadding(ld::Internal
& state
)
408 // In other sections, any extra space is put and end of segment.
409 // In __TEXT segment, any extra space is put after load commands to allow post-processing of load commands
410 // Do a reverse layout of __TEXT segment to determine padding size and adjust section size
411 uint64_t paddingSize
= 0;
412 switch ( _options
.outputKind() ) {
414 // dyld itself has special padding requirements. We want the beginning __text section to start at a stable address
415 assert(strcmp(state
.sections
[1]->sectionName(),"__text") == 0);
416 state
.sections
[1]->alignment
= 12; // page align __text
418 case Options::kObjectFile
:
419 // mach-o .o files need no padding between load commands and first section
420 // but leave enough room that the object file could be signed
423 case Options::kPreload
:
424 // mach-o MH_PRELOAD files need no padding between load commands and first section
427 // work backwards from end of segment and lay out sections so that extra room goes to padding atom
429 for (std::vector
<ld::Internal::FinalSection
*>::reverse_iterator it
= state
.sections
.rbegin(); it
!= state
.sections
.rend(); ++it
) {
430 ld::Internal::FinalSection
* sect
= *it
;
431 if ( strcmp(sect
->segmentName(), "__TEXT") != 0 )
433 if ( sect
== headerAndLoadCommandsSection
) {
434 addr
-= headerAndLoadCommandsSection
->size
;
435 paddingSize
= addr
% _options
.segmentAlignment();
439 addr
= addr
& (0 - (1 << sect
->alignment
));
442 // if command line requires more padding than this
443 uint32_t minPad
= _options
.minimumHeaderPad();
444 if ( _options
.maxMminimumHeaderPad() ) {
445 // -headerpad_max_install_names means there should be room for every path load command to grow to 1204 bytes
446 uint32_t altMin
= _dylibsToLoad
.size() * MAXPATHLEN
;
447 if ( _options
.outputKind() == Options::kDynamicLibrary
)
448 altMin
+= MAXPATHLEN
;
449 if ( altMin
> minPad
)
452 if ( paddingSize
< minPad
) {
453 int extraPages
= (minPad
- paddingSize
+ _options
.segmentAlignment() - 1)/_options
.segmentAlignment();
454 paddingSize
+= extraPages
* _options
.segmentAlignment();
457 if ( _options
.makeEncryptable() ) {
458 // load commands must be on a separate non-encrypted page
459 int loadCommandsPage
= (headerAndLoadCommandsSection
->size
+ minPad
)/_options
.segmentAlignment();
460 int textPage
= (headerAndLoadCommandsSection
->size
+ paddingSize
)/_options
.segmentAlignment();
461 if ( loadCommandsPage
== textPage
) {
462 paddingSize
+= _options
.segmentAlignment();
465 // remember start for later use by load command
466 _encryptedTEXTstartOffset
= textPage
*_options
.segmentAlignment();
470 // add padding to size of section
471 headerAndLoadCommandsSection
->size
+= paddingSize
;
475 uint64_t OutputFile::pageAlign(uint64_t addr
)
477 const uint64_t alignment
= _options
.segmentAlignment();
478 return ((addr
+alignment
-1) & (-alignment
));
481 uint64_t OutputFile::pageAlign(uint64_t addr
, uint64_t pageSize
)
483 return ((addr
+pageSize
-1) & (-pageSize
));
487 void OutputFile::assignFileOffsets(ld::Internal
& state
)
489 const bool log
= false;
490 const bool hiddenSectionsOccupyAddressSpace
= ((_options
.outputKind() != Options::kObjectFile
)
491 && (_options
.outputKind() != Options::kPreload
));
492 const bool segmentsArePageAligned
= (_options
.outputKind() != Options::kObjectFile
);
494 uint64_t address
= 0;
495 const char* lastSegName
= "";
496 uint64_t floatingAddressStart
= _options
.baseAddress();
498 // first pass, assign addresses to sections in segments with fixed start addresses
499 if ( log
) fprintf(stderr
, "Fixed address segments:\n");
500 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
501 ld::Internal::FinalSection
* sect
= *it
;
502 if ( ! _options
.hasCustomSegmentAddress(sect
->segmentName()) )
504 if ( segmentsArePageAligned
) {
505 if ( strcmp(lastSegName
, sect
->segmentName()) != 0 ) {
506 address
= _options
.customSegmentAddress(sect
->segmentName());
507 lastSegName
= sect
->segmentName();
510 // adjust section address based on alignment
511 uint64_t unalignedAddress
= address
;
512 uint64_t alignment
= (1 << sect
->alignment
);
513 address
= ( (unalignedAddress
+alignment
-1) & (-alignment
) );
515 // update section info
516 sect
->address
= address
;
517 sect
->alignmentPaddingBytes
= (address
- unalignedAddress
);
520 if ( ((address
+ sect
->size
) > _options
.maxAddress()) && (_options
.outputKind() != Options::kObjectFile
)
521 && (_options
.outputKind() != Options::kStaticExecutable
) )
522 throwf("section %s (address=0x%08llX, size=%llu) would make the output executable exceed available address range",
523 sect
->sectionName(), address
, sect
->size
);
525 if ( log
) fprintf(stderr
, " address=0x%08llX, hidden=%d, alignment=%02d, section=%s,%s\n",
526 sect
->address
, sect
->isSectionHidden(), sect
->alignment
, sect
->segmentName(), sect
->sectionName());
527 // update running totals
528 if ( !sect
->isSectionHidden() || hiddenSectionsOccupyAddressSpace
)
529 address
+= sect
->size
;
531 // if TEXT segment address is fixed, then flow other segments after it
532 if ( strcmp(sect
->segmentName(), "__TEXT") == 0 ) {
533 floatingAddressStart
= address
;
537 // second pass, assign section address to sections in segments that are contiguous with previous segment
538 address
= floatingAddressStart
;
540 ld::Internal::FinalSection
* overlappingFixedSection
= NULL
;
541 ld::Internal::FinalSection
* overlappingFlowSection
= NULL
;
542 if ( log
) fprintf(stderr
, "Regular layout segments:\n");
543 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
544 ld::Internal::FinalSection
* sect
= *it
;
545 if ( _options
.hasCustomSegmentAddress(sect
->segmentName()) )
547 if ( (_options
.outputKind() == Options::kPreload
) && (sect
->type() == ld::Section::typeMachHeader
) ) {
548 sect
->alignmentPaddingBytes
= 0;
551 if ( segmentsArePageAligned
) {
552 if ( strcmp(lastSegName
, sect
->segmentName()) != 0 ) {
553 // round up size of last segment if needed
554 if ( *lastSegName
!= '\0' ) {
555 address
= pageAlign(address
, _options
.segPageSize(lastSegName
));
557 // set segment address based on end of last segment
558 address
= pageAlign(address
);
559 lastSegName
= sect
->segmentName();
562 // adjust section address based on alignment
563 uint64_t unalignedAddress
= address
;
564 uint64_t alignment
= (1 << sect
->alignment
);
565 address
= ( (unalignedAddress
+alignment
-1) & (-alignment
) );
567 // update section info
568 sect
->address
= address
;
569 sect
->alignmentPaddingBytes
= (address
- unalignedAddress
);
572 if ( ((address
+ sect
->size
) > _options
.maxAddress()) && (_options
.outputKind() != Options::kObjectFile
)
573 && (_options
.outputKind() != Options::kStaticExecutable
) )
574 throwf("section %s (address=0x%08llX, size=%llu) would make the output executable exceed available address range",
575 sect
->sectionName(), address
, sect
->size
);
577 // sanity check it does not overlap a fixed address segment
578 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
579 ld::Internal::FinalSection
* otherSect
= *sit
;
580 if ( ! _options
.hasCustomSegmentAddress(otherSect
->segmentName()) )
582 if ( sect
->address
> otherSect
->address
) {
583 if ( (otherSect
->address
+otherSect
->size
) > sect
->address
) {
584 overlappingFixedSection
= otherSect
;
585 overlappingFlowSection
= sect
;
589 if ( (sect
->address
+sect
->size
) > otherSect
->address
) {
590 overlappingFixedSection
= otherSect
;
591 overlappingFlowSection
= sect
;
596 if ( log
) fprintf(stderr
, " address=0x%08llX, size=0x%08llX, hidden=%d, alignment=%02d, padBytes=%d, section=%s,%s\n",
597 sect
->address
, sect
->size
, sect
->isSectionHidden(), sect
->alignment
, sect
->alignmentPaddingBytes
,
598 sect
->segmentName(), sect
->sectionName());
599 // update running totals
600 if ( !sect
->isSectionHidden() || hiddenSectionsOccupyAddressSpace
)
601 address
+= sect
->size
;
603 if ( overlappingFixedSection
!= NULL
) {
604 fprintf(stderr
, "Section layout:\n");
605 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
606 ld::Internal::FinalSection
* sect
= *it
;
607 if ( sect
->isSectionHidden() )
609 fprintf(stderr
, " address:0x%08llX, alignment:2^%d, size:0x%08llX, padBytes:%d, section:%s/%s\n",
610 sect
->address
, sect
->alignment
, sect
->size
, sect
->alignmentPaddingBytes
,
611 sect
->segmentName(), sect
->sectionName());
614 throwf("Section (%s/%s) overlaps fixed address section (%s/%s)",
615 overlappingFlowSection
->segmentName(), overlappingFlowSection
->sectionName(),
616 overlappingFixedSection
->segmentName(), overlappingFixedSection
->sectionName());
620 // third pass, assign section file offsets
621 uint64_t fileOffset
= 0;
623 if ( log
) fprintf(stderr
, "All segments with file offsets:\n");
624 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
625 ld::Internal::FinalSection
* sect
= *it
;
626 if ( hasZeroForFileOffset(sect
) ) {
627 // fileoff of zerofill sections is moot, but historically it is set to zero
628 sect
->fileOffset
= 0;
630 // <rdar://problem/10445047> align file offset with address layout
631 fileOffset
+= sect
->alignmentPaddingBytes
;
634 // page align file offset at start of each segment
635 if ( segmentsArePageAligned
&& (*lastSegName
!= '\0') && (strcmp(lastSegName
, sect
->segmentName()) != 0) ) {
636 fileOffset
= pageAlign(fileOffset
, _options
.segPageSize(lastSegName
));
638 lastSegName
= sect
->segmentName();
640 // align file offset with address layout
641 fileOffset
+= sect
->alignmentPaddingBytes
;
643 // update section info
644 sect
->fileOffset
= fileOffset
;
646 // update running total
647 fileOffset
+= sect
->size
;
650 if ( log
) fprintf(stderr
, " fileoffset=0x%08llX, address=0x%08llX, hidden=%d, size=%lld, alignment=%02d, section=%s,%s\n",
651 sect
->fileOffset
, sect
->address
, sect
->isSectionHidden(), sect
->size
, sect
->alignment
,
652 sect
->segmentName(), sect
->sectionName());
656 // for encrypted iPhoneOS apps
657 if ( _options
.makeEncryptable() ) {
658 // remember end of __TEXT for later use by load command
659 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
660 ld::Internal::FinalSection
* sect
= *it
;
661 if ( strcmp(sect
->segmentName(), "__TEXT") == 0 ) {
662 _encryptedTEXTendOffset
= pageAlign(sect
->fileOffset
+ sect
->size
);
667 // remember total file size
668 _fileSize
= fileOffset
;
672 static const char* makeName(const ld::Atom
& atom
)
674 static char buffer
[4096];
675 switch ( atom
.symbolTableInclusion() ) {
676 case ld::Atom::symbolTableNotIn
:
677 case ld::Atom::symbolTableNotInFinalLinkedImages
:
678 sprintf(buffer
, "%s@0x%08llX", atom
.name(), atom
.objectAddress());
680 case ld::Atom::symbolTableIn
:
681 case ld::Atom::symbolTableInAndNeverStrip
:
682 case ld::Atom::symbolTableInAsAbsolute
:
683 case ld::Atom::symbolTableInWithRandomAutoStripLabel
:
684 strlcpy(buffer
, atom
.name(), 4096);
690 static const char* referenceTargetAtomName(ld::Internal
& state
, const ld::Fixup
* ref
)
692 switch ( ref
->binding
) {
693 case ld::Fixup::bindingNone
:
695 case ld::Fixup::bindingByNameUnbound
:
696 return (char*)(ref
->u
.target
);
697 case ld::Fixup::bindingByContentBound
:
698 case ld::Fixup::bindingDirectlyBound
:
699 return makeName(*((ld::Atom
*)(ref
->u
.target
)));
700 case ld::Fixup::bindingsIndirectlyBound
:
701 return makeName(*state
.indirectBindingTable
[ref
->u
.bindingIndex
]);
703 return "BAD BINDING";
706 bool OutputFile::targetIsThumb(ld::Internal
& state
, const ld::Fixup
* fixup
)
708 switch ( fixup
->binding
) {
709 case ld::Fixup::bindingByContentBound
:
710 case ld::Fixup::bindingDirectlyBound
:
711 return fixup
->u
.target
->isThumb();
712 case ld::Fixup::bindingsIndirectlyBound
:
713 return state
.indirectBindingTable
[fixup
->u
.bindingIndex
]->isThumb();
717 throw "unexpected binding";
720 uint64_t OutputFile::addressOf(const ld::Internal
& state
, const ld::Fixup
* fixup
, const ld::Atom
** target
)
722 if ( !_options
.makeCompressedDyldInfo() ) {
723 // For external relocations the classic mach-o format
724 // has addend only stored in the content. That means
725 // that the address of the target is not used.
726 if ( fixup
->contentAddendOnly
)
729 switch ( fixup
->binding
) {
730 case ld::Fixup::bindingNone
:
731 throw "unexpected bindingNone";
732 case ld::Fixup::bindingByNameUnbound
:
733 throw "unexpected bindingByNameUnbound";
734 case ld::Fixup::bindingByContentBound
:
735 case ld::Fixup::bindingDirectlyBound
:
736 *target
= fixup
->u
.target
;
737 return (*target
)->finalAddress();
738 case ld::Fixup::bindingsIndirectlyBound
:
739 *target
= state
.indirectBindingTable
[fixup
->u
.bindingIndex
];
741 if ( ! (*target
)->finalAddressMode() ) {
742 throwf("reference to symbol (which has not been assigned an address) %s", (*target
)->name());
745 return (*target
)->finalAddress();
747 throw "unexpected binding";
750 uint64_t OutputFile::sectionOffsetOf(const ld::Internal
& state
, const ld::Fixup
* fixup
)
752 const ld::Atom
* target
= NULL
;
753 switch ( fixup
->binding
) {
754 case ld::Fixup::bindingNone
:
755 throw "unexpected bindingNone";
756 case ld::Fixup::bindingByNameUnbound
:
757 throw "unexpected bindingByNameUnbound";
758 case ld::Fixup::bindingByContentBound
:
759 case ld::Fixup::bindingDirectlyBound
:
760 target
= fixup
->u
.target
;
762 case ld::Fixup::bindingsIndirectlyBound
:
763 target
= state
.indirectBindingTable
[fixup
->u
.bindingIndex
];
766 assert(target
!= NULL
);
768 uint64_t targetAddress
= target
->finalAddress();
769 for (std::vector
<ld::Internal::FinalSection
*>::const_iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
770 const ld::Internal::FinalSection
* sect
= *it
;
771 if ( (sect
->address
<= targetAddress
) && (targetAddress
< (sect
->address
+sect
->size
)) )
772 return targetAddress
- sect
->address
;
774 throw "section not found for section offset";
779 uint64_t OutputFile::tlvTemplateOffsetOf(const ld::Internal
& state
, const ld::Fixup
* fixup
)
781 const ld::Atom
* target
= NULL
;
782 switch ( fixup
->binding
) {
783 case ld::Fixup::bindingNone
:
784 throw "unexpected bindingNone";
785 case ld::Fixup::bindingByNameUnbound
:
786 throw "unexpected bindingByNameUnbound";
787 case ld::Fixup::bindingByContentBound
:
788 case ld::Fixup::bindingDirectlyBound
:
789 target
= fixup
->u
.target
;
791 case ld::Fixup::bindingsIndirectlyBound
:
792 target
= state
.indirectBindingTable
[fixup
->u
.bindingIndex
];
795 assert(target
!= NULL
);
797 for (std::vector
<ld::Internal::FinalSection
*>::const_iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
798 const ld::Internal::FinalSection
* sect
= *it
;
799 switch ( sect
->type() ) {
800 case ld::Section::typeTLVInitialValues
:
801 case ld::Section::typeTLVZeroFill
:
802 return target
->finalAddress() - sect
->address
;
807 throw "section not found for tlvTemplateOffsetOf";
810 void OutputFile::printSectionLayout(ld::Internal
& state
)
812 // show layout of final image
813 fprintf(stderr
, "final section layout:\n");
814 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
815 if ( (*it
)->isSectionHidden() )
817 fprintf(stderr
, " %s/%s addr=0x%08llX, size=0x%08llX, fileOffset=0x%08llX, type=%d\n",
818 (*it
)->segmentName(), (*it
)->sectionName(),
819 (*it
)->address
, (*it
)->size
, (*it
)->fileOffset
, (*it
)->type());
824 void OutputFile::rangeCheck8(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
826 if ( (displacement
> 127) || (displacement
< -128) ) {
827 // show layout of final image
828 printSectionLayout(state
);
830 const ld::Atom
* target
;
831 throwf("8-bit reference out of range (%lld max is +/-127B): from %s (0x%08llX) to %s (0x%08llX)",
832 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
833 addressOf(state
, fixup
, &target
));
837 void OutputFile::rangeCheck16(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
839 const int64_t thirtyTwoKLimit
= 0x00007FFF;
840 if ( (displacement
> thirtyTwoKLimit
) || (displacement
< (-thirtyTwoKLimit
)) ) {
841 // show layout of final image
842 printSectionLayout(state
);
844 const ld::Atom
* target
;
845 throwf("16-bit reference out of range (%lld max is +/-32KB): from %s (0x%08llX) to %s (0x%08llX)",
846 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
847 addressOf(state
, fixup
, &target
));
851 void OutputFile::rangeCheckBranch32(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
853 const int64_t twoGigLimit
= 0x7FFFFFFF;
854 if ( (displacement
> twoGigLimit
) || (displacement
< (-twoGigLimit
)) ) {
855 // show layout of final image
856 printSectionLayout(state
);
858 const ld::Atom
* target
;
859 throwf("32-bit branch out of range (%lld max is +/-2GB): from %s (0x%08llX) to %s (0x%08llX)",
860 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
861 addressOf(state
, fixup
, &target
));
866 void OutputFile::rangeCheckAbsolute32(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
868 const int64_t fourGigLimit
= 0xFFFFFFFF;
869 if ( displacement
> fourGigLimit
) {
870 // <rdar://problem/9610466> cannot enforce 32-bit range checks on 32-bit archs because assembler loses sign information
871 // .long _foo - 0xC0000000
872 // is encoded in mach-o the same as:
873 // .long _foo + 0x40000000
874 // so if _foo lays out to 0xC0000100, the first is ok, but the second is not.
875 if ( (_options
.architecture() == CPU_TYPE_ARM
) || (_options
.architecture() == CPU_TYPE_I386
) ) {
876 // Unlikely userland code does funky stuff like this, so warn for them, but not warn for -preload
877 if ( _options
.outputKind() != Options::kPreload
) {
878 warning("32-bit absolute address out of range (0x%08llX max is 4GB): from %s + 0x%08X (0x%08llX) to 0x%08llX",
879 displacement
, atom
->name(), fixup
->offsetInAtom
, atom
->finalAddress(), displacement
);
883 // show layout of final image
884 printSectionLayout(state
);
886 const ld::Atom
* target
;
887 if ( fixup
->binding
== ld::Fixup::bindingNone
)
888 throwf("32-bit absolute address out of range (0x%08llX max is 4GB): from %s + 0x%08X (0x%08llX) to 0x%08llX",
889 displacement
, atom
->name(), fixup
->offsetInAtom
, atom
->finalAddress(), displacement
);
891 throwf("32-bit absolute address out of range (0x%08llX max is 4GB): from %s + 0x%08X (0x%08llX) to %s (0x%08llX)",
892 displacement
, atom
->name(), fixup
->offsetInAtom
, atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
893 addressOf(state
, fixup
, &target
));
898 void OutputFile::rangeCheckRIP32(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
900 const int64_t twoGigLimit
= 0x7FFFFFFF;
901 if ( (displacement
> twoGigLimit
) || (displacement
< (-twoGigLimit
)) ) {
902 // show layout of final image
903 printSectionLayout(state
);
905 const ld::Atom
* target
;
906 throwf("32-bit RIP relative reference out of range (%lld max is +/-4GB): from %s (0x%08llX) to %s (0x%08llX)",
907 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
908 addressOf(state
, fixup
, &target
));
912 void OutputFile::rangeCheckARM12(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
914 if ( (displacement
> 4092LL) || (displacement
< (-4092LL)) ) {
915 // show layout of final image
916 printSectionLayout(state
);
918 const ld::Atom
* target
;
919 throwf("ARM ldr 12-bit displacement out of range (%lld max is +/-4096B): from %s (0x%08llX) to %s (0x%08llX)",
920 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
921 addressOf(state
, fixup
, &target
));
926 void OutputFile::rangeCheckARMBranch24(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
928 if ( (displacement
> 33554428LL) || (displacement
< (-33554432LL)) ) {
929 // show layout of final image
930 printSectionLayout(state
);
932 const ld::Atom
* target
;
933 throwf("b/bl/blx ARM branch out of range (%lld max is +/-32MB): from %s (0x%08llX) to %s (0x%08llX)",
934 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
935 addressOf(state
, fixup
, &target
));
939 void OutputFile::rangeCheckThumbBranch22(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
941 // thumb2 supports a larger displacement
942 if ( _options
.preferSubArchitecture() && _options
.archSupportsThumb2() ) {
943 if ( (displacement
> 16777214LL) || (displacement
< (-16777216LL)) ) {
944 // show layout of final image
945 printSectionLayout(state
);
947 const ld::Atom
* target
;
948 throwf("b/bl/blx thumb2 branch out of range (%lld max is +/-16MB): from %s (0x%08llX) to %s (0x%08llX)",
949 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
950 addressOf(state
, fixup
, &target
));
954 if ( (displacement
> 4194302LL) || (displacement
< (-4194304LL)) ) {
955 // show layout of final image
956 printSectionLayout(state
);
958 const ld::Atom
* target
;
959 throwf("b/bl/blx thumb1 branch out of range (%lld max is +/-4MB): from %s (0x%08llX) to %s (0x%08llX)",
960 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
961 addressOf(state
, fixup
, &target
));
970 uint16_t OutputFile::get16LE(uint8_t* loc
) { return LittleEndian::get16(*(uint16_t*)loc
); }
971 void OutputFile::set16LE(uint8_t* loc
, uint16_t value
) { LittleEndian::set16(*(uint16_t*)loc
, value
); }
973 uint32_t OutputFile::get32LE(uint8_t* loc
) { return LittleEndian::get32(*(uint32_t*)loc
); }
974 void OutputFile::set32LE(uint8_t* loc
, uint32_t value
) { LittleEndian::set32(*(uint32_t*)loc
, value
); }
976 uint64_t OutputFile::get64LE(uint8_t* loc
) { return LittleEndian::get64(*(uint64_t*)loc
); }
977 void OutputFile::set64LE(uint8_t* loc
, uint64_t value
) { LittleEndian::set64(*(uint64_t*)loc
, value
); }
979 uint16_t OutputFile::get16BE(uint8_t* loc
) { return BigEndian::get16(*(uint16_t*)loc
); }
980 void OutputFile::set16BE(uint8_t* loc
, uint16_t value
) { BigEndian::set16(*(uint16_t*)loc
, value
); }
982 uint32_t OutputFile::get32BE(uint8_t* loc
) { return BigEndian::get32(*(uint32_t*)loc
); }
983 void OutputFile::set32BE(uint8_t* loc
, uint32_t value
) { BigEndian::set32(*(uint32_t*)loc
, value
); }
985 uint64_t OutputFile::get64BE(uint8_t* loc
) { return BigEndian::get64(*(uint64_t*)loc
); }
986 void OutputFile::set64BE(uint8_t* loc
, uint64_t value
) { BigEndian::set64(*(uint64_t*)loc
, value
); }
988 void OutputFile::applyFixUps(ld::Internal
& state
, uint64_t mhAddress
, const ld::Atom
* atom
, uint8_t* buffer
)
990 //fprintf(stderr, "applyFixUps() on %s\n", atom->name());
991 int64_t accumulator
= 0;
992 const ld::Atom
* toTarget
= NULL
;
993 const ld::Atom
* fromTarget
;
995 uint32_t instruction
;
996 uint32_t newInstruction
;
1000 bool thumbTarget
= false;
1001 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(), end
=atom
->fixupsEnd(); fit
!= end
; ++fit
) {
1002 uint8_t* fixUpLocation
= &buffer
[fit
->offsetInAtom
];
1003 switch ( (ld::Fixup::Kind
)(fit
->kind
) ) {
1004 case ld::Fixup::kindNone
:
1005 case ld::Fixup::kindNoneFollowOn
:
1006 case ld::Fixup::kindNoneGroupSubordinate
:
1007 case ld::Fixup::kindNoneGroupSubordinateFDE
:
1008 case ld::Fixup::kindNoneGroupSubordinateLSDA
:
1009 case ld::Fixup::kindNoneGroupSubordinatePersonality
:
1011 case ld::Fixup::kindSetTargetAddress
:
1012 accumulator
= addressOf(state
, fit
, &toTarget
);
1013 thumbTarget
= targetIsThumb(state
, fit
);
1016 if ( fit
->contentAddendOnly
|| fit
->contentDetlaToAddendOnly
)
1019 case ld::Fixup::kindSubtractTargetAddress
:
1020 delta
= addressOf(state
, fit
, &fromTarget
);
1021 if ( ! fit
->contentAddendOnly
)
1022 accumulator
-= delta
;
1024 case ld::Fixup::kindAddAddend
:
1025 // <rdar://problem/8342028> ARM main executables main contain .long constants pointing
1026 // into themselves such as jump tables. These .long should not have thumb bit set
1027 // even though the target is a thumb instruction. We can tell it is an interior pointer
1028 // because we are processing an addend.
1029 if ( thumbTarget
&& (toTarget
== atom
) && ((int32_t)fit
->u
.addend
> 0) ) {
1030 accumulator
&= (-2);
1031 //warning("removing thumb bit from intra-atom pointer in %s %s+0x%0X",
1032 // atom->section().sectionName(), atom->name(), fit->offsetInAtom);
1034 accumulator
+= fit
->u
.addend
;
1036 case ld::Fixup::kindSubtractAddend
:
1037 accumulator
-= fit
->u
.addend
;
1039 case ld::Fixup::kindSetTargetImageOffset
:
1040 accumulator
= addressOf(state
, fit
, &toTarget
) - mhAddress
;
1042 case ld::Fixup::kindSetTargetSectionOffset
:
1043 accumulator
= sectionOffsetOf(state
, fit
);
1045 case ld::Fixup::kindSetTargetTLVTemplateOffset
:
1046 accumulator
= tlvTemplateOffsetOf(state
, fit
);
1048 case ld::Fixup::kindStore8
:
1049 *fixUpLocation
+= accumulator
;
1051 case ld::Fixup::kindStoreLittleEndian16
:
1052 set16LE(fixUpLocation
, accumulator
);
1054 case ld::Fixup::kindStoreLittleEndianLow24of32
:
1055 set32LE(fixUpLocation
, (get32LE(fixUpLocation
) & 0xFF000000) | (accumulator
& 0x00FFFFFF) );
1057 case ld::Fixup::kindStoreLittleEndian32
:
1058 rangeCheckAbsolute32(accumulator
, state
, atom
, fit
);
1059 set32LE(fixUpLocation
, accumulator
);
1061 case ld::Fixup::kindStoreLittleEndian64
:
1062 set64LE(fixUpLocation
, accumulator
);
1064 case ld::Fixup::kindStoreBigEndian16
:
1065 set16BE(fixUpLocation
, accumulator
);
1067 case ld::Fixup::kindStoreBigEndianLow24of32
:
1068 set32BE(fixUpLocation
, (get32BE(fixUpLocation
) & 0xFF000000) | (accumulator
& 0x00FFFFFF) );
1070 case ld::Fixup::kindStoreBigEndian32
:
1071 rangeCheckAbsolute32(accumulator
, state
, atom
, fit
);
1072 set32BE(fixUpLocation
, accumulator
);
1074 case ld::Fixup::kindStoreBigEndian64
:
1075 set64BE(fixUpLocation
, accumulator
);
1077 case ld::Fixup::kindStoreX86PCRel8
:
1078 case ld::Fixup::kindStoreX86BranchPCRel8
:
1079 if ( fit
->contentAddendOnly
)
1080 delta
= accumulator
;
1082 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 1);
1083 rangeCheck8(delta
, state
, atom
, fit
);
1084 *fixUpLocation
= delta
;
1086 case ld::Fixup::kindStoreX86PCRel16
:
1087 if ( fit
->contentAddendOnly
)
1088 delta
= accumulator
;
1090 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 2);
1091 rangeCheck16(delta
, state
, atom
, fit
);
1092 set16LE(fixUpLocation
, delta
);
1094 case ld::Fixup::kindStoreX86BranchPCRel32
:
1095 if ( fit
->contentAddendOnly
)
1096 delta
= accumulator
;
1098 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1099 rangeCheckBranch32(delta
, state
, atom
, fit
);
1100 set32LE(fixUpLocation
, delta
);
1102 case ld::Fixup::kindStoreX86PCRel32GOTLoad
:
1103 case ld::Fixup::kindStoreX86PCRel32GOT
:
1104 case ld::Fixup::kindStoreX86PCRel32
:
1105 case ld::Fixup::kindStoreX86PCRel32TLVLoad
:
1106 if ( fit
->contentAddendOnly
)
1107 delta
= accumulator
;
1109 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1110 rangeCheckRIP32(delta
, state
, atom
, fit
);
1111 set32LE(fixUpLocation
, delta
);
1113 case ld::Fixup::kindStoreX86PCRel32_1
:
1114 if ( fit
->contentAddendOnly
)
1115 delta
= accumulator
- 1;
1117 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 5);
1118 rangeCheckRIP32(delta
, state
, atom
, fit
);
1119 set32LE(fixUpLocation
, delta
);
1121 case ld::Fixup::kindStoreX86PCRel32_2
:
1122 if ( fit
->contentAddendOnly
)
1123 delta
= accumulator
- 2;
1125 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 6);
1126 rangeCheckRIP32(delta
, state
, atom
, fit
);
1127 set32LE(fixUpLocation
, delta
);
1129 case ld::Fixup::kindStoreX86PCRel32_4
:
1130 if ( fit
->contentAddendOnly
)
1131 delta
= accumulator
- 4;
1133 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 8);
1134 rangeCheckRIP32(delta
, state
, atom
, fit
);
1135 set32LE(fixUpLocation
, delta
);
1137 case ld::Fixup::kindStoreX86Abs32TLVLoad
:
1138 set32LE(fixUpLocation
, accumulator
);
1140 case ld::Fixup::kindStoreX86Abs32TLVLoadNowLEA
:
1141 assert(_options
.outputKind() != Options::kObjectFile
);
1142 // TLV entry was optimized away, change movl instruction to a leal
1143 if ( fixUpLocation
[-1] != 0xA1 )
1144 throw "TLV load reloc does not point to a movl instruction";
1145 fixUpLocation
[-1] = 0xB8;
1146 set32LE(fixUpLocation
, accumulator
);
1148 case ld::Fixup::kindStoreX86PCRel32GOTLoadNowLEA
:
1149 assert(_options
.outputKind() != Options::kObjectFile
);
1150 // GOT entry was optimized away, change movq instruction to a leaq
1151 if ( fixUpLocation
[-2] != 0x8B )
1152 throw "GOT load reloc does not point to a movq instruction";
1153 fixUpLocation
[-2] = 0x8D;
1154 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1155 rangeCheckRIP32(delta
, state
, atom
, fit
);
1156 set32LE(fixUpLocation
, delta
);
1158 case ld::Fixup::kindStoreX86PCRel32TLVLoadNowLEA
:
1159 assert(_options
.outputKind() != Options::kObjectFile
);
1160 // TLV entry was optimized away, change movq instruction to a leaq
1161 if ( fixUpLocation
[-2] != 0x8B )
1162 throw "TLV load reloc does not point to a movq instruction";
1163 fixUpLocation
[-2] = 0x8D;
1164 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1165 rangeCheckRIP32(delta
, state
, atom
, fit
);
1166 set32LE(fixUpLocation
, delta
);
1168 case ld::Fixup::kindStoreTargetAddressARMLoad12
:
1169 accumulator
= addressOf(state
, fit
, &toTarget
);
1170 // fall into kindStoreARMLoad12 case
1171 case ld::Fixup::kindStoreARMLoad12
:
1172 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 8);
1173 rangeCheckARM12(delta
, state
, atom
, fit
);
1174 instruction
= get32LE(fixUpLocation
);
1176 newInstruction
= instruction
& 0xFFFFF000;
1177 newInstruction
|= ((uint32_t)delta
& 0xFFF);
1180 newInstruction
= instruction
& 0xFF7FF000;
1181 newInstruction
|= ((uint32_t)(-delta
) & 0xFFF);
1183 set32LE(fixUpLocation
, newInstruction
);
1185 case ld::Fixup::kindDtraceExtra
:
1187 case ld::Fixup::kindStoreX86DtraceCallSiteNop
:
1188 if ( _options
.outputKind() != Options::kObjectFile
) {
1189 // change call site to a NOP
1190 fixUpLocation
[-1] = 0x90; // 1-byte nop
1191 fixUpLocation
[0] = 0x0F; // 4-byte nop
1192 fixUpLocation
[1] = 0x1F;
1193 fixUpLocation
[2] = 0x40;
1194 fixUpLocation
[3] = 0x00;
1197 case ld::Fixup::kindStoreX86DtraceIsEnableSiteClear
:
1198 if ( _options
.outputKind() != Options::kObjectFile
) {
1199 // change call site to a clear eax
1200 fixUpLocation
[-1] = 0x33; // xorl eax,eax
1201 fixUpLocation
[0] = 0xC0;
1202 fixUpLocation
[1] = 0x90; // 1-byte nop
1203 fixUpLocation
[2] = 0x90; // 1-byte nop
1204 fixUpLocation
[3] = 0x90; // 1-byte nop
1207 case ld::Fixup::kindStoreARMDtraceCallSiteNop
:
1208 if ( _options
.outputKind() != Options::kObjectFile
) {
1209 // change call site to a NOP
1210 set32LE(fixUpLocation
, 0xE1A00000);
1213 case ld::Fixup::kindStoreARMDtraceIsEnableSiteClear
:
1214 if ( _options
.outputKind() != Options::kObjectFile
) {
1215 // change call site to 'eor r0, r0, r0'
1216 set32LE(fixUpLocation
, 0xE0200000);
1219 case ld::Fixup::kindStoreThumbDtraceCallSiteNop
:
1220 if ( _options
.outputKind() != Options::kObjectFile
) {
1221 // change 32-bit blx call site to two thumb NOPs
1222 set32LE(fixUpLocation
, 0x46C046C0);
1225 case ld::Fixup::kindStoreThumbDtraceIsEnableSiteClear
:
1226 if ( _options
.outputKind() != Options::kObjectFile
) {
1227 // change 32-bit blx call site to 'nop', 'eor r0, r0'
1228 set32LE(fixUpLocation
, 0x46C04040);
1231 case ld::Fixup::kindLazyTarget
:
1233 case ld::Fixup::kindSetLazyOffset
:
1234 assert(fit
->binding
== ld::Fixup::bindingDirectlyBound
);
1235 accumulator
= this->lazyBindingInfoOffsetForLazyPointerAddress(fit
->u
.target
->finalAddress());
1237 case ld::Fixup::kindDataInCodeStartData
:
1238 case ld::Fixup::kindDataInCodeStartJT8
:
1239 case ld::Fixup::kindDataInCodeStartJT16
:
1240 case ld::Fixup::kindDataInCodeStartJT32
:
1241 case ld::Fixup::kindDataInCodeStartJTA32
:
1242 case ld::Fixup::kindDataInCodeEnd
:
1244 case ld::Fixup::kindStoreTargetAddressLittleEndian32
:
1245 accumulator
= addressOf(state
, fit
, &toTarget
);
1246 thumbTarget
= targetIsThumb(state
, fit
);
1249 if ( fit
->contentAddendOnly
)
1251 rangeCheckAbsolute32(accumulator
, state
, atom
, fit
);
1252 set32LE(fixUpLocation
, accumulator
);
1254 case ld::Fixup::kindStoreTargetAddressLittleEndian64
:
1255 accumulator
= addressOf(state
, fit
, &toTarget
);
1256 if ( fit
->contentAddendOnly
)
1258 set64LE(fixUpLocation
, accumulator
);
1260 case ld::Fixup::kindStoreTargetAddressBigEndian32
:
1261 accumulator
= addressOf(state
, fit
, &toTarget
);
1262 if ( fit
->contentAddendOnly
)
1264 set32BE(fixUpLocation
, accumulator
);
1266 case ld::Fixup::kindStoreTargetAddressBigEndian64
:
1267 accumulator
= addressOf(state
, fit
, &toTarget
);
1268 if ( fit
->contentAddendOnly
)
1270 set64BE(fixUpLocation
, accumulator
);
1272 case ld::Fixup::kindSetTargetTLVTemplateOffsetLittleEndian32
:
1273 accumulator
= tlvTemplateOffsetOf(state
, fit
);
1274 set32LE(fixUpLocation
, accumulator
);
1276 case ld::Fixup::kindSetTargetTLVTemplateOffsetLittleEndian64
:
1277 accumulator
= tlvTemplateOffsetOf(state
, fit
);
1278 set64LE(fixUpLocation
, accumulator
);
1280 case ld::Fixup::kindStoreTargetAddressX86PCRel32
:
1281 case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32
:
1282 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad
:
1283 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoad
:
1284 accumulator
= addressOf(state
, fit
, &toTarget
);
1285 if ( fit
->contentDetlaToAddendOnly
)
1287 if ( fit
->contentAddendOnly
)
1290 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1291 rangeCheckRIP32(delta
, state
, atom
, fit
);
1292 set32LE(fixUpLocation
, delta
);
1294 case ld::Fixup::kindStoreTargetAddressX86Abs32TLVLoad
:
1295 set32LE(fixUpLocation
, accumulator
);
1297 case ld::Fixup::kindStoreTargetAddressX86Abs32TLVLoadNowLEA
:
1298 // TLV entry was optimized away, change movl instruction to a leal
1299 if ( fixUpLocation
[-1] != 0xA1 )
1300 throw "TLV load reloc does not point to a movl <abs-address>,<reg> instruction";
1301 fixUpLocation
[-1] = 0xB8;
1302 accumulator
= addressOf(state
, fit
, &toTarget
);
1303 set32LE(fixUpLocation
, accumulator
);
1305 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA
:
1306 // GOT entry was optimized away, change movq instruction to a leaq
1307 if ( fixUpLocation
[-2] != 0x8B )
1308 throw "GOT load reloc does not point to a movq instruction";
1309 fixUpLocation
[-2] = 0x8D;
1310 accumulator
= addressOf(state
, fit
, &toTarget
);
1311 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1312 rangeCheckRIP32(delta
, state
, atom
, fit
);
1313 set32LE(fixUpLocation
, delta
);
1315 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoadNowLEA
:
1316 // TLV entry was optimized away, change movq instruction to a leaq
1317 if ( fixUpLocation
[-2] != 0x8B )
1318 throw "TLV load reloc does not point to a movq instruction";
1319 fixUpLocation
[-2] = 0x8D;
1320 accumulator
= addressOf(state
, fit
, &toTarget
);
1321 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1322 rangeCheckRIP32(delta
, state
, atom
, fit
);
1323 set32LE(fixUpLocation
, delta
);
1325 case ld::Fixup::kindStoreTargetAddressARMBranch24
:
1326 accumulator
= addressOf(state
, fit
, &toTarget
);
1327 thumbTarget
= targetIsThumb(state
, fit
);
1330 if ( fit
->contentDetlaToAddendOnly
)
1332 // fall into kindStoreARMBranch24 case
1333 case ld::Fixup::kindStoreARMBranch24
:
1334 // The pc added will be +8 from the pc
1335 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 8);
1336 rangeCheckARMBranch24(delta
, state
, atom
, fit
);
1337 instruction
= get32LE(fixUpLocation
);
1338 // Make sure we are calling arm with bl, thumb with blx
1339 is_bl
= ((instruction
& 0xFF000000) == 0xEB000000);
1340 is_blx
= ((instruction
& 0xFE000000) == 0xFA000000);
1341 is_b
= !is_blx
&& ((instruction
& 0x0F000000) == 0x0A000000);
1342 if ( is_bl
&& thumbTarget
) {
1343 uint32_t opcode
= 0xFA000000;
1344 uint32_t disp
= (uint32_t)(delta
>> 2) & 0x00FFFFFF;
1345 uint32_t h_bit
= (uint32_t)(delta
<< 23) & 0x01000000;
1346 newInstruction
= opcode
| h_bit
| disp
;
1348 else if ( is_blx
&& !thumbTarget
) {
1349 uint32_t opcode
= 0xEB000000;
1350 uint32_t disp
= (uint32_t)(delta
>> 2) & 0x00FFFFFF;
1351 newInstruction
= opcode
| disp
;
1353 else if ( is_b
&& thumbTarget
) {
1354 if ( fit
->contentDetlaToAddendOnly
)
1355 newInstruction
= (instruction
& 0xFF000000) | ((uint32_t)(delta
>> 2) & 0x00FFFFFF);
1357 throwf("no pc-rel bx arm instruction. Can't fix up branch to %s in %s",
1358 referenceTargetAtomName(state
, fit
), atom
->name());
1360 else if ( !is_bl
&& !is_blx
&& thumbTarget
) {
1361 throwf("don't know how to convert instruction %x referencing %s to thumb",
1362 instruction
, referenceTargetAtomName(state
, fit
));
1365 newInstruction
= (instruction
& 0xFF000000) | ((uint32_t)(delta
>> 2) & 0x00FFFFFF);
1367 set32LE(fixUpLocation
, newInstruction
);
1369 case ld::Fixup::kindStoreTargetAddressThumbBranch22
:
1370 accumulator
= addressOf(state
, fit
, &toTarget
);
1371 thumbTarget
= targetIsThumb(state
, fit
);
1374 if ( fit
->contentDetlaToAddendOnly
)
1376 // fall into kindStoreThumbBranch22 case
1377 case ld::Fixup::kindStoreThumbBranch22
:
1378 instruction
= get32LE(fixUpLocation
);
1379 is_bl
= ((instruction
& 0xD000F800) == 0xD000F000);
1380 is_blx
= ((instruction
& 0xD000F800) == 0xC000F000);
1381 is_b
= ((instruction
& 0xD000F800) == 0x9000F000);
1382 // If the target is not thumb, we will be generating a blx instruction
1383 // Since blx cannot have the low bit set, set bit[1] of the target to
1384 // bit[1] of the base address, so that the difference is a multiple of
1386 if ( !thumbTarget
&& !fit
->contentDetlaToAddendOnly
) {
1387 accumulator
&= -3ULL;
1388 accumulator
|= ((atom
->finalAddress() + fit
->offsetInAtom
) & 2LL);
1390 // The pc added will be +4 from the pc
1391 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1392 rangeCheckThumbBranch22(delta
, state
, atom
, fit
);
1393 if ( _options
.preferSubArchitecture() && _options
.archSupportsThumb2() ) {
1394 // The instruction is really two instructions:
1395 // The lower 16 bits are the first instruction, which contains the high
1396 // 11 bits of the displacement.
1397 // The upper 16 bits are the second instruction, which contains the low
1398 // 11 bits of the displacement, as well as differentiating bl and blx.
1399 uint32_t s
= (uint32_t)(delta
>> 24) & 0x1;
1400 uint32_t i1
= (uint32_t)(delta
>> 23) & 0x1;
1401 uint32_t i2
= (uint32_t)(delta
>> 22) & 0x1;
1402 uint32_t imm10
= (uint32_t)(delta
>> 12) & 0x3FF;
1403 uint32_t imm11
= (uint32_t)(delta
>> 1) & 0x7FF;
1404 uint32_t j1
= (i1
== s
);
1405 uint32_t j2
= (i2
== s
);
1408 instruction
= 0xD000F000; // keep bl
1410 instruction
= 0xC000F000; // change to blx
1412 else if ( is_blx
) {
1414 instruction
= 0xD000F000; // change to bl
1416 instruction
= 0xC000F000; // keep blx
1419 instruction
= 0x9000F000; // keep b
1420 if ( !thumbTarget
&& !fit
->contentDetlaToAddendOnly
) {
1421 throwf("armv7 has no pc-rel bx thumb instruction. Can't fix up branch to %s in %s",
1422 referenceTargetAtomName(state
, fit
), atom
->name());
1427 throwf("don't know how to convert branch instruction %x referencing %s to bx",
1428 instruction
, referenceTargetAtomName(state
, fit
));
1429 instruction
= 0x9000F000; // keep b
1431 uint32_t nextDisp
= (j1
<< 13) | (j2
<< 11) | imm11
;
1432 uint32_t firstDisp
= (s
<< 10) | imm10
;
1433 newInstruction
= instruction
| (nextDisp
<< 16) | firstDisp
;
1434 //warning("s=%d, j1=%d, j2=%d, imm10=0x%0X, imm11=0x%0X, opcode=0x%08X, first=0x%04X, next=0x%04X, new=0x%08X, disp=0x%llX for %s to %s\n",
1435 // s, j1, j2, imm10, imm11, opcode, firstDisp, nextDisp, newInstruction, delta, inAtom->getDisplayName(), ref->getTarget().getDisplayName());
1436 set32LE(fixUpLocation
, newInstruction
);
1439 // The instruction is really two instructions:
1440 // The lower 16 bits are the first instruction, which contains the high
1441 // 11 bits of the displacement.
1442 // The upper 16 bits are the second instruction, which contains the low
1443 // 11 bits of the displacement, as well as differentiating bl and blx.
1444 uint32_t firstDisp
= (uint32_t)(delta
>> 12) & 0x7FF;
1445 uint32_t nextDisp
= (uint32_t)(delta
>> 1) & 0x7FF;
1446 if ( is_bl
&& !thumbTarget
) {
1447 instruction
= 0xE800F000;
1449 else if ( is_blx
&& thumbTarget
) {
1450 instruction
= 0xF800F000;
1453 instruction
= 0x9000F000; // keep b
1454 if ( !thumbTarget
&& !fit
->contentDetlaToAddendOnly
) {
1455 throwf("armv6 has no pc-rel bx thumb instruction. Can't fix up branch to %s in %s",
1456 referenceTargetAtomName(state
, fit
), atom
->name());
1460 instruction
= instruction
& 0xF800F800;
1462 newInstruction
= instruction
| (nextDisp
<< 16) | firstDisp
;
1463 set32LE(fixUpLocation
, newInstruction
);
1466 case ld::Fixup::kindStoreARMLow16
:
1468 uint32_t imm4
= (accumulator
& 0x0000F000) >> 12;
1469 uint32_t imm12
= accumulator
& 0x00000FFF;
1470 instruction
= get32LE(fixUpLocation
);
1471 newInstruction
= (instruction
& 0xFFF0F000) | (imm4
<< 16) | imm12
;
1472 set32LE(fixUpLocation
, newInstruction
);
1475 case ld::Fixup::kindStoreARMHigh16
:
1477 uint32_t imm4
= (accumulator
& 0xF0000000) >> 28;
1478 uint32_t imm12
= (accumulator
& 0x0FFF0000) >> 16;
1479 instruction
= get32LE(fixUpLocation
);
1480 newInstruction
= (instruction
& 0xFFF0F000) | (imm4
<< 16) | imm12
;
1481 set32LE(fixUpLocation
, newInstruction
);
1484 case ld::Fixup::kindStoreThumbLow16
:
1486 uint32_t imm4
= (accumulator
& 0x0000F000) >> 12;
1487 uint32_t i
= (accumulator
& 0x00000800) >> 11;
1488 uint32_t imm3
= (accumulator
& 0x00000700) >> 8;
1489 uint32_t imm8
= accumulator
& 0x000000FF;
1490 instruction
= get32LE(fixUpLocation
);
1491 newInstruction
= (instruction
& 0x8F00FBF0) | imm4
| (i
<< 10) | (imm3
<< 28) | (imm8
<< 16);
1492 set32LE(fixUpLocation
, newInstruction
);
1495 case ld::Fixup::kindStoreThumbHigh16
:
1497 uint32_t imm4
= (accumulator
& 0xF0000000) >> 28;
1498 uint32_t i
= (accumulator
& 0x08000000) >> 27;
1499 uint32_t imm3
= (accumulator
& 0x07000000) >> 24;
1500 uint32_t imm8
= (accumulator
& 0x00FF0000) >> 16;
1501 instruction
= get32LE(fixUpLocation
);
1502 newInstruction
= (instruction
& 0x8F00FBF0) | imm4
| (i
<< 10) | (imm3
<< 28) | (imm8
<< 16);
1503 set32LE(fixUpLocation
, newInstruction
);
1510 void OutputFile::copyNoOps(uint8_t* from
, uint8_t* to
, bool thumb
)
1512 switch ( _options
.architecture() ) {
1514 case CPU_TYPE_X86_64
:
1515 for (uint8_t* p
=from
; p
< to
; ++p
)
1520 for (uint8_t* p
=from
; p
< to
; p
+= 2)
1521 OSWriteLittleInt16((uint16_t*)p
, 0, 0x46c0);
1524 for (uint8_t* p
=from
; p
< to
; p
+= 4)
1525 OSWriteLittleInt32((uint32_t*)p
, 0, 0xe1a00000);
1529 for (uint8_t* p
=from
; p
< to
; ++p
)
1535 bool OutputFile::takesNoDiskSpace(const ld::Section
* sect
)
1537 switch ( sect
->type() ) {
1538 case ld::Section::typeZeroFill
:
1539 case ld::Section::typeTLVZeroFill
:
1540 return _options
.optimizeZeroFill();
1541 case ld::Section::typePageZero
:
1542 case ld::Section::typeStack
:
1543 case ld::Section::typeAbsoluteSymbols
:
1544 case ld::Section::typeTentativeDefs
:
1552 bool OutputFile::hasZeroForFileOffset(const ld::Section
* sect
)
1554 switch ( sect
->type() ) {
1555 case ld::Section::typeZeroFill
:
1556 case ld::Section::typeTLVZeroFill
:
1557 return _options
.optimizeZeroFill();
1558 case ld::Section::typePageZero
:
1559 case ld::Section::typeStack
:
1560 case ld::Section::typeTentativeDefs
:
1568 void OutputFile::writeAtoms(ld::Internal
& state
, uint8_t* wholeBuffer
)
1570 // have each atom write itself
1571 uint64_t fileOffsetOfEndOfLastAtom
= 0;
1572 uint64_t mhAddress
= 0;
1573 bool lastAtomUsesNoOps
= false;
1574 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
1575 ld::Internal::FinalSection
* sect
= *sit
;
1576 if ( sect
->type() == ld::Section::typeMachHeader
)
1577 mhAddress
= sect
->address
;
1578 if ( takesNoDiskSpace(sect
) )
1580 const bool sectionUsesNops
= (sect
->type() == ld::Section::typeCode
);
1581 //fprintf(stderr, "file offset=0x%08llX, section %s\n", sect->fileOffset, sect->sectionName());
1582 std::vector
<const ld::Atom
*>& atoms
= sect
->atoms
;
1583 bool lastAtomWasThumb
= false;
1584 for (std::vector
<const ld::Atom
*>::iterator ait
= atoms
.begin(); ait
!= atoms
.end(); ++ait
) {
1585 const ld::Atom
* atom
= *ait
;
1586 if ( atom
->definition() == ld::Atom::definitionProxy
)
1589 uint64_t fileOffset
= atom
->finalAddress() - sect
->address
+ sect
->fileOffset
;
1590 // check for alignment padding between atoms
1591 if ( (fileOffset
!= fileOffsetOfEndOfLastAtom
) && lastAtomUsesNoOps
) {
1592 this->copyNoOps(&wholeBuffer
[fileOffsetOfEndOfLastAtom
], &wholeBuffer
[fileOffset
], lastAtomWasThumb
);
1594 // copy atom content
1595 atom
->copyRawContent(&wholeBuffer
[fileOffset
]);
1597 this->applyFixUps(state
, mhAddress
, atom
, &wholeBuffer
[fileOffset
]);
1598 fileOffsetOfEndOfLastAtom
= fileOffset
+atom
->size();
1599 lastAtomUsesNoOps
= sectionUsesNops
;
1600 lastAtomWasThumb
= atom
->isThumb();
1602 catch (const char* msg
) {
1603 if ( atom
->file() != NULL
)
1604 throwf("%s in %s from %s", msg
, atom
->name(), atom
->file()->path());
1606 throwf("%s in %s", msg
, atom
->name());
1613 void OutputFile::computeContentUUID(ld::Internal
& state
, uint8_t* wholeBuffer
)
1615 const bool log
= false;
1616 if ( (_options
.outputKind() != Options::kObjectFile
) || state
.someObjectFileHasDwarf
) {
1617 uint8_t digest
[CC_MD5_DIGEST_LENGTH
];
1618 uint32_t stabsStringsOffsetStart
;
1619 uint32_t tabsStringsOffsetEnd
;
1620 uint32_t stabsOffsetStart
;
1621 uint32_t stabsOffsetEnd
;
1622 if ( _symbolTableAtom
->hasStabs(stabsStringsOffsetStart
, tabsStringsOffsetEnd
, stabsOffsetStart
, stabsOffsetEnd
) ) {
1623 // find two areas of file that are stabs info and should not contribute to checksum
1624 uint64_t stringPoolFileOffset
= 0;
1625 uint64_t symbolTableFileOffset
= 0;
1626 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
1627 ld::Internal::FinalSection
* sect
= *sit
;
1628 if ( sect
->type() == ld::Section::typeLinkEdit
) {
1629 if ( strcmp(sect
->sectionName(), "__string_pool") == 0 )
1630 stringPoolFileOffset
= sect
->fileOffset
;
1631 else if ( strcmp(sect
->sectionName(), "__symbol_table") == 0 )
1632 symbolTableFileOffset
= sect
->fileOffset
;
1635 uint64_t firstStabNlistFileOffset
= symbolTableFileOffset
+ stabsOffsetStart
;
1636 uint64_t lastStabNlistFileOffset
= symbolTableFileOffset
+ stabsOffsetEnd
;
1637 uint64_t firstStabStringFileOffset
= stringPoolFileOffset
+ stabsStringsOffsetStart
;
1638 uint64_t lastStabStringFileOffset
= stringPoolFileOffset
+ tabsStringsOffsetEnd
;
1639 if ( log
) fprintf(stderr
, "firstStabNlistFileOffset=0x%08llX\n", firstStabNlistFileOffset
);
1640 if ( log
) fprintf(stderr
, "lastStabNlistFileOffset=0x%08llX\n", lastStabNlistFileOffset
);
1641 if ( log
) fprintf(stderr
, "firstStabStringFileOffset=0x%08llX\n", firstStabStringFileOffset
);
1642 if ( log
) fprintf(stderr
, "lastStabStringFileOffset=0x%08llX\n", lastStabStringFileOffset
);
1643 assert(firstStabNlistFileOffset
<= firstStabStringFileOffset
);
1645 CC_MD5_CTX md5state
;
1646 CC_MD5_Init(&md5state
);
1647 // checksum everything up to first stabs nlist
1648 if ( log
) fprintf(stderr
, "checksum 0x%08X -> 0x%08llX\n", 0, firstStabNlistFileOffset
);
1649 CC_MD5_Update(&md5state
, &wholeBuffer
[0], firstStabNlistFileOffset
);
1650 // checkusm everything after last stabs nlist and up to first stabs string
1651 if ( log
) fprintf(stderr
, "checksum 0x%08llX -> 0x%08llX\n", lastStabNlistFileOffset
, firstStabStringFileOffset
);
1652 CC_MD5_Update(&md5state
, &wholeBuffer
[lastStabNlistFileOffset
], firstStabStringFileOffset
-lastStabNlistFileOffset
);
1653 // checksum everything after last stabs string to end of file
1654 if ( log
) fprintf(stderr
, "checksum 0x%08llX -> 0x%08llX\n", lastStabStringFileOffset
, _fileSize
);
1655 CC_MD5_Update(&md5state
, &wholeBuffer
[lastStabStringFileOffset
], _fileSize
-lastStabStringFileOffset
);
1656 CC_MD5_Final(digest
, &md5state
);
1657 if ( log
) fprintf(stderr
, "uuid=%02X, %02X, %02X, %02X, %02X, %02X, %02X, %02X\n", digest
[0], digest
[1], digest
[2],
1658 digest
[3], digest
[4], digest
[5], digest
[6], digest
[7]);
1661 CC_MD5(wholeBuffer
, _fileSize
, digest
);
1663 // <rdar://problem/6723729> LC_UUID uuids should conform to RFC 4122 UUID version 4 & UUID version 5 formats
1664 digest
[6] = ( digest
[6] & 0x0F ) | ( 3 << 4 );
1665 digest
[8] = ( digest
[8] & 0x3F ) | 0x80;
1666 // update buffer with new UUID
1667 _headersAndLoadCommandAtom
->setUUID(digest
);
1668 _headersAndLoadCommandAtom
->recopyUUIDCommand();
1673 void OutputFile::writeOutputFile(ld::Internal
& state
)
1675 // for UNIX conformance, error if file exists and is not writable
1676 if ( (access(_options
.outputFilePath(), F_OK
) == 0) && (access(_options
.outputFilePath(), W_OK
) == -1) )
1677 throwf("can't write output file: %s", _options
.outputFilePath());
1679 mode_t permissions
= 0777;
1680 if ( _options
.outputKind() == Options::kObjectFile
)
1682 mode_t umask
= ::umask(0);
1683 ::umask(umask
); // put back the original umask
1684 permissions
&= ~umask
;
1685 // Calling unlink first assures the file is gone so that open creates it with correct permissions
1686 // It also handles the case where __options.outputFilePath() file is not writable but its directory is
1687 // And it means we don't have to truncate the file when done writing (in case new is smaller than old)
1688 // Lastly, only delete existing file if it is a normal file (e.g. not /dev/null).
1689 struct stat stat_buf
;
1690 bool outputIsRegularFile
= true;
1691 if ( stat(_options
.outputFilePath(), &stat_buf
) != -1 ) {
1692 if (stat_buf
.st_mode
& S_IFREG
) {
1693 (void)unlink(_options
.outputFilePath());
1695 outputIsRegularFile
= false;
1700 // Construct a temporary path of the form {outputFilePath}.ld_XXXXXX
1701 const char filenameTemplate
[] = ".ld_XXXXXX";
1702 char tmpOutput
[PATH_MAX
];
1703 uint8_t *wholeBuffer
;
1704 if (outputIsRegularFile
) {
1705 strcpy(tmpOutput
, _options
.outputFilePath());
1706 // If the path is too long to add a suffix for a temporary name then
1707 // just fall back to using the output path.
1708 if (strlen(tmpOutput
)+strlen(filenameTemplate
) < PATH_MAX
) {
1709 strcat(tmpOutput
, filenameTemplate
);
1710 fd
= mkstemp(tmpOutput
);
1712 fd
= open(tmpOutput
, O_RDWR
|O_CREAT
, permissions
);
1715 throwf("can't open output file for writing: %s, errno=%d", tmpOutput
, errno
);
1716 ftruncate(fd
, _fileSize
);
1718 wholeBuffer
= (uint8_t *)mmap(NULL
, _fileSize
, PROT_WRITE
|PROT_READ
, MAP_SHARED
, fd
, 0);
1719 if ( wholeBuffer
== MAP_FAILED
)
1720 throwf("can't create buffer of %llu bytes for output", _fileSize
);
1722 fd
= open(_options
.outputFilePath(), O_WRONLY
);
1724 throwf("can't open output file for writing: %s, errno=%d", _options
.outputFilePath(), errno
);
1725 // try to allocate buffer for entire output file content
1726 wholeBuffer
= (uint8_t*)calloc(_fileSize
, 1);
1727 if ( wholeBuffer
== NULL
)
1728 throwf("can't create buffer of %llu bytes for output", _fileSize
);
1731 if ( _options
.UUIDMode() == Options::kUUIDRandom
) {
1733 ::uuid_generate_random(bits
);
1734 _headersAndLoadCommandAtom
->setUUID(bits
);
1737 writeAtoms(state
, wholeBuffer
);
1740 if ( _options
.UUIDMode() == Options::kUUIDContent
)
1741 computeContentUUID(state
, wholeBuffer
);
1743 if (outputIsRegularFile
) {
1744 if ( ::chmod(tmpOutput
, permissions
) == -1 ) {
1746 throwf("can't set permissions on output file: %s, errno=%d", tmpOutput
, errno
);
1748 if ( ::rename(tmpOutput
, _options
.outputFilePath()) == -1 && strcmp(tmpOutput
, _options
.outputFilePath()) != 0) {
1750 throwf("can't move output file in place, errno=%d", errno
);
1753 if ( ::write(fd
, wholeBuffer
, _fileSize
) == -1 ) {
1754 throwf("can't write to output file: %s, errno=%d", _options
.outputFilePath(), errno
);
1759 struct AtomByNameSorter
1761 bool operator()(const ld::Atom
* left
, const ld::Atom
* right
)
1763 return (strcmp(left
->name(), right
->name()) < 0);
1770 NotInSet(const std::set
<const ld::Atom
*>& theSet
) : _set(theSet
) {}
1772 bool operator()(const ld::Atom
* atom
) const {
1773 return ( _set
.count(atom
) == 0 );
1776 const std::set
<const ld::Atom
*>& _set
;
1780 void OutputFile::buildSymbolTable(ld::Internal
& state
)
1782 unsigned int machoSectionIndex
= 0;
1783 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
1784 ld::Internal::FinalSection
* sect
= *sit
;
1785 bool setMachoSectionIndex
= !sect
->isSectionHidden() && (sect
->type() != ld::Section::typeTentativeDefs
);
1786 if ( setMachoSectionIndex
)
1787 ++machoSectionIndex
;
1788 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
1789 const ld::Atom
* atom
= *ait
;
1790 if ( setMachoSectionIndex
)
1791 (const_cast<ld::Atom
*>(atom
))->setMachoSection(machoSectionIndex
);
1792 else if ( sect
->type() == ld::Section::typeMachHeader
)
1793 (const_cast<ld::Atom
*>(atom
))->setMachoSection(1); // __mh_execute_header is not in any section by needs n_sect==1
1794 else if ( sect
->type() == ld::Section::typeLastSection
)
1795 (const_cast<ld::Atom
*>(atom
))->setMachoSection(machoSectionIndex
); // use section index of previous section
1796 else if ( sect
->type() == ld::Section::typeFirstSection
)
1797 (const_cast<ld::Atom
*>(atom
))->setMachoSection(machoSectionIndex
+1); // use section index of next section
1799 // in -r mode, clarify symbolTableNotInFinalLinkedImages
1800 if ( _options
.outputKind() == Options::kObjectFile
) {
1801 if ( _options
.architecture() == CPU_TYPE_X86_64
) {
1802 // x86_64 .o files need labels on anonymous literal strings
1803 if ( (sect
->type() == ld::Section::typeCString
) && (atom
->combine() == ld::Atom::combineByNameAndContent
) ) {
1804 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableIn
);
1805 _localAtoms
.push_back(atom
);
1809 if ( sect
->type() == ld::Section::typeCFI
) {
1810 if ( _options
.removeEHLabels() )
1811 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableNotIn
);
1813 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableIn
);
1815 if ( atom
->symbolTableInclusion() == ld::Atom::symbolTableNotInFinalLinkedImages
)
1816 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableIn
);
1819 // TEMP work around until <rdar://problem/7702923> goes in
1820 if ( (atom
->symbolTableInclusion() == ld::Atom::symbolTableInAndNeverStrip
)
1821 && (atom
->scope() == ld::Atom::scopeLinkageUnit
)
1822 && (_options
.outputKind() == Options::kDynamicLibrary
) ) {
1823 (const_cast<ld::Atom
*>(atom
))->setScope(ld::Atom::scopeGlobal
);
1826 // <rdar://problem/6783167> support auto hidden weak symbols: .weak_def_can_be_hidden
1827 if ( atom
->autoHide() && (_options
.outputKind() != Options::kObjectFile
) ) {
1828 // adding auto-hide symbol to .exp file should keep it global
1829 if ( !_options
.hasExportMaskList() || !_options
.shouldExport(atom
->name()) )
1830 (const_cast<ld::Atom
*>(atom
))->setScope(ld::Atom::scopeLinkageUnit
);
1833 // <rdar://problem/8626058> ld should consistently warn when resolvers are not exported
1834 if ( (atom
->contentType() == ld::Atom::typeResolver
) && (atom
->scope() == ld::Atom::scopeLinkageUnit
) )
1835 warning("resolver functions should be external, but '%s' is hidden", atom
->name());
1837 if ( sect
->type() == ld::Section::typeImportProxies
) {
1838 if ( atom
->combine() == ld::Atom::combineByName
)
1839 this->usesWeakExternalSymbols
= true;
1840 // alias proxy is a re-export with a name change, don't import changed name
1841 if ( ! atom
->isAlias() )
1842 _importedAtoms
.push_back(atom
);
1843 // scope of proxies are usually linkage unit, so done
1844 // if scope is global, we need to re-export it too
1845 if ( atom
->scope() == ld::Atom::scopeGlobal
)
1846 _exportedAtoms
.push_back(atom
);
1849 if ( atom
->symbolTableInclusion() == ld::Atom::symbolTableNotInFinalLinkedImages
) {
1850 assert(_options
.outputKind() != Options::kObjectFile
);
1851 continue; // don't add to symbol table
1853 if ( atom
->symbolTableInclusion() == ld::Atom::symbolTableNotIn
) {
1854 continue; // don't add to symbol table
1857 if ( (atom
->definition() == ld::Atom::definitionTentative
) && (_options
.outputKind() == Options::kObjectFile
) ) {
1858 if ( _options
.makeTentativeDefinitionsReal() ) {
1859 // -r -d turns tentative defintions into real def
1860 _exportedAtoms
.push_back(atom
);
1863 // in mach-o object files tentative defintions are stored like undefined symbols
1864 _importedAtoms
.push_back(atom
);
1869 switch ( atom
->scope() ) {
1870 case ld::Atom::scopeTranslationUnit
:
1871 if ( _options
.keepLocalSymbol(atom
->name()) ) {
1872 _localAtoms
.push_back(atom
);
1875 if ( _options
.outputKind() == Options::kObjectFile
) {
1876 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableInWithRandomAutoStripLabel
);
1877 _localAtoms
.push_back(atom
);
1880 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableNotIn
);
1883 case ld::Atom::scopeGlobal
:
1884 _exportedAtoms
.push_back(atom
);
1886 case ld::Atom::scopeLinkageUnit
:
1887 if ( _options
.outputKind() == Options::kObjectFile
) {
1888 if ( _options
.keepPrivateExterns() ) {
1889 assert( (atom
->combine() == ld::Atom::combineNever
) || (atom
->combine() == ld::Atom::combineByName
) );
1890 _exportedAtoms
.push_back(atom
);
1892 else if ( _options
.keepLocalSymbol(atom
->name()) ) {
1893 _localAtoms
.push_back(atom
);
1896 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableInWithRandomAutoStripLabel
);
1897 _localAtoms
.push_back(atom
);
1901 if ( _options
.keepLocalSymbol(atom
->name()) )
1902 _localAtoms
.push_back(atom
);
1903 // <rdar://problem/5804214> ld should never have a symbol in the non-lazy indirect symbol table with index 0
1904 // this works by making __mh_execute_header be a local symbol which takes symbol index 0
1905 else if ( (atom
->symbolTableInclusion() == ld::Atom::symbolTableInAndNeverStrip
) && !_options
.makeCompressedDyldInfo() )
1906 _localAtoms
.push_back(atom
);
1908 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableNotIn
);
1915 // <rdar://problem/6978069> ld adds undefined symbol from .exp file to binary
1916 if ( (_options
.outputKind() == Options::kKextBundle
) && _options
.hasExportRestrictList() ) {
1917 // search for referenced undefines
1918 std::set
<const ld::Atom
*> referencedProxyAtoms
;
1919 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
=state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
1920 ld::Internal::FinalSection
* sect
= *sit
;
1921 for (std::vector
<const ld::Atom
*>::iterator ait
=sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
1922 const ld::Atom
* atom
= *ait
;
1923 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(), end
=atom
->fixupsEnd(); fit
!= end
; ++fit
) {
1924 switch ( fit
->binding
) {
1925 case ld::Fixup::bindingsIndirectlyBound
:
1926 referencedProxyAtoms
.insert(state
.indirectBindingTable
[fit
->u
.bindingIndex
]);
1928 case ld::Fixup::bindingDirectlyBound
:
1929 referencedProxyAtoms
.insert(fit
->u
.target
);
1937 // remove any unreferenced _importedAtoms
1938 _importedAtoms
.erase(std::remove_if(_importedAtoms
.begin(), _importedAtoms
.end(), NotInSet(referencedProxyAtoms
)), _importedAtoms
.end());
1942 std::sort(_exportedAtoms
.begin(), _exportedAtoms
.end(), AtomByNameSorter());
1943 std::sort(_importedAtoms
.begin(), _importedAtoms
.end(), AtomByNameSorter());
1946 void OutputFile::addPreloadLinkEdit(ld::Internal
& state
)
1948 switch ( _options
.architecture() ) {
1949 #if SUPPORT_ARCH_i386
1951 if ( _hasLocalRelocations
) {
1952 _localRelocsAtom
= new LocalRelocationsAtom
<x86
>(_options
, state
, *this);
1953 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
1955 if ( _hasExternalRelocations
) {
1956 _externalRelocsAtom
= new ExternalRelocationsAtom
<x86
>(_options
, state
, *this);
1957 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
1959 if ( _hasSymbolTable
) {
1960 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<x86
>(_options
, state
, *this);
1961 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
1962 _symbolTableAtom
= new SymbolTableAtom
<x86
>(_options
, state
, *this);
1963 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
1964 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 4);
1965 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
1969 #if SUPPORT_ARCH_x86_64
1970 case CPU_TYPE_X86_64
:
1971 if ( _hasLocalRelocations
) {
1972 _localRelocsAtom
= new LocalRelocationsAtom
<x86_64
>(_options
, state
, *this);
1973 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
1975 if ( _hasExternalRelocations
) {
1976 _externalRelocsAtom
= new ExternalRelocationsAtom
<x86_64
>(_options
, state
, *this);
1977 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
1979 if ( _hasSymbolTable
) {
1980 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<x86_64
>(_options
, state
, *this);
1981 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
1982 _symbolTableAtom
= new SymbolTableAtom
<x86_64
>(_options
, state
, *this);
1983 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
1984 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 4);
1985 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
1989 #if SUPPORT_ARCH_arm_any
1991 if ( _hasLocalRelocations
) {
1992 _localRelocsAtom
= new LocalRelocationsAtom
<arm
>(_options
, state
, *this);
1993 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
1995 if ( _hasExternalRelocations
) {
1996 _externalRelocsAtom
= new ExternalRelocationsAtom
<arm
>(_options
, state
, *this);
1997 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
1999 if ( _hasSymbolTable
) {
2000 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<arm
>(_options
, state
, *this);
2001 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
2002 _symbolTableAtom
= new SymbolTableAtom
<arm
>(_options
, state
, *this);
2003 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
2004 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 4);
2005 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
2010 throw "architecture not supported for -preload";
2016 void OutputFile::addLinkEdit(ld::Internal
& state
)
2018 // for historical reasons, -preload orders LINKEDIT content differently
2019 if ( _options
.outputKind() == Options::kPreload
)
2020 return addPreloadLinkEdit(state
);
2022 switch ( _options
.architecture() ) {
2023 #if SUPPORT_ARCH_i386
2025 if ( _hasSectionRelocations
) {
2026 _sectionsRelocationsAtom
= new SectionRelocationsAtom
<x86
>(_options
, state
, *this);
2027 sectionRelocationsSection
= state
.addAtom(*_sectionsRelocationsAtom
);
2029 if ( _hasDyldInfo
) {
2030 _rebasingInfoAtom
= new RebaseInfoAtom
<x86
>(_options
, state
, *this);
2031 rebaseSection
= state
.addAtom(*_rebasingInfoAtom
);
2033 _bindingInfoAtom
= new BindingInfoAtom
<x86
>(_options
, state
, *this);
2034 bindingSection
= state
.addAtom(*_bindingInfoAtom
);
2036 _weakBindingInfoAtom
= new WeakBindingInfoAtom
<x86
>(_options
, state
, *this);
2037 weakBindingSection
= state
.addAtom(*_weakBindingInfoAtom
);
2039 _lazyBindingInfoAtom
= new LazyBindingInfoAtom
<x86
>(_options
, state
, *this);
2040 lazyBindingSection
= state
.addAtom(*_lazyBindingInfoAtom
);
2042 _exportInfoAtom
= new ExportInfoAtom
<x86
>(_options
, state
, *this);
2043 exportSection
= state
.addAtom(*_exportInfoAtom
);
2045 if ( _hasLocalRelocations
) {
2046 _localRelocsAtom
= new LocalRelocationsAtom
<x86
>(_options
, state
, *this);
2047 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
2049 if ( _hasSplitSegInfo
) {
2050 _splitSegInfoAtom
= new SplitSegInfoAtom
<x86
>(_options
, state
, *this);
2051 splitSegInfoSection
= state
.addAtom(*_splitSegInfoAtom
);
2053 if ( _hasFunctionStartsInfo
) {
2054 _functionStartsAtom
= new FunctionStartsAtom
<x86
>(_options
, state
, *this);
2055 functionStartsSection
= state
.addAtom(*_functionStartsAtom
);
2057 if ( _hasDataInCodeInfo
) {
2058 _dataInCodeAtom
= new DataInCodeAtom
<x86
>(_options
, state
, *this);
2059 dataInCodeSection
= state
.addAtom(*_dataInCodeAtom
);
2061 if ( _hasDependentDRInfo
) {
2062 _dependentDRInfoAtom
= new DependentDRAtom
<x86
>(_options
, state
, *this);
2063 dependentDRsSection
= state
.addAtom(*_dependentDRInfoAtom
);
2065 if ( _hasSymbolTable
) {
2066 _symbolTableAtom
= new SymbolTableAtom
<x86
>(_options
, state
, *this);
2067 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
2069 if ( _hasExternalRelocations
) {
2070 _externalRelocsAtom
= new ExternalRelocationsAtom
<x86
>(_options
, state
, *this);
2071 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
2073 if ( _hasSymbolTable
) {
2074 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<x86
>(_options
, state
, *this);
2075 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
2076 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 4);
2077 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
2081 #if SUPPORT_ARCH_x86_64
2082 case CPU_TYPE_X86_64
:
2083 if ( _hasSectionRelocations
) {
2084 _sectionsRelocationsAtom
= new SectionRelocationsAtom
<x86_64
>(_options
, state
, *this);
2085 sectionRelocationsSection
= state
.addAtom(*_sectionsRelocationsAtom
);
2087 if ( _hasDyldInfo
) {
2088 _rebasingInfoAtom
= new RebaseInfoAtom
<x86_64
>(_options
, state
, *this);
2089 rebaseSection
= state
.addAtom(*_rebasingInfoAtom
);
2091 _bindingInfoAtom
= new BindingInfoAtom
<x86_64
>(_options
, state
, *this);
2092 bindingSection
= state
.addAtom(*_bindingInfoAtom
);
2094 _weakBindingInfoAtom
= new WeakBindingInfoAtom
<x86_64
>(_options
, state
, *this);
2095 weakBindingSection
= state
.addAtom(*_weakBindingInfoAtom
);
2097 _lazyBindingInfoAtom
= new LazyBindingInfoAtom
<x86_64
>(_options
, state
, *this);
2098 lazyBindingSection
= state
.addAtom(*_lazyBindingInfoAtom
);
2100 _exportInfoAtom
= new ExportInfoAtom
<x86_64
>(_options
, state
, *this);
2101 exportSection
= state
.addAtom(*_exportInfoAtom
);
2103 if ( _hasLocalRelocations
) {
2104 _localRelocsAtom
= new LocalRelocationsAtom
<x86_64
>(_options
, state
, *this);
2105 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
2107 if ( _hasSplitSegInfo
) {
2108 _splitSegInfoAtom
= new SplitSegInfoAtom
<x86_64
>(_options
, state
, *this);
2109 splitSegInfoSection
= state
.addAtom(*_splitSegInfoAtom
);
2111 if ( _hasFunctionStartsInfo
) {
2112 _functionStartsAtom
= new FunctionStartsAtom
<x86_64
>(_options
, state
, *this);
2113 functionStartsSection
= state
.addAtom(*_functionStartsAtom
);
2115 if ( _hasDataInCodeInfo
) {
2116 _dataInCodeAtom
= new DataInCodeAtom
<x86_64
>(_options
, state
, *this);
2117 dataInCodeSection
= state
.addAtom(*_dataInCodeAtom
);
2119 if ( _hasDependentDRInfo
) {
2120 _dependentDRInfoAtom
= new DependentDRAtom
<x86_64
>(_options
, state
, *this);
2121 dependentDRsSection
= state
.addAtom(*_dependentDRInfoAtom
);
2123 if ( _hasSymbolTable
) {
2124 _symbolTableAtom
= new SymbolTableAtom
<x86_64
>(_options
, state
, *this);
2125 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
2127 if ( _hasExternalRelocations
) {
2128 _externalRelocsAtom
= new ExternalRelocationsAtom
<x86_64
>(_options
, state
, *this);
2129 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
2131 if ( _hasSymbolTable
) {
2132 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<x86_64
>(_options
, state
, *this);
2133 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
2134 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 8);
2135 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
2139 #if SUPPORT_ARCH_arm_any
2141 if ( _hasSectionRelocations
) {
2142 _sectionsRelocationsAtom
= new SectionRelocationsAtom
<arm
>(_options
, state
, *this);
2143 sectionRelocationsSection
= state
.addAtom(*_sectionsRelocationsAtom
);
2145 if ( _hasDyldInfo
) {
2146 _rebasingInfoAtom
= new RebaseInfoAtom
<arm
>(_options
, state
, *this);
2147 rebaseSection
= state
.addAtom(*_rebasingInfoAtom
);
2149 _bindingInfoAtom
= new BindingInfoAtom
<arm
>(_options
, state
, *this);
2150 bindingSection
= state
.addAtom(*_bindingInfoAtom
);
2152 _weakBindingInfoAtom
= new WeakBindingInfoAtom
<arm
>(_options
, state
, *this);
2153 weakBindingSection
= state
.addAtom(*_weakBindingInfoAtom
);
2155 _lazyBindingInfoAtom
= new LazyBindingInfoAtom
<arm
>(_options
, state
, *this);
2156 lazyBindingSection
= state
.addAtom(*_lazyBindingInfoAtom
);
2158 _exportInfoAtom
= new ExportInfoAtom
<arm
>(_options
, state
, *this);
2159 exportSection
= state
.addAtom(*_exportInfoAtom
);
2161 if ( _hasLocalRelocations
) {
2162 _localRelocsAtom
= new LocalRelocationsAtom
<arm
>(_options
, state
, *this);
2163 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
2165 if ( _hasSplitSegInfo
) {
2166 _splitSegInfoAtom
= new SplitSegInfoAtom
<arm
>(_options
, state
, *this);
2167 splitSegInfoSection
= state
.addAtom(*_splitSegInfoAtom
);
2169 if ( _hasFunctionStartsInfo
) {
2170 _functionStartsAtom
= new FunctionStartsAtom
<arm
>(_options
, state
, *this);
2171 functionStartsSection
= state
.addAtom(*_functionStartsAtom
);
2173 if ( _hasDataInCodeInfo
) {
2174 _dataInCodeAtom
= new DataInCodeAtom
<arm
>(_options
, state
, *this);
2175 dataInCodeSection
= state
.addAtom(*_dataInCodeAtom
);
2177 if ( _hasDependentDRInfo
) {
2178 _dependentDRInfoAtom
= new DependentDRAtom
<arm
>(_options
, state
, *this);
2179 dependentDRsSection
= state
.addAtom(*_dependentDRInfoAtom
);
2181 if ( _hasSymbolTable
) {
2182 _symbolTableAtom
= new SymbolTableAtom
<arm
>(_options
, state
, *this);
2183 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
2185 if ( _hasExternalRelocations
) {
2186 _externalRelocsAtom
= new ExternalRelocationsAtom
<arm
>(_options
, state
, *this);
2187 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
2189 if ( _hasSymbolTable
) {
2190 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<arm
>(_options
, state
, *this);
2191 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
2192 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 4);
2193 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
2198 throw "unknown architecture";
2202 void OutputFile::addLoadCommands(ld::Internal
& state
)
2204 switch ( _options
.architecture() ) {
2205 #if SUPPORT_ARCH_x86_64
2206 case CPU_TYPE_X86_64
:
2207 _headersAndLoadCommandAtom
= new HeaderAndLoadCommandsAtom
<x86_64
>(_options
, state
, *this);
2208 headerAndLoadCommandsSection
= state
.addAtom(*_headersAndLoadCommandAtom
);
2211 #if SUPPORT_ARCH_arm_any
2213 _headersAndLoadCommandAtom
= new HeaderAndLoadCommandsAtom
<arm
>(_options
, state
, *this);
2214 headerAndLoadCommandsSection
= state
.addAtom(*_headersAndLoadCommandAtom
);
2217 #if SUPPORT_ARCH_i386
2219 _headersAndLoadCommandAtom
= new HeaderAndLoadCommandsAtom
<x86
>(_options
, state
, *this);
2220 headerAndLoadCommandsSection
= state
.addAtom(*_headersAndLoadCommandAtom
);
2224 throw "unknown architecture";
2228 uint32_t OutputFile::dylibCount()
2230 return _dylibsToLoad
.size();
2233 const ld::dylib::File
* OutputFile::dylibByOrdinal(unsigned int ordinal
)
2235 assert( ordinal
> 0 );
2236 assert( ordinal
<= _dylibsToLoad
.size() );
2237 return _dylibsToLoad
[ordinal
-1];
2240 bool OutputFile::hasOrdinalForInstallPath(const char* path
, int* ordinal
)
2242 for (std::map
<const ld::dylib::File
*, int>::const_iterator it
= _dylibToOrdinal
.begin(); it
!= _dylibToOrdinal
.end(); ++it
) {
2243 const char* installPath
= it
->first
->installPath();
2244 if ( (installPath
!= NULL
) && (strcmp(path
, installPath
) == 0) ) {
2245 *ordinal
= it
->second
;
2252 uint32_t OutputFile::dylibToOrdinal(const ld::dylib::File
* dylib
)
2254 return _dylibToOrdinal
[dylib
];
2258 void OutputFile::buildDylibOrdinalMapping(ld::Internal
& state
)
2260 // count non-public re-exported dylibs
2261 unsigned int nonPublicReExportCount
= 0;
2262 for (std::vector
<ld::dylib::File
*>::iterator it
= state
.dylibs
.begin(); it
!= state
.dylibs
.end(); ++it
) {
2263 ld::dylib::File
* aDylib
= *it
;
2264 if ( aDylib
->willBeReExported() && ! aDylib
->hasPublicInstallName() )
2265 ++nonPublicReExportCount
;
2268 // look at each dylib supplied in state
2269 bool hasReExports
= false;
2270 bool haveLazyDylibs
= false;
2271 for (std::vector
<ld::dylib::File
*>::iterator it
= state
.dylibs
.begin(); it
!= state
.dylibs
.end(); ++it
) {
2272 ld::dylib::File
* aDylib
= *it
;
2274 if ( aDylib
== state
.bundleLoader
) {
2275 _dylibToOrdinal
[aDylib
] = BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE
;
2277 else if ( this->hasOrdinalForInstallPath(aDylib
->installPath(), &ordinal
) ) {
2278 // already have a dylib with that install path, map all uses to that ordinal
2279 _dylibToOrdinal
[aDylib
] = ordinal
;
2281 else if ( aDylib
->willBeLazyLoadedDylib() ) {
2282 // all lazy dylib need to be at end of ordinals
2283 haveLazyDylibs
= true;
2285 else if ( aDylib
->willBeReExported() && ! aDylib
->hasPublicInstallName() && (nonPublicReExportCount
>= 2) ) {
2286 _dylibsToLoad
.push_back(aDylib
);
2287 _dylibToOrdinal
[aDylib
] = BIND_SPECIAL_DYLIB_SELF
;
2290 // first time this install path seen, create new ordinal
2291 _dylibsToLoad
.push_back(aDylib
);
2292 _dylibToOrdinal
[aDylib
] = _dylibsToLoad
.size();
2294 if ( aDylib
->explicitlyLinked() && aDylib
->willBeReExported() )
2295 hasReExports
= true;
2297 if ( haveLazyDylibs
) {
2298 // second pass to determine ordinals for lazy loaded dylibs
2299 for (std::vector
<ld::dylib::File
*>::iterator it
= state
.dylibs
.begin(); it
!= state
.dylibs
.end(); ++it
) {
2300 ld::dylib::File
* aDylib
= *it
;
2301 if ( aDylib
->willBeLazyLoadedDylib() ) {
2303 if ( this->hasOrdinalForInstallPath(aDylib
->installPath(), &ordinal
) ) {
2304 // already have a dylib with that install path, map all uses to that ordinal
2305 _dylibToOrdinal
[aDylib
] = ordinal
;
2308 // first time this install path seen, create new ordinal
2309 _dylibsToLoad
.push_back(aDylib
);
2310 _dylibToOrdinal
[aDylib
] = _dylibsToLoad
.size();
2315 _noReExportedDylibs
= !hasReExports
;
2316 //fprintf(stderr, "dylibs:\n");
2317 //for (std::map<const ld::dylib::File*, int>::const_iterator it = _dylibToOrdinal.begin(); it != _dylibToOrdinal.end(); ++it) {
2318 // fprintf(stderr, " %p ord=%u, install_name=%s\n",it->first, it->second, it->first->installPath());
2322 uint32_t OutputFile::lazyBindingInfoOffsetForLazyPointerAddress(uint64_t lpAddress
)
2324 return _lazyPointerAddressToInfoOffset
[lpAddress
];
2327 void OutputFile::setLazyBindingInfoOffset(uint64_t lpAddress
, uint32_t lpInfoOffset
)
2329 _lazyPointerAddressToInfoOffset
[lpAddress
] = lpInfoOffset
;
2332 int OutputFile::compressedOrdinalForAtom(const ld::Atom
* target
)
2334 // flat namespace images use zero for all ordinals
2335 if ( _options
.nameSpace() != Options::kTwoLevelNameSpace
)
2336 return BIND_SPECIAL_DYLIB_FLAT_LOOKUP
;
2338 // handle -interposable
2339 if ( target
->definition() == ld::Atom::definitionRegular
)
2340 return BIND_SPECIAL_DYLIB_SELF
;
2343 const ld::dylib::File
* dylib
= dynamic_cast<const ld::dylib::File
*>(target
->file());
2344 if ( dylib
!= NULL
)
2345 return _dylibToOrdinal
[dylib
];
2347 // handle undefined dynamic_lookup
2348 if ( _options
.undefinedTreatment() == Options::kUndefinedDynamicLookup
)
2349 return BIND_SPECIAL_DYLIB_FLAT_LOOKUP
;
2352 if ( _options
.allowedUndefined(target
->name()) )
2353 return BIND_SPECIAL_DYLIB_FLAT_LOOKUP
;
2355 throw "can't find ordinal for imported symbol";
2359 bool OutputFile::isPcRelStore(ld::Fixup::Kind kind
)
2362 case ld::Fixup::kindStoreX86BranchPCRel8
:
2363 case ld::Fixup::kindStoreX86BranchPCRel32
:
2364 case ld::Fixup::kindStoreX86PCRel8
:
2365 case ld::Fixup::kindStoreX86PCRel16
:
2366 case ld::Fixup::kindStoreX86PCRel32
:
2367 case ld::Fixup::kindStoreX86PCRel32_1
:
2368 case ld::Fixup::kindStoreX86PCRel32_2
:
2369 case ld::Fixup::kindStoreX86PCRel32_4
:
2370 case ld::Fixup::kindStoreX86PCRel32GOTLoad
:
2371 case ld::Fixup::kindStoreX86PCRel32GOTLoadNowLEA
:
2372 case ld::Fixup::kindStoreX86PCRel32GOT
:
2373 case ld::Fixup::kindStoreX86PCRel32TLVLoad
:
2374 case ld::Fixup::kindStoreX86PCRel32TLVLoadNowLEA
:
2375 case ld::Fixup::kindStoreARMBranch24
:
2376 case ld::Fixup::kindStoreThumbBranch22
:
2377 case ld::Fixup::kindStoreARMLoad12
:
2378 case ld::Fixup::kindStoreTargetAddressX86PCRel32
:
2379 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad
:
2380 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA
:
2381 case ld::Fixup::kindStoreTargetAddressARMBranch24
:
2382 case ld::Fixup::kindStoreTargetAddressThumbBranch22
:
2383 case ld::Fixup::kindStoreTargetAddressARMLoad12
:
2385 case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32
:
2386 return (_options
.outputKind() != Options::kKextBundle
);
2393 bool OutputFile::isStore(ld::Fixup::Kind kind
)
2396 case ld::Fixup::kindNone
:
2397 case ld::Fixup::kindNoneFollowOn
:
2398 case ld::Fixup::kindNoneGroupSubordinate
:
2399 case ld::Fixup::kindNoneGroupSubordinateFDE
:
2400 case ld::Fixup::kindNoneGroupSubordinateLSDA
:
2401 case ld::Fixup::kindNoneGroupSubordinatePersonality
:
2402 case ld::Fixup::kindSetTargetAddress
:
2403 case ld::Fixup::kindSubtractTargetAddress
:
2404 case ld::Fixup::kindAddAddend
:
2405 case ld::Fixup::kindSubtractAddend
:
2406 case ld::Fixup::kindSetTargetImageOffset
:
2407 case ld::Fixup::kindSetTargetSectionOffset
:
2416 bool OutputFile::setsTarget(ld::Fixup::Kind kind
)
2419 case ld::Fixup::kindSetTargetAddress
:
2420 case ld::Fixup::kindLazyTarget
:
2421 case ld::Fixup::kindStoreTargetAddressLittleEndian32
:
2422 case ld::Fixup::kindStoreTargetAddressLittleEndian64
:
2423 case ld::Fixup::kindStoreTargetAddressBigEndian32
:
2424 case ld::Fixup::kindStoreTargetAddressBigEndian64
:
2425 case ld::Fixup::kindStoreTargetAddressX86PCRel32
:
2426 case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32
:
2427 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad
:
2428 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA
:
2429 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoad
:
2430 case ld::Fixup::kindStoreTargetAddressX86Abs32TLVLoad
:
2431 case ld::Fixup::kindStoreTargetAddressARMBranch24
:
2432 case ld::Fixup::kindStoreTargetAddressThumbBranch22
:
2433 case ld::Fixup::kindStoreTargetAddressARMLoad12
:
2435 case ld::Fixup::kindStoreX86DtraceCallSiteNop
:
2436 case ld::Fixup::kindStoreX86DtraceIsEnableSiteClear
:
2437 case ld::Fixup::kindStoreARMDtraceCallSiteNop
:
2438 case ld::Fixup::kindStoreARMDtraceIsEnableSiteClear
:
2439 case ld::Fixup::kindStoreThumbDtraceCallSiteNop
:
2440 case ld::Fixup::kindStoreThumbDtraceIsEnableSiteClear
:
2441 return (_options
.outputKind() == Options::kObjectFile
);
2448 bool OutputFile::isPointerToTarget(ld::Fixup::Kind kind
)
2451 case ld::Fixup::kindSetTargetAddress
:
2452 case ld::Fixup::kindStoreTargetAddressLittleEndian32
:
2453 case ld::Fixup::kindStoreTargetAddressLittleEndian64
:
2454 case ld::Fixup::kindStoreTargetAddressBigEndian32
:
2455 case ld::Fixup::kindStoreTargetAddressBigEndian64
:
2456 case ld::Fixup::kindLazyTarget
:
2463 bool OutputFile::isPointerFromTarget(ld::Fixup::Kind kind
)
2466 case ld::Fixup::kindSubtractTargetAddress
:
2475 uint64_t OutputFile::lookBackAddend(ld::Fixup::iterator fit
)
2477 uint64_t addend
= 0;
2478 switch ( fit
->clusterSize
) {
2479 case ld::Fixup::k1of1
:
2480 case ld::Fixup::k1of2
:
2481 case ld::Fixup::k2of2
:
2483 case ld::Fixup::k2of3
:
2485 switch ( fit
->kind
) {
2486 case ld::Fixup::kindAddAddend
:
2487 addend
+= fit
->u
.addend
;
2489 case ld::Fixup::kindSubtractAddend
:
2490 addend
-= fit
->u
.addend
;
2493 throw "unexpected fixup kind for binding";
2496 case ld::Fixup::k1of3
:
2498 switch ( fit
->kind
) {
2499 case ld::Fixup::kindAddAddend
:
2500 addend
+= fit
->u
.addend
;
2502 case ld::Fixup::kindSubtractAddend
:
2503 addend
-= fit
->u
.addend
;
2506 throw "unexpected fixup kind for binding";
2510 throw "unexpected fixup cluster size for binding";
2519 void OutputFile::generateLinkEditInfo(ld::Internal
& state
)
2521 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
2522 ld::Internal::FinalSection
* sect
= *sit
;
2523 bool objc1ClassRefSection
= ( (sect
->type() == ld::Section::typeCStringPointer
)
2524 && (strcmp(sect
->sectionName(), "__cls_refs") == 0)
2525 && (strcmp(sect
->segmentName(), "__OBJC") == 0) );
2526 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
2527 const ld::Atom
* atom
= *ait
;
2529 // Record regular atoms that override a dylib's weak definitions
2530 if ( (atom
->scope() == ld::Atom::scopeGlobal
) && atom
->overridesDylibsWeakDef() ) {
2531 if ( _options
.makeCompressedDyldInfo() ) {
2532 uint8_t wtype
= BIND_TYPE_OVERRIDE_OF_WEAKDEF_IN_DYLIB
;
2533 bool nonWeakDef
= (atom
->combine() == ld::Atom::combineNever
);
2534 _weakBindingInfo
.push_back(BindingInfo(wtype
, atom
->name(), nonWeakDef
, atom
->finalAddress(), 0));
2536 this->overridesWeakExternalSymbols
= true;
2537 if ( _options
.warnWeakExports() )
2538 warning("overrides weak external symbol: %s", atom
->name());
2541 ld::Fixup
* fixupWithTarget
= NULL
;
2542 ld::Fixup
* fixupWithMinusTarget
= NULL
;
2543 ld::Fixup
* fixupWithStore
= NULL
;
2544 const ld::Atom
* target
= NULL
;
2545 const ld::Atom
* minusTarget
= NULL
;
2546 uint64_t targetAddend
= 0;
2547 uint64_t minusTargetAddend
= 0;
2548 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(); fit
!= atom
->fixupsEnd(); ++fit
) {
2549 if ( fit
->firstInCluster() ) {
2550 fixupWithTarget
= NULL
;
2551 fixupWithMinusTarget
= NULL
;
2552 fixupWithStore
= NULL
;
2556 minusTargetAddend
= 0;
2558 if ( this->setsTarget(fit
->kind
) ) {
2559 switch ( fit
->binding
) {
2560 case ld::Fixup::bindingNone
:
2561 case ld::Fixup::bindingByNameUnbound
:
2563 case ld::Fixup::bindingByContentBound
:
2564 case ld::Fixup::bindingDirectlyBound
:
2565 fixupWithTarget
= fit
;
2566 target
= fit
->u
.target
;
2568 case ld::Fixup::bindingsIndirectlyBound
:
2569 fixupWithTarget
= fit
;
2570 target
= state
.indirectBindingTable
[fit
->u
.bindingIndex
];
2573 assert(target
!= NULL
);
2575 switch ( fit
->kind
) {
2576 case ld::Fixup::kindAddAddend
:
2577 targetAddend
= fit
->u
.addend
;
2579 case ld::Fixup::kindSubtractAddend
:
2580 minusTargetAddend
= fit
->u
.addend
;
2582 case ld::Fixup::kindSubtractTargetAddress
:
2583 switch ( fit
->binding
) {
2584 case ld::Fixup::bindingNone
:
2585 case ld::Fixup::bindingByNameUnbound
:
2587 case ld::Fixup::bindingByContentBound
:
2588 case ld::Fixup::bindingDirectlyBound
:
2589 fixupWithMinusTarget
= fit
;
2590 minusTarget
= fit
->u
.target
;
2592 case ld::Fixup::bindingsIndirectlyBound
:
2593 fixupWithMinusTarget
= fit
;
2594 minusTarget
= state
.indirectBindingTable
[fit
->u
.bindingIndex
];
2597 assert(minusTarget
!= NULL
);
2599 case ld::Fixup::kindDataInCodeStartData
:
2600 case ld::Fixup::kindDataInCodeStartJT8
:
2601 case ld::Fixup::kindDataInCodeStartJT16
:
2602 case ld::Fixup::kindDataInCodeStartJT32
:
2603 case ld::Fixup::kindDataInCodeStartJTA32
:
2604 case ld::Fixup::kindDataInCodeEnd
:
2605 hasDataInCode
= true;
2610 if ( this->isStore(fit
->kind
) ) {
2611 fixupWithStore
= fit
;
2613 if ( fit
->lastInCluster() ) {
2614 if ( (fixupWithStore
!= NULL
) && (target
!= NULL
) ) {
2615 if ( _options
.outputKind() == Options::kObjectFile
) {
2616 this->addSectionRelocs(state
, sect
, atom
, fixupWithTarget
, fixupWithMinusTarget
, fixupWithStore
,
2617 target
, minusTarget
, targetAddend
, minusTargetAddend
);
2620 if ( _options
.makeCompressedDyldInfo() ) {
2621 this->addDyldInfo(state
, sect
, atom
, fixupWithTarget
, fixupWithMinusTarget
, fixupWithStore
,
2622 target
, minusTarget
, targetAddend
, minusTargetAddend
);
2625 this->addClassicRelocs(state
, sect
, atom
, fixupWithTarget
, fixupWithMinusTarget
, fixupWithStore
,
2626 target
, minusTarget
, targetAddend
, minusTargetAddend
);
2630 else if ( objc1ClassRefSection
&& (target
!= NULL
) && (fixupWithStore
== NULL
) ) {
2631 // check for class refs to lazy loaded dylibs
2632 const ld::dylib::File
* dylib
= dynamic_cast<const ld::dylib::File
*>(target
->file());
2633 if ( (dylib
!= NULL
) && dylib
->willBeLazyLoadedDylib() )
2634 throwf("illegal class reference to %s in lazy loaded dylib %s", target
->name(), dylib
->path());
2643 void OutputFile::noteTextReloc(const ld::Atom
* atom
, const ld::Atom
* target
)
2645 if ( (atom
->contentType() == ld::Atom::typeStub
) || (atom
->contentType() == ld::Atom::typeStubHelper
) ) {
2646 // silently let stubs (synthesized by linker) use text relocs
2648 else if ( _options
.allowTextRelocs() ) {
2649 if ( _options
.warnAboutTextRelocs() )
2650 warning("text reloc in %s to %s", atom
->name(), target
->name());
2652 else if ( _options
.positionIndependentExecutable() && (_options
.outputKind() == Options::kDynamicExecutable
)
2653 && ((_options
.iOSVersionMin() >= ld::iOS_4_3
) || (_options
.macosxVersionMin() >= ld::mac10_7
)) ) {
2654 if ( ! this->pieDisabled
) {
2655 warning("PIE disabled. Absolute addressing (perhaps -mdynamic-no-pic) not allowed in code signed PIE, "
2656 "but used in %s from %s. "
2657 "To fix this warning, don't compile with -mdynamic-no-pic or link with -Wl,-no_pie",
2658 atom
->name(), atom
->file()->path());
2660 this->pieDisabled
= true;
2662 else if ( (target
->scope() == ld::Atom::scopeGlobal
) && (target
->combine() == ld::Atom::combineByName
) ) {
2663 throwf("illegal text-relocoation (direct reference) to (global,weak) %s in %s from %s in %s", target
->name(), target
->file()->path(), atom
->name(), atom
->file()->path());
2666 throwf("illegal text-relocation to %s in %s from %s in %s", target
->name(), target
->file()->path(), atom
->name(), atom
->file()->path());
2670 void OutputFile::addDyldInfo(ld::Internal
& state
, ld::Internal::FinalSection
* sect
, const ld::Atom
* atom
,
2671 ld::Fixup
* fixupWithTarget
, ld::Fixup
* fixupWithMinusTarget
, ld::Fixup
* fixupWithStore
,
2672 const ld::Atom
* target
, const ld::Atom
* minusTarget
,
2673 uint64_t targetAddend
, uint64_t minusTargetAddend
)
2675 if ( sect
->isSectionHidden() )
2678 // no need to rebase or bind PCRel stores
2679 if ( this->isPcRelStore(fixupWithStore
->kind
) ) {
2680 // as long as target is in same linkage unit
2681 if ( (target
== NULL
) || (target
->definition() != ld::Atom::definitionProxy
) ) {
2682 // make sure target is not global and weak
2683 if ( (target
->scope() == ld::Atom::scopeGlobal
) && (target
->combine() == ld::Atom::combineByName
) && (target
->definition() == ld::Atom::definitionRegular
)) {
2684 if ( (atom
->section().type() == ld::Section::typeCFI
)
2685 || (atom
->section().type() == ld::Section::typeDtraceDOF
)
2686 || (atom
->section().type() == ld::Section::typeUnwindInfo
) ) {
2687 // ok for __eh_frame and __uwind_info to use pointer diffs to global weak symbols
2690 // Have direct reference to weak-global. This should be an indrect reference
2691 const char* demangledName
= strdup(_options
.demangleSymbol(atom
->name()));
2692 warning("direct access in %s to global weak symbol %s means the weak symbol cannot be overridden at runtime. "
2693 "This was likely caused by different translation units being compiled with different visibility settings.",
2694 demangledName
, _options
.demangleSymbol(target
->name()));
2700 // no need to rebase or bind PIC internal pointer diff
2701 if ( minusTarget
!= NULL
) {
2702 // with pointer diffs, both need to be in same linkage unit
2703 assert(minusTarget
->definition() != ld::Atom::definitionProxy
);
2704 assert(target
!= NULL
);
2705 assert(target
->definition() != ld::Atom::definitionProxy
);
2706 if ( target
== minusTarget
) {
2707 // This is a compile time constant and could have been optimized away by compiler
2711 // check if target of pointer-diff is global and weak
2712 if ( (target
->scope() == ld::Atom::scopeGlobal
) && (target
->combine() == ld::Atom::combineByName
) && (target
->definition() == ld::Atom::definitionRegular
) ) {
2713 if ( (atom
->section().type() == ld::Section::typeCFI
)
2714 || (atom
->section().type() == ld::Section::typeDtraceDOF
)
2715 || (atom
->section().type() == ld::Section::typeUnwindInfo
) ) {
2716 // ok for __eh_frame and __uwind_info to use pointer diffs to global weak symbols
2719 // Have direct reference to weak-global. This should be an indrect reference
2720 const char* demangledName
= strdup(_options
.demangleSymbol(atom
->name()));
2721 warning("direct access in %s to global weak symbol %s means the weak symbol cannot be overridden at runtime. "
2722 "This was likely caused by different translation units being compiled with different visibility settings.",
2723 demangledName
, _options
.demangleSymbol(target
->name()));
2728 // no need to rebase or bind an atom's references to itself if the output is not slidable
2729 if ( (atom
== target
) && !_options
.outputSlidable() )
2732 // cluster has no target, so needs no rebasing or binding
2733 if ( target
== NULL
)
2736 bool inReadOnlySeg
= ( strcmp(sect
->segmentName(), "__TEXT") == 0 );
2737 bool needsRebase
= false;
2738 bool needsBinding
= false;
2739 bool needsLazyBinding
= false;
2740 bool needsWeakBinding
= false;
2742 uint8_t rebaseType
= REBASE_TYPE_POINTER
;
2743 uint8_t type
= BIND_TYPE_POINTER
;
2744 const ld::dylib::File
* dylib
= dynamic_cast<const ld::dylib::File
*>(target
->file());
2745 bool weak_import
= (fixupWithTarget
->weakImport
|| ((dylib
!= NULL
) && dylib
->forcedWeakLinked()));
2746 uint64_t address
= atom
->finalAddress() + fixupWithTarget
->offsetInAtom
;
2747 uint64_t addend
= targetAddend
- minusTargetAddend
;
2749 // special case lazy pointers
2750 if ( fixupWithTarget
->kind
== ld::Fixup::kindLazyTarget
) {
2751 assert(fixupWithTarget
->u
.target
== target
);
2752 assert(addend
== 0);
2753 // lazy dylib lazy pointers do not have any dyld info
2754 if ( atom
->section().type() == ld::Section::typeLazyDylibPointer
)
2756 // lazy binding to weak definitions are done differently
2757 // they are directly bound to target, then have a weak bind in case of a collision
2758 if ( target
->combine() == ld::Atom::combineByName
) {
2759 if ( target
->definition() == ld::Atom::definitionProxy
) {
2760 // weak def exported from another dylib
2761 // must non-lazy bind to it plus have weak binding info in case of collision
2762 needsBinding
= true;
2763 needsWeakBinding
= true;
2766 // weak def in this linkage unit.
2767 // just rebase, plus have weak binding info in case of collision
2768 // this will be done by other cluster on lazy pointer atom
2771 else if ( (target
->contentType() == ld::Atom::typeResolver
) && (target
->scope() != ld::Atom::scopeGlobal
) ) {
2772 // <rdar://problem/8553647> Hidden resolver functions should not have lazy binding info
2773 needsLazyBinding
= false;
2776 // normal case of a pointer to non-weak-def symbol, so can lazily bind
2777 needsLazyBinding
= true;
2781 // everything except lazy pointers
2782 switch ( target
->definition() ) {
2783 case ld::Atom::definitionProxy
:
2784 if ( (dylib
!= NULL
) && dylib
->willBeLazyLoadedDylib() )
2785 throwf("illegal data reference to %s in lazy loaded dylib %s", target
->name(), dylib
->path());
2786 if ( target
->contentType() == ld::Atom::typeTLV
) {
2787 if ( sect
->type() != ld::Section::typeTLVPointers
)
2788 throwf("illegal data reference in %s to thread local variable %s in dylib %s",
2789 atom
->name(), target
->name(), dylib
->path());
2791 if ( inReadOnlySeg
)
2792 type
= BIND_TYPE_TEXT_ABSOLUTE32
;
2793 needsBinding
= true;
2794 if ( target
->combine() == ld::Atom::combineByName
)
2795 needsWeakBinding
= true;
2797 case ld::Atom::definitionRegular
:
2798 case ld::Atom::definitionTentative
:
2799 // only slideable images need rebasing info
2800 if ( _options
.outputSlidable() ) {
2803 // references to internal symbol never need binding
2804 if ( target
->scope() != ld::Atom::scopeGlobal
)
2806 // reference to global weak def needs weak binding
2807 if ( (target
->combine() == ld::Atom::combineByName
) && (target
->definition() == ld::Atom::definitionRegular
) )
2808 needsWeakBinding
= true;
2809 else if ( _options
.outputKind() == Options::kDynamicExecutable
) {
2810 // in main executables, the only way regular symbols are indirected is if -interposable is used
2811 if ( _options
.interposable(target
->name()) ) {
2812 needsRebase
= false;
2813 needsBinding
= true;
2817 // for flat-namespace or interposable two-level-namespace
2818 // all references to exported symbols get indirected
2819 if ( (_options
.nameSpace() != Options::kTwoLevelNameSpace
) || _options
.interposable(target
->name()) ) {
2820 // <rdar://problem/5254468> no external relocs for flat objc classes
2821 if ( strncmp(target
->name(), ".objc_class_", 12) == 0 )
2823 // no rebase info for references to global symbols that will have binding info
2824 needsRebase
= false;
2825 needsBinding
= true;
2829 case ld::Atom::definitionAbsolute
:
2834 // record dyld info for this cluster
2835 if ( needsRebase
) {
2836 if ( inReadOnlySeg
) {
2837 noteTextReloc(atom
, target
);
2838 sect
->hasLocalRelocs
= true; // so dyld knows to change permissions on __TEXT segment
2839 rebaseType
= REBASE_TYPE_TEXT_ABSOLUTE32
;
2841 if ( (addend
!= 0) && _options
.sharedRegionEligible() ) {
2842 // make sure the addend does not cause the pointer to point outside the target's segment
2843 // if it does, update_dyld_shared_cache will not be able to put this dylib into the shared cache
2844 uint64_t targetAddress
= target
->finalAddress();
2845 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
2846 ld::Internal::FinalSection
* sct
= *sit
;
2847 uint64_t sctEnd
= (sct
->address
+sct
->size
);
2848 if ( (sct
->address
<= targetAddress
) && (targetAddress
< sctEnd
) ) {
2849 if ( (targetAddress
+addend
) > sctEnd
) {
2850 warning("data symbol %s from %s has pointer to %s + 0x%08llX. "
2851 "That large of an addend may disable %s from being put in the dyld shared cache.",
2852 atom
->name(), atom
->file()->path(), target
->name(), addend
, _options
.installPath() );
2857 _rebaseInfo
.push_back(RebaseInfo(rebaseType
, address
));
2859 if ( needsBinding
) {
2860 if ( inReadOnlySeg
) {
2861 noteTextReloc(atom
, target
);
2862 sect
->hasExternalRelocs
= true; // so dyld knows to change permissions on __TEXT segment
2864 _bindingInfo
.push_back(BindingInfo(type
, this->compressedOrdinalForAtom(target
), target
->name(), weak_import
, address
, addend
));
2866 if ( needsLazyBinding
) {
2867 if ( _options
.bindAtLoad() )
2868 _bindingInfo
.push_back(BindingInfo(type
, this->compressedOrdinalForAtom(target
), target
->name(), weak_import
, address
, addend
));
2870 _lazyBindingInfo
.push_back(BindingInfo(type
, this->compressedOrdinalForAtom(target
), target
->name(), weak_import
, address
, addend
));
2872 if ( needsWeakBinding
)
2873 _weakBindingInfo
.push_back(BindingInfo(type
, 0, target
->name(), false, address
, addend
));
2877 void OutputFile::addClassicRelocs(ld::Internal
& state
, ld::Internal::FinalSection
* sect
, const ld::Atom
* atom
,
2878 ld::Fixup
* fixupWithTarget
, ld::Fixup
* fixupWithMinusTarget
, ld::Fixup
* fixupWithStore
,
2879 const ld::Atom
* target
, const ld::Atom
* minusTarget
,
2880 uint64_t targetAddend
, uint64_t minusTargetAddend
)
2882 if ( sect
->isSectionHidden() )
2885 // non-lazy-pointer section is encoded in indirect symbol table - not using relocations
2886 if ( sect
->type() == ld::Section::typeNonLazyPointer
) {
2887 // except kexts and static pie which *do* use relocations
2888 switch (_options
.outputKind()) {
2889 case Options::kKextBundle
:
2891 case Options::kStaticExecutable
:
2892 if ( _options
.positionIndependentExecutable() )
2894 // else fall into default case
2896 assert(target
!= NULL
);
2897 assert(fixupWithTarget
!= NULL
);
2902 // no need to rebase or bind PCRel stores
2903 if ( this->isPcRelStore(fixupWithStore
->kind
) ) {
2904 // as long as target is in same linkage unit
2905 if ( (target
== NULL
) || (target
->definition() != ld::Atom::definitionProxy
) )
2909 // no need to rebase or bind PIC internal pointer diff
2910 if ( minusTarget
!= NULL
) {
2911 // with pointer diffs, both need to be in same linkage unit
2912 assert(minusTarget
->definition() != ld::Atom::definitionProxy
);
2913 assert(target
!= NULL
);
2914 assert(target
->definition() != ld::Atom::definitionProxy
);
2915 // make sure target is not global and weak
2916 if ( (target
->scope() == ld::Atom::scopeGlobal
) && (target
->combine() == ld::Atom::combineByName
)
2917 && (atom
->section().type() != ld::Section::typeCFI
)
2918 && (atom
->section().type() != ld::Section::typeDtraceDOF
)
2919 && (atom
->section().type() != ld::Section::typeUnwindInfo
)
2920 && (minusTarget
!= target
) ) {
2921 // ok for __eh_frame and __uwind_info to use pointer diffs to global weak symbols
2922 throwf("bad codegen, pointer diff in %s to global weak symbol %s", atom
->name(), target
->name());
2927 // cluster has no target, so needs no rebasing or binding
2928 if ( target
== NULL
)
2931 assert(_localRelocsAtom
!= NULL
);
2932 uint64_t relocAddress
= atom
->finalAddress() + fixupWithTarget
->offsetInAtom
- _localRelocsAtom
->relocBaseAddress(state
);
2934 bool inReadOnlySeg
= ( strcmp(sect
->segmentName(), "__TEXT") == 0 );
2935 bool needsLocalReloc
= false;
2936 bool needsExternReloc
= false;
2938 switch ( fixupWithStore
->kind
) {
2939 case ld::Fixup::kindLazyTarget
:
2940 // lazy pointers don't need relocs
2942 case ld::Fixup::kindStoreLittleEndian32
:
2943 case ld::Fixup::kindStoreLittleEndian64
:
2944 case ld::Fixup::kindStoreBigEndian32
:
2945 case ld::Fixup::kindStoreBigEndian64
:
2946 case ld::Fixup::kindStoreTargetAddressLittleEndian32
:
2947 case ld::Fixup::kindStoreTargetAddressLittleEndian64
:
2948 case ld::Fixup::kindStoreTargetAddressBigEndian32
:
2949 case ld::Fixup::kindStoreTargetAddressBigEndian64
:
2951 switch ( target
->definition() ) {
2952 case ld::Atom::definitionProxy
:
2953 needsExternReloc
= true;
2955 case ld::Atom::definitionRegular
:
2956 case ld::Atom::definitionTentative
:
2957 // only slideable images need local relocs
2958 if ( _options
.outputSlidable() )
2959 needsLocalReloc
= true;
2960 // references to internal symbol never need binding
2961 if ( target
->scope() != ld::Atom::scopeGlobal
)
2963 // reference to global weak def needs weak binding in dynamic images
2964 if ( (target
->combine() == ld::Atom::combineByName
)
2965 && (target
->definition() == ld::Atom::definitionRegular
)
2966 && (_options
.outputKind() != Options::kStaticExecutable
) ) {
2967 needsExternReloc
= true;
2969 else if ( _options
.outputKind() == Options::kDynamicExecutable
) {
2970 // in main executables, the only way regular symbols are indirected is if -interposable is used
2971 if ( _options
.interposable(target
->name()) )
2972 needsExternReloc
= true;
2975 // for flat-namespace or interposable two-level-namespace
2976 // all references to exported symbols get indirected
2977 if ( (_options
.nameSpace() != Options::kTwoLevelNameSpace
) || _options
.interposable(target
->name()) ) {
2978 // <rdar://problem/5254468> no external relocs for flat objc classes
2979 if ( strncmp(target
->name(), ".objc_class_", 12) == 0 )
2981 // no rebase info for references to global symbols that will have binding info
2982 needsExternReloc
= true;
2985 if ( needsExternReloc
)
2986 needsLocalReloc
= false;
2988 case ld::Atom::definitionAbsolute
:
2991 if ( needsExternReloc
) {
2992 if ( inReadOnlySeg
)
2993 noteTextReloc(atom
, target
);
2994 const ld::dylib::File
* dylib
= dynamic_cast<const ld::dylib::File
*>(target
->file());
2995 if ( (dylib
!= NULL
) && dylib
->willBeLazyLoadedDylib() )
2996 throwf("illegal data reference to %s in lazy loaded dylib %s", target
->name(), dylib
->path());
2997 _externalRelocsAtom
->addExternalPointerReloc(relocAddress
, target
);
2998 sect
->hasExternalRelocs
= true;
2999 fixupWithTarget
->contentAddendOnly
= true;
3001 else if ( needsLocalReloc
) {
3002 assert(target
!= NULL
);
3003 if ( inReadOnlySeg
)
3004 noteTextReloc(atom
, target
);
3005 _localRelocsAtom
->addPointerReloc(relocAddress
, target
->machoSection());
3006 sect
->hasLocalRelocs
= true;
3009 case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32
:
3010 if ( _options
.outputKind() == Options::kKextBundle
) {
3011 assert(target
!= NULL
);
3012 if ( target
->definition() == ld::Atom::definitionProxy
) {
3013 _externalRelocsAtom
->addExternalCallSiteReloc(relocAddress
, target
);
3014 fixupWithStore
->contentAddendOnly
= true;
3019 case ld::Fixup::kindStoreARMLow16
:
3020 case ld::Fixup::kindStoreThumbLow16
:
3021 // no way to encode rebasing of binding for these instructions
3022 if ( _options
.outputSlidable() || (target
->definition() == ld::Atom::definitionProxy
) )
3023 throwf("no supported runtime lo16 relocation in %s from %s to %s", atom
->name(), atom
->file()->path(), target
->name());
3026 case ld::Fixup::kindStoreARMHigh16
:
3027 case ld::Fixup::kindStoreThumbHigh16
:
3028 // no way to encode rebasing of binding for these instructions
3029 if ( _options
.outputSlidable() || (target
->definition() == ld::Atom::definitionProxy
) )
3030 throwf("no supported runtime hi16 relocation in %s from %s to %s", atom
->name(), atom
->file()->path(), target
->name());
3039 bool OutputFile::useExternalSectionReloc(const ld::Atom
* atom
, const ld::Atom
* target
, ld::Fixup
* fixupWithTarget
)
3041 if ( _options
.architecture() == CPU_TYPE_X86_64
) {
3042 // x86_64 uses external relocations for everthing that has a symbol
3043 return ( target
->symbolTableInclusion() != ld::Atom::symbolTableNotIn
);
3046 // <rdar://problem/9513487> support arm branch interworking in -r mode
3047 if ( (_options
.architecture() == CPU_TYPE_ARM
) && (_options
.outputKind() == Options::kObjectFile
) ) {
3048 if ( atom
->isThumb() != target
->isThumb() ) {
3049 switch ( fixupWithTarget
->kind
) {
3050 // have branch that switches mode, then might be 'b' not 'bl'
3051 // Force external relocation, since no way to do local reloc for 'b'
3052 case ld::Fixup::kindStoreTargetAddressThumbBranch22
:
3053 case ld::Fixup::kindStoreTargetAddressARMBranch24
:
3061 if ( (_options
.architecture() == CPU_TYPE_I386
) && (_options
.outputKind() == Options::kObjectFile
) ) {
3062 if ( target
->contentType() == ld::Atom::typeTLV
)
3066 // most architectures use external relocations only for references
3067 // to a symbol in another translation unit or for references to "weak symbols" or tentative definitions
3068 assert(target
!= NULL
);
3069 if ( target
->definition() == ld::Atom::definitionProxy
)
3071 if ( (target
->definition() == ld::Atom::definitionTentative
) && ! _options
.makeTentativeDefinitionsReal() )
3073 if ( target
->scope() != ld::Atom::scopeGlobal
)
3075 if ( (target
->combine() == ld::Atom::combineByName
) && (target
->definition() == ld::Atom::definitionRegular
) )
3083 void OutputFile::addSectionRelocs(ld::Internal
& state
, ld::Internal::FinalSection
* sect
, const ld::Atom
* atom
,
3084 ld::Fixup
* fixupWithTarget
, ld::Fixup
* fixupWithMinusTarget
, ld::Fixup
* fixupWithStore
,
3085 const ld::Atom
* target
, const ld::Atom
* minusTarget
,
3086 uint64_t targetAddend
, uint64_t minusTargetAddend
)
3088 if ( sect
->isSectionHidden() )
3091 // in -r mode where there will be no labels on __eh_frame section, there is no need for relocations
3092 if ( (sect
->type() == ld::Section::typeCFI
) && _options
.removeEHLabels() )
3095 // non-lazy-pointer section is encoded in indirect symbol table - not using relocations
3096 if ( sect
->type() == ld::Section::typeNonLazyPointer
)
3099 // tentative defs don't have any relocations
3100 if ( sect
->type() == ld::Section::typeTentativeDefs
)
3103 assert(target
!= NULL
);
3104 assert(fixupWithTarget
!= NULL
);
3105 bool targetUsesExternalReloc
= this->useExternalSectionReloc(atom
, target
, fixupWithTarget
);
3106 bool minusTargetUsesExternalReloc
= (minusTarget
!= NULL
) && this->useExternalSectionReloc(atom
, minusTarget
, fixupWithMinusTarget
);
3108 // in x86_64 .o files an external reloc means the content contains just the addend
3109 if ( _options
.architecture() == CPU_TYPE_X86_64
) {
3110 if ( targetUsesExternalReloc
) {
3111 fixupWithTarget
->contentAddendOnly
= true;
3112 fixupWithStore
->contentAddendOnly
= true;
3114 if ( minusTargetUsesExternalReloc
)
3115 fixupWithMinusTarget
->contentAddendOnly
= true;
3118 // for other archs, content is addend only with (non pc-rel) pointers
3119 // pc-rel instructions are funny. If the target is _foo+8 and _foo is
3120 // external, then the pc-rel instruction *evalutates* to the address 8.
3121 if ( targetUsesExternalReloc
) {
3122 // TLV support for i386 acts like RIP relative addressing
3123 // The addend is the offset from the PICBase to the end of the instruction
3124 if ( (_options
.architecture() == CPU_TYPE_I386
)
3125 && (_options
.outputKind() == Options::kObjectFile
)
3126 && (fixupWithStore
->kind
== ld::Fixup::kindStoreX86PCRel32TLVLoad
) ) {
3127 fixupWithTarget
->contentAddendOnly
= true;
3128 fixupWithStore
->contentAddendOnly
= true;
3130 else if ( isPcRelStore(fixupWithStore
->kind
) ) {
3131 fixupWithTarget
->contentDetlaToAddendOnly
= true;
3132 fixupWithStore
->contentDetlaToAddendOnly
= true;
3134 else if ( minusTarget
== NULL
){
3135 fixupWithTarget
->contentAddendOnly
= true;
3136 fixupWithStore
->contentAddendOnly
= true;
3141 if ( fixupWithStore
!= NULL
) {
3142 _sectionsRelocationsAtom
->addSectionReloc(sect
, fixupWithStore
->kind
, atom
, fixupWithStore
->offsetInAtom
,
3143 targetUsesExternalReloc
, minusTargetUsesExternalReloc
,
3144 target
, targetAddend
, minusTarget
, minusTargetAddend
);
3150 void OutputFile::makeSplitSegInfo(ld::Internal
& state
)
3152 if ( !_options
.sharedRegionEligible() )
3155 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
3156 ld::Internal::FinalSection
* sect
= *sit
;
3157 if ( sect
->isSectionHidden() )
3159 if ( strcmp(sect
->segmentName(), "__TEXT") != 0 )
3161 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
3162 const ld::Atom
* atom
= *ait
;
3163 const ld::Atom
* target
= NULL
;
3164 const ld::Atom
* fromTarget
= NULL
;
3165 uint64_t accumulator
= 0;
3167 bool hadSubtract
= false;
3168 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(), end
=atom
->fixupsEnd(); fit
!= end
; ++fit
) {
3169 if ( fit
->firstInCluster() )
3171 if ( this->setsTarget(fit
->kind
) ) {
3172 accumulator
= addressOf(state
, fit
, &target
);
3173 thumbTarget
= targetIsThumb(state
, fit
);
3177 switch ( fit
->kind
) {
3178 case ld::Fixup::kindSubtractTargetAddress
:
3179 accumulator
-= addressOf(state
, fit
, &fromTarget
);
3182 case ld::Fixup::kindAddAddend
:
3183 accumulator
+= fit
->u
.addend
;
3185 case ld::Fixup::kindSubtractAddend
:
3186 accumulator
-= fit
->u
.addend
;
3188 case ld::Fixup::kindStoreBigEndian32
:
3189 case ld::Fixup::kindStoreLittleEndian32
:
3190 case ld::Fixup::kindStoreLittleEndian64
:
3191 case ld::Fixup::kindStoreTargetAddressLittleEndian32
:
3192 case ld::Fixup::kindStoreTargetAddressLittleEndian64
:
3193 // if no subtract, then this is an absolute pointer which means
3194 // there is also a text reloc which update_dyld_shared_cache will use.
3195 if ( ! hadSubtract
)
3198 case ld::Fixup::kindStoreX86PCRel32
:
3199 case ld::Fixup::kindStoreX86PCRel32_1
:
3200 case ld::Fixup::kindStoreX86PCRel32_2
:
3201 case ld::Fixup::kindStoreX86PCRel32_4
:
3202 case ld::Fixup::kindStoreX86PCRel32GOTLoad
:
3203 case ld::Fixup::kindStoreX86PCRel32GOTLoadNowLEA
:
3204 case ld::Fixup::kindStoreX86PCRel32GOT
:
3205 case ld::Fixup::kindStoreTargetAddressX86PCRel32
:
3206 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad
:
3207 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA
:
3208 case ld::Fixup::kindStoreARMLow16
:
3209 case ld::Fixup::kindStoreThumbLow16
:
3210 assert(target
!= NULL
);
3211 if ( strcmp(sect
->segmentName(), target
->section().segmentName()) != 0 ) {
3212 _splitSegInfos
.push_back(SplitSegInfoEntry(atom
->finalAddress()+fit
->offsetInAtom
,fit
->kind
));
3215 case ld::Fixup::kindStoreARMHigh16
:
3216 case ld::Fixup::kindStoreThumbHigh16
:
3217 assert(target
!= NULL
);
3218 if ( strcmp(sect
->segmentName(), target
->section().segmentName()) != 0 ) {
3219 // hi16 needs to know upper 4-bits of low16 to compute carry
3220 uint32_t extra
= (accumulator
>> 12) & 0xF;
3221 _splitSegInfos
.push_back(SplitSegInfoEntry(atom
->finalAddress()+fit
->offsetInAtom
,fit
->kind
, extra
));
3224 case ld::Fixup::kindSetTargetImageOffset
:
3225 accumulator
= addressOf(state
, fit
, &target
);
3226 assert(target
!= NULL
);
3238 void OutputFile::writeMapFile(ld::Internal
& state
)
3240 if ( _options
.generatedMapPath() != NULL
) {
3241 FILE* mapFile
= fopen(_options
.generatedMapPath(), "w");
3242 if ( mapFile
!= NULL
) {
3243 // write output path
3244 fprintf(mapFile
, "# Path: %s\n", _options
.outputFilePath());
3245 // write output architecure
3246 fprintf(mapFile
, "# Arch: %s\n", _options
.architectureName());
3248 //if ( fUUIDAtom != NULL ) {
3249 // const uint8_t* uuid = fUUIDAtom->getUUID();
3250 // fprintf(mapFile, "# UUID: %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X \n",
3251 // uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
3252 // uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
3254 // write table of object files
3255 std::map
<const ld::File
*, ld::File::Ordinal
> readerToOrdinal
;
3256 std::map
<ld::File::Ordinal
, const ld::File
*> ordinalToReader
;
3257 std::map
<const ld::File
*, uint32_t> readerToFileOrdinal
;
3258 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
3259 ld::Internal::FinalSection
* sect
= *sit
;
3260 if ( sect
->isSectionHidden() )
3262 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
3263 const ld::Atom
* atom
= *ait
;
3264 const ld::File
* reader
= atom
->file();
3265 if ( reader
== NULL
)
3267 ld::File::Ordinal readerOrdinal
= reader
->ordinal();
3268 std::map
<const ld::File
*, ld::File::Ordinal
>::iterator pos
= readerToOrdinal
.find(reader
);
3269 if ( pos
== readerToOrdinal
.end() ) {
3270 readerToOrdinal
[reader
] = readerOrdinal
;
3271 ordinalToReader
[readerOrdinal
] = reader
;
3275 fprintf(mapFile
, "# Object files:\n");
3276 fprintf(mapFile
, "[%3u] %s\n", 0, "linker synthesized");
3277 uint32_t fileIndex
= 1;
3278 for(std::map
<ld::File::Ordinal
, const ld::File
*>::iterator it
= ordinalToReader
.begin(); it
!= ordinalToReader
.end(); ++it
) {
3279 fprintf(mapFile
, "[%3u] %s\n", fileIndex
, it
->second
->path());
3280 readerToFileOrdinal
[it
->second
] = fileIndex
++;
3282 // write table of sections
3283 fprintf(mapFile
, "# Sections:\n");
3284 fprintf(mapFile
, "# Address\tSize \tSegment\tSection\n");
3285 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
3286 ld::Internal::FinalSection
* sect
= *sit
;
3287 if ( sect
->isSectionHidden() )
3289 fprintf(mapFile
, "0x%08llX\t0x%08llX\t%s\t%s\n", sect
->address
, sect
->size
,
3290 sect
->segmentName(), sect
->sectionName());
3292 // write table of symbols
3293 fprintf(mapFile
, "# Symbols:\n");
3294 fprintf(mapFile
, "# Address\tSize \tFile Name\n");
3295 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
3296 ld::Internal::FinalSection
* sect
= *sit
;
3297 if ( sect
->isSectionHidden() )
3299 //bool isCstring = (sect->type() == ld::Section::typeCString);
3300 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
3302 const ld::Atom
* atom
= *ait
;
3303 const char* name
= atom
->name();
3304 if ( atom
->contentType() == ld::Atom::typeCString
) {
3305 strcpy(buffer
, "literal string: ");
3306 strlcat(buffer
, (char*)atom
->rawContentPointer(), 4096);
3309 else if ( (atom
->contentType() == ld::Atom::typeCFI
) && (strcmp(name
, "FDE") == 0) ) {
3310 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(); fit
!= atom
->fixupsEnd(); ++fit
) {
3311 if ( (fit
->kind
== ld::Fixup::kindSetTargetAddress
) && (fit
->clusterSize
== ld::Fixup::k1of4
) ) {
3312 assert(fit
->binding
== ld::Fixup::bindingDirectlyBound
);
3313 if ( fit
->u
.target
->section().type() == ld::Section::typeCode
) {
3314 strcpy(buffer
, "FDE for: ");
3315 strlcat(buffer
, fit
->u
.target
->name(), 4096);
3321 else if ( atom
->contentType() == ld::Atom::typeNonLazyPointer
) {
3322 strcpy(buffer
, "non-lazy-pointer");
3323 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(); fit
!= atom
->fixupsEnd(); ++fit
) {
3324 if ( fit
->binding
== ld::Fixup::bindingsIndirectlyBound
) {
3325 strcpy(buffer
, "non-lazy-pointer-to: ");
3326 strlcat(buffer
, state
.indirectBindingTable
[fit
->u
.bindingIndex
]->name(), 4096);
3329 else if ( fit
->binding
== ld::Fixup::bindingDirectlyBound
) {
3330 strcpy(buffer
, "non-lazy-pointer-to-local: ");
3331 strlcat(buffer
, fit
->u
.target
->name(), 4096);
3337 fprintf(mapFile
, "0x%08llX\t0x%08llX\t[%3u] %s\n", atom
->finalAddress(), atom
->size(),
3338 readerToFileOrdinal
[atom
->file()], name
);
3344 warning("could not write map file: %s\n", _options
.generatedMapPath());
3350 // used to sort atoms with debug notes
3351 class DebugNoteSorter
3354 bool operator()(const ld::Atom
* left
, const ld::Atom
* right
) const
3356 // first sort by reader
3357 ld::File::Ordinal leftFileOrdinal
= left
->file()->ordinal();
3358 ld::File::Ordinal rightFileOrdinal
= right
->file()->ordinal();
3359 if ( leftFileOrdinal
!= rightFileOrdinal
)
3360 return (leftFileOrdinal
< rightFileOrdinal
);
3362 // then sort by atom objectAddress
3363 uint64_t leftAddr
= left
->finalAddress();
3364 uint64_t rightAddr
= right
->finalAddress();
3365 return leftAddr
< rightAddr
;
3373 bool operator()(const char* left
, const char* right
) const { return (strcmp(left
, right
) == 0); }
3376 const char* OutputFile::assureFullPath(const char* path
)
3378 if ( path
[0] == '/' )
3380 char cwdbuff
[MAXPATHLEN
];
3381 if ( getcwd(cwdbuff
, MAXPATHLEN
) != NULL
) {
3383 asprintf(&result
, "%s/%s", cwdbuff
, path
);
3384 if ( result
!= NULL
)
3390 void OutputFile::synthesizeDebugNotes(ld::Internal
& state
)
3392 // -S means don't synthesize debug map
3393 if ( _options
.debugInfoStripping() == Options::kDebugInfoNone
)
3395 // make a vector of atoms that come from files compiled with dwarf debug info
3396 std::vector
<const ld::Atom
*> atomsNeedingDebugNotes
;
3397 std::set
<const ld::Atom
*> atomsWithStabs
;
3398 atomsNeedingDebugNotes
.reserve(1024);
3399 const ld::relocatable::File
* objFile
= NULL
;
3400 bool objFileHasDwarf
= false;
3401 bool objFileHasStabs
= false;
3402 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
3403 ld::Internal::FinalSection
* sect
= *sit
;
3404 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
3405 const ld::Atom
* atom
= *ait
;
3406 // no stabs for atoms that would not be in the symbol table
3407 if ( atom
->symbolTableInclusion() == ld::Atom::symbolTableNotIn
)
3409 if ( atom
->symbolTableInclusion() == ld::Atom::symbolTableNotInFinalLinkedImages
)
3411 // no stabs for absolute symbols
3412 if ( atom
->definition() == ld::Atom::definitionAbsolute
)
3414 // no stabs for .eh atoms
3415 if ( atom
->contentType() == ld::Atom::typeCFI
)
3417 const ld::File
* file
= atom
->file();
3418 if ( file
!= NULL
) {
3419 if ( file
!= objFile
) {
3420 objFileHasDwarf
= false;
3421 objFileHasStabs
= false;
3422 objFile
= dynamic_cast<const ld::relocatable::File
*>(file
);
3423 if ( objFile
!= NULL
) {
3424 switch ( objFile
->debugInfo() ) {
3425 case ld::relocatable::File::kDebugInfoNone
:
3427 case ld::relocatable::File::kDebugInfoDwarf
:
3428 objFileHasDwarf
= true;
3430 case ld::relocatable::File::kDebugInfoStabs
:
3431 case ld::relocatable::File::kDebugInfoStabsUUID
:
3432 objFileHasStabs
= true;
3437 if ( objFileHasDwarf
)
3438 atomsNeedingDebugNotes
.push_back(atom
);
3439 if ( objFileHasStabs
)
3440 atomsWithStabs
.insert(atom
);
3445 // sort by file ordinal then atom ordinal
3446 std::sort(atomsNeedingDebugNotes
.begin(), atomsNeedingDebugNotes
.end(), DebugNoteSorter());
3448 // synthesize "debug notes" and add them to master stabs vector
3449 const char* dirPath
= NULL
;
3450 const char* filename
= NULL
;
3451 bool wroteStartSO
= false;
3452 state
.stabs
.reserve(atomsNeedingDebugNotes
.size()*4);
3453 __gnu_cxx::hash_set
<const char*, __gnu_cxx::hash
<const char*>, CStringEquals
> seenFiles
;
3454 for (std::vector
<const ld::Atom
*>::iterator it
=atomsNeedingDebugNotes
.begin(); it
!= atomsNeedingDebugNotes
.end(); it
++) {
3455 const ld::Atom
* atom
= *it
;
3456 const ld::File
* atomFile
= atom
->file();
3457 const ld::relocatable::File
* atomObjFile
= dynamic_cast<const ld::relocatable::File
*>(atomFile
);
3458 //fprintf(stderr, "debug note for %s\n", atom->name());
3459 const char* newPath
= atom
->translationUnitSource();
3460 if ( newPath
!= NULL
) {
3461 const char* newDirPath
;
3462 const char* newFilename
;
3463 const char* lastSlash
= strrchr(newPath
, '/');
3464 if ( lastSlash
== NULL
)
3466 newFilename
= lastSlash
+1;
3467 char* temp
= strdup(newPath
);
3469 // gdb like directory SO's to end in '/', but dwarf DW_AT_comp_dir usually does not have trailing '/'
3470 temp
[lastSlash
-newPath
+1] = '\0';
3471 // need SO's whenever the translation unit source file changes
3472 if ( (filename
== NULL
) || (strcmp(newFilename
,filename
) != 0) ) {
3473 if ( filename
!= NULL
) {
3474 // translation unit change, emit ending SO
3475 ld::relocatable::File::Stab endFileStab
;
3476 endFileStab
.atom
= NULL
;
3477 endFileStab
.type
= N_SO
;
3478 endFileStab
.other
= 1;
3479 endFileStab
.desc
= 0;
3480 endFileStab
.value
= 0;
3481 endFileStab
.string
= "";
3482 state
.stabs
.push_back(endFileStab
);
3484 // new translation unit, emit start SO's
3485 ld::relocatable::File::Stab dirPathStab
;
3486 dirPathStab
.atom
= NULL
;
3487 dirPathStab
.type
= N_SO
;
3488 dirPathStab
.other
= 0;
3489 dirPathStab
.desc
= 0;
3490 dirPathStab
.value
= 0;
3491 dirPathStab
.string
= newDirPath
;
3492 state
.stabs
.push_back(dirPathStab
);
3493 ld::relocatable::File::Stab fileStab
;
3494 fileStab
.atom
= NULL
;
3495 fileStab
.type
= N_SO
;
3499 fileStab
.string
= newFilename
;
3500 state
.stabs
.push_back(fileStab
);
3501 // Synthesize OSO for start of file
3502 ld::relocatable::File::Stab objStab
;
3503 objStab
.atom
= NULL
;
3504 objStab
.type
= N_OSO
;
3505 // <rdar://problem/6337329> linker should put cpusubtype in n_sect field of nlist entry for N_OSO debug note entries
3506 objStab
.other
= atomFile
->cpuSubType();
3508 if ( atomObjFile
!= NULL
) {
3509 objStab
.string
= assureFullPath(atomObjFile
->debugInfoPath());
3510 objStab
.value
= atomObjFile
->debugInfoModificationTime();
3513 objStab
.string
= assureFullPath(atomFile
->path());
3514 objStab
.value
= atomFile
->modificationTime();
3516 state
.stabs
.push_back(objStab
);
3517 wroteStartSO
= true;
3518 // add the source file path to seenFiles so it does not show up in SOLs
3519 seenFiles
.insert(newFilename
);
3521 asprintf(&fullFilePath
, "%s%s", newDirPath
, newFilename
);
3522 // add both leaf path and full path
3523 seenFiles
.insert(fullFilePath
);
3525 filename
= newFilename
;
3526 dirPath
= newDirPath
;
3527 if ( atom
->section().type() == ld::Section::typeCode
) {
3528 // Synthesize BNSYM and start FUN stabs
3529 ld::relocatable::File::Stab beginSym
;
3530 beginSym
.atom
= atom
;
3531 beginSym
.type
= N_BNSYM
;
3535 beginSym
.string
= "";
3536 state
.stabs
.push_back(beginSym
);
3537 ld::relocatable::File::Stab startFun
;
3538 startFun
.atom
= atom
;
3539 startFun
.type
= N_FUN
;
3543 startFun
.string
= atom
->name();
3544 state
.stabs
.push_back(startFun
);
3545 // Synthesize any SOL stabs needed
3546 const char* curFile
= NULL
;
3547 for (ld::Atom::LineInfo::iterator lit
= atom
->beginLineInfo(); lit
!= atom
->endLineInfo(); ++lit
) {
3548 if ( lit
->fileName
!= curFile
) {
3549 if ( seenFiles
.count(lit
->fileName
) == 0 ) {
3550 seenFiles
.insert(lit
->fileName
);
3551 ld::relocatable::File::Stab sol
;
3557 sol
.string
= lit
->fileName
;
3558 state
.stabs
.push_back(sol
);
3560 curFile
= lit
->fileName
;
3563 // Synthesize end FUN and ENSYM stabs
3564 ld::relocatable::File::Stab endFun
;
3566 endFun
.type
= N_FUN
;
3571 state
.stabs
.push_back(endFun
);
3572 ld::relocatable::File::Stab endSym
;
3574 endSym
.type
= N_ENSYM
;
3579 state
.stabs
.push_back(endSym
);
3582 ld::relocatable::File::Stab globalsStab
;
3583 const char* name
= atom
->name();
3584 if ( atom
->scope() == ld::Atom::scopeTranslationUnit
) {
3585 // Synthesize STSYM stab for statics
3586 globalsStab
.atom
= atom
;
3587 globalsStab
.type
= N_STSYM
;
3588 globalsStab
.other
= 1;
3589 globalsStab
.desc
= 0;
3590 globalsStab
.value
= 0;
3591 globalsStab
.string
= name
;
3592 state
.stabs
.push_back(globalsStab
);
3595 // Synthesize GSYM stab for other globals
3596 globalsStab
.atom
= atom
;
3597 globalsStab
.type
= N_GSYM
;
3598 globalsStab
.other
= 1;
3599 globalsStab
.desc
= 0;
3600 globalsStab
.value
= 0;
3601 globalsStab
.string
= name
;
3602 state
.stabs
.push_back(globalsStab
);
3608 if ( wroteStartSO
) {
3610 ld::relocatable::File::Stab endFileStab
;
3611 endFileStab
.atom
= NULL
;
3612 endFileStab
.type
= N_SO
;
3613 endFileStab
.other
= 1;
3614 endFileStab
.desc
= 0;
3615 endFileStab
.value
= 0;
3616 endFileStab
.string
= "";
3617 state
.stabs
.push_back(endFileStab
);
3620 // copy any stabs from .o file
3621 std::set
<const ld::File
*> filesSeenWithStabs
;
3622 for (std::set
<const ld::Atom
*>::iterator it
=atomsWithStabs
.begin(); it
!= atomsWithStabs
.end(); it
++) {
3623 const ld::Atom
* atom
= *it
;
3624 objFile
= dynamic_cast<const ld::relocatable::File
*>(atom
->file());
3625 if ( objFile
!= NULL
) {
3626 if ( filesSeenWithStabs
.count(objFile
) == 0 ) {
3627 filesSeenWithStabs
.insert(objFile
);
3628 const std::vector
<ld::relocatable::File::Stab
>* stabs
= objFile
->stabs();
3629 if ( stabs
!= NULL
) {
3630 for(std::vector
<ld::relocatable::File::Stab
>::const_iterator sit
= stabs
->begin(); sit
!= stabs
->end(); ++sit
) {
3631 ld::relocatable::File::Stab stab
= *sit
;
3632 // ignore stabs associated with atoms that were dead stripped or coalesced away
3633 if ( (sit
->atom
!= NULL
) && (atomsWithStabs
.count(sit
->atom
) == 0) )
3635 // <rdar://problem/8284718> Value of N_SO stabs should be address of first atom from translation unit
3636 if ( (stab
.type
== N_SO
) && (stab
.string
!= NULL
) && (stab
.string
[0] != '\0') ) {
3639 state
.stabs
.push_back(stab
);