1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-*
3 * Copyright (c) 2009-2011 Apple Inc. All rights reserved.
5 * @APPLE_LICENSE_HEADER_START@
7 * This file contains Original Code and/or Modifications of Original Code
8 * as defined in and that are subject to the Apple Public Source License
9 * Version 2.0 (the 'License'). You may not use this file except in
10 * compliance with the License. Please obtain a copy of the License at
11 * http://www.opensource.apple.com/apsl/ and read it before using this
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
19 * Please see the License for the specific language governing rights and
20 * limitations under the License.
22 * @APPLE_LICENSE_HEADER_END@
27 #include <sys/types.h>
30 #include <sys/sysctl.h>
35 #include <mach/mach_time.h>
36 #include <mach/vm_statistics.h>
37 #include <mach/mach_init.h>
38 #include <mach/mach_host.h>
39 #include <uuid/uuid.h>
41 #include <mach-o/dyld.h>
42 #include <mach-o/fat.h>
51 #include <ext/hash_map>
52 #include <ext/hash_set>
54 #include <CommonCrypto/CommonDigest.h>
55 #include <AvailabilityMacros.h>
57 #include "MachOTrie.hpp"
61 #include "OutputFile.h"
62 #include "Architectures.hpp"
63 #include "HeaderAndLoadCommands.hpp"
64 #include "LinkEdit.hpp"
65 #include "LinkEditClassic.hpp"
72 OutputFile::OutputFile(const Options
& opts
)
74 hasWeakExternalSymbols(false), usesWeakExternalSymbols(false), overridesWeakExternalSymbols(false),
75 _noReExportedDylibs(false), hasThreadLocalVariableDefinitions(false), pieDisabled(false),
76 headerAndLoadCommandsSection(NULL
),
77 rebaseSection(NULL
), bindingSection(NULL
), weakBindingSection(NULL
),
78 lazyBindingSection(NULL
), exportSection(NULL
),
79 splitSegInfoSection(NULL
), functionStartsSection(NULL
),
80 symbolTableSection(NULL
), stringPoolSection(NULL
),
81 localRelocationsSection(NULL
), externalRelocationsSection(NULL
),
82 sectionRelocationsSection(NULL
),
83 indirectSymbolTableSection(NULL
),
85 _hasDyldInfo(opts
.makeCompressedDyldInfo()),
86 _hasSymbolTable(true),
87 _hasSectionRelocations(opts
.outputKind() == Options::kObjectFile
),
88 _hasSplitSegInfo(opts
.sharedRegionEligible()),
89 _hasFunctionStartsInfo(opts
.addFunctionStarts()),
90 _hasDynamicSymbolTable(true),
91 _hasLocalRelocations(!opts
.makeCompressedDyldInfo()),
92 _hasExternalRelocations(!opts
.makeCompressedDyldInfo()),
93 _encryptedTEXTstartOffset(0),
94 _encryptedTEXTendOffset(0),
95 _localSymbolsStartIndex(0),
96 _localSymbolsCount(0),
97 _globalSymbolsStartIndex(0),
98 _globalSymbolsCount(0),
99 _importSymbolsStartIndex(0),
100 _importSymbolsCount(0),
101 _sectionsRelocationsAtom(NULL
),
102 _localRelocsAtom(NULL
),
103 _externalRelocsAtom(NULL
),
104 _symbolTableAtom(NULL
),
105 _indirectSymbolTableAtom(NULL
),
106 _rebasingInfoAtom(NULL
),
107 _bindingInfoAtom(NULL
),
108 _lazyBindingInfoAtom(NULL
),
109 _weakBindingInfoAtom(NULL
),
110 _exportInfoAtom(NULL
),
111 _splitSegInfoAtom(NULL
),
112 _functionStartsAtom(NULL
)
116 void OutputFile::dumpAtomsBySection(ld::Internal
& state
, bool printAtoms
)
118 fprintf(stderr
, "SORTED:\n");
119 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
120 fprintf(stderr
, "final section %p %s/%s %s start addr=0x%08llX, size=0x%08llX, alignment=%02d, fileOffset=0x%08llX\n",
121 (*it
), (*it
)->segmentName(), (*it
)->sectionName(), (*it
)->isSectionHidden() ? "(hidden)" : "",
122 (*it
)->address
, (*it
)->size
, (*it
)->alignment
, (*it
)->fileOffset
);
124 std::vector
<const ld::Atom
*>& atoms
= (*it
)->atoms
;
125 for (std::vector
<const ld::Atom
*>::iterator ait
= atoms
.begin(); ait
!= atoms
.end(); ++ait
) {
126 fprintf(stderr
, " %p (0x%04llX) %s\n", *ait
, (*ait
)->size(), (*ait
)->name());
130 fprintf(stderr
, "DYLIBS:\n");
131 for (std::vector
<ld::dylib::File
*>::iterator it
=state
.dylibs
.begin(); it
!= state
.dylibs
.end(); ++it
)
132 fprintf(stderr
, " %s\n", (*it
)->installPath());
135 void OutputFile::write(ld::Internal
& state
)
137 this->buildDylibOrdinalMapping(state
);
138 this->addLoadCommands(state
);
139 this->addLinkEdit(state
);
140 this->setSectionSizesAndAlignments(state
);
141 this->setLoadCommandsPadding(state
);
142 this->assignFileOffsets(state
);
143 this->assignAtomAddresses(state
);
144 this->synthesizeDebugNotes(state
);
145 this->buildSymbolTable(state
);
146 this->generateLinkEditInfo(state
);
147 this->makeSplitSegInfo(state
);
148 this->updateLINKEDITAddresses(state
);
149 //this->dumpAtomsBySection(state, false);
150 this->writeOutputFile(state
);
151 this->writeMapFile(state
);
154 bool OutputFile::findSegment(ld::Internal
& state
, uint64_t addr
, uint64_t* start
, uint64_t* end
, uint32_t* index
)
156 uint32_t segIndex
= 0;
157 ld::Internal::FinalSection
* segFirstSection
= NULL
;
158 ld::Internal::FinalSection
* lastSection
= NULL
;
159 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
160 ld::Internal::FinalSection
* sect
= *it
;
161 if ( (segFirstSection
== NULL
) || strcmp(segFirstSection
->segmentName(), sect
->segmentName()) != 0 ) {
162 if ( segFirstSection
!= NULL
) {
163 //fprintf(stderr, "findSegment(0x%llX) seg changed to %s\n", addr, sect->segmentName());
164 if ( (addr
>= segFirstSection
->address
) && (addr
< lastSection
->address
+lastSection
->size
) ) {
165 *start
= segFirstSection
->address
;
166 *end
= lastSection
->address
+lastSection
->size
;
172 segFirstSection
= sect
;
180 void OutputFile::assignAtomAddresses(ld::Internal
& state
)
182 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
183 ld::Internal::FinalSection
* sect
= *sit
;
184 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
185 const ld::Atom
* atom
= *ait
;
186 switch ( sect
-> type() ) {
187 case ld::Section::typeImportProxies
:
188 // want finalAddress() of all proxy atoms to be zero
189 (const_cast<ld::Atom
*>(atom
))->setSectionStartAddress(0);
191 case ld::Section::typeAbsoluteSymbols
:
192 // want finalAddress() of all absolute atoms to be value of abs symbol
193 (const_cast<ld::Atom
*>(atom
))->setSectionStartAddress(0);
195 case ld::Section::typeLinkEdit
:
196 // linkedit layout is assigned later
199 (const_cast<ld::Atom
*>(atom
))->setSectionStartAddress(sect
->address
);
206 void OutputFile::updateLINKEDITAddresses(ld::Internal
& state
)
208 if ( _options
.makeCompressedDyldInfo() ) {
209 // build dylb rebasing info
210 assert(_rebasingInfoAtom
!= NULL
);
211 _rebasingInfoAtom
->encode();
213 // build dyld binding info
214 assert(_bindingInfoAtom
!= NULL
);
215 _bindingInfoAtom
->encode();
217 // build dyld lazy binding info
218 assert(_lazyBindingInfoAtom
!= NULL
);
219 _lazyBindingInfoAtom
->encode();
221 // build dyld weak binding info
222 assert(_weakBindingInfoAtom
!= NULL
);
223 _weakBindingInfoAtom
->encode();
225 // build dyld export info
226 assert(_exportInfoAtom
!= NULL
);
227 _exportInfoAtom
->encode();
230 if ( _options
.sharedRegionEligible() ) {
231 // build split seg info
232 assert(_splitSegInfoAtom
!= NULL
);
233 _splitSegInfoAtom
->encode();
236 if ( _options
.addFunctionStarts() ) {
237 // build function starts info
238 assert(_functionStartsAtom
!= NULL
);
239 _functionStartsAtom
->encode();
242 // build classic symbol table
243 assert(_symbolTableAtom
!= NULL
);
244 _symbolTableAtom
->encode();
245 assert(_indirectSymbolTableAtom
!= NULL
);
246 _indirectSymbolTableAtom
->encode();
248 // add relocations to .o files
249 if ( _options
.outputKind() == Options::kObjectFile
) {
250 assert(_sectionsRelocationsAtom
!= NULL
);
251 _sectionsRelocationsAtom
->encode();
254 if ( ! _options
.makeCompressedDyldInfo() ) {
255 // build external relocations
256 assert(_externalRelocsAtom
!= NULL
);
257 _externalRelocsAtom
->encode();
258 // build local relocations
259 assert(_localRelocsAtom
!= NULL
);
260 _localRelocsAtom
->encode();
263 // update address and file offsets now that linkedit content has been generated
264 uint64_t curLinkEditAddress
= 0;
265 uint64_t curLinkEditfileOffset
= 0;
266 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
267 ld::Internal::FinalSection
* sect
= *sit
;
268 if ( sect
->type() != ld::Section::typeLinkEdit
)
270 if ( curLinkEditAddress
== 0 ) {
271 curLinkEditAddress
= sect
->address
;
272 curLinkEditfileOffset
= sect
->fileOffset
;
274 uint16_t maxAlignment
= 0;
276 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
277 const ld::Atom
* atom
= *ait
;
278 //fprintf(stderr, "setting linkedit atom offset for %s\n", atom->name());
279 if ( atom
->alignment().powerOf2
> maxAlignment
)
280 maxAlignment
= atom
->alignment().powerOf2
;
281 // calculate section offset for this atom
282 uint64_t alignment
= 1 << atom
->alignment().powerOf2
;
283 uint64_t currentModulus
= (offset
% alignment
);
284 uint64_t requiredModulus
= atom
->alignment().modulus
;
285 if ( currentModulus
!= requiredModulus
) {
286 if ( requiredModulus
> currentModulus
)
287 offset
+= requiredModulus
-currentModulus
;
289 offset
+= requiredModulus
+alignment
-currentModulus
;
291 (const_cast<ld::Atom
*>(atom
))->setSectionOffset(offset
);
292 (const_cast<ld::Atom
*>(atom
))->setSectionStartAddress(curLinkEditAddress
);
293 offset
+= atom
->size();
296 // section alignment is that of a contained atom with the greatest alignment
297 sect
->alignment
= maxAlignment
;
298 sect
->address
= curLinkEditAddress
;
299 sect
->fileOffset
= curLinkEditfileOffset
;
300 curLinkEditAddress
+= sect
->size
;
301 curLinkEditfileOffset
+= sect
->size
;
304 _fileSize
= state
.sections
.back()->fileOffset
+ state
.sections
.back()->size
;
307 void OutputFile::setSectionSizesAndAlignments(ld::Internal
& state
)
309 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
310 ld::Internal::FinalSection
* sect
= *sit
;
311 if ( sect
->type() == ld::Section::typeAbsoluteSymbols
) {
312 // absolute symbols need their finalAddress() to their value
313 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
314 const ld::Atom
* atom
= *ait
;
315 (const_cast<ld::Atom
*>(atom
))->setSectionOffset(atom
->objectAddress());
319 uint16_t maxAlignment
= 0;
321 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
322 const ld::Atom
* atom
= *ait
;
323 bool pagePerAtom
= false;
324 uint32_t atomAlignmentPowerOf2
= atom
->alignment().powerOf2
;
325 if ( _options
.pageAlignDataAtoms() && ( strcmp(atom
->section().segmentName(), "__DATA") == 0) ) {
326 switch ( atom
->section().type() ) {
327 case ld::Section::typeUnclassified
:
328 case ld::Section::typeTentativeDefs
:
329 case ld::Section::typeZeroFill
:
331 if ( atomAlignmentPowerOf2
< 12 )
332 atomAlignmentPowerOf2
= 12;
338 if ( atomAlignmentPowerOf2
> maxAlignment
)
339 maxAlignment
= atomAlignmentPowerOf2
;
340 // calculate section offset for this atom
341 uint64_t alignment
= 1 << atomAlignmentPowerOf2
;
342 uint64_t currentModulus
= (offset
% alignment
);
343 uint64_t requiredModulus
= atom
->alignment().modulus
;
344 if ( currentModulus
!= requiredModulus
) {
345 if ( requiredModulus
> currentModulus
)
346 offset
+= requiredModulus
-currentModulus
;
348 offset
+= requiredModulus
+alignment
-currentModulus
;
350 // LINKEDIT atoms are laid out later
351 if ( sect
->type() != ld::Section::typeLinkEdit
) {
352 (const_cast<ld::Atom
*>(atom
))->setSectionOffset(offset
);
353 offset
+= atom
->size();
355 offset
= (offset
+ 4095) & (-4096); // round up to end of page
358 if ( (atom
->scope() == ld::Atom::scopeGlobal
)
359 && (atom
->definition() == ld::Atom::definitionRegular
)
360 && (atom
->combine() == ld::Atom::combineByName
)
361 && ((atom
->symbolTableInclusion() == ld::Atom::symbolTableIn
)
362 || (atom
->symbolTableInclusion() == ld::Atom::symbolTableInAndNeverStrip
)) ) {
363 this->hasWeakExternalSymbols
= true;
364 if ( _options
.warnWeakExports() )
365 warning("weak external symbol: %s", atom
->name());
369 // section alignment is that of a contained atom with the greatest alignment
370 sect
->alignment
= maxAlignment
;
371 // unless -sectalign command line option overrides
372 if ( _options
.hasCustomSectionAlignment(sect
->segmentName(), sect
->sectionName()) )
373 sect
->alignment
= _options
.customSectionAlignment(sect
->segmentName(), sect
->sectionName());
374 // each atom in __eh_frame has zero alignment to assure they pack together,
375 // but compilers usually make the CFIs pointer sized, so we want whole section
376 // to start on pointer sized boundary.
377 if ( sect
->type() == ld::Section::typeCFI
)
379 if ( sect
->type() == ld::Section::typeTLVDefs
)
380 this->hasThreadLocalVariableDefinitions
= true;
385 void OutputFile::setLoadCommandsPadding(ld::Internal
& state
)
387 // In other sections, any extra space is put and end of segment.
388 // In __TEXT segment, any extra space is put after load commands to allow post-processing of load commands
389 // Do a reverse layout of __TEXT segment to determine padding size and adjust section size
390 uint64_t paddingSize
= 0;
391 switch ( _options
.outputKind() ) {
393 // dyld itself has special padding requirements. We want the beginning __text section to start at a stable address
394 assert(strcmp(state
.sections
[1]->sectionName(),"__text") == 0);
395 state
.sections
[1]->alignment
= 12; // page align __text
397 case Options::kObjectFile
:
398 // mach-o .o files need no padding between load commands and first section
399 // but leave enough room that the object file could be signed
402 case Options::kPreload
:
403 // mach-o MH_PRELOAD files need no padding between load commands and first section
406 // work backwards from end of segment and lay out sections so that extra room goes to padding atom
408 for (std::vector
<ld::Internal::FinalSection
*>::reverse_iterator it
= state
.sections
.rbegin(); it
!= state
.sections
.rend(); ++it
) {
409 ld::Internal::FinalSection
* sect
= *it
;
410 if ( strcmp(sect
->segmentName(), "__TEXT") != 0 )
412 if ( sect
== headerAndLoadCommandsSection
) {
413 addr
-= headerAndLoadCommandsSection
->size
;
414 paddingSize
= addr
% _options
.segmentAlignment();
418 addr
= addr
& (0 - (1 << sect
->alignment
));
421 // if command line requires more padding than this
422 uint32_t minPad
= _options
.minimumHeaderPad();
423 if ( _options
.maxMminimumHeaderPad() ) {
424 // -headerpad_max_install_names means there should be room for every path load command to grow to 1204 bytes
425 uint32_t altMin
= _dylibsToLoad
.size() * MAXPATHLEN
;
426 if ( _options
.outputKind() == Options::kDynamicLibrary
)
427 altMin
+= MAXPATHLEN
;
428 if ( altMin
> minPad
)
431 if ( paddingSize
< minPad
) {
432 int extraPages
= (minPad
- paddingSize
+ _options
.segmentAlignment() - 1)/_options
.segmentAlignment();
433 paddingSize
+= extraPages
* _options
.segmentAlignment();
436 if ( _options
.makeEncryptable() ) {
437 // load commands must be on a separate non-encrypted page
438 int loadCommandsPage
= (headerAndLoadCommandsSection
->size
+ minPad
)/_options
.segmentAlignment();
439 int textPage
= (headerAndLoadCommandsSection
->size
+ paddingSize
)/_options
.segmentAlignment();
440 if ( loadCommandsPage
== textPage
) {
441 paddingSize
+= _options
.segmentAlignment();
444 // remember start for later use by load command
445 _encryptedTEXTstartOffset
= textPage
*_options
.segmentAlignment();
449 // add padding to size of section
450 headerAndLoadCommandsSection
->size
+= paddingSize
;
454 uint64_t OutputFile::pageAlign(uint64_t addr
)
456 const uint64_t alignment
= _options
.segmentAlignment();
457 return ((addr
+alignment
-1) & (-alignment
));
460 uint64_t OutputFile::pageAlign(uint64_t addr
, uint64_t pageSize
)
462 return ((addr
+pageSize
-1) & (-pageSize
));
466 void OutputFile::assignFileOffsets(ld::Internal
& state
)
468 const bool log
= false;
469 const bool hiddenSectionsOccupyAddressSpace
= ((_options
.outputKind() != Options::kObjectFile
)
470 && (_options
.outputKind() != Options::kPreload
));
471 const bool segmentsArePageAligned
= (_options
.outputKind() != Options::kObjectFile
);
473 uint64_t address
= 0;
474 const char* lastSegName
= "";
475 uint64_t floatingAddressStart
= _options
.baseAddress();
477 // first pass, assign addresses to sections in segments with fixed start addresses
478 if ( log
) fprintf(stderr
, "Fixed address segments:\n");
479 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
480 ld::Internal::FinalSection
* sect
= *it
;
481 if ( ! _options
.hasCustomSegmentAddress(sect
->segmentName()) )
483 if ( segmentsArePageAligned
) {
484 if ( strcmp(lastSegName
, sect
->segmentName()) != 0 ) {
485 address
= _options
.customSegmentAddress(sect
->segmentName());
486 lastSegName
= sect
->segmentName();
489 // adjust section address based on alignment
490 uint64_t unalignedAddress
= address
;
491 uint64_t alignment
= (1 << sect
->alignment
);
492 address
= ( (unalignedAddress
+alignment
-1) & (-alignment
) );
494 // update section info
495 sect
->address
= address
;
496 sect
->alignmentPaddingBytes
= (address
- unalignedAddress
);
499 if ( ((address
+ sect
->size
) > _options
.maxAddress()) && (_options
.outputKind() != Options::kObjectFile
)
500 && (_options
.outputKind() != Options::kStaticExecutable
) )
501 throwf("section %s (address=0x%08llX, size=%llu) would make the output executable exceed available address range",
502 sect
->sectionName(), address
, sect
->size
);
504 if ( log
) fprintf(stderr
, " address=0x%08llX, hidden=%d, alignment=%02d, section=%s,%s\n",
505 sect
->address
, sect
->isSectionHidden(), sect
->alignment
, sect
->segmentName(), sect
->sectionName());
506 // update running totals
507 if ( !sect
->isSectionHidden() || hiddenSectionsOccupyAddressSpace
)
508 address
+= sect
->size
;
510 // if TEXT segment address is fixed, then flow other segments after it
511 if ( strcmp(sect
->segmentName(), "__TEXT") == 0 ) {
512 floatingAddressStart
= address
;
516 // second pass, assign section address to sections in segments that are contiguous with previous segment
517 address
= floatingAddressStart
;
519 if ( log
) fprintf(stderr
, "Regular layout segments:\n");
520 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
521 ld::Internal::FinalSection
* sect
= *it
;
522 if ( _options
.hasCustomSegmentAddress(sect
->segmentName()) )
524 if ( (_options
.outputKind() == Options::kPreload
) && (sect
->type() == ld::Section::typeMachHeader
) ) {
525 sect
->alignmentPaddingBytes
= 0;
528 if ( segmentsArePageAligned
) {
529 if ( strcmp(lastSegName
, sect
->segmentName()) != 0 ) {
530 // round up size of last segment if needed
531 if ( *lastSegName
!= '\0' ) {
532 address
= pageAlign(address
, _options
.segPageSize(lastSegName
));
534 // set segment address based on end of last segment
535 address
= pageAlign(address
);
536 lastSegName
= sect
->segmentName();
539 // adjust section address based on alignment
540 uint64_t unalignedAddress
= address
;
541 uint64_t alignment
= (1 << sect
->alignment
);
542 address
= ( (unalignedAddress
+alignment
-1) & (-alignment
) );
544 // update section info
545 sect
->address
= address
;
546 sect
->alignmentPaddingBytes
= (address
- unalignedAddress
);
549 if ( ((address
+ sect
->size
) > _options
.maxAddress()) && (_options
.outputKind() != Options::kObjectFile
)
550 && (_options
.outputKind() != Options::kStaticExecutable
) )
551 throwf("section %s (address=0x%08llX, size=%llu) would make the output executable exceed available address range",
552 sect
->sectionName(), address
, sect
->size
);
554 if ( log
) fprintf(stderr
, " address=0x%08llX, hidden=%d, alignment=%02d, padBytes=%d, section=%s,%s\n",
555 sect
->address
, sect
->isSectionHidden(), sect
->alignment
, sect
->alignmentPaddingBytes
,
556 sect
->segmentName(), sect
->sectionName());
557 // update running totals
558 if ( !sect
->isSectionHidden() || hiddenSectionsOccupyAddressSpace
)
559 address
+= sect
->size
;
563 // third pass, assign section file offsets
564 uint64_t fileOffset
= 0;
566 if ( log
) fprintf(stderr
, "All segments with file offsets:\n");
567 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
568 ld::Internal::FinalSection
* sect
= *it
;
569 if ( hasZeroForFileOffset(sect
) ) {
570 // fileoff of zerofill sections is moot, but historically it is set to zero
571 sect
->fileOffset
= 0;
574 // page align file offset at start of each segment
575 if ( segmentsArePageAligned
&& (*lastSegName
!= '\0') && (strcmp(lastSegName
, sect
->segmentName()) != 0) ) {
576 fileOffset
= pageAlign(fileOffset
, _options
.segPageSize(lastSegName
));
578 lastSegName
= sect
->segmentName();
580 // align file offset with address layout
581 fileOffset
+= sect
->alignmentPaddingBytes
;
583 // update section info
584 sect
->fileOffset
= fileOffset
;
586 // update running total
587 fileOffset
+= sect
->size
;
590 if ( log
) fprintf(stderr
, " fileoffset=0x%08llX, address=0x%08llX, hidden=%d, size=%lld, alignment=%02d, section=%s,%s\n",
591 sect
->fileOffset
, sect
->address
, sect
->isSectionHidden(), sect
->size
, sect
->alignment
,
592 sect
->segmentName(), sect
->sectionName());
596 // for encrypted iPhoneOS apps
597 if ( _options
.makeEncryptable() ) {
598 // remember end of __TEXT for later use by load command
599 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
600 ld::Internal::FinalSection
* sect
= *it
;
601 if ( strcmp(sect
->segmentName(), "__TEXT") == 0 ) {
602 _encryptedTEXTendOffset
= pageAlign(sect
->fileOffset
+ sect
->size
);
607 // remember total file size
608 _fileSize
= fileOffset
;
612 static const char* makeName(const ld::Atom
& atom
)
614 static char buffer
[4096];
615 switch ( atom
.symbolTableInclusion() ) {
616 case ld::Atom::symbolTableNotIn
:
617 case ld::Atom::symbolTableNotInFinalLinkedImages
:
618 sprintf(buffer
, "%s@0x%08llX", atom
.name(), atom
.objectAddress());
620 case ld::Atom::symbolTableIn
:
621 case ld::Atom::symbolTableInAndNeverStrip
:
622 case ld::Atom::symbolTableInAsAbsolute
:
623 case ld::Atom::symbolTableInWithRandomAutoStripLabel
:
624 strlcpy(buffer
, atom
.name(), 4096);
630 static const char* referenceTargetAtomName(ld::Internal
& state
, const ld::Fixup
* ref
)
632 switch ( ref
->binding
) {
633 case ld::Fixup::bindingNone
:
635 case ld::Fixup::bindingByNameUnbound
:
636 return (char*)(ref
->u
.target
);
637 case ld::Fixup::bindingByContentBound
:
638 case ld::Fixup::bindingDirectlyBound
:
639 return makeName(*((ld::Atom
*)(ref
->u
.target
)));
640 case ld::Fixup::bindingsIndirectlyBound
:
641 return makeName(*state
.indirectBindingTable
[ref
->u
.bindingIndex
]);
643 return "BAD BINDING";
646 bool OutputFile::targetIsThumb(ld::Internal
& state
, const ld::Fixup
* fixup
)
648 switch ( fixup
->binding
) {
649 case ld::Fixup::bindingByContentBound
:
650 case ld::Fixup::bindingDirectlyBound
:
651 return fixup
->u
.target
->isThumb();
652 case ld::Fixup::bindingsIndirectlyBound
:
653 return state
.indirectBindingTable
[fixup
->u
.bindingIndex
]->isThumb();
657 throw "unexpected binding";
660 uint64_t OutputFile::addressOf(const ld::Internal
& state
, const ld::Fixup
* fixup
, const ld::Atom
** target
)
662 if ( !_options
.makeCompressedDyldInfo() ) {
663 // For external relocations the classic mach-o format
664 // has addend only stored in the content. That means
665 // that the address of the target is not used.
666 if ( fixup
->contentAddendOnly
)
669 switch ( fixup
->binding
) {
670 case ld::Fixup::bindingNone
:
671 throw "unexpected bindingNone";
672 case ld::Fixup::bindingByNameUnbound
:
673 throw "unexpected bindingByNameUnbound";
674 case ld::Fixup::bindingByContentBound
:
675 case ld::Fixup::bindingDirectlyBound
:
676 *target
= fixup
->u
.target
;
677 return (*target
)->finalAddress();
678 case ld::Fixup::bindingsIndirectlyBound
:
679 *target
= state
.indirectBindingTable
[fixup
->u
.bindingIndex
];
680 return (*target
)->finalAddress();
682 throw "unexpected binding";
685 uint64_t OutputFile::sectionOffsetOf(const ld::Internal
& state
, const ld::Fixup
* fixup
)
687 const ld::Atom
* target
= NULL
;
688 switch ( fixup
->binding
) {
689 case ld::Fixup::bindingNone
:
690 throw "unexpected bindingNone";
691 case ld::Fixup::bindingByNameUnbound
:
692 throw "unexpected bindingByNameUnbound";
693 case ld::Fixup::bindingByContentBound
:
694 case ld::Fixup::bindingDirectlyBound
:
695 target
= fixup
->u
.target
;
697 case ld::Fixup::bindingsIndirectlyBound
:
698 target
= state
.indirectBindingTable
[fixup
->u
.bindingIndex
];
701 assert(target
!= NULL
);
703 uint64_t targetAddress
= target
->finalAddress();
704 for (std::vector
<ld::Internal::FinalSection
*>::const_iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
705 const ld::Internal::FinalSection
* sect
= *it
;
706 if ( (sect
->address
<= targetAddress
) && (targetAddress
< (sect
->address
+sect
->size
)) )
707 return targetAddress
- sect
->address
;
709 throw "section not found for section offset";
714 uint64_t OutputFile::tlvTemplateOffsetOf(const ld::Internal
& state
, const ld::Fixup
* fixup
)
716 const ld::Atom
* target
= NULL
;
717 switch ( fixup
->binding
) {
718 case ld::Fixup::bindingNone
:
719 throw "unexpected bindingNone";
720 case ld::Fixup::bindingByNameUnbound
:
721 throw "unexpected bindingByNameUnbound";
722 case ld::Fixup::bindingByContentBound
:
723 case ld::Fixup::bindingDirectlyBound
:
724 target
= fixup
->u
.target
;
726 case ld::Fixup::bindingsIndirectlyBound
:
727 target
= state
.indirectBindingTable
[fixup
->u
.bindingIndex
];
730 assert(target
!= NULL
);
732 for (std::vector
<ld::Internal::FinalSection
*>::const_iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
733 const ld::Internal::FinalSection
* sect
= *it
;
734 switch ( sect
->type() ) {
735 case ld::Section::typeTLVInitialValues
:
736 case ld::Section::typeTLVZeroFill
:
737 return target
->finalAddress() - sect
->address
;
742 throw "section not found for tlvTemplateOffsetOf";
745 void OutputFile::printSectionLayout(ld::Internal
& state
)
747 // show layout of final image
748 fprintf(stderr
, "final section layout:\n");
749 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
750 if ( (*it
)->isSectionHidden() )
752 fprintf(stderr
, " %s/%s addr=0x%08llX, size=0x%08llX, fileOffset=0x%08llX, type=%d\n",
753 (*it
)->segmentName(), (*it
)->sectionName(),
754 (*it
)->address
, (*it
)->size
, (*it
)->fileOffset
, (*it
)->type());
759 void OutputFile::rangeCheck8(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
761 if ( (displacement
> 127) || (displacement
< -128) ) {
762 // show layout of final image
763 printSectionLayout(state
);
765 const ld::Atom
* target
;
766 throwf("8-bit reference out of range (%lld max is +/-127B): from %s (0x%08llX) to %s (0x%08llX)",
767 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
768 addressOf(state
, fixup
, &target
));
772 void OutputFile::rangeCheck16(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
774 const int64_t thirtyTwoKLimit
= 0x00007FFF;
775 if ( (displacement
> thirtyTwoKLimit
) || (displacement
< (-thirtyTwoKLimit
)) ) {
776 // show layout of final image
777 printSectionLayout(state
);
779 const ld::Atom
* target
;
780 throwf("16-bit reference out of range (%lld max is +/-32KB): from %s (0x%08llX) to %s (0x%08llX)",
781 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
782 addressOf(state
, fixup
, &target
));
786 void OutputFile::rangeCheckBranch32(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
788 const int64_t twoGigLimit
= 0x7FFFFFFF;
789 if ( (displacement
> twoGigLimit
) || (displacement
< (-twoGigLimit
)) ) {
790 // show layout of final image
791 printSectionLayout(state
);
793 const ld::Atom
* target
;
794 throwf("32-bit branch out of range (%lld max is +/-4GB): from %s (0x%08llX) to %s (0x%08llX)",
795 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
796 addressOf(state
, fixup
, &target
));
801 void OutputFile::rangeCheckAbsolute32(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
803 const int64_t fourGigLimit
= 0xFFFFFFFF;
804 if ( displacement
> fourGigLimit
) {
805 // <rdar://problem/9610466> cannot enforce 32-bit range checks on 32-bit archs because assembler loses sign information
806 // .long _foo - 0xC0000000
807 // is encoded in mach-o the same as:
808 // .long _foo + 0x40000000
809 // so if _foo lays out to 0xC0000100, the first is ok, but the second is not.
810 if ( (_options
.architecture() == CPU_TYPE_ARM
) || (_options
.architecture() == CPU_TYPE_I386
) ) {
811 // Unlikely userland code does funky stuff like this, so warn for them, but not warn for -preload
812 if ( _options
.outputKind() != Options::kPreload
) {
813 warning("32-bit absolute address out of range (0x%08llX max is 4GB): from %s + 0x%08X (0x%08llX) to 0x%08llX",
814 displacement
, atom
->name(), fixup
->offsetInAtom
, atom
->finalAddress(), displacement
);
818 // show layout of final image
819 printSectionLayout(state
);
821 const ld::Atom
* target
;
822 if ( fixup
->binding
== ld::Fixup::bindingNone
)
823 throwf("32-bit absolute address out of range (0x%08llX max is 4GB): from %s + 0x%08X (0x%08llX) to 0x%08llX",
824 displacement
, atom
->name(), fixup
->offsetInAtom
, atom
->finalAddress(), displacement
);
826 throwf("32-bit absolute address out of range (0x%08llX max is 4GB): from %s + 0x%08X (0x%08llX) to %s (0x%08llX)",
827 displacement
, atom
->name(), fixup
->offsetInAtom
, atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
828 addressOf(state
, fixup
, &target
));
833 void OutputFile::rangeCheckRIP32(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
835 const int64_t twoGigLimit
= 0x7FFFFFFF;
836 if ( (displacement
> twoGigLimit
) || (displacement
< (-twoGigLimit
)) ) {
837 // show layout of final image
838 printSectionLayout(state
);
840 const ld::Atom
* target
;
841 throwf("32-bit RIP relative reference out of range (%lld max is +/-4GB): from %s (0x%08llX) to %s (0x%08llX)",
842 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
843 addressOf(state
, fixup
, &target
));
847 void OutputFile::rangeCheckARM12(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
849 if ( (displacement
> 4092LL) || (displacement
< (-4092LL)) ) {
850 // show layout of final image
851 printSectionLayout(state
);
853 const ld::Atom
* target
;
854 throwf("ARM ldr 12-bit displacement out of range (%lld max is +/-4096B): from %s (0x%08llX) to %s (0x%08llX)",
855 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
856 addressOf(state
, fixup
, &target
));
861 void OutputFile::rangeCheckARMBranch24(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
863 if ( (displacement
> 33554428LL) || (displacement
< (-33554432LL)) ) {
864 // show layout of final image
865 printSectionLayout(state
);
867 const ld::Atom
* target
;
868 throwf("b/bl/blx ARM branch out of range (%lld max is +/-32MB): from %s (0x%08llX) to %s (0x%08llX)",
869 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
870 addressOf(state
, fixup
, &target
));
874 void OutputFile::rangeCheckThumbBranch22(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
876 // thumb2 supports a larger displacement
877 if ( _options
.preferSubArchitecture() && _options
.archSupportsThumb2() ) {
878 if ( (displacement
> 16777214LL) || (displacement
< (-16777216LL)) ) {
879 // show layout of final image
880 printSectionLayout(state
);
882 const ld::Atom
* target
;
883 throwf("b/bl/blx thumb2 branch out of range (%lld max is +/-16MB): from %s (0x%08llX) to %s (0x%08llX)",
884 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
885 addressOf(state
, fixup
, &target
));
889 if ( (displacement
> 4194302LL) || (displacement
< (-4194304LL)) ) {
890 // show layout of final image
891 printSectionLayout(state
);
893 const ld::Atom
* target
;
894 throwf("b/bl/blx thumb1 branch out of range (%lld max is +/-4MB): from %s (0x%08llX) to %s (0x%08llX)",
895 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
896 addressOf(state
, fixup
, &target
));
901 void OutputFile::rangeCheckPPCBranch24(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
903 const int64_t bl_eightMegLimit
= 0x00FFFFFF;
904 if ( (displacement
> bl_eightMegLimit
) || (displacement
< (-bl_eightMegLimit
)) ) {
905 // show layout of final image
906 printSectionLayout(state
);
908 const ld::Atom
* target
;
909 throwf("bl PPC branch out of range (%lld max is +/-16MB): from %s (0x%08llX) to %s (0x%08llX)",
910 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
911 addressOf(state
, fixup
, &target
));
915 void OutputFile::rangeCheckPPCBranch14(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
917 const int64_t b_sixtyFourKiloLimit
= 0x0000FFFF;
918 if ( (displacement
> b_sixtyFourKiloLimit
) || (displacement
< (-b_sixtyFourKiloLimit
)) ) {
919 // show layout of final image
920 printSectionLayout(state
);
922 const ld::Atom
* target
;
923 throwf("bcc PPC branch out of range (%lld max is +/-64KB): from %s (0x%08llX) to %s (0x%08llX)",
924 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
925 addressOf(state
, fixup
, &target
));
932 uint16_t OutputFile::get16LE(uint8_t* loc
) { return LittleEndian::get16(*(uint16_t*)loc
); }
933 void OutputFile::set16LE(uint8_t* loc
, uint16_t value
) { LittleEndian::set16(*(uint16_t*)loc
, value
); }
935 uint32_t OutputFile::get32LE(uint8_t* loc
) { return LittleEndian::get32(*(uint32_t*)loc
); }
936 void OutputFile::set32LE(uint8_t* loc
, uint32_t value
) { LittleEndian::set32(*(uint32_t*)loc
, value
); }
938 uint64_t OutputFile::get64LE(uint8_t* loc
) { return LittleEndian::get64(*(uint64_t*)loc
); }
939 void OutputFile::set64LE(uint8_t* loc
, uint64_t value
) { LittleEndian::set64(*(uint64_t*)loc
, value
); }
941 uint16_t OutputFile::get16BE(uint8_t* loc
) { return BigEndian::get16(*(uint16_t*)loc
); }
942 void OutputFile::set16BE(uint8_t* loc
, uint16_t value
) { BigEndian::set16(*(uint16_t*)loc
, value
); }
944 uint32_t OutputFile::get32BE(uint8_t* loc
) { return BigEndian::get32(*(uint32_t*)loc
); }
945 void OutputFile::set32BE(uint8_t* loc
, uint32_t value
) { BigEndian::set32(*(uint32_t*)loc
, value
); }
947 uint64_t OutputFile::get64BE(uint8_t* loc
) { return BigEndian::get64(*(uint64_t*)loc
); }
948 void OutputFile::set64BE(uint8_t* loc
, uint64_t value
) { BigEndian::set64(*(uint64_t*)loc
, value
); }
950 void OutputFile::applyFixUps(ld::Internal
& state
, uint64_t mhAddress
, const ld::Atom
* atom
, uint8_t* buffer
)
952 //fprintf(stderr, "applyFixUps() on %s\n", atom->name());
953 int64_t accumulator
= 0;
954 const ld::Atom
* toTarget
= NULL
;
955 const ld::Atom
* fromTarget
;
957 uint32_t instruction
;
958 uint32_t newInstruction
;
959 uint16_t instructionLowHalf
;
963 bool thumbTarget
= false;
964 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(), end
=atom
->fixupsEnd(); fit
!= end
; ++fit
) {
965 uint8_t* fixUpLocation
= &buffer
[fit
->offsetInAtom
];
966 switch ( (ld::Fixup::Kind
)(fit
->kind
) ) {
967 case ld::Fixup::kindNone
:
968 case ld::Fixup::kindNoneFollowOn
:
969 case ld::Fixup::kindNoneGroupSubordinate
:
970 case ld::Fixup::kindNoneGroupSubordinateFDE
:
971 case ld::Fixup::kindNoneGroupSubordinateLSDA
:
972 case ld::Fixup::kindNoneGroupSubordinatePersonality
:
974 case ld::Fixup::kindSetTargetAddress
:
975 accumulator
= addressOf(state
, fit
, &toTarget
);
976 thumbTarget
= targetIsThumb(state
, fit
);
979 if ( fit
->contentAddendOnly
|| fit
->contentDetlaToAddendOnly
)
982 case ld::Fixup::kindSubtractTargetAddress
:
983 delta
= addressOf(state
, fit
, &fromTarget
);
984 if ( ! fit
->contentAddendOnly
)
985 accumulator
-= delta
;
987 case ld::Fixup::kindAddAddend
:
988 // <rdar://problem/8342028> ARM main executables main contain .long constants pointing
989 // into themselves such as jump tables. These .long should not have thumb bit set
990 // even though the target is a thumb instruction. We can tell it is an interior pointer
991 // because we are processing an addend.
992 if ( thumbTarget
&& (toTarget
== atom
) && ((int32_t)fit
->u
.addend
> 0) ) {
994 //warning("removing thumb bit from intra-atom pointer in %s %s+0x%0X",
995 // atom->section().sectionName(), atom->name(), fit->offsetInAtom);
997 accumulator
+= fit
->u
.addend
;
999 case ld::Fixup::kindSubtractAddend
:
1000 accumulator
-= fit
->u
.addend
;
1002 case ld::Fixup::kindSetTargetImageOffset
:
1003 accumulator
= addressOf(state
, fit
, &toTarget
) - mhAddress
;
1005 case ld::Fixup::kindSetTargetSectionOffset
:
1006 accumulator
= sectionOffsetOf(state
, fit
);
1008 case ld::Fixup::kindSetTargetTLVTemplateOffset
:
1009 accumulator
= tlvTemplateOffsetOf(state
, fit
);
1011 case ld::Fixup::kindStore8
:
1012 *fixUpLocation
+= accumulator
;
1014 case ld::Fixup::kindStoreLittleEndian16
:
1015 set16LE(fixUpLocation
, accumulator
);
1017 case ld::Fixup::kindStoreLittleEndianLow24of32
:
1018 set32LE(fixUpLocation
, (get32LE(fixUpLocation
) & 0xFF000000) | (accumulator
& 0x00FFFFFF) );
1020 case ld::Fixup::kindStoreLittleEndian32
:
1021 rangeCheckAbsolute32(accumulator
, state
, atom
, fit
);
1022 set32LE(fixUpLocation
, accumulator
);
1024 case ld::Fixup::kindStoreLittleEndian64
:
1025 set64LE(fixUpLocation
, accumulator
);
1027 case ld::Fixup::kindStoreBigEndian16
:
1028 set16BE(fixUpLocation
, accumulator
);
1030 case ld::Fixup::kindStoreBigEndianLow24of32
:
1031 set32BE(fixUpLocation
, (get32BE(fixUpLocation
) & 0xFF000000) | (accumulator
& 0x00FFFFFF) );
1033 case ld::Fixup::kindStoreBigEndian32
:
1034 rangeCheckAbsolute32(accumulator
, state
, atom
, fit
);
1035 set32BE(fixUpLocation
, accumulator
);
1037 case ld::Fixup::kindStoreBigEndian64
:
1038 set64BE(fixUpLocation
, accumulator
);
1040 case ld::Fixup::kindStoreX86PCRel8
:
1041 case ld::Fixup::kindStoreX86BranchPCRel8
:
1042 if ( fit
->contentAddendOnly
)
1043 delta
= accumulator
;
1045 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 1);
1046 rangeCheck8(delta
, state
, atom
, fit
);
1047 *fixUpLocation
= delta
;
1049 case ld::Fixup::kindStoreX86PCRel16
:
1050 if ( fit
->contentAddendOnly
)
1051 delta
= accumulator
;
1053 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 2);
1054 rangeCheck16(delta
, state
, atom
, fit
);
1055 set16LE(fixUpLocation
, delta
);
1057 case ld::Fixup::kindStoreX86BranchPCRel32
:
1058 if ( fit
->contentAddendOnly
)
1059 delta
= accumulator
;
1061 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1062 rangeCheckBranch32(delta
, state
, atom
, fit
);
1063 set32LE(fixUpLocation
, delta
);
1065 case ld::Fixup::kindStoreX86PCRel32GOTLoad
:
1066 case ld::Fixup::kindStoreX86PCRel32GOT
:
1067 case ld::Fixup::kindStoreX86PCRel32
:
1068 case ld::Fixup::kindStoreX86PCRel32TLVLoad
:
1069 if ( fit
->contentAddendOnly
)
1070 delta
= accumulator
;
1072 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1073 rangeCheckRIP32(delta
, state
, atom
, fit
);
1074 set32LE(fixUpLocation
, delta
);
1076 case ld::Fixup::kindStoreX86PCRel32_1
:
1077 if ( fit
->contentAddendOnly
)
1078 delta
= accumulator
- 1;
1080 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 5);
1081 rangeCheckRIP32(delta
, state
, atom
, fit
);
1082 set32LE(fixUpLocation
, delta
);
1084 case ld::Fixup::kindStoreX86PCRel32_2
:
1085 if ( fit
->contentAddendOnly
)
1086 delta
= accumulator
- 2;
1088 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 6);
1089 rangeCheckRIP32(delta
, state
, atom
, fit
);
1090 set32LE(fixUpLocation
, delta
);
1092 case ld::Fixup::kindStoreX86PCRel32_4
:
1093 if ( fit
->contentAddendOnly
)
1094 delta
= accumulator
- 4;
1096 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 8);
1097 rangeCheckRIP32(delta
, state
, atom
, fit
);
1098 set32LE(fixUpLocation
, delta
);
1100 case ld::Fixup::kindStoreX86Abs32TLVLoad
:
1101 set32LE(fixUpLocation
, accumulator
);
1103 case ld::Fixup::kindStoreX86Abs32TLVLoadNowLEA
:
1104 assert(_options
.outputKind() != Options::kObjectFile
);
1105 // TLV entry was optimized away, change movl instruction to a leal
1106 if ( fixUpLocation
[-1] != 0xA1 )
1107 throw "TLV load reloc does not point to a movl instruction";
1108 fixUpLocation
[-1] = 0xB8;
1109 set32LE(fixUpLocation
, accumulator
);
1111 case ld::Fixup::kindStoreX86PCRel32GOTLoadNowLEA
:
1112 assert(_options
.outputKind() != Options::kObjectFile
);
1113 // GOT entry was optimized away, change movq instruction to a leaq
1114 if ( fixUpLocation
[-2] != 0x8B )
1115 throw "GOT load reloc does not point to a movq instruction";
1116 fixUpLocation
[-2] = 0x8D;
1117 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1118 rangeCheckRIP32(delta
, state
, atom
, fit
);
1119 set32LE(fixUpLocation
, delta
);
1121 case ld::Fixup::kindStoreX86PCRel32TLVLoadNowLEA
:
1122 assert(_options
.outputKind() != Options::kObjectFile
);
1123 // TLV entry was optimized away, change movq instruction to a leaq
1124 if ( fixUpLocation
[-2] != 0x8B )
1125 throw "TLV load reloc does not point to a movq instruction";
1126 fixUpLocation
[-2] = 0x8D;
1127 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1128 rangeCheckRIP32(delta
, state
, atom
, fit
);
1129 set32LE(fixUpLocation
, delta
);
1131 case ld::Fixup::kindStoreTargetAddressARMLoad12
:
1132 accumulator
= addressOf(state
, fit
, &toTarget
);
1133 // fall into kindStoreARMLoad12 case
1134 case ld::Fixup::kindStoreARMLoad12
:
1135 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 8);
1136 rangeCheckARM12(delta
, state
, atom
, fit
);
1137 instruction
= get32LE(fixUpLocation
);
1139 newInstruction
= instruction
& 0xFFFFF000;
1140 newInstruction
|= ((uint32_t)delta
& 0xFFF);
1143 newInstruction
= instruction
& 0xFF7FF000;
1144 newInstruction
|= ((uint32_t)(-delta
) & 0xFFF);
1146 set32LE(fixUpLocation
, newInstruction
);
1148 case ld::Fixup::kindStorePPCBranch14
:
1149 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
);
1150 rangeCheckPPCBranch14(delta
, state
, atom
, fit
);
1151 instruction
= get32BE(fixUpLocation
);
1152 newInstruction
= (instruction
& 0xFFFF0003) | ((uint32_t)delta
& 0x0000FFFC);
1153 set32BE(fixUpLocation
, newInstruction
);
1155 case ld::Fixup::kindStorePPCPicLow14
:
1156 case ld::Fixup::kindStorePPCAbsLow14
:
1157 instruction
= get32BE(fixUpLocation
);
1158 if ( (accumulator
& 0x3) != 0 )
1159 throwf("bad offset (0x%08X) for lo14 instruction pic-base fix-up", (uint32_t)accumulator
);
1160 newInstruction
= (instruction
& 0xFFFF0003) | (accumulator
& 0xFFFC);
1161 set32BE(fixUpLocation
, newInstruction
);
1163 case ld::Fixup::kindStorePPCAbsLow16
:
1164 case ld::Fixup::kindStorePPCPicLow16
:
1165 instruction
= get32BE(fixUpLocation
);
1166 newInstruction
= (instruction
& 0xFFFF0000) | (accumulator
& 0xFFFF);
1167 set32BE(fixUpLocation
, newInstruction
);
1169 case ld::Fixup::kindStorePPCAbsHigh16AddLow
:
1170 case ld::Fixup::kindStorePPCPicHigh16AddLow
:
1171 instructionLowHalf
= (accumulator
>> 16) & 0xFFFF;
1172 if ( accumulator
& 0x00008000 )
1173 ++instructionLowHalf
;
1174 instruction
= get32BE(fixUpLocation
);
1175 newInstruction
= (instruction
& 0xFFFF0000) | instructionLowHalf
;
1176 set32BE(fixUpLocation
, newInstruction
);
1178 case ld::Fixup::kindStorePPCAbsHigh16
:
1179 instruction
= get32BE(fixUpLocation
);
1180 newInstruction
= (instruction
& 0xFFFF0000) | ((accumulator
>> 16) & 0xFFFF);
1181 set32BE(fixUpLocation
, newInstruction
);
1183 case ld::Fixup::kindDtraceExtra
:
1185 case ld::Fixup::kindStoreX86DtraceCallSiteNop
:
1186 if ( _options
.outputKind() != Options::kObjectFile
) {
1187 // change call site to a NOP
1188 fixUpLocation
[-1] = 0x90; // 1-byte nop
1189 fixUpLocation
[0] = 0x0F; // 4-byte nop
1190 fixUpLocation
[1] = 0x1F;
1191 fixUpLocation
[2] = 0x40;
1192 fixUpLocation
[3] = 0x00;
1195 case ld::Fixup::kindStoreX86DtraceIsEnableSiteClear
:
1196 if ( _options
.outputKind() != Options::kObjectFile
) {
1197 // change call site to a clear eax
1198 fixUpLocation
[-1] = 0x33; // xorl eax,eax
1199 fixUpLocation
[0] = 0xC0;
1200 fixUpLocation
[1] = 0x90; // 1-byte nop
1201 fixUpLocation
[2] = 0x90; // 1-byte nop
1202 fixUpLocation
[3] = 0x90; // 1-byte nop
1205 case ld::Fixup::kindStorePPCDtraceCallSiteNop
:
1206 if ( _options
.outputKind() != Options::kObjectFile
) {
1207 // change call site to a NOP
1208 set32BE(fixUpLocation
, 0x60000000);
1211 case ld::Fixup::kindStorePPCDtraceIsEnableSiteClear
:
1212 if ( _options
.outputKind() != Options::kObjectFile
) {
1213 // change call site to a li r3,0
1214 set32BE(fixUpLocation
, 0x38600000);
1217 case ld::Fixup::kindStoreARMDtraceCallSiteNop
:
1218 if ( _options
.outputKind() != Options::kObjectFile
) {
1219 // change call site to a NOP
1220 set32LE(fixUpLocation
, 0xE1A00000);
1223 case ld::Fixup::kindStoreARMDtraceIsEnableSiteClear
:
1224 if ( _options
.outputKind() != Options::kObjectFile
) {
1225 // change call site to 'eor r0, r0, r0'
1226 set32LE(fixUpLocation
, 0xE0200000);
1229 case ld::Fixup::kindStoreThumbDtraceCallSiteNop
:
1230 if ( _options
.outputKind() != Options::kObjectFile
) {
1231 // change 32-bit blx call site to two thumb NOPs
1232 set32LE(fixUpLocation
, 0x46C046C0);
1235 case ld::Fixup::kindStoreThumbDtraceIsEnableSiteClear
:
1236 if ( _options
.outputKind() != Options::kObjectFile
) {
1237 // change 32-bit blx call site to 'nop', 'eor r0, r0'
1238 set32LE(fixUpLocation
, 0x46C04040);
1241 case ld::Fixup::kindLazyTarget
:
1243 case ld::Fixup::kindSetLazyOffset
:
1244 assert(fit
->binding
== ld::Fixup::bindingDirectlyBound
);
1245 accumulator
= this->lazyBindingInfoOffsetForLazyPointerAddress(fit
->u
.target
->finalAddress());
1247 case ld::Fixup::kindStoreTargetAddressLittleEndian32
:
1248 accumulator
= addressOf(state
, fit
, &toTarget
);
1249 thumbTarget
= targetIsThumb(state
, fit
);
1252 if ( fit
->contentAddendOnly
)
1254 rangeCheckAbsolute32(accumulator
, state
, atom
, fit
);
1255 set32LE(fixUpLocation
, accumulator
);
1257 case ld::Fixup::kindStoreTargetAddressLittleEndian64
:
1258 accumulator
= addressOf(state
, fit
, &toTarget
);
1259 if ( fit
->contentAddendOnly
)
1261 set64LE(fixUpLocation
, accumulator
);
1263 case ld::Fixup::kindStoreTargetAddressBigEndian32
:
1264 accumulator
= addressOf(state
, fit
, &toTarget
);
1265 if ( fit
->contentAddendOnly
)
1267 set32BE(fixUpLocation
, accumulator
);
1269 case ld::Fixup::kindStoreTargetAddressBigEndian64
:
1270 accumulator
= addressOf(state
, fit
, &toTarget
);
1271 if ( fit
->contentAddendOnly
)
1273 set64BE(fixUpLocation
, accumulator
);
1275 case ld::Fixup::kindSetTargetTLVTemplateOffsetLittleEndian32
:
1276 accumulator
= tlvTemplateOffsetOf(state
, fit
);
1277 set32LE(fixUpLocation
, accumulator
);
1279 case ld::Fixup::kindSetTargetTLVTemplateOffsetLittleEndian64
:
1280 accumulator
= tlvTemplateOffsetOf(state
, fit
);
1281 set64LE(fixUpLocation
, accumulator
);
1283 case ld::Fixup::kindStoreTargetAddressX86PCRel32
:
1284 case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32
:
1285 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad
:
1286 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoad
:
1287 accumulator
= addressOf(state
, fit
, &toTarget
);
1288 if ( fit
->contentDetlaToAddendOnly
)
1290 if ( fit
->contentAddendOnly
)
1293 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1294 rangeCheckRIP32(delta
, state
, atom
, fit
);
1295 set32LE(fixUpLocation
, delta
);
1297 case ld::Fixup::kindStoreTargetAddressX86Abs32TLVLoad
:
1298 set32LE(fixUpLocation
, accumulator
);
1300 case ld::Fixup::kindStoreTargetAddressX86Abs32TLVLoadNowLEA
:
1301 // TLV entry was optimized away, change movl instruction to a leal
1302 if ( fixUpLocation
[-1] != 0xA1 )
1303 throw "TLV load reloc does not point to a movl <abs-address>,<reg> instruction";
1304 fixUpLocation
[-1] = 0xB8;
1305 accumulator
= addressOf(state
, fit
, &toTarget
);
1306 set32LE(fixUpLocation
, accumulator
);
1308 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA
:
1309 // GOT entry was optimized away, change movq instruction to a leaq
1310 if ( fixUpLocation
[-2] != 0x8B )
1311 throw "GOT load reloc does not point to a movq instruction";
1312 fixUpLocation
[-2] = 0x8D;
1313 accumulator
= addressOf(state
, fit
, &toTarget
);
1314 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1315 rangeCheckRIP32(delta
, state
, atom
, fit
);
1316 set32LE(fixUpLocation
, delta
);
1318 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoadNowLEA
:
1319 // TLV entry was optimized away, change movq instruction to a leaq
1320 if ( fixUpLocation
[-2] != 0x8B )
1321 throw "TLV load reloc does not point to a movq instruction";
1322 fixUpLocation
[-2] = 0x8D;
1323 accumulator
= addressOf(state
, fit
, &toTarget
);
1324 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1325 rangeCheckRIP32(delta
, state
, atom
, fit
);
1326 set32LE(fixUpLocation
, delta
);
1328 case ld::Fixup::kindStoreTargetAddressARMBranch24
:
1329 accumulator
= addressOf(state
, fit
, &toTarget
);
1330 thumbTarget
= targetIsThumb(state
, fit
);
1333 if ( fit
->contentDetlaToAddendOnly
)
1335 // fall into kindStoreARMBranch24 case
1336 case ld::Fixup::kindStoreARMBranch24
:
1337 // The pc added will be +8 from the pc
1338 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 8);
1339 rangeCheckARMBranch24(delta
, state
, atom
, fit
);
1340 instruction
= get32LE(fixUpLocation
);
1341 // Make sure we are calling arm with bl, thumb with blx
1342 is_bl
= ((instruction
& 0xFF000000) == 0xEB000000);
1343 is_blx
= ((instruction
& 0xFE000000) == 0xFA000000);
1344 is_b
= !is_blx
&& ((instruction
& 0x0F000000) == 0x0A000000);
1345 if ( is_bl
&& thumbTarget
) {
1346 uint32_t opcode
= 0xFA000000;
1347 uint32_t disp
= (uint32_t)(delta
>> 2) & 0x00FFFFFF;
1348 uint32_t h_bit
= (uint32_t)(delta
<< 23) & 0x01000000;
1349 newInstruction
= opcode
| h_bit
| disp
;
1351 else if ( is_blx
&& !thumbTarget
) {
1352 uint32_t opcode
= 0xEB000000;
1353 uint32_t disp
= (uint32_t)(delta
>> 2) & 0x00FFFFFF;
1354 newInstruction
= opcode
| disp
;
1356 else if ( is_b
&& thumbTarget
) {
1357 if ( fit
->contentDetlaToAddendOnly
)
1358 newInstruction
= (instruction
& 0xFF000000) | ((uint32_t)(delta
>> 2) & 0x00FFFFFF);
1360 throwf("no pc-rel bx arm instruction. Can't fix up branch to %s in %s",
1361 referenceTargetAtomName(state
, fit
), atom
->name());
1363 else if ( !is_bl
&& !is_blx
&& thumbTarget
) {
1364 throwf("don't know how to convert instruction %x referencing %s to thumb",
1365 instruction
, referenceTargetAtomName(state
, fit
));
1368 newInstruction
= (instruction
& 0xFF000000) | ((uint32_t)(delta
>> 2) & 0x00FFFFFF);
1370 set32LE(fixUpLocation
, newInstruction
);
1372 case ld::Fixup::kindStoreTargetAddressThumbBranch22
:
1373 accumulator
= addressOf(state
, fit
, &toTarget
);
1374 thumbTarget
= targetIsThumb(state
, fit
);
1377 if ( fit
->contentDetlaToAddendOnly
)
1379 // fall into kindStoreThumbBranch22 case
1380 case ld::Fixup::kindStoreThumbBranch22
:
1381 instruction
= get32LE(fixUpLocation
);
1382 is_bl
= ((instruction
& 0xD000F800) == 0xD000F000);
1383 is_blx
= ((instruction
& 0xD000F800) == 0xC000F000);
1384 is_b
= ((instruction
& 0xD000F800) == 0x9000F000);
1385 // If the target is not thumb, we will be generating a blx instruction
1386 // Since blx cannot have the low bit set, set bit[1] of the target to
1387 // bit[1] of the base address, so that the difference is a multiple of
1389 if ( !thumbTarget
&& !fit
->contentDetlaToAddendOnly
) {
1390 accumulator
&= -3ULL;
1391 accumulator
|= ((atom
->finalAddress() + fit
->offsetInAtom
) & 2LL);
1393 // The pc added will be +4 from the pc
1394 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1395 rangeCheckThumbBranch22(delta
, state
, atom
, fit
);
1396 if ( _options
.preferSubArchitecture() && _options
.archSupportsThumb2() ) {
1397 // The instruction is really two instructions:
1398 // The lower 16 bits are the first instruction, which contains the high
1399 // 11 bits of the displacement.
1400 // The upper 16 bits are the second instruction, which contains the low
1401 // 11 bits of the displacement, as well as differentiating bl and blx.
1402 uint32_t s
= (uint32_t)(delta
>> 24) & 0x1;
1403 uint32_t i1
= (uint32_t)(delta
>> 23) & 0x1;
1404 uint32_t i2
= (uint32_t)(delta
>> 22) & 0x1;
1405 uint32_t imm10
= (uint32_t)(delta
>> 12) & 0x3FF;
1406 uint32_t imm11
= (uint32_t)(delta
>> 1) & 0x7FF;
1407 uint32_t j1
= (i1
== s
);
1408 uint32_t j2
= (i2
== s
);
1411 instruction
= 0xD000F000; // keep bl
1413 instruction
= 0xC000F000; // change to blx
1415 else if ( is_blx
) {
1417 instruction
= 0xD000F000; // change to bl
1419 instruction
= 0xC000F000; // keep blx
1422 instruction
= 0x9000F000; // keep b
1423 if ( !thumbTarget
&& !fit
->contentDetlaToAddendOnly
) {
1424 throwf("armv7 has no pc-rel bx thumb instruction. Can't fix up branch to %s in %s",
1425 referenceTargetAtomName(state
, fit
), atom
->name());
1430 throwf("don't know how to convert branch instruction %x referencing %s to bx",
1431 instruction
, referenceTargetAtomName(state
, fit
));
1432 instruction
= 0x9000F000; // keep b
1434 uint32_t nextDisp
= (j1
<< 13) | (j2
<< 11) | imm11
;
1435 uint32_t firstDisp
= (s
<< 10) | imm10
;
1436 newInstruction
= instruction
| (nextDisp
<< 16) | firstDisp
;
1437 //warning("s=%d, j1=%d, j2=%d, imm10=0x%0X, imm11=0x%0X, opcode=0x%08X, first=0x%04X, next=0x%04X, new=0x%08X, disp=0x%llX for %s to %s\n",
1438 // s, j1, j2, imm10, imm11, opcode, firstDisp, nextDisp, newInstruction, delta, inAtom->getDisplayName(), ref->getTarget().getDisplayName());
1439 set32LE(fixUpLocation
, newInstruction
);
1442 // The instruction is really two instructions:
1443 // The lower 16 bits are the first instruction, which contains the high
1444 // 11 bits of the displacement.
1445 // The upper 16 bits are the second instruction, which contains the low
1446 // 11 bits of the displacement, as well as differentiating bl and blx.
1447 uint32_t firstDisp
= (uint32_t)(delta
>> 12) & 0x7FF;
1448 uint32_t nextDisp
= (uint32_t)(delta
>> 1) & 0x7FF;
1449 if ( is_bl
&& !thumbTarget
) {
1450 instruction
= 0xE800F000;
1452 else if ( is_blx
&& thumbTarget
) {
1453 instruction
= 0xF800F000;
1456 instruction
= 0x9000F000; // keep b
1457 if ( !thumbTarget
&& !fit
->contentDetlaToAddendOnly
) {
1458 throwf("armv6 has no pc-rel bx thumb instruction. Can't fix up branch to %s in %s",
1459 referenceTargetAtomName(state
, fit
), atom
->name());
1463 instruction
= instruction
& 0xF800F800;
1465 newInstruction
= instruction
| (nextDisp
<< 16) | firstDisp
;
1466 set32LE(fixUpLocation
, newInstruction
);
1469 case ld::Fixup::kindStoreARMLow16
:
1471 uint32_t imm4
= (accumulator
& 0x0000F000) >> 12;
1472 uint32_t imm12
= accumulator
& 0x00000FFF;
1473 instruction
= get32LE(fixUpLocation
);
1474 newInstruction
= (instruction
& 0xFFF0F000) | (imm4
<< 16) | imm12
;
1475 set32LE(fixUpLocation
, newInstruction
);
1478 case ld::Fixup::kindStoreARMHigh16
:
1480 uint32_t imm4
= (accumulator
& 0xF0000000) >> 28;
1481 uint32_t imm12
= (accumulator
& 0x0FFF0000) >> 16;
1482 instruction
= get32LE(fixUpLocation
);
1483 newInstruction
= (instruction
& 0xFFF0F000) | (imm4
<< 16) | imm12
;
1484 set32LE(fixUpLocation
, newInstruction
);
1487 case ld::Fixup::kindStoreThumbLow16
:
1489 uint32_t imm4
= (accumulator
& 0x0000F000) >> 12;
1490 uint32_t i
= (accumulator
& 0x00000800) >> 11;
1491 uint32_t imm3
= (accumulator
& 0x00000700) >> 8;
1492 uint32_t imm8
= accumulator
& 0x000000FF;
1493 instruction
= get32LE(fixUpLocation
);
1494 newInstruction
= (instruction
& 0x8F00FBF0) | imm4
| (i
<< 10) | (imm3
<< 28) | (imm8
<< 16);
1495 set32LE(fixUpLocation
, newInstruction
);
1498 case ld::Fixup::kindStoreThumbHigh16
:
1500 uint32_t imm4
= (accumulator
& 0xF0000000) >> 28;
1501 uint32_t i
= (accumulator
& 0x08000000) >> 27;
1502 uint32_t imm3
= (accumulator
& 0x07000000) >> 24;
1503 uint32_t imm8
= (accumulator
& 0x00FF0000) >> 16;
1504 instruction
= get32LE(fixUpLocation
);
1505 newInstruction
= (instruction
& 0x8F00FBF0) | imm4
| (i
<< 10) | (imm3
<< 28) | (imm8
<< 16);
1506 set32LE(fixUpLocation
, newInstruction
);
1509 case ld::Fixup::kindStoreTargetAddressPPCBranch24
:
1510 accumulator
= addressOf(state
, fit
, &toTarget
);
1511 if ( fit
->contentDetlaToAddendOnly
)
1513 // fall into kindStorePPCBranch24 case
1514 case ld::Fixup::kindStorePPCBranch24
:
1515 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
);
1516 rangeCheckPPCBranch24(delta
, state
, atom
, fit
);
1517 instruction
= get32BE(fixUpLocation
);
1518 newInstruction
= (instruction
& 0xFC000003) | ((uint32_t)delta
& 0x03FFFFFC);
1519 set32BE(fixUpLocation
, newInstruction
);
1525 void OutputFile::copyNoOps(uint8_t* from
, uint8_t* to
, bool thumb
)
1527 switch ( _options
.architecture() ) {
1528 case CPU_TYPE_POWERPC
:
1529 for (uint8_t* p
=from
; p
< to
; p
+= 4)
1530 OSWriteBigInt32((uint32_t*)p
, 0, 0x60000000);
1533 case CPU_TYPE_X86_64
:
1534 for (uint8_t* p
=from
; p
< to
; ++p
)
1539 for (uint8_t* p
=from
; p
< to
; p
+= 2)
1540 OSWriteLittleInt16((uint16_t*)p
, 0, 0x46c0);
1543 for (uint8_t* p
=from
; p
< to
; p
+= 4)
1544 OSWriteLittleInt32((uint32_t*)p
, 0, 0xe1a00000);
1548 for (uint8_t* p
=from
; p
< to
; ++p
)
1554 bool OutputFile::takesNoDiskSpace(const ld::Section
* sect
)
1556 switch ( sect
->type() ) {
1557 case ld::Section::typeZeroFill
:
1558 case ld::Section::typeTLVZeroFill
:
1559 return _options
.optimizeZeroFill();
1560 case ld::Section::typePageZero
:
1561 case ld::Section::typeStack
:
1562 case ld::Section::typeAbsoluteSymbols
:
1563 case ld::Section::typeTentativeDefs
:
1571 bool OutputFile::hasZeroForFileOffset(const ld::Section
* sect
)
1573 switch ( sect
->type() ) {
1574 case ld::Section::typeZeroFill
:
1575 case ld::Section::typeTLVZeroFill
:
1576 return _options
.optimizeZeroFill();
1577 case ld::Section::typePageZero
:
1578 case ld::Section::typeStack
:
1579 case ld::Section::typeTentativeDefs
:
1588 void OutputFile::writeOutputFile(ld::Internal
& state
)
1590 // for UNIX conformance, error if file exists and is not writable
1591 if ( (access(_options
.outputFilePath(), F_OK
) == 0) && (access(_options
.outputFilePath(), W_OK
) == -1) )
1592 throwf("can't write output file: %s", _options
.outputFilePath());
1594 int permissions
= 0777;
1595 if ( _options
.outputKind() == Options::kObjectFile
)
1597 // Calling unlink first assures the file is gone so that open creates it with correct permissions
1598 // It also handles the case where __options.outputFilePath() file is not writable but its directory is
1599 // And it means we don't have to truncate the file when done writing (in case new is smaller than old)
1600 // Lastly, only delete existing file if it is a normal file (e.g. not /dev/null).
1601 struct stat stat_buf
;
1602 if ( (stat(_options
.outputFilePath(), &stat_buf
) != -1) && (stat_buf
.st_mode
& S_IFREG
) )
1603 (void)unlink(_options
.outputFilePath());
1605 // try to allocate buffer for entire output file content
1606 uint8_t* wholeBuffer
= (uint8_t*)calloc(_fileSize
, 1);
1607 if ( wholeBuffer
== NULL
)
1608 throwf("can't create buffer of %llu bytes for output", _fileSize
);
1610 if ( _options
.UUIDMode() == Options::kUUIDRandom
) {
1612 ::uuid_generate_random(bits
);
1613 _headersAndLoadCommandAtom
->setUUID(bits
);
1616 // have each atom write itself
1617 uint64_t fileOffsetOfEndOfLastAtom
= 0;
1618 uint64_t mhAddress
= 0;
1619 bool lastAtomUsesNoOps
= false;
1620 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
1621 ld::Internal::FinalSection
* sect
= *sit
;
1622 if ( sect
->type() == ld::Section::typeMachHeader
)
1623 mhAddress
= sect
->address
;
1624 if ( takesNoDiskSpace(sect
) )
1626 const bool sectionUsesNops
= (sect
->type() == ld::Section::typeCode
);
1627 //fprintf(stderr, "file offset=0x%08llX, section %s\n", sect->fileOffset, sect->sectionName());
1628 std::vector
<const ld::Atom
*>& atoms
= sect
->atoms
;
1629 bool lastAtomWasThumb
= false;
1630 for (std::vector
<const ld::Atom
*>::iterator ait
= atoms
.begin(); ait
!= atoms
.end(); ++ait
) {
1631 const ld::Atom
* atom
= *ait
;
1632 if ( atom
->definition() == ld::Atom::definitionProxy
)
1635 uint64_t fileOffset
= atom
->finalAddress() - sect
->address
+ sect
->fileOffset
;
1636 // check for alignment padding between atoms
1637 if ( (fileOffset
!= fileOffsetOfEndOfLastAtom
) && lastAtomUsesNoOps
) {
1638 this->copyNoOps(&wholeBuffer
[fileOffsetOfEndOfLastAtom
], &wholeBuffer
[fileOffset
], lastAtomWasThumb
);
1640 // copy atom content
1641 atom
->copyRawContent(&wholeBuffer
[fileOffset
]);
1643 this->applyFixUps(state
, mhAddress
, atom
, &wholeBuffer
[fileOffset
]);
1644 fileOffsetOfEndOfLastAtom
= fileOffset
+atom
->size();
1645 lastAtomUsesNoOps
= sectionUsesNops
;
1646 lastAtomWasThumb
= atom
->isThumb();
1648 catch (const char* msg
) {
1649 if ( atom
->file() != NULL
)
1650 throwf("%s in %s from %s", msg
, atom
->name(), atom
->file()->path());
1652 throwf("%s in %s", msg
, atom
->name());
1658 if ( _options
.UUIDMode() == Options::kUUIDContent
) {
1659 const bool log
= false;
1660 if ( (_options
.outputKind() != Options::kObjectFile
) || state
.someObjectFileHasDwarf
) {
1661 uint8_t digest
[CC_MD5_DIGEST_LENGTH
];
1662 uint32_t stabsStringsOffsetStart
;
1663 uint32_t tabsStringsOffsetEnd
;
1664 uint32_t stabsOffsetStart
;
1665 uint32_t stabsOffsetEnd
;
1666 if ( _symbolTableAtom
->hasStabs(stabsStringsOffsetStart
, tabsStringsOffsetEnd
, stabsOffsetStart
, stabsOffsetEnd
) ) {
1667 // find two areas of file that are stabs info and should not contribute to checksum
1668 uint64_t stringPoolFileOffset
= 0;
1669 uint64_t symbolTableFileOffset
= 0;
1670 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
1671 ld::Internal::FinalSection
* sect
= *sit
;
1672 if ( sect
->type() == ld::Section::typeLinkEdit
) {
1673 if ( strcmp(sect
->sectionName(), "__string_pool") == 0 )
1674 stringPoolFileOffset
= sect
->fileOffset
;
1675 else if ( strcmp(sect
->sectionName(), "__symbol_table") == 0 )
1676 symbolTableFileOffset
= sect
->fileOffset
;
1679 uint64_t firstStabNlistFileOffset
= symbolTableFileOffset
+ stabsOffsetStart
;
1680 uint64_t lastStabNlistFileOffset
= symbolTableFileOffset
+ stabsOffsetEnd
;
1681 uint64_t firstStabStringFileOffset
= stringPoolFileOffset
+ stabsStringsOffsetStart
;
1682 uint64_t lastStabStringFileOffset
= stringPoolFileOffset
+ tabsStringsOffsetEnd
;
1683 if ( log
) fprintf(stderr
, "firstStabNlistFileOffset=0x%08llX\n", firstStabNlistFileOffset
);
1684 if ( log
) fprintf(stderr
, "lastStabNlistFileOffset=0x%08llX\n", lastStabNlistFileOffset
);
1685 if ( log
) fprintf(stderr
, "firstStabStringFileOffset=0x%08llX\n", firstStabStringFileOffset
);
1686 if ( log
) fprintf(stderr
, "lastStabStringFileOffset=0x%08llX\n", lastStabStringFileOffset
);
1687 assert(firstStabNlistFileOffset
<= firstStabStringFileOffset
);
1689 CC_MD5_CTX md5state
;
1690 CC_MD5_Init(&md5state
);
1691 // checksum everything up to first stabs nlist
1692 if ( log
) fprintf(stderr
, "checksum 0x%08X -> 0x%08llX\n", 0, firstStabNlistFileOffset
);
1693 CC_MD5_Update(&md5state
, &wholeBuffer
[0], firstStabNlistFileOffset
);
1694 // checkusm everything after last stabs nlist and up to first stabs string
1695 if ( log
) fprintf(stderr
, "checksum 0x%08llX -> 0x%08llX\n", lastStabNlistFileOffset
, firstStabStringFileOffset
);
1696 CC_MD5_Update(&md5state
, &wholeBuffer
[lastStabNlistFileOffset
], firstStabStringFileOffset
-lastStabNlistFileOffset
);
1697 // checksum everything after last stabs string to end of file
1698 if ( log
) fprintf(stderr
, "checksum 0x%08llX -> 0x%08llX\n", lastStabStringFileOffset
, _fileSize
);
1699 CC_MD5_Update(&md5state
, &wholeBuffer
[lastStabStringFileOffset
], _fileSize
-lastStabStringFileOffset
);
1700 CC_MD5_Final(digest
, &md5state
);
1701 if ( log
) fprintf(stderr
, "uuid=%02X, %02X, %02X, %02X, %02X, %02X, %02X, %02X\n", digest
[0], digest
[1], digest
[2],
1702 digest
[3], digest
[4], digest
[5], digest
[6], digest
[7]);
1705 CC_MD5(wholeBuffer
, _fileSize
, digest
);
1707 // <rdar://problem/6723729> LC_UUID uuids should conform to RFC 4122 UUID version 4 & UUID version 5 formats
1708 digest
[6] = ( digest
[6] & 0x0F ) | ( 3 << 4 );
1709 digest
[8] = ( digest
[8] & 0x3F ) | 0x80;
1710 // update buffer with new UUID
1711 _headersAndLoadCommandAtom
->setUUID(digest
);
1712 _headersAndLoadCommandAtom
->recopyUUIDCommand();
1716 // write whole output file in one chunk
1717 int fd
= open(_options
.outputFilePath(), O_CREAT
| O_WRONLY
| O_TRUNC
, permissions
);
1719 throwf("can't open output file for writing: %s, errno=%d", _options
.outputFilePath(), errno
);
1720 if ( ::pwrite(fd
, wholeBuffer
, _fileSize
, 0) == -1 )
1721 throwf("can't write to output file: %s, errno=%d", _options
.outputFilePath(), errno
);
1726 struct AtomByNameSorter
1728 bool operator()(const ld::Atom
* left
, const ld::Atom
* right
)
1730 return (strcmp(left
->name(), right
->name()) < 0);
1737 NotInSet(const std::set
<const ld::Atom
*>& theSet
) : _set(theSet
) {}
1739 bool operator()(const ld::Atom
* atom
) const {
1740 return ( _set
.count(atom
) == 0 );
1743 const std::set
<const ld::Atom
*>& _set
;
1747 void OutputFile::buildSymbolTable(ld::Internal
& state
)
1749 unsigned int machoSectionIndex
= 0;
1750 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
1751 ld::Internal::FinalSection
* sect
= *sit
;
1752 bool setMachoSectionIndex
= !sect
->isSectionHidden() && (sect
->type() != ld::Section::typeTentativeDefs
);
1753 if ( setMachoSectionIndex
)
1754 ++machoSectionIndex
;
1755 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
1756 const ld::Atom
* atom
= *ait
;
1757 if ( setMachoSectionIndex
)
1758 (const_cast<ld::Atom
*>(atom
))->setMachoSection(machoSectionIndex
);
1759 else if ( sect
->type() == ld::Section::typeMachHeader
)
1760 (const_cast<ld::Atom
*>(atom
))->setMachoSection(1); // __mh_execute_header is not in any section by needs n_sect==1
1761 else if ( sect
->type() == ld::Section::typeLastSection
)
1762 (const_cast<ld::Atom
*>(atom
))->setMachoSection(machoSectionIndex
); // use section index of previous section
1763 else if ( sect
->type() == ld::Section::typeFirstSection
)
1764 (const_cast<ld::Atom
*>(atom
))->setMachoSection(machoSectionIndex
+1); // use section index of next section
1766 // in -r mode, clarify symbolTableNotInFinalLinkedImages
1767 if ( _options
.outputKind() == Options::kObjectFile
) {
1768 if ( _options
.architecture() == CPU_TYPE_X86_64
) {
1769 // x86_64 .o files need labels on anonymous literal strings
1770 if ( (sect
->type() == ld::Section::typeCString
) && (atom
->combine() == ld::Atom::combineByNameAndContent
) ) {
1771 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableIn
);
1772 _localAtoms
.push_back(atom
);
1776 if ( sect
->type() == ld::Section::typeCFI
) {
1777 if ( _options
.removeEHLabels() )
1778 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableNotIn
);
1780 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableIn
);
1782 if ( atom
->symbolTableInclusion() == ld::Atom::symbolTableNotInFinalLinkedImages
)
1783 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableIn
);
1786 // TEMP work around until <rdar://problem/7702923> goes in
1787 if ( (atom
->symbolTableInclusion() == ld::Atom::symbolTableInAndNeverStrip
)
1788 && (atom
->scope() == ld::Atom::scopeLinkageUnit
)
1789 && (_options
.outputKind() == Options::kDynamicLibrary
) ) {
1790 (const_cast<ld::Atom
*>(atom
))->setScope(ld::Atom::scopeGlobal
);
1793 // <rdar://problem/6783167> support auto hidden weak symbols: .weak_def_can_be_hidden
1794 if ( atom
->autoHide() && (_options
.outputKind() != Options::kObjectFile
) ) {
1795 // adding auto-hide symbol to .exp file should keep it global
1796 if ( !_options
.hasExportMaskList() || !_options
.shouldExport(atom
->name()) )
1797 (const_cast<ld::Atom
*>(atom
))->setScope(ld::Atom::scopeLinkageUnit
);
1800 // <rdar://problem/8626058> ld should consistently warn when resolvers are not exported
1801 if ( (atom
->contentType() == ld::Atom::typeResolver
) && (atom
->scope() == ld::Atom::scopeLinkageUnit
) )
1802 warning("resolver functions should be external, but '%s' is hidden", atom
->name());
1804 if ( sect
->type() == ld::Section::typeImportProxies
) {
1805 if ( atom
->combine() == ld::Atom::combineByName
)
1806 this->usesWeakExternalSymbols
= true;
1807 // alias proxy is a re-export with a name change, don't import changed name
1808 if ( ! atom
->isAlias() )
1809 _importedAtoms
.push_back(atom
);
1810 // scope of proxies are usually linkage unit, so done
1811 // if scope is global, we need to re-export it too
1812 if ( atom
->scope() == ld::Atom::scopeGlobal
)
1813 _exportedAtoms
.push_back(atom
);
1816 if ( atom
->symbolTableInclusion() == ld::Atom::symbolTableNotInFinalLinkedImages
) {
1817 assert(_options
.outputKind() != Options::kObjectFile
);
1818 continue; // don't add to symbol table
1820 if ( atom
->symbolTableInclusion() == ld::Atom::symbolTableNotIn
) {
1821 continue; // don't add to symbol table
1824 if ( (atom
->definition() == ld::Atom::definitionTentative
) && (_options
.outputKind() == Options::kObjectFile
) ) {
1825 if ( _options
.makeTentativeDefinitionsReal() ) {
1826 // -r -d turns tentative defintions into real def
1827 _exportedAtoms
.push_back(atom
);
1830 // in mach-o object files tentative defintions are stored like undefined symbols
1831 _importedAtoms
.push_back(atom
);
1836 // <rdar://problem/7977374> Add command line options to control symbol weak-def bit on exported symbols
1837 if ( _options
.hasWeakBitTweaks() && (atom
->definition() == ld::Atom::definitionRegular
) ) {
1838 const char* name
= atom
->name();
1839 if ( atom
->scope() == ld::Atom::scopeGlobal
) {
1840 if ( atom
->combine() == ld::Atom::combineNever
) {
1841 if ( _options
.forceWeak(name
) )
1842 (const_cast<ld::Atom
*>(atom
))->setCombine(ld::Atom::combineByName
);
1844 else if ( atom
->combine() == ld::Atom::combineByName
) {
1845 if ( _options
.forceNotWeak(name
) )
1846 (const_cast<ld::Atom
*>(atom
))->setCombine(ld::Atom::combineNever
);
1850 if ( _options
.forceWeakNonWildCard(name
) )
1851 warning("cannot force to be weak, non-external symbol %s", name
);
1852 else if ( _options
.forceNotWeakNonWildcard(name
) )
1853 warning("cannot force to be not-weak, non-external symbol %s", name
);
1857 switch ( atom
->scope() ) {
1858 case ld::Atom::scopeTranslationUnit
:
1859 if ( _options
.keepLocalSymbol(atom
->name()) ) {
1860 _localAtoms
.push_back(atom
);
1863 if ( _options
.outputKind() == Options::kObjectFile
) {
1864 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableInWithRandomAutoStripLabel
);
1865 _localAtoms
.push_back(atom
);
1868 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableNotIn
);
1871 case ld::Atom::scopeGlobal
:
1872 _exportedAtoms
.push_back(atom
);
1874 case ld::Atom::scopeLinkageUnit
:
1875 if ( _options
.outputKind() == Options::kObjectFile
) {
1876 if ( _options
.keepPrivateExterns() ) {
1877 assert( (atom
->combine() == ld::Atom::combineNever
) || (atom
->combine() == ld::Atom::combineByName
) );
1878 _exportedAtoms
.push_back(atom
);
1880 else if ( _options
.keepLocalSymbol(atom
->name()) ) {
1881 _localAtoms
.push_back(atom
);
1884 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableInWithRandomAutoStripLabel
);
1885 _localAtoms
.push_back(atom
);
1889 if ( _options
.keepLocalSymbol(atom
->name()) )
1890 _localAtoms
.push_back(atom
);
1891 // <rdar://problem/5804214> ld should never have a symbol in the non-lazy indirect symbol table with index 0
1892 // this works by making __mh_execute_header be a local symbol which takes symbol index 0
1893 else if ( (atom
->symbolTableInclusion() == ld::Atom::symbolTableInAndNeverStrip
) && !_options
.makeCompressedDyldInfo() )
1894 _localAtoms
.push_back(atom
);
1896 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableNotIn
);
1903 // <rdar://problem/6978069> ld adds undefined symbol from .exp file to binary
1904 if ( (_options
.outputKind() == Options::kKextBundle
) && _options
.hasExportRestrictList() ) {
1905 // search for referenced undefines
1906 std::set
<const ld::Atom
*> referencedProxyAtoms
;
1907 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
=state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
1908 ld::Internal::FinalSection
* sect
= *sit
;
1909 for (std::vector
<const ld::Atom
*>::iterator ait
=sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
1910 const ld::Atom
* atom
= *ait
;
1911 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(), end
=atom
->fixupsEnd(); fit
!= end
; ++fit
) {
1912 switch ( fit
->binding
) {
1913 case ld::Fixup::bindingsIndirectlyBound
:
1914 referencedProxyAtoms
.insert(state
.indirectBindingTable
[fit
->u
.bindingIndex
]);
1916 case ld::Fixup::bindingDirectlyBound
:
1917 referencedProxyAtoms
.insert(fit
->u
.target
);
1925 // remove any unreferenced _importedAtoms
1926 _importedAtoms
.erase(std::remove_if(_importedAtoms
.begin(), _importedAtoms
.end(), NotInSet(referencedProxyAtoms
)), _importedAtoms
.end());
1930 std::sort(_exportedAtoms
.begin(), _exportedAtoms
.end(), AtomByNameSorter());
1931 std::sort(_importedAtoms
.begin(), _importedAtoms
.end(), AtomByNameSorter());
1934 void OutputFile::addPreloadLinkEdit(ld::Internal
& state
)
1936 switch ( _options
.architecture() ) {
1938 if ( _hasLocalRelocations
) {
1939 _localRelocsAtom
= new LocalRelocationsAtom
<x86
>(_options
, state
, *this);
1940 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
1942 if ( _hasExternalRelocations
) {
1943 _externalRelocsAtom
= new ExternalRelocationsAtom
<x86
>(_options
, state
, *this);
1944 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
1946 if ( _hasSymbolTable
) {
1947 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<x86
>(_options
, state
, *this);
1948 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
1949 _symbolTableAtom
= new SymbolTableAtom
<x86
>(_options
, state
, *this);
1950 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
1951 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 4);
1952 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
1955 case CPU_TYPE_X86_64
:
1956 if ( _hasLocalRelocations
) {
1957 _localRelocsAtom
= new LocalRelocationsAtom
<x86_64
>(_options
, state
, *this);
1958 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
1960 if ( _hasExternalRelocations
) {
1961 _externalRelocsAtom
= new ExternalRelocationsAtom
<x86_64
>(_options
, state
, *this);
1962 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
1964 if ( _hasSymbolTable
) {
1965 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<x86_64
>(_options
, state
, *this);
1966 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
1967 _symbolTableAtom
= new SymbolTableAtom
<x86_64
>(_options
, state
, *this);
1968 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
1969 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 4);
1970 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
1974 if ( _hasLocalRelocations
) {
1975 _localRelocsAtom
= new LocalRelocationsAtom
<arm
>(_options
, state
, *this);
1976 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
1978 if ( _hasExternalRelocations
) {
1979 _externalRelocsAtom
= new ExternalRelocationsAtom
<arm
>(_options
, state
, *this);
1980 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
1982 if ( _hasSymbolTable
) {
1983 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<arm
>(_options
, state
, *this);
1984 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
1985 _symbolTableAtom
= new SymbolTableAtom
<arm
>(_options
, state
, *this);
1986 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
1987 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 4);
1988 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
1992 throw "architecture not supported for -preload";
1998 void OutputFile::addLinkEdit(ld::Internal
& state
)
2000 // for historical reasons, -preload orders LINKEDIT content differently
2001 if ( _options
.outputKind() == Options::kPreload
)
2002 return addPreloadLinkEdit(state
);
2004 switch ( _options
.architecture() ) {
2005 case CPU_TYPE_POWERPC
:
2006 if ( _hasSectionRelocations
) {
2007 _sectionsRelocationsAtom
= new SectionRelocationsAtom
<ppc
>(_options
, state
, *this);
2008 sectionRelocationsSection
= state
.addAtom(*_sectionsRelocationsAtom
);
2010 if ( _hasDyldInfo
) {
2011 _rebasingInfoAtom
= new RebaseInfoAtom
<ppc
>(_options
, state
, *this);
2012 rebaseSection
= state
.addAtom(*_rebasingInfoAtom
);
2014 _bindingInfoAtom
= new BindingInfoAtom
<ppc
>(_options
, state
, *this);
2015 bindingSection
= state
.addAtom(*_bindingInfoAtom
);
2017 _weakBindingInfoAtom
= new WeakBindingInfoAtom
<ppc
>(_options
, state
, *this);
2018 weakBindingSection
= state
.addAtom(*_weakBindingInfoAtom
);
2020 _lazyBindingInfoAtom
= new LazyBindingInfoAtom
<ppc
>(_options
, state
, *this);
2021 lazyBindingSection
= state
.addAtom(*_lazyBindingInfoAtom
);
2023 _exportInfoAtom
= new ExportInfoAtom
<ppc
>(_options
, state
, *this);
2024 exportSection
= state
.addAtom(*_exportInfoAtom
);
2026 if ( _hasLocalRelocations
) {
2027 _localRelocsAtom
= new LocalRelocationsAtom
<ppc
>(_options
, state
, *this);
2028 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
2030 if ( _hasSplitSegInfo
) {
2031 _splitSegInfoAtom
= new SplitSegInfoAtom
<ppc
>(_options
, state
, *this);
2032 splitSegInfoSection
= state
.addAtom(*_splitSegInfoAtom
);
2034 if ( _hasFunctionStartsInfo
) {
2035 _functionStartsAtom
= new FunctionStartsAtom
<ppc
>(_options
, state
, *this);
2036 functionStartsSection
= state
.addAtom(*_functionStartsAtom
);
2038 if ( _hasSymbolTable
) {
2039 _symbolTableAtom
= new SymbolTableAtom
<ppc
>(_options
, state
, *this);
2040 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
2042 if ( _hasExternalRelocations
) {
2043 _externalRelocsAtom
= new ExternalRelocationsAtom
<ppc
>(_options
, state
, *this);
2044 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
2046 if ( _hasSymbolTable
) {
2047 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<ppc
>(_options
, state
, *this);
2048 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
2049 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 4);
2050 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
2054 if ( _hasSectionRelocations
) {
2055 _sectionsRelocationsAtom
= new SectionRelocationsAtom
<x86
>(_options
, state
, *this);
2056 sectionRelocationsSection
= state
.addAtom(*_sectionsRelocationsAtom
);
2058 if ( _hasDyldInfo
) {
2059 _rebasingInfoAtom
= new RebaseInfoAtom
<x86
>(_options
, state
, *this);
2060 rebaseSection
= state
.addAtom(*_rebasingInfoAtom
);
2062 _bindingInfoAtom
= new BindingInfoAtom
<x86
>(_options
, state
, *this);
2063 bindingSection
= state
.addAtom(*_bindingInfoAtom
);
2065 _weakBindingInfoAtom
= new WeakBindingInfoAtom
<x86
>(_options
, state
, *this);
2066 weakBindingSection
= state
.addAtom(*_weakBindingInfoAtom
);
2068 _lazyBindingInfoAtom
= new LazyBindingInfoAtom
<x86
>(_options
, state
, *this);
2069 lazyBindingSection
= state
.addAtom(*_lazyBindingInfoAtom
);
2071 _exportInfoAtom
= new ExportInfoAtom
<x86
>(_options
, state
, *this);
2072 exportSection
= state
.addAtom(*_exportInfoAtom
);
2074 if ( _hasLocalRelocations
) {
2075 _localRelocsAtom
= new LocalRelocationsAtom
<x86
>(_options
, state
, *this);
2076 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
2078 if ( _hasSplitSegInfo
) {
2079 _splitSegInfoAtom
= new SplitSegInfoAtom
<x86
>(_options
, state
, *this);
2080 splitSegInfoSection
= state
.addAtom(*_splitSegInfoAtom
);
2082 if ( _hasFunctionStartsInfo
) {
2083 _functionStartsAtom
= new FunctionStartsAtom
<x86
>(_options
, state
, *this);
2084 functionStartsSection
= state
.addAtom(*_functionStartsAtom
);
2086 if ( _hasSymbolTable
) {
2087 _symbolTableAtom
= new SymbolTableAtom
<x86
>(_options
, state
, *this);
2088 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
2090 if ( _hasExternalRelocations
) {
2091 _externalRelocsAtom
= new ExternalRelocationsAtom
<x86
>(_options
, state
, *this);
2092 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
2094 if ( _hasSymbolTable
) {
2095 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<x86
>(_options
, state
, *this);
2096 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
2097 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 4);
2098 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
2101 case CPU_TYPE_X86_64
:
2102 if ( _hasSectionRelocations
) {
2103 _sectionsRelocationsAtom
= new SectionRelocationsAtom
<x86_64
>(_options
, state
, *this);
2104 sectionRelocationsSection
= state
.addAtom(*_sectionsRelocationsAtom
);
2106 if ( _hasDyldInfo
) {
2107 _rebasingInfoAtom
= new RebaseInfoAtom
<x86_64
>(_options
, state
, *this);
2108 rebaseSection
= state
.addAtom(*_rebasingInfoAtom
);
2110 _bindingInfoAtom
= new BindingInfoAtom
<x86_64
>(_options
, state
, *this);
2111 bindingSection
= state
.addAtom(*_bindingInfoAtom
);
2113 _weakBindingInfoAtom
= new WeakBindingInfoAtom
<x86_64
>(_options
, state
, *this);
2114 weakBindingSection
= state
.addAtom(*_weakBindingInfoAtom
);
2116 _lazyBindingInfoAtom
= new LazyBindingInfoAtom
<x86_64
>(_options
, state
, *this);
2117 lazyBindingSection
= state
.addAtom(*_lazyBindingInfoAtom
);
2119 _exportInfoAtom
= new ExportInfoAtom
<x86_64
>(_options
, state
, *this);
2120 exportSection
= state
.addAtom(*_exportInfoAtom
);
2122 if ( _hasLocalRelocations
) {
2123 _localRelocsAtom
= new LocalRelocationsAtom
<x86_64
>(_options
, state
, *this);
2124 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
2126 if ( _hasSplitSegInfo
) {
2127 _splitSegInfoAtom
= new SplitSegInfoAtom
<x86_64
>(_options
, state
, *this);
2128 splitSegInfoSection
= state
.addAtom(*_splitSegInfoAtom
);
2130 if ( _hasFunctionStartsInfo
) {
2131 _functionStartsAtom
= new FunctionStartsAtom
<x86_64
>(_options
, state
, *this);
2132 functionStartsSection
= state
.addAtom(*_functionStartsAtom
);
2134 if ( _hasSymbolTable
) {
2135 _symbolTableAtom
= new SymbolTableAtom
<x86_64
>(_options
, state
, *this);
2136 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
2138 if ( _hasExternalRelocations
) {
2139 _externalRelocsAtom
= new ExternalRelocationsAtom
<x86_64
>(_options
, state
, *this);
2140 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
2142 if ( _hasSymbolTable
) {
2143 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<x86_64
>(_options
, state
, *this);
2144 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
2145 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 8);
2146 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
2150 if ( _hasSectionRelocations
) {
2151 _sectionsRelocationsAtom
= new SectionRelocationsAtom
<arm
>(_options
, state
, *this);
2152 sectionRelocationsSection
= state
.addAtom(*_sectionsRelocationsAtom
);
2154 if ( _hasDyldInfo
) {
2155 _rebasingInfoAtom
= new RebaseInfoAtom
<arm
>(_options
, state
, *this);
2156 rebaseSection
= state
.addAtom(*_rebasingInfoAtom
);
2158 _bindingInfoAtom
= new BindingInfoAtom
<arm
>(_options
, state
, *this);
2159 bindingSection
= state
.addAtom(*_bindingInfoAtom
);
2161 _weakBindingInfoAtom
= new WeakBindingInfoAtom
<arm
>(_options
, state
, *this);
2162 weakBindingSection
= state
.addAtom(*_weakBindingInfoAtom
);
2164 _lazyBindingInfoAtom
= new LazyBindingInfoAtom
<arm
>(_options
, state
, *this);
2165 lazyBindingSection
= state
.addAtom(*_lazyBindingInfoAtom
);
2167 _exportInfoAtom
= new ExportInfoAtom
<arm
>(_options
, state
, *this);
2168 exportSection
= state
.addAtom(*_exportInfoAtom
);
2170 if ( _hasLocalRelocations
) {
2171 _localRelocsAtom
= new LocalRelocationsAtom
<arm
>(_options
, state
, *this);
2172 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
2174 if ( _hasSplitSegInfo
) {
2175 _splitSegInfoAtom
= new SplitSegInfoAtom
<arm
>(_options
, state
, *this);
2176 splitSegInfoSection
= state
.addAtom(*_splitSegInfoAtom
);
2178 if ( _hasFunctionStartsInfo
) {
2179 _functionStartsAtom
= new FunctionStartsAtom
<arm
>(_options
, state
, *this);
2180 functionStartsSection
= state
.addAtom(*_functionStartsAtom
);
2182 if ( _hasSymbolTable
) {
2183 _symbolTableAtom
= new SymbolTableAtom
<arm
>(_options
, state
, *this);
2184 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
2186 if ( _hasExternalRelocations
) {
2187 _externalRelocsAtom
= new ExternalRelocationsAtom
<arm
>(_options
, state
, *this);
2188 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
2190 if ( _hasSymbolTable
) {
2191 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<arm
>(_options
, state
, *this);
2192 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
2193 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 4);
2194 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
2197 case CPU_TYPE_POWERPC64
:
2198 if ( _hasSectionRelocations
) {
2199 _sectionsRelocationsAtom
= new SectionRelocationsAtom
<ppc64
>(_options
, state
, *this);
2200 sectionRelocationsSection
= state
.addAtom(*_sectionsRelocationsAtom
);
2202 if ( _hasDyldInfo
) {
2203 _rebasingInfoAtom
= new RebaseInfoAtom
<ppc64
>(_options
, state
, *this);
2204 rebaseSection
= state
.addAtom(*_rebasingInfoAtom
);
2206 _bindingInfoAtom
= new BindingInfoAtom
<ppc64
>(_options
, state
, *this);
2207 bindingSection
= state
.addAtom(*_bindingInfoAtom
);
2209 _weakBindingInfoAtom
= new WeakBindingInfoAtom
<ppc64
>(_options
, state
, *this);
2210 weakBindingSection
= state
.addAtom(*_weakBindingInfoAtom
);
2212 _lazyBindingInfoAtom
= new LazyBindingInfoAtom
<ppc64
>(_options
, state
, *this);
2213 lazyBindingSection
= state
.addAtom(*_lazyBindingInfoAtom
);
2215 _exportInfoAtom
= new ExportInfoAtom
<ppc64
>(_options
, state
, *this);
2216 exportSection
= state
.addAtom(*_exportInfoAtom
);
2218 if ( _hasLocalRelocations
) {
2219 _localRelocsAtom
= new LocalRelocationsAtom
<ppc64
>(_options
, state
, *this);
2220 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
2222 if ( _hasSplitSegInfo
) {
2223 _splitSegInfoAtom
= new SplitSegInfoAtom
<ppc64
>(_options
, state
, *this);
2224 splitSegInfoSection
= state
.addAtom(*_splitSegInfoAtom
);
2226 if ( _hasFunctionStartsInfo
) {
2227 _functionStartsAtom
= new FunctionStartsAtom
<ppc64
>(_options
, state
, *this);
2228 functionStartsSection
= state
.addAtom(*_functionStartsAtom
);
2230 if ( _hasSymbolTable
) {
2231 _symbolTableAtom
= new SymbolTableAtom
<ppc64
>(_options
, state
, *this);
2232 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
2234 if ( _hasExternalRelocations
) {
2235 _externalRelocsAtom
= new ExternalRelocationsAtom
<ppc64
>(_options
, state
, *this);
2236 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
2238 if ( _hasSymbolTable
) {
2239 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<ppc64
>(_options
, state
, *this);
2240 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
2241 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 4);
2242 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
2246 throw "unknown architecture";
2250 void OutputFile::addLoadCommands(ld::Internal
& state
)
2252 switch ( _options
.architecture() ) {
2253 case CPU_TYPE_X86_64
:
2254 _headersAndLoadCommandAtom
= new HeaderAndLoadCommandsAtom
<x86_64
>(_options
, state
, *this);
2255 headerAndLoadCommandsSection
= state
.addAtom(*_headersAndLoadCommandAtom
);
2258 _headersAndLoadCommandAtom
= new HeaderAndLoadCommandsAtom
<arm
>(_options
, state
, *this);
2259 headerAndLoadCommandsSection
= state
.addAtom(*_headersAndLoadCommandAtom
);
2262 _headersAndLoadCommandAtom
= new HeaderAndLoadCommandsAtom
<x86
>(_options
, state
, *this);
2263 headerAndLoadCommandsSection
= state
.addAtom(*_headersAndLoadCommandAtom
);
2265 case CPU_TYPE_POWERPC
:
2266 _headersAndLoadCommandAtom
= new HeaderAndLoadCommandsAtom
<ppc
>(_options
, state
, *this);
2267 headerAndLoadCommandsSection
= state
.addAtom(*_headersAndLoadCommandAtom
);
2269 case CPU_TYPE_POWERPC64
:
2270 _headersAndLoadCommandAtom
= new HeaderAndLoadCommandsAtom
<ppc64
>(_options
, state
, *this);
2271 headerAndLoadCommandsSection
= state
.addAtom(*_headersAndLoadCommandAtom
);
2274 throw "unknown architecture";
2278 uint32_t OutputFile::dylibCount()
2280 return _dylibsToLoad
.size();
2283 const ld::dylib::File
* OutputFile::dylibByOrdinal(unsigned int ordinal
)
2285 assert( ordinal
> 0 );
2286 assert( ordinal
<= _dylibsToLoad
.size() );
2287 return _dylibsToLoad
[ordinal
-1];
2290 bool OutputFile::hasOrdinalForInstallPath(const char* path
, int* ordinal
)
2292 for (std::map
<const ld::dylib::File
*, int>::const_iterator it
= _dylibToOrdinal
.begin(); it
!= _dylibToOrdinal
.end(); ++it
) {
2293 const char* installPath
= it
->first
->installPath();
2294 if ( (installPath
!= NULL
) && (strcmp(path
, installPath
) == 0) ) {
2295 *ordinal
= it
->second
;
2302 uint32_t OutputFile::dylibToOrdinal(const ld::dylib::File
* dylib
)
2304 return _dylibToOrdinal
[dylib
];
2308 void OutputFile::buildDylibOrdinalMapping(ld::Internal
& state
)
2310 // count non-public re-exported dylibs
2311 unsigned int nonPublicReExportCount
= 0;
2312 for (std::vector
<ld::dylib::File
*>::iterator it
= state
.dylibs
.begin(); it
!= state
.dylibs
.end(); ++it
) {
2313 ld::dylib::File
* aDylib
= *it
;
2314 if ( aDylib
->willBeReExported() && ! aDylib
->hasPublicInstallName() )
2315 ++nonPublicReExportCount
;
2318 // look at each dylib supplied in state
2319 bool hasReExports
= false;
2320 bool haveLazyDylibs
= false;
2321 for (std::vector
<ld::dylib::File
*>::iterator it
= state
.dylibs
.begin(); it
!= state
.dylibs
.end(); ++it
) {
2322 ld::dylib::File
* aDylib
= *it
;
2324 if ( aDylib
== state
.bundleLoader
) {
2325 _dylibToOrdinal
[aDylib
] = BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE
;
2327 else if ( this->hasOrdinalForInstallPath(aDylib
->installPath(), &ordinal
) ) {
2328 // already have a dylib with that install path, map all uses to that ordinal
2329 _dylibToOrdinal
[aDylib
] = ordinal
;
2331 else if ( aDylib
->willBeLazyLoadedDylib() ) {
2332 // all lazy dylib need to be at end of ordinals
2333 haveLazyDylibs
= true;
2335 else if ( aDylib
->willBeReExported() && ! aDylib
->hasPublicInstallName() && (nonPublicReExportCount
>= 2) ) {
2336 _dylibsToLoad
.push_back(aDylib
);
2337 _dylibToOrdinal
[aDylib
] = BIND_SPECIAL_DYLIB_SELF
;
2340 // first time this install path seen, create new ordinal
2341 _dylibsToLoad
.push_back(aDylib
);
2342 _dylibToOrdinal
[aDylib
] = _dylibsToLoad
.size();
2344 if ( aDylib
->explicitlyLinked() && aDylib
->willBeReExported() )
2345 hasReExports
= true;
2347 if ( haveLazyDylibs
) {
2348 // second pass to determine ordinals for lazy loaded dylibs
2349 for (std::vector
<ld::dylib::File
*>::iterator it
= state
.dylibs
.begin(); it
!= state
.dylibs
.end(); ++it
) {
2350 ld::dylib::File
* aDylib
= *it
;
2351 if ( aDylib
->willBeLazyLoadedDylib() ) {
2353 if ( this->hasOrdinalForInstallPath(aDylib
->installPath(), &ordinal
) ) {
2354 // already have a dylib with that install path, map all uses to that ordinal
2355 _dylibToOrdinal
[aDylib
] = ordinal
;
2358 // first time this install path seen, create new ordinal
2359 _dylibsToLoad
.push_back(aDylib
);
2360 _dylibToOrdinal
[aDylib
] = _dylibsToLoad
.size();
2365 _noReExportedDylibs
= !hasReExports
;
2366 //fprintf(stderr, "dylibs:\n");
2367 //for (std::map<const ld::dylib::File*, int>::const_iterator it = _dylibToOrdinal.begin(); it != _dylibToOrdinal.end(); ++it) {
2368 // fprintf(stderr, " %p ord=%u, install_name=%s\n",it->first, it->second, it->first->installPath());
2372 uint32_t OutputFile::lazyBindingInfoOffsetForLazyPointerAddress(uint64_t lpAddress
)
2374 return _lazyPointerAddressToInfoOffset
[lpAddress
];
2377 void OutputFile::setLazyBindingInfoOffset(uint64_t lpAddress
, uint32_t lpInfoOffset
)
2379 _lazyPointerAddressToInfoOffset
[lpAddress
] = lpInfoOffset
;
2382 int OutputFile::compressedOrdinalForAtom(const ld::Atom
* target
)
2384 // flat namespace images use zero for all ordinals
2385 if ( _options
.nameSpace() != Options::kTwoLevelNameSpace
)
2386 return BIND_SPECIAL_DYLIB_FLAT_LOOKUP
;
2388 // handle -interposable
2389 if ( target
->definition() == ld::Atom::definitionRegular
)
2390 return BIND_SPECIAL_DYLIB_SELF
;
2393 const ld::dylib::File
* dylib
= dynamic_cast<const ld::dylib::File
*>(target
->file());
2394 if ( dylib
!= NULL
)
2395 return _dylibToOrdinal
[dylib
];
2397 // handle undefined dynamic_lookup
2398 if ( _options
.undefinedTreatment() == Options::kUndefinedDynamicLookup
)
2399 return BIND_SPECIAL_DYLIB_FLAT_LOOKUP
;
2402 if ( _options
.allowedUndefined(target
->name()) )
2403 return BIND_SPECIAL_DYLIB_FLAT_LOOKUP
;
2405 throw "can't find ordinal for imported symbol";
2409 bool OutputFile::isPcRelStore(ld::Fixup::Kind kind
)
2412 case ld::Fixup::kindStoreX86BranchPCRel8
:
2413 case ld::Fixup::kindStoreX86BranchPCRel32
:
2414 case ld::Fixup::kindStoreX86PCRel8
:
2415 case ld::Fixup::kindStoreX86PCRel16
:
2416 case ld::Fixup::kindStoreX86PCRel32
:
2417 case ld::Fixup::kindStoreX86PCRel32_1
:
2418 case ld::Fixup::kindStoreX86PCRel32_2
:
2419 case ld::Fixup::kindStoreX86PCRel32_4
:
2420 case ld::Fixup::kindStoreX86PCRel32GOTLoad
:
2421 case ld::Fixup::kindStoreX86PCRel32GOTLoadNowLEA
:
2422 case ld::Fixup::kindStoreX86PCRel32GOT
:
2423 case ld::Fixup::kindStoreX86PCRel32TLVLoad
:
2424 case ld::Fixup::kindStoreX86PCRel32TLVLoadNowLEA
:
2425 case ld::Fixup::kindStoreARMBranch24
:
2426 case ld::Fixup::kindStoreThumbBranch22
:
2427 case ld::Fixup::kindStoreARMLoad12
:
2428 case ld::Fixup::kindStorePPCBranch24
:
2429 case ld::Fixup::kindStorePPCBranch14
:
2430 case ld::Fixup::kindStorePPCPicLow14
:
2431 case ld::Fixup::kindStorePPCPicLow16
:
2432 case ld::Fixup::kindStorePPCPicHigh16AddLow
:
2433 case ld::Fixup::kindStoreTargetAddressX86PCRel32
:
2434 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad
:
2435 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA
:
2436 case ld::Fixup::kindStoreTargetAddressARMBranch24
:
2437 case ld::Fixup::kindStoreTargetAddressThumbBranch22
:
2438 case ld::Fixup::kindStoreTargetAddressARMLoad12
:
2439 case ld::Fixup::kindStoreTargetAddressPPCBranch24
:
2441 case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32
:
2442 return (_options
.outputKind() != Options::kKextBundle
);
2449 bool OutputFile::isStore(ld::Fixup::Kind kind
)
2452 case ld::Fixup::kindNone
:
2453 case ld::Fixup::kindNoneFollowOn
:
2454 case ld::Fixup::kindNoneGroupSubordinate
:
2455 case ld::Fixup::kindNoneGroupSubordinateFDE
:
2456 case ld::Fixup::kindNoneGroupSubordinateLSDA
:
2457 case ld::Fixup::kindNoneGroupSubordinatePersonality
:
2458 case ld::Fixup::kindSetTargetAddress
:
2459 case ld::Fixup::kindSubtractTargetAddress
:
2460 case ld::Fixup::kindAddAddend
:
2461 case ld::Fixup::kindSubtractAddend
:
2462 case ld::Fixup::kindSetTargetImageOffset
:
2463 case ld::Fixup::kindSetTargetSectionOffset
:
2472 bool OutputFile::setsTarget(ld::Fixup::Kind kind
)
2475 case ld::Fixup::kindSetTargetAddress
:
2476 case ld::Fixup::kindLazyTarget
:
2477 case ld::Fixup::kindStoreTargetAddressLittleEndian32
:
2478 case ld::Fixup::kindStoreTargetAddressLittleEndian64
:
2479 case ld::Fixup::kindStoreTargetAddressBigEndian32
:
2480 case ld::Fixup::kindStoreTargetAddressBigEndian64
:
2481 case ld::Fixup::kindStoreTargetAddressX86PCRel32
:
2482 case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32
:
2483 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad
:
2484 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA
:
2485 case ld::Fixup::kindStoreTargetAddressARMBranch24
:
2486 case ld::Fixup::kindStoreTargetAddressThumbBranch22
:
2487 case ld::Fixup::kindStoreTargetAddressARMLoad12
:
2488 case ld::Fixup::kindStoreTargetAddressPPCBranch24
:
2490 case ld::Fixup::kindStoreX86DtraceCallSiteNop
:
2491 case ld::Fixup::kindStoreX86DtraceIsEnableSiteClear
:
2492 case ld::Fixup::kindStoreARMDtraceCallSiteNop
:
2493 case ld::Fixup::kindStoreARMDtraceIsEnableSiteClear
:
2494 case ld::Fixup::kindStoreThumbDtraceCallSiteNop
:
2495 case ld::Fixup::kindStoreThumbDtraceIsEnableSiteClear
:
2496 case ld::Fixup::kindStorePPCDtraceCallSiteNop
:
2497 case ld::Fixup::kindStorePPCDtraceIsEnableSiteClear
:
2498 return (_options
.outputKind() == Options::kObjectFile
);
2505 bool OutputFile::isPointerToTarget(ld::Fixup::Kind kind
)
2508 case ld::Fixup::kindSetTargetAddress
:
2509 case ld::Fixup::kindStoreTargetAddressLittleEndian32
:
2510 case ld::Fixup::kindStoreTargetAddressLittleEndian64
:
2511 case ld::Fixup::kindStoreTargetAddressBigEndian32
:
2512 case ld::Fixup::kindStoreTargetAddressBigEndian64
:
2513 case ld::Fixup::kindLazyTarget
:
2520 bool OutputFile::isPointerFromTarget(ld::Fixup::Kind kind
)
2523 case ld::Fixup::kindSubtractTargetAddress
:
2532 uint64_t OutputFile::lookBackAddend(ld::Fixup::iterator fit
)
2534 uint64_t addend
= 0;
2535 switch ( fit
->clusterSize
) {
2536 case ld::Fixup::k1of1
:
2537 case ld::Fixup::k1of2
:
2538 case ld::Fixup::k2of2
:
2540 case ld::Fixup::k2of3
:
2542 switch ( fit
->kind
) {
2543 case ld::Fixup::kindAddAddend
:
2544 addend
+= fit
->u
.addend
;
2546 case ld::Fixup::kindSubtractAddend
:
2547 addend
-= fit
->u
.addend
;
2550 throw "unexpected fixup kind for binding";
2553 case ld::Fixup::k1of3
:
2555 switch ( fit
->kind
) {
2556 case ld::Fixup::kindAddAddend
:
2557 addend
+= fit
->u
.addend
;
2559 case ld::Fixup::kindSubtractAddend
:
2560 addend
-= fit
->u
.addend
;
2563 throw "unexpected fixup kind for binding";
2567 throw "unexpected fixup cluster size for binding";
2576 void OutputFile::generateLinkEditInfo(ld::Internal
& state
)
2578 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
2579 ld::Internal::FinalSection
* sect
= *sit
;
2580 bool objc1ClassRefSection
= ( (sect
->type() == ld::Section::typeCStringPointer
)
2581 && (strcmp(sect
->sectionName(), "__cls_refs") == 0)
2582 && (strcmp(sect
->segmentName(), "__OBJC") == 0) );
2583 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
2584 const ld::Atom
* atom
= *ait
;
2586 // Record regular atoms that override a dylib's weak definitions
2587 if ( (atom
->scope() == ld::Atom::scopeGlobal
) && atom
->overridesDylibsWeakDef() ) {
2588 if ( _options
.makeCompressedDyldInfo() ) {
2589 uint8_t wtype
= BIND_TYPE_OVERRIDE_OF_WEAKDEF_IN_DYLIB
;
2590 bool nonWeakDef
= (atom
->combine() == ld::Atom::combineNever
);
2591 _weakBindingInfo
.push_back(BindingInfo(wtype
, atom
->name(), nonWeakDef
, atom
->finalAddress(), 0));
2593 this->overridesWeakExternalSymbols
= true;
2594 if ( _options
.warnWeakExports() )
2595 warning("overrides weak external symbol: %s", atom
->name());
2598 ld::Fixup
* fixupWithTarget
= NULL
;
2599 ld::Fixup
* fixupWithMinusTarget
= NULL
;
2600 ld::Fixup
* fixupWithStore
= NULL
;
2601 const ld::Atom
* target
= NULL
;
2602 const ld::Atom
* minusTarget
= NULL
;
2603 uint64_t targetAddend
= 0;
2604 uint64_t minusTargetAddend
= 0;
2605 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(); fit
!= atom
->fixupsEnd(); ++fit
) {
2606 if ( fit
->firstInCluster() ) {
2607 fixupWithTarget
= NULL
;
2608 fixupWithMinusTarget
= NULL
;
2609 fixupWithStore
= NULL
;
2613 minusTargetAddend
= 0;
2615 if ( this->setsTarget(fit
->kind
) ) {
2616 switch ( fit
->binding
) {
2617 case ld::Fixup::bindingNone
:
2618 case ld::Fixup::bindingByNameUnbound
:
2620 case ld::Fixup::bindingByContentBound
:
2621 case ld::Fixup::bindingDirectlyBound
:
2622 fixupWithTarget
= fit
;
2623 target
= fit
->u
.target
;
2625 case ld::Fixup::bindingsIndirectlyBound
:
2626 fixupWithTarget
= fit
;
2627 target
= state
.indirectBindingTable
[fit
->u
.bindingIndex
];
2630 assert(target
!= NULL
);
2632 switch ( fit
->kind
) {
2633 case ld::Fixup::kindAddAddend
:
2634 targetAddend
= fit
->u
.addend
;
2636 case ld::Fixup::kindSubtractAddend
:
2637 minusTargetAddend
= fit
->u
.addend
;
2639 case ld::Fixup::kindSubtractTargetAddress
:
2640 switch ( fit
->binding
) {
2641 case ld::Fixup::bindingNone
:
2642 case ld::Fixup::bindingByNameUnbound
:
2644 case ld::Fixup::bindingByContentBound
:
2645 case ld::Fixup::bindingDirectlyBound
:
2646 fixupWithMinusTarget
= fit
;
2647 minusTarget
= fit
->u
.target
;
2649 case ld::Fixup::bindingsIndirectlyBound
:
2650 fixupWithMinusTarget
= fit
;
2651 minusTarget
= state
.indirectBindingTable
[fit
->u
.bindingIndex
];
2654 assert(minusTarget
!= NULL
);
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
.iOSVersionMin() >= ld::iOS_4_3
) || (_options
.macosxVersionMin() >= ld::mac10_7
)) ) {
2702 if ( ! this->pieDisabled
) {
2703 warning("PIE disabled. Absolute addressing (perhaps -mdynamic-no-pic) not allowed in code signed PIE, "
2704 "but used in %s from %s. "
2705 "To fix this warning, don't compile with -mdynamic-no-pic or link with -Wl,-no_pie",
2706 atom
->name(), atom
->file()->path());
2708 this->pieDisabled
= true;
2710 else if ( (target
->scope() == ld::Atom::scopeGlobal
) && (target
->combine() == ld::Atom::combineByName
) ) {
2711 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());
2714 throwf("illegal text-relocation to %s in %s from %s in %s", target
->name(), target
->file()->path(), atom
->name(), atom
->file()->path());
2718 void OutputFile::addDyldInfo(ld::Internal
& state
, ld::Internal::FinalSection
* sect
, const ld::Atom
* atom
,
2719 ld::Fixup
* fixupWithTarget
, ld::Fixup
* fixupWithMinusTarget
, ld::Fixup
* fixupWithStore
,
2720 const ld::Atom
* target
, const ld::Atom
* minusTarget
,
2721 uint64_t targetAddend
, uint64_t minusTargetAddend
)
2723 if ( sect
->isSectionHidden() )
2726 // no need to rebase or bind PCRel stores
2727 if ( this->isPcRelStore(fixupWithStore
->kind
) ) {
2728 // as long as target is in same linkage unit
2729 if ( (target
== NULL
) || (target
->definition() != ld::Atom::definitionProxy
) ) {
2730 // make sure target is not global and weak
2731 if ( (target
->scope() == ld::Atom::scopeGlobal
) && (target
->combine() == ld::Atom::combineByName
) && (target
->definition() == ld::Atom::definitionRegular
)) {
2732 if ( (atom
->section().type() == ld::Section::typeCFI
)
2733 || (atom
->section().type() == ld::Section::typeDtraceDOF
)
2734 || (atom
->section().type() == ld::Section::typeUnwindInfo
) ) {
2735 // ok for __eh_frame and __uwind_info to use pointer diffs to global weak symbols
2738 // Have direct reference to weak-global. This should be an indrect reference
2739 warning("direct access in %s to global weak symbol %s means the weak symbol cannot be overridden at runtime. "
2740 "This was likely caused by different translation units being compiled with different visibility settings.",
2741 atom
->name(), target
->name());
2747 // no need to rebase or bind PIC internal pointer diff
2748 if ( minusTarget
!= NULL
) {
2749 // with pointer diffs, both need to be in same linkage unit
2750 assert(minusTarget
->definition() != ld::Atom::definitionProxy
);
2751 assert(target
!= NULL
);
2752 assert(target
->definition() != ld::Atom::definitionProxy
);
2753 if ( target
== minusTarget
) {
2754 // This is a compile time constant and could have been optimized away by compiler
2758 // check if target of pointer-diff is global and weak
2759 if ( (target
->scope() == ld::Atom::scopeGlobal
) && (target
->combine() == ld::Atom::combineByName
) && (target
->definition() == ld::Atom::definitionRegular
) ) {
2760 if ( (atom
->section().type() == ld::Section::typeCFI
)
2761 || (atom
->section().type() == ld::Section::typeDtraceDOF
)
2762 || (atom
->section().type() == ld::Section::typeUnwindInfo
) ) {
2763 // ok for __eh_frame and __uwind_info to use pointer diffs to global weak symbols
2766 // Have direct reference to weak-global. This should be an indrect reference
2767 warning("direct access in %s to global weak symbol %s means the weak symbol cannot be overridden at runtime. "
2768 "This was likely caused by different translation units being compiled with different visibility settings.",
2769 atom
->name(), target
->name());
2774 // no need to rebase or bind an atom's references to itself if the output is not slidable
2775 if ( (atom
== target
) && !_options
.outputSlidable() )
2778 // cluster has no target, so needs no rebasing or binding
2779 if ( target
== NULL
)
2782 bool inReadOnlySeg
= ( strcmp(sect
->segmentName(), "__TEXT") == 0 );
2783 bool needsRebase
= false;
2784 bool needsBinding
= false;
2785 bool needsLazyBinding
= false;
2786 bool needsWeakBinding
= false;
2788 uint8_t rebaseType
= REBASE_TYPE_POINTER
;
2789 uint8_t type
= BIND_TYPE_POINTER
;
2790 const ld::dylib::File
* dylib
= dynamic_cast<const ld::dylib::File
*>(target
->file());
2791 bool weak_import
= ((dylib
!= NULL
) && (fixupWithTarget
->weakImport
|| dylib
->forcedWeakLinked()));
2792 uint64_t address
= atom
->finalAddress() + fixupWithTarget
->offsetInAtom
;
2793 uint64_t addend
= targetAddend
- minusTargetAddend
;
2795 // special case lazy pointers
2796 if ( fixupWithTarget
->kind
== ld::Fixup::kindLazyTarget
) {
2797 assert(fixupWithTarget
->u
.target
== target
);
2798 assert(addend
== 0);
2799 // lazy dylib lazy pointers do not have any dyld info
2800 if ( atom
->section().type() == ld::Section::typeLazyDylibPointer
)
2802 // lazy binding to weak definitions are done differently
2803 // they are directly bound to target, then have a weak bind in case of a collision
2804 if ( target
->combine() == ld::Atom::combineByName
) {
2805 if ( target
->definition() == ld::Atom::definitionProxy
) {
2806 // weak def exported from another dylib
2807 // must non-lazy bind to it plus have weak binding info in case of collision
2808 needsBinding
= true;
2809 needsWeakBinding
= true;
2812 // weak def in this linkage unit.
2813 // just rebase, plus have weak binding info in case of collision
2814 // this will be done by other cluster on lazy pointer atom
2817 else if ( (target
->contentType() == ld::Atom::typeResolver
) && (target
->scope() != ld::Atom::scopeGlobal
) ) {
2818 // <rdar://problem/8553647> Hidden resolver functions should not have lazy binding info
2819 needsLazyBinding
= false;
2822 // normal case of a pointer to non-weak-def symbol, so can lazily bind
2823 needsLazyBinding
= true;
2827 // everything except lazy pointers
2828 switch ( target
->definition() ) {
2829 case ld::Atom::definitionProxy
:
2830 if ( (dylib
!= NULL
) && dylib
->willBeLazyLoadedDylib() )
2831 throwf("illegal data reference to %s in lazy loaded dylib %s", target
->name(), dylib
->path());
2832 if ( target
->contentType() == ld::Atom::typeTLV
) {
2833 if ( sect
->type() != ld::Section::typeTLVPointers
)
2834 throwf("illegal data reference in %s to thread local variable %s in dylib %s",
2835 atom
->name(), target
->name(), dylib
->path());
2837 if ( inReadOnlySeg
)
2838 type
= BIND_TYPE_TEXT_ABSOLUTE32
;
2839 needsBinding
= true;
2840 if ( target
->combine() == ld::Atom::combineByName
)
2841 needsWeakBinding
= true;
2843 case ld::Atom::definitionRegular
:
2844 case ld::Atom::definitionTentative
:
2845 // only slideable images need rebasing info
2846 if ( _options
.outputSlidable() ) {
2849 // references to internal symbol never need binding
2850 if ( target
->scope() != ld::Atom::scopeGlobal
)
2852 // reference to global weak def needs weak binding
2853 if ( (target
->combine() == ld::Atom::combineByName
) && (target
->definition() == ld::Atom::definitionRegular
) )
2854 needsWeakBinding
= true;
2855 else if ( _options
.outputKind() == Options::kDynamicExecutable
) {
2856 // in main executables, the only way regular symbols are indirected is if -interposable is used
2857 if ( _options
.interposable(target
->name()) ) {
2858 needsRebase
= false;
2859 needsBinding
= true;
2863 // for flat-namespace or interposable two-level-namespace
2864 // all references to exported symbols get indirected
2865 if ( (_options
.nameSpace() != Options::kTwoLevelNameSpace
) || _options
.interposable(target
->name()) ) {
2866 // <rdar://problem/5254468> no external relocs for flat objc classes
2867 if ( strncmp(target
->name(), ".objc_class_", 12) == 0 )
2869 // no rebase info for references to global symbols that will have binding info
2870 needsRebase
= false;
2871 needsBinding
= true;
2875 case ld::Atom::definitionAbsolute
:
2880 // record dyld info for this cluster
2881 if ( needsRebase
) {
2882 if ( inReadOnlySeg
) {
2883 noteTextReloc(atom
, target
);
2884 sect
->hasLocalRelocs
= true; // so dyld knows to change permissions on __TEXT segment
2885 rebaseType
= REBASE_TYPE_TEXT_ABSOLUTE32
;
2887 _rebaseInfo
.push_back(RebaseInfo(rebaseType
, address
));
2889 if ( needsBinding
) {
2890 if ( inReadOnlySeg
) {
2891 noteTextReloc(atom
, target
);
2892 sect
->hasExternalRelocs
= true; // so dyld knows to change permissions on __TEXT segment
2894 _bindingInfo
.push_back(BindingInfo(type
, this->compressedOrdinalForAtom(target
), target
->name(), weak_import
, address
, addend
));
2896 if ( needsLazyBinding
) {
2897 if ( _options
.bindAtLoad() )
2898 _bindingInfo
.push_back(BindingInfo(type
, this->compressedOrdinalForAtom(target
), target
->name(), weak_import
, address
, addend
));
2900 _lazyBindingInfo
.push_back(BindingInfo(type
, this->compressedOrdinalForAtom(target
), target
->name(), weak_import
, address
, addend
));
2902 if ( needsWeakBinding
)
2903 _weakBindingInfo
.push_back(BindingInfo(type
, 0, target
->name(), false, address
, addend
));
2907 void OutputFile::addClassicRelocs(ld::Internal
& state
, ld::Internal::FinalSection
* sect
, const ld::Atom
* atom
,
2908 ld::Fixup
* fixupWithTarget
, ld::Fixup
* fixupWithMinusTarget
, ld::Fixup
* fixupWithStore
,
2909 const ld::Atom
* target
, const ld::Atom
* minusTarget
,
2910 uint64_t targetAddend
, uint64_t minusTargetAddend
)
2912 if ( sect
->isSectionHidden() )
2915 // non-lazy-pointer section is encoded in indirect symbol table - not using relocations
2916 if ( (sect
->type() == ld::Section::typeNonLazyPointer
) && (_options
.outputKind() != Options::kKextBundle
) ) {
2917 assert(target
!= NULL
);
2918 assert(fixupWithTarget
!= NULL
);
2922 // no need to rebase or bind PCRel stores
2923 if ( this->isPcRelStore(fixupWithStore
->kind
) ) {
2924 // as long as target is in same linkage unit
2925 if ( (target
== NULL
) || (target
->definition() != ld::Atom::definitionProxy
) )
2929 // no need to rebase or bind PIC internal pointer diff
2930 if ( minusTarget
!= NULL
) {
2931 // with pointer diffs, both need to be in same linkage unit
2932 assert(minusTarget
->definition() != ld::Atom::definitionProxy
);
2933 assert(target
!= NULL
);
2934 assert(target
->definition() != ld::Atom::definitionProxy
);
2935 // make sure target is not global and weak
2936 if ( (target
->scope() == ld::Atom::scopeGlobal
) && (target
->combine() == ld::Atom::combineByName
)
2937 && (atom
->section().type() != ld::Section::typeCFI
)
2938 && (atom
->section().type() != ld::Section::typeDtraceDOF
)
2939 && (atom
->section().type() != ld::Section::typeUnwindInfo
)
2940 && (minusTarget
!= target
) ) {
2941 // ok for __eh_frame and __uwind_info to use pointer diffs to global weak symbols
2942 throwf("bad codegen, pointer diff in %s to global weak symbol %s", atom
->name(), target
->name());
2947 // cluster has no target, so needs no rebasing or binding
2948 if ( target
== NULL
)
2951 assert(_localRelocsAtom
!= NULL
);
2952 uint64_t relocAddress
= atom
->finalAddress() + fixupWithTarget
->offsetInAtom
- _localRelocsAtom
->relocBaseAddress(state
);
2954 bool inReadOnlySeg
= ( strcmp(sect
->segmentName(), "__TEXT") == 0 );
2955 bool needsLocalReloc
= false;
2956 bool needsExternReloc
= false;
2958 switch ( fixupWithStore
->kind
) {
2959 case ld::Fixup::kindLazyTarget
:
2960 // lazy pointers don't need relocs
2962 case ld::Fixup::kindStoreLittleEndian32
:
2963 case ld::Fixup::kindStoreLittleEndian64
:
2964 case ld::Fixup::kindStoreBigEndian32
:
2965 case ld::Fixup::kindStoreBigEndian64
:
2966 case ld::Fixup::kindStoreTargetAddressLittleEndian32
:
2967 case ld::Fixup::kindStoreTargetAddressLittleEndian64
:
2968 case ld::Fixup::kindStoreTargetAddressBigEndian32
:
2969 case ld::Fixup::kindStoreTargetAddressBigEndian64
:
2971 switch ( target
->definition() ) {
2972 case ld::Atom::definitionProxy
:
2973 needsExternReloc
= true;
2975 case ld::Atom::definitionRegular
:
2976 case ld::Atom::definitionTentative
:
2977 // only slideable images need local relocs
2978 if ( _options
.outputSlidable() )
2979 needsLocalReloc
= true;
2980 // references to internal symbol never need binding
2981 if ( target
->scope() != ld::Atom::scopeGlobal
)
2983 // reference to global weak def needs weak binding in dynamic images
2984 if ( (target
->combine() == ld::Atom::combineByName
)
2985 && (target
->definition() == ld::Atom::definitionRegular
)
2986 && (_options
.outputKind() != Options::kStaticExecutable
) ) {
2987 needsExternReloc
= true;
2989 else if ( _options
.outputKind() == Options::kDynamicExecutable
) {
2990 // in main executables, the only way regular symbols are indirected is if -interposable is used
2991 if ( _options
.interposable(target
->name()) )
2992 needsExternReloc
= true;
2995 // for flat-namespace or interposable two-level-namespace
2996 // all references to exported symbols get indirected
2997 if ( (_options
.nameSpace() != Options::kTwoLevelNameSpace
) || _options
.interposable(target
->name()) ) {
2998 // <rdar://problem/5254468> no external relocs for flat objc classes
2999 if ( strncmp(target
->name(), ".objc_class_", 12) == 0 )
3001 // no rebase info for references to global symbols that will have binding info
3002 needsExternReloc
= true;
3005 if ( needsExternReloc
)
3006 needsLocalReloc
= false;
3008 case ld::Atom::definitionAbsolute
:
3011 if ( needsExternReloc
) {
3012 if ( inReadOnlySeg
)
3013 noteTextReloc(atom
, target
);
3014 const ld::dylib::File
* dylib
= dynamic_cast<const ld::dylib::File
*>(target
->file());
3015 if ( (dylib
!= NULL
) && dylib
->willBeLazyLoadedDylib() )
3016 throwf("illegal data reference to %s in lazy loaded dylib %s", target
->name(), dylib
->path());
3017 _externalRelocsAtom
->addExternalPointerReloc(relocAddress
, target
);
3018 sect
->hasExternalRelocs
= true;
3019 fixupWithTarget
->contentAddendOnly
= true;
3021 else if ( needsLocalReloc
) {
3022 assert(target
!= NULL
);
3023 if ( inReadOnlySeg
)
3024 noteTextReloc(atom
, target
);
3025 _localRelocsAtom
->addPointerReloc(relocAddress
, target
->machoSection());
3026 sect
->hasLocalRelocs
= true;
3029 case ld::Fixup::kindStorePPCAbsLow14
:
3030 case ld::Fixup::kindStorePPCAbsLow16
:
3031 case ld::Fixup::kindStorePPCAbsHigh16AddLow
:
3032 case ld::Fixup::kindStorePPCAbsHigh16
:
3034 assert(target
!= NULL
);
3035 if ( target
->definition() == ld::Atom::definitionProxy
)
3036 throwf("half word text relocs not supported in %s", atom
->name());
3037 if ( _options
.outputSlidable() ) {
3038 if ( inReadOnlySeg
)
3039 noteTextReloc(atom
, target
);
3040 uint32_t machoSectionIndex
= (target
->definition() == ld::Atom::definitionAbsolute
)
3041 ? R_ABS
: target
->machoSection();
3042 _localRelocsAtom
->addTextReloc(relocAddress
, fixupWithTarget
->kind
,
3043 target
->finalAddress(), machoSectionIndex
);
3044 sect
->hasLocalRelocs
= true;
3048 case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32
:
3049 if ( _options
.outputKind() == Options::kKextBundle
) {
3050 assert(target
!= NULL
);
3051 if ( target
->definition() == ld::Atom::definitionProxy
) {
3052 _externalRelocsAtom
->addExternalCallSiteReloc(relocAddress
, target
);
3053 fixupWithStore
->contentAddendOnly
= true;
3058 case ld::Fixup::kindStoreARMLow16
:
3059 case ld::Fixup::kindStoreThumbLow16
:
3060 // no way to encode rebasing of binding for these instructions
3061 if ( _options
.outputSlidable() || (target
->definition() == ld::Atom::definitionProxy
) )
3062 throwf("no supported runtime lo16 relocation in %s from %s to %s", atom
->name(), atom
->file()->path(), target
->name());
3065 case ld::Fixup::kindStoreARMHigh16
:
3066 case ld::Fixup::kindStoreThumbHigh16
:
3067 // no way to encode rebasing of binding for these instructions
3068 if ( _options
.outputSlidable() || (target
->definition() == ld::Atom::definitionProxy
) )
3069 throwf("no supported runtime hi16 relocation in %s from %s to %s", atom
->name(), atom
->file()->path(), target
->name());
3078 bool OutputFile::useExternalSectionReloc(const ld::Atom
* atom
, const ld::Atom
* target
, ld::Fixup
* fixupWithTarget
)
3080 if ( _options
.architecture() == CPU_TYPE_X86_64
) {
3081 // x86_64 uses external relocations for everthing that has a symbol
3082 return ( target
->symbolTableInclusion() != ld::Atom::symbolTableNotIn
);
3085 // <rdar://problem/9513487> support arm branch interworking in -r mode
3086 if ( (_options
.architecture() == CPU_TYPE_ARM
) && (_options
.outputKind() == Options::kObjectFile
) ) {
3087 if ( atom
->isThumb() != target
->isThumb() ) {
3088 switch ( fixupWithTarget
->kind
) {
3089 // have branch that switches mode, then might be 'b' not 'bl'
3090 // Force external relocation, since no way to do local reloc for 'b'
3091 case ld::Fixup::kindStoreTargetAddressThumbBranch22
:
3092 case ld::Fixup::kindStoreTargetAddressARMBranch24
:
3100 // most architectures use external relocations only for references
3101 // to a symbol in another translation unit or for references to "weak symbols" or tentative definitions
3102 assert(target
!= NULL
);
3103 if ( target
->definition() == ld::Atom::definitionProxy
)
3105 if ( (target
->definition() == ld::Atom::definitionTentative
) && ! _options
.makeTentativeDefinitionsReal() )
3107 if ( target
->scope() != ld::Atom::scopeGlobal
)
3109 if ( (target
->combine() == ld::Atom::combineByName
) && (target
->definition() == ld::Atom::definitionRegular
) )
3117 void OutputFile::addSectionRelocs(ld::Internal
& state
, ld::Internal::FinalSection
* sect
, const ld::Atom
* atom
,
3118 ld::Fixup
* fixupWithTarget
, ld::Fixup
* fixupWithMinusTarget
, ld::Fixup
* fixupWithStore
,
3119 const ld::Atom
* target
, const ld::Atom
* minusTarget
,
3120 uint64_t targetAddend
, uint64_t minusTargetAddend
)
3122 if ( sect
->isSectionHidden() )
3125 // in -r mode where there will be no labels on __eh_frame section, there is no need for relocations
3126 if ( (sect
->type() == ld::Section::typeCFI
) && _options
.removeEHLabels() )
3129 // non-lazy-pointer section is encoded in indirect symbol table - not using relocations
3130 if ( sect
->type() == ld::Section::typeNonLazyPointer
)
3133 // tentative defs don't have any relocations
3134 if ( sect
->type() == ld::Section::typeTentativeDefs
)
3137 assert(target
!= NULL
);
3138 assert(fixupWithTarget
!= NULL
);
3139 bool targetUsesExternalReloc
= this->useExternalSectionReloc(atom
, target
, fixupWithTarget
);
3140 bool minusTargetUsesExternalReloc
= (minusTarget
!= NULL
) && this->useExternalSectionReloc(atom
, minusTarget
, fixupWithMinusTarget
);
3142 // in x86_64 .o files an external reloc means the content contains just the addend
3143 if ( _options
.architecture() == CPU_TYPE_X86_64
) {
3144 if ( targetUsesExternalReloc
) {
3145 fixupWithTarget
->contentAddendOnly
= true;
3146 fixupWithStore
->contentAddendOnly
= true;
3148 if ( minusTargetUsesExternalReloc
)
3149 fixupWithMinusTarget
->contentAddendOnly
= true;
3152 // for other archs, content is addend only with (non pc-rel) pointers
3153 // pc-rel instructions are funny. If the target is _foo+8 and _foo is
3154 // external, then the pc-rel instruction *evalutates* to the address 8.
3155 if ( targetUsesExternalReloc
) {
3156 if ( isPcRelStore(fixupWithStore
->kind
) ) {
3157 fixupWithTarget
->contentDetlaToAddendOnly
= true;
3158 fixupWithStore
->contentDetlaToAddendOnly
= true;
3160 else if ( minusTarget
== NULL
){
3161 fixupWithTarget
->contentAddendOnly
= true;
3162 fixupWithStore
->contentAddendOnly
= true;
3167 if ( fixupWithStore
!= NULL
) {
3168 _sectionsRelocationsAtom
->addSectionReloc(sect
, fixupWithStore
->kind
, atom
, fixupWithStore
->offsetInAtom
,
3169 targetUsesExternalReloc
, minusTargetUsesExternalReloc
,
3170 target
, targetAddend
, minusTarget
, minusTargetAddend
);
3176 void OutputFile::makeSplitSegInfo(ld::Internal
& state
)
3178 if ( !_options
.sharedRegionEligible() )
3181 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
3182 ld::Internal::FinalSection
* sect
= *sit
;
3183 if ( sect
->isSectionHidden() )
3185 if ( strcmp(sect
->segmentName(), "__TEXT") != 0 )
3187 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
3188 const ld::Atom
* atom
= *ait
;
3189 const ld::Atom
* target
= NULL
;
3190 const ld::Atom
* fromTarget
= NULL
;
3191 uint64_t accumulator
= 0;
3193 bool hadSubtract
= false;
3194 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(), end
=atom
->fixupsEnd(); fit
!= end
; ++fit
) {
3195 if ( fit
->firstInCluster() )
3197 if ( this->setsTarget(fit
->kind
) ) {
3198 accumulator
= addressOf(state
, fit
, &target
);
3199 thumbTarget
= targetIsThumb(state
, fit
);
3203 switch ( fit
->kind
) {
3204 case ld::Fixup::kindSubtractTargetAddress
:
3205 accumulator
-= addressOf(state
, fit
, &fromTarget
);
3208 case ld::Fixup::kindAddAddend
:
3209 accumulator
+= fit
->u
.addend
;
3211 case ld::Fixup::kindSubtractAddend
:
3212 accumulator
-= fit
->u
.addend
;
3214 case ld::Fixup::kindStoreBigEndian32
:
3215 case ld::Fixup::kindStoreLittleEndian32
:
3216 case ld::Fixup::kindStoreLittleEndian64
:
3217 case ld::Fixup::kindStoreTargetAddressLittleEndian32
:
3218 case ld::Fixup::kindStoreTargetAddressLittleEndian64
:
3219 // if no subtract, then this is an absolute pointer which means
3220 // there is also a text reloc which update_dyld_shared_cache will use.
3221 if ( ! hadSubtract
)
3224 case ld::Fixup::kindStoreX86PCRel32
:
3225 case ld::Fixup::kindStoreX86PCRel32_1
:
3226 case ld::Fixup::kindStoreX86PCRel32_2
:
3227 case ld::Fixup::kindStoreX86PCRel32_4
:
3228 case ld::Fixup::kindStoreX86PCRel32GOTLoad
:
3229 case ld::Fixup::kindStoreX86PCRel32GOTLoadNowLEA
:
3230 case ld::Fixup::kindStoreX86PCRel32GOT
:
3231 case ld::Fixup::kindStorePPCPicHigh16AddLow
:
3232 case ld::Fixup::kindStoreTargetAddressX86PCRel32
:
3233 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad
:
3234 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA
:
3235 case ld::Fixup::kindStoreARMLow16
:
3236 case ld::Fixup::kindStoreThumbLow16
:
3237 assert(target
!= NULL
);
3238 if ( strcmp(sect
->segmentName(), target
->section().segmentName()) != 0 ) {
3239 _splitSegInfos
.push_back(SplitSegInfoEntry(atom
->finalAddress()+fit
->offsetInAtom
,fit
->kind
));
3242 case ld::Fixup::kindStoreARMHigh16
:
3243 case ld::Fixup::kindStoreThumbHigh16
:
3244 assert(target
!= NULL
);
3245 if ( strcmp(sect
->segmentName(), target
->section().segmentName()) != 0 ) {
3246 // hi16 needs to know upper 4-bits of low16 to compute carry
3247 uint32_t extra
= (accumulator
>> 12) & 0xF;
3248 _splitSegInfos
.push_back(SplitSegInfoEntry(atom
->finalAddress()+fit
->offsetInAtom
,fit
->kind
, extra
));
3251 case ld::Fixup::kindSetTargetImageOffset
:
3252 accumulator
= addressOf(state
, fit
, &target
);
3253 assert(target
!= NULL
);
3265 void OutputFile::writeMapFile(ld::Internal
& state
)
3267 if ( _options
.generatedMapPath() != NULL
) {
3268 FILE* mapFile
= fopen(_options
.generatedMapPath(), "w");
3269 if ( mapFile
!= NULL
) {
3270 // write output path
3271 fprintf(mapFile
, "# Path: %s\n", _options
.outputFilePath());
3272 // write output architecure
3273 fprintf(mapFile
, "# Arch: %s\n", _options
.architectureName());
3275 //if ( fUUIDAtom != NULL ) {
3276 // const uint8_t* uuid = fUUIDAtom->getUUID();
3277 // fprintf(mapFile, "# UUID: %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X \n",
3278 // uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
3279 // uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
3281 // write table of object files
3282 std::map
<const ld::File
*, uint32_t> readerToOrdinal
;
3283 std::map
<uint32_t, const ld::File
*> ordinalToReader
;
3284 std::map
<const ld::File
*, uint32_t> readerToFileOrdinal
;
3285 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
3286 ld::Internal::FinalSection
* sect
= *sit
;
3287 if ( sect
->isSectionHidden() )
3289 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
3290 const ld::Atom
* atom
= *ait
;
3291 const ld::File
* reader
= atom
->file();
3292 if ( reader
== NULL
)
3294 uint32_t readerOrdinal
= reader
->ordinal();
3295 std::map
<const ld::File
*, uint32_t>::iterator pos
= readerToOrdinal
.find(reader
);
3296 if ( pos
== readerToOrdinal
.end() ) {
3297 readerToOrdinal
[reader
] = readerOrdinal
;
3298 ordinalToReader
[readerOrdinal
] = reader
;
3302 fprintf(mapFile
, "# Object files:\n");
3303 fprintf(mapFile
, "[%3u] %s\n", 0, "linker synthesized");
3304 uint32_t fileIndex
= 0;
3305 readerToFileOrdinal
[NULL
] = fileIndex
++;
3306 for(std::map
<uint32_t, const ld::File
*>::iterator it
= ordinalToReader
.begin(); it
!= ordinalToReader
.end(); ++it
) {
3307 if ( it
->first
!= 0 ) {
3308 fprintf(mapFile
, "[%3u] %s\n", fileIndex
, it
->second
->path());
3309 readerToFileOrdinal
[it
->second
] = fileIndex
++;
3312 // write table of sections
3313 fprintf(mapFile
, "# Sections:\n");
3314 fprintf(mapFile
, "# Address\tSize \tSegment\tSection\n");
3315 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
3316 ld::Internal::FinalSection
* sect
= *sit
;
3317 if ( sect
->isSectionHidden() )
3319 fprintf(mapFile
, "0x%08llX\t0x%08llX\t%s\t%s\n", sect
->address
, sect
->size
,
3320 sect
->segmentName(), sect
->sectionName());
3322 // write table of symbols
3323 fprintf(mapFile
, "# Symbols:\n");
3324 fprintf(mapFile
, "# Address\tSize \tFile Name\n");
3325 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
3326 ld::Internal::FinalSection
* sect
= *sit
;
3327 if ( sect
->isSectionHidden() )
3329 //bool isCstring = (sect->type() == ld::Section::typeCString);
3330 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
3332 const ld::Atom
* atom
= *ait
;
3333 const char* name
= atom
->name();
3334 if ( atom
->contentType() == ld::Atom::typeCString
) {
3335 strcpy(buffer
, "literal string: ");
3336 strlcat(buffer
, (char*)atom
->rawContentPointer(), 4096);
3339 else if ( (atom
->contentType() == ld::Atom::typeCFI
) && (strcmp(name
, "FDE") == 0) ) {
3340 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(); fit
!= atom
->fixupsEnd(); ++fit
) {
3341 if ( (fit
->kind
== ld::Fixup::kindSetTargetAddress
) && (fit
->clusterSize
== ld::Fixup::k1of4
) ) {
3342 assert(fit
->binding
== ld::Fixup::bindingDirectlyBound
);
3343 if ( fit
->u
.target
->section().type() == ld::Section::typeCode
) {
3344 strcpy(buffer
, "FDE for: ");
3345 strlcat(buffer
, fit
->u
.target
->name(), 4096);
3351 else if ( atom
->contentType() == ld::Atom::typeNonLazyPointer
) {
3352 strcpy(buffer
, "non-lazy-pointer");
3353 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(); fit
!= atom
->fixupsEnd(); ++fit
) {
3354 if ( fit
->binding
== ld::Fixup::bindingsIndirectlyBound
) {
3355 strcpy(buffer
, "non-lazy-pointer-to: ");
3356 strlcat(buffer
, state
.indirectBindingTable
[fit
->u
.bindingIndex
]->name(), 4096);
3359 else if ( fit
->binding
== ld::Fixup::bindingDirectlyBound
) {
3360 strcpy(buffer
, "non-lazy-pointer-to-local: ");
3361 strlcat(buffer
, fit
->u
.target
->name(), 4096);
3367 fprintf(mapFile
, "0x%08llX\t0x%08llX\t[%3u] %s\n", atom
->finalAddress(), atom
->size(),
3368 readerToFileOrdinal
[atom
->file()], name
);
3374 warning("could not write map file: %s\n", _options
.generatedMapPath());
3380 // used to sort atoms with debug notes
3381 class DebugNoteSorter
3384 bool operator()(const ld::Atom
* left
, const ld::Atom
* right
) const
3386 // first sort by reader
3387 uint32_t leftFileOrdinal
= left
->file()->ordinal();
3388 uint32_t rightFileOrdinal
= right
->file()->ordinal();
3389 if ( leftFileOrdinal
!= rightFileOrdinal
)
3390 return (leftFileOrdinal
< rightFileOrdinal
);
3392 // then sort by atom objectAddress
3393 uint64_t leftAddr
= left
->finalAddress();
3394 uint64_t rightAddr
= right
->finalAddress();
3395 return leftAddr
< rightAddr
;
3403 bool operator()(const char* left
, const char* right
) const { return (strcmp(left
, right
) == 0); }
3406 const char* OutputFile::assureFullPath(const char* path
)
3408 if ( path
[0] == '/' )
3410 char cwdbuff
[MAXPATHLEN
];
3411 if ( getcwd(cwdbuff
, MAXPATHLEN
) != NULL
) {
3413 asprintf(&result
, "%s/%s", cwdbuff
, path
);
3414 if ( result
!= NULL
)
3420 void OutputFile::synthesizeDebugNotes(ld::Internal
& state
)
3422 // -S means don't synthesize debug map
3423 if ( _options
.debugInfoStripping() == Options::kDebugInfoNone
)
3425 // make a vector of atoms that come from files compiled with dwarf debug info
3426 std::vector
<const ld::Atom
*> atomsNeedingDebugNotes
;
3427 std::set
<const ld::Atom
*> atomsWithStabs
;
3428 atomsNeedingDebugNotes
.reserve(1024);
3429 const ld::relocatable::File
* objFile
= NULL
;
3430 bool objFileHasDwarf
= false;
3431 bool objFileHasStabs
= false;
3432 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
3433 ld::Internal::FinalSection
* sect
= *sit
;
3434 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
3435 const ld::Atom
* atom
= *ait
;
3436 // no stabs for atoms that would not be in the symbol table
3437 if ( atom
->symbolTableInclusion() == ld::Atom::symbolTableNotIn
)
3439 if ( atom
->symbolTableInclusion() == ld::Atom::symbolTableNotInFinalLinkedImages
)
3441 // no stabs for absolute symbols
3442 if ( atom
->definition() == ld::Atom::definitionAbsolute
)
3444 // no stabs for .eh atoms
3445 if ( atom
->contentType() == ld::Atom::typeCFI
)
3447 const ld::File
* file
= atom
->file();
3448 if ( file
!= NULL
) {
3449 if ( file
!= objFile
) {
3450 objFileHasDwarf
= false;
3451 objFileHasStabs
= false;
3452 objFile
= dynamic_cast<const ld::relocatable::File
*>(file
);
3453 if ( objFile
!= NULL
) {
3454 switch ( objFile
->debugInfo() ) {
3455 case ld::relocatable::File::kDebugInfoNone
:
3457 case ld::relocatable::File::kDebugInfoDwarf
:
3458 objFileHasDwarf
= true;
3460 case ld::relocatable::File::kDebugInfoStabs
:
3461 case ld::relocatable::File::kDebugInfoStabsUUID
:
3462 objFileHasStabs
= true;
3467 if ( objFileHasDwarf
)
3468 atomsNeedingDebugNotes
.push_back(atom
);
3469 if ( objFileHasStabs
)
3470 atomsWithStabs
.insert(atom
);
3475 // sort by file ordinal then atom ordinal
3476 std::sort(atomsNeedingDebugNotes
.begin(), atomsNeedingDebugNotes
.end(), DebugNoteSorter());
3478 // synthesize "debug notes" and add them to master stabs vector
3479 const char* dirPath
= NULL
;
3480 const char* filename
= NULL
;
3481 bool wroteStartSO
= false;
3482 state
.stabs
.reserve(atomsNeedingDebugNotes
.size()*4);
3483 __gnu_cxx::hash_set
<const char*, __gnu_cxx::hash
<const char*>, CStringEquals
> seenFiles
;
3484 for (std::vector
<const ld::Atom
*>::iterator it
=atomsNeedingDebugNotes
.begin(); it
!= atomsNeedingDebugNotes
.end(); it
++) {
3485 const ld::Atom
* atom
= *it
;
3486 const ld::File
* atomFile
= atom
->file();
3487 const ld::relocatable::File
* atomObjFile
= dynamic_cast<const ld::relocatable::File
*>(atomFile
);
3488 const char* newDirPath
;
3489 const char* newFilename
;
3490 //fprintf(stderr, "debug note for %s\n", atom->name());
3491 if ( atom
->translationUnitSource(&newDirPath
, &newFilename
) ) {
3492 // need SO's whenever the translation unit source file changes
3493 if ( newFilename
!= filename
) {
3494 // gdb like directory SO's to end in '/', but dwarf DW_AT_comp_dir usually does not have trailing '/'
3495 if ( (newDirPath
!= NULL
) && (strlen(newDirPath
) > 1 ) && (newDirPath
[strlen(newDirPath
)-1] != '/') )
3496 asprintf((char**)&newDirPath
, "%s/", newDirPath
);
3497 if ( filename
!= NULL
) {
3498 // translation unit change, emit ending SO
3499 ld::relocatable::File::Stab endFileStab
;
3500 endFileStab
.atom
= NULL
;
3501 endFileStab
.type
= N_SO
;
3502 endFileStab
.other
= 1;
3503 endFileStab
.desc
= 0;
3504 endFileStab
.value
= 0;
3505 endFileStab
.string
= "";
3506 state
.stabs
.push_back(endFileStab
);
3508 // new translation unit, emit start SO's
3509 ld::relocatable::File::Stab dirPathStab
;
3510 dirPathStab
.atom
= NULL
;
3511 dirPathStab
.type
= N_SO
;
3512 dirPathStab
.other
= 0;
3513 dirPathStab
.desc
= 0;
3514 dirPathStab
.value
= 0;
3515 dirPathStab
.string
= newDirPath
;
3516 state
.stabs
.push_back(dirPathStab
);
3517 ld::relocatable::File::Stab fileStab
;
3518 fileStab
.atom
= NULL
;
3519 fileStab
.type
= N_SO
;
3523 fileStab
.string
= newFilename
;
3524 state
.stabs
.push_back(fileStab
);
3525 // Synthesize OSO for start of file
3526 ld::relocatable::File::Stab objStab
;
3527 objStab
.atom
= NULL
;
3528 objStab
.type
= N_OSO
;
3529 // <rdar://problem/6337329> linker should put cpusubtype in n_sect field of nlist entry for N_OSO debug note entries
3530 objStab
.other
= atomFile
->cpuSubType();
3532 if ( atomObjFile
!= NULL
) {
3533 objStab
.string
= assureFullPath(atomObjFile
->debugInfoPath());
3534 objStab
.value
= atomObjFile
->debugInfoModificationTime();
3537 objStab
.string
= assureFullPath(atomFile
->path());
3538 objStab
.value
= atomFile
->modificationTime();
3540 state
.stabs
.push_back(objStab
);
3541 wroteStartSO
= true;
3542 // add the source file path to seenFiles so it does not show up in SOLs
3543 seenFiles
.insert(newFilename
);
3545 asprintf(&fullFilePath
, "%s%s", newDirPath
, newFilename
);
3546 // add both leaf path and full path
3547 seenFiles
.insert(fullFilePath
);
3549 filename
= newFilename
;
3550 dirPath
= newDirPath
;
3551 if ( atom
->section().type() == ld::Section::typeCode
) {
3552 // Synthesize BNSYM and start FUN stabs
3553 ld::relocatable::File::Stab beginSym
;
3554 beginSym
.atom
= atom
;
3555 beginSym
.type
= N_BNSYM
;
3559 beginSym
.string
= "";
3560 state
.stabs
.push_back(beginSym
);
3561 ld::relocatable::File::Stab startFun
;
3562 startFun
.atom
= atom
;
3563 startFun
.type
= N_FUN
;
3567 startFun
.string
= atom
->name();
3568 state
.stabs
.push_back(startFun
);
3569 // Synthesize any SOL stabs needed
3570 const char* curFile
= NULL
;
3571 for (ld::Atom::LineInfo::iterator lit
= atom
->beginLineInfo(); lit
!= atom
->endLineInfo(); ++lit
) {
3572 if ( lit
->fileName
!= curFile
) {
3573 if ( seenFiles
.count(lit
->fileName
) == 0 ) {
3574 seenFiles
.insert(lit
->fileName
);
3575 ld::relocatable::File::Stab sol
;
3581 sol
.string
= lit
->fileName
;
3582 state
.stabs
.push_back(sol
);
3584 curFile
= lit
->fileName
;
3587 // Synthesize end FUN and ENSYM stabs
3588 ld::relocatable::File::Stab endFun
;
3590 endFun
.type
= N_FUN
;
3595 state
.stabs
.push_back(endFun
);
3596 ld::relocatable::File::Stab endSym
;
3598 endSym
.type
= N_ENSYM
;
3603 state
.stabs
.push_back(endSym
);
3606 ld::relocatable::File::Stab globalsStab
;
3607 const char* name
= atom
->name();
3608 if ( atom
->scope() == ld::Atom::scopeTranslationUnit
) {
3609 // Synthesize STSYM stab for statics
3610 globalsStab
.atom
= atom
;
3611 globalsStab
.type
= N_STSYM
;
3612 globalsStab
.other
= 1;
3613 globalsStab
.desc
= 0;
3614 globalsStab
.value
= 0;
3615 globalsStab
.string
= name
;
3616 state
.stabs
.push_back(globalsStab
);
3619 // Synthesize GSYM stab for other globals
3620 globalsStab
.atom
= atom
;
3621 globalsStab
.type
= N_GSYM
;
3622 globalsStab
.other
= 1;
3623 globalsStab
.desc
= 0;
3624 globalsStab
.value
= 0;
3625 globalsStab
.string
= name
;
3626 state
.stabs
.push_back(globalsStab
);
3632 if ( wroteStartSO
) {
3634 ld::relocatable::File::Stab endFileStab
;
3635 endFileStab
.atom
= NULL
;
3636 endFileStab
.type
= N_SO
;
3637 endFileStab
.other
= 1;
3638 endFileStab
.desc
= 0;
3639 endFileStab
.value
= 0;
3640 endFileStab
.string
= "";
3641 state
.stabs
.push_back(endFileStab
);
3644 // copy any stabs from .o file
3645 std::set
<const ld::File
*> filesSeenWithStabs
;
3646 for (std::set
<const ld::Atom
*>::iterator it
=atomsWithStabs
.begin(); it
!= atomsWithStabs
.end(); it
++) {
3647 const ld::Atom
* atom
= *it
;
3648 objFile
= dynamic_cast<const ld::relocatable::File
*>(atom
->file());
3649 if ( objFile
!= NULL
) {
3650 if ( filesSeenWithStabs
.count(objFile
) == 0 ) {
3651 filesSeenWithStabs
.insert(objFile
);
3652 const std::vector
<ld::relocatable::File::Stab
>* stabs
= objFile
->stabs();
3653 if ( stabs
!= NULL
) {
3654 for(std::vector
<ld::relocatable::File::Stab
>::const_iterator sit
= stabs
->begin(); sit
!= stabs
->end(); ++sit
) {
3655 ld::relocatable::File::Stab stab
= *sit
;
3656 // ignore stabs associated with atoms that were dead stripped or coalesced away
3657 if ( (sit
->atom
!= NULL
) && (atomsWithStabs
.count(sit
->atom
) == 0) )
3659 // <rdar://problem/8284718> Value of N_SO stabs should be address of first atom from translation unit
3660 if ( (stab
.type
== N_SO
) && (stab
.string
!= NULL
) && (stab
.string
[0] != '\0') ) {
3663 state
.stabs
.push_back(stab
);