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>
31 #include <sys/param.h>
32 #include <sys/mount.h>
37 #include <mach/mach_time.h>
38 #include <mach/vm_statistics.h>
39 #include <mach/mach_init.h>
40 #include <mach/mach_host.h>
41 #include <uuid/uuid.h>
43 #include <mach-o/dyld.h>
44 #include <mach-o/fat.h>
53 #include <unordered_set>
55 #include <CommonCrypto/CommonDigest.h>
56 #include <AvailabilityMacros.h>
58 #include "MachOTrie.hpp"
62 #include "OutputFile.h"
63 #include "Architectures.hpp"
64 #include "HeaderAndLoadCommands.hpp"
65 #include "LinkEdit.hpp"
66 #include "LinkEditClassic.hpp"
73 OutputFile::OutputFile(const Options
& opts
)
75 hasWeakExternalSymbols(false), usesWeakExternalSymbols(false), overridesWeakExternalSymbols(false),
76 _noReExportedDylibs(false), hasThreadLocalVariableDefinitions(false), pieDisabled(false), hasDataInCode(false),
77 headerAndLoadCommandsSection(NULL
),
78 rebaseSection(NULL
), bindingSection(NULL
), weakBindingSection(NULL
),
79 lazyBindingSection(NULL
), exportSection(NULL
),
80 splitSegInfoSection(NULL
), functionStartsSection(NULL
),
81 dataInCodeSection(NULL
), dependentDRsSection(NULL
),
82 symbolTableSection(NULL
), stringPoolSection(NULL
),
83 localRelocationsSection(NULL
), externalRelocationsSection(NULL
),
84 sectionRelocationsSection(NULL
),
85 indirectSymbolTableSection(NULL
),
87 _hasDyldInfo(opts
.makeCompressedDyldInfo()),
88 _hasSymbolTable(true),
89 _hasSectionRelocations(opts
.outputKind() == Options::kObjectFile
),
90 _hasSplitSegInfo(opts
.sharedRegionEligible()),
91 _hasFunctionStartsInfo(opts
.addFunctionStarts()),
92 _hasDataInCodeInfo(opts
.addDataInCodeInfo()),
93 _hasDependentDRInfo(opts
.needsDependentDRInfo()),
94 _hasDynamicSymbolTable(true),
95 _hasLocalRelocations(!opts
.makeCompressedDyldInfo()),
96 _hasExternalRelocations(!opts
.makeCompressedDyldInfo()),
97 _encryptedTEXTstartOffset(0),
98 _encryptedTEXTendOffset(0),
99 _localSymbolsStartIndex(0),
100 _localSymbolsCount(0),
101 _globalSymbolsStartIndex(0),
102 _globalSymbolsCount(0),
103 _importSymbolsStartIndex(0),
104 _importSymbolsCount(0),
105 _sectionsRelocationsAtom(NULL
),
106 _localRelocsAtom(NULL
),
107 _externalRelocsAtom(NULL
),
108 _symbolTableAtom(NULL
),
109 _indirectSymbolTableAtom(NULL
),
110 _rebasingInfoAtom(NULL
),
111 _bindingInfoAtom(NULL
),
112 _lazyBindingInfoAtom(NULL
),
113 _weakBindingInfoAtom(NULL
),
114 _exportInfoAtom(NULL
),
115 _splitSegInfoAtom(NULL
),
116 _functionStartsAtom(NULL
),
117 _dataInCodeAtom(NULL
),
118 _dependentDRInfoAtom(NULL
)
122 void OutputFile::dumpAtomsBySection(ld::Internal
& state
, bool printAtoms
)
124 fprintf(stderr
, "SORTED:\n");
125 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
126 fprintf(stderr
, "final section %p %s/%s %s start addr=0x%08llX, size=0x%08llX, alignment=%02d, fileOffset=0x%08llX\n",
127 (*it
), (*it
)->segmentName(), (*it
)->sectionName(), (*it
)->isSectionHidden() ? "(hidden)" : "",
128 (*it
)->address
, (*it
)->size
, (*it
)->alignment
, (*it
)->fileOffset
);
130 std::vector
<const ld::Atom
*>& atoms
= (*it
)->atoms
;
131 for (std::vector
<const ld::Atom
*>::iterator ait
= atoms
.begin(); ait
!= atoms
.end(); ++ait
) {
132 fprintf(stderr
, " %p (0x%04llX) %s\n", *ait
, (*ait
)->size(), (*ait
)->name());
136 fprintf(stderr
, "DYLIBS:\n");
137 for (std::vector
<ld::dylib::File
*>::iterator it
=state
.dylibs
.begin(); it
!= state
.dylibs
.end(); ++it
)
138 fprintf(stderr
, " %s\n", (*it
)->installPath());
141 void OutputFile::write(ld::Internal
& state
)
143 this->buildDylibOrdinalMapping(state
);
144 this->addLoadCommands(state
);
145 this->addLinkEdit(state
);
146 this->setSectionSizesAndAlignments(state
);
147 this->setLoadCommandsPadding(state
);
148 this->assignFileOffsets(state
);
149 this->assignAtomAddresses(state
);
150 this->synthesizeDebugNotes(state
);
151 this->buildSymbolTable(state
);
152 this->generateLinkEditInfo(state
);
153 this->makeSplitSegInfo(state
);
154 this->updateLINKEDITAddresses(state
);
155 //this->dumpAtomsBySection(state, false);
156 this->writeOutputFile(state
);
157 this->writeMapFile(state
);
160 bool OutputFile::findSegment(ld::Internal
& state
, uint64_t addr
, uint64_t* start
, uint64_t* end
, uint32_t* index
)
162 uint32_t segIndex
= 0;
163 ld::Internal::FinalSection
* segFirstSection
= NULL
;
164 ld::Internal::FinalSection
* lastSection
= NULL
;
165 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
166 ld::Internal::FinalSection
* sect
= *it
;
167 if ( (segFirstSection
== NULL
) || strcmp(segFirstSection
->segmentName(), sect
->segmentName()) != 0 ) {
168 if ( segFirstSection
!= NULL
) {
169 //fprintf(stderr, "findSegment(0x%llX) seg changed to %s\n", addr, sect->segmentName());
170 if ( (addr
>= segFirstSection
->address
) && (addr
< lastSection
->address
+lastSection
->size
) ) {
171 *start
= segFirstSection
->address
;
172 *end
= lastSection
->address
+lastSection
->size
;
178 segFirstSection
= sect
;
186 void OutputFile::assignAtomAddresses(ld::Internal
& state
)
188 const bool log
= false;
189 if ( log
) fprintf(stderr
, "assignAtomAddresses()\n");
190 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
191 ld::Internal::FinalSection
* sect
= *sit
;
192 if ( log
) fprintf(stderr
, " section=%s/%s\n", sect
->segmentName(), sect
->sectionName());
193 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
194 const ld::Atom
* atom
= *ait
;
195 if ( log
) fprintf(stderr
, " atom=%p, name=%s\n", atom
, atom
->name());
196 switch ( sect
-> type() ) {
197 case ld::Section::typeImportProxies
:
198 // want finalAddress() of all proxy atoms to be zero
199 (const_cast<ld::Atom
*>(atom
))->setSectionStartAddress(0);
201 case ld::Section::typeAbsoluteSymbols
:
202 // want finalAddress() of all absolute atoms to be value of abs symbol
203 (const_cast<ld::Atom
*>(atom
))->setSectionStartAddress(0);
205 case ld::Section::typeLinkEdit
:
206 // linkedit layout is assigned later
209 (const_cast<ld::Atom
*>(atom
))->setSectionStartAddress(sect
->address
);
216 void OutputFile::updateLINKEDITAddresses(ld::Internal
& state
)
218 if ( _options
.makeCompressedDyldInfo() ) {
219 // build dylb rebasing info
220 assert(_rebasingInfoAtom
!= NULL
);
221 _rebasingInfoAtom
->encode();
223 // build dyld binding info
224 assert(_bindingInfoAtom
!= NULL
);
225 _bindingInfoAtom
->encode();
227 // build dyld lazy binding info
228 assert(_lazyBindingInfoAtom
!= NULL
);
229 _lazyBindingInfoAtom
->encode();
231 // build dyld weak binding info
232 assert(_weakBindingInfoAtom
!= NULL
);
233 _weakBindingInfoAtom
->encode();
235 // build dyld export info
236 assert(_exportInfoAtom
!= NULL
);
237 _exportInfoAtom
->encode();
240 if ( _options
.sharedRegionEligible() ) {
241 // build split seg info
242 assert(_splitSegInfoAtom
!= NULL
);
243 _splitSegInfoAtom
->encode();
246 if ( _options
.addFunctionStarts() ) {
247 // build function starts info
248 assert(_functionStartsAtom
!= NULL
);
249 _functionStartsAtom
->encode();
252 if ( _options
.addDataInCodeInfo() ) {
253 // build data-in-code info
254 assert(_dataInCodeAtom
!= NULL
);
255 _dataInCodeAtom
->encode();
258 if ( _options
.needsDependentDRInfo() ) {
259 // build dependent dylib DR info
260 assert(_dependentDRInfoAtom
!= NULL
);
261 _dependentDRInfoAtom
->encode();
264 // build classic symbol table
265 assert(_symbolTableAtom
!= NULL
);
266 _symbolTableAtom
->encode();
267 assert(_indirectSymbolTableAtom
!= NULL
);
268 _indirectSymbolTableAtom
->encode();
270 // add relocations to .o files
271 if ( _options
.outputKind() == Options::kObjectFile
) {
272 assert(_sectionsRelocationsAtom
!= NULL
);
273 _sectionsRelocationsAtom
->encode();
276 if ( ! _options
.makeCompressedDyldInfo() ) {
277 // build external relocations
278 assert(_externalRelocsAtom
!= NULL
);
279 _externalRelocsAtom
->encode();
280 // build local relocations
281 assert(_localRelocsAtom
!= NULL
);
282 _localRelocsAtom
->encode();
285 // update address and file offsets now that linkedit content has been generated
286 uint64_t curLinkEditAddress
= 0;
287 uint64_t curLinkEditfileOffset
= 0;
288 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
289 ld::Internal::FinalSection
* sect
= *sit
;
290 if ( sect
->type() != ld::Section::typeLinkEdit
)
292 if ( curLinkEditAddress
== 0 ) {
293 curLinkEditAddress
= sect
->address
;
294 curLinkEditfileOffset
= sect
->fileOffset
;
296 uint16_t maxAlignment
= 0;
298 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
299 const ld::Atom
* atom
= *ait
;
300 //fprintf(stderr, "setting linkedit atom offset for %s\n", atom->name());
301 if ( atom
->alignment().powerOf2
> maxAlignment
)
302 maxAlignment
= atom
->alignment().powerOf2
;
303 // calculate section offset for this atom
304 uint64_t alignment
= 1 << atom
->alignment().powerOf2
;
305 uint64_t currentModulus
= (offset
% alignment
);
306 uint64_t requiredModulus
= atom
->alignment().modulus
;
307 if ( currentModulus
!= requiredModulus
) {
308 if ( requiredModulus
> currentModulus
)
309 offset
+= requiredModulus
-currentModulus
;
311 offset
+= requiredModulus
+alignment
-currentModulus
;
313 (const_cast<ld::Atom
*>(atom
))->setSectionOffset(offset
);
314 (const_cast<ld::Atom
*>(atom
))->setSectionStartAddress(curLinkEditAddress
);
315 offset
+= atom
->size();
318 // section alignment is that of a contained atom with the greatest alignment
319 sect
->alignment
= maxAlignment
;
320 sect
->address
= curLinkEditAddress
;
321 sect
->fileOffset
= curLinkEditfileOffset
;
322 curLinkEditAddress
+= sect
->size
;
323 curLinkEditfileOffset
+= sect
->size
;
326 _fileSize
= state
.sections
.back()->fileOffset
+ state
.sections
.back()->size
;
329 void OutputFile::setSectionSizesAndAlignments(ld::Internal
& state
)
331 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
332 ld::Internal::FinalSection
* sect
= *sit
;
333 if ( sect
->type() == ld::Section::typeAbsoluteSymbols
) {
334 // absolute symbols need their finalAddress() to their value
335 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
336 const ld::Atom
* atom
= *ait
;
337 (const_cast<ld::Atom
*>(atom
))->setSectionOffset(atom
->objectAddress());
341 uint16_t maxAlignment
= 0;
343 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
344 const ld::Atom
* atom
= *ait
;
345 bool pagePerAtom
= false;
346 uint32_t atomAlignmentPowerOf2
= atom
->alignment().powerOf2
;
347 uint32_t atomModulus
= atom
->alignment().modulus
;
348 if ( _options
.pageAlignDataAtoms() && ( strcmp(atom
->section().segmentName(), "__DATA") == 0) ) {
349 // most objc sections cannot be padded
350 bool contiguousObjCSection
= ( strncmp(atom
->section().sectionName(), "__objc_", 7) == 0 );
351 if ( strcmp(atom
->section().sectionName(), "__objc_const") == 0 )
352 contiguousObjCSection
= false;
353 if ( strcmp(atom
->section().sectionName(), "__objc_data") == 0 )
354 contiguousObjCSection
= false;
355 switch ( atom
->section().type() ) {
356 case ld::Section::typeUnclassified
:
357 case ld::Section::typeTentativeDefs
:
358 case ld::Section::typeZeroFill
:
359 if ( contiguousObjCSection
)
362 if ( atomAlignmentPowerOf2
< 12 ) {
363 atomAlignmentPowerOf2
= 12;
371 if ( atomAlignmentPowerOf2
> maxAlignment
)
372 maxAlignment
= atomAlignmentPowerOf2
;
373 // calculate section offset for this atom
374 uint64_t alignment
= 1 << atomAlignmentPowerOf2
;
375 uint64_t currentModulus
= (offset
% alignment
);
376 uint64_t requiredModulus
= atomModulus
;
377 if ( currentModulus
!= requiredModulus
) {
378 if ( requiredModulus
> currentModulus
)
379 offset
+= requiredModulus
-currentModulus
;
381 offset
+= requiredModulus
+alignment
-currentModulus
;
383 // LINKEDIT atoms are laid out later
384 if ( sect
->type() != ld::Section::typeLinkEdit
) {
385 (const_cast<ld::Atom
*>(atom
))->setSectionOffset(offset
);
386 offset
+= atom
->size();
388 offset
= (offset
+ 4095) & (-4096); // round up to end of page
391 if ( (atom
->scope() == ld::Atom::scopeGlobal
)
392 && (atom
->definition() == ld::Atom::definitionRegular
)
393 && (atom
->combine() == ld::Atom::combineByName
)
394 && ((atom
->symbolTableInclusion() == ld::Atom::symbolTableIn
)
395 || (atom
->symbolTableInclusion() == ld::Atom::symbolTableInAndNeverStrip
)) ) {
396 this->hasWeakExternalSymbols
= true;
397 if ( _options
.warnWeakExports() )
398 warning("weak external symbol: %s", atom
->name());
402 // section alignment is that of a contained atom with the greatest alignment
403 sect
->alignment
= maxAlignment
;
404 // unless -sectalign command line option overrides
405 if ( _options
.hasCustomSectionAlignment(sect
->segmentName(), sect
->sectionName()) )
406 sect
->alignment
= _options
.customSectionAlignment(sect
->segmentName(), sect
->sectionName());
407 // each atom in __eh_frame has zero alignment to assure they pack together,
408 // but compilers usually make the CFIs pointer sized, so we want whole section
409 // to start on pointer sized boundary.
410 if ( sect
->type() == ld::Section::typeCFI
)
412 if ( sect
->type() == ld::Section::typeTLVDefs
)
413 this->hasThreadLocalVariableDefinitions
= true;
418 void OutputFile::setLoadCommandsPadding(ld::Internal
& state
)
420 // In other sections, any extra space is put and end of segment.
421 // In __TEXT segment, any extra space is put after load commands to allow post-processing of load commands
422 // Do a reverse layout of __TEXT segment to determine padding size and adjust section size
423 uint64_t paddingSize
= 0;
424 switch ( _options
.outputKind() ) {
426 // dyld itself has special padding requirements. We want the beginning __text section to start at a stable address
427 assert(strcmp(state
.sections
[1]->sectionName(),"__text") == 0);
428 state
.sections
[1]->alignment
= 12; // page align __text
430 case Options::kObjectFile
:
431 // mach-o .o files need no padding between load commands and first section
432 // but leave enough room that the object file could be signed
435 case Options::kPreload
:
436 // mach-o MH_PRELOAD files need no padding between load commands and first section
439 // work backwards from end of segment and lay out sections so that extra room goes to padding atom
441 for (std::vector
<ld::Internal::FinalSection
*>::reverse_iterator it
= state
.sections
.rbegin(); it
!= state
.sections
.rend(); ++it
) {
442 ld::Internal::FinalSection
* sect
= *it
;
443 if ( strcmp(sect
->segmentName(), "__TEXT") != 0 )
445 if ( sect
== headerAndLoadCommandsSection
) {
446 addr
-= headerAndLoadCommandsSection
->size
;
447 paddingSize
= addr
% _options
.segmentAlignment();
451 addr
= addr
& (0 - (1 << sect
->alignment
));
454 // if command line requires more padding than this
455 uint32_t minPad
= _options
.minimumHeaderPad();
456 if ( _options
.maxMminimumHeaderPad() ) {
457 // -headerpad_max_install_names means there should be room for every path load command to grow to 1204 bytes
458 uint32_t altMin
= _dylibsToLoad
.size() * MAXPATHLEN
;
459 if ( _options
.outputKind() == Options::kDynamicLibrary
)
460 altMin
+= MAXPATHLEN
;
461 if ( altMin
> minPad
)
464 if ( paddingSize
< minPad
) {
465 int extraPages
= (minPad
- paddingSize
+ _options
.segmentAlignment() - 1)/_options
.segmentAlignment();
466 paddingSize
+= extraPages
* _options
.segmentAlignment();
469 if ( _options
.makeEncryptable() ) {
470 // load commands must be on a separate non-encrypted page
471 int loadCommandsPage
= (headerAndLoadCommandsSection
->size
+ minPad
)/_options
.segmentAlignment();
472 int textPage
= (headerAndLoadCommandsSection
->size
+ paddingSize
)/_options
.segmentAlignment();
473 if ( loadCommandsPage
== textPage
) {
474 paddingSize
+= _options
.segmentAlignment();
477 // remember start for later use by load command
478 _encryptedTEXTstartOffset
= textPage
*_options
.segmentAlignment();
482 // add padding to size of section
483 headerAndLoadCommandsSection
->size
+= paddingSize
;
487 uint64_t OutputFile::pageAlign(uint64_t addr
)
489 const uint64_t alignment
= _options
.segmentAlignment();
490 return ((addr
+alignment
-1) & (-alignment
));
493 uint64_t OutputFile::pageAlign(uint64_t addr
, uint64_t pageSize
)
495 return ((addr
+pageSize
-1) & (-pageSize
));
499 void OutputFile::assignFileOffsets(ld::Internal
& state
)
501 const bool log
= false;
502 const bool hiddenSectionsOccupyAddressSpace
= ((_options
.outputKind() != Options::kObjectFile
)
503 && (_options
.outputKind() != Options::kPreload
));
504 const bool segmentsArePageAligned
= (_options
.outputKind() != Options::kObjectFile
);
506 uint64_t address
= 0;
507 const char* lastSegName
= "";
508 uint64_t floatingAddressStart
= _options
.baseAddress();
510 // first pass, assign addresses to sections in segments with fixed start addresses
511 if ( log
) fprintf(stderr
, "Fixed address segments:\n");
512 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
513 ld::Internal::FinalSection
* sect
= *it
;
514 if ( ! _options
.hasCustomSegmentAddress(sect
->segmentName()) )
516 if ( segmentsArePageAligned
) {
517 if ( strcmp(lastSegName
, sect
->segmentName()) != 0 ) {
518 address
= _options
.customSegmentAddress(sect
->segmentName());
519 lastSegName
= sect
->segmentName();
522 // adjust section address based on alignment
523 uint64_t unalignedAddress
= address
;
524 uint64_t alignment
= (1 << sect
->alignment
);
525 address
= ( (unalignedAddress
+alignment
-1) & (-alignment
) );
527 // update section info
528 sect
->address
= address
;
529 sect
->alignmentPaddingBytes
= (address
- unalignedAddress
);
532 if ( ((address
+ sect
->size
) > _options
.maxAddress()) && (_options
.outputKind() != Options::kObjectFile
)
533 && (_options
.outputKind() != Options::kStaticExecutable
) )
534 throwf("section %s (address=0x%08llX, size=%llu) would make the output executable exceed available address range",
535 sect
->sectionName(), address
, sect
->size
);
537 if ( log
) fprintf(stderr
, " address=0x%08llX, hidden=%d, alignment=%02d, section=%s,%s\n",
538 sect
->address
, sect
->isSectionHidden(), sect
->alignment
, sect
->segmentName(), sect
->sectionName());
539 // update running totals
540 if ( !sect
->isSectionHidden() || hiddenSectionsOccupyAddressSpace
)
541 address
+= sect
->size
;
543 // if TEXT segment address is fixed, then flow other segments after it
544 if ( strcmp(sect
->segmentName(), "__TEXT") == 0 ) {
545 floatingAddressStart
= address
;
549 // second pass, assign section address to sections in segments that are contiguous with previous segment
550 address
= floatingAddressStart
;
552 ld::Internal::FinalSection
* overlappingFixedSection
= NULL
;
553 ld::Internal::FinalSection
* overlappingFlowSection
= NULL
;
554 if ( log
) fprintf(stderr
, "Regular layout segments:\n");
555 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
556 ld::Internal::FinalSection
* sect
= *it
;
557 if ( _options
.hasCustomSegmentAddress(sect
->segmentName()) )
559 if ( (_options
.outputKind() == Options::kPreload
) && (sect
->type() == ld::Section::typeMachHeader
) ) {
560 sect
->alignmentPaddingBytes
= 0;
563 if ( segmentsArePageAligned
) {
564 if ( strcmp(lastSegName
, sect
->segmentName()) != 0 ) {
565 // round up size of last segment if needed
566 if ( *lastSegName
!= '\0' ) {
567 address
= pageAlign(address
, _options
.segPageSize(lastSegName
));
569 // set segment address based on end of last segment
570 address
= pageAlign(address
);
571 lastSegName
= sect
->segmentName();
574 // adjust section address based on alignment
575 uint64_t unalignedAddress
= address
;
576 uint64_t alignment
= (1 << sect
->alignment
);
577 address
= ( (unalignedAddress
+alignment
-1) & (-alignment
) );
579 // update section info
580 sect
->address
= address
;
581 sect
->alignmentPaddingBytes
= (address
- unalignedAddress
);
584 if ( ((address
+ sect
->size
) > _options
.maxAddress()) && (_options
.outputKind() != Options::kObjectFile
)
585 && (_options
.outputKind() != Options::kStaticExecutable
) )
586 throwf("section %s (address=0x%08llX, size=%llu) would make the output executable exceed available address range",
587 sect
->sectionName(), address
, sect
->size
);
589 // sanity check it does not overlap a fixed address segment
590 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
591 ld::Internal::FinalSection
* otherSect
= *sit
;
592 if ( ! _options
.hasCustomSegmentAddress(otherSect
->segmentName()) )
594 if ( sect
->address
> otherSect
->address
) {
595 if ( (otherSect
->address
+otherSect
->size
) > sect
->address
) {
596 overlappingFixedSection
= otherSect
;
597 overlappingFlowSection
= sect
;
601 if ( (sect
->address
+sect
->size
) > otherSect
->address
) {
602 overlappingFixedSection
= otherSect
;
603 overlappingFlowSection
= sect
;
608 if ( log
) fprintf(stderr
, " address=0x%08llX, size=0x%08llX, hidden=%d, alignment=%02d, padBytes=%d, section=%s,%s\n",
609 sect
->address
, sect
->size
, sect
->isSectionHidden(), sect
->alignment
, sect
->alignmentPaddingBytes
,
610 sect
->segmentName(), sect
->sectionName());
611 // update running totals
612 if ( !sect
->isSectionHidden() || hiddenSectionsOccupyAddressSpace
)
613 address
+= sect
->size
;
615 if ( overlappingFixedSection
!= NULL
) {
616 fprintf(stderr
, "Section layout:\n");
617 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
618 ld::Internal::FinalSection
* sect
= *it
;
619 if ( sect
->isSectionHidden() )
621 fprintf(stderr
, " address:0x%08llX, alignment:2^%d, size:0x%08llX, padBytes:%d, section:%s/%s\n",
622 sect
->address
, sect
->alignment
, sect
->size
, sect
->alignmentPaddingBytes
,
623 sect
->segmentName(), sect
->sectionName());
626 throwf("Section (%s/%s) overlaps fixed address section (%s/%s)",
627 overlappingFlowSection
->segmentName(), overlappingFlowSection
->sectionName(),
628 overlappingFixedSection
->segmentName(), overlappingFixedSection
->sectionName());
632 // third pass, assign section file offsets
633 uint64_t fileOffset
= 0;
635 if ( log
) fprintf(stderr
, "All segments with file offsets:\n");
636 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
637 ld::Internal::FinalSection
* sect
= *it
;
638 if ( hasZeroForFileOffset(sect
) ) {
639 // fileoff of zerofill sections is moot, but historically it is set to zero
640 sect
->fileOffset
= 0;
642 // <rdar://problem/10445047> align file offset with address layout
643 fileOffset
+= sect
->alignmentPaddingBytes
;
646 // page align file offset at start of each segment
647 if ( segmentsArePageAligned
&& (*lastSegName
!= '\0') && (strcmp(lastSegName
, sect
->segmentName()) != 0) ) {
648 fileOffset
= pageAlign(fileOffset
, _options
.segPageSize(lastSegName
));
650 lastSegName
= sect
->segmentName();
652 // align file offset with address layout
653 fileOffset
+= sect
->alignmentPaddingBytes
;
655 // update section info
656 sect
->fileOffset
= fileOffset
;
658 // update running total
659 fileOffset
+= sect
->size
;
662 if ( log
) fprintf(stderr
, " fileoffset=0x%08llX, address=0x%08llX, hidden=%d, size=%lld, alignment=%02d, section=%s,%s\n",
663 sect
->fileOffset
, sect
->address
, sect
->isSectionHidden(), sect
->size
, sect
->alignment
,
664 sect
->segmentName(), sect
->sectionName());
668 // for encrypted iPhoneOS apps
669 if ( _options
.makeEncryptable() ) {
670 // remember end of __TEXT for later use by load command
671 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
672 ld::Internal::FinalSection
* sect
= *it
;
673 if ( strcmp(sect
->segmentName(), "__TEXT") == 0 ) {
674 _encryptedTEXTendOffset
= pageAlign(sect
->fileOffset
+ sect
->size
);
679 // remember total file size
680 _fileSize
= fileOffset
;
684 static const char* makeName(const ld::Atom
& atom
)
686 static char buffer
[4096];
687 switch ( atom
.symbolTableInclusion() ) {
688 case ld::Atom::symbolTableNotIn
:
689 case ld::Atom::symbolTableNotInFinalLinkedImages
:
690 sprintf(buffer
, "%s@0x%08llX", atom
.name(), atom
.objectAddress());
692 case ld::Atom::symbolTableIn
:
693 case ld::Atom::symbolTableInAndNeverStrip
:
694 case ld::Atom::symbolTableInAsAbsolute
:
695 case ld::Atom::symbolTableInWithRandomAutoStripLabel
:
696 strlcpy(buffer
, atom
.name(), 4096);
702 static const char* referenceTargetAtomName(ld::Internal
& state
, const ld::Fixup
* ref
)
704 switch ( ref
->binding
) {
705 case ld::Fixup::bindingNone
:
707 case ld::Fixup::bindingByNameUnbound
:
708 return (char*)(ref
->u
.target
);
709 case ld::Fixup::bindingByContentBound
:
710 case ld::Fixup::bindingDirectlyBound
:
711 return makeName(*((ld::Atom
*)(ref
->u
.target
)));
712 case ld::Fixup::bindingsIndirectlyBound
:
713 return makeName(*state
.indirectBindingTable
[ref
->u
.bindingIndex
]);
715 return "BAD BINDING";
718 bool OutputFile::targetIsThumb(ld::Internal
& state
, const ld::Fixup
* fixup
)
720 switch ( fixup
->binding
) {
721 case ld::Fixup::bindingByContentBound
:
722 case ld::Fixup::bindingDirectlyBound
:
723 return fixup
->u
.target
->isThumb();
724 case ld::Fixup::bindingsIndirectlyBound
:
725 return state
.indirectBindingTable
[fixup
->u
.bindingIndex
]->isThumb();
729 throw "unexpected binding";
732 uint64_t OutputFile::addressOf(const ld::Internal
& state
, const ld::Fixup
* fixup
, const ld::Atom
** target
)
734 if ( !_options
.makeCompressedDyldInfo() ) {
735 // For external relocations the classic mach-o format
736 // has addend only stored in the content. That means
737 // that the address of the target is not used.
738 if ( fixup
->contentAddendOnly
)
741 switch ( fixup
->binding
) {
742 case ld::Fixup::bindingNone
:
743 throw "unexpected bindingNone";
744 case ld::Fixup::bindingByNameUnbound
:
745 throw "unexpected bindingByNameUnbound";
746 case ld::Fixup::bindingByContentBound
:
747 case ld::Fixup::bindingDirectlyBound
:
748 *target
= fixup
->u
.target
;
749 return (*target
)->finalAddress();
750 case ld::Fixup::bindingsIndirectlyBound
:
751 *target
= state
.indirectBindingTable
[fixup
->u
.bindingIndex
];
753 if ( ! (*target
)->finalAddressMode() ) {
754 throwf("reference to symbol (which has not been assigned an address) %s", (*target
)->name());
757 return (*target
)->finalAddress();
759 throw "unexpected binding";
762 uint64_t OutputFile::sectionOffsetOf(const ld::Internal
& state
, const ld::Fixup
* fixup
)
764 const ld::Atom
* target
= NULL
;
765 switch ( fixup
->binding
) {
766 case ld::Fixup::bindingNone
:
767 throw "unexpected bindingNone";
768 case ld::Fixup::bindingByNameUnbound
:
769 throw "unexpected bindingByNameUnbound";
770 case ld::Fixup::bindingByContentBound
:
771 case ld::Fixup::bindingDirectlyBound
:
772 target
= fixup
->u
.target
;
774 case ld::Fixup::bindingsIndirectlyBound
:
775 target
= state
.indirectBindingTable
[fixup
->u
.bindingIndex
];
778 assert(target
!= NULL
);
780 uint64_t targetAddress
= target
->finalAddress();
781 for (std::vector
<ld::Internal::FinalSection
*>::const_iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
782 const ld::Internal::FinalSection
* sect
= *it
;
783 if ( (sect
->address
<= targetAddress
) && (targetAddress
< (sect
->address
+sect
->size
)) )
784 return targetAddress
- sect
->address
;
786 throw "section not found for section offset";
791 uint64_t OutputFile::tlvTemplateOffsetOf(const ld::Internal
& state
, const ld::Fixup
* fixup
)
793 const ld::Atom
* target
= NULL
;
794 switch ( fixup
->binding
) {
795 case ld::Fixup::bindingNone
:
796 throw "unexpected bindingNone";
797 case ld::Fixup::bindingByNameUnbound
:
798 throw "unexpected bindingByNameUnbound";
799 case ld::Fixup::bindingByContentBound
:
800 case ld::Fixup::bindingDirectlyBound
:
801 target
= fixup
->u
.target
;
803 case ld::Fixup::bindingsIndirectlyBound
:
804 target
= state
.indirectBindingTable
[fixup
->u
.bindingIndex
];
807 assert(target
!= NULL
);
809 for (std::vector
<ld::Internal::FinalSection
*>::const_iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
810 const ld::Internal::FinalSection
* sect
= *it
;
811 switch ( sect
->type() ) {
812 case ld::Section::typeTLVInitialValues
:
813 case ld::Section::typeTLVZeroFill
:
814 return target
->finalAddress() - sect
->address
;
819 throw "section not found for tlvTemplateOffsetOf";
822 void OutputFile::printSectionLayout(ld::Internal
& state
)
824 // show layout of final image
825 fprintf(stderr
, "final section layout:\n");
826 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
827 if ( (*it
)->isSectionHidden() )
829 fprintf(stderr
, " %s/%s addr=0x%08llX, size=0x%08llX, fileOffset=0x%08llX, type=%d\n",
830 (*it
)->segmentName(), (*it
)->sectionName(),
831 (*it
)->address
, (*it
)->size
, (*it
)->fileOffset
, (*it
)->type());
836 void OutputFile::rangeCheck8(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
838 if ( (displacement
> 127) || (displacement
< -128) ) {
839 // show layout of final image
840 printSectionLayout(state
);
842 const ld::Atom
* target
;
843 throwf("8-bit reference out of range (%lld max is +/-127B): from %s (0x%08llX) to %s (0x%08llX)",
844 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
845 addressOf(state
, fixup
, &target
));
849 void OutputFile::rangeCheck16(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
851 const int64_t thirtyTwoKLimit
= 0x00007FFF;
852 if ( (displacement
> thirtyTwoKLimit
) || (displacement
< (-thirtyTwoKLimit
)) ) {
853 // show layout of final image
854 printSectionLayout(state
);
856 const ld::Atom
* target
;
857 throwf("16-bit reference out of range (%lld max is +/-32KB): from %s (0x%08llX) to %s (0x%08llX)",
858 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
859 addressOf(state
, fixup
, &target
));
863 void OutputFile::rangeCheckBranch32(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
865 const int64_t twoGigLimit
= 0x7FFFFFFF;
866 if ( (displacement
> twoGigLimit
) || (displacement
< (-twoGigLimit
)) ) {
867 // show layout of final image
868 printSectionLayout(state
);
870 const ld::Atom
* target
;
871 throwf("32-bit branch out of range (%lld max is +/-2GB): from %s (0x%08llX) to %s (0x%08llX)",
872 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
873 addressOf(state
, fixup
, &target
));
878 void OutputFile::rangeCheckAbsolute32(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
880 const int64_t fourGigLimit
= 0xFFFFFFFF;
881 if ( displacement
> fourGigLimit
) {
882 // <rdar://problem/9610466> cannot enforce 32-bit range checks on 32-bit archs because assembler loses sign information
883 // .long _foo - 0xC0000000
884 // is encoded in mach-o the same as:
885 // .long _foo + 0x40000000
886 // so if _foo lays out to 0xC0000100, the first is ok, but the second is not.
887 if ( (_options
.architecture() == CPU_TYPE_ARM
) || (_options
.architecture() == CPU_TYPE_I386
) ) {
888 // Unlikely userland code does funky stuff like this, so warn for them, but not warn for -preload or -static
889 if ( (_options
.outputKind() != Options::kPreload
) && (_options
.outputKind() != Options::kStaticExecutable
) ) {
890 warning("32-bit absolute address out of range (0x%08llX max is 4GB): from %s + 0x%08X (0x%08llX) to 0x%08llX",
891 displacement
, atom
->name(), fixup
->offsetInAtom
, atom
->finalAddress(), displacement
);
895 // show layout of final image
896 printSectionLayout(state
);
898 const ld::Atom
* target
;
899 if ( fixup
->binding
== ld::Fixup::bindingNone
)
900 throwf("32-bit absolute address out of range (0x%08llX max is 4GB): from %s + 0x%08X (0x%08llX) to 0x%08llX",
901 displacement
, atom
->name(), fixup
->offsetInAtom
, atom
->finalAddress(), displacement
);
903 throwf("32-bit absolute address out of range (0x%08llX max is 4GB): from %s + 0x%08X (0x%08llX) to %s (0x%08llX)",
904 displacement
, atom
->name(), fixup
->offsetInAtom
, atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
905 addressOf(state
, fixup
, &target
));
910 void OutputFile::rangeCheckRIP32(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
912 const int64_t twoGigLimit
= 0x7FFFFFFF;
913 if ( (displacement
> twoGigLimit
) || (displacement
< (-twoGigLimit
)) ) {
914 // show layout of final image
915 printSectionLayout(state
);
917 const ld::Atom
* target
;
918 throwf("32-bit RIP relative reference out of range (%lld max is +/-4GB): from %s (0x%08llX) to %s (0x%08llX)",
919 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
920 addressOf(state
, fixup
, &target
));
924 void OutputFile::rangeCheckARM12(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
926 if ( (displacement
> 4092LL) || (displacement
< (-4092LL)) ) {
927 // show layout of final image
928 printSectionLayout(state
);
930 const ld::Atom
* target
;
931 throwf("ARM ldr 12-bit displacement out of range (%lld max is +/-4096B): from %s (0x%08llX) to %s (0x%08llX)",
932 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
933 addressOf(state
, fixup
, &target
));
938 void OutputFile::rangeCheckARMBranch24(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
940 if ( (displacement
> 33554428LL) || (displacement
< (-33554432LL)) ) {
941 // show layout of final image
942 printSectionLayout(state
);
944 const ld::Atom
* target
;
945 throwf("b/bl/blx ARM branch out of range (%lld max is +/-32MB): from %s (0x%08llX) to %s (0x%08llX)",
946 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
947 addressOf(state
, fixup
, &target
));
951 void OutputFile::rangeCheckThumbBranch22(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
953 // thumb2 supports a larger displacement
954 if ( _options
.preferSubArchitecture() && _options
.archSupportsThumb2() ) {
955 if ( (displacement
> 16777214LL) || (displacement
< (-16777216LL)) ) {
956 // show layout of final image
957 printSectionLayout(state
);
959 const ld::Atom
* target
;
960 throwf("b/bl/blx thumb2 branch out of range (%lld max is +/-16MB): from %s (0x%08llX) to %s (0x%08llX)",
961 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
962 addressOf(state
, fixup
, &target
));
966 if ( (displacement
> 4194302LL) || (displacement
< (-4194304LL)) ) {
967 // show layout of final image
968 printSectionLayout(state
);
970 const ld::Atom
* target
;
971 throwf("b/bl/blx thumb1 branch out of range (%lld max is +/-4MB): from %s (0x%08llX) to %s (0x%08llX)",
972 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
973 addressOf(state
, fixup
, &target
));
979 void OutputFile::rangeCheckARM64Branch26(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
981 const int64_t bl_128MegLimit
= 0x07FFFFFF;
982 if ( (displacement
> bl_128MegLimit
) || (displacement
< (-bl_128MegLimit
)) ) {
983 // show layout of final image
984 printSectionLayout(state
);
986 const ld::Atom
* target
;
987 throwf("b(l) ARM64 branch out of range (%lld max is +/-128MB): from %s (0x%08llX) to %s (0x%08llX)",
988 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
989 addressOf(state
, fixup
, &target
));
993 void OutputFile::rangeCheckARM64Page21(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
995 const int64_t adrp_4GigLimit
= 0x100000000ULL
;
996 if ( (displacement
> adrp_4GigLimit
) || (displacement
< (-adrp_4GigLimit
)) ) {
997 // show layout of final image
998 printSectionLayout(state
);
1000 const ld::Atom
* target
;
1001 throwf("ARM64 ADRP out of range (%lld max is +/-4GB): from %s (0x%08llX) to %s (0x%08llX)",
1002 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
1003 addressOf(state
, fixup
, &target
));
1008 uint16_t OutputFile::get16LE(uint8_t* loc
) { return LittleEndian::get16(*(uint16_t*)loc
); }
1009 void OutputFile::set16LE(uint8_t* loc
, uint16_t value
) { LittleEndian::set16(*(uint16_t*)loc
, value
); }
1011 uint32_t OutputFile::get32LE(uint8_t* loc
) { return LittleEndian::get32(*(uint32_t*)loc
); }
1012 void OutputFile::set32LE(uint8_t* loc
, uint32_t value
) { LittleEndian::set32(*(uint32_t*)loc
, value
); }
1014 uint64_t OutputFile::get64LE(uint8_t* loc
) { return LittleEndian::get64(*(uint64_t*)loc
); }
1015 void OutputFile::set64LE(uint8_t* loc
, uint64_t value
) { LittleEndian::set64(*(uint64_t*)loc
, value
); }
1017 uint16_t OutputFile::get16BE(uint8_t* loc
) { return BigEndian::get16(*(uint16_t*)loc
); }
1018 void OutputFile::set16BE(uint8_t* loc
, uint16_t value
) { BigEndian::set16(*(uint16_t*)loc
, value
); }
1020 uint32_t OutputFile::get32BE(uint8_t* loc
) { return BigEndian::get32(*(uint32_t*)loc
); }
1021 void OutputFile::set32BE(uint8_t* loc
, uint32_t value
) { BigEndian::set32(*(uint32_t*)loc
, value
); }
1023 uint64_t OutputFile::get64BE(uint8_t* loc
) { return BigEndian::get64(*(uint64_t*)loc
); }
1024 void OutputFile::set64BE(uint8_t* loc
, uint64_t value
) { BigEndian::set64(*(uint64_t*)loc
, value
); }
1026 void OutputFile::applyFixUps(ld::Internal
& state
, uint64_t mhAddress
, const ld::Atom
* atom
, uint8_t* buffer
)
1028 //fprintf(stderr, "applyFixUps() on %s\n", atom->name());
1029 int64_t accumulator
= 0;
1030 const ld::Atom
* toTarget
= NULL
;
1031 const ld::Atom
* fromTarget
;
1033 uint32_t instruction
;
1034 uint32_t newInstruction
;
1038 bool thumbTarget
= false;
1039 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(), end
=atom
->fixupsEnd(); fit
!= end
; ++fit
) {
1040 uint8_t* fixUpLocation
= &buffer
[fit
->offsetInAtom
];
1041 switch ( (ld::Fixup::Kind
)(fit
->kind
) ) {
1042 case ld::Fixup::kindNone
:
1043 case ld::Fixup::kindNoneFollowOn
:
1044 case ld::Fixup::kindNoneGroupSubordinate
:
1045 case ld::Fixup::kindNoneGroupSubordinateFDE
:
1046 case ld::Fixup::kindNoneGroupSubordinateLSDA
:
1047 case ld::Fixup::kindNoneGroupSubordinatePersonality
:
1049 case ld::Fixup::kindSetTargetAddress
:
1050 accumulator
= addressOf(state
, fit
, &toTarget
);
1051 thumbTarget
= targetIsThumb(state
, fit
);
1054 if ( fit
->contentAddendOnly
|| fit
->contentDetlaToAddendOnly
)
1057 case ld::Fixup::kindSubtractTargetAddress
:
1058 delta
= addressOf(state
, fit
, &fromTarget
);
1059 if ( ! fit
->contentAddendOnly
)
1060 accumulator
-= delta
;
1062 case ld::Fixup::kindAddAddend
:
1063 if ( ! fit
->contentIgnoresAddend
) {
1064 // <rdar://problem/8342028> ARM main executables main contain .long constants pointing
1065 // into themselves such as jump tables. These .long should not have thumb bit set
1066 // even though the target is a thumb instruction. We can tell it is an interior pointer
1067 // because we are processing an addend.
1068 if ( thumbTarget
&& (toTarget
== atom
) && ((int32_t)fit
->u
.addend
> 0) ) {
1069 accumulator
&= (-2);
1070 //warning("removing thumb bit from intra-atom pointer in %s %s+0x%0X",
1071 // atom->section().sectionName(), atom->name(), fit->offsetInAtom);
1073 accumulator
+= fit
->u
.addend
;
1076 case ld::Fixup::kindSubtractAddend
:
1077 accumulator
-= fit
->u
.addend
;
1079 case ld::Fixup::kindSetTargetImageOffset
:
1080 accumulator
= addressOf(state
, fit
, &toTarget
) - mhAddress
;
1082 case ld::Fixup::kindSetTargetSectionOffset
:
1083 accumulator
= sectionOffsetOf(state
, fit
);
1085 case ld::Fixup::kindSetTargetTLVTemplateOffset
:
1086 accumulator
= tlvTemplateOffsetOf(state
, fit
);
1088 case ld::Fixup::kindStore8
:
1089 *fixUpLocation
+= accumulator
;
1091 case ld::Fixup::kindStoreLittleEndian16
:
1092 set16LE(fixUpLocation
, accumulator
);
1094 case ld::Fixup::kindStoreLittleEndianLow24of32
:
1095 set32LE(fixUpLocation
, (get32LE(fixUpLocation
) & 0xFF000000) | (accumulator
& 0x00FFFFFF) );
1097 case ld::Fixup::kindStoreLittleEndian32
:
1098 rangeCheckAbsolute32(accumulator
, state
, atom
, fit
);
1099 set32LE(fixUpLocation
, accumulator
);
1101 case ld::Fixup::kindStoreLittleEndian64
:
1102 set64LE(fixUpLocation
, accumulator
);
1104 case ld::Fixup::kindStoreBigEndian16
:
1105 set16BE(fixUpLocation
, accumulator
);
1107 case ld::Fixup::kindStoreBigEndianLow24of32
:
1108 set32BE(fixUpLocation
, (get32BE(fixUpLocation
) & 0xFF000000) | (accumulator
& 0x00FFFFFF) );
1110 case ld::Fixup::kindStoreBigEndian32
:
1111 rangeCheckAbsolute32(accumulator
, state
, atom
, fit
);
1112 set32BE(fixUpLocation
, accumulator
);
1114 case ld::Fixup::kindStoreBigEndian64
:
1115 set64BE(fixUpLocation
, accumulator
);
1117 case ld::Fixup::kindStoreX86PCRel8
:
1118 case ld::Fixup::kindStoreX86BranchPCRel8
:
1119 if ( fit
->contentAddendOnly
)
1120 delta
= accumulator
;
1122 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 1);
1123 rangeCheck8(delta
, state
, atom
, fit
);
1124 *fixUpLocation
= delta
;
1126 case ld::Fixup::kindStoreX86PCRel16
:
1127 if ( fit
->contentAddendOnly
)
1128 delta
= accumulator
;
1130 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 2);
1131 rangeCheck16(delta
, state
, atom
, fit
);
1132 set16LE(fixUpLocation
, delta
);
1134 case ld::Fixup::kindStoreX86BranchPCRel32
:
1135 if ( fit
->contentAddendOnly
)
1136 delta
= accumulator
;
1138 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1139 rangeCheckBranch32(delta
, state
, atom
, fit
);
1140 set32LE(fixUpLocation
, delta
);
1142 case ld::Fixup::kindStoreX86PCRel32GOTLoad
:
1143 case ld::Fixup::kindStoreX86PCRel32GOT
:
1144 case ld::Fixup::kindStoreX86PCRel32
:
1145 case ld::Fixup::kindStoreX86PCRel32TLVLoad
:
1146 if ( fit
->contentAddendOnly
)
1147 delta
= accumulator
;
1149 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1150 rangeCheckRIP32(delta
, state
, atom
, fit
);
1151 set32LE(fixUpLocation
, delta
);
1153 case ld::Fixup::kindStoreX86PCRel32_1
:
1154 if ( fit
->contentAddendOnly
)
1155 delta
= accumulator
- 1;
1157 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 5);
1158 rangeCheckRIP32(delta
, state
, atom
, fit
);
1159 set32LE(fixUpLocation
, delta
);
1161 case ld::Fixup::kindStoreX86PCRel32_2
:
1162 if ( fit
->contentAddendOnly
)
1163 delta
= accumulator
- 2;
1165 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 6);
1166 rangeCheckRIP32(delta
, state
, atom
, fit
);
1167 set32LE(fixUpLocation
, delta
);
1169 case ld::Fixup::kindStoreX86PCRel32_4
:
1170 if ( fit
->contentAddendOnly
)
1171 delta
= accumulator
- 4;
1173 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 8);
1174 rangeCheckRIP32(delta
, state
, atom
, fit
);
1175 set32LE(fixUpLocation
, delta
);
1177 case ld::Fixup::kindStoreX86Abs32TLVLoad
:
1178 set32LE(fixUpLocation
, accumulator
);
1180 case ld::Fixup::kindStoreX86Abs32TLVLoadNowLEA
:
1181 assert(_options
.outputKind() != Options::kObjectFile
);
1182 // TLV entry was optimized away, change movl instruction to a leal
1183 if ( fixUpLocation
[-1] != 0xA1 )
1184 throw "TLV load reloc does not point to a movl instruction";
1185 fixUpLocation
[-1] = 0xB8;
1186 set32LE(fixUpLocation
, accumulator
);
1188 case ld::Fixup::kindStoreX86PCRel32GOTLoadNowLEA
:
1189 assert(_options
.outputKind() != Options::kObjectFile
);
1190 // GOT entry was optimized away, change movq instruction to a leaq
1191 if ( fixUpLocation
[-2] != 0x8B )
1192 throw "GOT load reloc does not point to a movq instruction";
1193 fixUpLocation
[-2] = 0x8D;
1194 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1195 rangeCheckRIP32(delta
, state
, atom
, fit
);
1196 set32LE(fixUpLocation
, delta
);
1198 case ld::Fixup::kindStoreX86PCRel32TLVLoadNowLEA
:
1199 assert(_options
.outputKind() != Options::kObjectFile
);
1200 // TLV entry was optimized away, change movq instruction to a leaq
1201 if ( fixUpLocation
[-2] != 0x8B )
1202 throw "TLV load reloc does not point to a movq instruction";
1203 fixUpLocation
[-2] = 0x8D;
1204 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1205 rangeCheckRIP32(delta
, state
, atom
, fit
);
1206 set32LE(fixUpLocation
, delta
);
1208 case ld::Fixup::kindStoreTargetAddressARMLoad12
:
1209 accumulator
= addressOf(state
, fit
, &toTarget
);
1210 // fall into kindStoreARMLoad12 case
1211 case ld::Fixup::kindStoreARMLoad12
:
1212 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 8);
1213 rangeCheckARM12(delta
, state
, atom
, fit
);
1214 instruction
= get32LE(fixUpLocation
);
1216 newInstruction
= instruction
& 0xFFFFF000;
1217 newInstruction
|= ((uint32_t)delta
& 0xFFF);
1220 newInstruction
= instruction
& 0xFF7FF000;
1221 newInstruction
|= ((uint32_t)(-delta
) & 0xFFF);
1223 set32LE(fixUpLocation
, newInstruction
);
1225 case ld::Fixup::kindDtraceExtra
:
1227 case ld::Fixup::kindStoreX86DtraceCallSiteNop
:
1228 if ( _options
.outputKind() != Options::kObjectFile
) {
1229 // change call site to a NOP
1230 fixUpLocation
[-1] = 0x90; // 1-byte nop
1231 fixUpLocation
[0] = 0x0F; // 4-byte nop
1232 fixUpLocation
[1] = 0x1F;
1233 fixUpLocation
[2] = 0x40;
1234 fixUpLocation
[3] = 0x00;
1237 case ld::Fixup::kindStoreX86DtraceIsEnableSiteClear
:
1238 if ( _options
.outputKind() != Options::kObjectFile
) {
1239 // change call site to a clear eax
1240 fixUpLocation
[-1] = 0x33; // xorl eax,eax
1241 fixUpLocation
[0] = 0xC0;
1242 fixUpLocation
[1] = 0x90; // 1-byte nop
1243 fixUpLocation
[2] = 0x90; // 1-byte nop
1244 fixUpLocation
[3] = 0x90; // 1-byte nop
1247 case ld::Fixup::kindStoreARMDtraceCallSiteNop
:
1248 if ( _options
.outputKind() != Options::kObjectFile
) {
1249 // change call site to a NOP
1250 set32LE(fixUpLocation
, 0xE1A00000);
1253 case ld::Fixup::kindStoreARMDtraceIsEnableSiteClear
:
1254 if ( _options
.outputKind() != Options::kObjectFile
) {
1255 // change call site to 'eor r0, r0, r0'
1256 set32LE(fixUpLocation
, 0xE0200000);
1259 case ld::Fixup::kindStoreThumbDtraceCallSiteNop
:
1260 if ( _options
.outputKind() != Options::kObjectFile
) {
1261 // change 32-bit blx call site to two thumb NOPs
1262 set32LE(fixUpLocation
, 0x46C046C0);
1265 case ld::Fixup::kindStoreThumbDtraceIsEnableSiteClear
:
1266 if ( _options
.outputKind() != Options::kObjectFile
) {
1267 // change 32-bit blx call site to 'nop', 'eor r0, r0'
1268 set32LE(fixUpLocation
, 0x46C04040);
1271 case ld::Fixup::kindStoreARM64DtraceCallSiteNop
:
1272 if ( _options
.outputKind() != Options::kObjectFile
) {
1273 // change call site to a NOP
1274 set32LE(fixUpLocation
, 0xD503201F);
1277 case ld::Fixup::kindStoreARM64DtraceIsEnableSiteClear
:
1278 if ( _options
.outputKind() != Options::kObjectFile
) {
1279 // change call site to 'MOVZ X0,0'
1280 set32LE(fixUpLocation
, 0xD2800000);
1283 case ld::Fixup::kindLazyTarget
:
1285 case ld::Fixup::kindSetLazyOffset
:
1286 assert(fit
->binding
== ld::Fixup::bindingDirectlyBound
);
1287 accumulator
= this->lazyBindingInfoOffsetForLazyPointerAddress(fit
->u
.target
->finalAddress());
1289 case ld::Fixup::kindDataInCodeStartData
:
1290 case ld::Fixup::kindDataInCodeStartJT8
:
1291 case ld::Fixup::kindDataInCodeStartJT16
:
1292 case ld::Fixup::kindDataInCodeStartJT32
:
1293 case ld::Fixup::kindDataInCodeStartJTA32
:
1294 case ld::Fixup::kindDataInCodeEnd
:
1296 case ld::Fixup::kindStoreTargetAddressLittleEndian32
:
1297 accumulator
= addressOf(state
, fit
, &toTarget
);
1298 thumbTarget
= targetIsThumb(state
, fit
);
1301 if ( fit
->contentAddendOnly
)
1303 rangeCheckAbsolute32(accumulator
, state
, atom
, fit
);
1304 set32LE(fixUpLocation
, accumulator
);
1306 case ld::Fixup::kindStoreTargetAddressLittleEndian64
:
1307 accumulator
= addressOf(state
, fit
, &toTarget
);
1308 if ( fit
->contentAddendOnly
)
1310 set64LE(fixUpLocation
, accumulator
);
1312 case ld::Fixup::kindStoreTargetAddressBigEndian32
:
1313 accumulator
= addressOf(state
, fit
, &toTarget
);
1314 if ( fit
->contentAddendOnly
)
1316 set32BE(fixUpLocation
, accumulator
);
1318 case ld::Fixup::kindStoreTargetAddressBigEndian64
:
1319 accumulator
= addressOf(state
, fit
, &toTarget
);
1320 if ( fit
->contentAddendOnly
)
1322 set64BE(fixUpLocation
, accumulator
);
1324 case ld::Fixup::kindSetTargetTLVTemplateOffsetLittleEndian32
:
1325 accumulator
= tlvTemplateOffsetOf(state
, fit
);
1326 set32LE(fixUpLocation
, accumulator
);
1328 case ld::Fixup::kindSetTargetTLVTemplateOffsetLittleEndian64
:
1329 accumulator
= tlvTemplateOffsetOf(state
, fit
);
1330 set64LE(fixUpLocation
, accumulator
);
1332 case ld::Fixup::kindStoreTargetAddressX86PCRel32
:
1333 case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32
:
1334 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad
:
1335 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoad
:
1336 accumulator
= addressOf(state
, fit
, &toTarget
);
1337 if ( fit
->contentDetlaToAddendOnly
)
1339 if ( fit
->contentAddendOnly
)
1342 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1343 rangeCheckRIP32(delta
, state
, atom
, fit
);
1344 set32LE(fixUpLocation
, delta
);
1346 case ld::Fixup::kindStoreTargetAddressX86Abs32TLVLoad
:
1347 set32LE(fixUpLocation
, accumulator
);
1349 case ld::Fixup::kindStoreTargetAddressX86Abs32TLVLoadNowLEA
:
1350 // TLV entry was optimized away, change movl instruction to a leal
1351 if ( fixUpLocation
[-1] != 0xA1 )
1352 throw "TLV load reloc does not point to a movl <abs-address>,<reg> instruction";
1353 fixUpLocation
[-1] = 0xB8;
1354 accumulator
= addressOf(state
, fit
, &toTarget
);
1355 set32LE(fixUpLocation
, accumulator
);
1357 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA
:
1358 // GOT entry was optimized away, change movq instruction to a leaq
1359 if ( fixUpLocation
[-2] != 0x8B )
1360 throw "GOT load reloc does not point to a movq instruction";
1361 fixUpLocation
[-2] = 0x8D;
1362 accumulator
= addressOf(state
, fit
, &toTarget
);
1363 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1364 rangeCheckRIP32(delta
, state
, atom
, fit
);
1365 set32LE(fixUpLocation
, delta
);
1367 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoadNowLEA
:
1368 // TLV entry was optimized away, change movq instruction to a leaq
1369 if ( fixUpLocation
[-2] != 0x8B )
1370 throw "TLV load reloc does not point to a movq instruction";
1371 fixUpLocation
[-2] = 0x8D;
1372 accumulator
= addressOf(state
, fit
, &toTarget
);
1373 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1374 rangeCheckRIP32(delta
, state
, atom
, fit
);
1375 set32LE(fixUpLocation
, delta
);
1377 case ld::Fixup::kindStoreTargetAddressARMBranch24
:
1378 accumulator
= addressOf(state
, fit
, &toTarget
);
1379 thumbTarget
= targetIsThumb(state
, fit
);
1382 if ( fit
->contentDetlaToAddendOnly
)
1384 // fall into kindStoreARMBranch24 case
1385 case ld::Fixup::kindStoreARMBranch24
:
1386 // The pc added will be +8 from the pc
1387 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 8);
1388 rangeCheckARMBranch24(delta
, state
, atom
, fit
);
1389 instruction
= get32LE(fixUpLocation
);
1390 // Make sure we are calling arm with bl, thumb with blx
1391 is_bl
= ((instruction
& 0xFF000000) == 0xEB000000);
1392 is_blx
= ((instruction
& 0xFE000000) == 0xFA000000);
1393 is_b
= !is_blx
&& ((instruction
& 0x0F000000) == 0x0A000000);
1394 if ( is_bl
&& thumbTarget
) {
1395 uint32_t opcode
= 0xFA000000;
1396 uint32_t disp
= (uint32_t)(delta
>> 2) & 0x00FFFFFF;
1397 uint32_t h_bit
= (uint32_t)(delta
<< 23) & 0x01000000;
1398 newInstruction
= opcode
| h_bit
| disp
;
1400 else if ( is_blx
&& !thumbTarget
) {
1401 uint32_t opcode
= 0xEB000000;
1402 uint32_t disp
= (uint32_t)(delta
>> 2) & 0x00FFFFFF;
1403 newInstruction
= opcode
| disp
;
1405 else if ( is_b
&& thumbTarget
) {
1406 if ( fit
->contentDetlaToAddendOnly
)
1407 newInstruction
= (instruction
& 0xFF000000) | ((uint32_t)(delta
>> 2) & 0x00FFFFFF);
1409 throwf("no pc-rel bx arm instruction. Can't fix up branch to %s in %s",
1410 referenceTargetAtomName(state
, fit
), atom
->name());
1412 else if ( !is_bl
&& !is_blx
&& thumbTarget
) {
1413 throwf("don't know how to convert instruction %x referencing %s to thumb",
1414 instruction
, referenceTargetAtomName(state
, fit
));
1417 newInstruction
= (instruction
& 0xFF000000) | ((uint32_t)(delta
>> 2) & 0x00FFFFFF);
1419 set32LE(fixUpLocation
, newInstruction
);
1421 case ld::Fixup::kindStoreTargetAddressThumbBranch22
:
1422 accumulator
= addressOf(state
, fit
, &toTarget
);
1423 thumbTarget
= targetIsThumb(state
, fit
);
1426 if ( fit
->contentDetlaToAddendOnly
)
1428 // fall into kindStoreThumbBranch22 case
1429 case ld::Fixup::kindStoreThumbBranch22
:
1430 instruction
= get32LE(fixUpLocation
);
1431 is_bl
= ((instruction
& 0xD000F800) == 0xD000F000);
1432 is_blx
= ((instruction
& 0xD000F800) == 0xC000F000);
1433 is_b
= ((instruction
& 0xD000F800) == 0x9000F000);
1434 // If the target is not thumb, we will be generating a blx instruction
1435 // Since blx cannot have the low bit set, set bit[1] of the target to
1436 // bit[1] of the base address, so that the difference is a multiple of
1438 if ( !thumbTarget
&& !fit
->contentDetlaToAddendOnly
) {
1439 accumulator
&= -3ULL;
1440 accumulator
|= ((atom
->finalAddress() + fit
->offsetInAtom
) & 2LL);
1442 // The pc added will be +4 from the pc
1443 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1444 rangeCheckThumbBranch22(delta
, state
, atom
, fit
);
1445 if ( _options
.preferSubArchitecture() && _options
.archSupportsThumb2() ) {
1446 // The instruction is really two instructions:
1447 // The lower 16 bits are the first instruction, which contains the high
1448 // 11 bits of the displacement.
1449 // The upper 16 bits are the second instruction, which contains the low
1450 // 11 bits of the displacement, as well as differentiating bl and blx.
1451 uint32_t s
= (uint32_t)(delta
>> 24) & 0x1;
1452 uint32_t i1
= (uint32_t)(delta
>> 23) & 0x1;
1453 uint32_t i2
= (uint32_t)(delta
>> 22) & 0x1;
1454 uint32_t imm10
= (uint32_t)(delta
>> 12) & 0x3FF;
1455 uint32_t imm11
= (uint32_t)(delta
>> 1) & 0x7FF;
1456 uint32_t j1
= (i1
== s
);
1457 uint32_t j2
= (i2
== s
);
1460 instruction
= 0xD000F000; // keep bl
1462 instruction
= 0xC000F000; // change to blx
1464 else if ( is_blx
) {
1466 instruction
= 0xD000F000; // change to bl
1468 instruction
= 0xC000F000; // keep blx
1471 instruction
= 0x9000F000; // keep b
1472 if ( !thumbTarget
&& !fit
->contentDetlaToAddendOnly
) {
1473 throwf("armv7 has no pc-rel bx thumb instruction. Can't fix up branch to %s in %s",
1474 referenceTargetAtomName(state
, fit
), atom
->name());
1479 throwf("don't know how to convert branch instruction %x referencing %s to bx",
1480 instruction
, referenceTargetAtomName(state
, fit
));
1481 instruction
= 0x9000F000; // keep b
1483 uint32_t nextDisp
= (j1
<< 13) | (j2
<< 11) | imm11
;
1484 uint32_t firstDisp
= (s
<< 10) | imm10
;
1485 newInstruction
= instruction
| (nextDisp
<< 16) | firstDisp
;
1486 //warning("s=%d, j1=%d, j2=%d, imm10=0x%0X, imm11=0x%0X, instruction=0x%08X, first=0x%04X, next=0x%04X, new=0x%08X, disp=0x%llX for %s to %s\n",
1487 // s, j1, j2, imm10, imm11, instruction, firstDisp, nextDisp, newInstruction, delta, atom->name(), toTarget->name());
1488 set32LE(fixUpLocation
, newInstruction
);
1491 // The instruction is really two instructions:
1492 // The lower 16 bits are the first instruction, which contains the high
1493 // 11 bits of the displacement.
1494 // The upper 16 bits are the second instruction, which contains the low
1495 // 11 bits of the displacement, as well as differentiating bl and blx.
1496 uint32_t firstDisp
= (uint32_t)(delta
>> 12) & 0x7FF;
1497 uint32_t nextDisp
= (uint32_t)(delta
>> 1) & 0x7FF;
1498 if ( is_bl
&& !thumbTarget
) {
1499 instruction
= 0xE800F000;
1501 else if ( is_blx
&& thumbTarget
) {
1502 instruction
= 0xF800F000;
1505 instruction
= 0x9000F000; // keep b
1506 if ( !thumbTarget
&& !fit
->contentDetlaToAddendOnly
) {
1507 throwf("armv6 has no pc-rel bx thumb instruction. Can't fix up branch to %s in %s",
1508 referenceTargetAtomName(state
, fit
), atom
->name());
1512 instruction
= instruction
& 0xF800F800;
1514 newInstruction
= instruction
| (nextDisp
<< 16) | firstDisp
;
1515 set32LE(fixUpLocation
, newInstruction
);
1518 case ld::Fixup::kindStoreARMLow16
:
1520 uint32_t imm4
= (accumulator
& 0x0000F000) >> 12;
1521 uint32_t imm12
= accumulator
& 0x00000FFF;
1522 instruction
= get32LE(fixUpLocation
);
1523 newInstruction
= (instruction
& 0xFFF0F000) | (imm4
<< 16) | imm12
;
1524 set32LE(fixUpLocation
, newInstruction
);
1527 case ld::Fixup::kindStoreARMHigh16
:
1529 uint32_t imm4
= (accumulator
& 0xF0000000) >> 28;
1530 uint32_t imm12
= (accumulator
& 0x0FFF0000) >> 16;
1531 instruction
= get32LE(fixUpLocation
);
1532 newInstruction
= (instruction
& 0xFFF0F000) | (imm4
<< 16) | imm12
;
1533 set32LE(fixUpLocation
, newInstruction
);
1536 case ld::Fixup::kindStoreThumbLow16
:
1538 uint32_t imm4
= (accumulator
& 0x0000F000) >> 12;
1539 uint32_t i
= (accumulator
& 0x00000800) >> 11;
1540 uint32_t imm3
= (accumulator
& 0x00000700) >> 8;
1541 uint32_t imm8
= accumulator
& 0x000000FF;
1542 instruction
= get32LE(fixUpLocation
);
1543 newInstruction
= (instruction
& 0x8F00FBF0) | imm4
| (i
<< 10) | (imm3
<< 28) | (imm8
<< 16);
1544 set32LE(fixUpLocation
, newInstruction
);
1547 case ld::Fixup::kindStoreThumbHigh16
:
1549 uint32_t imm4
= (accumulator
& 0xF0000000) >> 28;
1550 uint32_t i
= (accumulator
& 0x08000000) >> 27;
1551 uint32_t imm3
= (accumulator
& 0x07000000) >> 24;
1552 uint32_t imm8
= (accumulator
& 0x00FF0000) >> 16;
1553 instruction
= get32LE(fixUpLocation
);
1554 newInstruction
= (instruction
& 0x8F00FBF0) | imm4
| (i
<< 10) | (imm3
<< 28) | (imm8
<< 16);
1555 set32LE(fixUpLocation
, newInstruction
);
1558 #if SUPPORT_ARCH_arm64
1559 case ld::Fixup::kindStoreTargetAddressARM64Branch26
:
1560 accumulator
= addressOf(state
, fit
, &toTarget
);
1561 // fall into kindStoreARM64Branch26 case
1562 case ld::Fixup::kindStoreARM64Branch26
:
1563 if ( fit
->contentAddendOnly
)
1564 delta
= accumulator
;
1566 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
);
1567 rangeCheckARM64Branch26(delta
, state
, atom
, fit
);
1568 instruction
= get32LE(fixUpLocation
);
1569 newInstruction
= (instruction
& 0xFC000000) | ((uint32_t)(delta
>> 2) & 0x03FFFFFF);
1570 set32LE(fixUpLocation
, newInstruction
);
1572 case ld::Fixup::kindStoreTargetAddressARM64GOTLeaPage21
:
1573 case ld::Fixup::kindStoreTargetAddressARM64GOTLoadPage21
:
1574 case ld::Fixup::kindStoreTargetAddressARM64Page21
:
1575 accumulator
= addressOf(state
, fit
, &toTarget
);
1576 // fall into kindStoreARM64Branch26 case
1577 case ld::Fixup::kindStoreARM64GOTLeaPage21
:
1578 case ld::Fixup::kindStoreARM64GOTLoadPage21
:
1579 case ld::Fixup::kindStoreARM64TLVPLoadPage21
:
1580 case ld::Fixup::kindStoreARM64Page21
:
1582 // the ADRP instruction adds the imm << 12 to the page that the pc is on
1583 if ( fit
->contentAddendOnly
)
1586 delta
= (accumulator
& (-4096)) - ((atom
->finalAddress() + fit
->offsetInAtom
) & (-4096));
1587 rangeCheckARM64Page21(delta
, state
, atom
, fit
);
1588 instruction
= get32LE(fixUpLocation
);
1589 uint32_t immhi
= (delta
>> 9) & (0x00FFFFE0);
1590 uint32_t immlo
= (delta
<< 17) & (0x60000000);
1591 newInstruction
= (instruction
& 0x9F00001F) | immlo
| immhi
;
1592 set32LE(fixUpLocation
, newInstruction
);
1595 case ld::Fixup::kindStoreTargetAddressARM64GOTLoadPageOff12
:
1596 case ld::Fixup::kindStoreTargetAddressARM64PageOff12
:
1597 accumulator
= addressOf(state
, fit
, &toTarget
);
1598 // fall into kindAddressARM64PageOff12 case
1599 case ld::Fixup::kindStoreARM64TLVPLoadPageOff12
:
1600 case ld::Fixup::kindStoreARM64GOTLoadPageOff12
:
1601 case ld::Fixup::kindStoreARM64PageOff12
:
1603 uint32_t offset
= accumulator
& 0x00000FFF;
1604 instruction
= get32LE(fixUpLocation
);
1605 // LDR/STR instruction have implicit scale factor, need to compensate for that
1606 if ( instruction
& 0x08000000 ) {
1607 uint32_t implictShift
= ((instruction
>> 30) & 0x3);
1608 switch ( implictShift
) {
1610 if ( (instruction
& 0x04800000) == 0x04800000 ) {
1611 // vector and byte LDR/STR have same "size" bits, need to check other bits to differenciate
1613 if ( (offset
& 0xF) != 0 ) {
1614 throwf("128-bit LDR/STR not 16-byte aligned: from %s (0x%08llX) to %s (0x%08llX)",
1615 atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fit
),
1616 addressOf(state
, fit
, &toTarget
));
1621 if ( (offset
& 0x1) != 0 ) {
1622 throwf("16-bit LDR/STR not 2-byte aligned: from %s (0x%08llX) to %s (0x%08llX)",
1623 atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fit
),
1624 addressOf(state
, fit
, &toTarget
));
1628 if ( (offset
& 0x3) != 0 ) {
1629 throwf("32-bit LDR/STR not 4-byte aligned: from %s (0x%08llX) to %s (0x%08llX)",
1630 atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fit
),
1631 addressOf(state
, fit
, &toTarget
));
1635 if ( (offset
& 0x7) != 0 ) {
1636 throwf("64-bit LDR/STR not 8-byte aligned: from %s (0x%08llX) to %s (0x%08llX)",
1637 atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fit
),
1638 addressOf(state
, fit
, &toTarget
));
1642 // compensate for implicit scale
1643 offset
>>= implictShift
;
1645 if ( fit
->contentAddendOnly
)
1647 uint32_t imm12
= offset
<< 10;
1648 newInstruction
= (instruction
& 0xFFC003FF) | imm12
;
1649 set32LE(fixUpLocation
, newInstruction
);
1652 case ld::Fixup::kindStoreTargetAddressARM64GOTLeaPageOff12
:
1653 accumulator
= addressOf(state
, fit
, &toTarget
);
1654 // fall into kindStoreARM64GOTLoadPage21 case
1655 case ld::Fixup::kindStoreARM64GOTLeaPageOff12
:
1657 // GOT entry was optimized away, change LDR instruction to a ADD
1658 instruction
= get32LE(fixUpLocation
);
1659 if ( (instruction
& 0xFFC00000) != 0xF9400000 )
1660 throwf("GOT load reloc does not point to a LDR instruction in %s", atom
->name());
1661 uint32_t offset
= accumulator
& 0x00000FFF;
1662 uint32_t imm12
= offset
<< 10;
1663 newInstruction
= 0x91000000 | imm12
| (instruction
& 0x000003FF);
1664 set32LE(fixUpLocation
, newInstruction
);
1667 case ld::Fixup::kindStoreARM64PointerToGOT
:
1668 set64LE(fixUpLocation
, accumulator
);
1670 case ld::Fixup::kindStoreARM64PCRelToGOT
:
1671 if ( fit
->contentAddendOnly
)
1672 delta
= accumulator
;
1674 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
);
1675 set32LE(fixUpLocation
, delta
);
1682 void OutputFile::copyNoOps(uint8_t* from
, uint8_t* to
, bool thumb
)
1684 switch ( _options
.architecture() ) {
1686 case CPU_TYPE_X86_64
:
1687 for (uint8_t* p
=from
; p
< to
; ++p
)
1692 for (uint8_t* p
=from
; p
< to
; p
+= 2)
1693 OSWriteLittleInt16((uint16_t*)p
, 0, 0x46c0);
1696 for (uint8_t* p
=from
; p
< to
; p
+= 4)
1697 OSWriteLittleInt32((uint32_t*)p
, 0, 0xe1a00000);
1701 for (uint8_t* p
=from
; p
< to
; ++p
)
1707 bool OutputFile::takesNoDiskSpace(const ld::Section
* sect
)
1709 switch ( sect
->type() ) {
1710 case ld::Section::typeZeroFill
:
1711 case ld::Section::typeTLVZeroFill
:
1712 return _options
.optimizeZeroFill();
1713 case ld::Section::typePageZero
:
1714 case ld::Section::typeStack
:
1715 case ld::Section::typeAbsoluteSymbols
:
1716 case ld::Section::typeTentativeDefs
:
1724 bool OutputFile::hasZeroForFileOffset(const ld::Section
* sect
)
1726 switch ( sect
->type() ) {
1727 case ld::Section::typeZeroFill
:
1728 case ld::Section::typeTLVZeroFill
:
1729 return _options
.optimizeZeroFill();
1730 case ld::Section::typePageZero
:
1731 case ld::Section::typeStack
:
1732 case ld::Section::typeTentativeDefs
:
1740 void OutputFile::writeAtoms(ld::Internal
& state
, uint8_t* wholeBuffer
)
1742 // have each atom write itself
1743 uint64_t fileOffsetOfEndOfLastAtom
= 0;
1744 uint64_t mhAddress
= 0;
1745 bool lastAtomUsesNoOps
= false;
1746 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
1747 ld::Internal::FinalSection
* sect
= *sit
;
1748 if ( sect
->type() == ld::Section::typeMachHeader
)
1749 mhAddress
= sect
->address
;
1750 if ( takesNoDiskSpace(sect
) )
1752 const bool sectionUsesNops
= (sect
->type() == ld::Section::typeCode
);
1753 //fprintf(stderr, "file offset=0x%08llX, section %s\n", sect->fileOffset, sect->sectionName());
1754 std::vector
<const ld::Atom
*>& atoms
= sect
->atoms
;
1755 bool lastAtomWasThumb
= false;
1756 for (std::vector
<const ld::Atom
*>::iterator ait
= atoms
.begin(); ait
!= atoms
.end(); ++ait
) {
1757 const ld::Atom
* atom
= *ait
;
1758 if ( atom
->definition() == ld::Atom::definitionProxy
)
1761 uint64_t fileOffset
= atom
->finalAddress() - sect
->address
+ sect
->fileOffset
;
1762 // check for alignment padding between atoms
1763 if ( (fileOffset
!= fileOffsetOfEndOfLastAtom
) && lastAtomUsesNoOps
) {
1764 this->copyNoOps(&wholeBuffer
[fileOffsetOfEndOfLastAtom
], &wholeBuffer
[fileOffset
], lastAtomWasThumb
);
1766 // copy atom content
1767 atom
->copyRawContent(&wholeBuffer
[fileOffset
]);
1769 this->applyFixUps(state
, mhAddress
, atom
, &wholeBuffer
[fileOffset
]);
1770 fileOffsetOfEndOfLastAtom
= fileOffset
+atom
->size();
1771 lastAtomUsesNoOps
= sectionUsesNops
;
1772 lastAtomWasThumb
= atom
->isThumb();
1774 catch (const char* msg
) {
1775 if ( atom
->file() != NULL
)
1776 throwf("%s in '%s' from %s", msg
, atom
->name(), atom
->file()->path());
1778 throwf("%s in '%s'", msg
, atom
->name());
1785 void OutputFile::computeContentUUID(ld::Internal
& state
, uint8_t* wholeBuffer
)
1787 const bool log
= false;
1788 if ( (_options
.outputKind() != Options::kObjectFile
) || state
.someObjectFileHasDwarf
) {
1789 uint8_t digest
[CC_MD5_DIGEST_LENGTH
];
1790 uint32_t stabsStringsOffsetStart
;
1791 uint32_t tabsStringsOffsetEnd
;
1792 uint32_t stabsOffsetStart
;
1793 uint32_t stabsOffsetEnd
;
1794 if ( _symbolTableAtom
->hasStabs(stabsStringsOffsetStart
, tabsStringsOffsetEnd
, stabsOffsetStart
, stabsOffsetEnd
) ) {
1795 // find two areas of file that are stabs info and should not contribute to checksum
1796 uint64_t stringPoolFileOffset
= 0;
1797 uint64_t symbolTableFileOffset
= 0;
1798 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
1799 ld::Internal::FinalSection
* sect
= *sit
;
1800 if ( sect
->type() == ld::Section::typeLinkEdit
) {
1801 if ( strcmp(sect
->sectionName(), "__string_pool") == 0 )
1802 stringPoolFileOffset
= sect
->fileOffset
;
1803 else if ( strcmp(sect
->sectionName(), "__symbol_table") == 0 )
1804 symbolTableFileOffset
= sect
->fileOffset
;
1807 uint64_t firstStabNlistFileOffset
= symbolTableFileOffset
+ stabsOffsetStart
;
1808 uint64_t lastStabNlistFileOffset
= symbolTableFileOffset
+ stabsOffsetEnd
;
1809 uint64_t firstStabStringFileOffset
= stringPoolFileOffset
+ stabsStringsOffsetStart
;
1810 uint64_t lastStabStringFileOffset
= stringPoolFileOffset
+ tabsStringsOffsetEnd
;
1811 if ( log
) fprintf(stderr
, "firstStabNlistFileOffset=0x%08llX\n", firstStabNlistFileOffset
);
1812 if ( log
) fprintf(stderr
, "lastStabNlistFileOffset=0x%08llX\n", lastStabNlistFileOffset
);
1813 if ( log
) fprintf(stderr
, "firstStabStringFileOffset=0x%08llX\n", firstStabStringFileOffset
);
1814 if ( log
) fprintf(stderr
, "lastStabStringFileOffset=0x%08llX\n", lastStabStringFileOffset
);
1815 assert(firstStabNlistFileOffset
<= firstStabStringFileOffset
);
1817 CC_MD5_CTX md5state
;
1818 CC_MD5_Init(&md5state
);
1819 // checksum everything up to first stabs nlist
1820 if ( log
) fprintf(stderr
, "checksum 0x%08X -> 0x%08llX\n", 0, firstStabNlistFileOffset
);
1821 CC_MD5_Update(&md5state
, &wholeBuffer
[0], firstStabNlistFileOffset
);
1822 // checkusm everything after last stabs nlist and up to first stabs string
1823 if ( log
) fprintf(stderr
, "checksum 0x%08llX -> 0x%08llX\n", lastStabNlistFileOffset
, firstStabStringFileOffset
);
1824 CC_MD5_Update(&md5state
, &wholeBuffer
[lastStabNlistFileOffset
], firstStabStringFileOffset
-lastStabNlistFileOffset
);
1825 // checksum everything after last stabs string to end of file
1826 if ( log
) fprintf(stderr
, "checksum 0x%08llX -> 0x%08llX\n", lastStabStringFileOffset
, _fileSize
);
1827 CC_MD5_Update(&md5state
, &wholeBuffer
[lastStabStringFileOffset
], _fileSize
-lastStabStringFileOffset
);
1828 CC_MD5_Final(digest
, &md5state
);
1829 if ( log
) fprintf(stderr
, "uuid=%02X, %02X, %02X, %02X, %02X, %02X, %02X, %02X\n", digest
[0], digest
[1], digest
[2],
1830 digest
[3], digest
[4], digest
[5], digest
[6], digest
[7]);
1833 CC_MD5(wholeBuffer
, _fileSize
, digest
);
1835 // <rdar://problem/6723729> LC_UUID uuids should conform to RFC 4122 UUID version 4 & UUID version 5 formats
1836 digest
[6] = ( digest
[6] & 0x0F ) | ( 3 << 4 );
1837 digest
[8] = ( digest
[8] & 0x3F ) | 0x80;
1838 // update buffer with new UUID
1839 _headersAndLoadCommandAtom
->setUUID(digest
);
1840 _headersAndLoadCommandAtom
->recopyUUIDCommand();
1845 void OutputFile::writeOutputFile(ld::Internal
& state
)
1847 // for UNIX conformance, error if file exists and is not writable
1848 if ( (access(_options
.outputFilePath(), F_OK
) == 0) && (access(_options
.outputFilePath(), W_OK
) == -1) )
1849 throwf("can't write output file: %s", _options
.outputFilePath());
1851 mode_t permissions
= 0777;
1852 if ( _options
.outputKind() == Options::kObjectFile
)
1854 mode_t umask
= ::umask(0);
1855 ::umask(umask
); // put back the original umask
1856 permissions
&= ~umask
;
1857 // Calling unlink first assures the file is gone so that open creates it with correct permissions
1858 // It also handles the case where __options.outputFilePath() file is not writable but its directory is
1859 // And it means we don't have to truncate the file when done writing (in case new is smaller than old)
1860 // Lastly, only delete existing file if it is a normal file (e.g. not /dev/null).
1861 struct stat stat_buf
;
1862 bool outputIsRegularFile
= false;
1863 bool outputIsMappableFile
= false;
1864 if ( stat(_options
.outputFilePath(), &stat_buf
) != -1 ) {
1865 if (stat_buf
.st_mode
& S_IFREG
) {
1866 outputIsRegularFile
= true;
1867 // <rdar://problem/12264302> Don't use mmap on non-hfs volumes
1868 struct statfs fsInfo
;
1869 if ( statfs(_options
.outputFilePath(), &fsInfo
) != -1 ) {
1870 if ( strcmp(fsInfo
.f_fstypename
, "hfs") == 0) {
1871 (void)unlink(_options
.outputFilePath());
1872 outputIsMappableFile
= true;
1876 outputIsMappableFile
= false;
1880 outputIsRegularFile
= false;
1884 // special files (pipes, devices, etc) must already exist
1885 outputIsRegularFile
= true;
1886 // output file does not exist yet
1887 char dirPath
[PATH_MAX
];
1888 strcpy(dirPath
, _options
.outputFilePath());
1889 char* end
= strrchr(dirPath
, '/');
1890 if ( end
!= NULL
) {
1892 struct statfs fsInfo
;
1893 if ( statfs(dirPath
, &fsInfo
) != -1 ) {
1894 if ( strcmp(fsInfo
.f_fstypename
, "hfs") == 0) {
1895 outputIsMappableFile
= true;
1901 //fprintf(stderr, "outputIsMappableFile=%d, outputIsRegularFile=%d, path=%s\n", outputIsMappableFile, outputIsRegularFile, _options.outputFilePath());
1904 // Construct a temporary path of the form {outputFilePath}.ld_XXXXXX
1905 const char filenameTemplate
[] = ".ld_XXXXXX";
1906 char tmpOutput
[PATH_MAX
];
1907 uint8_t *wholeBuffer
;
1908 if ( outputIsRegularFile
&& outputIsMappableFile
) {
1909 strcpy(tmpOutput
, _options
.outputFilePath());
1910 // If the path is too long to add a suffix for a temporary name then
1911 // just fall back to using the output path.
1912 if (strlen(tmpOutput
)+strlen(filenameTemplate
) < PATH_MAX
) {
1913 strcat(tmpOutput
, filenameTemplate
);
1914 fd
= mkstemp(tmpOutput
);
1917 fd
= open(tmpOutput
, O_RDWR
|O_CREAT
, permissions
);
1920 throwf("can't open output file for writing '%s', errno=%d", tmpOutput
, errno
);
1921 if ( ftruncate(fd
, _fileSize
) == -1 ) {
1924 if ( err
== ENOSPC
)
1925 throwf("not enough disk space for writing '%s'", _options
.outputFilePath());
1927 throwf("can't grow file for writing '%s', errno=%d", _options
.outputFilePath(), err
);
1930 wholeBuffer
= (uint8_t *)mmap(NULL
, _fileSize
, PROT_WRITE
|PROT_READ
, MAP_SHARED
, fd
, 0);
1931 if ( wholeBuffer
== MAP_FAILED
)
1932 throwf("can't create buffer of %llu bytes for output", _fileSize
);
1935 if ( outputIsRegularFile
)
1936 fd
= open(_options
.outputFilePath(), O_RDWR
|O_CREAT
, permissions
);
1938 fd
= open(_options
.outputFilePath(), O_WRONLY
);
1940 throwf("can't open output file for writing: %s, errno=%d", _options
.outputFilePath(), errno
);
1941 // try to allocate buffer for entire output file content
1942 wholeBuffer
= (uint8_t*)calloc(_fileSize
, 1);
1943 if ( wholeBuffer
== NULL
)
1944 throwf("can't create buffer of %llu bytes for output", _fileSize
);
1947 if ( _options
.UUIDMode() == Options::kUUIDRandom
) {
1949 ::uuid_generate_random(bits
);
1950 _headersAndLoadCommandAtom
->setUUID(bits
);
1953 writeAtoms(state
, wholeBuffer
);
1956 if ( _options
.UUIDMode() == Options::kUUIDContent
)
1957 computeContentUUID(state
, wholeBuffer
);
1959 if ( outputIsRegularFile
&& outputIsMappableFile
) {
1960 if ( ::chmod(tmpOutput
, permissions
) == -1 ) {
1962 throwf("can't set permissions on output file: %s, errno=%d", tmpOutput
, errno
);
1964 if ( ::rename(tmpOutput
, _options
.outputFilePath()) == -1 && strcmp(tmpOutput
, _options
.outputFilePath()) != 0) {
1966 throwf("can't move output file in place, errno=%d", errno
);
1970 if ( ::write(fd
, wholeBuffer
, _fileSize
) == -1 ) {
1971 throwf("can't write to output file: %s, errno=%d", _options
.outputFilePath(), errno
);
1974 // <rdar://problem/13118223> NFS: iOS incremental builds in Xcode 4.6 fail with codesign error
1975 // NFS seems to pad the end of the file sometimes. Calling trunc seems to correct it...
1976 ::truncate(_options
.outputFilePath(), _fileSize
);
1980 struct AtomByNameSorter
1982 bool operator()(const ld::Atom
* left
, const ld::Atom
* right
)
1984 return (strcmp(left
->name(), right
->name()) < 0);
1991 NotInSet(const std::set
<const ld::Atom
*>& theSet
) : _set(theSet
) {}
1993 bool operator()(const ld::Atom
* atom
) const {
1994 return ( _set
.count(atom
) == 0 );
1997 const std::set
<const ld::Atom
*>& _set
;
2001 void OutputFile::buildSymbolTable(ld::Internal
& state
)
2003 unsigned int machoSectionIndex
= 0;
2004 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
2005 ld::Internal::FinalSection
* sect
= *sit
;
2006 bool setMachoSectionIndex
= !sect
->isSectionHidden() && (sect
->type() != ld::Section::typeTentativeDefs
);
2007 if ( setMachoSectionIndex
)
2008 ++machoSectionIndex
;
2009 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
2010 const ld::Atom
* atom
= *ait
;
2011 if ( setMachoSectionIndex
)
2012 (const_cast<ld::Atom
*>(atom
))->setMachoSection(machoSectionIndex
);
2013 else if ( sect
->type() == ld::Section::typeMachHeader
)
2014 (const_cast<ld::Atom
*>(atom
))->setMachoSection(1); // __mh_execute_header is not in any section by needs n_sect==1
2015 else if ( sect
->type() == ld::Section::typeLastSection
)
2016 (const_cast<ld::Atom
*>(atom
))->setMachoSection(machoSectionIndex
); // use section index of previous section
2017 else if ( sect
->type() == ld::Section::typeFirstSection
)
2018 (const_cast<ld::Atom
*>(atom
))->setMachoSection(machoSectionIndex
+1); // use section index of next section
2020 // in -r mode, clarify symbolTableNotInFinalLinkedImages
2021 if ( _options
.outputKind() == Options::kObjectFile
) {
2022 if ( (_options
.architecture() == CPU_TYPE_X86_64
) || (_options
.architecture() == CPU_TYPE_ARM64
) ) {
2023 // x86_64 .o files need labels on anonymous literal strings
2024 if ( (sect
->type() == ld::Section::typeCString
) && (atom
->combine() == ld::Atom::combineByNameAndContent
) ) {
2025 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableIn
);
2026 _localAtoms
.push_back(atom
);
2030 if ( sect
->type() == ld::Section::typeCFI
) {
2031 if ( _options
.removeEHLabels() )
2032 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableNotIn
);
2034 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableIn
);
2036 if ( atom
->symbolTableInclusion() == ld::Atom::symbolTableNotInFinalLinkedImages
)
2037 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableIn
);
2040 // TEMP work around until <rdar://problem/7702923> goes in
2041 if ( (atom
->symbolTableInclusion() == ld::Atom::symbolTableInAndNeverStrip
)
2042 && (atom
->scope() == ld::Atom::scopeLinkageUnit
)
2043 && (_options
.outputKind() == Options::kDynamicLibrary
) ) {
2044 (const_cast<ld::Atom
*>(atom
))->setScope(ld::Atom::scopeGlobal
);
2047 // <rdar://problem/6783167> support auto hidden weak symbols: .weak_def_can_be_hidden
2048 if ( atom
->autoHide() && (_options
.outputKind() != Options::kObjectFile
) ) {
2049 // adding auto-hide symbol to .exp file should keep it global
2050 if ( !_options
.hasExportMaskList() || !_options
.shouldExport(atom
->name()) )
2051 (const_cast<ld::Atom
*>(atom
))->setScope(ld::Atom::scopeLinkageUnit
);
2054 // <rdar://problem/8626058> ld should consistently warn when resolvers are not exported
2055 if ( (atom
->contentType() == ld::Atom::typeResolver
) && (atom
->scope() == ld::Atom::scopeLinkageUnit
) )
2056 warning("resolver functions should be external, but '%s' is hidden", atom
->name());
2058 if ( sect
->type() == ld::Section::typeImportProxies
) {
2059 if ( atom
->combine() == ld::Atom::combineByName
)
2060 this->usesWeakExternalSymbols
= true;
2061 // alias proxy is a re-export with a name change, don't import changed name
2062 if ( ! atom
->isAlias() )
2063 _importedAtoms
.push_back(atom
);
2064 // scope of proxies are usually linkage unit, so done
2065 // if scope is global, we need to re-export it too
2066 if ( atom
->scope() == ld::Atom::scopeGlobal
)
2067 _exportedAtoms
.push_back(atom
);
2070 if ( atom
->symbolTableInclusion() == ld::Atom::symbolTableNotInFinalLinkedImages
) {
2071 assert(_options
.outputKind() != Options::kObjectFile
);
2072 continue; // don't add to symbol table
2074 if ( atom
->symbolTableInclusion() == ld::Atom::symbolTableNotIn
) {
2075 continue; // don't add to symbol table
2077 if ( (atom
->symbolTableInclusion() == ld::Atom::symbolTableInWithRandomAutoStripLabel
)
2078 && (_options
.outputKind() != Options::kObjectFile
) ) {
2079 continue; // don't add to symbol table
2082 if ( (atom
->definition() == ld::Atom::definitionTentative
) && (_options
.outputKind() == Options::kObjectFile
) ) {
2083 if ( _options
.makeTentativeDefinitionsReal() ) {
2084 // -r -d turns tentative defintions into real def
2085 _exportedAtoms
.push_back(atom
);
2088 // in mach-o object files tentative defintions are stored like undefined symbols
2089 _importedAtoms
.push_back(atom
);
2094 switch ( atom
->scope() ) {
2095 case ld::Atom::scopeTranslationUnit
:
2096 if ( _options
.keepLocalSymbol(atom
->name()) ) {
2097 _localAtoms
.push_back(atom
);
2100 if ( _options
.outputKind() == Options::kObjectFile
) {
2101 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableInWithRandomAutoStripLabel
);
2102 _localAtoms
.push_back(atom
);
2105 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableNotIn
);
2108 case ld::Atom::scopeGlobal
:
2109 _exportedAtoms
.push_back(atom
);
2111 case ld::Atom::scopeLinkageUnit
:
2112 if ( _options
.outputKind() == Options::kObjectFile
) {
2113 if ( _options
.keepPrivateExterns() ) {
2114 _exportedAtoms
.push_back(atom
);
2116 else if ( _options
.keepLocalSymbol(atom
->name()) ) {
2117 _localAtoms
.push_back(atom
);
2120 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableInWithRandomAutoStripLabel
);
2121 _localAtoms
.push_back(atom
);
2125 if ( _options
.keepLocalSymbol(atom
->name()) )
2126 _localAtoms
.push_back(atom
);
2127 // <rdar://problem/5804214> ld should never have a symbol in the non-lazy indirect symbol table with index 0
2128 // this works by making __mh_execute_header be a local symbol which takes symbol index 0
2129 else if ( (atom
->symbolTableInclusion() == ld::Atom::symbolTableInAndNeverStrip
) && !_options
.makeCompressedDyldInfo() )
2130 _localAtoms
.push_back(atom
);
2132 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableNotIn
);
2139 // <rdar://problem/6978069> ld adds undefined symbol from .exp file to binary
2140 if ( (_options
.outputKind() == Options::kKextBundle
) && _options
.hasExportRestrictList() ) {
2141 // search for referenced undefines
2142 std::set
<const ld::Atom
*> referencedProxyAtoms
;
2143 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
=state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
2144 ld::Internal::FinalSection
* sect
= *sit
;
2145 for (std::vector
<const ld::Atom
*>::iterator ait
=sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
2146 const ld::Atom
* atom
= *ait
;
2147 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(), end
=atom
->fixupsEnd(); fit
!= end
; ++fit
) {
2148 switch ( fit
->binding
) {
2149 case ld::Fixup::bindingsIndirectlyBound
:
2150 referencedProxyAtoms
.insert(state
.indirectBindingTable
[fit
->u
.bindingIndex
]);
2152 case ld::Fixup::bindingDirectlyBound
:
2153 referencedProxyAtoms
.insert(fit
->u
.target
);
2161 // remove any unreferenced _importedAtoms
2162 _importedAtoms
.erase(std::remove_if(_importedAtoms
.begin(), _importedAtoms
.end(), NotInSet(referencedProxyAtoms
)), _importedAtoms
.end());
2166 std::sort(_exportedAtoms
.begin(), _exportedAtoms
.end(), AtomByNameSorter());
2167 std::sort(_importedAtoms
.begin(), _importedAtoms
.end(), AtomByNameSorter());
2170 void OutputFile::addPreloadLinkEdit(ld::Internal
& state
)
2172 switch ( _options
.architecture() ) {
2173 #if SUPPORT_ARCH_i386
2175 if ( _hasLocalRelocations
) {
2176 _localRelocsAtom
= new LocalRelocationsAtom
<x86
>(_options
, state
, *this);
2177 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
2179 if ( _hasExternalRelocations
) {
2180 _externalRelocsAtom
= new ExternalRelocationsAtom
<x86
>(_options
, state
, *this);
2181 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
2183 if ( _hasSymbolTable
) {
2184 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<x86
>(_options
, state
, *this);
2185 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
2186 _symbolTableAtom
= new SymbolTableAtom
<x86
>(_options
, state
, *this);
2187 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
2188 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 4);
2189 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
2193 #if SUPPORT_ARCH_x86_64
2194 case CPU_TYPE_X86_64
:
2195 if ( _hasLocalRelocations
) {
2196 _localRelocsAtom
= new LocalRelocationsAtom
<x86_64
>(_options
, state
, *this);
2197 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
2199 if ( _hasExternalRelocations
) {
2200 _externalRelocsAtom
= new ExternalRelocationsAtom
<x86_64
>(_options
, state
, *this);
2201 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
2203 if ( _hasSymbolTable
) {
2204 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<x86_64
>(_options
, state
, *this);
2205 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
2206 _symbolTableAtom
= new SymbolTableAtom
<x86_64
>(_options
, state
, *this);
2207 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
2208 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 4);
2209 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
2213 #if SUPPORT_ARCH_arm_any
2215 if ( _hasLocalRelocations
) {
2216 _localRelocsAtom
= new LocalRelocationsAtom
<arm
>(_options
, state
, *this);
2217 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
2219 if ( _hasExternalRelocations
) {
2220 _externalRelocsAtom
= new ExternalRelocationsAtom
<arm
>(_options
, state
, *this);
2221 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
2223 if ( _hasSymbolTable
) {
2224 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<arm
>(_options
, state
, *this);
2225 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
2226 _symbolTableAtom
= new SymbolTableAtom
<arm
>(_options
, state
, *this);
2227 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
2228 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 4);
2229 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
2233 #if SUPPORT_ARCH_arm64
2234 case CPU_TYPE_ARM64
:
2235 if ( _hasLocalRelocations
) {
2236 _localRelocsAtom
= new LocalRelocationsAtom
<arm64
>(_options
, state
, *this);
2237 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
2239 if ( _hasExternalRelocations
) {
2240 _externalRelocsAtom
= new ExternalRelocationsAtom
<arm64
>(_options
, state
, *this);
2241 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
2243 if ( _hasSymbolTable
) {
2244 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<arm64
>(_options
, state
, *this);
2245 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
2246 _symbolTableAtom
= new SymbolTableAtom
<arm64
>(_options
, state
, *this);
2247 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
2248 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 4);
2249 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
2254 throw "-preload not supported";
2260 void OutputFile::addLinkEdit(ld::Internal
& state
)
2262 // for historical reasons, -preload orders LINKEDIT content differently
2263 if ( _options
.outputKind() == Options::kPreload
)
2264 return addPreloadLinkEdit(state
);
2266 switch ( _options
.architecture() ) {
2267 #if SUPPORT_ARCH_i386
2269 if ( _hasSectionRelocations
) {
2270 _sectionsRelocationsAtom
= new SectionRelocationsAtom
<x86
>(_options
, state
, *this);
2271 sectionRelocationsSection
= state
.addAtom(*_sectionsRelocationsAtom
);
2273 if ( _hasDyldInfo
) {
2274 _rebasingInfoAtom
= new RebaseInfoAtom
<x86
>(_options
, state
, *this);
2275 rebaseSection
= state
.addAtom(*_rebasingInfoAtom
);
2277 _bindingInfoAtom
= new BindingInfoAtom
<x86
>(_options
, state
, *this);
2278 bindingSection
= state
.addAtom(*_bindingInfoAtom
);
2280 _weakBindingInfoAtom
= new WeakBindingInfoAtom
<x86
>(_options
, state
, *this);
2281 weakBindingSection
= state
.addAtom(*_weakBindingInfoAtom
);
2283 _lazyBindingInfoAtom
= new LazyBindingInfoAtom
<x86
>(_options
, state
, *this);
2284 lazyBindingSection
= state
.addAtom(*_lazyBindingInfoAtom
);
2286 _exportInfoAtom
= new ExportInfoAtom
<x86
>(_options
, state
, *this);
2287 exportSection
= state
.addAtom(*_exportInfoAtom
);
2289 if ( _hasLocalRelocations
) {
2290 _localRelocsAtom
= new LocalRelocationsAtom
<x86
>(_options
, state
, *this);
2291 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
2293 if ( _hasSplitSegInfo
) {
2294 _splitSegInfoAtom
= new SplitSegInfoAtom
<x86
>(_options
, state
, *this);
2295 splitSegInfoSection
= state
.addAtom(*_splitSegInfoAtom
);
2297 if ( _hasFunctionStartsInfo
) {
2298 _functionStartsAtom
= new FunctionStartsAtom
<x86
>(_options
, state
, *this);
2299 functionStartsSection
= state
.addAtom(*_functionStartsAtom
);
2301 if ( _hasDataInCodeInfo
) {
2302 _dataInCodeAtom
= new DataInCodeAtom
<x86
>(_options
, state
, *this);
2303 dataInCodeSection
= state
.addAtom(*_dataInCodeAtom
);
2305 if ( _hasDependentDRInfo
) {
2306 _dependentDRInfoAtom
= new DependentDRAtom
<x86
>(_options
, state
, *this);
2307 dependentDRsSection
= state
.addAtom(*_dependentDRInfoAtom
);
2309 if ( _hasSymbolTable
) {
2310 _symbolTableAtom
= new SymbolTableAtom
<x86
>(_options
, state
, *this);
2311 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
2313 if ( _hasExternalRelocations
) {
2314 _externalRelocsAtom
= new ExternalRelocationsAtom
<x86
>(_options
, state
, *this);
2315 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
2317 if ( _hasSymbolTable
) {
2318 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<x86
>(_options
, state
, *this);
2319 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
2320 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 4);
2321 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
2325 #if SUPPORT_ARCH_x86_64
2326 case CPU_TYPE_X86_64
:
2327 if ( _hasSectionRelocations
) {
2328 _sectionsRelocationsAtom
= new SectionRelocationsAtom
<x86_64
>(_options
, state
, *this);
2329 sectionRelocationsSection
= state
.addAtom(*_sectionsRelocationsAtom
);
2331 if ( _hasDyldInfo
) {
2332 _rebasingInfoAtom
= new RebaseInfoAtom
<x86_64
>(_options
, state
, *this);
2333 rebaseSection
= state
.addAtom(*_rebasingInfoAtom
);
2335 _bindingInfoAtom
= new BindingInfoAtom
<x86_64
>(_options
, state
, *this);
2336 bindingSection
= state
.addAtom(*_bindingInfoAtom
);
2338 _weakBindingInfoAtom
= new WeakBindingInfoAtom
<x86_64
>(_options
, state
, *this);
2339 weakBindingSection
= state
.addAtom(*_weakBindingInfoAtom
);
2341 _lazyBindingInfoAtom
= new LazyBindingInfoAtom
<x86_64
>(_options
, state
, *this);
2342 lazyBindingSection
= state
.addAtom(*_lazyBindingInfoAtom
);
2344 _exportInfoAtom
= new ExportInfoAtom
<x86_64
>(_options
, state
, *this);
2345 exportSection
= state
.addAtom(*_exportInfoAtom
);
2347 if ( _hasLocalRelocations
) {
2348 _localRelocsAtom
= new LocalRelocationsAtom
<x86_64
>(_options
, state
, *this);
2349 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
2351 if ( _hasSplitSegInfo
) {
2352 _splitSegInfoAtom
= new SplitSegInfoAtom
<x86_64
>(_options
, state
, *this);
2353 splitSegInfoSection
= state
.addAtom(*_splitSegInfoAtom
);
2355 if ( _hasFunctionStartsInfo
) {
2356 _functionStartsAtom
= new FunctionStartsAtom
<x86_64
>(_options
, state
, *this);
2357 functionStartsSection
= state
.addAtom(*_functionStartsAtom
);
2359 if ( _hasDataInCodeInfo
) {
2360 _dataInCodeAtom
= new DataInCodeAtom
<x86_64
>(_options
, state
, *this);
2361 dataInCodeSection
= state
.addAtom(*_dataInCodeAtom
);
2363 if ( _hasDependentDRInfo
) {
2364 _dependentDRInfoAtom
= new DependentDRAtom
<x86_64
>(_options
, state
, *this);
2365 dependentDRsSection
= state
.addAtom(*_dependentDRInfoAtom
);
2367 if ( _hasSymbolTable
) {
2368 _symbolTableAtom
= new SymbolTableAtom
<x86_64
>(_options
, state
, *this);
2369 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
2371 if ( _hasExternalRelocations
) {
2372 _externalRelocsAtom
= new ExternalRelocationsAtom
<x86_64
>(_options
, state
, *this);
2373 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
2375 if ( _hasSymbolTable
) {
2376 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<x86_64
>(_options
, state
, *this);
2377 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
2378 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 8);
2379 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
2383 #if SUPPORT_ARCH_arm_any
2385 if ( _hasSectionRelocations
) {
2386 _sectionsRelocationsAtom
= new SectionRelocationsAtom
<arm
>(_options
, state
, *this);
2387 sectionRelocationsSection
= state
.addAtom(*_sectionsRelocationsAtom
);
2389 if ( _hasDyldInfo
) {
2390 _rebasingInfoAtom
= new RebaseInfoAtom
<arm
>(_options
, state
, *this);
2391 rebaseSection
= state
.addAtom(*_rebasingInfoAtom
);
2393 _bindingInfoAtom
= new BindingInfoAtom
<arm
>(_options
, state
, *this);
2394 bindingSection
= state
.addAtom(*_bindingInfoAtom
);
2396 _weakBindingInfoAtom
= new WeakBindingInfoAtom
<arm
>(_options
, state
, *this);
2397 weakBindingSection
= state
.addAtom(*_weakBindingInfoAtom
);
2399 _lazyBindingInfoAtom
= new LazyBindingInfoAtom
<arm
>(_options
, state
, *this);
2400 lazyBindingSection
= state
.addAtom(*_lazyBindingInfoAtom
);
2402 _exportInfoAtom
= new ExportInfoAtom
<arm
>(_options
, state
, *this);
2403 exportSection
= state
.addAtom(*_exportInfoAtom
);
2405 if ( _hasLocalRelocations
) {
2406 _localRelocsAtom
= new LocalRelocationsAtom
<arm
>(_options
, state
, *this);
2407 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
2409 if ( _hasSplitSegInfo
) {
2410 _splitSegInfoAtom
= new SplitSegInfoAtom
<arm
>(_options
, state
, *this);
2411 splitSegInfoSection
= state
.addAtom(*_splitSegInfoAtom
);
2413 if ( _hasFunctionStartsInfo
) {
2414 _functionStartsAtom
= new FunctionStartsAtom
<arm
>(_options
, state
, *this);
2415 functionStartsSection
= state
.addAtom(*_functionStartsAtom
);
2417 if ( _hasDataInCodeInfo
) {
2418 _dataInCodeAtom
= new DataInCodeAtom
<arm
>(_options
, state
, *this);
2419 dataInCodeSection
= state
.addAtom(*_dataInCodeAtom
);
2421 if ( _hasDependentDRInfo
) {
2422 _dependentDRInfoAtom
= new DependentDRAtom
<arm
>(_options
, state
, *this);
2423 dependentDRsSection
= state
.addAtom(*_dependentDRInfoAtom
);
2425 if ( _hasSymbolTable
) {
2426 _symbolTableAtom
= new SymbolTableAtom
<arm
>(_options
, state
, *this);
2427 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
2429 if ( _hasExternalRelocations
) {
2430 _externalRelocsAtom
= new ExternalRelocationsAtom
<arm
>(_options
, state
, *this);
2431 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
2433 if ( _hasSymbolTable
) {
2434 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<arm
>(_options
, state
, *this);
2435 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
2436 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 4);
2437 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
2441 #if SUPPORT_ARCH_arm64
2442 case CPU_TYPE_ARM64
:
2443 if ( _hasSectionRelocations
) {
2444 _sectionsRelocationsAtom
= new SectionRelocationsAtom
<arm64
>(_options
, state
, *this);
2445 sectionRelocationsSection
= state
.addAtom(*_sectionsRelocationsAtom
);
2447 if ( _hasDyldInfo
) {
2448 _rebasingInfoAtom
= new RebaseInfoAtom
<arm64
>(_options
, state
, *this);
2449 rebaseSection
= state
.addAtom(*_rebasingInfoAtom
);
2451 _bindingInfoAtom
= new BindingInfoAtom
<arm64
>(_options
, state
, *this);
2452 bindingSection
= state
.addAtom(*_bindingInfoAtom
);
2454 _weakBindingInfoAtom
= new WeakBindingInfoAtom
<arm64
>(_options
, state
, *this);
2455 weakBindingSection
= state
.addAtom(*_weakBindingInfoAtom
);
2457 _lazyBindingInfoAtom
= new LazyBindingInfoAtom
<arm64
>(_options
, state
, *this);
2458 lazyBindingSection
= state
.addAtom(*_lazyBindingInfoAtom
);
2460 _exportInfoAtom
= new ExportInfoAtom
<arm64
>(_options
, state
, *this);
2461 exportSection
= state
.addAtom(*_exportInfoAtom
);
2463 if ( _hasLocalRelocations
) {
2464 _localRelocsAtom
= new LocalRelocationsAtom
<arm64
>(_options
, state
, *this);
2465 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
2467 if ( _hasSplitSegInfo
) {
2468 _splitSegInfoAtom
= new SplitSegInfoAtom
<arm64
>(_options
, state
, *this);
2469 splitSegInfoSection
= state
.addAtom(*_splitSegInfoAtom
);
2471 if ( _hasFunctionStartsInfo
) {
2472 _functionStartsAtom
= new FunctionStartsAtom
<arm64
>(_options
, state
, *this);
2473 functionStartsSection
= state
.addAtom(*_functionStartsAtom
);
2475 if ( _hasDataInCodeInfo
) {
2476 _dataInCodeAtom
= new DataInCodeAtom
<arm64
>(_options
, state
, *this);
2477 dataInCodeSection
= state
.addAtom(*_dataInCodeAtom
);
2479 if ( _hasDependentDRInfo
) {
2480 _dependentDRInfoAtom
= new DependentDRAtom
<arm64
>(_options
, state
, *this);
2481 dependentDRsSection
= state
.addAtom(*_dependentDRInfoAtom
);
2483 if ( _hasSymbolTable
) {
2484 _symbolTableAtom
= new SymbolTableAtom
<arm64
>(_options
, state
, *this);
2485 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
2487 if ( _hasExternalRelocations
) {
2488 _externalRelocsAtom
= new ExternalRelocationsAtom
<arm64
>(_options
, state
, *this);
2489 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
2491 if ( _hasSymbolTable
) {
2492 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<arm64
>(_options
, state
, *this);
2493 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
2494 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 4);
2495 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
2500 throw "unknown architecture";
2504 void OutputFile::addLoadCommands(ld::Internal
& state
)
2506 switch ( _options
.architecture() ) {
2507 #if SUPPORT_ARCH_x86_64
2508 case CPU_TYPE_X86_64
:
2509 _headersAndLoadCommandAtom
= new HeaderAndLoadCommandsAtom
<x86_64
>(_options
, state
, *this);
2510 headerAndLoadCommandsSection
= state
.addAtom(*_headersAndLoadCommandAtom
);
2513 #if SUPPORT_ARCH_arm_any
2515 _headersAndLoadCommandAtom
= new HeaderAndLoadCommandsAtom
<arm
>(_options
, state
, *this);
2516 headerAndLoadCommandsSection
= state
.addAtom(*_headersAndLoadCommandAtom
);
2519 #if SUPPORT_ARCH_arm64
2520 case CPU_TYPE_ARM64
:
2521 _headersAndLoadCommandAtom
= new HeaderAndLoadCommandsAtom
<arm64
>(_options
, state
, *this);
2522 headerAndLoadCommandsSection
= state
.addAtom(*_headersAndLoadCommandAtom
);
2525 #if SUPPORT_ARCH_i386
2527 _headersAndLoadCommandAtom
= new HeaderAndLoadCommandsAtom
<x86
>(_options
, state
, *this);
2528 headerAndLoadCommandsSection
= state
.addAtom(*_headersAndLoadCommandAtom
);
2532 throw "unknown architecture";
2536 uint32_t OutputFile::dylibCount()
2538 return _dylibsToLoad
.size();
2541 const ld::dylib::File
* OutputFile::dylibByOrdinal(unsigned int ordinal
)
2543 assert( ordinal
> 0 );
2544 assert( ordinal
<= _dylibsToLoad
.size() );
2545 return _dylibsToLoad
[ordinal
-1];
2548 bool OutputFile::hasOrdinalForInstallPath(const char* path
, int* ordinal
)
2550 for (std::map
<const ld::dylib::File
*, int>::const_iterator it
= _dylibToOrdinal
.begin(); it
!= _dylibToOrdinal
.end(); ++it
) {
2551 const char* installPath
= it
->first
->installPath();
2552 if ( (installPath
!= NULL
) && (strcmp(path
, installPath
) == 0) ) {
2553 *ordinal
= it
->second
;
2560 uint32_t OutputFile::dylibToOrdinal(const ld::dylib::File
* dylib
)
2562 return _dylibToOrdinal
[dylib
];
2566 void OutputFile::buildDylibOrdinalMapping(ld::Internal
& state
)
2568 // count non-public re-exported dylibs
2569 unsigned int nonPublicReExportCount
= 0;
2570 for (std::vector
<ld::dylib::File
*>::iterator it
= state
.dylibs
.begin(); it
!= state
.dylibs
.end(); ++it
) {
2571 ld::dylib::File
* aDylib
= *it
;
2572 if ( aDylib
->willBeReExported() && ! aDylib
->hasPublicInstallName() )
2573 ++nonPublicReExportCount
;
2576 // look at each dylib supplied in state
2577 bool hasReExports
= false;
2578 bool haveLazyDylibs
= false;
2579 for (std::vector
<ld::dylib::File
*>::iterator it
= state
.dylibs
.begin(); it
!= state
.dylibs
.end(); ++it
) {
2580 ld::dylib::File
* aDylib
= *it
;
2582 if ( aDylib
== state
.bundleLoader
) {
2583 _dylibToOrdinal
[aDylib
] = BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE
;
2585 else if ( this->hasOrdinalForInstallPath(aDylib
->installPath(), &ordinal
) ) {
2586 // already have a dylib with that install path, map all uses to that ordinal
2587 _dylibToOrdinal
[aDylib
] = ordinal
;
2589 else if ( aDylib
->willBeLazyLoadedDylib() ) {
2590 // all lazy dylib need to be at end of ordinals
2591 haveLazyDylibs
= true;
2593 else if ( aDylib
->willBeReExported() && ! aDylib
->hasPublicInstallName() && (nonPublicReExportCount
>= 2) ) {
2594 _dylibsToLoad
.push_back(aDylib
);
2595 _dylibToOrdinal
[aDylib
] = BIND_SPECIAL_DYLIB_SELF
;
2598 // first time this install path seen, create new ordinal
2599 _dylibsToLoad
.push_back(aDylib
);
2600 _dylibToOrdinal
[aDylib
] = _dylibsToLoad
.size();
2602 if ( aDylib
->explicitlyLinked() && aDylib
->willBeReExported() )
2603 hasReExports
= true;
2605 if ( haveLazyDylibs
) {
2606 // second pass to determine ordinals for lazy loaded dylibs
2607 for (std::vector
<ld::dylib::File
*>::iterator it
= state
.dylibs
.begin(); it
!= state
.dylibs
.end(); ++it
) {
2608 ld::dylib::File
* aDylib
= *it
;
2609 if ( aDylib
->willBeLazyLoadedDylib() ) {
2611 if ( this->hasOrdinalForInstallPath(aDylib
->installPath(), &ordinal
) ) {
2612 // already have a dylib with that install path, map all uses to that ordinal
2613 _dylibToOrdinal
[aDylib
] = ordinal
;
2616 // first time this install path seen, create new ordinal
2617 _dylibsToLoad
.push_back(aDylib
);
2618 _dylibToOrdinal
[aDylib
] = _dylibsToLoad
.size();
2623 _noReExportedDylibs
= !hasReExports
;
2624 //fprintf(stderr, "dylibs:\n");
2625 //for (std::map<const ld::dylib::File*, int>::const_iterator it = _dylibToOrdinal.begin(); it != _dylibToOrdinal.end(); ++it) {
2626 // fprintf(stderr, " %p ord=%u, install_name=%s\n",it->first, it->second, it->first->installPath());
2630 uint32_t OutputFile::lazyBindingInfoOffsetForLazyPointerAddress(uint64_t lpAddress
)
2632 return _lazyPointerAddressToInfoOffset
[lpAddress
];
2635 void OutputFile::setLazyBindingInfoOffset(uint64_t lpAddress
, uint32_t lpInfoOffset
)
2637 _lazyPointerAddressToInfoOffset
[lpAddress
] = lpInfoOffset
;
2640 int OutputFile::compressedOrdinalForAtom(const ld::Atom
* target
)
2642 // flat namespace images use zero for all ordinals
2643 if ( _options
.nameSpace() != Options::kTwoLevelNameSpace
)
2644 return BIND_SPECIAL_DYLIB_FLAT_LOOKUP
;
2646 // handle -interposable
2647 if ( target
->definition() == ld::Atom::definitionRegular
)
2648 return BIND_SPECIAL_DYLIB_SELF
;
2651 const ld::dylib::File
* dylib
= dynamic_cast<const ld::dylib::File
*>(target
->file());
2652 if ( dylib
!= NULL
) {
2653 std::map
<const ld::dylib::File
*, int>::iterator pos
= _dylibToOrdinal
.find(dylib
);
2654 if ( pos
!= _dylibToOrdinal
.end() )
2656 assert(0 && "dylib not assigned ordinal");
2659 // handle undefined dynamic_lookup
2660 if ( _options
.undefinedTreatment() == Options::kUndefinedDynamicLookup
)
2661 return BIND_SPECIAL_DYLIB_FLAT_LOOKUP
;
2664 if ( _options
.allowedUndefined(target
->name()) )
2665 return BIND_SPECIAL_DYLIB_FLAT_LOOKUP
;
2667 throw "can't find ordinal for imported symbol";
2671 bool OutputFile::isPcRelStore(ld::Fixup::Kind kind
)
2674 case ld::Fixup::kindStoreX86BranchPCRel8
:
2675 case ld::Fixup::kindStoreX86BranchPCRel32
:
2676 case ld::Fixup::kindStoreX86PCRel8
:
2677 case ld::Fixup::kindStoreX86PCRel16
:
2678 case ld::Fixup::kindStoreX86PCRel32
:
2679 case ld::Fixup::kindStoreX86PCRel32_1
:
2680 case ld::Fixup::kindStoreX86PCRel32_2
:
2681 case ld::Fixup::kindStoreX86PCRel32_4
:
2682 case ld::Fixup::kindStoreX86PCRel32GOTLoad
:
2683 case ld::Fixup::kindStoreX86PCRel32GOTLoadNowLEA
:
2684 case ld::Fixup::kindStoreX86PCRel32GOT
:
2685 case ld::Fixup::kindStoreX86PCRel32TLVLoad
:
2686 case ld::Fixup::kindStoreX86PCRel32TLVLoadNowLEA
:
2687 case ld::Fixup::kindStoreARMBranch24
:
2688 case ld::Fixup::kindStoreThumbBranch22
:
2689 case ld::Fixup::kindStoreARMLoad12
:
2690 case ld::Fixup::kindStoreTargetAddressX86PCRel32
:
2691 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad
:
2692 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA
:
2693 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoad
:
2694 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoadNowLEA
:
2695 case ld::Fixup::kindStoreTargetAddressARMBranch24
:
2696 case ld::Fixup::kindStoreTargetAddressThumbBranch22
:
2697 case ld::Fixup::kindStoreTargetAddressARMLoad12
:
2698 #if SUPPORT_ARCH_arm64
2699 case ld::Fixup::kindStoreARM64Page21
:
2700 case ld::Fixup::kindStoreARM64PageOff12
:
2701 case ld::Fixup::kindStoreARM64GOTLoadPage21
:
2702 case ld::Fixup::kindStoreARM64GOTLoadPageOff12
:
2703 case ld::Fixup::kindStoreARM64GOTLeaPage21
:
2704 case ld::Fixup::kindStoreARM64GOTLeaPageOff12
:
2705 case ld::Fixup::kindStoreARM64PCRelToGOT
:
2706 case ld::Fixup::kindStoreTargetAddressARM64Page21
:
2707 case ld::Fixup::kindStoreTargetAddressARM64PageOff12
:
2708 case ld::Fixup::kindStoreTargetAddressARM64GOTLoadPage21
:
2709 case ld::Fixup::kindStoreTargetAddressARM64GOTLoadPageOff12
:
2710 case ld::Fixup::kindStoreTargetAddressARM64GOTLeaPage21
:
2711 case ld::Fixup::kindStoreTargetAddressARM64GOTLeaPageOff12
:
2714 case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32
:
2715 #if SUPPORT_ARCH_arm64
2716 case ld::Fixup::kindStoreTargetAddressARM64Branch26
:
2718 return (_options
.outputKind() != Options::kKextBundle
);
2725 bool OutputFile::isStore(ld::Fixup::Kind kind
)
2728 case ld::Fixup::kindNone
:
2729 case ld::Fixup::kindNoneFollowOn
:
2730 case ld::Fixup::kindNoneGroupSubordinate
:
2731 case ld::Fixup::kindNoneGroupSubordinateFDE
:
2732 case ld::Fixup::kindNoneGroupSubordinateLSDA
:
2733 case ld::Fixup::kindNoneGroupSubordinatePersonality
:
2734 case ld::Fixup::kindSetTargetAddress
:
2735 case ld::Fixup::kindSubtractTargetAddress
:
2736 case ld::Fixup::kindAddAddend
:
2737 case ld::Fixup::kindSubtractAddend
:
2738 case ld::Fixup::kindSetTargetImageOffset
:
2739 case ld::Fixup::kindSetTargetSectionOffset
:
2748 bool OutputFile::setsTarget(ld::Fixup::Kind kind
)
2751 case ld::Fixup::kindSetTargetAddress
:
2752 case ld::Fixup::kindLazyTarget
:
2753 case ld::Fixup::kindStoreTargetAddressLittleEndian32
:
2754 case ld::Fixup::kindStoreTargetAddressLittleEndian64
:
2755 case ld::Fixup::kindStoreTargetAddressBigEndian32
:
2756 case ld::Fixup::kindStoreTargetAddressBigEndian64
:
2757 case ld::Fixup::kindStoreTargetAddressX86PCRel32
:
2758 case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32
:
2759 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad
:
2760 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA
:
2761 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoad
:
2762 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoadNowLEA
:
2763 case ld::Fixup::kindStoreTargetAddressX86Abs32TLVLoad
:
2764 case ld::Fixup::kindStoreTargetAddressARMBranch24
:
2765 case ld::Fixup::kindStoreTargetAddressThumbBranch22
:
2766 case ld::Fixup::kindStoreTargetAddressARMLoad12
:
2767 #if SUPPORT_ARCH_arm64
2768 case ld::Fixup::kindStoreTargetAddressARM64Branch26
:
2769 case ld::Fixup::kindStoreTargetAddressARM64Page21
:
2770 case ld::Fixup::kindStoreTargetAddressARM64PageOff12
:
2771 case ld::Fixup::kindStoreTargetAddressARM64GOTLoadPage21
:
2772 case ld::Fixup::kindStoreTargetAddressARM64GOTLoadPageOff12
:
2773 case ld::Fixup::kindStoreTargetAddressARM64GOTLeaPage21
:
2774 case ld::Fixup::kindStoreTargetAddressARM64GOTLeaPageOff12
:
2777 case ld::Fixup::kindStoreX86DtraceCallSiteNop
:
2778 case ld::Fixup::kindStoreX86DtraceIsEnableSiteClear
:
2779 case ld::Fixup::kindStoreARMDtraceCallSiteNop
:
2780 case ld::Fixup::kindStoreARMDtraceIsEnableSiteClear
:
2781 case ld::Fixup::kindStoreARM64DtraceCallSiteNop
:
2782 case ld::Fixup::kindStoreARM64DtraceIsEnableSiteClear
:
2783 case ld::Fixup::kindStoreThumbDtraceCallSiteNop
:
2784 case ld::Fixup::kindStoreThumbDtraceIsEnableSiteClear
:
2785 return (_options
.outputKind() == Options::kObjectFile
);
2792 bool OutputFile::isPointerToTarget(ld::Fixup::Kind kind
)
2795 case ld::Fixup::kindSetTargetAddress
:
2796 case ld::Fixup::kindStoreTargetAddressLittleEndian32
:
2797 case ld::Fixup::kindStoreTargetAddressLittleEndian64
:
2798 case ld::Fixup::kindStoreTargetAddressBigEndian32
:
2799 case ld::Fixup::kindStoreTargetAddressBigEndian64
:
2800 case ld::Fixup::kindLazyTarget
:
2807 bool OutputFile::isPointerFromTarget(ld::Fixup::Kind kind
)
2810 case ld::Fixup::kindSubtractTargetAddress
:
2819 uint64_t OutputFile::lookBackAddend(ld::Fixup::iterator fit
)
2821 uint64_t addend
= 0;
2822 switch ( fit
->clusterSize
) {
2823 case ld::Fixup::k1of1
:
2824 case ld::Fixup::k1of2
:
2825 case ld::Fixup::k2of2
:
2827 case ld::Fixup::k2of3
:
2829 switch ( fit
->kind
) {
2830 case ld::Fixup::kindAddAddend
:
2831 addend
+= fit
->u
.addend
;
2833 case ld::Fixup::kindSubtractAddend
:
2834 addend
-= fit
->u
.addend
;
2837 throw "unexpected fixup kind for binding";
2840 case ld::Fixup::k1of3
:
2842 switch ( fit
->kind
) {
2843 case ld::Fixup::kindAddAddend
:
2844 addend
+= fit
->u
.addend
;
2846 case ld::Fixup::kindSubtractAddend
:
2847 addend
-= fit
->u
.addend
;
2850 throw "unexpected fixup kind for binding";
2854 throw "unexpected fixup cluster size for binding";
2863 void OutputFile::generateLinkEditInfo(ld::Internal
& state
)
2865 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
2866 ld::Internal::FinalSection
* sect
= *sit
;
2867 bool objc1ClassRefSection
= ( (sect
->type() == ld::Section::typeCStringPointer
)
2868 && (strcmp(sect
->sectionName(), "__cls_refs") == 0)
2869 && (strcmp(sect
->segmentName(), "__OBJC") == 0) );
2870 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
2871 const ld::Atom
* atom
= *ait
;
2873 // Record regular atoms that override a dylib's weak definitions
2874 if ( (atom
->scope() == ld::Atom::scopeGlobal
) && atom
->overridesDylibsWeakDef() ) {
2875 if ( _options
.makeCompressedDyldInfo() ) {
2876 uint8_t wtype
= BIND_TYPE_OVERRIDE_OF_WEAKDEF_IN_DYLIB
;
2877 bool nonWeakDef
= (atom
->combine() == ld::Atom::combineNever
);
2878 _weakBindingInfo
.push_back(BindingInfo(wtype
, atom
->name(), nonWeakDef
, atom
->finalAddress(), 0));
2880 this->overridesWeakExternalSymbols
= true;
2881 if ( _options
.warnWeakExports() )
2882 warning("overrides weak external symbol: %s", atom
->name());
2885 ld::Fixup
* fixupWithTarget
= NULL
;
2886 ld::Fixup
* fixupWithMinusTarget
= NULL
;
2887 ld::Fixup
* fixupWithStore
= NULL
;
2888 ld::Fixup
* fixupWithAddend
= NULL
;
2889 const ld::Atom
* target
= NULL
;
2890 const ld::Atom
* minusTarget
= NULL
;
2891 uint64_t targetAddend
= 0;
2892 uint64_t minusTargetAddend
= 0;
2893 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(); fit
!= atom
->fixupsEnd(); ++fit
) {
2894 if ( fit
->firstInCluster() ) {
2895 fixupWithTarget
= NULL
;
2896 fixupWithMinusTarget
= NULL
;
2897 fixupWithStore
= NULL
;
2901 minusTargetAddend
= 0;
2903 if ( this->setsTarget(fit
->kind
) ) {
2904 switch ( fit
->binding
) {
2905 case ld::Fixup::bindingNone
:
2906 case ld::Fixup::bindingByNameUnbound
:
2908 case ld::Fixup::bindingByContentBound
:
2909 case ld::Fixup::bindingDirectlyBound
:
2910 fixupWithTarget
= fit
;
2911 target
= fit
->u
.target
;
2913 case ld::Fixup::bindingsIndirectlyBound
:
2914 fixupWithTarget
= fit
;
2915 target
= state
.indirectBindingTable
[fit
->u
.bindingIndex
];
2918 assert(target
!= NULL
);
2920 switch ( fit
->kind
) {
2921 case ld::Fixup::kindAddAddend
:
2922 targetAddend
= fit
->u
.addend
;
2923 fixupWithAddend
= fit
;
2925 case ld::Fixup::kindSubtractAddend
:
2926 minusTargetAddend
= fit
->u
.addend
;
2927 fixupWithAddend
= fit
;
2929 case ld::Fixup::kindSubtractTargetAddress
:
2930 switch ( fit
->binding
) {
2931 case ld::Fixup::bindingNone
:
2932 case ld::Fixup::bindingByNameUnbound
:
2934 case ld::Fixup::bindingByContentBound
:
2935 case ld::Fixup::bindingDirectlyBound
:
2936 fixupWithMinusTarget
= fit
;
2937 minusTarget
= fit
->u
.target
;
2939 case ld::Fixup::bindingsIndirectlyBound
:
2940 fixupWithMinusTarget
= fit
;
2941 minusTarget
= state
.indirectBindingTable
[fit
->u
.bindingIndex
];
2944 assert(minusTarget
!= NULL
);
2946 case ld::Fixup::kindDataInCodeStartData
:
2947 case ld::Fixup::kindDataInCodeStartJT8
:
2948 case ld::Fixup::kindDataInCodeStartJT16
:
2949 case ld::Fixup::kindDataInCodeStartJT32
:
2950 case ld::Fixup::kindDataInCodeStartJTA32
:
2951 case ld::Fixup::kindDataInCodeEnd
:
2952 hasDataInCode
= true;
2957 if ( this->isStore(fit
->kind
) ) {
2958 fixupWithStore
= fit
;
2960 if ( fit
->lastInCluster() ) {
2961 if ( (fixupWithStore
!= NULL
) && (target
!= NULL
) ) {
2962 if ( _options
.outputKind() == Options::kObjectFile
) {
2963 this->addSectionRelocs(state
, sect
, atom
, fixupWithTarget
, fixupWithMinusTarget
, fixupWithAddend
, fixupWithStore
,
2964 target
, minusTarget
, targetAddend
, minusTargetAddend
);
2967 if ( _options
.makeCompressedDyldInfo() ) {
2968 this->addDyldInfo(state
, sect
, atom
, fixupWithTarget
, fixupWithMinusTarget
, fixupWithStore
,
2969 target
, minusTarget
, targetAddend
, minusTargetAddend
);
2972 this->addClassicRelocs(state
, sect
, atom
, fixupWithTarget
, fixupWithMinusTarget
, fixupWithStore
,
2973 target
, minusTarget
, targetAddend
, minusTargetAddend
);
2977 else if ( objc1ClassRefSection
&& (target
!= NULL
) && (fixupWithStore
== NULL
) ) {
2978 // check for class refs to lazy loaded dylibs
2979 const ld::dylib::File
* dylib
= dynamic_cast<const ld::dylib::File
*>(target
->file());
2980 if ( (dylib
!= NULL
) && dylib
->willBeLazyLoadedDylib() )
2981 throwf("illegal class reference to %s in lazy loaded dylib %s", target
->name(), dylib
->path());
2990 void OutputFile::noteTextReloc(const ld::Atom
* atom
, const ld::Atom
* target
)
2992 if ( (atom
->contentType() == ld::Atom::typeStub
) || (atom
->contentType() == ld::Atom::typeStubHelper
) ) {
2993 // silently let stubs (synthesized by linker) use text relocs
2995 else if ( _options
.allowTextRelocs() ) {
2996 if ( _options
.warnAboutTextRelocs() )
2997 warning("text reloc in %s to %s", atom
->name(), target
->name());
2999 else if ( _options
.positionIndependentExecutable() && (_options
.outputKind() == Options::kDynamicExecutable
)
3000 && ((_options
.iOSVersionMin() >= ld::iOS_4_3
) || (_options
.macosxVersionMin() >= ld::mac10_7
)) ) {
3001 if ( ! this->pieDisabled
) {
3002 #if SUPPORT_ARCH_arm64
3003 if ( _options
.architecture() == CPU_TYPE_ARM64
) {
3004 const char* demangledName
= strdup(_options
.demangleSymbol(atom
->name()));
3005 throwf("Absolute addressing not allowed in arm64 code but used in '%s' referencing '%s'", demangledName
, _options
.demangleSymbol(target
->name()));
3010 warning("PIE disabled. Absolute addressing (perhaps -mdynamic-no-pic) not allowed in code signed PIE, "
3011 "but used in %s from %s. "
3012 "To fix this warning, don't compile with -mdynamic-no-pic or link with -Wl,-no_pie",
3013 atom
->name(), atom
->file()->path());
3016 this->pieDisabled
= true;
3018 else if ( (target
->scope() == ld::Atom::scopeGlobal
) && (target
->combine() == ld::Atom::combineByName
) ) {
3019 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());
3022 if ( (target
->file() != NULL
) && (atom
->file() != NULL
) )
3023 throwf("illegal text-relocation to '%s' in %s from '%s' in %s", target
->name(), target
->file()->path(), atom
->name(), atom
->file()->path());
3025 throwf("illegal text reloc in '%s' to '%s'", atom
->name(), target
->name());
3029 void OutputFile::addDyldInfo(ld::Internal
& state
, ld::Internal::FinalSection
* sect
, const ld::Atom
* atom
,
3030 ld::Fixup
* fixupWithTarget
, ld::Fixup
* fixupWithMinusTarget
, ld::Fixup
* fixupWithStore
,
3031 const ld::Atom
* target
, const ld::Atom
* minusTarget
,
3032 uint64_t targetAddend
, uint64_t minusTargetAddend
)
3034 if ( sect
->isSectionHidden() )
3037 // no need to rebase or bind PCRel stores
3038 if ( this->isPcRelStore(fixupWithStore
->kind
) ) {
3039 // as long as target is in same linkage unit
3040 if ( (target
== NULL
) || (target
->definition() != ld::Atom::definitionProxy
) ) {
3041 // make sure target is not global and weak
3042 if ( (target
->scope() == ld::Atom::scopeGlobal
) && (target
->combine() == ld::Atom::combineByName
) && (target
->definition() == ld::Atom::definitionRegular
)) {
3043 if ( (atom
->section().type() == ld::Section::typeCFI
)
3044 || (atom
->section().type() == ld::Section::typeDtraceDOF
)
3045 || (atom
->section().type() == ld::Section::typeUnwindInfo
) ) {
3046 // ok for __eh_frame and __uwind_info to use pointer diffs to global weak symbols
3049 // <rdar://problem/13700961> spurious warning when weak function has reference to itself
3050 if ( fixupWithTarget
->binding
== ld::Fixup::bindingDirectlyBound
) {
3051 // ok to ignore pc-rel references within a weak function to itself
3054 // Have direct reference to weak-global. This should be an indrect reference
3055 const char* demangledName
= strdup(_options
.demangleSymbol(atom
->name()));
3056 warning("direct access in %s to global weak symbol %s means the weak symbol cannot be overridden at runtime. "
3057 "This was likely caused by different translation units being compiled with different visibility settings.",
3058 demangledName
, _options
.demangleSymbol(target
->name()));
3064 // no need to rebase or bind PIC internal pointer diff
3065 if ( minusTarget
!= NULL
) {
3066 // with pointer diffs, both need to be in same linkage unit
3067 assert(minusTarget
->definition() != ld::Atom::definitionProxy
);
3068 assert(target
!= NULL
);
3069 assert(target
->definition() != ld::Atom::definitionProxy
);
3070 if ( target
== minusTarget
) {
3071 // This is a compile time constant and could have been optimized away by compiler
3075 // check if target of pointer-diff is global and weak
3076 if ( (target
->scope() == ld::Atom::scopeGlobal
) && (target
->combine() == ld::Atom::combineByName
) && (target
->definition() == ld::Atom::definitionRegular
) ) {
3077 if ( (atom
->section().type() == ld::Section::typeCFI
)
3078 || (atom
->section().type() == ld::Section::typeDtraceDOF
)
3079 || (atom
->section().type() == ld::Section::typeUnwindInfo
) ) {
3080 // ok for __eh_frame and __uwind_info to use pointer diffs to global weak symbols
3083 // Have direct reference to weak-global. This should be an indrect reference
3084 const char* demangledName
= strdup(_options
.demangleSymbol(atom
->name()));
3085 warning("direct access in %s to global weak symbol %s means the weak symbol cannot be overridden at runtime. "
3086 "This was likely caused by different translation units being compiled with different visibility settings.",
3087 demangledName
, _options
.demangleSymbol(target
->name()));
3092 // no need to rebase or bind an atom's references to itself if the output is not slidable
3093 if ( (atom
== target
) && !_options
.outputSlidable() )
3096 // cluster has no target, so needs no rebasing or binding
3097 if ( target
== NULL
)
3100 bool inReadOnlySeg
= ( strcmp(sect
->segmentName(), "__TEXT") == 0 );
3101 bool needsRebase
= false;
3102 bool needsBinding
= false;
3103 bool needsLazyBinding
= false;
3104 bool needsWeakBinding
= false;
3106 uint8_t rebaseType
= REBASE_TYPE_POINTER
;
3107 uint8_t type
= BIND_TYPE_POINTER
;
3108 const ld::dylib::File
* dylib
= dynamic_cast<const ld::dylib::File
*>(target
->file());
3109 bool weak_import
= (fixupWithTarget
->weakImport
|| ((dylib
!= NULL
) && dylib
->forcedWeakLinked()));
3110 uint64_t address
= atom
->finalAddress() + fixupWithTarget
->offsetInAtom
;
3111 uint64_t addend
= targetAddend
- minusTargetAddend
;
3113 // special case lazy pointers
3114 if ( fixupWithTarget
->kind
== ld::Fixup::kindLazyTarget
) {
3115 assert(fixupWithTarget
->u
.target
== target
);
3116 assert(addend
== 0);
3117 // lazy dylib lazy pointers do not have any dyld info
3118 if ( atom
->section().type() == ld::Section::typeLazyDylibPointer
)
3120 // lazy binding to weak definitions are done differently
3121 // they are directly bound to target, then have a weak bind in case of a collision
3122 if ( target
->combine() == ld::Atom::combineByName
) {
3123 if ( target
->definition() == ld::Atom::definitionProxy
) {
3124 // weak def exported from another dylib
3125 // must non-lazy bind to it plus have weak binding info in case of collision
3126 needsBinding
= true;
3127 needsWeakBinding
= true;
3130 // weak def in this linkage unit.
3131 // just rebase, plus have weak binding info in case of collision
3132 // this will be done by other cluster on lazy pointer atom
3135 else if ( target
->contentType() == ld::Atom::typeResolver
) {
3136 // <rdar://problem/8553647> Hidden resolver functions should not have lazy binding info
3137 // <rdar://problem/12629331> Resolver function run before initializers when overriding the dyld shared cache
3138 // The lazy pointers used by stubs used when non-lazy binding to a resolver are not normal lazy pointers
3139 // and should not be in lazy binding info.
3140 needsLazyBinding
= false;
3143 // normal case of a pointer to non-weak-def symbol, so can lazily bind
3144 needsLazyBinding
= true;
3148 // everything except lazy pointers
3149 switch ( target
->definition() ) {
3150 case ld::Atom::definitionProxy
:
3151 if ( (dylib
!= NULL
) && dylib
->willBeLazyLoadedDylib() )
3152 throwf("illegal data reference to %s in lazy loaded dylib %s", target
->name(), dylib
->path());
3153 if ( target
->contentType() == ld::Atom::typeTLV
) {
3154 if ( sect
->type() != ld::Section::typeTLVPointers
)
3155 throwf("illegal data reference in %s to thread local variable %s in dylib %s",
3156 atom
->name(), target
->name(), dylib
->path());
3158 if ( inReadOnlySeg
)
3159 type
= BIND_TYPE_TEXT_ABSOLUTE32
;
3160 needsBinding
= true;
3161 if ( target
->combine() == ld::Atom::combineByName
)
3162 needsWeakBinding
= true;
3164 case ld::Atom::definitionRegular
:
3165 case ld::Atom::definitionTentative
:
3166 // only slideable images need rebasing info
3167 if ( _options
.outputSlidable() ) {
3170 // references to internal symbol never need binding
3171 if ( target
->scope() != ld::Atom::scopeGlobal
)
3173 // reference to global weak def needs weak binding
3174 if ( (target
->combine() == ld::Atom::combineByName
) && (target
->definition() == ld::Atom::definitionRegular
) )
3175 needsWeakBinding
= true;
3176 else if ( _options
.outputKind() == Options::kDynamicExecutable
) {
3177 // in main executables, the only way regular symbols are indirected is if -interposable is used
3178 if ( _options
.interposable(target
->name()) ) {
3179 needsRebase
= false;
3180 needsBinding
= true;
3184 // for flat-namespace or interposable two-level-namespace
3185 // all references to exported symbols get indirected
3186 if ( (_options
.nameSpace() != Options::kTwoLevelNameSpace
) || _options
.interposable(target
->name()) ) {
3187 // <rdar://problem/5254468> no external relocs for flat objc classes
3188 if ( strncmp(target
->name(), ".objc_class_", 12) == 0 )
3190 // no rebase info for references to global symbols that will have binding info
3191 needsRebase
= false;
3192 needsBinding
= true;
3194 else if ( _options
.forceCoalesce(target
->name()) ) {
3195 needsWeakBinding
= true;
3199 case ld::Atom::definitionAbsolute
:
3204 // <rdar://problem/13828711> if target is an import alias, use base of alias
3205 if ( target
->isAlias() && (target
->definition() == ld::Atom::definitionProxy
) ) {
3206 for (ld::Fixup::iterator fit
= target
->fixupsBegin(), end
=target
->fixupsEnd(); fit
!= end
; ++fit
) {
3207 if ( fit
->firstInCluster() ) {
3208 if ( fit
->kind
== ld::Fixup::kindNoneFollowOn
) {
3209 if ( fit
->binding
== ld::Fixup::bindingDirectlyBound
) {
3210 //fprintf(stderr, "switching import of %s to import of %s\n", target->name(), fit->u.target->name());
3211 target
= fit
->u
.target
;
3218 // record dyld info for this cluster
3219 if ( needsRebase
) {
3220 if ( inReadOnlySeg
) {
3221 noteTextReloc(atom
, target
);
3222 sect
->hasLocalRelocs
= true; // so dyld knows to change permissions on __TEXT segment
3223 rebaseType
= REBASE_TYPE_TEXT_ABSOLUTE32
;
3225 if ( _options
.sharedRegionEligible() ) {
3226 // <rdar://problem/13287063> when range checking, ignore high byte of arm64 addends
3227 uint64_t checkAddend
= addend
;
3228 if ( _options
.architecture() == CPU_TYPE_ARM64
)
3229 checkAddend
&= 0x0FFFFFFFFFFFFFFFULL
;
3230 if ( checkAddend
!= 0 ) {
3231 // make sure the addend does not cause the pointer to point outside the target's segment
3232 // if it does, update_dyld_shared_cache will not be able to put this dylib into the shared cache
3233 uint64_t targetAddress
= target
->finalAddress();
3234 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
3235 ld::Internal::FinalSection
* sct
= *sit
;
3236 uint64_t sctEnd
= (sct
->address
+sct
->size
);
3237 if ( (sct
->address
<= targetAddress
) && (targetAddress
< sctEnd
) ) {
3238 if ( (targetAddress
+checkAddend
) > sctEnd
) {
3239 warning("data symbol %s from %s has pointer to %s + 0x%08llX. "
3240 "That large of an addend may disable %s from being put in the dyld shared cache.",
3241 atom
->name(), atom
->file()->path(), target
->name(), addend
, _options
.installPath() );
3247 _rebaseInfo
.push_back(RebaseInfo(rebaseType
, address
));
3249 if ( needsBinding
) {
3250 if ( inReadOnlySeg
) {
3251 noteTextReloc(atom
, target
);
3252 sect
->hasExternalRelocs
= true; // so dyld knows to change permissions on __TEXT segment
3254 _bindingInfo
.push_back(BindingInfo(type
, this->compressedOrdinalForAtom(target
), target
->name(), weak_import
, address
, addend
));
3256 if ( needsLazyBinding
) {
3257 if ( _options
.bindAtLoad() )
3258 _bindingInfo
.push_back(BindingInfo(type
, this->compressedOrdinalForAtom(target
), target
->name(), weak_import
, address
, addend
));
3260 _lazyBindingInfo
.push_back(BindingInfo(type
, this->compressedOrdinalForAtom(target
), target
->name(), weak_import
, address
, addend
));
3262 if ( needsWeakBinding
)
3263 _weakBindingInfo
.push_back(BindingInfo(type
, 0, target
->name(), false, address
, addend
));
3267 void OutputFile::addClassicRelocs(ld::Internal
& state
, ld::Internal::FinalSection
* sect
, const ld::Atom
* atom
,
3268 ld::Fixup
* fixupWithTarget
, ld::Fixup
* fixupWithMinusTarget
, ld::Fixup
* fixupWithStore
,
3269 const ld::Atom
* target
, const ld::Atom
* minusTarget
,
3270 uint64_t targetAddend
, uint64_t minusTargetAddend
)
3272 if ( sect
->isSectionHidden() )
3275 // non-lazy-pointer section is encoded in indirect symbol table - not using relocations
3276 if ( sect
->type() == ld::Section::typeNonLazyPointer
) {
3277 // except kexts and static pie which *do* use relocations
3278 switch (_options
.outputKind()) {
3279 case Options::kKextBundle
:
3281 case Options::kStaticExecutable
:
3282 if ( _options
.positionIndependentExecutable() )
3284 // else fall into default case
3286 assert(target
!= NULL
);
3287 assert(fixupWithTarget
!= NULL
);
3292 // no need to rebase or bind PCRel stores
3293 if ( this->isPcRelStore(fixupWithStore
->kind
) ) {
3294 // as long as target is in same linkage unit
3295 if ( (target
== NULL
) || (target
->definition() != ld::Atom::definitionProxy
) )
3299 // no need to rebase or bind PIC internal pointer diff
3300 if ( minusTarget
!= NULL
) {
3301 // with pointer diffs, both need to be in same linkage unit
3302 assert(minusTarget
->definition() != ld::Atom::definitionProxy
);
3303 assert(target
!= NULL
);
3304 assert(target
->definition() != ld::Atom::definitionProxy
);
3305 // make sure target is not global and weak
3306 if ( (target
->scope() == ld::Atom::scopeGlobal
) && (target
->combine() == ld::Atom::combineByName
)
3307 && (atom
->section().type() != ld::Section::typeCFI
)
3308 && (atom
->section().type() != ld::Section::typeDtraceDOF
)
3309 && (atom
->section().type() != ld::Section::typeUnwindInfo
)
3310 && (minusTarget
!= target
) ) {
3311 // ok for __eh_frame and __uwind_info to use pointer diffs to global weak symbols
3312 throwf("bad codegen, pointer diff in %s to global weak symbol %s", atom
->name(), target
->name());
3317 // cluster has no target, so needs no rebasing or binding
3318 if ( target
== NULL
)
3321 assert(_localRelocsAtom
!= NULL
);
3322 uint64_t relocAddress
= atom
->finalAddress() + fixupWithTarget
->offsetInAtom
- _localRelocsAtom
->relocBaseAddress(state
);
3324 bool inReadOnlySeg
= ( strcmp(sect
->segmentName(), "__TEXT") == 0 );
3325 bool needsLocalReloc
= false;
3326 bool needsExternReloc
= false;
3328 switch ( fixupWithStore
->kind
) {
3329 case ld::Fixup::kindLazyTarget
:
3330 // lazy pointers don't need relocs
3332 case ld::Fixup::kindStoreLittleEndian32
:
3333 case ld::Fixup::kindStoreLittleEndian64
:
3334 case ld::Fixup::kindStoreBigEndian32
:
3335 case ld::Fixup::kindStoreBigEndian64
:
3336 case ld::Fixup::kindStoreTargetAddressLittleEndian32
:
3337 case ld::Fixup::kindStoreTargetAddressLittleEndian64
:
3338 case ld::Fixup::kindStoreTargetAddressBigEndian32
:
3339 case ld::Fixup::kindStoreTargetAddressBigEndian64
:
3341 switch ( target
->definition() ) {
3342 case ld::Atom::definitionProxy
:
3343 needsExternReloc
= true;
3345 case ld::Atom::definitionRegular
:
3346 case ld::Atom::definitionTentative
:
3347 // only slideable images need local relocs
3348 if ( _options
.outputSlidable() )
3349 needsLocalReloc
= true;
3350 // references to internal symbol never need binding
3351 if ( target
->scope() != ld::Atom::scopeGlobal
)
3353 // reference to global weak def needs weak binding in dynamic images
3354 if ( (target
->combine() == ld::Atom::combineByName
)
3355 && (target
->definition() == ld::Atom::definitionRegular
)
3356 && (_options
.outputKind() != Options::kStaticExecutable
)
3357 && (_options
.outputKind() != Options::kPreload
)
3358 && (atom
!= target
) ) {
3359 needsExternReloc
= true;
3361 else if ( _options
.outputKind() == Options::kDynamicExecutable
) {
3362 // in main executables, the only way regular symbols are indirected is if -interposable is used
3363 if ( _options
.interposable(target
->name()) )
3364 needsExternReloc
= true;
3367 // for flat-namespace or interposable two-level-namespace
3368 // all references to exported symbols get indirected
3369 if ( (_options
.nameSpace() != Options::kTwoLevelNameSpace
) || _options
.interposable(target
->name()) ) {
3370 // <rdar://problem/5254468> no external relocs for flat objc classes
3371 if ( strncmp(target
->name(), ".objc_class_", 12) == 0 )
3373 // no rebase info for references to global symbols that will have binding info
3374 needsExternReloc
= true;
3377 if ( needsExternReloc
)
3378 needsLocalReloc
= false;
3380 case ld::Atom::definitionAbsolute
:
3383 if ( needsExternReloc
) {
3384 if ( inReadOnlySeg
)
3385 noteTextReloc(atom
, target
);
3386 const ld::dylib::File
* dylib
= dynamic_cast<const ld::dylib::File
*>(target
->file());
3387 if ( (dylib
!= NULL
) && dylib
->willBeLazyLoadedDylib() )
3388 throwf("illegal data reference to %s in lazy loaded dylib %s", target
->name(), dylib
->path());
3389 _externalRelocsAtom
->addExternalPointerReloc(relocAddress
, target
);
3390 sect
->hasExternalRelocs
= true;
3391 fixupWithTarget
->contentAddendOnly
= true;
3393 else if ( needsLocalReloc
) {
3394 assert(target
!= NULL
);
3395 if ( inReadOnlySeg
)
3396 noteTextReloc(atom
, target
);
3397 _localRelocsAtom
->addPointerReloc(relocAddress
, target
->machoSection());
3398 sect
->hasLocalRelocs
= true;
3401 case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32
:
3402 #if SUPPORT_ARCH_arm64
3403 case ld::Fixup::kindStoreTargetAddressARM64Branch26
:
3405 if ( _options
.outputKind() == Options::kKextBundle
) {
3406 assert(target
!= NULL
);
3407 if ( target
->definition() == ld::Atom::definitionProxy
) {
3408 _externalRelocsAtom
->addExternalCallSiteReloc(relocAddress
, target
);
3409 fixupWithStore
->contentAddendOnly
= true;
3414 case ld::Fixup::kindStoreARMLow16
:
3415 case ld::Fixup::kindStoreThumbLow16
:
3416 // no way to encode rebasing of binding for these instructions
3417 if ( _options
.outputSlidable() || (target
->definition() == ld::Atom::definitionProxy
) )
3418 throwf("no supported runtime lo16 relocation in %s from %s to %s", atom
->name(), atom
->file()->path(), target
->name());
3421 case ld::Fixup::kindStoreARMHigh16
:
3422 case ld::Fixup::kindStoreThumbHigh16
:
3423 // no way to encode rebasing of binding for these instructions
3424 if ( _options
.outputSlidable() || (target
->definition() == ld::Atom::definitionProxy
) )
3425 throwf("no supported runtime hi16 relocation in %s from %s to %s", atom
->name(), atom
->file()->path(), target
->name());
3434 bool OutputFile::useExternalSectionReloc(const ld::Atom
* atom
, const ld::Atom
* target
, ld::Fixup
* fixupWithTarget
)
3436 if ( (_options
.architecture() == CPU_TYPE_X86_64
) || (_options
.architecture() == CPU_TYPE_ARM64
) ) {
3437 // x86_64 and ARM64 use external relocations for everthing that has a symbol
3438 return ( target
->symbolTableInclusion() != ld::Atom::symbolTableNotIn
);
3441 // <rdar://problem/9513487> support arm branch interworking in -r mode
3442 if ( (_options
.architecture() == CPU_TYPE_ARM
) && (_options
.outputKind() == Options::kObjectFile
) ) {
3443 if ( atom
->isThumb() != target
->isThumb() ) {
3444 switch ( fixupWithTarget
->kind
) {
3445 // have branch that switches mode, then might be 'b' not 'bl'
3446 // Force external relocation, since no way to do local reloc for 'b'
3447 case ld::Fixup::kindStoreTargetAddressThumbBranch22
:
3448 case ld::Fixup::kindStoreTargetAddressARMBranch24
:
3456 if ( (_options
.architecture() == CPU_TYPE_I386
) && (_options
.outputKind() == Options::kObjectFile
) ) {
3457 if ( target
->contentType() == ld::Atom::typeTLV
)
3461 // most architectures use external relocations only for references
3462 // to a symbol in another translation unit or for references to "weak symbols" or tentative definitions
3463 assert(target
!= NULL
);
3464 if ( target
->definition() == ld::Atom::definitionProxy
)
3466 if ( (target
->definition() == ld::Atom::definitionTentative
) && ! _options
.makeTentativeDefinitionsReal() )
3468 if ( target
->scope() != ld::Atom::scopeGlobal
)
3470 if ( (target
->combine() == ld::Atom::combineByName
) && (target
->definition() == ld::Atom::definitionRegular
) )
3475 bool OutputFile::useSectionRelocAddend(ld::Fixup
* fixupWithTarget
)
3477 #if SUPPORT_ARCH_arm64
3478 if ( _options
.architecture() == CPU_TYPE_ARM64
) {
3479 switch ( fixupWithTarget
->kind
) {
3480 case ld::Fixup::kindStoreARM64Branch26
:
3481 case ld::Fixup::kindStoreARM64Page21
:
3482 case ld::Fixup::kindStoreARM64PageOff12
:
3495 void OutputFile::addSectionRelocs(ld::Internal
& state
, ld::Internal::FinalSection
* sect
, const ld::Atom
* atom
,
3496 ld::Fixup
* fixupWithTarget
, ld::Fixup
* fixupWithMinusTarget
,
3497 ld::Fixup
* fixupWithAddend
, ld::Fixup
* fixupWithStore
,
3498 const ld::Atom
* target
, const ld::Atom
* minusTarget
,
3499 uint64_t targetAddend
, uint64_t minusTargetAddend
)
3501 if ( sect
->isSectionHidden() )
3504 // in -r mode where there will be no labels on __eh_frame section, there is no need for relocations
3505 if ( (sect
->type() == ld::Section::typeCFI
) && _options
.removeEHLabels() )
3508 // non-lazy-pointer section is encoded in indirect symbol table - not using relocations
3509 if ( sect
->type() == ld::Section::typeNonLazyPointer
)
3512 // tentative defs don't have any relocations
3513 if ( sect
->type() == ld::Section::typeTentativeDefs
)
3516 assert(target
!= NULL
);
3517 assert(fixupWithTarget
!= NULL
);
3518 bool targetUsesExternalReloc
= this->useExternalSectionReloc(atom
, target
, fixupWithTarget
);
3519 bool minusTargetUsesExternalReloc
= (minusTarget
!= NULL
) && this->useExternalSectionReloc(atom
, minusTarget
, fixupWithMinusTarget
);
3521 // in x86_64 and arm64 .o files an external reloc means the content contains just the addend
3522 if ( (_options
.architecture() == CPU_TYPE_X86_64
) ||(_options
.architecture() == CPU_TYPE_ARM64
) ) {
3523 if ( targetUsesExternalReloc
) {
3524 fixupWithTarget
->contentAddendOnly
= true;
3525 fixupWithStore
->contentAddendOnly
= true;
3526 if ( this->useSectionRelocAddend(fixupWithStore
) && (fixupWithAddend
!= NULL
) )
3527 fixupWithAddend
->contentIgnoresAddend
= true;
3529 if ( minusTargetUsesExternalReloc
)
3530 fixupWithMinusTarget
->contentAddendOnly
= true;
3533 // for other archs, content is addend only with (non pc-rel) pointers
3534 // pc-rel instructions are funny. If the target is _foo+8 and _foo is
3535 // external, then the pc-rel instruction *evalutates* to the address 8.
3536 if ( targetUsesExternalReloc
) {
3537 // TLV support for i386 acts like RIP relative addressing
3538 // The addend is the offset from the PICBase to the end of the instruction
3539 if ( (_options
.architecture() == CPU_TYPE_I386
)
3540 && (_options
.outputKind() == Options::kObjectFile
)
3541 && (fixupWithStore
->kind
== ld::Fixup::kindStoreX86PCRel32TLVLoad
) ) {
3542 fixupWithTarget
->contentAddendOnly
= true;
3543 fixupWithStore
->contentAddendOnly
= true;
3545 else if ( isPcRelStore(fixupWithStore
->kind
) ) {
3546 fixupWithTarget
->contentDetlaToAddendOnly
= true;
3547 fixupWithStore
->contentDetlaToAddendOnly
= true;
3549 else if ( minusTarget
== NULL
){
3550 fixupWithTarget
->contentAddendOnly
= true;
3551 fixupWithStore
->contentAddendOnly
= true;
3556 if ( fixupWithStore
!= NULL
) {
3557 _sectionsRelocationsAtom
->addSectionReloc(sect
, fixupWithStore
->kind
, atom
, fixupWithStore
->offsetInAtom
,
3558 targetUsesExternalReloc
, minusTargetUsesExternalReloc
,
3559 target
, targetAddend
, minusTarget
, minusTargetAddend
);
3565 void OutputFile::makeSplitSegInfo(ld::Internal
& state
)
3567 if ( !_options
.sharedRegionEligible() )
3570 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
3571 ld::Internal::FinalSection
* sect
= *sit
;
3572 if ( sect
->isSectionHidden() )
3574 if ( strcmp(sect
->segmentName(), "__TEXT") != 0 )
3576 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
3577 const ld::Atom
* atom
= *ait
;
3578 const ld::Atom
* target
= NULL
;
3579 const ld::Atom
* fromTarget
= NULL
;
3580 uint64_t accumulator
= 0;
3582 bool hadSubtract
= false;
3583 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(), end
=atom
->fixupsEnd(); fit
!= end
; ++fit
) {
3584 if ( fit
->firstInCluster() )
3586 if ( this->setsTarget(fit
->kind
) ) {
3587 accumulator
= addressOf(state
, fit
, &target
);
3588 thumbTarget
= targetIsThumb(state
, fit
);
3592 switch ( fit
->kind
) {
3593 case ld::Fixup::kindSubtractTargetAddress
:
3594 accumulator
-= addressOf(state
, fit
, &fromTarget
);
3597 case ld::Fixup::kindAddAddend
:
3598 accumulator
+= fit
->u
.addend
;
3600 case ld::Fixup::kindSubtractAddend
:
3601 accumulator
-= fit
->u
.addend
;
3603 case ld::Fixup::kindStoreBigEndian32
:
3604 case ld::Fixup::kindStoreLittleEndian32
:
3605 case ld::Fixup::kindStoreLittleEndian64
:
3606 case ld::Fixup::kindStoreTargetAddressLittleEndian32
:
3607 case ld::Fixup::kindStoreTargetAddressLittleEndian64
:
3608 // if no subtract, then this is an absolute pointer which means
3609 // there is also a text reloc which update_dyld_shared_cache will use.
3610 if ( ! hadSubtract
)
3613 case ld::Fixup::kindStoreX86PCRel32
:
3614 case ld::Fixup::kindStoreX86PCRel32_1
:
3615 case ld::Fixup::kindStoreX86PCRel32_2
:
3616 case ld::Fixup::kindStoreX86PCRel32_4
:
3617 case ld::Fixup::kindStoreX86PCRel32GOTLoad
:
3618 case ld::Fixup::kindStoreX86PCRel32GOTLoadNowLEA
:
3619 case ld::Fixup::kindStoreX86PCRel32GOT
:
3620 case ld::Fixup::kindStoreX86PCRel32TLVLoad
:
3621 case ld::Fixup::kindStoreX86PCRel32TLVLoadNowLEA
:
3622 case ld::Fixup::kindStoreTargetAddressX86PCRel32
:
3623 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad
:
3624 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA
:
3625 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoad
:
3626 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoadNowLEA
:
3627 case ld::Fixup::kindStoreARMLow16
:
3628 case ld::Fixup::kindStoreThumbLow16
:
3629 #if SUPPORT_ARCH_arm64
3630 case ld::Fixup::kindStoreARM64Page21
:
3631 case ld::Fixup::kindStoreARM64GOTLoadPage21
:
3632 case ld::Fixup::kindStoreARM64GOTLeaPage21
:
3633 case ld::Fixup::kindStoreARM64TLVPLoadPage21
:
3634 case ld::Fixup::kindStoreTargetAddressARM64Page21
:
3635 case ld::Fixup::kindStoreTargetAddressARM64GOTLoadPage21
:
3636 case ld::Fixup::kindStoreTargetAddressARM64GOTLeaPage21
:
3637 case ld::Fixup::kindStoreARM64PCRelToGOT
:
3639 assert(target
!= NULL
);
3640 if ( strcmp(sect
->segmentName(), target
->section().segmentName()) != 0 ) {
3641 _splitSegInfos
.push_back(SplitSegInfoEntry(atom
->finalAddress()+fit
->offsetInAtom
,fit
->kind
));
3644 case ld::Fixup::kindStoreARMHigh16
:
3645 case ld::Fixup::kindStoreThumbHigh16
:
3646 assert(target
!= NULL
);
3647 if ( strcmp(sect
->segmentName(), target
->section().segmentName()) != 0 ) {
3648 // hi16 needs to know upper 4-bits of low16 to compute carry
3649 uint32_t extra
= (accumulator
>> 12) & 0xF;
3650 _splitSegInfos
.push_back(SplitSegInfoEntry(atom
->finalAddress()+fit
->offsetInAtom
,fit
->kind
, extra
));
3653 case ld::Fixup::kindSetTargetImageOffset
:
3654 accumulator
= addressOf(state
, fit
, &target
);
3655 assert(target
!= NULL
);
3667 void OutputFile::writeMapFile(ld::Internal
& state
)
3669 if ( _options
.generatedMapPath() != NULL
) {
3670 FILE* mapFile
= fopen(_options
.generatedMapPath(), "w");
3671 if ( mapFile
!= NULL
) {
3672 // write output path
3673 fprintf(mapFile
, "# Path: %s\n", _options
.outputFilePath());
3674 // write output architecure
3675 fprintf(mapFile
, "# Arch: %s\n", _options
.architectureName());
3677 //if ( fUUIDAtom != NULL ) {
3678 // const uint8_t* uuid = fUUIDAtom->getUUID();
3679 // fprintf(mapFile, "# UUID: %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X \n",
3680 // uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
3681 // uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
3683 // write table of object files
3684 std::map
<const ld::File
*, ld::File::Ordinal
> readerToOrdinal
;
3685 std::map
<ld::File::Ordinal
, const ld::File
*> ordinalToReader
;
3686 std::map
<const ld::File
*, uint32_t> readerToFileOrdinal
;
3687 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
3688 ld::Internal::FinalSection
* sect
= *sit
;
3689 if ( sect
->isSectionHidden() )
3691 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
3692 const ld::Atom
* atom
= *ait
;
3693 const ld::File
* reader
= atom
->file();
3694 if ( reader
== NULL
)
3696 ld::File::Ordinal readerOrdinal
= reader
->ordinal();
3697 std::map
<const ld::File
*, ld::File::Ordinal
>::iterator pos
= readerToOrdinal
.find(reader
);
3698 if ( pos
== readerToOrdinal
.end() ) {
3699 readerToOrdinal
[reader
] = readerOrdinal
;
3700 ordinalToReader
[readerOrdinal
] = reader
;
3704 fprintf(mapFile
, "# Object files:\n");
3705 fprintf(mapFile
, "[%3u] %s\n", 0, "linker synthesized");
3706 uint32_t fileIndex
= 1;
3707 for(std::map
<ld::File::Ordinal
, const ld::File
*>::iterator it
= ordinalToReader
.begin(); it
!= ordinalToReader
.end(); ++it
) {
3708 fprintf(mapFile
, "[%3u] %s\n", fileIndex
, it
->second
->path());
3709 readerToFileOrdinal
[it
->second
] = fileIndex
++;
3711 // write table of sections
3712 fprintf(mapFile
, "# Sections:\n");
3713 fprintf(mapFile
, "# Address\tSize \tSegment\tSection\n");
3714 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
3715 ld::Internal::FinalSection
* sect
= *sit
;
3716 if ( sect
->isSectionHidden() )
3718 fprintf(mapFile
, "0x%08llX\t0x%08llX\t%s\t%s\n", sect
->address
, sect
->size
,
3719 sect
->segmentName(), sect
->sectionName());
3721 // write table of symbols
3722 fprintf(mapFile
, "# Symbols:\n");
3723 fprintf(mapFile
, "# Address\tSize \tFile Name\n");
3724 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
3725 ld::Internal::FinalSection
* sect
= *sit
;
3726 if ( sect
->isSectionHidden() )
3728 //bool isCstring = (sect->type() == ld::Section::typeCString);
3729 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
3731 const ld::Atom
* atom
= *ait
;
3732 const char* name
= atom
->name();
3733 // don't add auto-stripped aliases to .map file
3734 if ( (atom
->size() == 0) && (atom
->symbolTableInclusion() == ld::Atom::symbolTableNotInFinalLinkedImages
) )
3736 if ( atom
->contentType() == ld::Atom::typeCString
) {
3737 strcpy(buffer
, "literal string: ");
3738 strlcat(buffer
, (char*)atom
->rawContentPointer(), 4096);
3741 else if ( (atom
->contentType() == ld::Atom::typeCFI
) && (strcmp(name
, "FDE") == 0) ) {
3742 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(); fit
!= atom
->fixupsEnd(); ++fit
) {
3743 if ( (fit
->kind
== ld::Fixup::kindSetTargetAddress
) && (fit
->clusterSize
== ld::Fixup::k1of4
) ) {
3744 assert(fit
->binding
== ld::Fixup::bindingDirectlyBound
);
3745 if ( fit
->u
.target
->section().type() == ld::Section::typeCode
) {
3746 strcpy(buffer
, "FDE for: ");
3747 strlcat(buffer
, fit
->u
.target
->name(), 4096);
3753 else if ( atom
->contentType() == ld::Atom::typeNonLazyPointer
) {
3754 strcpy(buffer
, "non-lazy-pointer");
3755 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(); fit
!= atom
->fixupsEnd(); ++fit
) {
3756 if ( fit
->binding
== ld::Fixup::bindingsIndirectlyBound
) {
3757 strcpy(buffer
, "non-lazy-pointer-to: ");
3758 strlcat(buffer
, state
.indirectBindingTable
[fit
->u
.bindingIndex
]->name(), 4096);
3761 else if ( fit
->binding
== ld::Fixup::bindingDirectlyBound
) {
3762 strcpy(buffer
, "non-lazy-pointer-to-local: ");
3763 strlcat(buffer
, fit
->u
.target
->name(), 4096);
3769 fprintf(mapFile
, "0x%08llX\t0x%08llX\t[%3u] %s\n", atom
->finalAddress(), atom
->size(),
3770 readerToFileOrdinal
[atom
->file()], name
);
3776 warning("could not write map file: %s\n", _options
.generatedMapPath());
3782 // used to sort atoms with debug notes
3783 class DebugNoteSorter
3786 bool operator()(const ld::Atom
* left
, const ld::Atom
* right
) const
3788 // first sort by reader
3789 ld::File::Ordinal leftFileOrdinal
= left
->file()->ordinal();
3790 ld::File::Ordinal rightFileOrdinal
= right
->file()->ordinal();
3791 if ( leftFileOrdinal
!= rightFileOrdinal
)
3792 return (leftFileOrdinal
< rightFileOrdinal
);
3794 // then sort by atom objectAddress
3795 uint64_t leftAddr
= left
->finalAddress();
3796 uint64_t rightAddr
= right
->finalAddress();
3797 return leftAddr
< rightAddr
;
3802 const char* OutputFile::assureFullPath(const char* path
)
3804 if ( path
[0] == '/' )
3806 char cwdbuff
[MAXPATHLEN
];
3807 if ( getcwd(cwdbuff
, MAXPATHLEN
) != NULL
) {
3809 asprintf(&result
, "%s/%s", cwdbuff
, path
);
3810 if ( result
!= NULL
)
3816 void OutputFile::synthesizeDebugNotes(ld::Internal
& state
)
3818 // -S means don't synthesize debug map
3819 if ( _options
.debugInfoStripping() == Options::kDebugInfoNone
)
3821 // make a vector of atoms that come from files compiled with dwarf debug info
3822 std::vector
<const ld::Atom
*> atomsNeedingDebugNotes
;
3823 std::set
<const ld::Atom
*> atomsWithStabs
;
3824 atomsNeedingDebugNotes
.reserve(1024);
3825 const ld::relocatable::File
* objFile
= NULL
;
3826 bool objFileHasDwarf
= false;
3827 bool objFileHasStabs
= false;
3828 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
3829 ld::Internal::FinalSection
* sect
= *sit
;
3830 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
3831 const ld::Atom
* atom
= *ait
;
3832 // no stabs for atoms that would not be in the symbol table
3833 if ( atom
->symbolTableInclusion() == ld::Atom::symbolTableNotIn
)
3835 if ( atom
->symbolTableInclusion() == ld::Atom::symbolTableNotInFinalLinkedImages
)
3837 if ( atom
->symbolTableInclusion() == ld::Atom::symbolTableInWithRandomAutoStripLabel
)
3839 // no stabs for absolute symbols
3840 if ( atom
->definition() == ld::Atom::definitionAbsolute
)
3842 // no stabs for .eh atoms
3843 if ( atom
->contentType() == ld::Atom::typeCFI
)
3845 // no stabs for string literal atoms
3846 if ( atom
->contentType() == ld::Atom::typeCString
)
3848 // no stabs for kernel dtrace probes
3849 if ( (_options
.outputKind() == Options::kStaticExecutable
) && (strncmp(atom
->name(), "__dtrace_probe$", 15) == 0) )
3851 const ld::File
* file
= atom
->file();
3852 if ( file
!= NULL
) {
3853 if ( file
!= objFile
) {
3854 objFileHasDwarf
= false;
3855 objFileHasStabs
= false;
3856 objFile
= dynamic_cast<const ld::relocatable::File
*>(file
);
3857 if ( objFile
!= NULL
) {
3858 switch ( objFile
->debugInfo() ) {
3859 case ld::relocatable::File::kDebugInfoNone
:
3861 case ld::relocatable::File::kDebugInfoDwarf
:
3862 objFileHasDwarf
= true;
3864 case ld::relocatable::File::kDebugInfoStabs
:
3865 case ld::relocatable::File::kDebugInfoStabsUUID
:
3866 objFileHasStabs
= true;
3871 if ( objFileHasDwarf
)
3872 atomsNeedingDebugNotes
.push_back(atom
);
3873 if ( objFileHasStabs
)
3874 atomsWithStabs
.insert(atom
);
3879 // sort by file ordinal then atom ordinal
3880 std::sort(atomsNeedingDebugNotes
.begin(), atomsNeedingDebugNotes
.end(), DebugNoteSorter());
3882 // synthesize "debug notes" and add them to master stabs vector
3883 const char* dirPath
= NULL
;
3884 const char* filename
= NULL
;
3885 bool wroteStartSO
= false;
3886 state
.stabs
.reserve(atomsNeedingDebugNotes
.size()*4);
3887 std::unordered_set
<const char*, CStringHash
, CStringEquals
> seenFiles
;
3888 for (std::vector
<const ld::Atom
*>::iterator it
=atomsNeedingDebugNotes
.begin(); it
!= atomsNeedingDebugNotes
.end(); it
++) {
3889 const ld::Atom
* atom
= *it
;
3890 const ld::File
* atomFile
= atom
->file();
3891 const ld::relocatable::File
* atomObjFile
= dynamic_cast<const ld::relocatable::File
*>(atomFile
);
3892 //fprintf(stderr, "debug note for %s\n", atom->name());
3893 const char* newPath
= atom
->translationUnitSource();
3894 if ( newPath
!= NULL
) {
3895 const char* newDirPath
;
3896 const char* newFilename
;
3897 const char* lastSlash
= strrchr(newPath
, '/');
3898 if ( lastSlash
== NULL
)
3900 newFilename
= lastSlash
+1;
3901 char* temp
= strdup(newPath
);
3903 // gdb like directory SO's to end in '/', but dwarf DW_AT_comp_dir usually does not have trailing '/'
3904 temp
[lastSlash
-newPath
+1] = '\0';
3905 // need SO's whenever the translation unit source file changes
3906 if ( (filename
== NULL
) || (strcmp(newFilename
,filename
) != 0) ) {
3907 if ( filename
!= NULL
) {
3908 // translation unit change, emit ending SO
3909 ld::relocatable::File::Stab endFileStab
;
3910 endFileStab
.atom
= NULL
;
3911 endFileStab
.type
= N_SO
;
3912 endFileStab
.other
= 1;
3913 endFileStab
.desc
= 0;
3914 endFileStab
.value
= 0;
3915 endFileStab
.string
= "";
3916 state
.stabs
.push_back(endFileStab
);
3918 // new translation unit, emit start SO's
3919 ld::relocatable::File::Stab dirPathStab
;
3920 dirPathStab
.atom
= NULL
;
3921 dirPathStab
.type
= N_SO
;
3922 dirPathStab
.other
= 0;
3923 dirPathStab
.desc
= 0;
3924 dirPathStab
.value
= 0;
3925 dirPathStab
.string
= newDirPath
;
3926 state
.stabs
.push_back(dirPathStab
);
3927 ld::relocatable::File::Stab fileStab
;
3928 fileStab
.atom
= NULL
;
3929 fileStab
.type
= N_SO
;
3933 fileStab
.string
= newFilename
;
3934 state
.stabs
.push_back(fileStab
);
3935 // Synthesize OSO for start of file
3936 ld::relocatable::File::Stab objStab
;
3937 objStab
.atom
= NULL
;
3938 objStab
.type
= N_OSO
;
3939 // <rdar://problem/6337329> linker should put cpusubtype in n_sect field of nlist entry for N_OSO debug note entries
3940 objStab
.other
= atomFile
->cpuSubType();
3942 if ( atomObjFile
!= NULL
) {
3943 objStab
.string
= assureFullPath(atomObjFile
->debugInfoPath());
3944 objStab
.value
= atomObjFile
->debugInfoModificationTime();
3947 objStab
.string
= assureFullPath(atomFile
->path());
3948 objStab
.value
= atomFile
->modificationTime();
3950 state
.stabs
.push_back(objStab
);
3951 wroteStartSO
= true;
3952 // add the source file path to seenFiles so it does not show up in SOLs
3953 seenFiles
.insert(newFilename
);
3955 asprintf(&fullFilePath
, "%s%s", newDirPath
, newFilename
);
3956 // add both leaf path and full path
3957 seenFiles
.insert(fullFilePath
);
3959 filename
= newFilename
;
3960 dirPath
= newDirPath
;
3961 if ( atom
->section().type() == ld::Section::typeCode
) {
3962 // Synthesize BNSYM and start FUN stabs
3963 ld::relocatable::File::Stab beginSym
;
3964 beginSym
.atom
= atom
;
3965 beginSym
.type
= N_BNSYM
;
3969 beginSym
.string
= "";
3970 state
.stabs
.push_back(beginSym
);
3971 ld::relocatable::File::Stab startFun
;
3972 startFun
.atom
= atom
;
3973 startFun
.type
= N_FUN
;
3977 startFun
.string
= atom
->name();
3978 state
.stabs
.push_back(startFun
);
3979 // Synthesize any SOL stabs needed
3980 const char* curFile
= NULL
;
3981 for (ld::Atom::LineInfo::iterator lit
= atom
->beginLineInfo(); lit
!= atom
->endLineInfo(); ++lit
) {
3982 if ( lit
->fileName
!= curFile
) {
3983 if ( seenFiles
.count(lit
->fileName
) == 0 ) {
3984 seenFiles
.insert(lit
->fileName
);
3985 ld::relocatable::File::Stab sol
;
3991 sol
.string
= lit
->fileName
;
3992 state
.stabs
.push_back(sol
);
3994 curFile
= lit
->fileName
;
3997 // Synthesize end FUN and ENSYM stabs
3998 ld::relocatable::File::Stab endFun
;
4000 endFun
.type
= N_FUN
;
4005 state
.stabs
.push_back(endFun
);
4006 ld::relocatable::File::Stab endSym
;
4008 endSym
.type
= N_ENSYM
;
4013 state
.stabs
.push_back(endSym
);
4016 ld::relocatable::File::Stab globalsStab
;
4017 const char* name
= atom
->name();
4018 if ( atom
->scope() == ld::Atom::scopeTranslationUnit
) {
4019 // Synthesize STSYM stab for statics
4020 globalsStab
.atom
= atom
;
4021 globalsStab
.type
= N_STSYM
;
4022 globalsStab
.other
= 1;
4023 globalsStab
.desc
= 0;
4024 globalsStab
.value
= 0;
4025 globalsStab
.string
= name
;
4026 state
.stabs
.push_back(globalsStab
);
4029 // Synthesize GSYM stab for other globals
4030 globalsStab
.atom
= atom
;
4031 globalsStab
.type
= N_GSYM
;
4032 globalsStab
.other
= 1;
4033 globalsStab
.desc
= 0;
4034 globalsStab
.value
= 0;
4035 globalsStab
.string
= name
;
4036 state
.stabs
.push_back(globalsStab
);
4042 if ( wroteStartSO
) {
4044 ld::relocatable::File::Stab endFileStab
;
4045 endFileStab
.atom
= NULL
;
4046 endFileStab
.type
= N_SO
;
4047 endFileStab
.other
= 1;
4048 endFileStab
.desc
= 0;
4049 endFileStab
.value
= 0;
4050 endFileStab
.string
= "";
4051 state
.stabs
.push_back(endFileStab
);
4054 // copy any stabs from .o file
4055 std::set
<const ld::File
*> filesSeenWithStabs
;
4056 for (std::set
<const ld::Atom
*>::iterator it
=atomsWithStabs
.begin(); it
!= atomsWithStabs
.end(); it
++) {
4057 const ld::Atom
* atom
= *it
;
4058 objFile
= dynamic_cast<const ld::relocatable::File
*>(atom
->file());
4059 if ( objFile
!= NULL
) {
4060 if ( filesSeenWithStabs
.count(objFile
) == 0 ) {
4061 filesSeenWithStabs
.insert(objFile
);
4062 const std::vector
<ld::relocatable::File::Stab
>* stabs
= objFile
->stabs();
4063 if ( stabs
!= NULL
) {
4064 for(std::vector
<ld::relocatable::File::Stab
>::const_iterator sit
= stabs
->begin(); sit
!= stabs
->end(); ++sit
) {
4065 ld::relocatable::File::Stab stab
= *sit
;
4066 // ignore stabs associated with atoms that were dead stripped or coalesced away
4067 if ( (sit
->atom
!= NULL
) && (atomsWithStabs
.count(sit
->atom
) == 0) )
4069 // <rdar://problem/8284718> Value of N_SO stabs should be address of first atom from translation unit
4070 if ( (stab
.type
== N_SO
) && (stab
.string
!= NULL
) && (stab
.string
[0] != '\0') ) {
4073 state
.stabs
.push_back(stab
);