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 +/-4GB): 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::kindStoreTargetAddressARMBranch24
:
2430 case ld::Fixup::kindStoreTargetAddressThumbBranch22
:
2431 case ld::Fixup::kindStoreTargetAddressARMLoad12
:
2433 case ld::Fixup::kindStoreX86DtraceCallSiteNop
:
2434 case ld::Fixup::kindStoreX86DtraceIsEnableSiteClear
:
2435 case ld::Fixup::kindStoreARMDtraceCallSiteNop
:
2436 case ld::Fixup::kindStoreARMDtraceIsEnableSiteClear
:
2437 case ld::Fixup::kindStoreThumbDtraceCallSiteNop
:
2438 case ld::Fixup::kindStoreThumbDtraceIsEnableSiteClear
:
2439 return (_options
.outputKind() == Options::kObjectFile
);
2446 bool OutputFile::isPointerToTarget(ld::Fixup::Kind kind
)
2449 case ld::Fixup::kindSetTargetAddress
:
2450 case ld::Fixup::kindStoreTargetAddressLittleEndian32
:
2451 case ld::Fixup::kindStoreTargetAddressLittleEndian64
:
2452 case ld::Fixup::kindStoreTargetAddressBigEndian32
:
2453 case ld::Fixup::kindStoreTargetAddressBigEndian64
:
2454 case ld::Fixup::kindLazyTarget
:
2461 bool OutputFile::isPointerFromTarget(ld::Fixup::Kind kind
)
2464 case ld::Fixup::kindSubtractTargetAddress
:
2473 uint64_t OutputFile::lookBackAddend(ld::Fixup::iterator fit
)
2475 uint64_t addend
= 0;
2476 switch ( fit
->clusterSize
) {
2477 case ld::Fixup::k1of1
:
2478 case ld::Fixup::k1of2
:
2479 case ld::Fixup::k2of2
:
2481 case ld::Fixup::k2of3
:
2483 switch ( fit
->kind
) {
2484 case ld::Fixup::kindAddAddend
:
2485 addend
+= fit
->u
.addend
;
2487 case ld::Fixup::kindSubtractAddend
:
2488 addend
-= fit
->u
.addend
;
2491 throw "unexpected fixup kind for binding";
2494 case ld::Fixup::k1of3
:
2496 switch ( fit
->kind
) {
2497 case ld::Fixup::kindAddAddend
:
2498 addend
+= fit
->u
.addend
;
2500 case ld::Fixup::kindSubtractAddend
:
2501 addend
-= fit
->u
.addend
;
2504 throw "unexpected fixup kind for binding";
2508 throw "unexpected fixup cluster size for binding";
2517 void OutputFile::generateLinkEditInfo(ld::Internal
& state
)
2519 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
2520 ld::Internal::FinalSection
* sect
= *sit
;
2521 bool objc1ClassRefSection
= ( (sect
->type() == ld::Section::typeCStringPointer
)
2522 && (strcmp(sect
->sectionName(), "__cls_refs") == 0)
2523 && (strcmp(sect
->segmentName(), "__OBJC") == 0) );
2524 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
2525 const ld::Atom
* atom
= *ait
;
2527 // Record regular atoms that override a dylib's weak definitions
2528 if ( (atom
->scope() == ld::Atom::scopeGlobal
) && atom
->overridesDylibsWeakDef() ) {
2529 if ( _options
.makeCompressedDyldInfo() ) {
2530 uint8_t wtype
= BIND_TYPE_OVERRIDE_OF_WEAKDEF_IN_DYLIB
;
2531 bool nonWeakDef
= (atom
->combine() == ld::Atom::combineNever
);
2532 _weakBindingInfo
.push_back(BindingInfo(wtype
, atom
->name(), nonWeakDef
, atom
->finalAddress(), 0));
2534 this->overridesWeakExternalSymbols
= true;
2535 if ( _options
.warnWeakExports() )
2536 warning("overrides weak external symbol: %s", atom
->name());
2539 ld::Fixup
* fixupWithTarget
= NULL
;
2540 ld::Fixup
* fixupWithMinusTarget
= NULL
;
2541 ld::Fixup
* fixupWithStore
= NULL
;
2542 const ld::Atom
* target
= NULL
;
2543 const ld::Atom
* minusTarget
= NULL
;
2544 uint64_t targetAddend
= 0;
2545 uint64_t minusTargetAddend
= 0;
2546 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(); fit
!= atom
->fixupsEnd(); ++fit
) {
2547 if ( fit
->firstInCluster() ) {
2548 fixupWithTarget
= NULL
;
2549 fixupWithMinusTarget
= NULL
;
2550 fixupWithStore
= NULL
;
2554 minusTargetAddend
= 0;
2556 if ( this->setsTarget(fit
->kind
) ) {
2557 switch ( fit
->binding
) {
2558 case ld::Fixup::bindingNone
:
2559 case ld::Fixup::bindingByNameUnbound
:
2561 case ld::Fixup::bindingByContentBound
:
2562 case ld::Fixup::bindingDirectlyBound
:
2563 fixupWithTarget
= fit
;
2564 target
= fit
->u
.target
;
2566 case ld::Fixup::bindingsIndirectlyBound
:
2567 fixupWithTarget
= fit
;
2568 target
= state
.indirectBindingTable
[fit
->u
.bindingIndex
];
2571 assert(target
!= NULL
);
2573 switch ( fit
->kind
) {
2574 case ld::Fixup::kindAddAddend
:
2575 targetAddend
= fit
->u
.addend
;
2577 case ld::Fixup::kindSubtractAddend
:
2578 minusTargetAddend
= fit
->u
.addend
;
2580 case ld::Fixup::kindSubtractTargetAddress
:
2581 switch ( fit
->binding
) {
2582 case ld::Fixup::bindingNone
:
2583 case ld::Fixup::bindingByNameUnbound
:
2585 case ld::Fixup::bindingByContentBound
:
2586 case ld::Fixup::bindingDirectlyBound
:
2587 fixupWithMinusTarget
= fit
;
2588 minusTarget
= fit
->u
.target
;
2590 case ld::Fixup::bindingsIndirectlyBound
:
2591 fixupWithMinusTarget
= fit
;
2592 minusTarget
= state
.indirectBindingTable
[fit
->u
.bindingIndex
];
2595 assert(minusTarget
!= NULL
);
2597 case ld::Fixup::kindDataInCodeStartData
:
2598 case ld::Fixup::kindDataInCodeStartJT8
:
2599 case ld::Fixup::kindDataInCodeStartJT16
:
2600 case ld::Fixup::kindDataInCodeStartJT32
:
2601 case ld::Fixup::kindDataInCodeStartJTA32
:
2602 case ld::Fixup::kindDataInCodeEnd
:
2603 hasDataInCode
= true;
2608 if ( this->isStore(fit
->kind
) ) {
2609 fixupWithStore
= fit
;
2611 if ( fit
->lastInCluster() ) {
2612 if ( (fixupWithStore
!= NULL
) && (target
!= NULL
) ) {
2613 if ( _options
.outputKind() == Options::kObjectFile
) {
2614 this->addSectionRelocs(state
, sect
, atom
, fixupWithTarget
, fixupWithMinusTarget
, fixupWithStore
,
2615 target
, minusTarget
, targetAddend
, minusTargetAddend
);
2618 if ( _options
.makeCompressedDyldInfo() ) {
2619 this->addDyldInfo(state
, sect
, atom
, fixupWithTarget
, fixupWithMinusTarget
, fixupWithStore
,
2620 target
, minusTarget
, targetAddend
, minusTargetAddend
);
2623 this->addClassicRelocs(state
, sect
, atom
, fixupWithTarget
, fixupWithMinusTarget
, fixupWithStore
,
2624 target
, minusTarget
, targetAddend
, minusTargetAddend
);
2628 else if ( objc1ClassRefSection
&& (target
!= NULL
) && (fixupWithStore
== NULL
) ) {
2629 // check for class refs to lazy loaded dylibs
2630 const ld::dylib::File
* dylib
= dynamic_cast<const ld::dylib::File
*>(target
->file());
2631 if ( (dylib
!= NULL
) && dylib
->willBeLazyLoadedDylib() )
2632 throwf("illegal class reference to %s in lazy loaded dylib %s", target
->name(), dylib
->path());
2641 void OutputFile::noteTextReloc(const ld::Atom
* atom
, const ld::Atom
* target
)
2643 if ( (atom
->contentType() == ld::Atom::typeStub
) || (atom
->contentType() == ld::Atom::typeStubHelper
) ) {
2644 // silently let stubs (synthesized by linker) use text relocs
2646 else if ( _options
.allowTextRelocs() ) {
2647 if ( _options
.warnAboutTextRelocs() )
2648 warning("text reloc in %s to %s", atom
->name(), target
->name());
2650 else if ( _options
.positionIndependentExecutable() && (_options
.outputKind() == Options::kDynamicExecutable
)
2651 && ((_options
.iOSVersionMin() >= ld::iOS_4_3
) || (_options
.macosxVersionMin() >= ld::mac10_7
)) ) {
2652 if ( ! this->pieDisabled
) {
2653 warning("PIE disabled. Absolute addressing (perhaps -mdynamic-no-pic) not allowed in code signed PIE, "
2654 "but used in %s from %s. "
2655 "To fix this warning, don't compile with -mdynamic-no-pic or link with -Wl,-no_pie",
2656 atom
->name(), atom
->file()->path());
2658 this->pieDisabled
= true;
2660 else if ( (target
->scope() == ld::Atom::scopeGlobal
) && (target
->combine() == ld::Atom::combineByName
) ) {
2661 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());
2664 throwf("illegal text-relocation to %s in %s from %s in %s", target
->name(), target
->file()->path(), atom
->name(), atom
->file()->path());
2668 void OutputFile::addDyldInfo(ld::Internal
& state
, ld::Internal::FinalSection
* sect
, const ld::Atom
* atom
,
2669 ld::Fixup
* fixupWithTarget
, ld::Fixup
* fixupWithMinusTarget
, ld::Fixup
* fixupWithStore
,
2670 const ld::Atom
* target
, const ld::Atom
* minusTarget
,
2671 uint64_t targetAddend
, uint64_t minusTargetAddend
)
2673 if ( sect
->isSectionHidden() )
2676 // no need to rebase or bind PCRel stores
2677 if ( this->isPcRelStore(fixupWithStore
->kind
) ) {
2678 // as long as target is in same linkage unit
2679 if ( (target
== NULL
) || (target
->definition() != ld::Atom::definitionProxy
) ) {
2680 // make sure target is not global and weak
2681 if ( (target
->scope() == ld::Atom::scopeGlobal
) && (target
->combine() == ld::Atom::combineByName
) && (target
->definition() == ld::Atom::definitionRegular
)) {
2682 if ( (atom
->section().type() == ld::Section::typeCFI
)
2683 || (atom
->section().type() == ld::Section::typeDtraceDOF
)
2684 || (atom
->section().type() == ld::Section::typeUnwindInfo
) ) {
2685 // ok for __eh_frame and __uwind_info to use pointer diffs to global weak symbols
2688 // Have direct reference to weak-global. This should be an indrect reference
2689 const char* demangledName
= strdup(_options
.demangleSymbol(atom
->name()));
2690 warning("direct access in %s to global weak symbol %s means the weak symbol cannot be overridden at runtime. "
2691 "This was likely caused by different translation units being compiled with different visibility settings.",
2692 demangledName
, _options
.demangleSymbol(target
->name()));
2698 // no need to rebase or bind PIC internal pointer diff
2699 if ( minusTarget
!= NULL
) {
2700 // with pointer diffs, both need to be in same linkage unit
2701 assert(minusTarget
->definition() != ld::Atom::definitionProxy
);
2702 assert(target
!= NULL
);
2703 assert(target
->definition() != ld::Atom::definitionProxy
);
2704 if ( target
== minusTarget
) {
2705 // This is a compile time constant and could have been optimized away by compiler
2709 // check if target of pointer-diff is global and weak
2710 if ( (target
->scope() == ld::Atom::scopeGlobal
) && (target
->combine() == ld::Atom::combineByName
) && (target
->definition() == ld::Atom::definitionRegular
) ) {
2711 if ( (atom
->section().type() == ld::Section::typeCFI
)
2712 || (atom
->section().type() == ld::Section::typeDtraceDOF
)
2713 || (atom
->section().type() == ld::Section::typeUnwindInfo
) ) {
2714 // ok for __eh_frame and __uwind_info to use pointer diffs to global weak symbols
2717 // Have direct reference to weak-global. This should be an indrect reference
2718 const char* demangledName
= strdup(_options
.demangleSymbol(atom
->name()));
2719 warning("direct access in %s to global weak symbol %s means the weak symbol cannot be overridden at runtime. "
2720 "This was likely caused by different translation units being compiled with different visibility settings.",
2721 demangledName
, _options
.demangleSymbol(target
->name()));
2726 // no need to rebase or bind an atom's references to itself if the output is not slidable
2727 if ( (atom
== target
) && !_options
.outputSlidable() )
2730 // cluster has no target, so needs no rebasing or binding
2731 if ( target
== NULL
)
2734 bool inReadOnlySeg
= ( strcmp(sect
->segmentName(), "__TEXT") == 0 );
2735 bool needsRebase
= false;
2736 bool needsBinding
= false;
2737 bool needsLazyBinding
= false;
2738 bool needsWeakBinding
= false;
2740 uint8_t rebaseType
= REBASE_TYPE_POINTER
;
2741 uint8_t type
= BIND_TYPE_POINTER
;
2742 const ld::dylib::File
* dylib
= dynamic_cast<const ld::dylib::File
*>(target
->file());
2743 bool weak_import
= (fixupWithTarget
->weakImport
|| ((dylib
!= NULL
) && dylib
->forcedWeakLinked()));
2744 uint64_t address
= atom
->finalAddress() + fixupWithTarget
->offsetInAtom
;
2745 uint64_t addend
= targetAddend
- minusTargetAddend
;
2747 // special case lazy pointers
2748 if ( fixupWithTarget
->kind
== ld::Fixup::kindLazyTarget
) {
2749 assert(fixupWithTarget
->u
.target
== target
);
2750 assert(addend
== 0);
2751 // lazy dylib lazy pointers do not have any dyld info
2752 if ( atom
->section().type() == ld::Section::typeLazyDylibPointer
)
2754 // lazy binding to weak definitions are done differently
2755 // they are directly bound to target, then have a weak bind in case of a collision
2756 if ( target
->combine() == ld::Atom::combineByName
) {
2757 if ( target
->definition() == ld::Atom::definitionProxy
) {
2758 // weak def exported from another dylib
2759 // must non-lazy bind to it plus have weak binding info in case of collision
2760 needsBinding
= true;
2761 needsWeakBinding
= true;
2764 // weak def in this linkage unit.
2765 // just rebase, plus have weak binding info in case of collision
2766 // this will be done by other cluster on lazy pointer atom
2769 else if ( (target
->contentType() == ld::Atom::typeResolver
) && (target
->scope() != ld::Atom::scopeGlobal
) ) {
2770 // <rdar://problem/8553647> Hidden resolver functions should not have lazy binding info
2771 needsLazyBinding
= false;
2774 // normal case of a pointer to non-weak-def symbol, so can lazily bind
2775 needsLazyBinding
= true;
2779 // everything except lazy pointers
2780 switch ( target
->definition() ) {
2781 case ld::Atom::definitionProxy
:
2782 if ( (dylib
!= NULL
) && dylib
->willBeLazyLoadedDylib() )
2783 throwf("illegal data reference to %s in lazy loaded dylib %s", target
->name(), dylib
->path());
2784 if ( target
->contentType() == ld::Atom::typeTLV
) {
2785 if ( sect
->type() != ld::Section::typeTLVPointers
)
2786 throwf("illegal data reference in %s to thread local variable %s in dylib %s",
2787 atom
->name(), target
->name(), dylib
->path());
2789 if ( inReadOnlySeg
)
2790 type
= BIND_TYPE_TEXT_ABSOLUTE32
;
2791 needsBinding
= true;
2792 if ( target
->combine() == ld::Atom::combineByName
)
2793 needsWeakBinding
= true;
2795 case ld::Atom::definitionRegular
:
2796 case ld::Atom::definitionTentative
:
2797 // only slideable images need rebasing info
2798 if ( _options
.outputSlidable() ) {
2801 // references to internal symbol never need binding
2802 if ( target
->scope() != ld::Atom::scopeGlobal
)
2804 // reference to global weak def needs weak binding
2805 if ( (target
->combine() == ld::Atom::combineByName
) && (target
->definition() == ld::Atom::definitionRegular
) )
2806 needsWeakBinding
= true;
2807 else if ( _options
.outputKind() == Options::kDynamicExecutable
) {
2808 // in main executables, the only way regular symbols are indirected is if -interposable is used
2809 if ( _options
.interposable(target
->name()) ) {
2810 needsRebase
= false;
2811 needsBinding
= true;
2815 // for flat-namespace or interposable two-level-namespace
2816 // all references to exported symbols get indirected
2817 if ( (_options
.nameSpace() != Options::kTwoLevelNameSpace
) || _options
.interposable(target
->name()) ) {
2818 // <rdar://problem/5254468> no external relocs for flat objc classes
2819 if ( strncmp(target
->name(), ".objc_class_", 12) == 0 )
2821 // no rebase info for references to global symbols that will have binding info
2822 needsRebase
= false;
2823 needsBinding
= true;
2827 case ld::Atom::definitionAbsolute
:
2832 // record dyld info for this cluster
2833 if ( needsRebase
) {
2834 if ( inReadOnlySeg
) {
2835 noteTextReloc(atom
, target
);
2836 sect
->hasLocalRelocs
= true; // so dyld knows to change permissions on __TEXT segment
2837 rebaseType
= REBASE_TYPE_TEXT_ABSOLUTE32
;
2839 if ( (addend
!= 0) && _options
.sharedRegionEligible() ) {
2840 // make sure the addend does not cause the pointer to point outside the target's segment
2841 // if it does, update_dyld_shared_cache will not be able to put this dylib into the shared cache
2842 uint64_t targetAddress
= target
->finalAddress();
2843 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
2844 ld::Internal::FinalSection
* sct
= *sit
;
2845 uint64_t sctEnd
= (sct
->address
+sct
->size
);
2846 if ( (sct
->address
<= targetAddress
) && (targetAddress
< sctEnd
) ) {
2847 if ( (targetAddress
+addend
) > sctEnd
) {
2848 warning("data symbol %s from %s has pointer to %s + 0x%08llX. "
2849 "That large of an addend may disable %s from being put in the dyld shared cache.",
2850 atom
->name(), atom
->file()->path(), target
->name(), addend
, _options
.installPath() );
2855 _rebaseInfo
.push_back(RebaseInfo(rebaseType
, address
));
2857 if ( needsBinding
) {
2858 if ( inReadOnlySeg
) {
2859 noteTextReloc(atom
, target
);
2860 sect
->hasExternalRelocs
= true; // so dyld knows to change permissions on __TEXT segment
2862 _bindingInfo
.push_back(BindingInfo(type
, this->compressedOrdinalForAtom(target
), target
->name(), weak_import
, address
, addend
));
2864 if ( needsLazyBinding
) {
2865 if ( _options
.bindAtLoad() )
2866 _bindingInfo
.push_back(BindingInfo(type
, this->compressedOrdinalForAtom(target
), target
->name(), weak_import
, address
, addend
));
2868 _lazyBindingInfo
.push_back(BindingInfo(type
, this->compressedOrdinalForAtom(target
), target
->name(), weak_import
, address
, addend
));
2870 if ( needsWeakBinding
)
2871 _weakBindingInfo
.push_back(BindingInfo(type
, 0, target
->name(), false, address
, addend
));
2875 void OutputFile::addClassicRelocs(ld::Internal
& state
, ld::Internal::FinalSection
* sect
, const ld::Atom
* atom
,
2876 ld::Fixup
* fixupWithTarget
, ld::Fixup
* fixupWithMinusTarget
, ld::Fixup
* fixupWithStore
,
2877 const ld::Atom
* target
, const ld::Atom
* minusTarget
,
2878 uint64_t targetAddend
, uint64_t minusTargetAddend
)
2880 if ( sect
->isSectionHidden() )
2883 // non-lazy-pointer section is encoded in indirect symbol table - not using relocations
2884 if ( sect
->type() == ld::Section::typeNonLazyPointer
) {
2885 // except kexts and static pie which *do* use relocations
2886 switch (_options
.outputKind()) {
2887 case Options::kKextBundle
:
2889 case Options::kStaticExecutable
:
2890 if ( _options
.positionIndependentExecutable() )
2892 // else fall into default case
2894 assert(target
!= NULL
);
2895 assert(fixupWithTarget
!= NULL
);
2900 // no need to rebase or bind PCRel stores
2901 if ( this->isPcRelStore(fixupWithStore
->kind
) ) {
2902 // as long as target is in same linkage unit
2903 if ( (target
== NULL
) || (target
->definition() != ld::Atom::definitionProxy
) )
2907 // no need to rebase or bind PIC internal pointer diff
2908 if ( minusTarget
!= NULL
) {
2909 // with pointer diffs, both need to be in same linkage unit
2910 assert(minusTarget
->definition() != ld::Atom::definitionProxy
);
2911 assert(target
!= NULL
);
2912 assert(target
->definition() != ld::Atom::definitionProxy
);
2913 // make sure target is not global and weak
2914 if ( (target
->scope() == ld::Atom::scopeGlobal
) && (target
->combine() == ld::Atom::combineByName
)
2915 && (atom
->section().type() != ld::Section::typeCFI
)
2916 && (atom
->section().type() != ld::Section::typeDtraceDOF
)
2917 && (atom
->section().type() != ld::Section::typeUnwindInfo
)
2918 && (minusTarget
!= target
) ) {
2919 // ok for __eh_frame and __uwind_info to use pointer diffs to global weak symbols
2920 throwf("bad codegen, pointer diff in %s to global weak symbol %s", atom
->name(), target
->name());
2925 // cluster has no target, so needs no rebasing or binding
2926 if ( target
== NULL
)
2929 assert(_localRelocsAtom
!= NULL
);
2930 uint64_t relocAddress
= atom
->finalAddress() + fixupWithTarget
->offsetInAtom
- _localRelocsAtom
->relocBaseAddress(state
);
2932 bool inReadOnlySeg
= ( strcmp(sect
->segmentName(), "__TEXT") == 0 );
2933 bool needsLocalReloc
= false;
2934 bool needsExternReloc
= false;
2936 switch ( fixupWithStore
->kind
) {
2937 case ld::Fixup::kindLazyTarget
:
2938 // lazy pointers don't need relocs
2940 case ld::Fixup::kindStoreLittleEndian32
:
2941 case ld::Fixup::kindStoreLittleEndian64
:
2942 case ld::Fixup::kindStoreBigEndian32
:
2943 case ld::Fixup::kindStoreBigEndian64
:
2944 case ld::Fixup::kindStoreTargetAddressLittleEndian32
:
2945 case ld::Fixup::kindStoreTargetAddressLittleEndian64
:
2946 case ld::Fixup::kindStoreTargetAddressBigEndian32
:
2947 case ld::Fixup::kindStoreTargetAddressBigEndian64
:
2949 switch ( target
->definition() ) {
2950 case ld::Atom::definitionProxy
:
2951 needsExternReloc
= true;
2953 case ld::Atom::definitionRegular
:
2954 case ld::Atom::definitionTentative
:
2955 // only slideable images need local relocs
2956 if ( _options
.outputSlidable() )
2957 needsLocalReloc
= true;
2958 // references to internal symbol never need binding
2959 if ( target
->scope() != ld::Atom::scopeGlobal
)
2961 // reference to global weak def needs weak binding in dynamic images
2962 if ( (target
->combine() == ld::Atom::combineByName
)
2963 && (target
->definition() == ld::Atom::definitionRegular
)
2964 && (_options
.outputKind() != Options::kStaticExecutable
) ) {
2965 needsExternReloc
= true;
2967 else if ( _options
.outputKind() == Options::kDynamicExecutable
) {
2968 // in main executables, the only way regular symbols are indirected is if -interposable is used
2969 if ( _options
.interposable(target
->name()) )
2970 needsExternReloc
= true;
2973 // for flat-namespace or interposable two-level-namespace
2974 // all references to exported symbols get indirected
2975 if ( (_options
.nameSpace() != Options::kTwoLevelNameSpace
) || _options
.interposable(target
->name()) ) {
2976 // <rdar://problem/5254468> no external relocs for flat objc classes
2977 if ( strncmp(target
->name(), ".objc_class_", 12) == 0 )
2979 // no rebase info for references to global symbols that will have binding info
2980 needsExternReloc
= true;
2983 if ( needsExternReloc
)
2984 needsLocalReloc
= false;
2986 case ld::Atom::definitionAbsolute
:
2989 if ( needsExternReloc
) {
2990 if ( inReadOnlySeg
)
2991 noteTextReloc(atom
, target
);
2992 const ld::dylib::File
* dylib
= dynamic_cast<const ld::dylib::File
*>(target
->file());
2993 if ( (dylib
!= NULL
) && dylib
->willBeLazyLoadedDylib() )
2994 throwf("illegal data reference to %s in lazy loaded dylib %s", target
->name(), dylib
->path());
2995 _externalRelocsAtom
->addExternalPointerReloc(relocAddress
, target
);
2996 sect
->hasExternalRelocs
= true;
2997 fixupWithTarget
->contentAddendOnly
= true;
2999 else if ( needsLocalReloc
) {
3000 assert(target
!= NULL
);
3001 if ( inReadOnlySeg
)
3002 noteTextReloc(atom
, target
);
3003 _localRelocsAtom
->addPointerReloc(relocAddress
, target
->machoSection());
3004 sect
->hasLocalRelocs
= true;
3007 case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32
:
3008 if ( _options
.outputKind() == Options::kKextBundle
) {
3009 assert(target
!= NULL
);
3010 if ( target
->definition() == ld::Atom::definitionProxy
) {
3011 _externalRelocsAtom
->addExternalCallSiteReloc(relocAddress
, target
);
3012 fixupWithStore
->contentAddendOnly
= true;
3017 case ld::Fixup::kindStoreARMLow16
:
3018 case ld::Fixup::kindStoreThumbLow16
:
3019 // no way to encode rebasing of binding for these instructions
3020 if ( _options
.outputSlidable() || (target
->definition() == ld::Atom::definitionProxy
) )
3021 throwf("no supported runtime lo16 relocation in %s from %s to %s", atom
->name(), atom
->file()->path(), target
->name());
3024 case ld::Fixup::kindStoreARMHigh16
:
3025 case ld::Fixup::kindStoreThumbHigh16
:
3026 // no way to encode rebasing of binding for these instructions
3027 if ( _options
.outputSlidable() || (target
->definition() == ld::Atom::definitionProxy
) )
3028 throwf("no supported runtime hi16 relocation in %s from %s to %s", atom
->name(), atom
->file()->path(), target
->name());
3037 bool OutputFile::useExternalSectionReloc(const ld::Atom
* atom
, const ld::Atom
* target
, ld::Fixup
* fixupWithTarget
)
3039 if ( _options
.architecture() == CPU_TYPE_X86_64
) {
3040 // x86_64 uses external relocations for everthing that has a symbol
3041 return ( target
->symbolTableInclusion() != ld::Atom::symbolTableNotIn
);
3044 // <rdar://problem/9513487> support arm branch interworking in -r mode
3045 if ( (_options
.architecture() == CPU_TYPE_ARM
) && (_options
.outputKind() == Options::kObjectFile
) ) {
3046 if ( atom
->isThumb() != target
->isThumb() ) {
3047 switch ( fixupWithTarget
->kind
) {
3048 // have branch that switches mode, then might be 'b' not 'bl'
3049 // Force external relocation, since no way to do local reloc for 'b'
3050 case ld::Fixup::kindStoreTargetAddressThumbBranch22
:
3051 case ld::Fixup::kindStoreTargetAddressARMBranch24
:
3059 // most architectures use external relocations only for references
3060 // to a symbol in another translation unit or for references to "weak symbols" or tentative definitions
3061 assert(target
!= NULL
);
3062 if ( target
->definition() == ld::Atom::definitionProxy
)
3064 if ( (target
->definition() == ld::Atom::definitionTentative
) && ! _options
.makeTentativeDefinitionsReal() )
3066 if ( target
->scope() != ld::Atom::scopeGlobal
)
3068 if ( (target
->combine() == ld::Atom::combineByName
) && (target
->definition() == ld::Atom::definitionRegular
) )
3076 void OutputFile::addSectionRelocs(ld::Internal
& state
, ld::Internal::FinalSection
* sect
, const ld::Atom
* atom
,
3077 ld::Fixup
* fixupWithTarget
, ld::Fixup
* fixupWithMinusTarget
, ld::Fixup
* fixupWithStore
,
3078 const ld::Atom
* target
, const ld::Atom
* minusTarget
,
3079 uint64_t targetAddend
, uint64_t minusTargetAddend
)
3081 if ( sect
->isSectionHidden() )
3084 // in -r mode where there will be no labels on __eh_frame section, there is no need for relocations
3085 if ( (sect
->type() == ld::Section::typeCFI
) && _options
.removeEHLabels() )
3088 // non-lazy-pointer section is encoded in indirect symbol table - not using relocations
3089 if ( sect
->type() == ld::Section::typeNonLazyPointer
)
3092 // tentative defs don't have any relocations
3093 if ( sect
->type() == ld::Section::typeTentativeDefs
)
3096 assert(target
!= NULL
);
3097 assert(fixupWithTarget
!= NULL
);
3098 bool targetUsesExternalReloc
= this->useExternalSectionReloc(atom
, target
, fixupWithTarget
);
3099 bool minusTargetUsesExternalReloc
= (minusTarget
!= NULL
) && this->useExternalSectionReloc(atom
, minusTarget
, fixupWithMinusTarget
);
3101 // in x86_64 .o files an external reloc means the content contains just the addend
3102 if ( _options
.architecture() == CPU_TYPE_X86_64
) {
3103 if ( targetUsesExternalReloc
) {
3104 fixupWithTarget
->contentAddendOnly
= true;
3105 fixupWithStore
->contentAddendOnly
= true;
3107 if ( minusTargetUsesExternalReloc
)
3108 fixupWithMinusTarget
->contentAddendOnly
= true;
3111 // for other archs, content is addend only with (non pc-rel) pointers
3112 // pc-rel instructions are funny. If the target is _foo+8 and _foo is
3113 // external, then the pc-rel instruction *evalutates* to the address 8.
3114 if ( targetUsesExternalReloc
) {
3115 if ( isPcRelStore(fixupWithStore
->kind
) ) {
3116 fixupWithTarget
->contentDetlaToAddendOnly
= true;
3117 fixupWithStore
->contentDetlaToAddendOnly
= true;
3119 else if ( minusTarget
== NULL
){
3120 fixupWithTarget
->contentAddendOnly
= true;
3121 fixupWithStore
->contentAddendOnly
= true;
3126 if ( fixupWithStore
!= NULL
) {
3127 _sectionsRelocationsAtom
->addSectionReloc(sect
, fixupWithStore
->kind
, atom
, fixupWithStore
->offsetInAtom
,
3128 targetUsesExternalReloc
, minusTargetUsesExternalReloc
,
3129 target
, targetAddend
, minusTarget
, minusTargetAddend
);
3135 void OutputFile::makeSplitSegInfo(ld::Internal
& state
)
3137 if ( !_options
.sharedRegionEligible() )
3140 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
3141 ld::Internal::FinalSection
* sect
= *sit
;
3142 if ( sect
->isSectionHidden() )
3144 if ( strcmp(sect
->segmentName(), "__TEXT") != 0 )
3146 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
3147 const ld::Atom
* atom
= *ait
;
3148 const ld::Atom
* target
= NULL
;
3149 const ld::Atom
* fromTarget
= NULL
;
3150 uint64_t accumulator
= 0;
3152 bool hadSubtract
= false;
3153 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(), end
=atom
->fixupsEnd(); fit
!= end
; ++fit
) {
3154 if ( fit
->firstInCluster() )
3156 if ( this->setsTarget(fit
->kind
) ) {
3157 accumulator
= addressOf(state
, fit
, &target
);
3158 thumbTarget
= targetIsThumb(state
, fit
);
3162 switch ( fit
->kind
) {
3163 case ld::Fixup::kindSubtractTargetAddress
:
3164 accumulator
-= addressOf(state
, fit
, &fromTarget
);
3167 case ld::Fixup::kindAddAddend
:
3168 accumulator
+= fit
->u
.addend
;
3170 case ld::Fixup::kindSubtractAddend
:
3171 accumulator
-= fit
->u
.addend
;
3173 case ld::Fixup::kindStoreBigEndian32
:
3174 case ld::Fixup::kindStoreLittleEndian32
:
3175 case ld::Fixup::kindStoreLittleEndian64
:
3176 case ld::Fixup::kindStoreTargetAddressLittleEndian32
:
3177 case ld::Fixup::kindStoreTargetAddressLittleEndian64
:
3178 // if no subtract, then this is an absolute pointer which means
3179 // there is also a text reloc which update_dyld_shared_cache will use.
3180 if ( ! hadSubtract
)
3183 case ld::Fixup::kindStoreX86PCRel32
:
3184 case ld::Fixup::kindStoreX86PCRel32_1
:
3185 case ld::Fixup::kindStoreX86PCRel32_2
:
3186 case ld::Fixup::kindStoreX86PCRel32_4
:
3187 case ld::Fixup::kindStoreX86PCRel32GOTLoad
:
3188 case ld::Fixup::kindStoreX86PCRel32GOTLoadNowLEA
:
3189 case ld::Fixup::kindStoreX86PCRel32GOT
:
3190 case ld::Fixup::kindStoreTargetAddressX86PCRel32
:
3191 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad
:
3192 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA
:
3193 case ld::Fixup::kindStoreARMLow16
:
3194 case ld::Fixup::kindStoreThumbLow16
:
3195 assert(target
!= NULL
);
3196 if ( strcmp(sect
->segmentName(), target
->section().segmentName()) != 0 ) {
3197 _splitSegInfos
.push_back(SplitSegInfoEntry(atom
->finalAddress()+fit
->offsetInAtom
,fit
->kind
));
3200 case ld::Fixup::kindStoreARMHigh16
:
3201 case ld::Fixup::kindStoreThumbHigh16
:
3202 assert(target
!= NULL
);
3203 if ( strcmp(sect
->segmentName(), target
->section().segmentName()) != 0 ) {
3204 // hi16 needs to know upper 4-bits of low16 to compute carry
3205 uint32_t extra
= (accumulator
>> 12) & 0xF;
3206 _splitSegInfos
.push_back(SplitSegInfoEntry(atom
->finalAddress()+fit
->offsetInAtom
,fit
->kind
, extra
));
3209 case ld::Fixup::kindSetTargetImageOffset
:
3210 accumulator
= addressOf(state
, fit
, &target
);
3211 assert(target
!= NULL
);
3223 void OutputFile::writeMapFile(ld::Internal
& state
)
3225 if ( _options
.generatedMapPath() != NULL
) {
3226 FILE* mapFile
= fopen(_options
.generatedMapPath(), "w");
3227 if ( mapFile
!= NULL
) {
3228 // write output path
3229 fprintf(mapFile
, "# Path: %s\n", _options
.outputFilePath());
3230 // write output architecure
3231 fprintf(mapFile
, "# Arch: %s\n", _options
.architectureName());
3233 //if ( fUUIDAtom != NULL ) {
3234 // const uint8_t* uuid = fUUIDAtom->getUUID();
3235 // fprintf(mapFile, "# UUID: %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X \n",
3236 // uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
3237 // uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
3239 // write table of object files
3240 std::map
<const ld::File
*, ld::File::Ordinal
> readerToOrdinal
;
3241 std::map
<ld::File::Ordinal
, const ld::File
*> ordinalToReader
;
3242 std::map
<const ld::File
*, uint32_t> readerToFileOrdinal
;
3243 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
3244 ld::Internal::FinalSection
* sect
= *sit
;
3245 if ( sect
->isSectionHidden() )
3247 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
3248 const ld::Atom
* atom
= *ait
;
3249 const ld::File
* reader
= atom
->file();
3250 if ( reader
== NULL
)
3252 ld::File::Ordinal readerOrdinal
= reader
->ordinal();
3253 std::map
<const ld::File
*, ld::File::Ordinal
>::iterator pos
= readerToOrdinal
.find(reader
);
3254 if ( pos
== readerToOrdinal
.end() ) {
3255 readerToOrdinal
[reader
] = readerOrdinal
;
3256 ordinalToReader
[readerOrdinal
] = reader
;
3260 fprintf(mapFile
, "# Object files:\n");
3261 fprintf(mapFile
, "[%3u] %s\n", 0, "linker synthesized");
3262 uint32_t fileIndex
= 1;
3263 for(std::map
<ld::File::Ordinal
, const ld::File
*>::iterator it
= ordinalToReader
.begin(); it
!= ordinalToReader
.end(); ++it
) {
3264 fprintf(mapFile
, "[%3u] %s\n", fileIndex
, it
->second
->path());
3265 readerToFileOrdinal
[it
->second
] = fileIndex
++;
3267 // write table of sections
3268 fprintf(mapFile
, "# Sections:\n");
3269 fprintf(mapFile
, "# Address\tSize \tSegment\tSection\n");
3270 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
3271 ld::Internal::FinalSection
* sect
= *sit
;
3272 if ( sect
->isSectionHidden() )
3274 fprintf(mapFile
, "0x%08llX\t0x%08llX\t%s\t%s\n", sect
->address
, sect
->size
,
3275 sect
->segmentName(), sect
->sectionName());
3277 // write table of symbols
3278 fprintf(mapFile
, "# Symbols:\n");
3279 fprintf(mapFile
, "# Address\tSize \tFile Name\n");
3280 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
3281 ld::Internal::FinalSection
* sect
= *sit
;
3282 if ( sect
->isSectionHidden() )
3284 //bool isCstring = (sect->type() == ld::Section::typeCString);
3285 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
3287 const ld::Atom
* atom
= *ait
;
3288 const char* name
= atom
->name();
3289 if ( atom
->contentType() == ld::Atom::typeCString
) {
3290 strcpy(buffer
, "literal string: ");
3291 strlcat(buffer
, (char*)atom
->rawContentPointer(), 4096);
3294 else if ( (atom
->contentType() == ld::Atom::typeCFI
) && (strcmp(name
, "FDE") == 0) ) {
3295 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(); fit
!= atom
->fixupsEnd(); ++fit
) {
3296 if ( (fit
->kind
== ld::Fixup::kindSetTargetAddress
) && (fit
->clusterSize
== ld::Fixup::k1of4
) ) {
3297 assert(fit
->binding
== ld::Fixup::bindingDirectlyBound
);
3298 if ( fit
->u
.target
->section().type() == ld::Section::typeCode
) {
3299 strcpy(buffer
, "FDE for: ");
3300 strlcat(buffer
, fit
->u
.target
->name(), 4096);
3306 else if ( atom
->contentType() == ld::Atom::typeNonLazyPointer
) {
3307 strcpy(buffer
, "non-lazy-pointer");
3308 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(); fit
!= atom
->fixupsEnd(); ++fit
) {
3309 if ( fit
->binding
== ld::Fixup::bindingsIndirectlyBound
) {
3310 strcpy(buffer
, "non-lazy-pointer-to: ");
3311 strlcat(buffer
, state
.indirectBindingTable
[fit
->u
.bindingIndex
]->name(), 4096);
3314 else if ( fit
->binding
== ld::Fixup::bindingDirectlyBound
) {
3315 strcpy(buffer
, "non-lazy-pointer-to-local: ");
3316 strlcat(buffer
, fit
->u
.target
->name(), 4096);
3322 fprintf(mapFile
, "0x%08llX\t0x%08llX\t[%3u] %s\n", atom
->finalAddress(), atom
->size(),
3323 readerToFileOrdinal
[atom
->file()], name
);
3329 warning("could not write map file: %s\n", _options
.generatedMapPath());
3335 // used to sort atoms with debug notes
3336 class DebugNoteSorter
3339 bool operator()(const ld::Atom
* left
, const ld::Atom
* right
) const
3341 // first sort by reader
3342 ld::File::Ordinal leftFileOrdinal
= left
->file()->ordinal();
3343 ld::File::Ordinal rightFileOrdinal
= right
->file()->ordinal();
3344 if ( leftFileOrdinal
!= rightFileOrdinal
)
3345 return (leftFileOrdinal
< rightFileOrdinal
);
3347 // then sort by atom objectAddress
3348 uint64_t leftAddr
= left
->finalAddress();
3349 uint64_t rightAddr
= right
->finalAddress();
3350 return leftAddr
< rightAddr
;
3358 bool operator()(const char* left
, const char* right
) const { return (strcmp(left
, right
) == 0); }
3361 const char* OutputFile::assureFullPath(const char* path
)
3363 if ( path
[0] == '/' )
3365 char cwdbuff
[MAXPATHLEN
];
3366 if ( getcwd(cwdbuff
, MAXPATHLEN
) != NULL
) {
3368 asprintf(&result
, "%s/%s", cwdbuff
, path
);
3369 if ( result
!= NULL
)
3375 void OutputFile::synthesizeDebugNotes(ld::Internal
& state
)
3377 // -S means don't synthesize debug map
3378 if ( _options
.debugInfoStripping() == Options::kDebugInfoNone
)
3380 // make a vector of atoms that come from files compiled with dwarf debug info
3381 std::vector
<const ld::Atom
*> atomsNeedingDebugNotes
;
3382 std::set
<const ld::Atom
*> atomsWithStabs
;
3383 atomsNeedingDebugNotes
.reserve(1024);
3384 const ld::relocatable::File
* objFile
= NULL
;
3385 bool objFileHasDwarf
= false;
3386 bool objFileHasStabs
= false;
3387 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
3388 ld::Internal::FinalSection
* sect
= *sit
;
3389 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
3390 const ld::Atom
* atom
= *ait
;
3391 // no stabs for atoms that would not be in the symbol table
3392 if ( atom
->symbolTableInclusion() == ld::Atom::symbolTableNotIn
)
3394 if ( atom
->symbolTableInclusion() == ld::Atom::symbolTableNotInFinalLinkedImages
)
3396 // no stabs for absolute symbols
3397 if ( atom
->definition() == ld::Atom::definitionAbsolute
)
3399 // no stabs for .eh atoms
3400 if ( atom
->contentType() == ld::Atom::typeCFI
)
3402 const ld::File
* file
= atom
->file();
3403 if ( file
!= NULL
) {
3404 if ( file
!= objFile
) {
3405 objFileHasDwarf
= false;
3406 objFileHasStabs
= false;
3407 objFile
= dynamic_cast<const ld::relocatable::File
*>(file
);
3408 if ( objFile
!= NULL
) {
3409 switch ( objFile
->debugInfo() ) {
3410 case ld::relocatable::File::kDebugInfoNone
:
3412 case ld::relocatable::File::kDebugInfoDwarf
:
3413 objFileHasDwarf
= true;
3415 case ld::relocatable::File::kDebugInfoStabs
:
3416 case ld::relocatable::File::kDebugInfoStabsUUID
:
3417 objFileHasStabs
= true;
3422 if ( objFileHasDwarf
)
3423 atomsNeedingDebugNotes
.push_back(atom
);
3424 if ( objFileHasStabs
)
3425 atomsWithStabs
.insert(atom
);
3430 // sort by file ordinal then atom ordinal
3431 std::sort(atomsNeedingDebugNotes
.begin(), atomsNeedingDebugNotes
.end(), DebugNoteSorter());
3433 // synthesize "debug notes" and add them to master stabs vector
3434 const char* dirPath
= NULL
;
3435 const char* filename
= NULL
;
3436 bool wroteStartSO
= false;
3437 state
.stabs
.reserve(atomsNeedingDebugNotes
.size()*4);
3438 __gnu_cxx::hash_set
<const char*, __gnu_cxx::hash
<const char*>, CStringEquals
> seenFiles
;
3439 for (std::vector
<const ld::Atom
*>::iterator it
=atomsNeedingDebugNotes
.begin(); it
!= atomsNeedingDebugNotes
.end(); it
++) {
3440 const ld::Atom
* atom
= *it
;
3441 const ld::File
* atomFile
= atom
->file();
3442 const ld::relocatable::File
* atomObjFile
= dynamic_cast<const ld::relocatable::File
*>(atomFile
);
3443 const char* newDirPath
;
3444 const char* newFilename
;
3445 //fprintf(stderr, "debug note for %s\n", atom->name());
3446 // guard against dwarf info that has no directory <rdar://problem/10991352>
3447 if ( atom
->translationUnitSource(&newDirPath
, &newFilename
) && (newDirPath
!= NULL
)) {
3448 // need SO's whenever the translation unit source file changes
3449 if ( newFilename
!= filename
) {
3450 // gdb like directory SO's to end in '/', but dwarf DW_AT_comp_dir usually does not have trailing '/'
3451 size_t len
= strlen(newDirPath
);
3452 if ( (newDirPath
!= NULL
) && (len
> 1 ) && (newDirPath
[len
-1] != '/') )
3453 asprintf((char**)&newDirPath
, "%s/", newDirPath
);
3454 if ( filename
!= NULL
) {
3455 // translation unit change, emit ending SO
3456 ld::relocatable::File::Stab endFileStab
;
3457 endFileStab
.atom
= NULL
;
3458 endFileStab
.type
= N_SO
;
3459 endFileStab
.other
= 1;
3460 endFileStab
.desc
= 0;
3461 endFileStab
.value
= 0;
3462 endFileStab
.string
= "";
3463 state
.stabs
.push_back(endFileStab
);
3465 // new translation unit, emit start SO's
3466 ld::relocatable::File::Stab dirPathStab
;
3467 dirPathStab
.atom
= NULL
;
3468 dirPathStab
.type
= N_SO
;
3469 dirPathStab
.other
= 0;
3470 dirPathStab
.desc
= 0;
3471 dirPathStab
.value
= 0;
3472 dirPathStab
.string
= newDirPath
;
3473 state
.stabs
.push_back(dirPathStab
);
3474 ld::relocatable::File::Stab fileStab
;
3475 fileStab
.atom
= NULL
;
3476 fileStab
.type
= N_SO
;
3480 fileStab
.string
= newFilename
;
3481 state
.stabs
.push_back(fileStab
);
3482 // Synthesize OSO for start of file
3483 ld::relocatable::File::Stab objStab
;
3484 objStab
.atom
= NULL
;
3485 objStab
.type
= N_OSO
;
3486 // <rdar://problem/6337329> linker should put cpusubtype in n_sect field of nlist entry for N_OSO debug note entries
3487 objStab
.other
= atomFile
->cpuSubType();
3489 if ( atomObjFile
!= NULL
) {
3490 objStab
.string
= assureFullPath(atomObjFile
->debugInfoPath());
3491 objStab
.value
= atomObjFile
->debugInfoModificationTime();
3494 objStab
.string
= assureFullPath(atomFile
->path());
3495 objStab
.value
= atomFile
->modificationTime();
3497 state
.stabs
.push_back(objStab
);
3498 wroteStartSO
= true;
3499 // add the source file path to seenFiles so it does not show up in SOLs
3500 seenFiles
.insert(newFilename
);
3502 asprintf(&fullFilePath
, "%s%s", newDirPath
, newFilename
);
3503 // add both leaf path and full path
3504 seenFiles
.insert(fullFilePath
);
3506 filename
= newFilename
;
3507 dirPath
= newDirPath
;
3508 if ( atom
->section().type() == ld::Section::typeCode
) {
3509 // Synthesize BNSYM and start FUN stabs
3510 ld::relocatable::File::Stab beginSym
;
3511 beginSym
.atom
= atom
;
3512 beginSym
.type
= N_BNSYM
;
3516 beginSym
.string
= "";
3517 state
.stabs
.push_back(beginSym
);
3518 ld::relocatable::File::Stab startFun
;
3519 startFun
.atom
= atom
;
3520 startFun
.type
= N_FUN
;
3524 startFun
.string
= atom
->name();
3525 state
.stabs
.push_back(startFun
);
3526 // Synthesize any SOL stabs needed
3527 const char* curFile
= NULL
;
3528 for (ld::Atom::LineInfo::iterator lit
= atom
->beginLineInfo(); lit
!= atom
->endLineInfo(); ++lit
) {
3529 if ( lit
->fileName
!= curFile
) {
3530 if ( seenFiles
.count(lit
->fileName
) == 0 ) {
3531 seenFiles
.insert(lit
->fileName
);
3532 ld::relocatable::File::Stab sol
;
3538 sol
.string
= lit
->fileName
;
3539 state
.stabs
.push_back(sol
);
3541 curFile
= lit
->fileName
;
3544 // Synthesize end FUN and ENSYM stabs
3545 ld::relocatable::File::Stab endFun
;
3547 endFun
.type
= N_FUN
;
3552 state
.stabs
.push_back(endFun
);
3553 ld::relocatable::File::Stab endSym
;
3555 endSym
.type
= N_ENSYM
;
3560 state
.stabs
.push_back(endSym
);
3563 ld::relocatable::File::Stab globalsStab
;
3564 const char* name
= atom
->name();
3565 if ( atom
->scope() == ld::Atom::scopeTranslationUnit
) {
3566 // Synthesize STSYM stab for statics
3567 globalsStab
.atom
= atom
;
3568 globalsStab
.type
= N_STSYM
;
3569 globalsStab
.other
= 1;
3570 globalsStab
.desc
= 0;
3571 globalsStab
.value
= 0;
3572 globalsStab
.string
= name
;
3573 state
.stabs
.push_back(globalsStab
);
3576 // Synthesize GSYM stab for other globals
3577 globalsStab
.atom
= atom
;
3578 globalsStab
.type
= N_GSYM
;
3579 globalsStab
.other
= 1;
3580 globalsStab
.desc
= 0;
3581 globalsStab
.value
= 0;
3582 globalsStab
.string
= name
;
3583 state
.stabs
.push_back(globalsStab
);
3589 if ( wroteStartSO
) {
3591 ld::relocatable::File::Stab endFileStab
;
3592 endFileStab
.atom
= NULL
;
3593 endFileStab
.type
= N_SO
;
3594 endFileStab
.other
= 1;
3595 endFileStab
.desc
= 0;
3596 endFileStab
.value
= 0;
3597 endFileStab
.string
= "";
3598 state
.stabs
.push_back(endFileStab
);
3601 // copy any stabs from .o file
3602 std::set
<const ld::File
*> filesSeenWithStabs
;
3603 for (std::set
<const ld::Atom
*>::iterator it
=atomsWithStabs
.begin(); it
!= atomsWithStabs
.end(); it
++) {
3604 const ld::Atom
* atom
= *it
;
3605 objFile
= dynamic_cast<const ld::relocatable::File
*>(atom
->file());
3606 if ( objFile
!= NULL
) {
3607 if ( filesSeenWithStabs
.count(objFile
) == 0 ) {
3608 filesSeenWithStabs
.insert(objFile
);
3609 const std::vector
<ld::relocatable::File::Stab
>* stabs
= objFile
->stabs();
3610 if ( stabs
!= NULL
) {
3611 for(std::vector
<ld::relocatable::File::Stab
>::const_iterator sit
= stabs
->begin(); sit
!= stabs
->end(); ++sit
) {
3612 ld::relocatable::File::Stab stab
= *sit
;
3613 // ignore stabs associated with atoms that were dead stripped or coalesced away
3614 if ( (sit
->atom
!= NULL
) && (atomsWithStabs
.count(sit
->atom
) == 0) )
3616 // <rdar://problem/8284718> Value of N_SO stabs should be address of first atom from translation unit
3617 if ( (stab
.type
== N_SO
) && (stab
.string
!= NULL
) && (stab
.string
[0] != '\0') ) {
3620 state
.stabs
.push_back(stab
);