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 ld::Internal::FinalSection
* overlappingFixedSection
= NULL
;
520 ld::Internal::FinalSection
* overlappingFlowSection
= NULL
;
521 if ( log
) fprintf(stderr
, "Regular layout segments:\n");
522 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
523 ld::Internal::FinalSection
* sect
= *it
;
524 if ( _options
.hasCustomSegmentAddress(sect
->segmentName()) )
526 if ( (_options
.outputKind() == Options::kPreload
) && (sect
->type() == ld::Section::typeMachHeader
) ) {
527 sect
->alignmentPaddingBytes
= 0;
530 if ( segmentsArePageAligned
) {
531 if ( strcmp(lastSegName
, sect
->segmentName()) != 0 ) {
532 // round up size of last segment if needed
533 if ( *lastSegName
!= '\0' ) {
534 address
= pageAlign(address
, _options
.segPageSize(lastSegName
));
536 // set segment address based on end of last segment
537 address
= pageAlign(address
);
538 lastSegName
= sect
->segmentName();
541 // adjust section address based on alignment
542 uint64_t unalignedAddress
= address
;
543 uint64_t alignment
= (1 << sect
->alignment
);
544 address
= ( (unalignedAddress
+alignment
-1) & (-alignment
) );
546 // update section info
547 sect
->address
= address
;
548 sect
->alignmentPaddingBytes
= (address
- unalignedAddress
);
551 if ( ((address
+ sect
->size
) > _options
.maxAddress()) && (_options
.outputKind() != Options::kObjectFile
)
552 && (_options
.outputKind() != Options::kStaticExecutable
) )
553 throwf("section %s (address=0x%08llX, size=%llu) would make the output executable exceed available address range",
554 sect
->sectionName(), address
, sect
->size
);
556 // sanity check it does not overlap a fixed address segment
557 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
558 ld::Internal::FinalSection
* otherSect
= *sit
;
559 if ( ! _options
.hasCustomSegmentAddress(otherSect
->segmentName()) )
561 if ( sect
->address
> otherSect
->address
) {
562 if ( (otherSect
->address
+otherSect
->size
) > sect
->address
) {
563 overlappingFixedSection
= otherSect
;
564 overlappingFlowSection
= sect
;
568 if ( (sect
->address
+sect
->size
) > otherSect
->address
) {
569 overlappingFixedSection
= otherSect
;
570 overlappingFlowSection
= sect
;
575 if ( log
) fprintf(stderr
, " address=0x%08llX, hidden=%d, alignment=%02d, padBytes=%d, section=%s,%s\n",
576 sect
->address
, sect
->isSectionHidden(), sect
->alignment
, sect
->alignmentPaddingBytes
,
577 sect
->segmentName(), sect
->sectionName());
578 // update running totals
579 if ( !sect
->isSectionHidden() || hiddenSectionsOccupyAddressSpace
)
580 address
+= sect
->size
;
582 if ( overlappingFixedSection
!= NULL
) {
583 fprintf(stderr
, "Section layout:\n");
584 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
585 ld::Internal::FinalSection
* sect
= *it
;
586 if ( sect
->isSectionHidden() )
588 fprintf(stderr
, " address:0x%08llX, alignment:2^%d, size:0x%08llX, padBytes:%d, section:%s/%s\n",
589 sect
->address
, sect
->alignment
, sect
->size
, sect
->alignmentPaddingBytes
,
590 sect
->segmentName(), sect
->sectionName());
593 throwf("Section (%s/%s) overlaps fixed address section (%s/%s)",
594 overlappingFlowSection
->segmentName(), overlappingFlowSection
->sectionName(),
595 overlappingFixedSection
->segmentName(), overlappingFixedSection
->sectionName());
599 // third pass, assign section file offsets
600 uint64_t fileOffset
= 0;
602 if ( log
) fprintf(stderr
, "All segments with file offsets:\n");
603 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
604 ld::Internal::FinalSection
* sect
= *it
;
605 if ( hasZeroForFileOffset(sect
) ) {
606 // fileoff of zerofill sections is moot, but historically it is set to zero
607 sect
->fileOffset
= 0;
610 // page align file offset at start of each segment
611 if ( segmentsArePageAligned
&& (*lastSegName
!= '\0') && (strcmp(lastSegName
, sect
->segmentName()) != 0) ) {
612 fileOffset
= pageAlign(fileOffset
, _options
.segPageSize(lastSegName
));
614 lastSegName
= sect
->segmentName();
616 // align file offset with address layout
617 fileOffset
+= sect
->alignmentPaddingBytes
;
619 // update section info
620 sect
->fileOffset
= fileOffset
;
622 // update running total
623 fileOffset
+= sect
->size
;
626 if ( log
) fprintf(stderr
, " fileoffset=0x%08llX, address=0x%08llX, hidden=%d, size=%lld, alignment=%02d, section=%s,%s\n",
627 sect
->fileOffset
, sect
->address
, sect
->isSectionHidden(), sect
->size
, sect
->alignment
,
628 sect
->segmentName(), sect
->sectionName());
632 // for encrypted iPhoneOS apps
633 if ( _options
.makeEncryptable() ) {
634 // remember end of __TEXT for later use by load command
635 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
636 ld::Internal::FinalSection
* sect
= *it
;
637 if ( strcmp(sect
->segmentName(), "__TEXT") == 0 ) {
638 _encryptedTEXTendOffset
= pageAlign(sect
->fileOffset
+ sect
->size
);
643 // remember total file size
644 _fileSize
= fileOffset
;
648 static const char* makeName(const ld::Atom
& atom
)
650 static char buffer
[4096];
651 switch ( atom
.symbolTableInclusion() ) {
652 case ld::Atom::symbolTableNotIn
:
653 case ld::Atom::symbolTableNotInFinalLinkedImages
:
654 sprintf(buffer
, "%s@0x%08llX", atom
.name(), atom
.objectAddress());
656 case ld::Atom::symbolTableIn
:
657 case ld::Atom::symbolTableInAndNeverStrip
:
658 case ld::Atom::symbolTableInAsAbsolute
:
659 case ld::Atom::symbolTableInWithRandomAutoStripLabel
:
660 strlcpy(buffer
, atom
.name(), 4096);
666 static const char* referenceTargetAtomName(ld::Internal
& state
, const ld::Fixup
* ref
)
668 switch ( ref
->binding
) {
669 case ld::Fixup::bindingNone
:
671 case ld::Fixup::bindingByNameUnbound
:
672 return (char*)(ref
->u
.target
);
673 case ld::Fixup::bindingByContentBound
:
674 case ld::Fixup::bindingDirectlyBound
:
675 return makeName(*((ld::Atom
*)(ref
->u
.target
)));
676 case ld::Fixup::bindingsIndirectlyBound
:
677 return makeName(*state
.indirectBindingTable
[ref
->u
.bindingIndex
]);
679 return "BAD BINDING";
682 bool OutputFile::targetIsThumb(ld::Internal
& state
, const ld::Fixup
* fixup
)
684 switch ( fixup
->binding
) {
685 case ld::Fixup::bindingByContentBound
:
686 case ld::Fixup::bindingDirectlyBound
:
687 return fixup
->u
.target
->isThumb();
688 case ld::Fixup::bindingsIndirectlyBound
:
689 return state
.indirectBindingTable
[fixup
->u
.bindingIndex
]->isThumb();
693 throw "unexpected binding";
696 uint64_t OutputFile::addressOf(const ld::Internal
& state
, const ld::Fixup
* fixup
, const ld::Atom
** target
)
698 if ( !_options
.makeCompressedDyldInfo() ) {
699 // For external relocations the classic mach-o format
700 // has addend only stored in the content. That means
701 // that the address of the target is not used.
702 if ( fixup
->contentAddendOnly
)
705 switch ( fixup
->binding
) {
706 case ld::Fixup::bindingNone
:
707 throw "unexpected bindingNone";
708 case ld::Fixup::bindingByNameUnbound
:
709 throw "unexpected bindingByNameUnbound";
710 case ld::Fixup::bindingByContentBound
:
711 case ld::Fixup::bindingDirectlyBound
:
712 *target
= fixup
->u
.target
;
713 return (*target
)->finalAddress();
714 case ld::Fixup::bindingsIndirectlyBound
:
715 *target
= state
.indirectBindingTable
[fixup
->u
.bindingIndex
];
716 return (*target
)->finalAddress();
718 throw "unexpected binding";
721 uint64_t OutputFile::sectionOffsetOf(const ld::Internal
& state
, const ld::Fixup
* fixup
)
723 const ld::Atom
* target
= NULL
;
724 switch ( fixup
->binding
) {
725 case ld::Fixup::bindingNone
:
726 throw "unexpected bindingNone";
727 case ld::Fixup::bindingByNameUnbound
:
728 throw "unexpected bindingByNameUnbound";
729 case ld::Fixup::bindingByContentBound
:
730 case ld::Fixup::bindingDirectlyBound
:
731 target
= fixup
->u
.target
;
733 case ld::Fixup::bindingsIndirectlyBound
:
734 target
= state
.indirectBindingTable
[fixup
->u
.bindingIndex
];
737 assert(target
!= NULL
);
739 uint64_t targetAddress
= target
->finalAddress();
740 for (std::vector
<ld::Internal::FinalSection
*>::const_iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
741 const ld::Internal::FinalSection
* sect
= *it
;
742 if ( (sect
->address
<= targetAddress
) && (targetAddress
< (sect
->address
+sect
->size
)) )
743 return targetAddress
- sect
->address
;
745 throw "section not found for section offset";
750 uint64_t OutputFile::tlvTemplateOffsetOf(const ld::Internal
& state
, const ld::Fixup
* fixup
)
752 const ld::Atom
* target
= NULL
;
753 switch ( fixup
->binding
) {
754 case ld::Fixup::bindingNone
:
755 throw "unexpected bindingNone";
756 case ld::Fixup::bindingByNameUnbound
:
757 throw "unexpected bindingByNameUnbound";
758 case ld::Fixup::bindingByContentBound
:
759 case ld::Fixup::bindingDirectlyBound
:
760 target
= fixup
->u
.target
;
762 case ld::Fixup::bindingsIndirectlyBound
:
763 target
= state
.indirectBindingTable
[fixup
->u
.bindingIndex
];
766 assert(target
!= NULL
);
768 for (std::vector
<ld::Internal::FinalSection
*>::const_iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
769 const ld::Internal::FinalSection
* sect
= *it
;
770 switch ( sect
->type() ) {
771 case ld::Section::typeTLVInitialValues
:
772 case ld::Section::typeTLVZeroFill
:
773 return target
->finalAddress() - sect
->address
;
778 throw "section not found for tlvTemplateOffsetOf";
781 void OutputFile::printSectionLayout(ld::Internal
& state
)
783 // show layout of final image
784 fprintf(stderr
, "final section layout:\n");
785 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
786 if ( (*it
)->isSectionHidden() )
788 fprintf(stderr
, " %s/%s addr=0x%08llX, size=0x%08llX, fileOffset=0x%08llX, type=%d\n",
789 (*it
)->segmentName(), (*it
)->sectionName(),
790 (*it
)->address
, (*it
)->size
, (*it
)->fileOffset
, (*it
)->type());
795 void OutputFile::rangeCheck8(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
797 if ( (displacement
> 127) || (displacement
< -128) ) {
798 // show layout of final image
799 printSectionLayout(state
);
801 const ld::Atom
* target
;
802 throwf("8-bit reference out of range (%lld max is +/-127B): from %s (0x%08llX) to %s (0x%08llX)",
803 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
804 addressOf(state
, fixup
, &target
));
808 void OutputFile::rangeCheck16(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
810 const int64_t thirtyTwoKLimit
= 0x00007FFF;
811 if ( (displacement
> thirtyTwoKLimit
) || (displacement
< (-thirtyTwoKLimit
)) ) {
812 // show layout of final image
813 printSectionLayout(state
);
815 const ld::Atom
* target
;
816 throwf("16-bit reference out of range (%lld max is +/-32KB): from %s (0x%08llX) to %s (0x%08llX)",
817 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
818 addressOf(state
, fixup
, &target
));
822 void OutputFile::rangeCheckBranch32(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
824 const int64_t twoGigLimit
= 0x7FFFFFFF;
825 if ( (displacement
> twoGigLimit
) || (displacement
< (-twoGigLimit
)) ) {
826 // show layout of final image
827 printSectionLayout(state
);
829 const ld::Atom
* target
;
830 throwf("32-bit branch out of range (%lld max is +/-4GB): from %s (0x%08llX) to %s (0x%08llX)",
831 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
832 addressOf(state
, fixup
, &target
));
837 void OutputFile::rangeCheckAbsolute32(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
839 const int64_t fourGigLimit
= 0xFFFFFFFF;
840 if ( displacement
> fourGigLimit
) {
841 // <rdar://problem/9610466> cannot enforce 32-bit range checks on 32-bit archs because assembler loses sign information
842 // .long _foo - 0xC0000000
843 // is encoded in mach-o the same as:
844 // .long _foo + 0x40000000
845 // so if _foo lays out to 0xC0000100, the first is ok, but the second is not.
846 if ( (_options
.architecture() == CPU_TYPE_ARM
) || (_options
.architecture() == CPU_TYPE_I386
) ) {
847 // Unlikely userland code does funky stuff like this, so warn for them, but not warn for -preload
848 if ( _options
.outputKind() != Options::kPreload
) {
849 warning("32-bit absolute address out of range (0x%08llX max is 4GB): from %s + 0x%08X (0x%08llX) to 0x%08llX",
850 displacement
, atom
->name(), fixup
->offsetInAtom
, atom
->finalAddress(), displacement
);
854 // show layout of final image
855 printSectionLayout(state
);
857 const ld::Atom
* target
;
858 if ( fixup
->binding
== ld::Fixup::bindingNone
)
859 throwf("32-bit absolute address out of range (0x%08llX max is 4GB): from %s + 0x%08X (0x%08llX) to 0x%08llX",
860 displacement
, atom
->name(), fixup
->offsetInAtom
, atom
->finalAddress(), displacement
);
862 throwf("32-bit absolute address out of range (0x%08llX max is 4GB): from %s + 0x%08X (0x%08llX) to %s (0x%08llX)",
863 displacement
, atom
->name(), fixup
->offsetInAtom
, atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
864 addressOf(state
, fixup
, &target
));
869 void OutputFile::rangeCheckRIP32(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
871 const int64_t twoGigLimit
= 0x7FFFFFFF;
872 if ( (displacement
> twoGigLimit
) || (displacement
< (-twoGigLimit
)) ) {
873 // show layout of final image
874 printSectionLayout(state
);
876 const ld::Atom
* target
;
877 throwf("32-bit RIP relative reference out of range (%lld max is +/-4GB): from %s (0x%08llX) to %s (0x%08llX)",
878 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
879 addressOf(state
, fixup
, &target
));
883 void OutputFile::rangeCheckARM12(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
885 if ( (displacement
> 4092LL) || (displacement
< (-4092LL)) ) {
886 // show layout of final image
887 printSectionLayout(state
);
889 const ld::Atom
* target
;
890 throwf("ARM ldr 12-bit displacement out of range (%lld max is +/-4096B): from %s (0x%08llX) to %s (0x%08llX)",
891 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
892 addressOf(state
, fixup
, &target
));
897 void OutputFile::rangeCheckARMBranch24(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
899 if ( (displacement
> 33554428LL) || (displacement
< (-33554432LL)) ) {
900 // show layout of final image
901 printSectionLayout(state
);
903 const ld::Atom
* target
;
904 throwf("b/bl/blx ARM branch out of range (%lld max is +/-32MB): from %s (0x%08llX) to %s (0x%08llX)",
905 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
906 addressOf(state
, fixup
, &target
));
910 void OutputFile::rangeCheckThumbBranch22(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
912 // thumb2 supports a larger displacement
913 if ( _options
.preferSubArchitecture() && _options
.archSupportsThumb2() ) {
914 if ( (displacement
> 16777214LL) || (displacement
< (-16777216LL)) ) {
915 // show layout of final image
916 printSectionLayout(state
);
918 const ld::Atom
* target
;
919 throwf("b/bl/blx thumb2 branch out of range (%lld max is +/-16MB): from %s (0x%08llX) to %s (0x%08llX)",
920 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
921 addressOf(state
, fixup
, &target
));
925 if ( (displacement
> 4194302LL) || (displacement
< (-4194304LL)) ) {
926 // show layout of final image
927 printSectionLayout(state
);
929 const ld::Atom
* target
;
930 throwf("b/bl/blx thumb1 branch out of range (%lld max is +/-4MB): from %s (0x%08llX) to %s (0x%08llX)",
931 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
932 addressOf(state
, fixup
, &target
));
941 uint16_t OutputFile::get16LE(uint8_t* loc
) { return LittleEndian::get16(*(uint16_t*)loc
); }
942 void OutputFile::set16LE(uint8_t* loc
, uint16_t value
) { LittleEndian::set16(*(uint16_t*)loc
, value
); }
944 uint32_t OutputFile::get32LE(uint8_t* loc
) { return LittleEndian::get32(*(uint32_t*)loc
); }
945 void OutputFile::set32LE(uint8_t* loc
, uint32_t value
) { LittleEndian::set32(*(uint32_t*)loc
, value
); }
947 uint64_t OutputFile::get64LE(uint8_t* loc
) { return LittleEndian::get64(*(uint64_t*)loc
); }
948 void OutputFile::set64LE(uint8_t* loc
, uint64_t value
) { LittleEndian::set64(*(uint64_t*)loc
, value
); }
950 uint16_t OutputFile::get16BE(uint8_t* loc
) { return BigEndian::get16(*(uint16_t*)loc
); }
951 void OutputFile::set16BE(uint8_t* loc
, uint16_t value
) { BigEndian::set16(*(uint16_t*)loc
, value
); }
953 uint32_t OutputFile::get32BE(uint8_t* loc
) { return BigEndian::get32(*(uint32_t*)loc
); }
954 void OutputFile::set32BE(uint8_t* loc
, uint32_t value
) { BigEndian::set32(*(uint32_t*)loc
, value
); }
956 uint64_t OutputFile::get64BE(uint8_t* loc
) { return BigEndian::get64(*(uint64_t*)loc
); }
957 void OutputFile::set64BE(uint8_t* loc
, uint64_t value
) { BigEndian::set64(*(uint64_t*)loc
, value
); }
959 void OutputFile::applyFixUps(ld::Internal
& state
, uint64_t mhAddress
, const ld::Atom
* atom
, uint8_t* buffer
)
961 //fprintf(stderr, "applyFixUps() on %s\n", atom->name());
962 int64_t accumulator
= 0;
963 const ld::Atom
* toTarget
= NULL
;
964 const ld::Atom
* fromTarget
;
966 uint32_t instruction
;
967 uint32_t newInstruction
;
971 bool thumbTarget
= false;
972 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(), end
=atom
->fixupsEnd(); fit
!= end
; ++fit
) {
973 uint8_t* fixUpLocation
= &buffer
[fit
->offsetInAtom
];
974 switch ( (ld::Fixup::Kind
)(fit
->kind
) ) {
975 case ld::Fixup::kindNone
:
976 case ld::Fixup::kindNoneFollowOn
:
977 case ld::Fixup::kindNoneGroupSubordinate
:
978 case ld::Fixup::kindNoneGroupSubordinateFDE
:
979 case ld::Fixup::kindNoneGroupSubordinateLSDA
:
980 case ld::Fixup::kindNoneGroupSubordinatePersonality
:
982 case ld::Fixup::kindSetTargetAddress
:
983 accumulator
= addressOf(state
, fit
, &toTarget
);
984 thumbTarget
= targetIsThumb(state
, fit
);
987 if ( fit
->contentAddendOnly
|| fit
->contentDetlaToAddendOnly
)
990 case ld::Fixup::kindSubtractTargetAddress
:
991 delta
= addressOf(state
, fit
, &fromTarget
);
992 if ( ! fit
->contentAddendOnly
)
993 accumulator
-= delta
;
995 case ld::Fixup::kindAddAddend
:
996 // <rdar://problem/8342028> ARM main executables main contain .long constants pointing
997 // into themselves such as jump tables. These .long should not have thumb bit set
998 // even though the target is a thumb instruction. We can tell it is an interior pointer
999 // because we are processing an addend.
1000 if ( thumbTarget
&& (toTarget
== atom
) && ((int32_t)fit
->u
.addend
> 0) ) {
1001 accumulator
&= (-2);
1002 //warning("removing thumb bit from intra-atom pointer in %s %s+0x%0X",
1003 // atom->section().sectionName(), atom->name(), fit->offsetInAtom);
1005 accumulator
+= fit
->u
.addend
;
1007 case ld::Fixup::kindSubtractAddend
:
1008 accumulator
-= fit
->u
.addend
;
1010 case ld::Fixup::kindSetTargetImageOffset
:
1011 accumulator
= addressOf(state
, fit
, &toTarget
) - mhAddress
;
1013 case ld::Fixup::kindSetTargetSectionOffset
:
1014 accumulator
= sectionOffsetOf(state
, fit
);
1016 case ld::Fixup::kindSetTargetTLVTemplateOffset
:
1017 accumulator
= tlvTemplateOffsetOf(state
, fit
);
1019 case ld::Fixup::kindStore8
:
1020 *fixUpLocation
+= accumulator
;
1022 case ld::Fixup::kindStoreLittleEndian16
:
1023 set16LE(fixUpLocation
, accumulator
);
1025 case ld::Fixup::kindStoreLittleEndianLow24of32
:
1026 set32LE(fixUpLocation
, (get32LE(fixUpLocation
) & 0xFF000000) | (accumulator
& 0x00FFFFFF) );
1028 case ld::Fixup::kindStoreLittleEndian32
:
1029 rangeCheckAbsolute32(accumulator
, state
, atom
, fit
);
1030 set32LE(fixUpLocation
, accumulator
);
1032 case ld::Fixup::kindStoreLittleEndian64
:
1033 set64LE(fixUpLocation
, accumulator
);
1035 case ld::Fixup::kindStoreBigEndian16
:
1036 set16BE(fixUpLocation
, accumulator
);
1038 case ld::Fixup::kindStoreBigEndianLow24of32
:
1039 set32BE(fixUpLocation
, (get32BE(fixUpLocation
) & 0xFF000000) | (accumulator
& 0x00FFFFFF) );
1041 case ld::Fixup::kindStoreBigEndian32
:
1042 rangeCheckAbsolute32(accumulator
, state
, atom
, fit
);
1043 set32BE(fixUpLocation
, accumulator
);
1045 case ld::Fixup::kindStoreBigEndian64
:
1046 set64BE(fixUpLocation
, accumulator
);
1048 case ld::Fixup::kindStoreX86PCRel8
:
1049 case ld::Fixup::kindStoreX86BranchPCRel8
:
1050 if ( fit
->contentAddendOnly
)
1051 delta
= accumulator
;
1053 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 1);
1054 rangeCheck8(delta
, state
, atom
, fit
);
1055 *fixUpLocation
= delta
;
1057 case ld::Fixup::kindStoreX86PCRel16
:
1058 if ( fit
->contentAddendOnly
)
1059 delta
= accumulator
;
1061 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 2);
1062 rangeCheck16(delta
, state
, atom
, fit
);
1063 set16LE(fixUpLocation
, delta
);
1065 case ld::Fixup::kindStoreX86BranchPCRel32
:
1066 if ( fit
->contentAddendOnly
)
1067 delta
= accumulator
;
1069 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1070 rangeCheckBranch32(delta
, state
, atom
, fit
);
1071 set32LE(fixUpLocation
, delta
);
1073 case ld::Fixup::kindStoreX86PCRel32GOTLoad
:
1074 case ld::Fixup::kindStoreX86PCRel32GOT
:
1075 case ld::Fixup::kindStoreX86PCRel32
:
1076 case ld::Fixup::kindStoreX86PCRel32TLVLoad
:
1077 if ( fit
->contentAddendOnly
)
1078 delta
= accumulator
;
1080 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1081 rangeCheckRIP32(delta
, state
, atom
, fit
);
1082 set32LE(fixUpLocation
, delta
);
1084 case ld::Fixup::kindStoreX86PCRel32_1
:
1085 if ( fit
->contentAddendOnly
)
1086 delta
= accumulator
- 1;
1088 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 5);
1089 rangeCheckRIP32(delta
, state
, atom
, fit
);
1090 set32LE(fixUpLocation
, delta
);
1092 case ld::Fixup::kindStoreX86PCRel32_2
:
1093 if ( fit
->contentAddendOnly
)
1094 delta
= accumulator
- 2;
1096 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 6);
1097 rangeCheckRIP32(delta
, state
, atom
, fit
);
1098 set32LE(fixUpLocation
, delta
);
1100 case ld::Fixup::kindStoreX86PCRel32_4
:
1101 if ( fit
->contentAddendOnly
)
1102 delta
= accumulator
- 4;
1104 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 8);
1105 rangeCheckRIP32(delta
, state
, atom
, fit
);
1106 set32LE(fixUpLocation
, delta
);
1108 case ld::Fixup::kindStoreX86Abs32TLVLoad
:
1109 set32LE(fixUpLocation
, accumulator
);
1111 case ld::Fixup::kindStoreX86Abs32TLVLoadNowLEA
:
1112 assert(_options
.outputKind() != Options::kObjectFile
);
1113 // TLV entry was optimized away, change movl instruction to a leal
1114 if ( fixUpLocation
[-1] != 0xA1 )
1115 throw "TLV load reloc does not point to a movl instruction";
1116 fixUpLocation
[-1] = 0xB8;
1117 set32LE(fixUpLocation
, accumulator
);
1119 case ld::Fixup::kindStoreX86PCRel32GOTLoadNowLEA
:
1120 assert(_options
.outputKind() != Options::kObjectFile
);
1121 // GOT entry was optimized away, change movq instruction to a leaq
1122 if ( fixUpLocation
[-2] != 0x8B )
1123 throw "GOT load reloc does not point to a movq instruction";
1124 fixUpLocation
[-2] = 0x8D;
1125 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1126 rangeCheckRIP32(delta
, state
, atom
, fit
);
1127 set32LE(fixUpLocation
, delta
);
1129 case ld::Fixup::kindStoreX86PCRel32TLVLoadNowLEA
:
1130 assert(_options
.outputKind() != Options::kObjectFile
);
1131 // TLV entry was optimized away, change movq instruction to a leaq
1132 if ( fixUpLocation
[-2] != 0x8B )
1133 throw "TLV load reloc does not point to a movq instruction";
1134 fixUpLocation
[-2] = 0x8D;
1135 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1136 rangeCheckRIP32(delta
, state
, atom
, fit
);
1137 set32LE(fixUpLocation
, delta
);
1139 case ld::Fixup::kindStoreTargetAddressARMLoad12
:
1140 accumulator
= addressOf(state
, fit
, &toTarget
);
1141 // fall into kindStoreARMLoad12 case
1142 case ld::Fixup::kindStoreARMLoad12
:
1143 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 8);
1144 rangeCheckARM12(delta
, state
, atom
, fit
);
1145 instruction
= get32LE(fixUpLocation
);
1147 newInstruction
= instruction
& 0xFFFFF000;
1148 newInstruction
|= ((uint32_t)delta
& 0xFFF);
1151 newInstruction
= instruction
& 0xFF7FF000;
1152 newInstruction
|= ((uint32_t)(-delta
) & 0xFFF);
1154 set32LE(fixUpLocation
, newInstruction
);
1156 case ld::Fixup::kindDtraceExtra
:
1158 case ld::Fixup::kindStoreX86DtraceCallSiteNop
:
1159 if ( _options
.outputKind() != Options::kObjectFile
) {
1160 // change call site to a NOP
1161 fixUpLocation
[-1] = 0x90; // 1-byte nop
1162 fixUpLocation
[0] = 0x0F; // 4-byte nop
1163 fixUpLocation
[1] = 0x1F;
1164 fixUpLocation
[2] = 0x40;
1165 fixUpLocation
[3] = 0x00;
1168 case ld::Fixup::kindStoreX86DtraceIsEnableSiteClear
:
1169 if ( _options
.outputKind() != Options::kObjectFile
) {
1170 // change call site to a clear eax
1171 fixUpLocation
[-1] = 0x33; // xorl eax,eax
1172 fixUpLocation
[0] = 0xC0;
1173 fixUpLocation
[1] = 0x90; // 1-byte nop
1174 fixUpLocation
[2] = 0x90; // 1-byte nop
1175 fixUpLocation
[3] = 0x90; // 1-byte nop
1178 case ld::Fixup::kindStoreARMDtraceCallSiteNop
:
1179 if ( _options
.outputKind() != Options::kObjectFile
) {
1180 // change call site to a NOP
1181 set32LE(fixUpLocation
, 0xE1A00000);
1184 case ld::Fixup::kindStoreARMDtraceIsEnableSiteClear
:
1185 if ( _options
.outputKind() != Options::kObjectFile
) {
1186 // change call site to 'eor r0, r0, r0'
1187 set32LE(fixUpLocation
, 0xE0200000);
1190 case ld::Fixup::kindStoreThumbDtraceCallSiteNop
:
1191 if ( _options
.outputKind() != Options::kObjectFile
) {
1192 // change 32-bit blx call site to two thumb NOPs
1193 set32LE(fixUpLocation
, 0x46C046C0);
1196 case ld::Fixup::kindStoreThumbDtraceIsEnableSiteClear
:
1197 if ( _options
.outputKind() != Options::kObjectFile
) {
1198 // change 32-bit blx call site to 'nop', 'eor r0, r0'
1199 set32LE(fixUpLocation
, 0x46C04040);
1202 case ld::Fixup::kindLazyTarget
:
1204 case ld::Fixup::kindSetLazyOffset
:
1205 assert(fit
->binding
== ld::Fixup::bindingDirectlyBound
);
1206 accumulator
= this->lazyBindingInfoOffsetForLazyPointerAddress(fit
->u
.target
->finalAddress());
1208 case ld::Fixup::kindStoreTargetAddressLittleEndian32
:
1209 accumulator
= addressOf(state
, fit
, &toTarget
);
1210 thumbTarget
= targetIsThumb(state
, fit
);
1213 if ( fit
->contentAddendOnly
)
1215 rangeCheckAbsolute32(accumulator
, state
, atom
, fit
);
1216 set32LE(fixUpLocation
, accumulator
);
1218 case ld::Fixup::kindStoreTargetAddressLittleEndian64
:
1219 accumulator
= addressOf(state
, fit
, &toTarget
);
1220 if ( fit
->contentAddendOnly
)
1222 set64LE(fixUpLocation
, accumulator
);
1224 case ld::Fixup::kindStoreTargetAddressBigEndian32
:
1225 accumulator
= addressOf(state
, fit
, &toTarget
);
1226 if ( fit
->contentAddendOnly
)
1228 set32BE(fixUpLocation
, accumulator
);
1230 case ld::Fixup::kindStoreTargetAddressBigEndian64
:
1231 accumulator
= addressOf(state
, fit
, &toTarget
);
1232 if ( fit
->contentAddendOnly
)
1234 set64BE(fixUpLocation
, accumulator
);
1236 case ld::Fixup::kindSetTargetTLVTemplateOffsetLittleEndian32
:
1237 accumulator
= tlvTemplateOffsetOf(state
, fit
);
1238 set32LE(fixUpLocation
, accumulator
);
1240 case ld::Fixup::kindSetTargetTLVTemplateOffsetLittleEndian64
:
1241 accumulator
= tlvTemplateOffsetOf(state
, fit
);
1242 set64LE(fixUpLocation
, accumulator
);
1244 case ld::Fixup::kindStoreTargetAddressX86PCRel32
:
1245 case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32
:
1246 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad
:
1247 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoad
:
1248 accumulator
= addressOf(state
, fit
, &toTarget
);
1249 if ( fit
->contentDetlaToAddendOnly
)
1251 if ( fit
->contentAddendOnly
)
1254 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1255 rangeCheckRIP32(delta
, state
, atom
, fit
);
1256 set32LE(fixUpLocation
, delta
);
1258 case ld::Fixup::kindStoreTargetAddressX86Abs32TLVLoad
:
1259 set32LE(fixUpLocation
, accumulator
);
1261 case ld::Fixup::kindStoreTargetAddressX86Abs32TLVLoadNowLEA
:
1262 // TLV entry was optimized away, change movl instruction to a leal
1263 if ( fixUpLocation
[-1] != 0xA1 )
1264 throw "TLV load reloc does not point to a movl <abs-address>,<reg> instruction";
1265 fixUpLocation
[-1] = 0xB8;
1266 accumulator
= addressOf(state
, fit
, &toTarget
);
1267 set32LE(fixUpLocation
, accumulator
);
1269 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA
:
1270 // GOT entry was optimized away, change movq instruction to a leaq
1271 if ( fixUpLocation
[-2] != 0x8B )
1272 throw "GOT load reloc does not point to a movq instruction";
1273 fixUpLocation
[-2] = 0x8D;
1274 accumulator
= addressOf(state
, fit
, &toTarget
);
1275 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1276 rangeCheckRIP32(delta
, state
, atom
, fit
);
1277 set32LE(fixUpLocation
, delta
);
1279 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoadNowLEA
:
1280 // TLV entry was optimized away, change movq instruction to a leaq
1281 if ( fixUpLocation
[-2] != 0x8B )
1282 throw "TLV load reloc does not point to a movq instruction";
1283 fixUpLocation
[-2] = 0x8D;
1284 accumulator
= addressOf(state
, fit
, &toTarget
);
1285 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1286 rangeCheckRIP32(delta
, state
, atom
, fit
);
1287 set32LE(fixUpLocation
, delta
);
1289 case ld::Fixup::kindStoreTargetAddressARMBranch24
:
1290 accumulator
= addressOf(state
, fit
, &toTarget
);
1291 thumbTarget
= targetIsThumb(state
, fit
);
1294 if ( fit
->contentDetlaToAddendOnly
)
1296 // fall into kindStoreARMBranch24 case
1297 case ld::Fixup::kindStoreARMBranch24
:
1298 // The pc added will be +8 from the pc
1299 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 8);
1300 rangeCheckARMBranch24(delta
, state
, atom
, fit
);
1301 instruction
= get32LE(fixUpLocation
);
1302 // Make sure we are calling arm with bl, thumb with blx
1303 is_bl
= ((instruction
& 0xFF000000) == 0xEB000000);
1304 is_blx
= ((instruction
& 0xFE000000) == 0xFA000000);
1305 is_b
= !is_blx
&& ((instruction
& 0x0F000000) == 0x0A000000);
1306 if ( is_bl
&& thumbTarget
) {
1307 uint32_t opcode
= 0xFA000000;
1308 uint32_t disp
= (uint32_t)(delta
>> 2) & 0x00FFFFFF;
1309 uint32_t h_bit
= (uint32_t)(delta
<< 23) & 0x01000000;
1310 newInstruction
= opcode
| h_bit
| disp
;
1312 else if ( is_blx
&& !thumbTarget
) {
1313 uint32_t opcode
= 0xEB000000;
1314 uint32_t disp
= (uint32_t)(delta
>> 2) & 0x00FFFFFF;
1315 newInstruction
= opcode
| disp
;
1317 else if ( is_b
&& thumbTarget
) {
1318 if ( fit
->contentDetlaToAddendOnly
)
1319 newInstruction
= (instruction
& 0xFF000000) | ((uint32_t)(delta
>> 2) & 0x00FFFFFF);
1321 throwf("no pc-rel bx arm instruction. Can't fix up branch to %s in %s",
1322 referenceTargetAtomName(state
, fit
), atom
->name());
1324 else if ( !is_bl
&& !is_blx
&& thumbTarget
) {
1325 throwf("don't know how to convert instruction %x referencing %s to thumb",
1326 instruction
, referenceTargetAtomName(state
, fit
));
1329 newInstruction
= (instruction
& 0xFF000000) | ((uint32_t)(delta
>> 2) & 0x00FFFFFF);
1331 set32LE(fixUpLocation
, newInstruction
);
1333 case ld::Fixup::kindStoreTargetAddressThumbBranch22
:
1334 accumulator
= addressOf(state
, fit
, &toTarget
);
1335 thumbTarget
= targetIsThumb(state
, fit
);
1338 if ( fit
->contentDetlaToAddendOnly
)
1340 // fall into kindStoreThumbBranch22 case
1341 case ld::Fixup::kindStoreThumbBranch22
:
1342 instruction
= get32LE(fixUpLocation
);
1343 is_bl
= ((instruction
& 0xD000F800) == 0xD000F000);
1344 is_blx
= ((instruction
& 0xD000F800) == 0xC000F000);
1345 is_b
= ((instruction
& 0xD000F800) == 0x9000F000);
1346 // If the target is not thumb, we will be generating a blx instruction
1347 // Since blx cannot have the low bit set, set bit[1] of the target to
1348 // bit[1] of the base address, so that the difference is a multiple of
1350 if ( !thumbTarget
&& !fit
->contentDetlaToAddendOnly
) {
1351 accumulator
&= -3ULL;
1352 accumulator
|= ((atom
->finalAddress() + fit
->offsetInAtom
) & 2LL);
1354 // The pc added will be +4 from the pc
1355 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1356 rangeCheckThumbBranch22(delta
, state
, atom
, fit
);
1357 if ( _options
.preferSubArchitecture() && _options
.archSupportsThumb2() ) {
1358 // The instruction is really two instructions:
1359 // The lower 16 bits are the first instruction, which contains the high
1360 // 11 bits of the displacement.
1361 // The upper 16 bits are the second instruction, which contains the low
1362 // 11 bits of the displacement, as well as differentiating bl and blx.
1363 uint32_t s
= (uint32_t)(delta
>> 24) & 0x1;
1364 uint32_t i1
= (uint32_t)(delta
>> 23) & 0x1;
1365 uint32_t i2
= (uint32_t)(delta
>> 22) & 0x1;
1366 uint32_t imm10
= (uint32_t)(delta
>> 12) & 0x3FF;
1367 uint32_t imm11
= (uint32_t)(delta
>> 1) & 0x7FF;
1368 uint32_t j1
= (i1
== s
);
1369 uint32_t j2
= (i2
== s
);
1372 instruction
= 0xD000F000; // keep bl
1374 instruction
= 0xC000F000; // change to blx
1376 else if ( is_blx
) {
1378 instruction
= 0xD000F000; // change to bl
1380 instruction
= 0xC000F000; // keep blx
1383 instruction
= 0x9000F000; // keep b
1384 if ( !thumbTarget
&& !fit
->contentDetlaToAddendOnly
) {
1385 throwf("armv7 has no pc-rel bx thumb instruction. Can't fix up branch to %s in %s",
1386 referenceTargetAtomName(state
, fit
), atom
->name());
1391 throwf("don't know how to convert branch instruction %x referencing %s to bx",
1392 instruction
, referenceTargetAtomName(state
, fit
));
1393 instruction
= 0x9000F000; // keep b
1395 uint32_t nextDisp
= (j1
<< 13) | (j2
<< 11) | imm11
;
1396 uint32_t firstDisp
= (s
<< 10) | imm10
;
1397 newInstruction
= instruction
| (nextDisp
<< 16) | firstDisp
;
1398 //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",
1399 // s, j1, j2, imm10, imm11, opcode, firstDisp, nextDisp, newInstruction, delta, inAtom->getDisplayName(), ref->getTarget().getDisplayName());
1400 set32LE(fixUpLocation
, newInstruction
);
1403 // The instruction is really two instructions:
1404 // The lower 16 bits are the first instruction, which contains the high
1405 // 11 bits of the displacement.
1406 // The upper 16 bits are the second instruction, which contains the low
1407 // 11 bits of the displacement, as well as differentiating bl and blx.
1408 uint32_t firstDisp
= (uint32_t)(delta
>> 12) & 0x7FF;
1409 uint32_t nextDisp
= (uint32_t)(delta
>> 1) & 0x7FF;
1410 if ( is_bl
&& !thumbTarget
) {
1411 instruction
= 0xE800F000;
1413 else if ( is_blx
&& thumbTarget
) {
1414 instruction
= 0xF800F000;
1417 instruction
= 0x9000F000; // keep b
1418 if ( !thumbTarget
&& !fit
->contentDetlaToAddendOnly
) {
1419 throwf("armv6 has no pc-rel bx thumb instruction. Can't fix up branch to %s in %s",
1420 referenceTargetAtomName(state
, fit
), atom
->name());
1424 instruction
= instruction
& 0xF800F800;
1426 newInstruction
= instruction
| (nextDisp
<< 16) | firstDisp
;
1427 set32LE(fixUpLocation
, newInstruction
);
1430 case ld::Fixup::kindStoreARMLow16
:
1432 uint32_t imm4
= (accumulator
& 0x0000F000) >> 12;
1433 uint32_t imm12
= accumulator
& 0x00000FFF;
1434 instruction
= get32LE(fixUpLocation
);
1435 newInstruction
= (instruction
& 0xFFF0F000) | (imm4
<< 16) | imm12
;
1436 set32LE(fixUpLocation
, newInstruction
);
1439 case ld::Fixup::kindStoreARMHigh16
:
1441 uint32_t imm4
= (accumulator
& 0xF0000000) >> 28;
1442 uint32_t imm12
= (accumulator
& 0x0FFF0000) >> 16;
1443 instruction
= get32LE(fixUpLocation
);
1444 newInstruction
= (instruction
& 0xFFF0F000) | (imm4
<< 16) | imm12
;
1445 set32LE(fixUpLocation
, newInstruction
);
1448 case ld::Fixup::kindStoreThumbLow16
:
1450 uint32_t imm4
= (accumulator
& 0x0000F000) >> 12;
1451 uint32_t i
= (accumulator
& 0x00000800) >> 11;
1452 uint32_t imm3
= (accumulator
& 0x00000700) >> 8;
1453 uint32_t imm8
= accumulator
& 0x000000FF;
1454 instruction
= get32LE(fixUpLocation
);
1455 newInstruction
= (instruction
& 0x8F00FBF0) | imm4
| (i
<< 10) | (imm3
<< 28) | (imm8
<< 16);
1456 set32LE(fixUpLocation
, newInstruction
);
1459 case ld::Fixup::kindStoreThumbHigh16
:
1461 uint32_t imm4
= (accumulator
& 0xF0000000) >> 28;
1462 uint32_t i
= (accumulator
& 0x08000000) >> 27;
1463 uint32_t imm3
= (accumulator
& 0x07000000) >> 24;
1464 uint32_t imm8
= (accumulator
& 0x00FF0000) >> 16;
1465 instruction
= get32LE(fixUpLocation
);
1466 newInstruction
= (instruction
& 0x8F00FBF0) | imm4
| (i
<< 10) | (imm3
<< 28) | (imm8
<< 16);
1467 set32LE(fixUpLocation
, newInstruction
);
1474 void OutputFile::copyNoOps(uint8_t* from
, uint8_t* to
, bool thumb
)
1476 switch ( _options
.architecture() ) {
1478 case CPU_TYPE_X86_64
:
1479 for (uint8_t* p
=from
; p
< to
; ++p
)
1484 for (uint8_t* p
=from
; p
< to
; p
+= 2)
1485 OSWriteLittleInt16((uint16_t*)p
, 0, 0x46c0);
1488 for (uint8_t* p
=from
; p
< to
; p
+= 4)
1489 OSWriteLittleInt32((uint32_t*)p
, 0, 0xe1a00000);
1493 for (uint8_t* p
=from
; p
< to
; ++p
)
1499 bool OutputFile::takesNoDiskSpace(const ld::Section
* sect
)
1501 switch ( sect
->type() ) {
1502 case ld::Section::typeZeroFill
:
1503 case ld::Section::typeTLVZeroFill
:
1504 return _options
.optimizeZeroFill();
1505 case ld::Section::typePageZero
:
1506 case ld::Section::typeStack
:
1507 case ld::Section::typeAbsoluteSymbols
:
1508 case ld::Section::typeTentativeDefs
:
1516 bool OutputFile::hasZeroForFileOffset(const ld::Section
* sect
)
1518 switch ( sect
->type() ) {
1519 case ld::Section::typeZeroFill
:
1520 case ld::Section::typeTLVZeroFill
:
1521 return _options
.optimizeZeroFill();
1522 case ld::Section::typePageZero
:
1523 case ld::Section::typeStack
:
1524 case ld::Section::typeTentativeDefs
:
1533 void OutputFile::writeOutputFile(ld::Internal
& state
)
1535 // for UNIX conformance, error if file exists and is not writable
1536 if ( (access(_options
.outputFilePath(), F_OK
) == 0) && (access(_options
.outputFilePath(), W_OK
) == -1) )
1537 throwf("can't write output file: %s", _options
.outputFilePath());
1539 int permissions
= 0777;
1540 if ( _options
.outputKind() == Options::kObjectFile
)
1542 // Calling unlink first assures the file is gone so that open creates it with correct permissions
1543 // It also handles the case where __options.outputFilePath() file is not writable but its directory is
1544 // And it means we don't have to truncate the file when done writing (in case new is smaller than old)
1545 // Lastly, only delete existing file if it is a normal file (e.g. not /dev/null).
1546 struct stat stat_buf
;
1547 if ( (stat(_options
.outputFilePath(), &stat_buf
) != -1) && (stat_buf
.st_mode
& S_IFREG
) )
1548 (void)unlink(_options
.outputFilePath());
1550 // try to allocate buffer for entire output file content
1551 uint8_t* wholeBuffer
= (uint8_t*)calloc(_fileSize
, 1);
1552 if ( wholeBuffer
== NULL
)
1553 throwf("can't create buffer of %llu bytes for output", _fileSize
);
1555 if ( _options
.UUIDMode() == Options::kUUIDRandom
) {
1557 ::uuid_generate_random(bits
);
1558 _headersAndLoadCommandAtom
->setUUID(bits
);
1561 // have each atom write itself
1562 uint64_t fileOffsetOfEndOfLastAtom
= 0;
1563 uint64_t mhAddress
= 0;
1564 bool lastAtomUsesNoOps
= false;
1565 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
1566 ld::Internal::FinalSection
* sect
= *sit
;
1567 if ( sect
->type() == ld::Section::typeMachHeader
)
1568 mhAddress
= sect
->address
;
1569 if ( takesNoDiskSpace(sect
) )
1571 const bool sectionUsesNops
= (sect
->type() == ld::Section::typeCode
);
1572 //fprintf(stderr, "file offset=0x%08llX, section %s\n", sect->fileOffset, sect->sectionName());
1573 std::vector
<const ld::Atom
*>& atoms
= sect
->atoms
;
1574 bool lastAtomWasThumb
= false;
1575 for (std::vector
<const ld::Atom
*>::iterator ait
= atoms
.begin(); ait
!= atoms
.end(); ++ait
) {
1576 const ld::Atom
* atom
= *ait
;
1577 if ( atom
->definition() == ld::Atom::definitionProxy
)
1580 uint64_t fileOffset
= atom
->finalAddress() - sect
->address
+ sect
->fileOffset
;
1581 // check for alignment padding between atoms
1582 if ( (fileOffset
!= fileOffsetOfEndOfLastAtom
) && lastAtomUsesNoOps
) {
1583 this->copyNoOps(&wholeBuffer
[fileOffsetOfEndOfLastAtom
], &wholeBuffer
[fileOffset
], lastAtomWasThumb
);
1585 // copy atom content
1586 atom
->copyRawContent(&wholeBuffer
[fileOffset
]);
1588 this->applyFixUps(state
, mhAddress
, atom
, &wholeBuffer
[fileOffset
]);
1589 fileOffsetOfEndOfLastAtom
= fileOffset
+atom
->size();
1590 lastAtomUsesNoOps
= sectionUsesNops
;
1591 lastAtomWasThumb
= atom
->isThumb();
1593 catch (const char* msg
) {
1594 if ( atom
->file() != NULL
)
1595 throwf("%s in %s from %s", msg
, atom
->name(), atom
->file()->path());
1597 throwf("%s in %s", msg
, atom
->name());
1603 if ( _options
.UUIDMode() == Options::kUUIDContent
) {
1604 const bool log
= false;
1605 if ( (_options
.outputKind() != Options::kObjectFile
) || state
.someObjectFileHasDwarf
) {
1606 uint8_t digest
[CC_MD5_DIGEST_LENGTH
];
1607 uint32_t stabsStringsOffsetStart
;
1608 uint32_t tabsStringsOffsetEnd
;
1609 uint32_t stabsOffsetStart
;
1610 uint32_t stabsOffsetEnd
;
1611 if ( _symbolTableAtom
->hasStabs(stabsStringsOffsetStart
, tabsStringsOffsetEnd
, stabsOffsetStart
, stabsOffsetEnd
) ) {
1612 // find two areas of file that are stabs info and should not contribute to checksum
1613 uint64_t stringPoolFileOffset
= 0;
1614 uint64_t symbolTableFileOffset
= 0;
1615 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
1616 ld::Internal::FinalSection
* sect
= *sit
;
1617 if ( sect
->type() == ld::Section::typeLinkEdit
) {
1618 if ( strcmp(sect
->sectionName(), "__string_pool") == 0 )
1619 stringPoolFileOffset
= sect
->fileOffset
;
1620 else if ( strcmp(sect
->sectionName(), "__symbol_table") == 0 )
1621 symbolTableFileOffset
= sect
->fileOffset
;
1624 uint64_t firstStabNlistFileOffset
= symbolTableFileOffset
+ stabsOffsetStart
;
1625 uint64_t lastStabNlistFileOffset
= symbolTableFileOffset
+ stabsOffsetEnd
;
1626 uint64_t firstStabStringFileOffset
= stringPoolFileOffset
+ stabsStringsOffsetStart
;
1627 uint64_t lastStabStringFileOffset
= stringPoolFileOffset
+ tabsStringsOffsetEnd
;
1628 if ( log
) fprintf(stderr
, "firstStabNlistFileOffset=0x%08llX\n", firstStabNlistFileOffset
);
1629 if ( log
) fprintf(stderr
, "lastStabNlistFileOffset=0x%08llX\n", lastStabNlistFileOffset
);
1630 if ( log
) fprintf(stderr
, "firstStabStringFileOffset=0x%08llX\n", firstStabStringFileOffset
);
1631 if ( log
) fprintf(stderr
, "lastStabStringFileOffset=0x%08llX\n", lastStabStringFileOffset
);
1632 assert(firstStabNlistFileOffset
<= firstStabStringFileOffset
);
1634 CC_MD5_CTX md5state
;
1635 CC_MD5_Init(&md5state
);
1636 // checksum everything up to first stabs nlist
1637 if ( log
) fprintf(stderr
, "checksum 0x%08X -> 0x%08llX\n", 0, firstStabNlistFileOffset
);
1638 CC_MD5_Update(&md5state
, &wholeBuffer
[0], firstStabNlistFileOffset
);
1639 // checkusm everything after last stabs nlist and up to first stabs string
1640 if ( log
) fprintf(stderr
, "checksum 0x%08llX -> 0x%08llX\n", lastStabNlistFileOffset
, firstStabStringFileOffset
);
1641 CC_MD5_Update(&md5state
, &wholeBuffer
[lastStabNlistFileOffset
], firstStabStringFileOffset
-lastStabNlistFileOffset
);
1642 // checksum everything after last stabs string to end of file
1643 if ( log
) fprintf(stderr
, "checksum 0x%08llX -> 0x%08llX\n", lastStabStringFileOffset
, _fileSize
);
1644 CC_MD5_Update(&md5state
, &wholeBuffer
[lastStabStringFileOffset
], _fileSize
-lastStabStringFileOffset
);
1645 CC_MD5_Final(digest
, &md5state
);
1646 if ( log
) fprintf(stderr
, "uuid=%02X, %02X, %02X, %02X, %02X, %02X, %02X, %02X\n", digest
[0], digest
[1], digest
[2],
1647 digest
[3], digest
[4], digest
[5], digest
[6], digest
[7]);
1650 CC_MD5(wholeBuffer
, _fileSize
, digest
);
1652 // <rdar://problem/6723729> LC_UUID uuids should conform to RFC 4122 UUID version 4 & UUID version 5 formats
1653 digest
[6] = ( digest
[6] & 0x0F ) | ( 3 << 4 );
1654 digest
[8] = ( digest
[8] & 0x3F ) | 0x80;
1655 // update buffer with new UUID
1656 _headersAndLoadCommandAtom
->setUUID(digest
);
1657 _headersAndLoadCommandAtom
->recopyUUIDCommand();
1661 // write whole output file in one chunk
1662 int fd
= open(_options
.outputFilePath(), O_CREAT
| O_WRONLY
| O_TRUNC
, permissions
);
1664 throwf("can't open output file for writing: %s, errno=%d", _options
.outputFilePath(), errno
);
1665 if ( ::pwrite(fd
, wholeBuffer
, _fileSize
, 0) == -1 )
1666 throwf("can't write to output file: %s, errno=%d", _options
.outputFilePath(), errno
);
1671 struct AtomByNameSorter
1673 bool operator()(const ld::Atom
* left
, const ld::Atom
* right
)
1675 return (strcmp(left
->name(), right
->name()) < 0);
1682 NotInSet(const std::set
<const ld::Atom
*>& theSet
) : _set(theSet
) {}
1684 bool operator()(const ld::Atom
* atom
) const {
1685 return ( _set
.count(atom
) == 0 );
1688 const std::set
<const ld::Atom
*>& _set
;
1692 void OutputFile::buildSymbolTable(ld::Internal
& state
)
1694 unsigned int machoSectionIndex
= 0;
1695 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
1696 ld::Internal::FinalSection
* sect
= *sit
;
1697 bool setMachoSectionIndex
= !sect
->isSectionHidden() && (sect
->type() != ld::Section::typeTentativeDefs
);
1698 if ( setMachoSectionIndex
)
1699 ++machoSectionIndex
;
1700 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
1701 const ld::Atom
* atom
= *ait
;
1702 if ( setMachoSectionIndex
)
1703 (const_cast<ld::Atom
*>(atom
))->setMachoSection(machoSectionIndex
);
1704 else if ( sect
->type() == ld::Section::typeMachHeader
)
1705 (const_cast<ld::Atom
*>(atom
))->setMachoSection(1); // __mh_execute_header is not in any section by needs n_sect==1
1706 else if ( sect
->type() == ld::Section::typeLastSection
)
1707 (const_cast<ld::Atom
*>(atom
))->setMachoSection(machoSectionIndex
); // use section index of previous section
1708 else if ( sect
->type() == ld::Section::typeFirstSection
)
1709 (const_cast<ld::Atom
*>(atom
))->setMachoSection(machoSectionIndex
+1); // use section index of next section
1711 // in -r mode, clarify symbolTableNotInFinalLinkedImages
1712 if ( _options
.outputKind() == Options::kObjectFile
) {
1713 if ( _options
.architecture() == CPU_TYPE_X86_64
) {
1714 // x86_64 .o files need labels on anonymous literal strings
1715 if ( (sect
->type() == ld::Section::typeCString
) && (atom
->combine() == ld::Atom::combineByNameAndContent
) ) {
1716 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableIn
);
1717 _localAtoms
.push_back(atom
);
1721 if ( sect
->type() == ld::Section::typeCFI
) {
1722 if ( _options
.removeEHLabels() )
1723 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableNotIn
);
1725 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableIn
);
1727 if ( atom
->symbolTableInclusion() == ld::Atom::symbolTableNotInFinalLinkedImages
)
1728 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableIn
);
1731 // TEMP work around until <rdar://problem/7702923> goes in
1732 if ( (atom
->symbolTableInclusion() == ld::Atom::symbolTableInAndNeverStrip
)
1733 && (atom
->scope() == ld::Atom::scopeLinkageUnit
)
1734 && (_options
.outputKind() == Options::kDynamicLibrary
) ) {
1735 (const_cast<ld::Atom
*>(atom
))->setScope(ld::Atom::scopeGlobal
);
1738 // <rdar://problem/6783167> support auto hidden weak symbols: .weak_def_can_be_hidden
1739 if ( atom
->autoHide() && (_options
.outputKind() != Options::kObjectFile
) ) {
1740 // adding auto-hide symbol to .exp file should keep it global
1741 if ( !_options
.hasExportMaskList() || !_options
.shouldExport(atom
->name()) )
1742 (const_cast<ld::Atom
*>(atom
))->setScope(ld::Atom::scopeLinkageUnit
);
1745 // <rdar://problem/8626058> ld should consistently warn when resolvers are not exported
1746 if ( (atom
->contentType() == ld::Atom::typeResolver
) && (atom
->scope() == ld::Atom::scopeLinkageUnit
) )
1747 warning("resolver functions should be external, but '%s' is hidden", atom
->name());
1749 if ( sect
->type() == ld::Section::typeImportProxies
) {
1750 if ( atom
->combine() == ld::Atom::combineByName
)
1751 this->usesWeakExternalSymbols
= true;
1752 // alias proxy is a re-export with a name change, don't import changed name
1753 if ( ! atom
->isAlias() )
1754 _importedAtoms
.push_back(atom
);
1755 // scope of proxies are usually linkage unit, so done
1756 // if scope is global, we need to re-export it too
1757 if ( atom
->scope() == ld::Atom::scopeGlobal
)
1758 _exportedAtoms
.push_back(atom
);
1761 if ( atom
->symbolTableInclusion() == ld::Atom::symbolTableNotInFinalLinkedImages
) {
1762 assert(_options
.outputKind() != Options::kObjectFile
);
1763 continue; // don't add to symbol table
1765 if ( atom
->symbolTableInclusion() == ld::Atom::symbolTableNotIn
) {
1766 continue; // don't add to symbol table
1769 if ( (atom
->definition() == ld::Atom::definitionTentative
) && (_options
.outputKind() == Options::kObjectFile
) ) {
1770 if ( _options
.makeTentativeDefinitionsReal() ) {
1771 // -r -d turns tentative defintions into real def
1772 _exportedAtoms
.push_back(atom
);
1775 // in mach-o object files tentative defintions are stored like undefined symbols
1776 _importedAtoms
.push_back(atom
);
1781 // <rdar://problem/7977374> Add command line options to control symbol weak-def bit on exported symbols
1782 if ( _options
.hasWeakBitTweaks() && (atom
->definition() == ld::Atom::definitionRegular
) ) {
1783 const char* name
= atom
->name();
1784 if ( atom
->scope() == ld::Atom::scopeGlobal
) {
1785 if ( atom
->combine() == ld::Atom::combineNever
) {
1786 if ( _options
.forceWeak(name
) )
1787 (const_cast<ld::Atom
*>(atom
))->setCombine(ld::Atom::combineByName
);
1789 else if ( atom
->combine() == ld::Atom::combineByName
) {
1790 if ( _options
.forceNotWeak(name
) )
1791 (const_cast<ld::Atom
*>(atom
))->setCombine(ld::Atom::combineNever
);
1795 if ( _options
.forceWeakNonWildCard(name
) )
1796 warning("cannot force to be weak, non-external symbol %s", name
);
1797 else if ( _options
.forceNotWeakNonWildcard(name
) )
1798 warning("cannot force to be not-weak, non-external symbol %s", name
);
1802 switch ( atom
->scope() ) {
1803 case ld::Atom::scopeTranslationUnit
:
1804 if ( _options
.keepLocalSymbol(atom
->name()) ) {
1805 _localAtoms
.push_back(atom
);
1808 if ( _options
.outputKind() == Options::kObjectFile
) {
1809 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableInWithRandomAutoStripLabel
);
1810 _localAtoms
.push_back(atom
);
1813 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableNotIn
);
1816 case ld::Atom::scopeGlobal
:
1817 _exportedAtoms
.push_back(atom
);
1819 case ld::Atom::scopeLinkageUnit
:
1820 if ( _options
.outputKind() == Options::kObjectFile
) {
1821 if ( _options
.keepPrivateExterns() ) {
1822 assert( (atom
->combine() == ld::Atom::combineNever
) || (atom
->combine() == ld::Atom::combineByName
) );
1823 _exportedAtoms
.push_back(atom
);
1825 else if ( _options
.keepLocalSymbol(atom
->name()) ) {
1826 _localAtoms
.push_back(atom
);
1829 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableInWithRandomAutoStripLabel
);
1830 _localAtoms
.push_back(atom
);
1834 if ( _options
.keepLocalSymbol(atom
->name()) )
1835 _localAtoms
.push_back(atom
);
1836 // <rdar://problem/5804214> ld should never have a symbol in the non-lazy indirect symbol table with index 0
1837 // this works by making __mh_execute_header be a local symbol which takes symbol index 0
1838 else if ( (atom
->symbolTableInclusion() == ld::Atom::symbolTableInAndNeverStrip
) && !_options
.makeCompressedDyldInfo() )
1839 _localAtoms
.push_back(atom
);
1841 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableNotIn
);
1848 // <rdar://problem/6978069> ld adds undefined symbol from .exp file to binary
1849 if ( (_options
.outputKind() == Options::kKextBundle
) && _options
.hasExportRestrictList() ) {
1850 // search for referenced undefines
1851 std::set
<const ld::Atom
*> referencedProxyAtoms
;
1852 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
=state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
1853 ld::Internal::FinalSection
* sect
= *sit
;
1854 for (std::vector
<const ld::Atom
*>::iterator ait
=sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
1855 const ld::Atom
* atom
= *ait
;
1856 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(), end
=atom
->fixupsEnd(); fit
!= end
; ++fit
) {
1857 switch ( fit
->binding
) {
1858 case ld::Fixup::bindingsIndirectlyBound
:
1859 referencedProxyAtoms
.insert(state
.indirectBindingTable
[fit
->u
.bindingIndex
]);
1861 case ld::Fixup::bindingDirectlyBound
:
1862 referencedProxyAtoms
.insert(fit
->u
.target
);
1870 // remove any unreferenced _importedAtoms
1871 _importedAtoms
.erase(std::remove_if(_importedAtoms
.begin(), _importedAtoms
.end(), NotInSet(referencedProxyAtoms
)), _importedAtoms
.end());
1875 std::sort(_exportedAtoms
.begin(), _exportedAtoms
.end(), AtomByNameSorter());
1876 std::sort(_importedAtoms
.begin(), _importedAtoms
.end(), AtomByNameSorter());
1879 void OutputFile::addPreloadLinkEdit(ld::Internal
& state
)
1881 switch ( _options
.architecture() ) {
1883 if ( _hasLocalRelocations
) {
1884 _localRelocsAtom
= new LocalRelocationsAtom
<x86
>(_options
, state
, *this);
1885 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
1887 if ( _hasExternalRelocations
) {
1888 _externalRelocsAtom
= new ExternalRelocationsAtom
<x86
>(_options
, state
, *this);
1889 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
1891 if ( _hasSymbolTable
) {
1892 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<x86
>(_options
, state
, *this);
1893 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
1894 _symbolTableAtom
= new SymbolTableAtom
<x86
>(_options
, state
, *this);
1895 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
1896 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 4);
1897 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
1900 case CPU_TYPE_X86_64
:
1901 if ( _hasLocalRelocations
) {
1902 _localRelocsAtom
= new LocalRelocationsAtom
<x86_64
>(_options
, state
, *this);
1903 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
1905 if ( _hasExternalRelocations
) {
1906 _externalRelocsAtom
= new ExternalRelocationsAtom
<x86_64
>(_options
, state
, *this);
1907 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
1909 if ( _hasSymbolTable
) {
1910 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<x86_64
>(_options
, state
, *this);
1911 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
1912 _symbolTableAtom
= new SymbolTableAtom
<x86_64
>(_options
, state
, *this);
1913 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
1914 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 4);
1915 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
1919 if ( _hasLocalRelocations
) {
1920 _localRelocsAtom
= new LocalRelocationsAtom
<arm
>(_options
, state
, *this);
1921 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
1923 if ( _hasExternalRelocations
) {
1924 _externalRelocsAtom
= new ExternalRelocationsAtom
<arm
>(_options
, state
, *this);
1925 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
1927 if ( _hasSymbolTable
) {
1928 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<arm
>(_options
, state
, *this);
1929 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
1930 _symbolTableAtom
= new SymbolTableAtom
<arm
>(_options
, state
, *this);
1931 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
1932 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 4);
1933 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
1937 throw "architecture not supported for -preload";
1943 void OutputFile::addLinkEdit(ld::Internal
& state
)
1945 // for historical reasons, -preload orders LINKEDIT content differently
1946 if ( _options
.outputKind() == Options::kPreload
)
1947 return addPreloadLinkEdit(state
);
1949 switch ( _options
.architecture() ) {
1951 if ( _hasSectionRelocations
) {
1952 _sectionsRelocationsAtom
= new SectionRelocationsAtom
<x86
>(_options
, state
, *this);
1953 sectionRelocationsSection
= state
.addAtom(*_sectionsRelocationsAtom
);
1955 if ( _hasDyldInfo
) {
1956 _rebasingInfoAtom
= new RebaseInfoAtom
<x86
>(_options
, state
, *this);
1957 rebaseSection
= state
.addAtom(*_rebasingInfoAtom
);
1959 _bindingInfoAtom
= new BindingInfoAtom
<x86
>(_options
, state
, *this);
1960 bindingSection
= state
.addAtom(*_bindingInfoAtom
);
1962 _weakBindingInfoAtom
= new WeakBindingInfoAtom
<x86
>(_options
, state
, *this);
1963 weakBindingSection
= state
.addAtom(*_weakBindingInfoAtom
);
1965 _lazyBindingInfoAtom
= new LazyBindingInfoAtom
<x86
>(_options
, state
, *this);
1966 lazyBindingSection
= state
.addAtom(*_lazyBindingInfoAtom
);
1968 _exportInfoAtom
= new ExportInfoAtom
<x86
>(_options
, state
, *this);
1969 exportSection
= state
.addAtom(*_exportInfoAtom
);
1971 if ( _hasLocalRelocations
) {
1972 _localRelocsAtom
= new LocalRelocationsAtom
<x86
>(_options
, state
, *this);
1973 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
1975 if ( _hasSplitSegInfo
) {
1976 _splitSegInfoAtom
= new SplitSegInfoAtom
<x86
>(_options
, state
, *this);
1977 splitSegInfoSection
= state
.addAtom(*_splitSegInfoAtom
);
1979 if ( _hasFunctionStartsInfo
) {
1980 _functionStartsAtom
= new FunctionStartsAtom
<x86
>(_options
, state
, *this);
1981 functionStartsSection
= state
.addAtom(*_functionStartsAtom
);
1983 if ( _hasSymbolTable
) {
1984 _symbolTableAtom
= new SymbolTableAtom
<x86
>(_options
, state
, *this);
1985 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
1987 if ( _hasExternalRelocations
) {
1988 _externalRelocsAtom
= new ExternalRelocationsAtom
<x86
>(_options
, state
, *this);
1989 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
1991 if ( _hasSymbolTable
) {
1992 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<x86
>(_options
, state
, *this);
1993 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
1994 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 4);
1995 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
1998 case CPU_TYPE_X86_64
:
1999 if ( _hasSectionRelocations
) {
2000 _sectionsRelocationsAtom
= new SectionRelocationsAtom
<x86_64
>(_options
, state
, *this);
2001 sectionRelocationsSection
= state
.addAtom(*_sectionsRelocationsAtom
);
2003 if ( _hasDyldInfo
) {
2004 _rebasingInfoAtom
= new RebaseInfoAtom
<x86_64
>(_options
, state
, *this);
2005 rebaseSection
= state
.addAtom(*_rebasingInfoAtom
);
2007 _bindingInfoAtom
= new BindingInfoAtom
<x86_64
>(_options
, state
, *this);
2008 bindingSection
= state
.addAtom(*_bindingInfoAtom
);
2010 _weakBindingInfoAtom
= new WeakBindingInfoAtom
<x86_64
>(_options
, state
, *this);
2011 weakBindingSection
= state
.addAtom(*_weakBindingInfoAtom
);
2013 _lazyBindingInfoAtom
= new LazyBindingInfoAtom
<x86_64
>(_options
, state
, *this);
2014 lazyBindingSection
= state
.addAtom(*_lazyBindingInfoAtom
);
2016 _exportInfoAtom
= new ExportInfoAtom
<x86_64
>(_options
, state
, *this);
2017 exportSection
= state
.addAtom(*_exportInfoAtom
);
2019 if ( _hasLocalRelocations
) {
2020 _localRelocsAtom
= new LocalRelocationsAtom
<x86_64
>(_options
, state
, *this);
2021 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
2023 if ( _hasSplitSegInfo
) {
2024 _splitSegInfoAtom
= new SplitSegInfoAtom
<x86_64
>(_options
, state
, *this);
2025 splitSegInfoSection
= state
.addAtom(*_splitSegInfoAtom
);
2027 if ( _hasFunctionStartsInfo
) {
2028 _functionStartsAtom
= new FunctionStartsAtom
<x86_64
>(_options
, state
, *this);
2029 functionStartsSection
= state
.addAtom(*_functionStartsAtom
);
2031 if ( _hasSymbolTable
) {
2032 _symbolTableAtom
= new SymbolTableAtom
<x86_64
>(_options
, state
, *this);
2033 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
2035 if ( _hasExternalRelocations
) {
2036 _externalRelocsAtom
= new ExternalRelocationsAtom
<x86_64
>(_options
, state
, *this);
2037 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
2039 if ( _hasSymbolTable
) {
2040 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<x86_64
>(_options
, state
, *this);
2041 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
2042 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 8);
2043 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
2047 if ( _hasSectionRelocations
) {
2048 _sectionsRelocationsAtom
= new SectionRelocationsAtom
<arm
>(_options
, state
, *this);
2049 sectionRelocationsSection
= state
.addAtom(*_sectionsRelocationsAtom
);
2051 if ( _hasDyldInfo
) {
2052 _rebasingInfoAtom
= new RebaseInfoAtom
<arm
>(_options
, state
, *this);
2053 rebaseSection
= state
.addAtom(*_rebasingInfoAtom
);
2055 _bindingInfoAtom
= new BindingInfoAtom
<arm
>(_options
, state
, *this);
2056 bindingSection
= state
.addAtom(*_bindingInfoAtom
);
2058 _weakBindingInfoAtom
= new WeakBindingInfoAtom
<arm
>(_options
, state
, *this);
2059 weakBindingSection
= state
.addAtom(*_weakBindingInfoAtom
);
2061 _lazyBindingInfoAtom
= new LazyBindingInfoAtom
<arm
>(_options
, state
, *this);
2062 lazyBindingSection
= state
.addAtom(*_lazyBindingInfoAtom
);
2064 _exportInfoAtom
= new ExportInfoAtom
<arm
>(_options
, state
, *this);
2065 exportSection
= state
.addAtom(*_exportInfoAtom
);
2067 if ( _hasLocalRelocations
) {
2068 _localRelocsAtom
= new LocalRelocationsAtom
<arm
>(_options
, state
, *this);
2069 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
2071 if ( _hasSplitSegInfo
) {
2072 _splitSegInfoAtom
= new SplitSegInfoAtom
<arm
>(_options
, state
, *this);
2073 splitSegInfoSection
= state
.addAtom(*_splitSegInfoAtom
);
2075 if ( _hasFunctionStartsInfo
) {
2076 _functionStartsAtom
= new FunctionStartsAtom
<arm
>(_options
, state
, *this);
2077 functionStartsSection
= state
.addAtom(*_functionStartsAtom
);
2079 if ( _hasSymbolTable
) {
2080 _symbolTableAtom
= new SymbolTableAtom
<arm
>(_options
, state
, *this);
2081 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
2083 if ( _hasExternalRelocations
) {
2084 _externalRelocsAtom
= new ExternalRelocationsAtom
<arm
>(_options
, state
, *this);
2085 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
2087 if ( _hasSymbolTable
) {
2088 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<arm
>(_options
, state
, *this);
2089 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
2090 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 4);
2091 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
2095 throw "unknown architecture";
2099 void OutputFile::addLoadCommands(ld::Internal
& state
)
2101 switch ( _options
.architecture() ) {
2102 case CPU_TYPE_X86_64
:
2103 _headersAndLoadCommandAtom
= new HeaderAndLoadCommandsAtom
<x86_64
>(_options
, state
, *this);
2104 headerAndLoadCommandsSection
= state
.addAtom(*_headersAndLoadCommandAtom
);
2107 _headersAndLoadCommandAtom
= new HeaderAndLoadCommandsAtom
<arm
>(_options
, state
, *this);
2108 headerAndLoadCommandsSection
= state
.addAtom(*_headersAndLoadCommandAtom
);
2111 _headersAndLoadCommandAtom
= new HeaderAndLoadCommandsAtom
<x86
>(_options
, state
, *this);
2112 headerAndLoadCommandsSection
= state
.addAtom(*_headersAndLoadCommandAtom
);
2115 throw "unknown architecture";
2119 uint32_t OutputFile::dylibCount()
2121 return _dylibsToLoad
.size();
2124 const ld::dylib::File
* OutputFile::dylibByOrdinal(unsigned int ordinal
)
2126 assert( ordinal
> 0 );
2127 assert( ordinal
<= _dylibsToLoad
.size() );
2128 return _dylibsToLoad
[ordinal
-1];
2131 bool OutputFile::hasOrdinalForInstallPath(const char* path
, int* ordinal
)
2133 for (std::map
<const ld::dylib::File
*, int>::const_iterator it
= _dylibToOrdinal
.begin(); it
!= _dylibToOrdinal
.end(); ++it
) {
2134 const char* installPath
= it
->first
->installPath();
2135 if ( (installPath
!= NULL
) && (strcmp(path
, installPath
) == 0) ) {
2136 *ordinal
= it
->second
;
2143 uint32_t OutputFile::dylibToOrdinal(const ld::dylib::File
* dylib
)
2145 return _dylibToOrdinal
[dylib
];
2149 void OutputFile::buildDylibOrdinalMapping(ld::Internal
& state
)
2151 // count non-public re-exported dylibs
2152 unsigned int nonPublicReExportCount
= 0;
2153 for (std::vector
<ld::dylib::File
*>::iterator it
= state
.dylibs
.begin(); it
!= state
.dylibs
.end(); ++it
) {
2154 ld::dylib::File
* aDylib
= *it
;
2155 if ( aDylib
->willBeReExported() && ! aDylib
->hasPublicInstallName() )
2156 ++nonPublicReExportCount
;
2159 // look at each dylib supplied in state
2160 bool hasReExports
= false;
2161 bool haveLazyDylibs
= false;
2162 for (std::vector
<ld::dylib::File
*>::iterator it
= state
.dylibs
.begin(); it
!= state
.dylibs
.end(); ++it
) {
2163 ld::dylib::File
* aDylib
= *it
;
2165 if ( aDylib
== state
.bundleLoader
) {
2166 _dylibToOrdinal
[aDylib
] = BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE
;
2168 else if ( this->hasOrdinalForInstallPath(aDylib
->installPath(), &ordinal
) ) {
2169 // already have a dylib with that install path, map all uses to that ordinal
2170 _dylibToOrdinal
[aDylib
] = ordinal
;
2172 else if ( aDylib
->willBeLazyLoadedDylib() ) {
2173 // all lazy dylib need to be at end of ordinals
2174 haveLazyDylibs
= true;
2176 else if ( aDylib
->willBeReExported() && ! aDylib
->hasPublicInstallName() && (nonPublicReExportCount
>= 2) ) {
2177 _dylibsToLoad
.push_back(aDylib
);
2178 _dylibToOrdinal
[aDylib
] = BIND_SPECIAL_DYLIB_SELF
;
2181 // first time this install path seen, create new ordinal
2182 _dylibsToLoad
.push_back(aDylib
);
2183 _dylibToOrdinal
[aDylib
] = _dylibsToLoad
.size();
2185 if ( aDylib
->explicitlyLinked() && aDylib
->willBeReExported() )
2186 hasReExports
= true;
2188 if ( haveLazyDylibs
) {
2189 // second pass to determine ordinals for lazy loaded dylibs
2190 for (std::vector
<ld::dylib::File
*>::iterator it
= state
.dylibs
.begin(); it
!= state
.dylibs
.end(); ++it
) {
2191 ld::dylib::File
* aDylib
= *it
;
2192 if ( aDylib
->willBeLazyLoadedDylib() ) {
2194 if ( this->hasOrdinalForInstallPath(aDylib
->installPath(), &ordinal
) ) {
2195 // already have a dylib with that install path, map all uses to that ordinal
2196 _dylibToOrdinal
[aDylib
] = ordinal
;
2199 // first time this install path seen, create new ordinal
2200 _dylibsToLoad
.push_back(aDylib
);
2201 _dylibToOrdinal
[aDylib
] = _dylibsToLoad
.size();
2206 _noReExportedDylibs
= !hasReExports
;
2207 //fprintf(stderr, "dylibs:\n");
2208 //for (std::map<const ld::dylib::File*, int>::const_iterator it = _dylibToOrdinal.begin(); it != _dylibToOrdinal.end(); ++it) {
2209 // fprintf(stderr, " %p ord=%u, install_name=%s\n",it->first, it->second, it->first->installPath());
2213 uint32_t OutputFile::lazyBindingInfoOffsetForLazyPointerAddress(uint64_t lpAddress
)
2215 return _lazyPointerAddressToInfoOffset
[lpAddress
];
2218 void OutputFile::setLazyBindingInfoOffset(uint64_t lpAddress
, uint32_t lpInfoOffset
)
2220 _lazyPointerAddressToInfoOffset
[lpAddress
] = lpInfoOffset
;
2223 int OutputFile::compressedOrdinalForAtom(const ld::Atom
* target
)
2225 // flat namespace images use zero for all ordinals
2226 if ( _options
.nameSpace() != Options::kTwoLevelNameSpace
)
2227 return BIND_SPECIAL_DYLIB_FLAT_LOOKUP
;
2229 // handle -interposable
2230 if ( target
->definition() == ld::Atom::definitionRegular
)
2231 return BIND_SPECIAL_DYLIB_SELF
;
2234 const ld::dylib::File
* dylib
= dynamic_cast<const ld::dylib::File
*>(target
->file());
2235 if ( dylib
!= NULL
)
2236 return _dylibToOrdinal
[dylib
];
2238 // handle undefined dynamic_lookup
2239 if ( _options
.undefinedTreatment() == Options::kUndefinedDynamicLookup
)
2240 return BIND_SPECIAL_DYLIB_FLAT_LOOKUP
;
2243 if ( _options
.allowedUndefined(target
->name()) )
2244 return BIND_SPECIAL_DYLIB_FLAT_LOOKUP
;
2246 throw "can't find ordinal for imported symbol";
2250 bool OutputFile::isPcRelStore(ld::Fixup::Kind kind
)
2253 case ld::Fixup::kindStoreX86BranchPCRel8
:
2254 case ld::Fixup::kindStoreX86BranchPCRel32
:
2255 case ld::Fixup::kindStoreX86PCRel8
:
2256 case ld::Fixup::kindStoreX86PCRel16
:
2257 case ld::Fixup::kindStoreX86PCRel32
:
2258 case ld::Fixup::kindStoreX86PCRel32_1
:
2259 case ld::Fixup::kindStoreX86PCRel32_2
:
2260 case ld::Fixup::kindStoreX86PCRel32_4
:
2261 case ld::Fixup::kindStoreX86PCRel32GOTLoad
:
2262 case ld::Fixup::kindStoreX86PCRel32GOTLoadNowLEA
:
2263 case ld::Fixup::kindStoreX86PCRel32GOT
:
2264 case ld::Fixup::kindStoreX86PCRel32TLVLoad
:
2265 case ld::Fixup::kindStoreX86PCRel32TLVLoadNowLEA
:
2266 case ld::Fixup::kindStoreARMBranch24
:
2267 case ld::Fixup::kindStoreThumbBranch22
:
2268 case ld::Fixup::kindStoreARMLoad12
:
2269 case ld::Fixup::kindStoreTargetAddressX86PCRel32
:
2270 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad
:
2271 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA
:
2272 case ld::Fixup::kindStoreTargetAddressARMBranch24
:
2273 case ld::Fixup::kindStoreTargetAddressThumbBranch22
:
2274 case ld::Fixup::kindStoreTargetAddressARMLoad12
:
2276 case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32
:
2277 return (_options
.outputKind() != Options::kKextBundle
);
2284 bool OutputFile::isStore(ld::Fixup::Kind kind
)
2287 case ld::Fixup::kindNone
:
2288 case ld::Fixup::kindNoneFollowOn
:
2289 case ld::Fixup::kindNoneGroupSubordinate
:
2290 case ld::Fixup::kindNoneGroupSubordinateFDE
:
2291 case ld::Fixup::kindNoneGroupSubordinateLSDA
:
2292 case ld::Fixup::kindNoneGroupSubordinatePersonality
:
2293 case ld::Fixup::kindSetTargetAddress
:
2294 case ld::Fixup::kindSubtractTargetAddress
:
2295 case ld::Fixup::kindAddAddend
:
2296 case ld::Fixup::kindSubtractAddend
:
2297 case ld::Fixup::kindSetTargetImageOffset
:
2298 case ld::Fixup::kindSetTargetSectionOffset
:
2307 bool OutputFile::setsTarget(ld::Fixup::Kind kind
)
2310 case ld::Fixup::kindSetTargetAddress
:
2311 case ld::Fixup::kindLazyTarget
:
2312 case ld::Fixup::kindStoreTargetAddressLittleEndian32
:
2313 case ld::Fixup::kindStoreTargetAddressLittleEndian64
:
2314 case ld::Fixup::kindStoreTargetAddressBigEndian32
:
2315 case ld::Fixup::kindStoreTargetAddressBigEndian64
:
2316 case ld::Fixup::kindStoreTargetAddressX86PCRel32
:
2317 case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32
:
2318 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad
:
2319 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA
:
2320 case ld::Fixup::kindStoreTargetAddressARMBranch24
:
2321 case ld::Fixup::kindStoreTargetAddressThumbBranch22
:
2322 case ld::Fixup::kindStoreTargetAddressARMLoad12
:
2324 case ld::Fixup::kindStoreX86DtraceCallSiteNop
:
2325 case ld::Fixup::kindStoreX86DtraceIsEnableSiteClear
:
2326 case ld::Fixup::kindStoreARMDtraceCallSiteNop
:
2327 case ld::Fixup::kindStoreARMDtraceIsEnableSiteClear
:
2328 case ld::Fixup::kindStoreThumbDtraceCallSiteNop
:
2329 case ld::Fixup::kindStoreThumbDtraceIsEnableSiteClear
:
2330 return (_options
.outputKind() == Options::kObjectFile
);
2337 bool OutputFile::isPointerToTarget(ld::Fixup::Kind kind
)
2340 case ld::Fixup::kindSetTargetAddress
:
2341 case ld::Fixup::kindStoreTargetAddressLittleEndian32
:
2342 case ld::Fixup::kindStoreTargetAddressLittleEndian64
:
2343 case ld::Fixup::kindStoreTargetAddressBigEndian32
:
2344 case ld::Fixup::kindStoreTargetAddressBigEndian64
:
2345 case ld::Fixup::kindLazyTarget
:
2352 bool OutputFile::isPointerFromTarget(ld::Fixup::Kind kind
)
2355 case ld::Fixup::kindSubtractTargetAddress
:
2364 uint64_t OutputFile::lookBackAddend(ld::Fixup::iterator fit
)
2366 uint64_t addend
= 0;
2367 switch ( fit
->clusterSize
) {
2368 case ld::Fixup::k1of1
:
2369 case ld::Fixup::k1of2
:
2370 case ld::Fixup::k2of2
:
2372 case ld::Fixup::k2of3
:
2374 switch ( fit
->kind
) {
2375 case ld::Fixup::kindAddAddend
:
2376 addend
+= fit
->u
.addend
;
2378 case ld::Fixup::kindSubtractAddend
:
2379 addend
-= fit
->u
.addend
;
2382 throw "unexpected fixup kind for binding";
2385 case ld::Fixup::k1of3
:
2387 switch ( fit
->kind
) {
2388 case ld::Fixup::kindAddAddend
:
2389 addend
+= fit
->u
.addend
;
2391 case ld::Fixup::kindSubtractAddend
:
2392 addend
-= fit
->u
.addend
;
2395 throw "unexpected fixup kind for binding";
2399 throw "unexpected fixup cluster size for binding";
2408 void OutputFile::generateLinkEditInfo(ld::Internal
& state
)
2410 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
2411 ld::Internal::FinalSection
* sect
= *sit
;
2412 bool objc1ClassRefSection
= ( (sect
->type() == ld::Section::typeCStringPointer
)
2413 && (strcmp(sect
->sectionName(), "__cls_refs") == 0)
2414 && (strcmp(sect
->segmentName(), "__OBJC") == 0) );
2415 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
2416 const ld::Atom
* atom
= *ait
;
2418 // Record regular atoms that override a dylib's weak definitions
2419 if ( (atom
->scope() == ld::Atom::scopeGlobal
) && atom
->overridesDylibsWeakDef() ) {
2420 if ( _options
.makeCompressedDyldInfo() ) {
2421 uint8_t wtype
= BIND_TYPE_OVERRIDE_OF_WEAKDEF_IN_DYLIB
;
2422 bool nonWeakDef
= (atom
->combine() == ld::Atom::combineNever
);
2423 _weakBindingInfo
.push_back(BindingInfo(wtype
, atom
->name(), nonWeakDef
, atom
->finalAddress(), 0));
2425 this->overridesWeakExternalSymbols
= true;
2426 if ( _options
.warnWeakExports() )
2427 warning("overrides weak external symbol: %s", atom
->name());
2430 ld::Fixup
* fixupWithTarget
= NULL
;
2431 ld::Fixup
* fixupWithMinusTarget
= NULL
;
2432 ld::Fixup
* fixupWithStore
= NULL
;
2433 const ld::Atom
* target
= NULL
;
2434 const ld::Atom
* minusTarget
= NULL
;
2435 uint64_t targetAddend
= 0;
2436 uint64_t minusTargetAddend
= 0;
2437 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(); fit
!= atom
->fixupsEnd(); ++fit
) {
2438 if ( fit
->firstInCluster() ) {
2439 fixupWithTarget
= NULL
;
2440 fixupWithMinusTarget
= NULL
;
2441 fixupWithStore
= NULL
;
2445 minusTargetAddend
= 0;
2447 if ( this->setsTarget(fit
->kind
) ) {
2448 switch ( fit
->binding
) {
2449 case ld::Fixup::bindingNone
:
2450 case ld::Fixup::bindingByNameUnbound
:
2452 case ld::Fixup::bindingByContentBound
:
2453 case ld::Fixup::bindingDirectlyBound
:
2454 fixupWithTarget
= fit
;
2455 target
= fit
->u
.target
;
2457 case ld::Fixup::bindingsIndirectlyBound
:
2458 fixupWithTarget
= fit
;
2459 target
= state
.indirectBindingTable
[fit
->u
.bindingIndex
];
2462 assert(target
!= NULL
);
2464 switch ( fit
->kind
) {
2465 case ld::Fixup::kindAddAddend
:
2466 targetAddend
= fit
->u
.addend
;
2468 case ld::Fixup::kindSubtractAddend
:
2469 minusTargetAddend
= fit
->u
.addend
;
2471 case ld::Fixup::kindSubtractTargetAddress
:
2472 switch ( fit
->binding
) {
2473 case ld::Fixup::bindingNone
:
2474 case ld::Fixup::bindingByNameUnbound
:
2476 case ld::Fixup::bindingByContentBound
:
2477 case ld::Fixup::bindingDirectlyBound
:
2478 fixupWithMinusTarget
= fit
;
2479 minusTarget
= fit
->u
.target
;
2481 case ld::Fixup::bindingsIndirectlyBound
:
2482 fixupWithMinusTarget
= fit
;
2483 minusTarget
= state
.indirectBindingTable
[fit
->u
.bindingIndex
];
2486 assert(minusTarget
!= NULL
);
2491 if ( this->isStore(fit
->kind
) ) {
2492 fixupWithStore
= fit
;
2494 if ( fit
->lastInCluster() ) {
2495 if ( (fixupWithStore
!= NULL
) && (target
!= NULL
) ) {
2496 if ( _options
.outputKind() == Options::kObjectFile
) {
2497 this->addSectionRelocs(state
, sect
, atom
, fixupWithTarget
, fixupWithMinusTarget
, fixupWithStore
,
2498 target
, minusTarget
, targetAddend
, minusTargetAddend
);
2501 if ( _options
.makeCompressedDyldInfo() ) {
2502 this->addDyldInfo(state
, sect
, atom
, fixupWithTarget
, fixupWithMinusTarget
, fixupWithStore
,
2503 target
, minusTarget
, targetAddend
, minusTargetAddend
);
2506 this->addClassicRelocs(state
, sect
, atom
, fixupWithTarget
, fixupWithMinusTarget
, fixupWithStore
,
2507 target
, minusTarget
, targetAddend
, minusTargetAddend
);
2511 else if ( objc1ClassRefSection
&& (target
!= NULL
) && (fixupWithStore
== NULL
) ) {
2512 // check for class refs to lazy loaded dylibs
2513 const ld::dylib::File
* dylib
= dynamic_cast<const ld::dylib::File
*>(target
->file());
2514 if ( (dylib
!= NULL
) && dylib
->willBeLazyLoadedDylib() )
2515 throwf("illegal class reference to %s in lazy loaded dylib %s", target
->name(), dylib
->path());
2524 void OutputFile::noteTextReloc(const ld::Atom
* atom
, const ld::Atom
* target
)
2526 if ( (atom
->contentType() == ld::Atom::typeStub
) || (atom
->contentType() == ld::Atom::typeStubHelper
) ) {
2527 // silently let stubs (synthesized by linker) use text relocs
2529 else if ( _options
.allowTextRelocs() ) {
2530 if ( _options
.warnAboutTextRelocs() )
2531 warning("text reloc in %s to %s", atom
->name(), target
->name());
2533 else if ( _options
.positionIndependentExecutable() && ((_options
.iOSVersionMin() >= ld::iOS_4_3
) || (_options
.macosxVersionMin() >= ld::mac10_7
)) ) {
2534 if ( ! this->pieDisabled
) {
2535 warning("PIE disabled. Absolute addressing (perhaps -mdynamic-no-pic) not allowed in code signed PIE, "
2536 "but used in %s from %s. "
2537 "To fix this warning, don't compile with -mdynamic-no-pic or link with -Wl,-no_pie",
2538 atom
->name(), atom
->file()->path());
2540 this->pieDisabled
= true;
2542 else if ( (target
->scope() == ld::Atom::scopeGlobal
) && (target
->combine() == ld::Atom::combineByName
) ) {
2543 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());
2546 throwf("illegal text-relocation to %s in %s from %s in %s", target
->name(), target
->file()->path(), atom
->name(), atom
->file()->path());
2550 void OutputFile::addDyldInfo(ld::Internal
& state
, ld::Internal::FinalSection
* sect
, const ld::Atom
* atom
,
2551 ld::Fixup
* fixupWithTarget
, ld::Fixup
* fixupWithMinusTarget
, ld::Fixup
* fixupWithStore
,
2552 const ld::Atom
* target
, const ld::Atom
* minusTarget
,
2553 uint64_t targetAddend
, uint64_t minusTargetAddend
)
2555 if ( sect
->isSectionHidden() )
2558 // no need to rebase or bind PCRel stores
2559 if ( this->isPcRelStore(fixupWithStore
->kind
) ) {
2560 // as long as target is in same linkage unit
2561 if ( (target
== NULL
) || (target
->definition() != ld::Atom::definitionProxy
) ) {
2562 // make sure target is not global and weak
2563 if ( (target
->scope() == ld::Atom::scopeGlobal
) && (target
->combine() == ld::Atom::combineByName
) && (target
->definition() == ld::Atom::definitionRegular
)) {
2564 if ( (atom
->section().type() == ld::Section::typeCFI
)
2565 || (atom
->section().type() == ld::Section::typeDtraceDOF
)
2566 || (atom
->section().type() == ld::Section::typeUnwindInfo
) ) {
2567 // ok for __eh_frame and __uwind_info to use pointer diffs to global weak symbols
2570 // Have direct reference to weak-global. This should be an indrect reference
2571 warning("direct access in %s to global weak symbol %s means the weak symbol cannot be overridden at runtime. "
2572 "This was likely caused by different translation units being compiled with different visibility settings.",
2573 atom
->name(), target
->name());
2579 // no need to rebase or bind PIC internal pointer diff
2580 if ( minusTarget
!= NULL
) {
2581 // with pointer diffs, both need to be in same linkage unit
2582 assert(minusTarget
->definition() != ld::Atom::definitionProxy
);
2583 assert(target
!= NULL
);
2584 assert(target
->definition() != ld::Atom::definitionProxy
);
2585 if ( target
== minusTarget
) {
2586 // This is a compile time constant and could have been optimized away by compiler
2590 // check if target of pointer-diff is global and weak
2591 if ( (target
->scope() == ld::Atom::scopeGlobal
) && (target
->combine() == ld::Atom::combineByName
) && (target
->definition() == ld::Atom::definitionRegular
) ) {
2592 if ( (atom
->section().type() == ld::Section::typeCFI
)
2593 || (atom
->section().type() == ld::Section::typeDtraceDOF
)
2594 || (atom
->section().type() == ld::Section::typeUnwindInfo
) ) {
2595 // ok for __eh_frame and __uwind_info to use pointer diffs to global weak symbols
2598 // Have direct reference to weak-global. This should be an indrect reference
2599 warning("direct access in %s to global weak symbol %s means the weak symbol cannot be overridden at runtime. "
2600 "This was likely caused by different translation units being compiled with different visibility settings.",
2601 atom
->name(), target
->name());
2606 // no need to rebase or bind an atom's references to itself if the output is not slidable
2607 if ( (atom
== target
) && !_options
.outputSlidable() )
2610 // cluster has no target, so needs no rebasing or binding
2611 if ( target
== NULL
)
2614 bool inReadOnlySeg
= ( strcmp(sect
->segmentName(), "__TEXT") == 0 );
2615 bool needsRebase
= false;
2616 bool needsBinding
= false;
2617 bool needsLazyBinding
= false;
2618 bool needsWeakBinding
= false;
2620 uint8_t rebaseType
= REBASE_TYPE_POINTER
;
2621 uint8_t type
= BIND_TYPE_POINTER
;
2622 const ld::dylib::File
* dylib
= dynamic_cast<const ld::dylib::File
*>(target
->file());
2623 bool weak_import
= ((dylib
!= NULL
) && (fixupWithTarget
->weakImport
|| dylib
->forcedWeakLinked()));
2624 uint64_t address
= atom
->finalAddress() + fixupWithTarget
->offsetInAtom
;
2625 uint64_t addend
= targetAddend
- minusTargetAddend
;
2627 // special case lazy pointers
2628 if ( fixupWithTarget
->kind
== ld::Fixup::kindLazyTarget
) {
2629 assert(fixupWithTarget
->u
.target
== target
);
2630 assert(addend
== 0);
2631 // lazy dylib lazy pointers do not have any dyld info
2632 if ( atom
->section().type() == ld::Section::typeLazyDylibPointer
)
2634 // lazy binding to weak definitions are done differently
2635 // they are directly bound to target, then have a weak bind in case of a collision
2636 if ( target
->combine() == ld::Atom::combineByName
) {
2637 if ( target
->definition() == ld::Atom::definitionProxy
) {
2638 // weak def exported from another dylib
2639 // must non-lazy bind to it plus have weak binding info in case of collision
2640 needsBinding
= true;
2641 needsWeakBinding
= true;
2644 // weak def in this linkage unit.
2645 // just rebase, plus have weak binding info in case of collision
2646 // this will be done by other cluster on lazy pointer atom
2649 else if ( (target
->contentType() == ld::Atom::typeResolver
) && (target
->scope() != ld::Atom::scopeGlobal
) ) {
2650 // <rdar://problem/8553647> Hidden resolver functions should not have lazy binding info
2651 needsLazyBinding
= false;
2654 // normal case of a pointer to non-weak-def symbol, so can lazily bind
2655 needsLazyBinding
= true;
2659 // everything except lazy pointers
2660 switch ( target
->definition() ) {
2661 case ld::Atom::definitionProxy
:
2662 if ( (dylib
!= NULL
) && dylib
->willBeLazyLoadedDylib() )
2663 throwf("illegal data reference to %s in lazy loaded dylib %s", target
->name(), dylib
->path());
2664 if ( target
->contentType() == ld::Atom::typeTLV
) {
2665 if ( sect
->type() != ld::Section::typeTLVPointers
)
2666 throwf("illegal data reference in %s to thread local variable %s in dylib %s",
2667 atom
->name(), target
->name(), dylib
->path());
2669 if ( inReadOnlySeg
)
2670 type
= BIND_TYPE_TEXT_ABSOLUTE32
;
2671 needsBinding
= true;
2672 if ( target
->combine() == ld::Atom::combineByName
)
2673 needsWeakBinding
= true;
2675 case ld::Atom::definitionRegular
:
2676 case ld::Atom::definitionTentative
:
2677 // only slideable images need rebasing info
2678 if ( _options
.outputSlidable() ) {
2681 // references to internal symbol never need binding
2682 if ( target
->scope() != ld::Atom::scopeGlobal
)
2684 // reference to global weak def needs weak binding
2685 if ( (target
->combine() == ld::Atom::combineByName
) && (target
->definition() == ld::Atom::definitionRegular
) )
2686 needsWeakBinding
= true;
2687 else if ( _options
.outputKind() == Options::kDynamicExecutable
) {
2688 // in main executables, the only way regular symbols are indirected is if -interposable is used
2689 if ( _options
.interposable(target
->name()) ) {
2690 needsRebase
= false;
2691 needsBinding
= true;
2695 // for flat-namespace or interposable two-level-namespace
2696 // all references to exported symbols get indirected
2697 if ( (_options
.nameSpace() != Options::kTwoLevelNameSpace
) || _options
.interposable(target
->name()) ) {
2698 // <rdar://problem/5254468> no external relocs for flat objc classes
2699 if ( strncmp(target
->name(), ".objc_class_", 12) == 0 )
2701 // no rebase info for references to global symbols that will have binding info
2702 needsRebase
= false;
2703 needsBinding
= true;
2707 case ld::Atom::definitionAbsolute
:
2712 // record dyld info for this cluster
2713 if ( needsRebase
) {
2714 if ( inReadOnlySeg
) {
2715 noteTextReloc(atom
, target
);
2716 sect
->hasLocalRelocs
= true; // so dyld knows to change permissions on __TEXT segment
2717 rebaseType
= REBASE_TYPE_TEXT_ABSOLUTE32
;
2719 _rebaseInfo
.push_back(RebaseInfo(rebaseType
, address
));
2721 if ( needsBinding
) {
2722 if ( inReadOnlySeg
) {
2723 noteTextReloc(atom
, target
);
2724 sect
->hasExternalRelocs
= true; // so dyld knows to change permissions on __TEXT segment
2726 _bindingInfo
.push_back(BindingInfo(type
, this->compressedOrdinalForAtom(target
), target
->name(), weak_import
, address
, addend
));
2728 if ( needsLazyBinding
) {
2729 if ( _options
.bindAtLoad() )
2730 _bindingInfo
.push_back(BindingInfo(type
, this->compressedOrdinalForAtom(target
), target
->name(), weak_import
, address
, addend
));
2732 _lazyBindingInfo
.push_back(BindingInfo(type
, this->compressedOrdinalForAtom(target
), target
->name(), weak_import
, address
, addend
));
2734 if ( needsWeakBinding
)
2735 _weakBindingInfo
.push_back(BindingInfo(type
, 0, target
->name(), false, address
, addend
));
2739 void OutputFile::addClassicRelocs(ld::Internal
& state
, ld::Internal::FinalSection
* sect
, const ld::Atom
* atom
,
2740 ld::Fixup
* fixupWithTarget
, ld::Fixup
* fixupWithMinusTarget
, ld::Fixup
* fixupWithStore
,
2741 const ld::Atom
* target
, const ld::Atom
* minusTarget
,
2742 uint64_t targetAddend
, uint64_t minusTargetAddend
)
2744 if ( sect
->isSectionHidden() )
2747 // non-lazy-pointer section is encoded in indirect symbol table - not using relocations
2748 if ( (sect
->type() == ld::Section::typeNonLazyPointer
) && (_options
.outputKind() != Options::kKextBundle
) ) {
2749 assert(target
!= NULL
);
2750 assert(fixupWithTarget
!= NULL
);
2754 // no need to rebase or bind PCRel stores
2755 if ( this->isPcRelStore(fixupWithStore
->kind
) ) {
2756 // as long as target is in same linkage unit
2757 if ( (target
== NULL
) || (target
->definition() != ld::Atom::definitionProxy
) )
2761 // no need to rebase or bind PIC internal pointer diff
2762 if ( minusTarget
!= NULL
) {
2763 // with pointer diffs, both need to be in same linkage unit
2764 assert(minusTarget
->definition() != ld::Atom::definitionProxy
);
2765 assert(target
!= NULL
);
2766 assert(target
->definition() != ld::Atom::definitionProxy
);
2767 // make sure target is not global and weak
2768 if ( (target
->scope() == ld::Atom::scopeGlobal
) && (target
->combine() == ld::Atom::combineByName
)
2769 && (atom
->section().type() != ld::Section::typeCFI
)
2770 && (atom
->section().type() != ld::Section::typeDtraceDOF
)
2771 && (atom
->section().type() != ld::Section::typeUnwindInfo
)
2772 && (minusTarget
!= target
) ) {
2773 // ok for __eh_frame and __uwind_info to use pointer diffs to global weak symbols
2774 throwf("bad codegen, pointer diff in %s to global weak symbol %s", atom
->name(), target
->name());
2779 // cluster has no target, so needs no rebasing or binding
2780 if ( target
== NULL
)
2783 assert(_localRelocsAtom
!= NULL
);
2784 uint64_t relocAddress
= atom
->finalAddress() + fixupWithTarget
->offsetInAtom
- _localRelocsAtom
->relocBaseAddress(state
);
2786 bool inReadOnlySeg
= ( strcmp(sect
->segmentName(), "__TEXT") == 0 );
2787 bool needsLocalReloc
= false;
2788 bool needsExternReloc
= false;
2790 switch ( fixupWithStore
->kind
) {
2791 case ld::Fixup::kindLazyTarget
:
2792 // lazy pointers don't need relocs
2794 case ld::Fixup::kindStoreLittleEndian32
:
2795 case ld::Fixup::kindStoreLittleEndian64
:
2796 case ld::Fixup::kindStoreBigEndian32
:
2797 case ld::Fixup::kindStoreBigEndian64
:
2798 case ld::Fixup::kindStoreTargetAddressLittleEndian32
:
2799 case ld::Fixup::kindStoreTargetAddressLittleEndian64
:
2800 case ld::Fixup::kindStoreTargetAddressBigEndian32
:
2801 case ld::Fixup::kindStoreTargetAddressBigEndian64
:
2803 switch ( target
->definition() ) {
2804 case ld::Atom::definitionProxy
:
2805 needsExternReloc
= true;
2807 case ld::Atom::definitionRegular
:
2808 case ld::Atom::definitionTentative
:
2809 // only slideable images need local relocs
2810 if ( _options
.outputSlidable() )
2811 needsLocalReloc
= true;
2812 // references to internal symbol never need binding
2813 if ( target
->scope() != ld::Atom::scopeGlobal
)
2815 // reference to global weak def needs weak binding in dynamic images
2816 if ( (target
->combine() == ld::Atom::combineByName
)
2817 && (target
->definition() == ld::Atom::definitionRegular
)
2818 && (_options
.outputKind() != Options::kStaticExecutable
) ) {
2819 needsExternReloc
= true;
2821 else if ( _options
.outputKind() == Options::kDynamicExecutable
) {
2822 // in main executables, the only way regular symbols are indirected is if -interposable is used
2823 if ( _options
.interposable(target
->name()) )
2824 needsExternReloc
= true;
2827 // for flat-namespace or interposable two-level-namespace
2828 // all references to exported symbols get indirected
2829 if ( (_options
.nameSpace() != Options::kTwoLevelNameSpace
) || _options
.interposable(target
->name()) ) {
2830 // <rdar://problem/5254468> no external relocs for flat objc classes
2831 if ( strncmp(target
->name(), ".objc_class_", 12) == 0 )
2833 // no rebase info for references to global symbols that will have binding info
2834 needsExternReloc
= true;
2837 if ( needsExternReloc
)
2838 needsLocalReloc
= false;
2840 case ld::Atom::definitionAbsolute
:
2843 if ( needsExternReloc
) {
2844 if ( inReadOnlySeg
)
2845 noteTextReloc(atom
, target
);
2846 const ld::dylib::File
* dylib
= dynamic_cast<const ld::dylib::File
*>(target
->file());
2847 if ( (dylib
!= NULL
) && dylib
->willBeLazyLoadedDylib() )
2848 throwf("illegal data reference to %s in lazy loaded dylib %s", target
->name(), dylib
->path());
2849 _externalRelocsAtom
->addExternalPointerReloc(relocAddress
, target
);
2850 sect
->hasExternalRelocs
= true;
2851 fixupWithTarget
->contentAddendOnly
= true;
2853 else if ( needsLocalReloc
) {
2854 assert(target
!= NULL
);
2855 if ( inReadOnlySeg
)
2856 noteTextReloc(atom
, target
);
2857 _localRelocsAtom
->addPointerReloc(relocAddress
, target
->machoSection());
2858 sect
->hasLocalRelocs
= true;
2861 case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32
:
2862 if ( _options
.outputKind() == Options::kKextBundle
) {
2863 assert(target
!= NULL
);
2864 if ( target
->definition() == ld::Atom::definitionProxy
) {
2865 _externalRelocsAtom
->addExternalCallSiteReloc(relocAddress
, target
);
2866 fixupWithStore
->contentAddendOnly
= true;
2871 case ld::Fixup::kindStoreARMLow16
:
2872 case ld::Fixup::kindStoreThumbLow16
:
2873 // no way to encode rebasing of binding for these instructions
2874 if ( _options
.outputSlidable() || (target
->definition() == ld::Atom::definitionProxy
) )
2875 throwf("no supported runtime lo16 relocation in %s from %s to %s", atom
->name(), atom
->file()->path(), target
->name());
2878 case ld::Fixup::kindStoreARMHigh16
:
2879 case ld::Fixup::kindStoreThumbHigh16
:
2880 // no way to encode rebasing of binding for these instructions
2881 if ( _options
.outputSlidable() || (target
->definition() == ld::Atom::definitionProxy
) )
2882 throwf("no supported runtime hi16 relocation in %s from %s to %s", atom
->name(), atom
->file()->path(), target
->name());
2891 bool OutputFile::useExternalSectionReloc(const ld::Atom
* atom
, const ld::Atom
* target
, ld::Fixup
* fixupWithTarget
)
2893 if ( _options
.architecture() == CPU_TYPE_X86_64
) {
2894 // x86_64 uses external relocations for everthing that has a symbol
2895 return ( target
->symbolTableInclusion() != ld::Atom::symbolTableNotIn
);
2898 // <rdar://problem/9513487> support arm branch interworking in -r mode
2899 if ( (_options
.architecture() == CPU_TYPE_ARM
) && (_options
.outputKind() == Options::kObjectFile
) ) {
2900 if ( atom
->isThumb() != target
->isThumb() ) {
2901 switch ( fixupWithTarget
->kind
) {
2902 // have branch that switches mode, then might be 'b' not 'bl'
2903 // Force external relocation, since no way to do local reloc for 'b'
2904 case ld::Fixup::kindStoreTargetAddressThumbBranch22
:
2905 case ld::Fixup::kindStoreTargetAddressARMBranch24
:
2913 // most architectures use external relocations only for references
2914 // to a symbol in another translation unit or for references to "weak symbols" or tentative definitions
2915 assert(target
!= NULL
);
2916 if ( target
->definition() == ld::Atom::definitionProxy
)
2918 if ( (target
->definition() == ld::Atom::definitionTentative
) && ! _options
.makeTentativeDefinitionsReal() )
2920 if ( target
->scope() != ld::Atom::scopeGlobal
)
2922 if ( (target
->combine() == ld::Atom::combineByName
) && (target
->definition() == ld::Atom::definitionRegular
) )
2930 void OutputFile::addSectionRelocs(ld::Internal
& state
, ld::Internal::FinalSection
* sect
, const ld::Atom
* atom
,
2931 ld::Fixup
* fixupWithTarget
, ld::Fixup
* fixupWithMinusTarget
, ld::Fixup
* fixupWithStore
,
2932 const ld::Atom
* target
, const ld::Atom
* minusTarget
,
2933 uint64_t targetAddend
, uint64_t minusTargetAddend
)
2935 if ( sect
->isSectionHidden() )
2938 // in -r mode where there will be no labels on __eh_frame section, there is no need for relocations
2939 if ( (sect
->type() == ld::Section::typeCFI
) && _options
.removeEHLabels() )
2942 // non-lazy-pointer section is encoded in indirect symbol table - not using relocations
2943 if ( sect
->type() == ld::Section::typeNonLazyPointer
)
2946 // tentative defs don't have any relocations
2947 if ( sect
->type() == ld::Section::typeTentativeDefs
)
2950 assert(target
!= NULL
);
2951 assert(fixupWithTarget
!= NULL
);
2952 bool targetUsesExternalReloc
= this->useExternalSectionReloc(atom
, target
, fixupWithTarget
);
2953 bool minusTargetUsesExternalReloc
= (minusTarget
!= NULL
) && this->useExternalSectionReloc(atom
, minusTarget
, fixupWithMinusTarget
);
2955 // in x86_64 .o files an external reloc means the content contains just the addend
2956 if ( _options
.architecture() == CPU_TYPE_X86_64
) {
2957 if ( targetUsesExternalReloc
) {
2958 fixupWithTarget
->contentAddendOnly
= true;
2959 fixupWithStore
->contentAddendOnly
= true;
2961 if ( minusTargetUsesExternalReloc
)
2962 fixupWithMinusTarget
->contentAddendOnly
= true;
2965 // for other archs, content is addend only with (non pc-rel) pointers
2966 // pc-rel instructions are funny. If the target is _foo+8 and _foo is
2967 // external, then the pc-rel instruction *evalutates* to the address 8.
2968 if ( targetUsesExternalReloc
) {
2969 if ( isPcRelStore(fixupWithStore
->kind
) ) {
2970 fixupWithTarget
->contentDetlaToAddendOnly
= true;
2971 fixupWithStore
->contentDetlaToAddendOnly
= true;
2973 else if ( minusTarget
== NULL
){
2974 fixupWithTarget
->contentAddendOnly
= true;
2975 fixupWithStore
->contentAddendOnly
= true;
2980 if ( fixupWithStore
!= NULL
) {
2981 _sectionsRelocationsAtom
->addSectionReloc(sect
, fixupWithStore
->kind
, atom
, fixupWithStore
->offsetInAtom
,
2982 targetUsesExternalReloc
, minusTargetUsesExternalReloc
,
2983 target
, targetAddend
, minusTarget
, minusTargetAddend
);
2989 void OutputFile::makeSplitSegInfo(ld::Internal
& state
)
2991 if ( !_options
.sharedRegionEligible() )
2994 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
2995 ld::Internal::FinalSection
* sect
= *sit
;
2996 if ( sect
->isSectionHidden() )
2998 if ( strcmp(sect
->segmentName(), "__TEXT") != 0 )
3000 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
3001 const ld::Atom
* atom
= *ait
;
3002 const ld::Atom
* target
= NULL
;
3003 const ld::Atom
* fromTarget
= NULL
;
3004 uint64_t accumulator
= 0;
3006 bool hadSubtract
= false;
3007 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(), end
=atom
->fixupsEnd(); fit
!= end
; ++fit
) {
3008 if ( fit
->firstInCluster() )
3010 if ( this->setsTarget(fit
->kind
) ) {
3011 accumulator
= addressOf(state
, fit
, &target
);
3012 thumbTarget
= targetIsThumb(state
, fit
);
3016 switch ( fit
->kind
) {
3017 case ld::Fixup::kindSubtractTargetAddress
:
3018 accumulator
-= addressOf(state
, fit
, &fromTarget
);
3021 case ld::Fixup::kindAddAddend
:
3022 accumulator
+= fit
->u
.addend
;
3024 case ld::Fixup::kindSubtractAddend
:
3025 accumulator
-= fit
->u
.addend
;
3027 case ld::Fixup::kindStoreBigEndian32
:
3028 case ld::Fixup::kindStoreLittleEndian32
:
3029 case ld::Fixup::kindStoreLittleEndian64
:
3030 case ld::Fixup::kindStoreTargetAddressLittleEndian32
:
3031 case ld::Fixup::kindStoreTargetAddressLittleEndian64
:
3032 // if no subtract, then this is an absolute pointer which means
3033 // there is also a text reloc which update_dyld_shared_cache will use.
3034 if ( ! hadSubtract
)
3037 case ld::Fixup::kindStoreX86PCRel32
:
3038 case ld::Fixup::kindStoreX86PCRel32_1
:
3039 case ld::Fixup::kindStoreX86PCRel32_2
:
3040 case ld::Fixup::kindStoreX86PCRel32_4
:
3041 case ld::Fixup::kindStoreX86PCRel32GOTLoad
:
3042 case ld::Fixup::kindStoreX86PCRel32GOTLoadNowLEA
:
3043 case ld::Fixup::kindStoreX86PCRel32GOT
:
3044 case ld::Fixup::kindStoreTargetAddressX86PCRel32
:
3045 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad
:
3046 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA
:
3047 case ld::Fixup::kindStoreARMLow16
:
3048 case ld::Fixup::kindStoreThumbLow16
:
3049 assert(target
!= NULL
);
3050 if ( strcmp(sect
->segmentName(), target
->section().segmentName()) != 0 ) {
3051 _splitSegInfos
.push_back(SplitSegInfoEntry(atom
->finalAddress()+fit
->offsetInAtom
,fit
->kind
));
3054 case ld::Fixup::kindStoreARMHigh16
:
3055 case ld::Fixup::kindStoreThumbHigh16
:
3056 assert(target
!= NULL
);
3057 if ( strcmp(sect
->segmentName(), target
->section().segmentName()) != 0 ) {
3058 // hi16 needs to know upper 4-bits of low16 to compute carry
3059 uint32_t extra
= (accumulator
>> 12) & 0xF;
3060 _splitSegInfos
.push_back(SplitSegInfoEntry(atom
->finalAddress()+fit
->offsetInAtom
,fit
->kind
, extra
));
3063 case ld::Fixup::kindSetTargetImageOffset
:
3064 accumulator
= addressOf(state
, fit
, &target
);
3065 assert(target
!= NULL
);
3077 void OutputFile::writeMapFile(ld::Internal
& state
)
3079 if ( _options
.generatedMapPath() != NULL
) {
3080 FILE* mapFile
= fopen(_options
.generatedMapPath(), "w");
3081 if ( mapFile
!= NULL
) {
3082 // write output path
3083 fprintf(mapFile
, "# Path: %s\n", _options
.outputFilePath());
3084 // write output architecure
3085 fprintf(mapFile
, "# Arch: %s\n", _options
.architectureName());
3087 //if ( fUUIDAtom != NULL ) {
3088 // const uint8_t* uuid = fUUIDAtom->getUUID();
3089 // fprintf(mapFile, "# UUID: %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X \n",
3090 // uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
3091 // uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
3093 // write table of object files
3094 std::map
<const ld::File
*, uint32_t> readerToOrdinal
;
3095 std::map
<uint32_t, const ld::File
*> ordinalToReader
;
3096 std::map
<const ld::File
*, uint32_t> readerToFileOrdinal
;
3097 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
3098 ld::Internal::FinalSection
* sect
= *sit
;
3099 if ( sect
->isSectionHidden() )
3101 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
3102 const ld::Atom
* atom
= *ait
;
3103 const ld::File
* reader
= atom
->file();
3104 if ( reader
== NULL
)
3106 uint32_t readerOrdinal
= reader
->ordinal();
3107 std::map
<const ld::File
*, uint32_t>::iterator pos
= readerToOrdinal
.find(reader
);
3108 if ( pos
== readerToOrdinal
.end() ) {
3109 readerToOrdinal
[reader
] = readerOrdinal
;
3110 ordinalToReader
[readerOrdinal
] = reader
;
3114 fprintf(mapFile
, "# Object files:\n");
3115 fprintf(mapFile
, "[%3u] %s\n", 0, "linker synthesized");
3116 uint32_t fileIndex
= 0;
3117 readerToFileOrdinal
[NULL
] = fileIndex
++;
3118 for(std::map
<uint32_t, const ld::File
*>::iterator it
= ordinalToReader
.begin(); it
!= ordinalToReader
.end(); ++it
) {
3119 if ( it
->first
!= 0 ) {
3120 fprintf(mapFile
, "[%3u] %s\n", fileIndex
, it
->second
->path());
3121 readerToFileOrdinal
[it
->second
] = fileIndex
++;
3124 // write table of sections
3125 fprintf(mapFile
, "# Sections:\n");
3126 fprintf(mapFile
, "# Address\tSize \tSegment\tSection\n");
3127 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
3128 ld::Internal::FinalSection
* sect
= *sit
;
3129 if ( sect
->isSectionHidden() )
3131 fprintf(mapFile
, "0x%08llX\t0x%08llX\t%s\t%s\n", sect
->address
, sect
->size
,
3132 sect
->segmentName(), sect
->sectionName());
3134 // write table of symbols
3135 fprintf(mapFile
, "# Symbols:\n");
3136 fprintf(mapFile
, "# Address\tSize \tFile Name\n");
3137 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
3138 ld::Internal::FinalSection
* sect
= *sit
;
3139 if ( sect
->isSectionHidden() )
3141 //bool isCstring = (sect->type() == ld::Section::typeCString);
3142 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
3144 const ld::Atom
* atom
= *ait
;
3145 const char* name
= atom
->name();
3146 if ( atom
->contentType() == ld::Atom::typeCString
) {
3147 strcpy(buffer
, "literal string: ");
3148 strlcat(buffer
, (char*)atom
->rawContentPointer(), 4096);
3151 else if ( (atom
->contentType() == ld::Atom::typeCFI
) && (strcmp(name
, "FDE") == 0) ) {
3152 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(); fit
!= atom
->fixupsEnd(); ++fit
) {
3153 if ( (fit
->kind
== ld::Fixup::kindSetTargetAddress
) && (fit
->clusterSize
== ld::Fixup::k1of4
) ) {
3154 assert(fit
->binding
== ld::Fixup::bindingDirectlyBound
);
3155 if ( fit
->u
.target
->section().type() == ld::Section::typeCode
) {
3156 strcpy(buffer
, "FDE for: ");
3157 strlcat(buffer
, fit
->u
.target
->name(), 4096);
3163 else if ( atom
->contentType() == ld::Atom::typeNonLazyPointer
) {
3164 strcpy(buffer
, "non-lazy-pointer");
3165 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(); fit
!= atom
->fixupsEnd(); ++fit
) {
3166 if ( fit
->binding
== ld::Fixup::bindingsIndirectlyBound
) {
3167 strcpy(buffer
, "non-lazy-pointer-to: ");
3168 strlcat(buffer
, state
.indirectBindingTable
[fit
->u
.bindingIndex
]->name(), 4096);
3171 else if ( fit
->binding
== ld::Fixup::bindingDirectlyBound
) {
3172 strcpy(buffer
, "non-lazy-pointer-to-local: ");
3173 strlcat(buffer
, fit
->u
.target
->name(), 4096);
3179 fprintf(mapFile
, "0x%08llX\t0x%08llX\t[%3u] %s\n", atom
->finalAddress(), atom
->size(),
3180 readerToFileOrdinal
[atom
->file()], name
);
3186 warning("could not write map file: %s\n", _options
.generatedMapPath());
3192 // used to sort atoms with debug notes
3193 class DebugNoteSorter
3196 bool operator()(const ld::Atom
* left
, const ld::Atom
* right
) const
3198 // first sort by reader
3199 uint32_t leftFileOrdinal
= left
->file()->ordinal();
3200 uint32_t rightFileOrdinal
= right
->file()->ordinal();
3201 if ( leftFileOrdinal
!= rightFileOrdinal
)
3202 return (leftFileOrdinal
< rightFileOrdinal
);
3204 // then sort by atom objectAddress
3205 uint64_t leftAddr
= left
->finalAddress();
3206 uint64_t rightAddr
= right
->finalAddress();
3207 return leftAddr
< rightAddr
;
3215 bool operator()(const char* left
, const char* right
) const { return (strcmp(left
, right
) == 0); }
3218 const char* OutputFile::assureFullPath(const char* path
)
3220 if ( path
[0] == '/' )
3222 char cwdbuff
[MAXPATHLEN
];
3223 if ( getcwd(cwdbuff
, MAXPATHLEN
) != NULL
) {
3225 asprintf(&result
, "%s/%s", cwdbuff
, path
);
3226 if ( result
!= NULL
)
3232 void OutputFile::synthesizeDebugNotes(ld::Internal
& state
)
3234 // -S means don't synthesize debug map
3235 if ( _options
.debugInfoStripping() == Options::kDebugInfoNone
)
3237 // make a vector of atoms that come from files compiled with dwarf debug info
3238 std::vector
<const ld::Atom
*> atomsNeedingDebugNotes
;
3239 std::set
<const ld::Atom
*> atomsWithStabs
;
3240 atomsNeedingDebugNotes
.reserve(1024);
3241 const ld::relocatable::File
* objFile
= NULL
;
3242 bool objFileHasDwarf
= false;
3243 bool objFileHasStabs
= false;
3244 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
3245 ld::Internal::FinalSection
* sect
= *sit
;
3246 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
3247 const ld::Atom
* atom
= *ait
;
3248 // no stabs for atoms that would not be in the symbol table
3249 if ( atom
->symbolTableInclusion() == ld::Atom::symbolTableNotIn
)
3251 if ( atom
->symbolTableInclusion() == ld::Atom::symbolTableNotInFinalLinkedImages
)
3253 // no stabs for absolute symbols
3254 if ( atom
->definition() == ld::Atom::definitionAbsolute
)
3256 // no stabs for .eh atoms
3257 if ( atom
->contentType() == ld::Atom::typeCFI
)
3259 const ld::File
* file
= atom
->file();
3260 if ( file
!= NULL
) {
3261 if ( file
!= objFile
) {
3262 objFileHasDwarf
= false;
3263 objFileHasStabs
= false;
3264 objFile
= dynamic_cast<const ld::relocatable::File
*>(file
);
3265 if ( objFile
!= NULL
) {
3266 switch ( objFile
->debugInfo() ) {
3267 case ld::relocatable::File::kDebugInfoNone
:
3269 case ld::relocatable::File::kDebugInfoDwarf
:
3270 objFileHasDwarf
= true;
3272 case ld::relocatable::File::kDebugInfoStabs
:
3273 case ld::relocatable::File::kDebugInfoStabsUUID
:
3274 objFileHasStabs
= true;
3279 if ( objFileHasDwarf
)
3280 atomsNeedingDebugNotes
.push_back(atom
);
3281 if ( objFileHasStabs
)
3282 atomsWithStabs
.insert(atom
);
3287 // sort by file ordinal then atom ordinal
3288 std::sort(atomsNeedingDebugNotes
.begin(), atomsNeedingDebugNotes
.end(), DebugNoteSorter());
3290 // synthesize "debug notes" and add them to master stabs vector
3291 const char* dirPath
= NULL
;
3292 const char* filename
= NULL
;
3293 bool wroteStartSO
= false;
3294 state
.stabs
.reserve(atomsNeedingDebugNotes
.size()*4);
3295 __gnu_cxx::hash_set
<const char*, __gnu_cxx::hash
<const char*>, CStringEquals
> seenFiles
;
3296 for (std::vector
<const ld::Atom
*>::iterator it
=atomsNeedingDebugNotes
.begin(); it
!= atomsNeedingDebugNotes
.end(); it
++) {
3297 const ld::Atom
* atom
= *it
;
3298 const ld::File
* atomFile
= atom
->file();
3299 const ld::relocatable::File
* atomObjFile
= dynamic_cast<const ld::relocatable::File
*>(atomFile
);
3300 const char* newDirPath
;
3301 const char* newFilename
;
3302 //fprintf(stderr, "debug note for %s\n", atom->name());
3303 if ( atom
->translationUnitSource(&newDirPath
, &newFilename
) ) {
3304 // need SO's whenever the translation unit source file changes
3305 if ( newFilename
!= filename
) {
3306 // gdb like directory SO's to end in '/', but dwarf DW_AT_comp_dir usually does not have trailing '/'
3307 if ( (newDirPath
!= NULL
) && (strlen(newDirPath
) > 1 ) && (newDirPath
[strlen(newDirPath
)-1] != '/') )
3308 asprintf((char**)&newDirPath
, "%s/", newDirPath
);
3309 if ( filename
!= NULL
) {
3310 // translation unit change, emit ending SO
3311 ld::relocatable::File::Stab endFileStab
;
3312 endFileStab
.atom
= NULL
;
3313 endFileStab
.type
= N_SO
;
3314 endFileStab
.other
= 1;
3315 endFileStab
.desc
= 0;
3316 endFileStab
.value
= 0;
3317 endFileStab
.string
= "";
3318 state
.stabs
.push_back(endFileStab
);
3320 // new translation unit, emit start SO's
3321 ld::relocatable::File::Stab dirPathStab
;
3322 dirPathStab
.atom
= NULL
;
3323 dirPathStab
.type
= N_SO
;
3324 dirPathStab
.other
= 0;
3325 dirPathStab
.desc
= 0;
3326 dirPathStab
.value
= 0;
3327 dirPathStab
.string
= newDirPath
;
3328 state
.stabs
.push_back(dirPathStab
);
3329 ld::relocatable::File::Stab fileStab
;
3330 fileStab
.atom
= NULL
;
3331 fileStab
.type
= N_SO
;
3335 fileStab
.string
= newFilename
;
3336 state
.stabs
.push_back(fileStab
);
3337 // Synthesize OSO for start of file
3338 ld::relocatable::File::Stab objStab
;
3339 objStab
.atom
= NULL
;
3340 objStab
.type
= N_OSO
;
3341 // <rdar://problem/6337329> linker should put cpusubtype in n_sect field of nlist entry for N_OSO debug note entries
3342 objStab
.other
= atomFile
->cpuSubType();
3344 if ( atomObjFile
!= NULL
) {
3345 objStab
.string
= assureFullPath(atomObjFile
->debugInfoPath());
3346 objStab
.value
= atomObjFile
->debugInfoModificationTime();
3349 objStab
.string
= assureFullPath(atomFile
->path());
3350 objStab
.value
= atomFile
->modificationTime();
3352 state
.stabs
.push_back(objStab
);
3353 wroteStartSO
= true;
3354 // add the source file path to seenFiles so it does not show up in SOLs
3355 seenFiles
.insert(newFilename
);
3357 asprintf(&fullFilePath
, "%s%s", newDirPath
, newFilename
);
3358 // add both leaf path and full path
3359 seenFiles
.insert(fullFilePath
);
3361 filename
= newFilename
;
3362 dirPath
= newDirPath
;
3363 if ( atom
->section().type() == ld::Section::typeCode
) {
3364 // Synthesize BNSYM and start FUN stabs
3365 ld::relocatable::File::Stab beginSym
;
3366 beginSym
.atom
= atom
;
3367 beginSym
.type
= N_BNSYM
;
3371 beginSym
.string
= "";
3372 state
.stabs
.push_back(beginSym
);
3373 ld::relocatable::File::Stab startFun
;
3374 startFun
.atom
= atom
;
3375 startFun
.type
= N_FUN
;
3379 startFun
.string
= atom
->name();
3380 state
.stabs
.push_back(startFun
);
3381 // Synthesize any SOL stabs needed
3382 const char* curFile
= NULL
;
3383 for (ld::Atom::LineInfo::iterator lit
= atom
->beginLineInfo(); lit
!= atom
->endLineInfo(); ++lit
) {
3384 if ( lit
->fileName
!= curFile
) {
3385 if ( seenFiles
.count(lit
->fileName
) == 0 ) {
3386 seenFiles
.insert(lit
->fileName
);
3387 ld::relocatable::File::Stab sol
;
3393 sol
.string
= lit
->fileName
;
3394 state
.stabs
.push_back(sol
);
3396 curFile
= lit
->fileName
;
3399 // Synthesize end FUN and ENSYM stabs
3400 ld::relocatable::File::Stab endFun
;
3402 endFun
.type
= N_FUN
;
3407 state
.stabs
.push_back(endFun
);
3408 ld::relocatable::File::Stab endSym
;
3410 endSym
.type
= N_ENSYM
;
3415 state
.stabs
.push_back(endSym
);
3418 ld::relocatable::File::Stab globalsStab
;
3419 const char* name
= atom
->name();
3420 if ( atom
->scope() == ld::Atom::scopeTranslationUnit
) {
3421 // Synthesize STSYM stab for statics
3422 globalsStab
.atom
= atom
;
3423 globalsStab
.type
= N_STSYM
;
3424 globalsStab
.other
= 1;
3425 globalsStab
.desc
= 0;
3426 globalsStab
.value
= 0;
3427 globalsStab
.string
= name
;
3428 state
.stabs
.push_back(globalsStab
);
3431 // Synthesize GSYM stab for other globals
3432 globalsStab
.atom
= atom
;
3433 globalsStab
.type
= N_GSYM
;
3434 globalsStab
.other
= 1;
3435 globalsStab
.desc
= 0;
3436 globalsStab
.value
= 0;
3437 globalsStab
.string
= name
;
3438 state
.stabs
.push_back(globalsStab
);
3444 if ( wroteStartSO
) {
3446 ld::relocatable::File::Stab endFileStab
;
3447 endFileStab
.atom
= NULL
;
3448 endFileStab
.type
= N_SO
;
3449 endFileStab
.other
= 1;
3450 endFileStab
.desc
= 0;
3451 endFileStab
.value
= 0;
3452 endFileStab
.string
= "";
3453 state
.stabs
.push_back(endFileStab
);
3456 // copy any stabs from .o file
3457 std::set
<const ld::File
*> filesSeenWithStabs
;
3458 for (std::set
<const ld::Atom
*>::iterator it
=atomsWithStabs
.begin(); it
!= atomsWithStabs
.end(); it
++) {
3459 const ld::Atom
* atom
= *it
;
3460 objFile
= dynamic_cast<const ld::relocatable::File
*>(atom
->file());
3461 if ( objFile
!= NULL
) {
3462 if ( filesSeenWithStabs
.count(objFile
) == 0 ) {
3463 filesSeenWithStabs
.insert(objFile
);
3464 const std::vector
<ld::relocatable::File::Stab
>* stabs
= objFile
->stabs();
3465 if ( stabs
!= NULL
) {
3466 for(std::vector
<ld::relocatable::File::Stab
>::const_iterator sit
= stabs
->begin(); sit
!= stabs
->end(); ++sit
) {
3467 ld::relocatable::File::Stab stab
= *sit
;
3468 // ignore stabs associated with atoms that were dead stripped or coalesced away
3469 if ( (sit
->atom
!= NULL
) && (atomsWithStabs
.count(sit
->atom
) == 0) )
3471 // <rdar://problem/8284718> Value of N_SO stabs should be address of first atom from translation unit
3472 if ( (stab
.type
== N_SO
) && (stab
.string
!= NULL
) && (stab
.string
[0] != '\0') ) {
3475 state
.stabs
.push_back(stab
);