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 if ( _options
.pageAlignDataAtoms() && ( strcmp(atom
->section().segmentName(), "__DATA") == 0) ) {
348 switch ( atom
->section().type() ) {
349 case ld::Section::typeUnclassified
:
350 case ld::Section::typeTentativeDefs
:
351 case ld::Section::typeZeroFill
:
353 if ( atomAlignmentPowerOf2
< 12 )
354 atomAlignmentPowerOf2
= 12;
360 if ( atomAlignmentPowerOf2
> maxAlignment
)
361 maxAlignment
= atomAlignmentPowerOf2
;
362 // calculate section offset for this atom
363 uint64_t alignment
= 1 << atomAlignmentPowerOf2
;
364 uint64_t currentModulus
= (offset
% alignment
);
365 uint64_t requiredModulus
= atom
->alignment().modulus
;
366 if ( currentModulus
!= requiredModulus
) {
367 if ( requiredModulus
> currentModulus
)
368 offset
+= requiredModulus
-currentModulus
;
370 offset
+= requiredModulus
+alignment
-currentModulus
;
372 // LINKEDIT atoms are laid out later
373 if ( sect
->type() != ld::Section::typeLinkEdit
) {
374 (const_cast<ld::Atom
*>(atom
))->setSectionOffset(offset
);
375 offset
+= atom
->size();
377 offset
= (offset
+ 4095) & (-4096); // round up to end of page
380 if ( (atom
->scope() == ld::Atom::scopeGlobal
)
381 && (atom
->definition() == ld::Atom::definitionRegular
)
382 && (atom
->combine() == ld::Atom::combineByName
)
383 && ((atom
->symbolTableInclusion() == ld::Atom::symbolTableIn
)
384 || (atom
->symbolTableInclusion() == ld::Atom::symbolTableInAndNeverStrip
)) ) {
385 this->hasWeakExternalSymbols
= true;
386 if ( _options
.warnWeakExports() )
387 warning("weak external symbol: %s", atom
->name());
391 // section alignment is that of a contained atom with the greatest alignment
392 sect
->alignment
= maxAlignment
;
393 // unless -sectalign command line option overrides
394 if ( _options
.hasCustomSectionAlignment(sect
->segmentName(), sect
->sectionName()) )
395 sect
->alignment
= _options
.customSectionAlignment(sect
->segmentName(), sect
->sectionName());
396 // each atom in __eh_frame has zero alignment to assure they pack together,
397 // but compilers usually make the CFIs pointer sized, so we want whole section
398 // to start on pointer sized boundary.
399 if ( sect
->type() == ld::Section::typeCFI
)
401 if ( sect
->type() == ld::Section::typeTLVDefs
)
402 this->hasThreadLocalVariableDefinitions
= true;
407 void OutputFile::setLoadCommandsPadding(ld::Internal
& state
)
409 // In other sections, any extra space is put and end of segment.
410 // In __TEXT segment, any extra space is put after load commands to allow post-processing of load commands
411 // Do a reverse layout of __TEXT segment to determine padding size and adjust section size
412 uint64_t paddingSize
= 0;
413 switch ( _options
.outputKind() ) {
415 // dyld itself has special padding requirements. We want the beginning __text section to start at a stable address
416 assert(strcmp(state
.sections
[1]->sectionName(),"__text") == 0);
417 state
.sections
[1]->alignment
= 12; // page align __text
419 case Options::kObjectFile
:
420 // mach-o .o files need no padding between load commands and first section
421 // but leave enough room that the object file could be signed
424 case Options::kPreload
:
425 // mach-o MH_PRELOAD files need no padding between load commands and first section
428 // work backwards from end of segment and lay out sections so that extra room goes to padding atom
430 for (std::vector
<ld::Internal::FinalSection
*>::reverse_iterator it
= state
.sections
.rbegin(); it
!= state
.sections
.rend(); ++it
) {
431 ld::Internal::FinalSection
* sect
= *it
;
432 if ( strcmp(sect
->segmentName(), "__TEXT") != 0 )
434 if ( sect
== headerAndLoadCommandsSection
) {
435 addr
-= headerAndLoadCommandsSection
->size
;
436 paddingSize
= addr
% _options
.segmentAlignment();
440 addr
= addr
& (0 - (1 << sect
->alignment
));
443 // if command line requires more padding than this
444 uint32_t minPad
= _options
.minimumHeaderPad();
445 if ( _options
.maxMminimumHeaderPad() ) {
446 // -headerpad_max_install_names means there should be room for every path load command to grow to 1204 bytes
447 uint32_t altMin
= _dylibsToLoad
.size() * MAXPATHLEN
;
448 if ( _options
.outputKind() == Options::kDynamicLibrary
)
449 altMin
+= MAXPATHLEN
;
450 if ( altMin
> minPad
)
453 if ( paddingSize
< minPad
) {
454 int extraPages
= (minPad
- paddingSize
+ _options
.segmentAlignment() - 1)/_options
.segmentAlignment();
455 paddingSize
+= extraPages
* _options
.segmentAlignment();
458 if ( _options
.makeEncryptable() ) {
459 // load commands must be on a separate non-encrypted page
460 int loadCommandsPage
= (headerAndLoadCommandsSection
->size
+ minPad
)/_options
.segmentAlignment();
461 int textPage
= (headerAndLoadCommandsSection
->size
+ paddingSize
)/_options
.segmentAlignment();
462 if ( loadCommandsPage
== textPage
) {
463 paddingSize
+= _options
.segmentAlignment();
466 // remember start for later use by load command
467 _encryptedTEXTstartOffset
= textPage
*_options
.segmentAlignment();
471 // add padding to size of section
472 headerAndLoadCommandsSection
->size
+= paddingSize
;
476 uint64_t OutputFile::pageAlign(uint64_t addr
)
478 const uint64_t alignment
= _options
.segmentAlignment();
479 return ((addr
+alignment
-1) & (-alignment
));
482 uint64_t OutputFile::pageAlign(uint64_t addr
, uint64_t pageSize
)
484 return ((addr
+pageSize
-1) & (-pageSize
));
488 void OutputFile::assignFileOffsets(ld::Internal
& state
)
490 const bool log
= false;
491 const bool hiddenSectionsOccupyAddressSpace
= ((_options
.outputKind() != Options::kObjectFile
)
492 && (_options
.outputKind() != Options::kPreload
));
493 const bool segmentsArePageAligned
= (_options
.outputKind() != Options::kObjectFile
);
495 uint64_t address
= 0;
496 const char* lastSegName
= "";
497 uint64_t floatingAddressStart
= _options
.baseAddress();
499 // first pass, assign addresses to sections in segments with fixed start addresses
500 if ( log
) fprintf(stderr
, "Fixed address segments:\n");
501 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
502 ld::Internal::FinalSection
* sect
= *it
;
503 if ( ! _options
.hasCustomSegmentAddress(sect
->segmentName()) )
505 if ( segmentsArePageAligned
) {
506 if ( strcmp(lastSegName
, sect
->segmentName()) != 0 ) {
507 address
= _options
.customSegmentAddress(sect
->segmentName());
508 lastSegName
= sect
->segmentName();
511 // adjust section address based on alignment
512 uint64_t unalignedAddress
= address
;
513 uint64_t alignment
= (1 << sect
->alignment
);
514 address
= ( (unalignedAddress
+alignment
-1) & (-alignment
) );
516 // update section info
517 sect
->address
= address
;
518 sect
->alignmentPaddingBytes
= (address
- unalignedAddress
);
521 if ( ((address
+ sect
->size
) > _options
.maxAddress()) && (_options
.outputKind() != Options::kObjectFile
)
522 && (_options
.outputKind() != Options::kStaticExecutable
) )
523 throwf("section %s (address=0x%08llX, size=%llu) would make the output executable exceed available address range",
524 sect
->sectionName(), address
, sect
->size
);
526 if ( log
) fprintf(stderr
, " address=0x%08llX, hidden=%d, alignment=%02d, section=%s,%s\n",
527 sect
->address
, sect
->isSectionHidden(), sect
->alignment
, sect
->segmentName(), sect
->sectionName());
528 // update running totals
529 if ( !sect
->isSectionHidden() || hiddenSectionsOccupyAddressSpace
)
530 address
+= sect
->size
;
532 // if TEXT segment address is fixed, then flow other segments after it
533 if ( strcmp(sect
->segmentName(), "__TEXT") == 0 ) {
534 floatingAddressStart
= address
;
538 // second pass, assign section address to sections in segments that are contiguous with previous segment
539 address
= floatingAddressStart
;
541 ld::Internal::FinalSection
* overlappingFixedSection
= NULL
;
542 ld::Internal::FinalSection
* overlappingFlowSection
= NULL
;
543 if ( log
) fprintf(stderr
, "Regular layout segments:\n");
544 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
545 ld::Internal::FinalSection
* sect
= *it
;
546 if ( _options
.hasCustomSegmentAddress(sect
->segmentName()) )
548 if ( (_options
.outputKind() == Options::kPreload
) && (sect
->type() == ld::Section::typeMachHeader
) ) {
549 sect
->alignmentPaddingBytes
= 0;
552 if ( segmentsArePageAligned
) {
553 if ( strcmp(lastSegName
, sect
->segmentName()) != 0 ) {
554 // round up size of last segment if needed
555 if ( *lastSegName
!= '\0' ) {
556 address
= pageAlign(address
, _options
.segPageSize(lastSegName
));
558 // set segment address based on end of last segment
559 address
= pageAlign(address
);
560 lastSegName
= sect
->segmentName();
563 // adjust section address based on alignment
564 uint64_t unalignedAddress
= address
;
565 uint64_t alignment
= (1 << sect
->alignment
);
566 address
= ( (unalignedAddress
+alignment
-1) & (-alignment
) );
568 // update section info
569 sect
->address
= address
;
570 sect
->alignmentPaddingBytes
= (address
- unalignedAddress
);
573 if ( ((address
+ sect
->size
) > _options
.maxAddress()) && (_options
.outputKind() != Options::kObjectFile
)
574 && (_options
.outputKind() != Options::kStaticExecutable
) )
575 throwf("section %s (address=0x%08llX, size=%llu) would make the output executable exceed available address range",
576 sect
->sectionName(), address
, sect
->size
);
578 // sanity check it does not overlap a fixed address segment
579 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
580 ld::Internal::FinalSection
* otherSect
= *sit
;
581 if ( ! _options
.hasCustomSegmentAddress(otherSect
->segmentName()) )
583 if ( sect
->address
> otherSect
->address
) {
584 if ( (otherSect
->address
+otherSect
->size
) > sect
->address
) {
585 overlappingFixedSection
= otherSect
;
586 overlappingFlowSection
= sect
;
590 if ( (sect
->address
+sect
->size
) > otherSect
->address
) {
591 overlappingFixedSection
= otherSect
;
592 overlappingFlowSection
= sect
;
597 if ( log
) fprintf(stderr
, " address=0x%08llX, size=0x%08llX, hidden=%d, alignment=%02d, padBytes=%d, section=%s,%s\n",
598 sect
->address
, sect
->size
, sect
->isSectionHidden(), sect
->alignment
, sect
->alignmentPaddingBytes
,
599 sect
->segmentName(), sect
->sectionName());
600 // update running totals
601 if ( !sect
->isSectionHidden() || hiddenSectionsOccupyAddressSpace
)
602 address
+= sect
->size
;
604 if ( overlappingFixedSection
!= NULL
) {
605 fprintf(stderr
, "Section layout:\n");
606 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
607 ld::Internal::FinalSection
* sect
= *it
;
608 if ( sect
->isSectionHidden() )
610 fprintf(stderr
, " address:0x%08llX, alignment:2^%d, size:0x%08llX, padBytes:%d, section:%s/%s\n",
611 sect
->address
, sect
->alignment
, sect
->size
, sect
->alignmentPaddingBytes
,
612 sect
->segmentName(), sect
->sectionName());
615 throwf("Section (%s/%s) overlaps fixed address section (%s/%s)",
616 overlappingFlowSection
->segmentName(), overlappingFlowSection
->sectionName(),
617 overlappingFixedSection
->segmentName(), overlappingFixedSection
->sectionName());
621 // third pass, assign section file offsets
622 uint64_t fileOffset
= 0;
624 if ( log
) fprintf(stderr
, "All segments with file offsets:\n");
625 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
626 ld::Internal::FinalSection
* sect
= *it
;
627 if ( hasZeroForFileOffset(sect
) ) {
628 // fileoff of zerofill sections is moot, but historically it is set to zero
629 sect
->fileOffset
= 0;
631 // <rdar://problem/10445047> align file offset with address layout
632 fileOffset
+= sect
->alignmentPaddingBytes
;
635 // page align file offset at start of each segment
636 if ( segmentsArePageAligned
&& (*lastSegName
!= '\0') && (strcmp(lastSegName
, sect
->segmentName()) != 0) ) {
637 fileOffset
= pageAlign(fileOffset
, _options
.segPageSize(lastSegName
));
639 lastSegName
= sect
->segmentName();
641 // align file offset with address layout
642 fileOffset
+= sect
->alignmentPaddingBytes
;
644 // update section info
645 sect
->fileOffset
= fileOffset
;
647 // update running total
648 fileOffset
+= sect
->size
;
651 if ( log
) fprintf(stderr
, " fileoffset=0x%08llX, address=0x%08llX, hidden=%d, size=%lld, alignment=%02d, section=%s,%s\n",
652 sect
->fileOffset
, sect
->address
, sect
->isSectionHidden(), sect
->size
, sect
->alignment
,
653 sect
->segmentName(), sect
->sectionName());
657 // for encrypted iPhoneOS apps
658 if ( _options
.makeEncryptable() ) {
659 // remember end of __TEXT for later use by load command
660 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
661 ld::Internal::FinalSection
* sect
= *it
;
662 if ( strcmp(sect
->segmentName(), "__TEXT") == 0 ) {
663 _encryptedTEXTendOffset
= pageAlign(sect
->fileOffset
+ sect
->size
);
668 // remember total file size
669 _fileSize
= fileOffset
;
673 static const char* makeName(const ld::Atom
& atom
)
675 static char buffer
[4096];
676 switch ( atom
.symbolTableInclusion() ) {
677 case ld::Atom::symbolTableNotIn
:
678 case ld::Atom::symbolTableNotInFinalLinkedImages
:
679 sprintf(buffer
, "%s@0x%08llX", atom
.name(), atom
.objectAddress());
681 case ld::Atom::symbolTableIn
:
682 case ld::Atom::symbolTableInAndNeverStrip
:
683 case ld::Atom::symbolTableInAsAbsolute
:
684 case ld::Atom::symbolTableInWithRandomAutoStripLabel
:
685 strlcpy(buffer
, atom
.name(), 4096);
691 static const char* referenceTargetAtomName(ld::Internal
& state
, const ld::Fixup
* ref
)
693 switch ( ref
->binding
) {
694 case ld::Fixup::bindingNone
:
696 case ld::Fixup::bindingByNameUnbound
:
697 return (char*)(ref
->u
.target
);
698 case ld::Fixup::bindingByContentBound
:
699 case ld::Fixup::bindingDirectlyBound
:
700 return makeName(*((ld::Atom
*)(ref
->u
.target
)));
701 case ld::Fixup::bindingsIndirectlyBound
:
702 return makeName(*state
.indirectBindingTable
[ref
->u
.bindingIndex
]);
704 return "BAD BINDING";
707 bool OutputFile::targetIsThumb(ld::Internal
& state
, const ld::Fixup
* fixup
)
709 switch ( fixup
->binding
) {
710 case ld::Fixup::bindingByContentBound
:
711 case ld::Fixup::bindingDirectlyBound
:
712 return fixup
->u
.target
->isThumb();
713 case ld::Fixup::bindingsIndirectlyBound
:
714 return state
.indirectBindingTable
[fixup
->u
.bindingIndex
]->isThumb();
718 throw "unexpected binding";
721 uint64_t OutputFile::addressOf(const ld::Internal
& state
, const ld::Fixup
* fixup
, const ld::Atom
** target
)
723 if ( !_options
.makeCompressedDyldInfo() ) {
724 // For external relocations the classic mach-o format
725 // has addend only stored in the content. That means
726 // that the address of the target is not used.
727 if ( fixup
->contentAddendOnly
)
730 switch ( fixup
->binding
) {
731 case ld::Fixup::bindingNone
:
732 throw "unexpected bindingNone";
733 case ld::Fixup::bindingByNameUnbound
:
734 throw "unexpected bindingByNameUnbound";
735 case ld::Fixup::bindingByContentBound
:
736 case ld::Fixup::bindingDirectlyBound
:
737 *target
= fixup
->u
.target
;
738 return (*target
)->finalAddress();
739 case ld::Fixup::bindingsIndirectlyBound
:
740 *target
= state
.indirectBindingTable
[fixup
->u
.bindingIndex
];
742 if ( ! (*target
)->finalAddressMode() ) {
743 throwf("reference to symbol (which has not been assigned an address) %s", (*target
)->name());
746 return (*target
)->finalAddress();
748 throw "unexpected binding";
751 uint64_t OutputFile::sectionOffsetOf(const ld::Internal
& state
, const ld::Fixup
* fixup
)
753 const ld::Atom
* target
= NULL
;
754 switch ( fixup
->binding
) {
755 case ld::Fixup::bindingNone
:
756 throw "unexpected bindingNone";
757 case ld::Fixup::bindingByNameUnbound
:
758 throw "unexpected bindingByNameUnbound";
759 case ld::Fixup::bindingByContentBound
:
760 case ld::Fixup::bindingDirectlyBound
:
761 target
= fixup
->u
.target
;
763 case ld::Fixup::bindingsIndirectlyBound
:
764 target
= state
.indirectBindingTable
[fixup
->u
.bindingIndex
];
767 assert(target
!= NULL
);
769 uint64_t targetAddress
= target
->finalAddress();
770 for (std::vector
<ld::Internal::FinalSection
*>::const_iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
771 const ld::Internal::FinalSection
* sect
= *it
;
772 if ( (sect
->address
<= targetAddress
) && (targetAddress
< (sect
->address
+sect
->size
)) )
773 return targetAddress
- sect
->address
;
775 throw "section not found for section offset";
780 uint64_t OutputFile::tlvTemplateOffsetOf(const ld::Internal
& state
, const ld::Fixup
* fixup
)
782 const ld::Atom
* target
= NULL
;
783 switch ( fixup
->binding
) {
784 case ld::Fixup::bindingNone
:
785 throw "unexpected bindingNone";
786 case ld::Fixup::bindingByNameUnbound
:
787 throw "unexpected bindingByNameUnbound";
788 case ld::Fixup::bindingByContentBound
:
789 case ld::Fixup::bindingDirectlyBound
:
790 target
= fixup
->u
.target
;
792 case ld::Fixup::bindingsIndirectlyBound
:
793 target
= state
.indirectBindingTable
[fixup
->u
.bindingIndex
];
796 assert(target
!= NULL
);
798 for (std::vector
<ld::Internal::FinalSection
*>::const_iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
799 const ld::Internal::FinalSection
* sect
= *it
;
800 switch ( sect
->type() ) {
801 case ld::Section::typeTLVInitialValues
:
802 case ld::Section::typeTLVZeroFill
:
803 return target
->finalAddress() - sect
->address
;
808 throw "section not found for tlvTemplateOffsetOf";
811 void OutputFile::printSectionLayout(ld::Internal
& state
)
813 // show layout of final image
814 fprintf(stderr
, "final section layout:\n");
815 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
816 if ( (*it
)->isSectionHidden() )
818 fprintf(stderr
, " %s/%s addr=0x%08llX, size=0x%08llX, fileOffset=0x%08llX, type=%d\n",
819 (*it
)->segmentName(), (*it
)->sectionName(),
820 (*it
)->address
, (*it
)->size
, (*it
)->fileOffset
, (*it
)->type());
825 void OutputFile::rangeCheck8(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
827 if ( (displacement
> 127) || (displacement
< -128) ) {
828 // show layout of final image
829 printSectionLayout(state
);
831 const ld::Atom
* target
;
832 throwf("8-bit reference out of range (%lld max is +/-127B): from %s (0x%08llX) to %s (0x%08llX)",
833 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
834 addressOf(state
, fixup
, &target
));
838 void OutputFile::rangeCheck16(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
840 const int64_t thirtyTwoKLimit
= 0x00007FFF;
841 if ( (displacement
> thirtyTwoKLimit
) || (displacement
< (-thirtyTwoKLimit
)) ) {
842 // show layout of final image
843 printSectionLayout(state
);
845 const ld::Atom
* target
;
846 throwf("16-bit reference out of range (%lld max is +/-32KB): from %s (0x%08llX) to %s (0x%08llX)",
847 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
848 addressOf(state
, fixup
, &target
));
852 void OutputFile::rangeCheckBranch32(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
854 const int64_t twoGigLimit
= 0x7FFFFFFF;
855 if ( (displacement
> twoGigLimit
) || (displacement
< (-twoGigLimit
)) ) {
856 // show layout of final image
857 printSectionLayout(state
);
859 const ld::Atom
* target
;
860 throwf("32-bit branch out of range (%lld max is +/-2GB): from %s (0x%08llX) to %s (0x%08llX)",
861 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
862 addressOf(state
, fixup
, &target
));
867 void OutputFile::rangeCheckAbsolute32(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
869 const int64_t fourGigLimit
= 0xFFFFFFFF;
870 if ( displacement
> fourGigLimit
) {
871 // <rdar://problem/9610466> cannot enforce 32-bit range checks on 32-bit archs because assembler loses sign information
872 // .long _foo - 0xC0000000
873 // is encoded in mach-o the same as:
874 // .long _foo + 0x40000000
875 // so if _foo lays out to 0xC0000100, the first is ok, but the second is not.
876 if ( (_options
.architecture() == CPU_TYPE_ARM
) || (_options
.architecture() == CPU_TYPE_I386
) ) {
877 // Unlikely userland code does funky stuff like this, so warn for them, but not warn for -preload or -static
878 if ( (_options
.outputKind() != Options::kPreload
) && (_options
.outputKind() != Options::kStaticExecutable
) ) {
879 warning("32-bit absolute address out of range (0x%08llX max is 4GB): from %s + 0x%08X (0x%08llX) to 0x%08llX",
880 displacement
, atom
->name(), fixup
->offsetInAtom
, atom
->finalAddress(), displacement
);
884 // show layout of final image
885 printSectionLayout(state
);
887 const ld::Atom
* target
;
888 if ( fixup
->binding
== ld::Fixup::bindingNone
)
889 throwf("32-bit absolute address out of range (0x%08llX max is 4GB): from %s + 0x%08X (0x%08llX) to 0x%08llX",
890 displacement
, atom
->name(), fixup
->offsetInAtom
, atom
->finalAddress(), displacement
);
892 throwf("32-bit absolute address out of range (0x%08llX max is 4GB): from %s + 0x%08X (0x%08llX) to %s (0x%08llX)",
893 displacement
, atom
->name(), fixup
->offsetInAtom
, atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
894 addressOf(state
, fixup
, &target
));
899 void OutputFile::rangeCheckRIP32(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
901 const int64_t twoGigLimit
= 0x7FFFFFFF;
902 if ( (displacement
> twoGigLimit
) || (displacement
< (-twoGigLimit
)) ) {
903 // show layout of final image
904 printSectionLayout(state
);
906 const ld::Atom
* target
;
907 throwf("32-bit RIP relative reference out of range (%lld max is +/-4GB): from %s (0x%08llX) to %s (0x%08llX)",
908 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
909 addressOf(state
, fixup
, &target
));
913 void OutputFile::rangeCheckARM12(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
915 if ( (displacement
> 4092LL) || (displacement
< (-4092LL)) ) {
916 // show layout of final image
917 printSectionLayout(state
);
919 const ld::Atom
* target
;
920 throwf("ARM ldr 12-bit displacement out of range (%lld max is +/-4096B): from %s (0x%08llX) to %s (0x%08llX)",
921 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
922 addressOf(state
, fixup
, &target
));
927 void OutputFile::rangeCheckARMBranch24(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
929 if ( (displacement
> 33554428LL) || (displacement
< (-33554432LL)) ) {
930 // show layout of final image
931 printSectionLayout(state
);
933 const ld::Atom
* target
;
934 throwf("b/bl/blx ARM branch out of range (%lld max is +/-32MB): from %s (0x%08llX) to %s (0x%08llX)",
935 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
936 addressOf(state
, fixup
, &target
));
940 void OutputFile::rangeCheckThumbBranch22(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
942 // thumb2 supports a larger displacement
943 if ( _options
.preferSubArchitecture() && _options
.archSupportsThumb2() ) {
944 if ( (displacement
> 16777214LL) || (displacement
< (-16777216LL)) ) {
945 // show layout of final image
946 printSectionLayout(state
);
948 const ld::Atom
* target
;
949 throwf("b/bl/blx thumb2 branch out of range (%lld max is +/-16MB): from %s (0x%08llX) to %s (0x%08llX)",
950 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
951 addressOf(state
, fixup
, &target
));
955 if ( (displacement
> 4194302LL) || (displacement
< (-4194304LL)) ) {
956 // show layout of final image
957 printSectionLayout(state
);
959 const ld::Atom
* target
;
960 throwf("b/bl/blx thumb1 branch out of range (%lld max is +/-4MB): from %s (0x%08llX) to %s (0x%08llX)",
961 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
962 addressOf(state
, fixup
, &target
));
971 uint16_t OutputFile::get16LE(uint8_t* loc
) { return LittleEndian::get16(*(uint16_t*)loc
); }
972 void OutputFile::set16LE(uint8_t* loc
, uint16_t value
) { LittleEndian::set16(*(uint16_t*)loc
, value
); }
974 uint32_t OutputFile::get32LE(uint8_t* loc
) { return LittleEndian::get32(*(uint32_t*)loc
); }
975 void OutputFile::set32LE(uint8_t* loc
, uint32_t value
) { LittleEndian::set32(*(uint32_t*)loc
, value
); }
977 uint64_t OutputFile::get64LE(uint8_t* loc
) { return LittleEndian::get64(*(uint64_t*)loc
); }
978 void OutputFile::set64LE(uint8_t* loc
, uint64_t value
) { LittleEndian::set64(*(uint64_t*)loc
, value
); }
980 uint16_t OutputFile::get16BE(uint8_t* loc
) { return BigEndian::get16(*(uint16_t*)loc
); }
981 void OutputFile::set16BE(uint8_t* loc
, uint16_t value
) { BigEndian::set16(*(uint16_t*)loc
, value
); }
983 uint32_t OutputFile::get32BE(uint8_t* loc
) { return BigEndian::get32(*(uint32_t*)loc
); }
984 void OutputFile::set32BE(uint8_t* loc
, uint32_t value
) { BigEndian::set32(*(uint32_t*)loc
, value
); }
986 uint64_t OutputFile::get64BE(uint8_t* loc
) { return BigEndian::get64(*(uint64_t*)loc
); }
987 void OutputFile::set64BE(uint8_t* loc
, uint64_t value
) { BigEndian::set64(*(uint64_t*)loc
, value
); }
989 void OutputFile::applyFixUps(ld::Internal
& state
, uint64_t mhAddress
, const ld::Atom
* atom
, uint8_t* buffer
)
991 //fprintf(stderr, "applyFixUps() on %s\n", atom->name());
992 int64_t accumulator
= 0;
993 const ld::Atom
* toTarget
= NULL
;
994 const ld::Atom
* fromTarget
;
996 uint32_t instruction
;
997 uint32_t newInstruction
;
1001 bool thumbTarget
= false;
1002 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(), end
=atom
->fixupsEnd(); fit
!= end
; ++fit
) {
1003 uint8_t* fixUpLocation
= &buffer
[fit
->offsetInAtom
];
1004 switch ( (ld::Fixup::Kind
)(fit
->kind
) ) {
1005 case ld::Fixup::kindNone
:
1006 case ld::Fixup::kindNoneFollowOn
:
1007 case ld::Fixup::kindNoneGroupSubordinate
:
1008 case ld::Fixup::kindNoneGroupSubordinateFDE
:
1009 case ld::Fixup::kindNoneGroupSubordinateLSDA
:
1010 case ld::Fixup::kindNoneGroupSubordinatePersonality
:
1012 case ld::Fixup::kindSetTargetAddress
:
1013 accumulator
= addressOf(state
, fit
, &toTarget
);
1014 thumbTarget
= targetIsThumb(state
, fit
);
1017 if ( fit
->contentAddendOnly
|| fit
->contentDetlaToAddendOnly
)
1020 case ld::Fixup::kindSubtractTargetAddress
:
1021 delta
= addressOf(state
, fit
, &fromTarget
);
1022 if ( ! fit
->contentAddendOnly
)
1023 accumulator
-= delta
;
1025 case ld::Fixup::kindAddAddend
:
1026 // <rdar://problem/8342028> ARM main executables main contain .long constants pointing
1027 // into themselves such as jump tables. These .long should not have thumb bit set
1028 // even though the target is a thumb instruction. We can tell it is an interior pointer
1029 // because we are processing an addend.
1030 if ( thumbTarget
&& (toTarget
== atom
) && ((int32_t)fit
->u
.addend
> 0) ) {
1031 accumulator
&= (-2);
1032 //warning("removing thumb bit from intra-atom pointer in %s %s+0x%0X",
1033 // atom->section().sectionName(), atom->name(), fit->offsetInAtom);
1035 accumulator
+= fit
->u
.addend
;
1037 case ld::Fixup::kindSubtractAddend
:
1038 accumulator
-= fit
->u
.addend
;
1040 case ld::Fixup::kindSetTargetImageOffset
:
1041 accumulator
= addressOf(state
, fit
, &toTarget
) - mhAddress
;
1043 case ld::Fixup::kindSetTargetSectionOffset
:
1044 accumulator
= sectionOffsetOf(state
, fit
);
1046 case ld::Fixup::kindSetTargetTLVTemplateOffset
:
1047 accumulator
= tlvTemplateOffsetOf(state
, fit
);
1049 case ld::Fixup::kindStore8
:
1050 *fixUpLocation
+= accumulator
;
1052 case ld::Fixup::kindStoreLittleEndian16
:
1053 set16LE(fixUpLocation
, accumulator
);
1055 case ld::Fixup::kindStoreLittleEndianLow24of32
:
1056 set32LE(fixUpLocation
, (get32LE(fixUpLocation
) & 0xFF000000) | (accumulator
& 0x00FFFFFF) );
1058 case ld::Fixup::kindStoreLittleEndian32
:
1059 rangeCheckAbsolute32(accumulator
, state
, atom
, fit
);
1060 set32LE(fixUpLocation
, accumulator
);
1062 case ld::Fixup::kindStoreLittleEndian64
:
1063 set64LE(fixUpLocation
, accumulator
);
1065 case ld::Fixup::kindStoreBigEndian16
:
1066 set16BE(fixUpLocation
, accumulator
);
1068 case ld::Fixup::kindStoreBigEndianLow24of32
:
1069 set32BE(fixUpLocation
, (get32BE(fixUpLocation
) & 0xFF000000) | (accumulator
& 0x00FFFFFF) );
1071 case ld::Fixup::kindStoreBigEndian32
:
1072 rangeCheckAbsolute32(accumulator
, state
, atom
, fit
);
1073 set32BE(fixUpLocation
, accumulator
);
1075 case ld::Fixup::kindStoreBigEndian64
:
1076 set64BE(fixUpLocation
, accumulator
);
1078 case ld::Fixup::kindStoreX86PCRel8
:
1079 case ld::Fixup::kindStoreX86BranchPCRel8
:
1080 if ( fit
->contentAddendOnly
)
1081 delta
= accumulator
;
1083 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 1);
1084 rangeCheck8(delta
, state
, atom
, fit
);
1085 *fixUpLocation
= delta
;
1087 case ld::Fixup::kindStoreX86PCRel16
:
1088 if ( fit
->contentAddendOnly
)
1089 delta
= accumulator
;
1091 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 2);
1092 rangeCheck16(delta
, state
, atom
, fit
);
1093 set16LE(fixUpLocation
, delta
);
1095 case ld::Fixup::kindStoreX86BranchPCRel32
:
1096 if ( fit
->contentAddendOnly
)
1097 delta
= accumulator
;
1099 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1100 rangeCheckBranch32(delta
, state
, atom
, fit
);
1101 set32LE(fixUpLocation
, delta
);
1103 case ld::Fixup::kindStoreX86PCRel32GOTLoad
:
1104 case ld::Fixup::kindStoreX86PCRel32GOT
:
1105 case ld::Fixup::kindStoreX86PCRel32
:
1106 case ld::Fixup::kindStoreX86PCRel32TLVLoad
:
1107 if ( fit
->contentAddendOnly
)
1108 delta
= accumulator
;
1110 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1111 rangeCheckRIP32(delta
, state
, atom
, fit
);
1112 set32LE(fixUpLocation
, delta
);
1114 case ld::Fixup::kindStoreX86PCRel32_1
:
1115 if ( fit
->contentAddendOnly
)
1116 delta
= accumulator
- 1;
1118 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 5);
1119 rangeCheckRIP32(delta
, state
, atom
, fit
);
1120 set32LE(fixUpLocation
, delta
);
1122 case ld::Fixup::kindStoreX86PCRel32_2
:
1123 if ( fit
->contentAddendOnly
)
1124 delta
= accumulator
- 2;
1126 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 6);
1127 rangeCheckRIP32(delta
, state
, atom
, fit
);
1128 set32LE(fixUpLocation
, delta
);
1130 case ld::Fixup::kindStoreX86PCRel32_4
:
1131 if ( fit
->contentAddendOnly
)
1132 delta
= accumulator
- 4;
1134 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 8);
1135 rangeCheckRIP32(delta
, state
, atom
, fit
);
1136 set32LE(fixUpLocation
, delta
);
1138 case ld::Fixup::kindStoreX86Abs32TLVLoad
:
1139 set32LE(fixUpLocation
, accumulator
);
1141 case ld::Fixup::kindStoreX86Abs32TLVLoadNowLEA
:
1142 assert(_options
.outputKind() != Options::kObjectFile
);
1143 // TLV entry was optimized away, change movl instruction to a leal
1144 if ( fixUpLocation
[-1] != 0xA1 )
1145 throw "TLV load reloc does not point to a movl instruction";
1146 fixUpLocation
[-1] = 0xB8;
1147 set32LE(fixUpLocation
, accumulator
);
1149 case ld::Fixup::kindStoreX86PCRel32GOTLoadNowLEA
:
1150 assert(_options
.outputKind() != Options::kObjectFile
);
1151 // GOT entry was optimized away, change movq instruction to a leaq
1152 if ( fixUpLocation
[-2] != 0x8B )
1153 throw "GOT load reloc does not point to a movq instruction";
1154 fixUpLocation
[-2] = 0x8D;
1155 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1156 rangeCheckRIP32(delta
, state
, atom
, fit
);
1157 set32LE(fixUpLocation
, delta
);
1159 case ld::Fixup::kindStoreX86PCRel32TLVLoadNowLEA
:
1160 assert(_options
.outputKind() != Options::kObjectFile
);
1161 // TLV entry was optimized away, change movq instruction to a leaq
1162 if ( fixUpLocation
[-2] != 0x8B )
1163 throw "TLV load reloc does not point to a movq instruction";
1164 fixUpLocation
[-2] = 0x8D;
1165 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1166 rangeCheckRIP32(delta
, state
, atom
, fit
);
1167 set32LE(fixUpLocation
, delta
);
1169 case ld::Fixup::kindStoreTargetAddressARMLoad12
:
1170 accumulator
= addressOf(state
, fit
, &toTarget
);
1171 // fall into kindStoreARMLoad12 case
1172 case ld::Fixup::kindStoreARMLoad12
:
1173 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 8);
1174 rangeCheckARM12(delta
, state
, atom
, fit
);
1175 instruction
= get32LE(fixUpLocation
);
1177 newInstruction
= instruction
& 0xFFFFF000;
1178 newInstruction
|= ((uint32_t)delta
& 0xFFF);
1181 newInstruction
= instruction
& 0xFF7FF000;
1182 newInstruction
|= ((uint32_t)(-delta
) & 0xFFF);
1184 set32LE(fixUpLocation
, newInstruction
);
1186 case ld::Fixup::kindDtraceExtra
:
1188 case ld::Fixup::kindStoreX86DtraceCallSiteNop
:
1189 if ( _options
.outputKind() != Options::kObjectFile
) {
1190 // change call site to a NOP
1191 fixUpLocation
[-1] = 0x90; // 1-byte nop
1192 fixUpLocation
[0] = 0x0F; // 4-byte nop
1193 fixUpLocation
[1] = 0x1F;
1194 fixUpLocation
[2] = 0x40;
1195 fixUpLocation
[3] = 0x00;
1198 case ld::Fixup::kindStoreX86DtraceIsEnableSiteClear
:
1199 if ( _options
.outputKind() != Options::kObjectFile
) {
1200 // change call site to a clear eax
1201 fixUpLocation
[-1] = 0x33; // xorl eax,eax
1202 fixUpLocation
[0] = 0xC0;
1203 fixUpLocation
[1] = 0x90; // 1-byte nop
1204 fixUpLocation
[2] = 0x90; // 1-byte nop
1205 fixUpLocation
[3] = 0x90; // 1-byte nop
1208 case ld::Fixup::kindStoreARMDtraceCallSiteNop
:
1209 if ( _options
.outputKind() != Options::kObjectFile
) {
1210 // change call site to a NOP
1211 set32LE(fixUpLocation
, 0xE1A00000);
1214 case ld::Fixup::kindStoreARMDtraceIsEnableSiteClear
:
1215 if ( _options
.outputKind() != Options::kObjectFile
) {
1216 // change call site to 'eor r0, r0, r0'
1217 set32LE(fixUpLocation
, 0xE0200000);
1220 case ld::Fixup::kindStoreThumbDtraceCallSiteNop
:
1221 if ( _options
.outputKind() != Options::kObjectFile
) {
1222 // change 32-bit blx call site to two thumb NOPs
1223 set32LE(fixUpLocation
, 0x46C046C0);
1226 case ld::Fixup::kindStoreThumbDtraceIsEnableSiteClear
:
1227 if ( _options
.outputKind() != Options::kObjectFile
) {
1228 // change 32-bit blx call site to 'nop', 'eor r0, r0'
1229 set32LE(fixUpLocation
, 0x46C04040);
1232 case ld::Fixup::kindLazyTarget
:
1234 case ld::Fixup::kindSetLazyOffset
:
1235 assert(fit
->binding
== ld::Fixup::bindingDirectlyBound
);
1236 accumulator
= this->lazyBindingInfoOffsetForLazyPointerAddress(fit
->u
.target
->finalAddress());
1238 case ld::Fixup::kindDataInCodeStartData
:
1239 case ld::Fixup::kindDataInCodeStartJT8
:
1240 case ld::Fixup::kindDataInCodeStartJT16
:
1241 case ld::Fixup::kindDataInCodeStartJT32
:
1242 case ld::Fixup::kindDataInCodeStartJTA32
:
1243 case ld::Fixup::kindDataInCodeEnd
:
1245 case ld::Fixup::kindStoreTargetAddressLittleEndian32
:
1246 accumulator
= addressOf(state
, fit
, &toTarget
);
1247 thumbTarget
= targetIsThumb(state
, fit
);
1250 if ( fit
->contentAddendOnly
)
1252 rangeCheckAbsolute32(accumulator
, state
, atom
, fit
);
1253 set32LE(fixUpLocation
, accumulator
);
1255 case ld::Fixup::kindStoreTargetAddressLittleEndian64
:
1256 accumulator
= addressOf(state
, fit
, &toTarget
);
1257 if ( fit
->contentAddendOnly
)
1259 set64LE(fixUpLocation
, accumulator
);
1261 case ld::Fixup::kindStoreTargetAddressBigEndian32
:
1262 accumulator
= addressOf(state
, fit
, &toTarget
);
1263 if ( fit
->contentAddendOnly
)
1265 set32BE(fixUpLocation
, accumulator
);
1267 case ld::Fixup::kindStoreTargetAddressBigEndian64
:
1268 accumulator
= addressOf(state
, fit
, &toTarget
);
1269 if ( fit
->contentAddendOnly
)
1271 set64BE(fixUpLocation
, accumulator
);
1273 case ld::Fixup::kindSetTargetTLVTemplateOffsetLittleEndian32
:
1274 accumulator
= tlvTemplateOffsetOf(state
, fit
);
1275 set32LE(fixUpLocation
, accumulator
);
1277 case ld::Fixup::kindSetTargetTLVTemplateOffsetLittleEndian64
:
1278 accumulator
= tlvTemplateOffsetOf(state
, fit
);
1279 set64LE(fixUpLocation
, accumulator
);
1281 case ld::Fixup::kindStoreTargetAddressX86PCRel32
:
1282 case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32
:
1283 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad
:
1284 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoad
:
1285 accumulator
= addressOf(state
, fit
, &toTarget
);
1286 if ( fit
->contentDetlaToAddendOnly
)
1288 if ( fit
->contentAddendOnly
)
1291 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1292 rangeCheckRIP32(delta
, state
, atom
, fit
);
1293 set32LE(fixUpLocation
, delta
);
1295 case ld::Fixup::kindStoreTargetAddressX86Abs32TLVLoad
:
1296 set32LE(fixUpLocation
, accumulator
);
1298 case ld::Fixup::kindStoreTargetAddressX86Abs32TLVLoadNowLEA
:
1299 // TLV entry was optimized away, change movl instruction to a leal
1300 if ( fixUpLocation
[-1] != 0xA1 )
1301 throw "TLV load reloc does not point to a movl <abs-address>,<reg> instruction";
1302 fixUpLocation
[-1] = 0xB8;
1303 accumulator
= addressOf(state
, fit
, &toTarget
);
1304 set32LE(fixUpLocation
, accumulator
);
1306 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA
:
1307 // GOT entry was optimized away, change movq instruction to a leaq
1308 if ( fixUpLocation
[-2] != 0x8B )
1309 throw "GOT load reloc does not point to a movq instruction";
1310 fixUpLocation
[-2] = 0x8D;
1311 accumulator
= addressOf(state
, fit
, &toTarget
);
1312 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1313 rangeCheckRIP32(delta
, state
, atom
, fit
);
1314 set32LE(fixUpLocation
, delta
);
1316 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoadNowLEA
:
1317 // TLV entry was optimized away, change movq instruction to a leaq
1318 if ( fixUpLocation
[-2] != 0x8B )
1319 throw "TLV load reloc does not point to a movq instruction";
1320 fixUpLocation
[-2] = 0x8D;
1321 accumulator
= addressOf(state
, fit
, &toTarget
);
1322 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1323 rangeCheckRIP32(delta
, state
, atom
, fit
);
1324 set32LE(fixUpLocation
, delta
);
1326 case ld::Fixup::kindStoreTargetAddressARMBranch24
:
1327 accumulator
= addressOf(state
, fit
, &toTarget
);
1328 thumbTarget
= targetIsThumb(state
, fit
);
1331 if ( fit
->contentDetlaToAddendOnly
)
1333 // fall into kindStoreARMBranch24 case
1334 case ld::Fixup::kindStoreARMBranch24
:
1335 // The pc added will be +8 from the pc
1336 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 8);
1337 rangeCheckARMBranch24(delta
, state
, atom
, fit
);
1338 instruction
= get32LE(fixUpLocation
);
1339 // Make sure we are calling arm with bl, thumb with blx
1340 is_bl
= ((instruction
& 0xFF000000) == 0xEB000000);
1341 is_blx
= ((instruction
& 0xFE000000) == 0xFA000000);
1342 is_b
= !is_blx
&& ((instruction
& 0x0F000000) == 0x0A000000);
1343 if ( is_bl
&& thumbTarget
) {
1344 uint32_t opcode
= 0xFA000000;
1345 uint32_t disp
= (uint32_t)(delta
>> 2) & 0x00FFFFFF;
1346 uint32_t h_bit
= (uint32_t)(delta
<< 23) & 0x01000000;
1347 newInstruction
= opcode
| h_bit
| disp
;
1349 else if ( is_blx
&& !thumbTarget
) {
1350 uint32_t opcode
= 0xEB000000;
1351 uint32_t disp
= (uint32_t)(delta
>> 2) & 0x00FFFFFF;
1352 newInstruction
= opcode
| disp
;
1354 else if ( is_b
&& thumbTarget
) {
1355 if ( fit
->contentDetlaToAddendOnly
)
1356 newInstruction
= (instruction
& 0xFF000000) | ((uint32_t)(delta
>> 2) & 0x00FFFFFF);
1358 throwf("no pc-rel bx arm instruction. Can't fix up branch to %s in %s",
1359 referenceTargetAtomName(state
, fit
), atom
->name());
1361 else if ( !is_bl
&& !is_blx
&& thumbTarget
) {
1362 throwf("don't know how to convert instruction %x referencing %s to thumb",
1363 instruction
, referenceTargetAtomName(state
, fit
));
1366 newInstruction
= (instruction
& 0xFF000000) | ((uint32_t)(delta
>> 2) & 0x00FFFFFF);
1368 set32LE(fixUpLocation
, newInstruction
);
1370 case ld::Fixup::kindStoreTargetAddressThumbBranch22
:
1371 accumulator
= addressOf(state
, fit
, &toTarget
);
1372 thumbTarget
= targetIsThumb(state
, fit
);
1375 if ( fit
->contentDetlaToAddendOnly
)
1377 // fall into kindStoreThumbBranch22 case
1378 case ld::Fixup::kindStoreThumbBranch22
:
1379 instruction
= get32LE(fixUpLocation
);
1380 is_bl
= ((instruction
& 0xD000F800) == 0xD000F000);
1381 is_blx
= ((instruction
& 0xD000F800) == 0xC000F000);
1382 is_b
= ((instruction
& 0xD000F800) == 0x9000F000);
1383 // If the target is not thumb, we will be generating a blx instruction
1384 // Since blx cannot have the low bit set, set bit[1] of the target to
1385 // bit[1] of the base address, so that the difference is a multiple of
1387 if ( !thumbTarget
&& !fit
->contentDetlaToAddendOnly
) {
1388 accumulator
&= -3ULL;
1389 accumulator
|= ((atom
->finalAddress() + fit
->offsetInAtom
) & 2LL);
1391 // The pc added will be +4 from the pc
1392 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1393 rangeCheckThumbBranch22(delta
, state
, atom
, fit
);
1394 if ( _options
.preferSubArchitecture() && _options
.archSupportsThumb2() ) {
1395 // The instruction is really two instructions:
1396 // The lower 16 bits are the first instruction, which contains the high
1397 // 11 bits of the displacement.
1398 // The upper 16 bits are the second instruction, which contains the low
1399 // 11 bits of the displacement, as well as differentiating bl and blx.
1400 uint32_t s
= (uint32_t)(delta
>> 24) & 0x1;
1401 uint32_t i1
= (uint32_t)(delta
>> 23) & 0x1;
1402 uint32_t i2
= (uint32_t)(delta
>> 22) & 0x1;
1403 uint32_t imm10
= (uint32_t)(delta
>> 12) & 0x3FF;
1404 uint32_t imm11
= (uint32_t)(delta
>> 1) & 0x7FF;
1405 uint32_t j1
= (i1
== s
);
1406 uint32_t j2
= (i2
== s
);
1409 instruction
= 0xD000F000; // keep bl
1411 instruction
= 0xC000F000; // change to blx
1413 else if ( is_blx
) {
1415 instruction
= 0xD000F000; // change to bl
1417 instruction
= 0xC000F000; // keep blx
1420 instruction
= 0x9000F000; // keep b
1421 if ( !thumbTarget
&& !fit
->contentDetlaToAddendOnly
) {
1422 throwf("armv7 has no pc-rel bx thumb instruction. Can't fix up branch to %s in %s",
1423 referenceTargetAtomName(state
, fit
), atom
->name());
1428 throwf("don't know how to convert branch instruction %x referencing %s to bx",
1429 instruction
, referenceTargetAtomName(state
, fit
));
1430 instruction
= 0x9000F000; // keep b
1432 uint32_t nextDisp
= (j1
<< 13) | (j2
<< 11) | imm11
;
1433 uint32_t firstDisp
= (s
<< 10) | imm10
;
1434 newInstruction
= instruction
| (nextDisp
<< 16) | firstDisp
;
1435 //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",
1436 // s, j1, j2, imm10, imm11, instruction, firstDisp, nextDisp, newInstruction, delta, atom->name(), toTarget->name());
1437 set32LE(fixUpLocation
, newInstruction
);
1440 // The instruction is really two instructions:
1441 // The lower 16 bits are the first instruction, which contains the high
1442 // 11 bits of the displacement.
1443 // The upper 16 bits are the second instruction, which contains the low
1444 // 11 bits of the displacement, as well as differentiating bl and blx.
1445 uint32_t firstDisp
= (uint32_t)(delta
>> 12) & 0x7FF;
1446 uint32_t nextDisp
= (uint32_t)(delta
>> 1) & 0x7FF;
1447 if ( is_bl
&& !thumbTarget
) {
1448 instruction
= 0xE800F000;
1450 else if ( is_blx
&& thumbTarget
) {
1451 instruction
= 0xF800F000;
1454 instruction
= 0x9000F000; // keep b
1455 if ( !thumbTarget
&& !fit
->contentDetlaToAddendOnly
) {
1456 throwf("armv6 has no pc-rel bx thumb instruction. Can't fix up branch to %s in %s",
1457 referenceTargetAtomName(state
, fit
), atom
->name());
1461 instruction
= instruction
& 0xF800F800;
1463 newInstruction
= instruction
| (nextDisp
<< 16) | firstDisp
;
1464 set32LE(fixUpLocation
, newInstruction
);
1467 case ld::Fixup::kindStoreARMLow16
:
1469 uint32_t imm4
= (accumulator
& 0x0000F000) >> 12;
1470 uint32_t imm12
= accumulator
& 0x00000FFF;
1471 instruction
= get32LE(fixUpLocation
);
1472 newInstruction
= (instruction
& 0xFFF0F000) | (imm4
<< 16) | imm12
;
1473 set32LE(fixUpLocation
, newInstruction
);
1476 case ld::Fixup::kindStoreARMHigh16
:
1478 uint32_t imm4
= (accumulator
& 0xF0000000) >> 28;
1479 uint32_t imm12
= (accumulator
& 0x0FFF0000) >> 16;
1480 instruction
= get32LE(fixUpLocation
);
1481 newInstruction
= (instruction
& 0xFFF0F000) | (imm4
<< 16) | imm12
;
1482 set32LE(fixUpLocation
, newInstruction
);
1485 case ld::Fixup::kindStoreThumbLow16
:
1487 uint32_t imm4
= (accumulator
& 0x0000F000) >> 12;
1488 uint32_t i
= (accumulator
& 0x00000800) >> 11;
1489 uint32_t imm3
= (accumulator
& 0x00000700) >> 8;
1490 uint32_t imm8
= accumulator
& 0x000000FF;
1491 instruction
= get32LE(fixUpLocation
);
1492 newInstruction
= (instruction
& 0x8F00FBF0) | imm4
| (i
<< 10) | (imm3
<< 28) | (imm8
<< 16);
1493 set32LE(fixUpLocation
, newInstruction
);
1496 case ld::Fixup::kindStoreThumbHigh16
:
1498 uint32_t imm4
= (accumulator
& 0xF0000000) >> 28;
1499 uint32_t i
= (accumulator
& 0x08000000) >> 27;
1500 uint32_t imm3
= (accumulator
& 0x07000000) >> 24;
1501 uint32_t imm8
= (accumulator
& 0x00FF0000) >> 16;
1502 instruction
= get32LE(fixUpLocation
);
1503 newInstruction
= (instruction
& 0x8F00FBF0) | imm4
| (i
<< 10) | (imm3
<< 28) | (imm8
<< 16);
1504 set32LE(fixUpLocation
, newInstruction
);
1511 void OutputFile::copyNoOps(uint8_t* from
, uint8_t* to
, bool thumb
)
1513 switch ( _options
.architecture() ) {
1515 case CPU_TYPE_X86_64
:
1516 for (uint8_t* p
=from
; p
< to
; ++p
)
1521 for (uint8_t* p
=from
; p
< to
; p
+= 2)
1522 OSWriteLittleInt16((uint16_t*)p
, 0, 0x46c0);
1525 for (uint8_t* p
=from
; p
< to
; p
+= 4)
1526 OSWriteLittleInt32((uint32_t*)p
, 0, 0xe1a00000);
1530 for (uint8_t* p
=from
; p
< to
; ++p
)
1536 bool OutputFile::takesNoDiskSpace(const ld::Section
* sect
)
1538 switch ( sect
->type() ) {
1539 case ld::Section::typeZeroFill
:
1540 case ld::Section::typeTLVZeroFill
:
1541 return _options
.optimizeZeroFill();
1542 case ld::Section::typePageZero
:
1543 case ld::Section::typeStack
:
1544 case ld::Section::typeAbsoluteSymbols
:
1545 case ld::Section::typeTentativeDefs
:
1553 bool OutputFile::hasZeroForFileOffset(const ld::Section
* sect
)
1555 switch ( sect
->type() ) {
1556 case ld::Section::typeZeroFill
:
1557 case ld::Section::typeTLVZeroFill
:
1558 return _options
.optimizeZeroFill();
1559 case ld::Section::typePageZero
:
1560 case ld::Section::typeStack
:
1561 case ld::Section::typeTentativeDefs
:
1569 void OutputFile::writeAtoms(ld::Internal
& state
, uint8_t* wholeBuffer
)
1571 // have each atom write itself
1572 uint64_t fileOffsetOfEndOfLastAtom
= 0;
1573 uint64_t mhAddress
= 0;
1574 bool lastAtomUsesNoOps
= false;
1575 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
1576 ld::Internal::FinalSection
* sect
= *sit
;
1577 if ( sect
->type() == ld::Section::typeMachHeader
)
1578 mhAddress
= sect
->address
;
1579 if ( takesNoDiskSpace(sect
) )
1581 const bool sectionUsesNops
= (sect
->type() == ld::Section::typeCode
);
1582 //fprintf(stderr, "file offset=0x%08llX, section %s\n", sect->fileOffset, sect->sectionName());
1583 std::vector
<const ld::Atom
*>& atoms
= sect
->atoms
;
1584 bool lastAtomWasThumb
= false;
1585 for (std::vector
<const ld::Atom
*>::iterator ait
= atoms
.begin(); ait
!= atoms
.end(); ++ait
) {
1586 const ld::Atom
* atom
= *ait
;
1587 if ( atom
->definition() == ld::Atom::definitionProxy
)
1590 uint64_t fileOffset
= atom
->finalAddress() - sect
->address
+ sect
->fileOffset
;
1591 // check for alignment padding between atoms
1592 if ( (fileOffset
!= fileOffsetOfEndOfLastAtom
) && lastAtomUsesNoOps
) {
1593 this->copyNoOps(&wholeBuffer
[fileOffsetOfEndOfLastAtom
], &wholeBuffer
[fileOffset
], lastAtomWasThumb
);
1595 // copy atom content
1596 atom
->copyRawContent(&wholeBuffer
[fileOffset
]);
1598 this->applyFixUps(state
, mhAddress
, atom
, &wholeBuffer
[fileOffset
]);
1599 fileOffsetOfEndOfLastAtom
= fileOffset
+atom
->size();
1600 lastAtomUsesNoOps
= sectionUsesNops
;
1601 lastAtomWasThumb
= atom
->isThumb();
1603 catch (const char* msg
) {
1604 if ( atom
->file() != NULL
)
1605 throwf("%s in '%s' from %s", msg
, atom
->name(), atom
->file()->path());
1607 throwf("%s in '%s'", msg
, atom
->name());
1614 void OutputFile::computeContentUUID(ld::Internal
& state
, uint8_t* wholeBuffer
)
1616 const bool log
= false;
1617 if ( (_options
.outputKind() != Options::kObjectFile
) || state
.someObjectFileHasDwarf
) {
1618 uint8_t digest
[CC_MD5_DIGEST_LENGTH
];
1619 uint32_t stabsStringsOffsetStart
;
1620 uint32_t tabsStringsOffsetEnd
;
1621 uint32_t stabsOffsetStart
;
1622 uint32_t stabsOffsetEnd
;
1623 if ( _symbolTableAtom
->hasStabs(stabsStringsOffsetStart
, tabsStringsOffsetEnd
, stabsOffsetStart
, stabsOffsetEnd
) ) {
1624 // find two areas of file that are stabs info and should not contribute to checksum
1625 uint64_t stringPoolFileOffset
= 0;
1626 uint64_t symbolTableFileOffset
= 0;
1627 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
1628 ld::Internal::FinalSection
* sect
= *sit
;
1629 if ( sect
->type() == ld::Section::typeLinkEdit
) {
1630 if ( strcmp(sect
->sectionName(), "__string_pool") == 0 )
1631 stringPoolFileOffset
= sect
->fileOffset
;
1632 else if ( strcmp(sect
->sectionName(), "__symbol_table") == 0 )
1633 symbolTableFileOffset
= sect
->fileOffset
;
1636 uint64_t firstStabNlistFileOffset
= symbolTableFileOffset
+ stabsOffsetStart
;
1637 uint64_t lastStabNlistFileOffset
= symbolTableFileOffset
+ stabsOffsetEnd
;
1638 uint64_t firstStabStringFileOffset
= stringPoolFileOffset
+ stabsStringsOffsetStart
;
1639 uint64_t lastStabStringFileOffset
= stringPoolFileOffset
+ tabsStringsOffsetEnd
;
1640 if ( log
) fprintf(stderr
, "firstStabNlistFileOffset=0x%08llX\n", firstStabNlistFileOffset
);
1641 if ( log
) fprintf(stderr
, "lastStabNlistFileOffset=0x%08llX\n", lastStabNlistFileOffset
);
1642 if ( log
) fprintf(stderr
, "firstStabStringFileOffset=0x%08llX\n", firstStabStringFileOffset
);
1643 if ( log
) fprintf(stderr
, "lastStabStringFileOffset=0x%08llX\n", lastStabStringFileOffset
);
1644 assert(firstStabNlistFileOffset
<= firstStabStringFileOffset
);
1646 CC_MD5_CTX md5state
;
1647 CC_MD5_Init(&md5state
);
1648 // checksum everything up to first stabs nlist
1649 if ( log
) fprintf(stderr
, "checksum 0x%08X -> 0x%08llX\n", 0, firstStabNlistFileOffset
);
1650 CC_MD5_Update(&md5state
, &wholeBuffer
[0], firstStabNlistFileOffset
);
1651 // checkusm everything after last stabs nlist and up to first stabs string
1652 if ( log
) fprintf(stderr
, "checksum 0x%08llX -> 0x%08llX\n", lastStabNlistFileOffset
, firstStabStringFileOffset
);
1653 CC_MD5_Update(&md5state
, &wholeBuffer
[lastStabNlistFileOffset
], firstStabStringFileOffset
-lastStabNlistFileOffset
);
1654 // checksum everything after last stabs string to end of file
1655 if ( log
) fprintf(stderr
, "checksum 0x%08llX -> 0x%08llX\n", lastStabStringFileOffset
, _fileSize
);
1656 CC_MD5_Update(&md5state
, &wholeBuffer
[lastStabStringFileOffset
], _fileSize
-lastStabStringFileOffset
);
1657 CC_MD5_Final(digest
, &md5state
);
1658 if ( log
) fprintf(stderr
, "uuid=%02X, %02X, %02X, %02X, %02X, %02X, %02X, %02X\n", digest
[0], digest
[1], digest
[2],
1659 digest
[3], digest
[4], digest
[5], digest
[6], digest
[7]);
1662 CC_MD5(wholeBuffer
, _fileSize
, digest
);
1664 // <rdar://problem/6723729> LC_UUID uuids should conform to RFC 4122 UUID version 4 & UUID version 5 formats
1665 digest
[6] = ( digest
[6] & 0x0F ) | ( 3 << 4 );
1666 digest
[8] = ( digest
[8] & 0x3F ) | 0x80;
1667 // update buffer with new UUID
1668 _headersAndLoadCommandAtom
->setUUID(digest
);
1669 _headersAndLoadCommandAtom
->recopyUUIDCommand();
1674 void OutputFile::writeOutputFile(ld::Internal
& state
)
1676 // for UNIX conformance, error if file exists and is not writable
1677 if ( (access(_options
.outputFilePath(), F_OK
) == 0) && (access(_options
.outputFilePath(), W_OK
) == -1) )
1678 throwf("can't write output file: %s", _options
.outputFilePath());
1680 mode_t permissions
= 0777;
1681 if ( _options
.outputKind() == Options::kObjectFile
)
1683 mode_t umask
= ::umask(0);
1684 ::umask(umask
); // put back the original umask
1685 permissions
&= ~umask
;
1686 // Calling unlink first assures the file is gone so that open creates it with correct permissions
1687 // It also handles the case where __options.outputFilePath() file is not writable but its directory is
1688 // And it means we don't have to truncate the file when done writing (in case new is smaller than old)
1689 // Lastly, only delete existing file if it is a normal file (e.g. not /dev/null).
1690 struct stat stat_buf
;
1691 bool outputIsRegularFile
= false;
1692 bool outputIsMappableFile
= false;
1693 if ( stat(_options
.outputFilePath(), &stat_buf
) != -1 ) {
1694 if (stat_buf
.st_mode
& S_IFREG
) {
1695 outputIsRegularFile
= true;
1696 // <rdar://problem/12264302> Don't use mmap on non-hfs volumes
1697 struct statfs fsInfo
;
1698 if ( statfs(_options
.outputFilePath(), &fsInfo
) != -1 ) {
1699 if ( strcmp(fsInfo
.f_fstypename
, "hfs") == 0) {
1700 (void)unlink(_options
.outputFilePath());
1701 outputIsMappableFile
= true;
1705 outputIsMappableFile
= false;
1709 outputIsRegularFile
= false;
1713 // special files (pipes, devices, etc) must already exist
1714 outputIsRegularFile
= true;
1715 // output file does not exist yet
1716 char dirPath
[PATH_MAX
];
1717 strcpy(dirPath
, _options
.outputFilePath());
1718 char* end
= strrchr(dirPath
, '/');
1719 if ( end
!= NULL
) {
1721 struct statfs fsInfo
;
1722 if ( statfs(dirPath
, &fsInfo
) != -1 ) {
1723 if ( strcmp(fsInfo
.f_fstypename
, "hfs") == 0) {
1724 outputIsMappableFile
= true;
1730 //fprintf(stderr, "outputIsMappableFile=%d, outputIsRegularFile=%d, path=%s\n", outputIsMappableFile, outputIsRegularFile, _options.outputFilePath());
1733 // Construct a temporary path of the form {outputFilePath}.ld_XXXXXX
1734 const char filenameTemplate
[] = ".ld_XXXXXX";
1735 char tmpOutput
[PATH_MAX
];
1736 uint8_t *wholeBuffer
;
1737 if ( outputIsRegularFile
&& outputIsMappableFile
) {
1738 strcpy(tmpOutput
, _options
.outputFilePath());
1739 // If the path is too long to add a suffix for a temporary name then
1740 // just fall back to using the output path.
1741 if (strlen(tmpOutput
)+strlen(filenameTemplate
) < PATH_MAX
) {
1742 strcat(tmpOutput
, filenameTemplate
);
1743 fd
= mkstemp(tmpOutput
);
1746 fd
= open(tmpOutput
, O_RDWR
|O_CREAT
, permissions
);
1749 throwf("can't open output file for writing: %s, errno=%d", tmpOutput
, errno
);
1750 ftruncate(fd
, _fileSize
);
1752 wholeBuffer
= (uint8_t *)mmap(NULL
, _fileSize
, PROT_WRITE
|PROT_READ
, MAP_SHARED
, fd
, 0);
1753 if ( wholeBuffer
== MAP_FAILED
)
1754 throwf("can't create buffer of %llu bytes for output", _fileSize
);
1757 if ( outputIsRegularFile
)
1758 fd
= open(_options
.outputFilePath(), O_RDWR
|O_CREAT
, permissions
);
1760 fd
= open(_options
.outputFilePath(), O_WRONLY
);
1762 throwf("can't open output file for writing: %s, errno=%d", _options
.outputFilePath(), errno
);
1763 // try to allocate buffer for entire output file content
1764 wholeBuffer
= (uint8_t*)calloc(_fileSize
, 1);
1765 if ( wholeBuffer
== NULL
)
1766 throwf("can't create buffer of %llu bytes for output", _fileSize
);
1769 if ( _options
.UUIDMode() == Options::kUUIDRandom
) {
1771 ::uuid_generate_random(bits
);
1772 _headersAndLoadCommandAtom
->setUUID(bits
);
1775 writeAtoms(state
, wholeBuffer
);
1778 if ( _options
.UUIDMode() == Options::kUUIDContent
)
1779 computeContentUUID(state
, wholeBuffer
);
1781 if ( outputIsRegularFile
&& outputIsMappableFile
) {
1782 if ( ::chmod(tmpOutput
, permissions
) == -1 ) {
1784 throwf("can't set permissions on output file: %s, errno=%d", tmpOutput
, errno
);
1786 if ( ::rename(tmpOutput
, _options
.outputFilePath()) == -1 && strcmp(tmpOutput
, _options
.outputFilePath()) != 0) {
1788 throwf("can't move output file in place, errno=%d", errno
);
1792 if ( ::write(fd
, wholeBuffer
, _fileSize
) == -1 ) {
1793 throwf("can't write to output file: %s, errno=%d", _options
.outputFilePath(), errno
);
1798 struct AtomByNameSorter
1800 bool operator()(const ld::Atom
* left
, const ld::Atom
* right
)
1802 return (strcmp(left
->name(), right
->name()) < 0);
1809 NotInSet(const std::set
<const ld::Atom
*>& theSet
) : _set(theSet
) {}
1811 bool operator()(const ld::Atom
* atom
) const {
1812 return ( _set
.count(atom
) == 0 );
1815 const std::set
<const ld::Atom
*>& _set
;
1819 void OutputFile::buildSymbolTable(ld::Internal
& state
)
1821 unsigned int machoSectionIndex
= 0;
1822 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
1823 ld::Internal::FinalSection
* sect
= *sit
;
1824 bool setMachoSectionIndex
= !sect
->isSectionHidden() && (sect
->type() != ld::Section::typeTentativeDefs
);
1825 if ( setMachoSectionIndex
)
1826 ++machoSectionIndex
;
1827 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
1828 const ld::Atom
* atom
= *ait
;
1829 if ( setMachoSectionIndex
)
1830 (const_cast<ld::Atom
*>(atom
))->setMachoSection(machoSectionIndex
);
1831 else if ( sect
->type() == ld::Section::typeMachHeader
)
1832 (const_cast<ld::Atom
*>(atom
))->setMachoSection(1); // __mh_execute_header is not in any section by needs n_sect==1
1833 else if ( sect
->type() == ld::Section::typeLastSection
)
1834 (const_cast<ld::Atom
*>(atom
))->setMachoSection(machoSectionIndex
); // use section index of previous section
1835 else if ( sect
->type() == ld::Section::typeFirstSection
)
1836 (const_cast<ld::Atom
*>(atom
))->setMachoSection(machoSectionIndex
+1); // use section index of next section
1838 // in -r mode, clarify symbolTableNotInFinalLinkedImages
1839 if ( _options
.outputKind() == Options::kObjectFile
) {
1840 if ( _options
.architecture() == CPU_TYPE_X86_64
) {
1841 // x86_64 .o files need labels on anonymous literal strings
1842 if ( (sect
->type() == ld::Section::typeCString
) && (atom
->combine() == ld::Atom::combineByNameAndContent
) ) {
1843 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableIn
);
1844 _localAtoms
.push_back(atom
);
1848 if ( sect
->type() == ld::Section::typeCFI
) {
1849 if ( _options
.removeEHLabels() )
1850 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableNotIn
);
1852 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableIn
);
1854 if ( atom
->symbolTableInclusion() == ld::Atom::symbolTableNotInFinalLinkedImages
)
1855 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableIn
);
1858 // TEMP work around until <rdar://problem/7702923> goes in
1859 if ( (atom
->symbolTableInclusion() == ld::Atom::symbolTableInAndNeverStrip
)
1860 && (atom
->scope() == ld::Atom::scopeLinkageUnit
)
1861 && (_options
.outputKind() == Options::kDynamicLibrary
) ) {
1862 (const_cast<ld::Atom
*>(atom
))->setScope(ld::Atom::scopeGlobal
);
1865 // <rdar://problem/6783167> support auto hidden weak symbols: .weak_def_can_be_hidden
1866 if ( atom
->autoHide() && (_options
.outputKind() != Options::kObjectFile
) ) {
1867 // adding auto-hide symbol to .exp file should keep it global
1868 if ( !_options
.hasExportMaskList() || !_options
.shouldExport(atom
->name()) )
1869 (const_cast<ld::Atom
*>(atom
))->setScope(ld::Atom::scopeLinkageUnit
);
1872 // <rdar://problem/8626058> ld should consistently warn when resolvers are not exported
1873 if ( (atom
->contentType() == ld::Atom::typeResolver
) && (atom
->scope() == ld::Atom::scopeLinkageUnit
) )
1874 warning("resolver functions should be external, but '%s' is hidden", atom
->name());
1876 if ( sect
->type() == ld::Section::typeImportProxies
) {
1877 if ( atom
->combine() == ld::Atom::combineByName
)
1878 this->usesWeakExternalSymbols
= true;
1879 // alias proxy is a re-export with a name change, don't import changed name
1880 if ( ! atom
->isAlias() )
1881 _importedAtoms
.push_back(atom
);
1882 // scope of proxies are usually linkage unit, so done
1883 // if scope is global, we need to re-export it too
1884 if ( atom
->scope() == ld::Atom::scopeGlobal
)
1885 _exportedAtoms
.push_back(atom
);
1888 if ( atom
->symbolTableInclusion() == ld::Atom::symbolTableNotInFinalLinkedImages
) {
1889 assert(_options
.outputKind() != Options::kObjectFile
);
1890 continue; // don't add to symbol table
1892 if ( atom
->symbolTableInclusion() == ld::Atom::symbolTableNotIn
) {
1893 continue; // don't add to symbol table
1895 if ( (atom
->symbolTableInclusion() == ld::Atom::symbolTableInWithRandomAutoStripLabel
)
1896 && (_options
.outputKind() != Options::kObjectFile
) ) {
1897 continue; // don't add to symbol table
1900 if ( (atom
->definition() == ld::Atom::definitionTentative
) && (_options
.outputKind() == Options::kObjectFile
) ) {
1901 if ( _options
.makeTentativeDefinitionsReal() ) {
1902 // -r -d turns tentative defintions into real def
1903 _exportedAtoms
.push_back(atom
);
1906 // in mach-o object files tentative defintions are stored like undefined symbols
1907 _importedAtoms
.push_back(atom
);
1912 switch ( atom
->scope() ) {
1913 case ld::Atom::scopeTranslationUnit
:
1914 if ( _options
.keepLocalSymbol(atom
->name()) ) {
1915 _localAtoms
.push_back(atom
);
1918 if ( _options
.outputKind() == Options::kObjectFile
) {
1919 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableInWithRandomAutoStripLabel
);
1920 _localAtoms
.push_back(atom
);
1923 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableNotIn
);
1926 case ld::Atom::scopeGlobal
:
1927 _exportedAtoms
.push_back(atom
);
1929 case ld::Atom::scopeLinkageUnit
:
1930 if ( _options
.outputKind() == Options::kObjectFile
) {
1931 if ( _options
.keepPrivateExterns() ) {
1932 assert( (atom
->combine() == ld::Atom::combineNever
) || (atom
->combine() == ld::Atom::combineByName
) );
1933 _exportedAtoms
.push_back(atom
);
1935 else if ( _options
.keepLocalSymbol(atom
->name()) ) {
1936 _localAtoms
.push_back(atom
);
1939 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableInWithRandomAutoStripLabel
);
1940 _localAtoms
.push_back(atom
);
1944 if ( _options
.keepLocalSymbol(atom
->name()) )
1945 _localAtoms
.push_back(atom
);
1946 // <rdar://problem/5804214> ld should never have a symbol in the non-lazy indirect symbol table with index 0
1947 // this works by making __mh_execute_header be a local symbol which takes symbol index 0
1948 else if ( (atom
->symbolTableInclusion() == ld::Atom::symbolTableInAndNeverStrip
) && !_options
.makeCompressedDyldInfo() )
1949 _localAtoms
.push_back(atom
);
1951 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableNotIn
);
1958 // <rdar://problem/6978069> ld adds undefined symbol from .exp file to binary
1959 if ( (_options
.outputKind() == Options::kKextBundle
) && _options
.hasExportRestrictList() ) {
1960 // search for referenced undefines
1961 std::set
<const ld::Atom
*> referencedProxyAtoms
;
1962 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
=state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
1963 ld::Internal::FinalSection
* sect
= *sit
;
1964 for (std::vector
<const ld::Atom
*>::iterator ait
=sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
1965 const ld::Atom
* atom
= *ait
;
1966 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(), end
=atom
->fixupsEnd(); fit
!= end
; ++fit
) {
1967 switch ( fit
->binding
) {
1968 case ld::Fixup::bindingsIndirectlyBound
:
1969 referencedProxyAtoms
.insert(state
.indirectBindingTable
[fit
->u
.bindingIndex
]);
1971 case ld::Fixup::bindingDirectlyBound
:
1972 referencedProxyAtoms
.insert(fit
->u
.target
);
1980 // remove any unreferenced _importedAtoms
1981 _importedAtoms
.erase(std::remove_if(_importedAtoms
.begin(), _importedAtoms
.end(), NotInSet(referencedProxyAtoms
)), _importedAtoms
.end());
1985 std::sort(_exportedAtoms
.begin(), _exportedAtoms
.end(), AtomByNameSorter());
1986 std::sort(_importedAtoms
.begin(), _importedAtoms
.end(), AtomByNameSorter());
1989 void OutputFile::addPreloadLinkEdit(ld::Internal
& state
)
1991 switch ( _options
.architecture() ) {
1992 #if SUPPORT_ARCH_i386
1994 if ( _hasLocalRelocations
) {
1995 _localRelocsAtom
= new LocalRelocationsAtom
<x86
>(_options
, state
, *this);
1996 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
1998 if ( _hasExternalRelocations
) {
1999 _externalRelocsAtom
= new ExternalRelocationsAtom
<x86
>(_options
, state
, *this);
2000 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
2002 if ( _hasSymbolTable
) {
2003 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<x86
>(_options
, state
, *this);
2004 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
2005 _symbolTableAtom
= new SymbolTableAtom
<x86
>(_options
, state
, *this);
2006 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
2007 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 4);
2008 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
2012 #if SUPPORT_ARCH_x86_64
2013 case CPU_TYPE_X86_64
:
2014 if ( _hasLocalRelocations
) {
2015 _localRelocsAtom
= new LocalRelocationsAtom
<x86_64
>(_options
, state
, *this);
2016 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
2018 if ( _hasExternalRelocations
) {
2019 _externalRelocsAtom
= new ExternalRelocationsAtom
<x86_64
>(_options
, state
, *this);
2020 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
2022 if ( _hasSymbolTable
) {
2023 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<x86_64
>(_options
, state
, *this);
2024 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
2025 _symbolTableAtom
= new SymbolTableAtom
<x86_64
>(_options
, state
, *this);
2026 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
2027 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 4);
2028 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
2032 #if SUPPORT_ARCH_arm_any
2034 if ( _hasLocalRelocations
) {
2035 _localRelocsAtom
= new LocalRelocationsAtom
<arm
>(_options
, state
, *this);
2036 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
2038 if ( _hasExternalRelocations
) {
2039 _externalRelocsAtom
= new ExternalRelocationsAtom
<arm
>(_options
, state
, *this);
2040 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
2042 if ( _hasSymbolTable
) {
2043 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<arm
>(_options
, state
, *this);
2044 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
2045 _symbolTableAtom
= new SymbolTableAtom
<arm
>(_options
, state
, *this);
2046 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
2047 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 4);
2048 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
2053 throw "architecture not supported for -preload";
2059 void OutputFile::addLinkEdit(ld::Internal
& state
)
2061 // for historical reasons, -preload orders LINKEDIT content differently
2062 if ( _options
.outputKind() == Options::kPreload
)
2063 return addPreloadLinkEdit(state
);
2065 switch ( _options
.architecture() ) {
2066 #if SUPPORT_ARCH_i386
2068 if ( _hasSectionRelocations
) {
2069 _sectionsRelocationsAtom
= new SectionRelocationsAtom
<x86
>(_options
, state
, *this);
2070 sectionRelocationsSection
= state
.addAtom(*_sectionsRelocationsAtom
);
2072 if ( _hasDyldInfo
) {
2073 _rebasingInfoAtom
= new RebaseInfoAtom
<x86
>(_options
, state
, *this);
2074 rebaseSection
= state
.addAtom(*_rebasingInfoAtom
);
2076 _bindingInfoAtom
= new BindingInfoAtom
<x86
>(_options
, state
, *this);
2077 bindingSection
= state
.addAtom(*_bindingInfoAtom
);
2079 _weakBindingInfoAtom
= new WeakBindingInfoAtom
<x86
>(_options
, state
, *this);
2080 weakBindingSection
= state
.addAtom(*_weakBindingInfoAtom
);
2082 _lazyBindingInfoAtom
= new LazyBindingInfoAtom
<x86
>(_options
, state
, *this);
2083 lazyBindingSection
= state
.addAtom(*_lazyBindingInfoAtom
);
2085 _exportInfoAtom
= new ExportInfoAtom
<x86
>(_options
, state
, *this);
2086 exportSection
= state
.addAtom(*_exportInfoAtom
);
2088 if ( _hasLocalRelocations
) {
2089 _localRelocsAtom
= new LocalRelocationsAtom
<x86
>(_options
, state
, *this);
2090 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
2092 if ( _hasSplitSegInfo
) {
2093 _splitSegInfoAtom
= new SplitSegInfoAtom
<x86
>(_options
, state
, *this);
2094 splitSegInfoSection
= state
.addAtom(*_splitSegInfoAtom
);
2096 if ( _hasFunctionStartsInfo
) {
2097 _functionStartsAtom
= new FunctionStartsAtom
<x86
>(_options
, state
, *this);
2098 functionStartsSection
= state
.addAtom(*_functionStartsAtom
);
2100 if ( _hasDataInCodeInfo
) {
2101 _dataInCodeAtom
= new DataInCodeAtom
<x86
>(_options
, state
, *this);
2102 dataInCodeSection
= state
.addAtom(*_dataInCodeAtom
);
2104 if ( _hasDependentDRInfo
) {
2105 _dependentDRInfoAtom
= new DependentDRAtom
<x86
>(_options
, state
, *this);
2106 dependentDRsSection
= state
.addAtom(*_dependentDRInfoAtom
);
2108 if ( _hasSymbolTable
) {
2109 _symbolTableAtom
= new SymbolTableAtom
<x86
>(_options
, state
, *this);
2110 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
2112 if ( _hasExternalRelocations
) {
2113 _externalRelocsAtom
= new ExternalRelocationsAtom
<x86
>(_options
, state
, *this);
2114 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
2116 if ( _hasSymbolTable
) {
2117 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<x86
>(_options
, state
, *this);
2118 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
2119 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 4);
2120 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
2124 #if SUPPORT_ARCH_x86_64
2125 case CPU_TYPE_X86_64
:
2126 if ( _hasSectionRelocations
) {
2127 _sectionsRelocationsAtom
= new SectionRelocationsAtom
<x86_64
>(_options
, state
, *this);
2128 sectionRelocationsSection
= state
.addAtom(*_sectionsRelocationsAtom
);
2130 if ( _hasDyldInfo
) {
2131 _rebasingInfoAtom
= new RebaseInfoAtom
<x86_64
>(_options
, state
, *this);
2132 rebaseSection
= state
.addAtom(*_rebasingInfoAtom
);
2134 _bindingInfoAtom
= new BindingInfoAtom
<x86_64
>(_options
, state
, *this);
2135 bindingSection
= state
.addAtom(*_bindingInfoAtom
);
2137 _weakBindingInfoAtom
= new WeakBindingInfoAtom
<x86_64
>(_options
, state
, *this);
2138 weakBindingSection
= state
.addAtom(*_weakBindingInfoAtom
);
2140 _lazyBindingInfoAtom
= new LazyBindingInfoAtom
<x86_64
>(_options
, state
, *this);
2141 lazyBindingSection
= state
.addAtom(*_lazyBindingInfoAtom
);
2143 _exportInfoAtom
= new ExportInfoAtom
<x86_64
>(_options
, state
, *this);
2144 exportSection
= state
.addAtom(*_exportInfoAtom
);
2146 if ( _hasLocalRelocations
) {
2147 _localRelocsAtom
= new LocalRelocationsAtom
<x86_64
>(_options
, state
, *this);
2148 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
2150 if ( _hasSplitSegInfo
) {
2151 _splitSegInfoAtom
= new SplitSegInfoAtom
<x86_64
>(_options
, state
, *this);
2152 splitSegInfoSection
= state
.addAtom(*_splitSegInfoAtom
);
2154 if ( _hasFunctionStartsInfo
) {
2155 _functionStartsAtom
= new FunctionStartsAtom
<x86_64
>(_options
, state
, *this);
2156 functionStartsSection
= state
.addAtom(*_functionStartsAtom
);
2158 if ( _hasDataInCodeInfo
) {
2159 _dataInCodeAtom
= new DataInCodeAtom
<x86_64
>(_options
, state
, *this);
2160 dataInCodeSection
= state
.addAtom(*_dataInCodeAtom
);
2162 if ( _hasDependentDRInfo
) {
2163 _dependentDRInfoAtom
= new DependentDRAtom
<x86_64
>(_options
, state
, *this);
2164 dependentDRsSection
= state
.addAtom(*_dependentDRInfoAtom
);
2166 if ( _hasSymbolTable
) {
2167 _symbolTableAtom
= new SymbolTableAtom
<x86_64
>(_options
, state
, *this);
2168 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
2170 if ( _hasExternalRelocations
) {
2171 _externalRelocsAtom
= new ExternalRelocationsAtom
<x86_64
>(_options
, state
, *this);
2172 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
2174 if ( _hasSymbolTable
) {
2175 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<x86_64
>(_options
, state
, *this);
2176 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
2177 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 8);
2178 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
2182 #if SUPPORT_ARCH_arm_any
2184 if ( _hasSectionRelocations
) {
2185 _sectionsRelocationsAtom
= new SectionRelocationsAtom
<arm
>(_options
, state
, *this);
2186 sectionRelocationsSection
= state
.addAtom(*_sectionsRelocationsAtom
);
2188 if ( _hasDyldInfo
) {
2189 _rebasingInfoAtom
= new RebaseInfoAtom
<arm
>(_options
, state
, *this);
2190 rebaseSection
= state
.addAtom(*_rebasingInfoAtom
);
2192 _bindingInfoAtom
= new BindingInfoAtom
<arm
>(_options
, state
, *this);
2193 bindingSection
= state
.addAtom(*_bindingInfoAtom
);
2195 _weakBindingInfoAtom
= new WeakBindingInfoAtom
<arm
>(_options
, state
, *this);
2196 weakBindingSection
= state
.addAtom(*_weakBindingInfoAtom
);
2198 _lazyBindingInfoAtom
= new LazyBindingInfoAtom
<arm
>(_options
, state
, *this);
2199 lazyBindingSection
= state
.addAtom(*_lazyBindingInfoAtom
);
2201 _exportInfoAtom
= new ExportInfoAtom
<arm
>(_options
, state
, *this);
2202 exportSection
= state
.addAtom(*_exportInfoAtom
);
2204 if ( _hasLocalRelocations
) {
2205 _localRelocsAtom
= new LocalRelocationsAtom
<arm
>(_options
, state
, *this);
2206 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
2208 if ( _hasSplitSegInfo
) {
2209 _splitSegInfoAtom
= new SplitSegInfoAtom
<arm
>(_options
, state
, *this);
2210 splitSegInfoSection
= state
.addAtom(*_splitSegInfoAtom
);
2212 if ( _hasFunctionStartsInfo
) {
2213 _functionStartsAtom
= new FunctionStartsAtom
<arm
>(_options
, state
, *this);
2214 functionStartsSection
= state
.addAtom(*_functionStartsAtom
);
2216 if ( _hasDataInCodeInfo
) {
2217 _dataInCodeAtom
= new DataInCodeAtom
<arm
>(_options
, state
, *this);
2218 dataInCodeSection
= state
.addAtom(*_dataInCodeAtom
);
2220 if ( _hasDependentDRInfo
) {
2221 _dependentDRInfoAtom
= new DependentDRAtom
<arm
>(_options
, state
, *this);
2222 dependentDRsSection
= state
.addAtom(*_dependentDRInfoAtom
);
2224 if ( _hasSymbolTable
) {
2225 _symbolTableAtom
= new SymbolTableAtom
<arm
>(_options
, state
, *this);
2226 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
2228 if ( _hasExternalRelocations
) {
2229 _externalRelocsAtom
= new ExternalRelocationsAtom
<arm
>(_options
, state
, *this);
2230 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
2232 if ( _hasSymbolTable
) {
2233 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<arm
>(_options
, state
, *this);
2234 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
2235 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 4);
2236 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
2241 throw "unknown architecture";
2245 void OutputFile::addLoadCommands(ld::Internal
& state
)
2247 switch ( _options
.architecture() ) {
2248 #if SUPPORT_ARCH_x86_64
2249 case CPU_TYPE_X86_64
:
2250 _headersAndLoadCommandAtom
= new HeaderAndLoadCommandsAtom
<x86_64
>(_options
, state
, *this);
2251 headerAndLoadCommandsSection
= state
.addAtom(*_headersAndLoadCommandAtom
);
2254 #if SUPPORT_ARCH_arm_any
2256 _headersAndLoadCommandAtom
= new HeaderAndLoadCommandsAtom
<arm
>(_options
, state
, *this);
2257 headerAndLoadCommandsSection
= state
.addAtom(*_headersAndLoadCommandAtom
);
2260 #if SUPPORT_ARCH_i386
2262 _headersAndLoadCommandAtom
= new HeaderAndLoadCommandsAtom
<x86
>(_options
, state
, *this);
2263 headerAndLoadCommandsSection
= state
.addAtom(*_headersAndLoadCommandAtom
);
2267 throw "unknown architecture";
2271 uint32_t OutputFile::dylibCount()
2273 return _dylibsToLoad
.size();
2276 const ld::dylib::File
* OutputFile::dylibByOrdinal(unsigned int ordinal
)
2278 assert( ordinal
> 0 );
2279 assert( ordinal
<= _dylibsToLoad
.size() );
2280 return _dylibsToLoad
[ordinal
-1];
2283 bool OutputFile::hasOrdinalForInstallPath(const char* path
, int* ordinal
)
2285 for (std::map
<const ld::dylib::File
*, int>::const_iterator it
= _dylibToOrdinal
.begin(); it
!= _dylibToOrdinal
.end(); ++it
) {
2286 const char* installPath
= it
->first
->installPath();
2287 if ( (installPath
!= NULL
) && (strcmp(path
, installPath
) == 0) ) {
2288 *ordinal
= it
->second
;
2295 uint32_t OutputFile::dylibToOrdinal(const ld::dylib::File
* dylib
)
2297 return _dylibToOrdinal
[dylib
];
2301 void OutputFile::buildDylibOrdinalMapping(ld::Internal
& state
)
2303 // count non-public re-exported dylibs
2304 unsigned int nonPublicReExportCount
= 0;
2305 for (std::vector
<ld::dylib::File
*>::iterator it
= state
.dylibs
.begin(); it
!= state
.dylibs
.end(); ++it
) {
2306 ld::dylib::File
* aDylib
= *it
;
2307 if ( aDylib
->willBeReExported() && ! aDylib
->hasPublicInstallName() )
2308 ++nonPublicReExportCount
;
2311 // look at each dylib supplied in state
2312 bool hasReExports
= false;
2313 bool haveLazyDylibs
= false;
2314 for (std::vector
<ld::dylib::File
*>::iterator it
= state
.dylibs
.begin(); it
!= state
.dylibs
.end(); ++it
) {
2315 ld::dylib::File
* aDylib
= *it
;
2317 if ( aDylib
== state
.bundleLoader
) {
2318 _dylibToOrdinal
[aDylib
] = BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE
;
2320 else if ( this->hasOrdinalForInstallPath(aDylib
->installPath(), &ordinal
) ) {
2321 // already have a dylib with that install path, map all uses to that ordinal
2322 _dylibToOrdinal
[aDylib
] = ordinal
;
2324 else if ( aDylib
->willBeLazyLoadedDylib() ) {
2325 // all lazy dylib need to be at end of ordinals
2326 haveLazyDylibs
= true;
2328 else if ( aDylib
->willBeReExported() && ! aDylib
->hasPublicInstallName() && (nonPublicReExportCount
>= 2) ) {
2329 _dylibsToLoad
.push_back(aDylib
);
2330 _dylibToOrdinal
[aDylib
] = BIND_SPECIAL_DYLIB_SELF
;
2333 // first time this install path seen, create new ordinal
2334 _dylibsToLoad
.push_back(aDylib
);
2335 _dylibToOrdinal
[aDylib
] = _dylibsToLoad
.size();
2337 if ( aDylib
->explicitlyLinked() && aDylib
->willBeReExported() )
2338 hasReExports
= true;
2340 if ( haveLazyDylibs
) {
2341 // second pass to determine ordinals for lazy loaded dylibs
2342 for (std::vector
<ld::dylib::File
*>::iterator it
= state
.dylibs
.begin(); it
!= state
.dylibs
.end(); ++it
) {
2343 ld::dylib::File
* aDylib
= *it
;
2344 if ( aDylib
->willBeLazyLoadedDylib() ) {
2346 if ( this->hasOrdinalForInstallPath(aDylib
->installPath(), &ordinal
) ) {
2347 // already have a dylib with that install path, map all uses to that ordinal
2348 _dylibToOrdinal
[aDylib
] = ordinal
;
2351 // first time this install path seen, create new ordinal
2352 _dylibsToLoad
.push_back(aDylib
);
2353 _dylibToOrdinal
[aDylib
] = _dylibsToLoad
.size();
2358 _noReExportedDylibs
= !hasReExports
;
2359 //fprintf(stderr, "dylibs:\n");
2360 //for (std::map<const ld::dylib::File*, int>::const_iterator it = _dylibToOrdinal.begin(); it != _dylibToOrdinal.end(); ++it) {
2361 // fprintf(stderr, " %p ord=%u, install_name=%s\n",it->first, it->second, it->first->installPath());
2365 uint32_t OutputFile::lazyBindingInfoOffsetForLazyPointerAddress(uint64_t lpAddress
)
2367 return _lazyPointerAddressToInfoOffset
[lpAddress
];
2370 void OutputFile::setLazyBindingInfoOffset(uint64_t lpAddress
, uint32_t lpInfoOffset
)
2372 _lazyPointerAddressToInfoOffset
[lpAddress
] = lpInfoOffset
;
2375 int OutputFile::compressedOrdinalForAtom(const ld::Atom
* target
)
2377 // flat namespace images use zero for all ordinals
2378 if ( _options
.nameSpace() != Options::kTwoLevelNameSpace
)
2379 return BIND_SPECIAL_DYLIB_FLAT_LOOKUP
;
2381 // handle -interposable
2382 if ( target
->definition() == ld::Atom::definitionRegular
)
2383 return BIND_SPECIAL_DYLIB_SELF
;
2386 const ld::dylib::File
* dylib
= dynamic_cast<const ld::dylib::File
*>(target
->file());
2387 if ( dylib
!= NULL
) {
2388 std::map
<const ld::dylib::File
*, int>::iterator pos
= _dylibToOrdinal
.find(dylib
);
2389 if ( pos
!= _dylibToOrdinal
.end() )
2391 assert(0 && "dylib not assigned ordinal");
2394 // handle undefined dynamic_lookup
2395 if ( _options
.undefinedTreatment() == Options::kUndefinedDynamicLookup
)
2396 return BIND_SPECIAL_DYLIB_FLAT_LOOKUP
;
2399 if ( _options
.allowedUndefined(target
->name()) )
2400 return BIND_SPECIAL_DYLIB_FLAT_LOOKUP
;
2402 throw "can't find ordinal for imported symbol";
2406 bool OutputFile::isPcRelStore(ld::Fixup::Kind kind
)
2409 case ld::Fixup::kindStoreX86BranchPCRel8
:
2410 case ld::Fixup::kindStoreX86BranchPCRel32
:
2411 case ld::Fixup::kindStoreX86PCRel8
:
2412 case ld::Fixup::kindStoreX86PCRel16
:
2413 case ld::Fixup::kindStoreX86PCRel32
:
2414 case ld::Fixup::kindStoreX86PCRel32_1
:
2415 case ld::Fixup::kindStoreX86PCRel32_2
:
2416 case ld::Fixup::kindStoreX86PCRel32_4
:
2417 case ld::Fixup::kindStoreX86PCRel32GOTLoad
:
2418 case ld::Fixup::kindStoreX86PCRel32GOTLoadNowLEA
:
2419 case ld::Fixup::kindStoreX86PCRel32GOT
:
2420 case ld::Fixup::kindStoreX86PCRel32TLVLoad
:
2421 case ld::Fixup::kindStoreX86PCRel32TLVLoadNowLEA
:
2422 case ld::Fixup::kindStoreARMBranch24
:
2423 case ld::Fixup::kindStoreThumbBranch22
:
2424 case ld::Fixup::kindStoreARMLoad12
:
2425 case ld::Fixup::kindStoreTargetAddressX86PCRel32
:
2426 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad
:
2427 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA
:
2428 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoad
:
2429 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoadNowLEA
:
2430 case ld::Fixup::kindStoreTargetAddressARMBranch24
:
2431 case ld::Fixup::kindStoreTargetAddressThumbBranch22
:
2432 case ld::Fixup::kindStoreTargetAddressARMLoad12
:
2434 case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32
:
2435 return (_options
.outputKind() != Options::kKextBundle
);
2442 bool OutputFile::isStore(ld::Fixup::Kind kind
)
2445 case ld::Fixup::kindNone
:
2446 case ld::Fixup::kindNoneFollowOn
:
2447 case ld::Fixup::kindNoneGroupSubordinate
:
2448 case ld::Fixup::kindNoneGroupSubordinateFDE
:
2449 case ld::Fixup::kindNoneGroupSubordinateLSDA
:
2450 case ld::Fixup::kindNoneGroupSubordinatePersonality
:
2451 case ld::Fixup::kindSetTargetAddress
:
2452 case ld::Fixup::kindSubtractTargetAddress
:
2453 case ld::Fixup::kindAddAddend
:
2454 case ld::Fixup::kindSubtractAddend
:
2455 case ld::Fixup::kindSetTargetImageOffset
:
2456 case ld::Fixup::kindSetTargetSectionOffset
:
2465 bool OutputFile::setsTarget(ld::Fixup::Kind kind
)
2468 case ld::Fixup::kindSetTargetAddress
:
2469 case ld::Fixup::kindLazyTarget
:
2470 case ld::Fixup::kindStoreTargetAddressLittleEndian32
:
2471 case ld::Fixup::kindStoreTargetAddressLittleEndian64
:
2472 case ld::Fixup::kindStoreTargetAddressBigEndian32
:
2473 case ld::Fixup::kindStoreTargetAddressBigEndian64
:
2474 case ld::Fixup::kindStoreTargetAddressX86PCRel32
:
2475 case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32
:
2476 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad
:
2477 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA
:
2478 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoad
:
2479 case ld::Fixup::kindStoreTargetAddressX86Abs32TLVLoad
:
2480 case ld::Fixup::kindStoreTargetAddressARMBranch24
:
2481 case ld::Fixup::kindStoreTargetAddressThumbBranch22
:
2482 case ld::Fixup::kindStoreTargetAddressARMLoad12
:
2484 case ld::Fixup::kindStoreX86DtraceCallSiteNop
:
2485 case ld::Fixup::kindStoreX86DtraceIsEnableSiteClear
:
2486 case ld::Fixup::kindStoreARMDtraceCallSiteNop
:
2487 case ld::Fixup::kindStoreARMDtraceIsEnableSiteClear
:
2488 case ld::Fixup::kindStoreThumbDtraceCallSiteNop
:
2489 case ld::Fixup::kindStoreThumbDtraceIsEnableSiteClear
:
2490 return (_options
.outputKind() == Options::kObjectFile
);
2497 bool OutputFile::isPointerToTarget(ld::Fixup::Kind kind
)
2500 case ld::Fixup::kindSetTargetAddress
:
2501 case ld::Fixup::kindStoreTargetAddressLittleEndian32
:
2502 case ld::Fixup::kindStoreTargetAddressLittleEndian64
:
2503 case ld::Fixup::kindStoreTargetAddressBigEndian32
:
2504 case ld::Fixup::kindStoreTargetAddressBigEndian64
:
2505 case ld::Fixup::kindLazyTarget
:
2512 bool OutputFile::isPointerFromTarget(ld::Fixup::Kind kind
)
2515 case ld::Fixup::kindSubtractTargetAddress
:
2524 uint64_t OutputFile::lookBackAddend(ld::Fixup::iterator fit
)
2526 uint64_t addend
= 0;
2527 switch ( fit
->clusterSize
) {
2528 case ld::Fixup::k1of1
:
2529 case ld::Fixup::k1of2
:
2530 case ld::Fixup::k2of2
:
2532 case ld::Fixup::k2of3
:
2534 switch ( fit
->kind
) {
2535 case ld::Fixup::kindAddAddend
:
2536 addend
+= fit
->u
.addend
;
2538 case ld::Fixup::kindSubtractAddend
:
2539 addend
-= fit
->u
.addend
;
2542 throw "unexpected fixup kind for binding";
2545 case ld::Fixup::k1of3
:
2547 switch ( fit
->kind
) {
2548 case ld::Fixup::kindAddAddend
:
2549 addend
+= fit
->u
.addend
;
2551 case ld::Fixup::kindSubtractAddend
:
2552 addend
-= fit
->u
.addend
;
2555 throw "unexpected fixup kind for binding";
2559 throw "unexpected fixup cluster size for binding";
2568 void OutputFile::generateLinkEditInfo(ld::Internal
& state
)
2570 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
2571 ld::Internal::FinalSection
* sect
= *sit
;
2572 bool objc1ClassRefSection
= ( (sect
->type() == ld::Section::typeCStringPointer
)
2573 && (strcmp(sect
->sectionName(), "__cls_refs") == 0)
2574 && (strcmp(sect
->segmentName(), "__OBJC") == 0) );
2575 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
2576 const ld::Atom
* atom
= *ait
;
2578 // Record regular atoms that override a dylib's weak definitions
2579 if ( (atom
->scope() == ld::Atom::scopeGlobal
) && atom
->overridesDylibsWeakDef() ) {
2580 if ( _options
.makeCompressedDyldInfo() ) {
2581 uint8_t wtype
= BIND_TYPE_OVERRIDE_OF_WEAKDEF_IN_DYLIB
;
2582 bool nonWeakDef
= (atom
->combine() == ld::Atom::combineNever
);
2583 _weakBindingInfo
.push_back(BindingInfo(wtype
, atom
->name(), nonWeakDef
, atom
->finalAddress(), 0));
2585 this->overridesWeakExternalSymbols
= true;
2586 if ( _options
.warnWeakExports() )
2587 warning("overrides weak external symbol: %s", atom
->name());
2590 ld::Fixup
* fixupWithTarget
= NULL
;
2591 ld::Fixup
* fixupWithMinusTarget
= NULL
;
2592 ld::Fixup
* fixupWithStore
= NULL
;
2593 const ld::Atom
* target
= NULL
;
2594 const ld::Atom
* minusTarget
= NULL
;
2595 uint64_t targetAddend
= 0;
2596 uint64_t minusTargetAddend
= 0;
2597 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(); fit
!= atom
->fixupsEnd(); ++fit
) {
2598 if ( fit
->firstInCluster() ) {
2599 fixupWithTarget
= NULL
;
2600 fixupWithMinusTarget
= NULL
;
2601 fixupWithStore
= NULL
;
2605 minusTargetAddend
= 0;
2607 if ( this->setsTarget(fit
->kind
) ) {
2608 switch ( fit
->binding
) {
2609 case ld::Fixup::bindingNone
:
2610 case ld::Fixup::bindingByNameUnbound
:
2612 case ld::Fixup::bindingByContentBound
:
2613 case ld::Fixup::bindingDirectlyBound
:
2614 fixupWithTarget
= fit
;
2615 target
= fit
->u
.target
;
2617 case ld::Fixup::bindingsIndirectlyBound
:
2618 fixupWithTarget
= fit
;
2619 target
= state
.indirectBindingTable
[fit
->u
.bindingIndex
];
2622 assert(target
!= NULL
);
2624 switch ( fit
->kind
) {
2625 case ld::Fixup::kindAddAddend
:
2626 targetAddend
= fit
->u
.addend
;
2628 case ld::Fixup::kindSubtractAddend
:
2629 minusTargetAddend
= fit
->u
.addend
;
2631 case ld::Fixup::kindSubtractTargetAddress
:
2632 switch ( fit
->binding
) {
2633 case ld::Fixup::bindingNone
:
2634 case ld::Fixup::bindingByNameUnbound
:
2636 case ld::Fixup::bindingByContentBound
:
2637 case ld::Fixup::bindingDirectlyBound
:
2638 fixupWithMinusTarget
= fit
;
2639 minusTarget
= fit
->u
.target
;
2641 case ld::Fixup::bindingsIndirectlyBound
:
2642 fixupWithMinusTarget
= fit
;
2643 minusTarget
= state
.indirectBindingTable
[fit
->u
.bindingIndex
];
2646 assert(minusTarget
!= NULL
);
2648 case ld::Fixup::kindDataInCodeStartData
:
2649 case ld::Fixup::kindDataInCodeStartJT8
:
2650 case ld::Fixup::kindDataInCodeStartJT16
:
2651 case ld::Fixup::kindDataInCodeStartJT32
:
2652 case ld::Fixup::kindDataInCodeStartJTA32
:
2653 case ld::Fixup::kindDataInCodeEnd
:
2654 hasDataInCode
= true;
2659 if ( this->isStore(fit
->kind
) ) {
2660 fixupWithStore
= fit
;
2662 if ( fit
->lastInCluster() ) {
2663 if ( (fixupWithStore
!= NULL
) && (target
!= NULL
) ) {
2664 if ( _options
.outputKind() == Options::kObjectFile
) {
2665 this->addSectionRelocs(state
, sect
, atom
, fixupWithTarget
, fixupWithMinusTarget
, fixupWithStore
,
2666 target
, minusTarget
, targetAddend
, minusTargetAddend
);
2669 if ( _options
.makeCompressedDyldInfo() ) {
2670 this->addDyldInfo(state
, sect
, atom
, fixupWithTarget
, fixupWithMinusTarget
, fixupWithStore
,
2671 target
, minusTarget
, targetAddend
, minusTargetAddend
);
2674 this->addClassicRelocs(state
, sect
, atom
, fixupWithTarget
, fixupWithMinusTarget
, fixupWithStore
,
2675 target
, minusTarget
, targetAddend
, minusTargetAddend
);
2679 else if ( objc1ClassRefSection
&& (target
!= NULL
) && (fixupWithStore
== NULL
) ) {
2680 // check for class refs to lazy loaded dylibs
2681 const ld::dylib::File
* dylib
= dynamic_cast<const ld::dylib::File
*>(target
->file());
2682 if ( (dylib
!= NULL
) && dylib
->willBeLazyLoadedDylib() )
2683 throwf("illegal class reference to %s in lazy loaded dylib %s", target
->name(), dylib
->path());
2692 void OutputFile::noteTextReloc(const ld::Atom
* atom
, const ld::Atom
* target
)
2694 if ( (atom
->contentType() == ld::Atom::typeStub
) || (atom
->contentType() == ld::Atom::typeStubHelper
) ) {
2695 // silently let stubs (synthesized by linker) use text relocs
2697 else if ( _options
.allowTextRelocs() ) {
2698 if ( _options
.warnAboutTextRelocs() )
2699 warning("text reloc in %s to %s", atom
->name(), target
->name());
2701 else if ( _options
.positionIndependentExecutable() && (_options
.outputKind() == Options::kDynamicExecutable
)
2702 && ((_options
.iOSVersionMin() >= ld::iOS_4_3
) || (_options
.macosxVersionMin() >= ld::mac10_7
)) ) {
2703 if ( ! this->pieDisabled
) {
2704 warning("PIE disabled. Absolute addressing (perhaps -mdynamic-no-pic) not allowed in code signed PIE, "
2705 "but used in %s from %s. "
2706 "To fix this warning, don't compile with -mdynamic-no-pic or link with -Wl,-no_pie",
2707 atom
->name(), atom
->file()->path());
2709 this->pieDisabled
= true;
2711 else if ( (target
->scope() == ld::Atom::scopeGlobal
) && (target
->combine() == ld::Atom::combineByName
) ) {
2712 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());
2715 throwf("illegal text-relocation to %s in %s from %s in %s", target
->name(), target
->file()->path(), atom
->name(), atom
->file()->path());
2719 void OutputFile::addDyldInfo(ld::Internal
& state
, ld::Internal::FinalSection
* sect
, const ld::Atom
* atom
,
2720 ld::Fixup
* fixupWithTarget
, ld::Fixup
* fixupWithMinusTarget
, ld::Fixup
* fixupWithStore
,
2721 const ld::Atom
* target
, const ld::Atom
* minusTarget
,
2722 uint64_t targetAddend
, uint64_t minusTargetAddend
)
2724 if ( sect
->isSectionHidden() )
2727 // no need to rebase or bind PCRel stores
2728 if ( this->isPcRelStore(fixupWithStore
->kind
) ) {
2729 // as long as target is in same linkage unit
2730 if ( (target
== NULL
) || (target
->definition() != ld::Atom::definitionProxy
) ) {
2731 // make sure target is not global and weak
2732 if ( (target
->scope() == ld::Atom::scopeGlobal
) && (target
->combine() == ld::Atom::combineByName
) && (target
->definition() == ld::Atom::definitionRegular
)) {
2733 if ( (atom
->section().type() == ld::Section::typeCFI
)
2734 || (atom
->section().type() == ld::Section::typeDtraceDOF
)
2735 || (atom
->section().type() == ld::Section::typeUnwindInfo
) ) {
2736 // ok for __eh_frame and __uwind_info to use pointer diffs to global weak symbols
2739 // Have direct reference to weak-global. This should be an indrect reference
2740 const char* demangledName
= strdup(_options
.demangleSymbol(atom
->name()));
2741 warning("direct access in %s to global weak symbol %s means the weak symbol cannot be overridden at runtime. "
2742 "This was likely caused by different translation units being compiled with different visibility settings.",
2743 demangledName
, _options
.demangleSymbol(target
->name()));
2749 // no need to rebase or bind PIC internal pointer diff
2750 if ( minusTarget
!= NULL
) {
2751 // with pointer diffs, both need to be in same linkage unit
2752 assert(minusTarget
->definition() != ld::Atom::definitionProxy
);
2753 assert(target
!= NULL
);
2754 assert(target
->definition() != ld::Atom::definitionProxy
);
2755 if ( target
== minusTarget
) {
2756 // This is a compile time constant and could have been optimized away by compiler
2760 // check if target of pointer-diff is global and weak
2761 if ( (target
->scope() == ld::Atom::scopeGlobal
) && (target
->combine() == ld::Atom::combineByName
) && (target
->definition() == ld::Atom::definitionRegular
) ) {
2762 if ( (atom
->section().type() == ld::Section::typeCFI
)
2763 || (atom
->section().type() == ld::Section::typeDtraceDOF
)
2764 || (atom
->section().type() == ld::Section::typeUnwindInfo
) ) {
2765 // ok for __eh_frame and __uwind_info to use pointer diffs to global weak symbols
2768 // Have direct reference to weak-global. This should be an indrect reference
2769 const char* demangledName
= strdup(_options
.demangleSymbol(atom
->name()));
2770 warning("direct access in %s to global weak symbol %s means the weak symbol cannot be overridden at runtime. "
2771 "This was likely caused by different translation units being compiled with different visibility settings.",
2772 demangledName
, _options
.demangleSymbol(target
->name()));
2777 // no need to rebase or bind an atom's references to itself if the output is not slidable
2778 if ( (atom
== target
) && !_options
.outputSlidable() )
2781 // cluster has no target, so needs no rebasing or binding
2782 if ( target
== NULL
)
2785 bool inReadOnlySeg
= ( strcmp(sect
->segmentName(), "__TEXT") == 0 );
2786 bool needsRebase
= false;
2787 bool needsBinding
= false;
2788 bool needsLazyBinding
= false;
2789 bool needsWeakBinding
= false;
2791 uint8_t rebaseType
= REBASE_TYPE_POINTER
;
2792 uint8_t type
= BIND_TYPE_POINTER
;
2793 const ld::dylib::File
* dylib
= dynamic_cast<const ld::dylib::File
*>(target
->file());
2794 bool weak_import
= (fixupWithTarget
->weakImport
|| ((dylib
!= NULL
) && dylib
->forcedWeakLinked()));
2795 uint64_t address
= atom
->finalAddress() + fixupWithTarget
->offsetInAtom
;
2796 uint64_t addend
= targetAddend
- minusTargetAddend
;
2798 // special case lazy pointers
2799 if ( fixupWithTarget
->kind
== ld::Fixup::kindLazyTarget
) {
2800 assert(fixupWithTarget
->u
.target
== target
);
2801 assert(addend
== 0);
2802 // lazy dylib lazy pointers do not have any dyld info
2803 if ( atom
->section().type() == ld::Section::typeLazyDylibPointer
)
2805 // lazy binding to weak definitions are done differently
2806 // they are directly bound to target, then have a weak bind in case of a collision
2807 if ( target
->combine() == ld::Atom::combineByName
) {
2808 if ( target
->definition() == ld::Atom::definitionProxy
) {
2809 // weak def exported from another dylib
2810 // must non-lazy bind to it plus have weak binding info in case of collision
2811 needsBinding
= true;
2812 needsWeakBinding
= true;
2815 // weak def in this linkage unit.
2816 // just rebase, plus have weak binding info in case of collision
2817 // this will be done by other cluster on lazy pointer atom
2820 else if ( (target
->contentType() == ld::Atom::typeResolver
) && (target
->scope() != ld::Atom::scopeGlobal
) ) {
2821 // <rdar://problem/8553647> Hidden resolver functions should not have lazy binding info
2822 needsLazyBinding
= false;
2825 // normal case of a pointer to non-weak-def symbol, so can lazily bind
2826 needsLazyBinding
= true;
2830 // everything except lazy pointers
2831 switch ( target
->definition() ) {
2832 case ld::Atom::definitionProxy
:
2833 if ( (dylib
!= NULL
) && dylib
->willBeLazyLoadedDylib() )
2834 throwf("illegal data reference to %s in lazy loaded dylib %s", target
->name(), dylib
->path());
2835 if ( target
->contentType() == ld::Atom::typeTLV
) {
2836 if ( sect
->type() != ld::Section::typeTLVPointers
)
2837 throwf("illegal data reference in %s to thread local variable %s in dylib %s",
2838 atom
->name(), target
->name(), dylib
->path());
2840 if ( inReadOnlySeg
)
2841 type
= BIND_TYPE_TEXT_ABSOLUTE32
;
2842 needsBinding
= true;
2843 if ( target
->combine() == ld::Atom::combineByName
)
2844 needsWeakBinding
= true;
2846 case ld::Atom::definitionRegular
:
2847 case ld::Atom::definitionTentative
:
2848 // only slideable images need rebasing info
2849 if ( _options
.outputSlidable() ) {
2852 // references to internal symbol never need binding
2853 if ( target
->scope() != ld::Atom::scopeGlobal
)
2855 // reference to global weak def needs weak binding
2856 if ( (target
->combine() == ld::Atom::combineByName
) && (target
->definition() == ld::Atom::definitionRegular
) )
2857 needsWeakBinding
= true;
2858 else if ( _options
.outputKind() == Options::kDynamicExecutable
) {
2859 // in main executables, the only way regular symbols are indirected is if -interposable is used
2860 if ( _options
.interposable(target
->name()) ) {
2861 needsRebase
= false;
2862 needsBinding
= true;
2866 // for flat-namespace or interposable two-level-namespace
2867 // all references to exported symbols get indirected
2868 if ( (_options
.nameSpace() != Options::kTwoLevelNameSpace
) || _options
.interposable(target
->name()) ) {
2869 // <rdar://problem/5254468> no external relocs for flat objc classes
2870 if ( strncmp(target
->name(), ".objc_class_", 12) == 0 )
2872 // no rebase info for references to global symbols that will have binding info
2873 needsRebase
= false;
2874 needsBinding
= true;
2878 case ld::Atom::definitionAbsolute
:
2883 // record dyld info for this cluster
2884 if ( needsRebase
) {
2885 if ( inReadOnlySeg
) {
2886 noteTextReloc(atom
, target
);
2887 sect
->hasLocalRelocs
= true; // so dyld knows to change permissions on __TEXT segment
2888 rebaseType
= REBASE_TYPE_TEXT_ABSOLUTE32
;
2890 if ( (addend
!= 0) && _options
.sharedRegionEligible() ) {
2891 // make sure the addend does not cause the pointer to point outside the target's segment
2892 // if it does, update_dyld_shared_cache will not be able to put this dylib into the shared cache
2893 uint64_t targetAddress
= target
->finalAddress();
2894 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
2895 ld::Internal::FinalSection
* sct
= *sit
;
2896 uint64_t sctEnd
= (sct
->address
+sct
->size
);
2897 if ( (sct
->address
<= targetAddress
) && (targetAddress
< sctEnd
) ) {
2898 if ( (targetAddress
+addend
) > sctEnd
) {
2899 warning("data symbol %s from %s has pointer to %s + 0x%08llX. "
2900 "That large of an addend may disable %s from being put in the dyld shared cache.",
2901 atom
->name(), atom
->file()->path(), target
->name(), addend
, _options
.installPath() );
2906 _rebaseInfo
.push_back(RebaseInfo(rebaseType
, address
));
2908 if ( needsBinding
) {
2909 if ( inReadOnlySeg
) {
2910 noteTextReloc(atom
, target
);
2911 sect
->hasExternalRelocs
= true; // so dyld knows to change permissions on __TEXT segment
2913 _bindingInfo
.push_back(BindingInfo(type
, this->compressedOrdinalForAtom(target
), target
->name(), weak_import
, address
, addend
));
2915 if ( needsLazyBinding
) {
2916 if ( _options
.bindAtLoad() )
2917 _bindingInfo
.push_back(BindingInfo(type
, this->compressedOrdinalForAtom(target
), target
->name(), weak_import
, address
, addend
));
2919 _lazyBindingInfo
.push_back(BindingInfo(type
, this->compressedOrdinalForAtom(target
), target
->name(), weak_import
, address
, addend
));
2921 if ( needsWeakBinding
)
2922 _weakBindingInfo
.push_back(BindingInfo(type
, 0, target
->name(), false, address
, addend
));
2926 void OutputFile::addClassicRelocs(ld::Internal
& state
, ld::Internal::FinalSection
* sect
, const ld::Atom
* atom
,
2927 ld::Fixup
* fixupWithTarget
, ld::Fixup
* fixupWithMinusTarget
, ld::Fixup
* fixupWithStore
,
2928 const ld::Atom
* target
, const ld::Atom
* minusTarget
,
2929 uint64_t targetAddend
, uint64_t minusTargetAddend
)
2931 if ( sect
->isSectionHidden() )
2934 // non-lazy-pointer section is encoded in indirect symbol table - not using relocations
2935 if ( sect
->type() == ld::Section::typeNonLazyPointer
) {
2936 // except kexts and static pie which *do* use relocations
2937 switch (_options
.outputKind()) {
2938 case Options::kKextBundle
:
2940 case Options::kStaticExecutable
:
2941 if ( _options
.positionIndependentExecutable() )
2943 // else fall into default case
2945 assert(target
!= NULL
);
2946 assert(fixupWithTarget
!= NULL
);
2951 // no need to rebase or bind PCRel stores
2952 if ( this->isPcRelStore(fixupWithStore
->kind
) ) {
2953 // as long as target is in same linkage unit
2954 if ( (target
== NULL
) || (target
->definition() != ld::Atom::definitionProxy
) )
2958 // no need to rebase or bind PIC internal pointer diff
2959 if ( minusTarget
!= NULL
) {
2960 // with pointer diffs, both need to be in same linkage unit
2961 assert(minusTarget
->definition() != ld::Atom::definitionProxy
);
2962 assert(target
!= NULL
);
2963 assert(target
->definition() != ld::Atom::definitionProxy
);
2964 // make sure target is not global and weak
2965 if ( (target
->scope() == ld::Atom::scopeGlobal
) && (target
->combine() == ld::Atom::combineByName
)
2966 && (atom
->section().type() != ld::Section::typeCFI
)
2967 && (atom
->section().type() != ld::Section::typeDtraceDOF
)
2968 && (atom
->section().type() != ld::Section::typeUnwindInfo
)
2969 && (minusTarget
!= target
) ) {
2970 // ok for __eh_frame and __uwind_info to use pointer diffs to global weak symbols
2971 throwf("bad codegen, pointer diff in %s to global weak symbol %s", atom
->name(), target
->name());
2976 // cluster has no target, so needs no rebasing or binding
2977 if ( target
== NULL
)
2980 assert(_localRelocsAtom
!= NULL
);
2981 uint64_t relocAddress
= atom
->finalAddress() + fixupWithTarget
->offsetInAtom
- _localRelocsAtom
->relocBaseAddress(state
);
2983 bool inReadOnlySeg
= ( strcmp(sect
->segmentName(), "__TEXT") == 0 );
2984 bool needsLocalReloc
= false;
2985 bool needsExternReloc
= false;
2987 switch ( fixupWithStore
->kind
) {
2988 case ld::Fixup::kindLazyTarget
:
2989 // lazy pointers don't need relocs
2991 case ld::Fixup::kindStoreLittleEndian32
:
2992 case ld::Fixup::kindStoreLittleEndian64
:
2993 case ld::Fixup::kindStoreBigEndian32
:
2994 case ld::Fixup::kindStoreBigEndian64
:
2995 case ld::Fixup::kindStoreTargetAddressLittleEndian32
:
2996 case ld::Fixup::kindStoreTargetAddressLittleEndian64
:
2997 case ld::Fixup::kindStoreTargetAddressBigEndian32
:
2998 case ld::Fixup::kindStoreTargetAddressBigEndian64
:
3000 switch ( target
->definition() ) {
3001 case ld::Atom::definitionProxy
:
3002 needsExternReloc
= true;
3004 case ld::Atom::definitionRegular
:
3005 case ld::Atom::definitionTentative
:
3006 // only slideable images need local relocs
3007 if ( _options
.outputSlidable() )
3008 needsLocalReloc
= true;
3009 // references to internal symbol never need binding
3010 if ( target
->scope() != ld::Atom::scopeGlobal
)
3012 // reference to global weak def needs weak binding in dynamic images
3013 if ( (target
->combine() == ld::Atom::combineByName
)
3014 && (target
->definition() == ld::Atom::definitionRegular
)
3015 && (_options
.outputKind() != Options::kStaticExecutable
)
3016 && (_options
.outputKind() != Options::kPreload
) ) {
3017 needsExternReloc
= true;
3019 else if ( _options
.outputKind() == Options::kDynamicExecutable
) {
3020 // in main executables, the only way regular symbols are indirected is if -interposable is used
3021 if ( _options
.interposable(target
->name()) )
3022 needsExternReloc
= true;
3025 // for flat-namespace or interposable two-level-namespace
3026 // all references to exported symbols get indirected
3027 if ( (_options
.nameSpace() != Options::kTwoLevelNameSpace
) || _options
.interposable(target
->name()) ) {
3028 // <rdar://problem/5254468> no external relocs for flat objc classes
3029 if ( strncmp(target
->name(), ".objc_class_", 12) == 0 )
3031 // no rebase info for references to global symbols that will have binding info
3032 needsExternReloc
= true;
3035 if ( needsExternReloc
)
3036 needsLocalReloc
= false;
3038 case ld::Atom::definitionAbsolute
:
3041 if ( needsExternReloc
) {
3042 if ( inReadOnlySeg
)
3043 noteTextReloc(atom
, target
);
3044 const ld::dylib::File
* dylib
= dynamic_cast<const ld::dylib::File
*>(target
->file());
3045 if ( (dylib
!= NULL
) && dylib
->willBeLazyLoadedDylib() )
3046 throwf("illegal data reference to %s in lazy loaded dylib %s", target
->name(), dylib
->path());
3047 _externalRelocsAtom
->addExternalPointerReloc(relocAddress
, target
);
3048 sect
->hasExternalRelocs
= true;
3049 fixupWithTarget
->contentAddendOnly
= true;
3051 else if ( needsLocalReloc
) {
3052 assert(target
!= NULL
);
3053 if ( inReadOnlySeg
)
3054 noteTextReloc(atom
, target
);
3055 _localRelocsAtom
->addPointerReloc(relocAddress
, target
->machoSection());
3056 sect
->hasLocalRelocs
= true;
3059 case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32
:
3060 if ( _options
.outputKind() == Options::kKextBundle
) {
3061 assert(target
!= NULL
);
3062 if ( target
->definition() == ld::Atom::definitionProxy
) {
3063 _externalRelocsAtom
->addExternalCallSiteReloc(relocAddress
, target
);
3064 fixupWithStore
->contentAddendOnly
= true;
3069 case ld::Fixup::kindStoreARMLow16
:
3070 case ld::Fixup::kindStoreThumbLow16
:
3071 // no way to encode rebasing of binding for these instructions
3072 if ( _options
.outputSlidable() || (target
->definition() == ld::Atom::definitionProxy
) )
3073 throwf("no supported runtime lo16 relocation in %s from %s to %s", atom
->name(), atom
->file()->path(), target
->name());
3076 case ld::Fixup::kindStoreARMHigh16
:
3077 case ld::Fixup::kindStoreThumbHigh16
:
3078 // no way to encode rebasing of binding for these instructions
3079 if ( _options
.outputSlidable() || (target
->definition() == ld::Atom::definitionProxy
) )
3080 throwf("no supported runtime hi16 relocation in %s from %s to %s", atom
->name(), atom
->file()->path(), target
->name());
3089 bool OutputFile::useExternalSectionReloc(const ld::Atom
* atom
, const ld::Atom
* target
, ld::Fixup
* fixupWithTarget
)
3091 if ( _options
.architecture() == CPU_TYPE_X86_64
) {
3092 // x86_64 uses external relocations for everthing that has a symbol
3093 return ( target
->symbolTableInclusion() != ld::Atom::symbolTableNotIn
);
3096 // <rdar://problem/9513487> support arm branch interworking in -r mode
3097 if ( (_options
.architecture() == CPU_TYPE_ARM
) && (_options
.outputKind() == Options::kObjectFile
) ) {
3098 if ( atom
->isThumb() != target
->isThumb() ) {
3099 switch ( fixupWithTarget
->kind
) {
3100 // have branch that switches mode, then might be 'b' not 'bl'
3101 // Force external relocation, since no way to do local reloc for 'b'
3102 case ld::Fixup::kindStoreTargetAddressThumbBranch22
:
3103 case ld::Fixup::kindStoreTargetAddressARMBranch24
:
3111 if ( (_options
.architecture() == CPU_TYPE_I386
) && (_options
.outputKind() == Options::kObjectFile
) ) {
3112 if ( target
->contentType() == ld::Atom::typeTLV
)
3116 // most architectures use external relocations only for references
3117 // to a symbol in another translation unit or for references to "weak symbols" or tentative definitions
3118 assert(target
!= NULL
);
3119 if ( target
->definition() == ld::Atom::definitionProxy
)
3121 if ( (target
->definition() == ld::Atom::definitionTentative
) && ! _options
.makeTentativeDefinitionsReal() )
3123 if ( target
->scope() != ld::Atom::scopeGlobal
)
3125 if ( (target
->combine() == ld::Atom::combineByName
) && (target
->definition() == ld::Atom::definitionRegular
) )
3133 void OutputFile::addSectionRelocs(ld::Internal
& state
, ld::Internal::FinalSection
* sect
, const ld::Atom
* atom
,
3134 ld::Fixup
* fixupWithTarget
, ld::Fixup
* fixupWithMinusTarget
, ld::Fixup
* fixupWithStore
,
3135 const ld::Atom
* target
, const ld::Atom
* minusTarget
,
3136 uint64_t targetAddend
, uint64_t minusTargetAddend
)
3138 if ( sect
->isSectionHidden() )
3141 // in -r mode where there will be no labels on __eh_frame section, there is no need for relocations
3142 if ( (sect
->type() == ld::Section::typeCFI
) && _options
.removeEHLabels() )
3145 // non-lazy-pointer section is encoded in indirect symbol table - not using relocations
3146 if ( sect
->type() == ld::Section::typeNonLazyPointer
)
3149 // tentative defs don't have any relocations
3150 if ( sect
->type() == ld::Section::typeTentativeDefs
)
3153 assert(target
!= NULL
);
3154 assert(fixupWithTarget
!= NULL
);
3155 bool targetUsesExternalReloc
= this->useExternalSectionReloc(atom
, target
, fixupWithTarget
);
3156 bool minusTargetUsesExternalReloc
= (minusTarget
!= NULL
) && this->useExternalSectionReloc(atom
, minusTarget
, fixupWithMinusTarget
);
3158 // in x86_64 .o files an external reloc means the content contains just the addend
3159 if ( _options
.architecture() == CPU_TYPE_X86_64
) {
3160 if ( targetUsesExternalReloc
) {
3161 fixupWithTarget
->contentAddendOnly
= true;
3162 fixupWithStore
->contentAddendOnly
= true;
3164 if ( minusTargetUsesExternalReloc
)
3165 fixupWithMinusTarget
->contentAddendOnly
= true;
3168 // for other archs, content is addend only with (non pc-rel) pointers
3169 // pc-rel instructions are funny. If the target is _foo+8 and _foo is
3170 // external, then the pc-rel instruction *evalutates* to the address 8.
3171 if ( targetUsesExternalReloc
) {
3172 // TLV support for i386 acts like RIP relative addressing
3173 // The addend is the offset from the PICBase to the end of the instruction
3174 if ( (_options
.architecture() == CPU_TYPE_I386
)
3175 && (_options
.outputKind() == Options::kObjectFile
)
3176 && (fixupWithStore
->kind
== ld::Fixup::kindStoreX86PCRel32TLVLoad
) ) {
3177 fixupWithTarget
->contentAddendOnly
= true;
3178 fixupWithStore
->contentAddendOnly
= true;
3180 else if ( isPcRelStore(fixupWithStore
->kind
) ) {
3181 fixupWithTarget
->contentDetlaToAddendOnly
= true;
3182 fixupWithStore
->contentDetlaToAddendOnly
= true;
3184 else if ( minusTarget
== NULL
){
3185 fixupWithTarget
->contentAddendOnly
= true;
3186 fixupWithStore
->contentAddendOnly
= true;
3191 if ( fixupWithStore
!= NULL
) {
3192 _sectionsRelocationsAtom
->addSectionReloc(sect
, fixupWithStore
->kind
, atom
, fixupWithStore
->offsetInAtom
,
3193 targetUsesExternalReloc
, minusTargetUsesExternalReloc
,
3194 target
, targetAddend
, minusTarget
, minusTargetAddend
);
3200 void OutputFile::makeSplitSegInfo(ld::Internal
& state
)
3202 if ( !_options
.sharedRegionEligible() )
3205 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
3206 ld::Internal::FinalSection
* sect
= *sit
;
3207 if ( sect
->isSectionHidden() )
3209 if ( strcmp(sect
->segmentName(), "__TEXT") != 0 )
3211 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
3212 const ld::Atom
* atom
= *ait
;
3213 const ld::Atom
* target
= NULL
;
3214 const ld::Atom
* fromTarget
= NULL
;
3215 uint64_t accumulator
= 0;
3217 bool hadSubtract
= false;
3218 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(), end
=atom
->fixupsEnd(); fit
!= end
; ++fit
) {
3219 if ( fit
->firstInCluster() )
3221 if ( this->setsTarget(fit
->kind
) ) {
3222 accumulator
= addressOf(state
, fit
, &target
);
3223 thumbTarget
= targetIsThumb(state
, fit
);
3227 switch ( fit
->kind
) {
3228 case ld::Fixup::kindSubtractTargetAddress
:
3229 accumulator
-= addressOf(state
, fit
, &fromTarget
);
3232 case ld::Fixup::kindAddAddend
:
3233 accumulator
+= fit
->u
.addend
;
3235 case ld::Fixup::kindSubtractAddend
:
3236 accumulator
-= fit
->u
.addend
;
3238 case ld::Fixup::kindStoreBigEndian32
:
3239 case ld::Fixup::kindStoreLittleEndian32
:
3240 case ld::Fixup::kindStoreLittleEndian64
:
3241 case ld::Fixup::kindStoreTargetAddressLittleEndian32
:
3242 case ld::Fixup::kindStoreTargetAddressLittleEndian64
:
3243 // if no subtract, then this is an absolute pointer which means
3244 // there is also a text reloc which update_dyld_shared_cache will use.
3245 if ( ! hadSubtract
)
3248 case ld::Fixup::kindStoreX86PCRel32
:
3249 case ld::Fixup::kindStoreX86PCRel32_1
:
3250 case ld::Fixup::kindStoreX86PCRel32_2
:
3251 case ld::Fixup::kindStoreX86PCRel32_4
:
3252 case ld::Fixup::kindStoreX86PCRel32GOTLoad
:
3253 case ld::Fixup::kindStoreX86PCRel32GOTLoadNowLEA
:
3254 case ld::Fixup::kindStoreX86PCRel32GOT
:
3255 case ld::Fixup::kindStoreTargetAddressX86PCRel32
:
3256 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad
:
3257 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA
:
3258 case ld::Fixup::kindStoreARMLow16
:
3259 case ld::Fixup::kindStoreThumbLow16
:
3260 assert(target
!= NULL
);
3261 if ( strcmp(sect
->segmentName(), target
->section().segmentName()) != 0 ) {
3262 _splitSegInfos
.push_back(SplitSegInfoEntry(atom
->finalAddress()+fit
->offsetInAtom
,fit
->kind
));
3265 case ld::Fixup::kindStoreARMHigh16
:
3266 case ld::Fixup::kindStoreThumbHigh16
:
3267 assert(target
!= NULL
);
3268 if ( strcmp(sect
->segmentName(), target
->section().segmentName()) != 0 ) {
3269 // hi16 needs to know upper 4-bits of low16 to compute carry
3270 uint32_t extra
= (accumulator
>> 12) & 0xF;
3271 _splitSegInfos
.push_back(SplitSegInfoEntry(atom
->finalAddress()+fit
->offsetInAtom
,fit
->kind
, extra
));
3274 case ld::Fixup::kindSetTargetImageOffset
:
3275 accumulator
= addressOf(state
, fit
, &target
);
3276 assert(target
!= NULL
);
3288 void OutputFile::writeMapFile(ld::Internal
& state
)
3290 if ( _options
.generatedMapPath() != NULL
) {
3291 FILE* mapFile
= fopen(_options
.generatedMapPath(), "w");
3292 if ( mapFile
!= NULL
) {
3293 // write output path
3294 fprintf(mapFile
, "# Path: %s\n", _options
.outputFilePath());
3295 // write output architecure
3296 fprintf(mapFile
, "# Arch: %s\n", _options
.architectureName());
3298 //if ( fUUIDAtom != NULL ) {
3299 // const uint8_t* uuid = fUUIDAtom->getUUID();
3300 // fprintf(mapFile, "# UUID: %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X \n",
3301 // uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
3302 // uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
3304 // write table of object files
3305 std::map
<const ld::File
*, ld::File::Ordinal
> readerToOrdinal
;
3306 std::map
<ld::File::Ordinal
, const ld::File
*> ordinalToReader
;
3307 std::map
<const ld::File
*, uint32_t> readerToFileOrdinal
;
3308 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
3309 ld::Internal::FinalSection
* sect
= *sit
;
3310 if ( sect
->isSectionHidden() )
3312 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
3313 const ld::Atom
* atom
= *ait
;
3314 const ld::File
* reader
= atom
->file();
3315 if ( reader
== NULL
)
3317 ld::File::Ordinal readerOrdinal
= reader
->ordinal();
3318 std::map
<const ld::File
*, ld::File::Ordinal
>::iterator pos
= readerToOrdinal
.find(reader
);
3319 if ( pos
== readerToOrdinal
.end() ) {
3320 readerToOrdinal
[reader
] = readerOrdinal
;
3321 ordinalToReader
[readerOrdinal
] = reader
;
3325 fprintf(mapFile
, "# Object files:\n");
3326 fprintf(mapFile
, "[%3u] %s\n", 0, "linker synthesized");
3327 uint32_t fileIndex
= 1;
3328 for(std::map
<ld::File::Ordinal
, const ld::File
*>::iterator it
= ordinalToReader
.begin(); it
!= ordinalToReader
.end(); ++it
) {
3329 fprintf(mapFile
, "[%3u] %s\n", fileIndex
, it
->second
->path());
3330 readerToFileOrdinal
[it
->second
] = fileIndex
++;
3332 // write table of sections
3333 fprintf(mapFile
, "# Sections:\n");
3334 fprintf(mapFile
, "# Address\tSize \tSegment\tSection\n");
3335 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
3336 ld::Internal::FinalSection
* sect
= *sit
;
3337 if ( sect
->isSectionHidden() )
3339 fprintf(mapFile
, "0x%08llX\t0x%08llX\t%s\t%s\n", sect
->address
, sect
->size
,
3340 sect
->segmentName(), sect
->sectionName());
3342 // write table of symbols
3343 fprintf(mapFile
, "# Symbols:\n");
3344 fprintf(mapFile
, "# Address\tSize \tFile Name\n");
3345 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
3346 ld::Internal::FinalSection
* sect
= *sit
;
3347 if ( sect
->isSectionHidden() )
3349 //bool isCstring = (sect->type() == ld::Section::typeCString);
3350 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
3352 const ld::Atom
* atom
= *ait
;
3353 const char* name
= atom
->name();
3354 // don't add auto-stripped aliases to .map file
3355 if ( (atom
->size() == 0) && (atom
->symbolTableInclusion() == ld::Atom::symbolTableNotInFinalLinkedImages
) )
3357 if ( atom
->contentType() == ld::Atom::typeCString
) {
3358 strcpy(buffer
, "literal string: ");
3359 strlcat(buffer
, (char*)atom
->rawContentPointer(), 4096);
3362 else if ( (atom
->contentType() == ld::Atom::typeCFI
) && (strcmp(name
, "FDE") == 0) ) {
3363 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(); fit
!= atom
->fixupsEnd(); ++fit
) {
3364 if ( (fit
->kind
== ld::Fixup::kindSetTargetAddress
) && (fit
->clusterSize
== ld::Fixup::k1of4
) ) {
3365 assert(fit
->binding
== ld::Fixup::bindingDirectlyBound
);
3366 if ( fit
->u
.target
->section().type() == ld::Section::typeCode
) {
3367 strcpy(buffer
, "FDE for: ");
3368 strlcat(buffer
, fit
->u
.target
->name(), 4096);
3374 else if ( atom
->contentType() == ld::Atom::typeNonLazyPointer
) {
3375 strcpy(buffer
, "non-lazy-pointer");
3376 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(); fit
!= atom
->fixupsEnd(); ++fit
) {
3377 if ( fit
->binding
== ld::Fixup::bindingsIndirectlyBound
) {
3378 strcpy(buffer
, "non-lazy-pointer-to: ");
3379 strlcat(buffer
, state
.indirectBindingTable
[fit
->u
.bindingIndex
]->name(), 4096);
3382 else if ( fit
->binding
== ld::Fixup::bindingDirectlyBound
) {
3383 strcpy(buffer
, "non-lazy-pointer-to-local: ");
3384 strlcat(buffer
, fit
->u
.target
->name(), 4096);
3390 fprintf(mapFile
, "0x%08llX\t0x%08llX\t[%3u] %s\n", atom
->finalAddress(), atom
->size(),
3391 readerToFileOrdinal
[atom
->file()], name
);
3397 warning("could not write map file: %s\n", _options
.generatedMapPath());
3403 // used to sort atoms with debug notes
3404 class DebugNoteSorter
3407 bool operator()(const ld::Atom
* left
, const ld::Atom
* right
) const
3409 // first sort by reader
3410 ld::File::Ordinal leftFileOrdinal
= left
->file()->ordinal();
3411 ld::File::Ordinal rightFileOrdinal
= right
->file()->ordinal();
3412 if ( leftFileOrdinal
!= rightFileOrdinal
)
3413 return (leftFileOrdinal
< rightFileOrdinal
);
3415 // then sort by atom objectAddress
3416 uint64_t leftAddr
= left
->finalAddress();
3417 uint64_t rightAddr
= right
->finalAddress();
3418 return leftAddr
< rightAddr
;
3423 const char* OutputFile::assureFullPath(const char* path
)
3425 if ( path
[0] == '/' )
3427 char cwdbuff
[MAXPATHLEN
];
3428 if ( getcwd(cwdbuff
, MAXPATHLEN
) != NULL
) {
3430 asprintf(&result
, "%s/%s", cwdbuff
, path
);
3431 if ( result
!= NULL
)
3437 void OutputFile::synthesizeDebugNotes(ld::Internal
& state
)
3439 // -S means don't synthesize debug map
3440 if ( _options
.debugInfoStripping() == Options::kDebugInfoNone
)
3442 // make a vector of atoms that come from files compiled with dwarf debug info
3443 std::vector
<const ld::Atom
*> atomsNeedingDebugNotes
;
3444 std::set
<const ld::Atom
*> atomsWithStabs
;
3445 atomsNeedingDebugNotes
.reserve(1024);
3446 const ld::relocatable::File
* objFile
= NULL
;
3447 bool objFileHasDwarf
= false;
3448 bool objFileHasStabs
= false;
3449 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
3450 ld::Internal::FinalSection
* sect
= *sit
;
3451 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
3452 const ld::Atom
* atom
= *ait
;
3453 // no stabs for atoms that would not be in the symbol table
3454 if ( atom
->symbolTableInclusion() == ld::Atom::symbolTableNotIn
)
3456 if ( atom
->symbolTableInclusion() == ld::Atom::symbolTableNotInFinalLinkedImages
)
3458 if ( atom
->symbolTableInclusion() == ld::Atom::symbolTableInWithRandomAutoStripLabel
)
3460 // no stabs for absolute symbols
3461 if ( atom
->definition() == ld::Atom::definitionAbsolute
)
3463 // no stabs for .eh atoms
3464 if ( atom
->contentType() == ld::Atom::typeCFI
)
3466 // no stabs for string literal atoms
3467 if ( atom
->contentType() == ld::Atom::typeCString
)
3469 // no stabs for kernel dtrace probes
3470 if ( (_options
.outputKind() == Options::kStaticExecutable
) && (strncmp(atom
->name(), "__dtrace_probe$", 15) == 0) )
3472 const ld::File
* file
= atom
->file();
3473 if ( file
!= NULL
) {
3474 if ( file
!= objFile
) {
3475 objFileHasDwarf
= false;
3476 objFileHasStabs
= false;
3477 objFile
= dynamic_cast<const ld::relocatable::File
*>(file
);
3478 if ( objFile
!= NULL
) {
3479 switch ( objFile
->debugInfo() ) {
3480 case ld::relocatable::File::kDebugInfoNone
:
3482 case ld::relocatable::File::kDebugInfoDwarf
:
3483 objFileHasDwarf
= true;
3485 case ld::relocatable::File::kDebugInfoStabs
:
3486 case ld::relocatable::File::kDebugInfoStabsUUID
:
3487 objFileHasStabs
= true;
3492 if ( objFileHasDwarf
)
3493 atomsNeedingDebugNotes
.push_back(atom
);
3494 if ( objFileHasStabs
)
3495 atomsWithStabs
.insert(atom
);
3500 // sort by file ordinal then atom ordinal
3501 std::sort(atomsNeedingDebugNotes
.begin(), atomsNeedingDebugNotes
.end(), DebugNoteSorter());
3503 // synthesize "debug notes" and add them to master stabs vector
3504 const char* dirPath
= NULL
;
3505 const char* filename
= NULL
;
3506 bool wroteStartSO
= false;
3507 state
.stabs
.reserve(atomsNeedingDebugNotes
.size()*4);
3508 std::unordered_set
<const char*, CStringHash
, CStringEquals
> seenFiles
;
3509 for (std::vector
<const ld::Atom
*>::iterator it
=atomsNeedingDebugNotes
.begin(); it
!= atomsNeedingDebugNotes
.end(); it
++) {
3510 const ld::Atom
* atom
= *it
;
3511 const ld::File
* atomFile
= atom
->file();
3512 const ld::relocatable::File
* atomObjFile
= dynamic_cast<const ld::relocatable::File
*>(atomFile
);
3513 //fprintf(stderr, "debug note for %s\n", atom->name());
3514 const char* newPath
= atom
->translationUnitSource();
3515 if ( newPath
!= NULL
) {
3516 const char* newDirPath
;
3517 const char* newFilename
;
3518 const char* lastSlash
= strrchr(newPath
, '/');
3519 if ( lastSlash
== NULL
)
3521 newFilename
= lastSlash
+1;
3522 char* temp
= strdup(newPath
);
3524 // gdb like directory SO's to end in '/', but dwarf DW_AT_comp_dir usually does not have trailing '/'
3525 temp
[lastSlash
-newPath
+1] = '\0';
3526 // need SO's whenever the translation unit source file changes
3527 if ( (filename
== NULL
) || (strcmp(newFilename
,filename
) != 0) ) {
3528 if ( filename
!= NULL
) {
3529 // translation unit change, emit ending SO
3530 ld::relocatable::File::Stab endFileStab
;
3531 endFileStab
.atom
= NULL
;
3532 endFileStab
.type
= N_SO
;
3533 endFileStab
.other
= 1;
3534 endFileStab
.desc
= 0;
3535 endFileStab
.value
= 0;
3536 endFileStab
.string
= "";
3537 state
.stabs
.push_back(endFileStab
);
3539 // new translation unit, emit start SO's
3540 ld::relocatable::File::Stab dirPathStab
;
3541 dirPathStab
.atom
= NULL
;
3542 dirPathStab
.type
= N_SO
;
3543 dirPathStab
.other
= 0;
3544 dirPathStab
.desc
= 0;
3545 dirPathStab
.value
= 0;
3546 dirPathStab
.string
= newDirPath
;
3547 state
.stabs
.push_back(dirPathStab
);
3548 ld::relocatable::File::Stab fileStab
;
3549 fileStab
.atom
= NULL
;
3550 fileStab
.type
= N_SO
;
3554 fileStab
.string
= newFilename
;
3555 state
.stabs
.push_back(fileStab
);
3556 // Synthesize OSO for start of file
3557 ld::relocatable::File::Stab objStab
;
3558 objStab
.atom
= NULL
;
3559 objStab
.type
= N_OSO
;
3560 // <rdar://problem/6337329> linker should put cpusubtype in n_sect field of nlist entry for N_OSO debug note entries
3561 objStab
.other
= atomFile
->cpuSubType();
3563 if ( atomObjFile
!= NULL
) {
3564 objStab
.string
= assureFullPath(atomObjFile
->debugInfoPath());
3565 objStab
.value
= atomObjFile
->debugInfoModificationTime();
3568 objStab
.string
= assureFullPath(atomFile
->path());
3569 objStab
.value
= atomFile
->modificationTime();
3571 state
.stabs
.push_back(objStab
);
3572 wroteStartSO
= true;
3573 // add the source file path to seenFiles so it does not show up in SOLs
3574 seenFiles
.insert(newFilename
);
3576 asprintf(&fullFilePath
, "%s%s", newDirPath
, newFilename
);
3577 // add both leaf path and full path
3578 seenFiles
.insert(fullFilePath
);
3580 filename
= newFilename
;
3581 dirPath
= newDirPath
;
3582 if ( atom
->section().type() == ld::Section::typeCode
) {
3583 // Synthesize BNSYM and start FUN stabs
3584 ld::relocatable::File::Stab beginSym
;
3585 beginSym
.atom
= atom
;
3586 beginSym
.type
= N_BNSYM
;
3590 beginSym
.string
= "";
3591 state
.stabs
.push_back(beginSym
);
3592 ld::relocatable::File::Stab startFun
;
3593 startFun
.atom
= atom
;
3594 startFun
.type
= N_FUN
;
3598 startFun
.string
= atom
->name();
3599 state
.stabs
.push_back(startFun
);
3600 // Synthesize any SOL stabs needed
3601 const char* curFile
= NULL
;
3602 for (ld::Atom::LineInfo::iterator lit
= atom
->beginLineInfo(); lit
!= atom
->endLineInfo(); ++lit
) {
3603 if ( lit
->fileName
!= curFile
) {
3604 if ( seenFiles
.count(lit
->fileName
) == 0 ) {
3605 seenFiles
.insert(lit
->fileName
);
3606 ld::relocatable::File::Stab sol
;
3612 sol
.string
= lit
->fileName
;
3613 state
.stabs
.push_back(sol
);
3615 curFile
= lit
->fileName
;
3618 // Synthesize end FUN and ENSYM stabs
3619 ld::relocatable::File::Stab endFun
;
3621 endFun
.type
= N_FUN
;
3626 state
.stabs
.push_back(endFun
);
3627 ld::relocatable::File::Stab endSym
;
3629 endSym
.type
= N_ENSYM
;
3634 state
.stabs
.push_back(endSym
);
3637 ld::relocatable::File::Stab globalsStab
;
3638 const char* name
= atom
->name();
3639 if ( atom
->scope() == ld::Atom::scopeTranslationUnit
) {
3640 // Synthesize STSYM stab for statics
3641 globalsStab
.atom
= atom
;
3642 globalsStab
.type
= N_STSYM
;
3643 globalsStab
.other
= 1;
3644 globalsStab
.desc
= 0;
3645 globalsStab
.value
= 0;
3646 globalsStab
.string
= name
;
3647 state
.stabs
.push_back(globalsStab
);
3650 // Synthesize GSYM stab for other globals
3651 globalsStab
.atom
= atom
;
3652 globalsStab
.type
= N_GSYM
;
3653 globalsStab
.other
= 1;
3654 globalsStab
.desc
= 0;
3655 globalsStab
.value
= 0;
3656 globalsStab
.string
= name
;
3657 state
.stabs
.push_back(globalsStab
);
3663 if ( wroteStartSO
) {
3665 ld::relocatable::File::Stab endFileStab
;
3666 endFileStab
.atom
= NULL
;
3667 endFileStab
.type
= N_SO
;
3668 endFileStab
.other
= 1;
3669 endFileStab
.desc
= 0;
3670 endFileStab
.value
= 0;
3671 endFileStab
.string
= "";
3672 state
.stabs
.push_back(endFileStab
);
3675 // copy any stabs from .o file
3676 std::set
<const ld::File
*> filesSeenWithStabs
;
3677 for (std::set
<const ld::Atom
*>::iterator it
=atomsWithStabs
.begin(); it
!= atomsWithStabs
.end(); it
++) {
3678 const ld::Atom
* atom
= *it
;
3679 objFile
= dynamic_cast<const ld::relocatable::File
*>(atom
->file());
3680 if ( objFile
!= NULL
) {
3681 if ( filesSeenWithStabs
.count(objFile
) == 0 ) {
3682 filesSeenWithStabs
.insert(objFile
);
3683 const std::vector
<ld::relocatable::File::Stab
>* stabs
= objFile
->stabs();
3684 if ( stabs
!= NULL
) {
3685 for(std::vector
<ld::relocatable::File::Stab
>::const_iterator sit
= stabs
->begin(); sit
!= stabs
->end(); ++sit
) {
3686 ld::relocatable::File::Stab stab
= *sit
;
3687 // ignore stabs associated with atoms that were dead stripped or coalesced away
3688 if ( (sit
->atom
!= NULL
) && (atomsWithStabs
.count(sit
->atom
) == 0) )
3690 // <rdar://problem/8284718> Value of N_SO stabs should be address of first atom from translation unit
3691 if ( (stab
.type
== N_SO
) && (stab
.string
!= NULL
) && (stab
.string
[0] != '\0') ) {
3694 state
.stabs
.push_back(stab
);