1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-*
3 * Copyright (c) 2009-2010 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 if ( atom
->alignment().powerOf2
> maxAlignment
)
324 maxAlignment
= atom
->alignment().powerOf2
;
325 // calculate section offset for this atom
326 uint64_t alignment
= 1 << atom
->alignment().powerOf2
;
327 uint64_t currentModulus
= (offset
% alignment
);
328 uint64_t requiredModulus
= atom
->alignment().modulus
;
329 if ( currentModulus
!= requiredModulus
) {
330 if ( requiredModulus
> currentModulus
)
331 offset
+= requiredModulus
-currentModulus
;
333 offset
+= requiredModulus
+alignment
-currentModulus
;
335 // LINKEDIT atoms are laid out later
336 if ( sect
->type() != ld::Section::typeLinkEdit
) {
337 (const_cast<ld::Atom
*>(atom
))->setSectionOffset(offset
);
338 offset
+= atom
->size();
340 if ( (atom
->scope() == ld::Atom::scopeGlobal
)
341 && (atom
->definition() == ld::Atom::definitionRegular
)
342 && (atom
->combine() == ld::Atom::combineByName
)
343 && ((atom
->symbolTableInclusion() == ld::Atom::symbolTableIn
)
344 || (atom
->symbolTableInclusion() == ld::Atom::symbolTableInAndNeverStrip
)) ) {
345 this->hasWeakExternalSymbols
= true;
346 if ( _options
.warnWeakExports() )
347 warning("weak external symbol: %s", atom
->name());
351 // section alignment is that of a contained atom with the greatest alignment
352 sect
->alignment
= maxAlignment
;
353 // unless -sectalign command line option overrides
354 if ( _options
.hasCustomSectionAlignment(sect
->segmentName(), sect
->sectionName()) )
355 sect
->alignment
= _options
.customSectionAlignment(sect
->segmentName(), sect
->sectionName());
356 // each atom in __eh_frame has zero alignment to assure they pack together,
357 // but compilers usually make the CFIs pointer sized, so we want whole section
358 // to start on pointer sized boundary.
359 if ( sect
->type() == ld::Section::typeCFI
)
361 if ( sect
->type() == ld::Section::typeTLVDefs
)
362 this->hasThreadLocalVariableDefinitions
= true;
367 void OutputFile::setLoadCommandsPadding(ld::Internal
& state
)
369 // In other sections, any extra space is put and end of segment.
370 // In __TEXT segment, any extra space is put after load commands to allow post-processing of load commands
371 // Do a reverse layout of __TEXT segment to determine padding size and adjust section size
372 uint64_t paddingSize
= 0;
373 switch ( _options
.outputKind() ) {
375 // dyld itself has special padding requirements. We want the beginning __text section to start at a stable address
376 assert(strcmp(state
.sections
[1]->sectionName(),"__text") == 0);
377 state
.sections
[1]->alignment
= 12; // page align __text
379 case Options::kObjectFile
:
380 // mach-o .o files need no padding between load commands and first section
381 // but leave enough room that the object file could be signed
384 case Options::kPreload
:
385 // mach-o MH_PRELOAD files need no padding between load commands and first section
388 // work backwards from end of segment and lay out sections so that extra room goes to padding atom
390 for (std::vector
<ld::Internal::FinalSection
*>::reverse_iterator it
= state
.sections
.rbegin(); it
!= state
.sections
.rend(); ++it
) {
391 ld::Internal::FinalSection
* sect
= *it
;
392 if ( strcmp(sect
->segmentName(), "__TEXT") != 0 )
394 if ( sect
== headerAndLoadCommandsSection
) {
395 addr
-= headerAndLoadCommandsSection
->size
;
396 paddingSize
= addr
% _options
.segmentAlignment();
400 addr
= addr
& (0 - (1 << sect
->alignment
));
403 // if command line requires more padding than this
404 uint32_t minPad
= _options
.minimumHeaderPad();
405 if ( _options
.maxMminimumHeaderPad() ) {
406 // -headerpad_max_install_names means there should be room for every path load command to grow to 1204 bytes
407 uint32_t altMin
= _dylibsToLoad
.size() * MAXPATHLEN
;
408 if ( _options
.outputKind() == Options::kDynamicLibrary
)
409 altMin
+= MAXPATHLEN
;
410 if ( altMin
> minPad
)
413 if ( paddingSize
< minPad
) {
414 int extraPages
= (minPad
- paddingSize
+ _options
.segmentAlignment() - 1)/_options
.segmentAlignment();
415 paddingSize
+= extraPages
* _options
.segmentAlignment();
418 if ( _options
.makeEncryptable() ) {
419 // load commands must be on a separate non-encrypted page
420 int loadCommandsPage
= (headerAndLoadCommandsSection
->size
+ minPad
)/_options
.segmentAlignment();
421 int textPage
= (headerAndLoadCommandsSection
->size
+ paddingSize
)/_options
.segmentAlignment();
422 if ( loadCommandsPage
== textPage
) {
423 paddingSize
+= _options
.segmentAlignment();
426 // remember start for later use by load command
427 _encryptedTEXTstartOffset
= textPage
*_options
.segmentAlignment();
431 // add padding to size of section
432 headerAndLoadCommandsSection
->size
+= paddingSize
;
436 uint64_t OutputFile::pageAlign(uint64_t addr
)
438 const uint64_t alignment
= _options
.segmentAlignment();
439 return ((addr
+alignment
-1) & (-alignment
));
442 uint64_t OutputFile::pageAlign(uint64_t addr
, uint64_t pageSize
)
444 return ((addr
+pageSize
-1) & (-pageSize
));
448 void OutputFile::assignFileOffsets(ld::Internal
& state
)
450 const bool log
= false;
451 const bool hiddenSectionsOccupyAddressSpace
= ((_options
.outputKind() != Options::kObjectFile
)
452 && (_options
.outputKind() != Options::kPreload
));
453 const bool segmentsArePageAligned
= (_options
.outputKind() != Options::kObjectFile
);
455 uint64_t address
= 0;
456 const char* lastSegName
= "";
457 uint64_t floatingAddressStart
= _options
.baseAddress();
459 // first pass, assign addresses to sections in segments with fixed start addresses
460 if ( log
) fprintf(stderr
, "Fixed address segments:\n");
461 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
462 ld::Internal::FinalSection
* sect
= *it
;
463 if ( ! _options
.hasCustomSegmentAddress(sect
->segmentName()) )
465 if ( segmentsArePageAligned
) {
466 if ( strcmp(lastSegName
, sect
->segmentName()) != 0 ) {
467 address
= _options
.customSegmentAddress(sect
->segmentName());
468 lastSegName
= sect
->segmentName();
471 // adjust section address based on alignment
472 uint64_t unalignedAddress
= address
;
473 uint64_t alignment
= (1 << sect
->alignment
);
474 address
= ( (unalignedAddress
+alignment
-1) & (-alignment
) );
476 // update section info
477 sect
->address
= address
;
478 sect
->alignmentPaddingBytes
= (address
- unalignedAddress
);
481 if ( ((address
+ sect
->size
) > _options
.maxAddress()) && (_options
.outputKind() != Options::kObjectFile
)
482 && (_options
.outputKind() != Options::kStaticExecutable
) )
483 throwf("section %s (address=0x%08llX, size=%llu) would make the output executable exceed available address range",
484 sect
->sectionName(), address
, sect
->size
);
486 if ( log
) fprintf(stderr
, " address=0x%08llX, hidden=%d, alignment=%02d, section=%s,%s\n",
487 sect
->address
, sect
->isSectionHidden(), sect
->alignment
, sect
->segmentName(), sect
->sectionName());
488 // update running totals
489 if ( !sect
->isSectionHidden() || hiddenSectionsOccupyAddressSpace
)
490 address
+= sect
->size
;
492 // if TEXT segment address is fixed, then flow other segments after it
493 if ( strcmp(sect
->segmentName(), "__TEXT") == 0 ) {
494 floatingAddressStart
= address
;
498 // second pass, assign section address to sections in segments that are contiguous with previous segment
499 address
= floatingAddressStart
;
501 if ( log
) fprintf(stderr
, "Regular layout segments:\n");
502 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
503 ld::Internal::FinalSection
* sect
= *it
;
504 if ( _options
.hasCustomSegmentAddress(sect
->segmentName()) )
506 if ( (_options
.outputKind() == Options::kPreload
) && (sect
->type() == ld::Section::typeMachHeader
) ) {
507 sect
->alignmentPaddingBytes
= 0;
510 if ( segmentsArePageAligned
) {
511 if ( strcmp(lastSegName
, sect
->segmentName()) != 0 ) {
512 // round up size of last segment if needed
513 if ( *lastSegName
!= '\0' ) {
514 address
= pageAlign(address
, _options
.segPageSize(lastSegName
));
516 // set segment address based on end of last segment
517 address
= pageAlign(address
);
518 lastSegName
= sect
->segmentName();
521 // adjust section address based on alignment
522 uint64_t unalignedAddress
= address
;
523 uint64_t alignment
= (1 << sect
->alignment
);
524 address
= ( (unalignedAddress
+alignment
-1) & (-alignment
) );
526 // update section info
527 sect
->address
= address
;
528 sect
->alignmentPaddingBytes
= (address
- unalignedAddress
);
531 if ( ((address
+ sect
->size
) > _options
.maxAddress()) && (_options
.outputKind() != Options::kObjectFile
)
532 && (_options
.outputKind() != Options::kStaticExecutable
) )
533 throwf("section %s (address=0x%08llX, size=%llu) would make the output executable exceed available address range",
534 sect
->sectionName(), address
, sect
->size
);
536 if ( log
) fprintf(stderr
, " address=0x%08llX, hidden=%d, alignment=%02d, padBytes=%d, section=%s,%s\n",
537 sect
->address
, sect
->isSectionHidden(), sect
->alignment
, sect
->alignmentPaddingBytes
,
538 sect
->segmentName(), sect
->sectionName());
539 // update running totals
540 if ( !sect
->isSectionHidden() || hiddenSectionsOccupyAddressSpace
)
541 address
+= sect
->size
;
545 // third pass, assign section file offsets
546 uint64_t fileOffset
= 0;
548 if ( log
) fprintf(stderr
, "All segments with file offsets:\n");
549 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
550 ld::Internal::FinalSection
* sect
= *it
;
551 if ( hasZeroForFileOffset(sect
) ) {
552 // fileoff of zerofill sections is moot, but historically it is set to zero
553 sect
->fileOffset
= 0;
556 // page align file offset at start of each segment
557 if ( segmentsArePageAligned
&& (*lastSegName
!= '\0') && (strcmp(lastSegName
, sect
->segmentName()) != 0) ) {
558 fileOffset
= pageAlign(fileOffset
, _options
.segPageSize(lastSegName
));
560 lastSegName
= sect
->segmentName();
562 // align file offset with address layout
563 fileOffset
+= sect
->alignmentPaddingBytes
;
565 // update section info
566 sect
->fileOffset
= fileOffset
;
568 // update running total
569 fileOffset
+= sect
->size
;
572 if ( log
) fprintf(stderr
, " fileoffset=0x%08llX, address=0x%08llX, hidden=%d, size=%lld, alignment=%02d, section=%s,%s\n",
573 sect
->fileOffset
, sect
->address
, sect
->isSectionHidden(), sect
->size
, sect
->alignment
,
574 sect
->segmentName(), sect
->sectionName());
578 // for encrypted iPhoneOS apps
579 if ( _options
.makeEncryptable() ) {
580 // remember end of __TEXT for later use by load command
581 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
582 ld::Internal::FinalSection
* sect
= *it
;
583 if ( strcmp(sect
->segmentName(), "__TEXT") == 0 ) {
584 _encryptedTEXTendOffset
= pageAlign(sect
->fileOffset
);
589 // remember total file size
590 _fileSize
= fileOffset
;
594 static const char* makeName(const ld::Atom
& atom
)
596 static char buffer
[4096];
597 switch ( atom
.symbolTableInclusion() ) {
598 case ld::Atom::symbolTableNotIn
:
599 case ld::Atom::symbolTableNotInFinalLinkedImages
:
600 sprintf(buffer
, "%s@0x%08llX", atom
.name(), atom
.objectAddress());
602 case ld::Atom::symbolTableIn
:
603 case ld::Atom::symbolTableInAndNeverStrip
:
604 case ld::Atom::symbolTableInAsAbsolute
:
605 case ld::Atom::symbolTableInWithRandomAutoStripLabel
:
606 strlcpy(buffer
, atom
.name(), 4096);
612 static const char* referenceTargetAtomName(ld::Internal
& state
, const ld::Fixup
* ref
)
614 switch ( ref
->binding
) {
615 case ld::Fixup::bindingNone
:
617 case ld::Fixup::bindingByNameUnbound
:
618 return (char*)(ref
->u
.target
);
619 case ld::Fixup::bindingByContentBound
:
620 case ld::Fixup::bindingDirectlyBound
:
621 return makeName(*((ld::Atom
*)(ref
->u
.target
)));
622 case ld::Fixup::bindingsIndirectlyBound
:
623 return makeName(*state
.indirectBindingTable
[ref
->u
.bindingIndex
]);
625 return "BAD BINDING";
628 bool OutputFile::targetIsThumb(ld::Internal
& state
, const ld::Fixup
* fixup
)
630 switch ( fixup
->binding
) {
631 case ld::Fixup::bindingByContentBound
:
632 case ld::Fixup::bindingDirectlyBound
:
633 return fixup
->u
.target
->isThumb();
634 case ld::Fixup::bindingsIndirectlyBound
:
635 return state
.indirectBindingTable
[fixup
->u
.bindingIndex
]->isThumb();
639 throw "unexpected binding";
642 uint64_t OutputFile::addressOf(const ld::Internal
& state
, const ld::Fixup
* fixup
, const ld::Atom
** target
)
644 if ( !_options
.makeCompressedDyldInfo() ) {
645 // For external relocations the classic mach-o format
646 // has addend only stored in the content. That means
647 // that the address of the target is not used.
648 if ( fixup
->contentAddendOnly
)
651 switch ( fixup
->binding
) {
652 case ld::Fixup::bindingNone
:
653 throw "unexpected bindingNone";
654 case ld::Fixup::bindingByNameUnbound
:
655 throw "unexpected bindingByNameUnbound";
656 case ld::Fixup::bindingByContentBound
:
657 case ld::Fixup::bindingDirectlyBound
:
658 *target
= fixup
->u
.target
;
659 return (*target
)->finalAddress();
660 case ld::Fixup::bindingsIndirectlyBound
:
661 *target
= state
.indirectBindingTable
[fixup
->u
.bindingIndex
];
662 return (*target
)->finalAddress();
664 throw "unexpected binding";
667 uint64_t OutputFile::sectionOffsetOf(const ld::Internal
& state
, const ld::Fixup
* fixup
)
669 const ld::Atom
* target
= NULL
;
670 switch ( fixup
->binding
) {
671 case ld::Fixup::bindingNone
:
672 throw "unexpected bindingNone";
673 case ld::Fixup::bindingByNameUnbound
:
674 throw "unexpected bindingByNameUnbound";
675 case ld::Fixup::bindingByContentBound
:
676 case ld::Fixup::bindingDirectlyBound
:
677 target
= fixup
->u
.target
;
679 case ld::Fixup::bindingsIndirectlyBound
:
680 target
= state
.indirectBindingTable
[fixup
->u
.bindingIndex
];
683 assert(target
!= NULL
);
685 uint64_t targetAddress
= target
->finalAddress();
686 for (std::vector
<ld::Internal::FinalSection
*>::const_iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
687 const ld::Internal::FinalSection
* sect
= *it
;
688 if ( (sect
->address
<= targetAddress
) && (targetAddress
< (sect
->address
+sect
->size
)) )
689 return targetAddress
- sect
->address
;
691 throw "section not found for section offset";
696 uint64_t OutputFile::tlvTemplateOffsetOf(const ld::Internal
& state
, const ld::Fixup
* fixup
)
698 const ld::Atom
* target
= NULL
;
699 switch ( fixup
->binding
) {
700 case ld::Fixup::bindingNone
:
701 throw "unexpected bindingNone";
702 case ld::Fixup::bindingByNameUnbound
:
703 throw "unexpected bindingByNameUnbound";
704 case ld::Fixup::bindingByContentBound
:
705 case ld::Fixup::bindingDirectlyBound
:
706 target
= fixup
->u
.target
;
708 case ld::Fixup::bindingsIndirectlyBound
:
709 target
= state
.indirectBindingTable
[fixup
->u
.bindingIndex
];
712 assert(target
!= NULL
);
714 for (std::vector
<ld::Internal::FinalSection
*>::const_iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
715 const ld::Internal::FinalSection
* sect
= *it
;
716 switch ( sect
->type() ) {
717 case ld::Section::typeTLVInitialValues
:
718 case ld::Section::typeTLVZeroFill
:
719 return target
->finalAddress() - sect
->address
;
724 throw "section not found for tlvTemplateOffsetOf";
727 void OutputFile::printSectionLayout(ld::Internal
& state
)
729 // show layout of final image
730 fprintf(stderr
, "final section layout:\n");
731 for (std::vector
<ld::Internal::FinalSection
*>::iterator it
= state
.sections
.begin(); it
!= state
.sections
.end(); ++it
) {
732 if ( (*it
)->isSectionHidden() )
734 fprintf(stderr
, " %s/%s addr=0x%08llX, size=0x%08llX, fileOffset=0x%08llX, type=%d\n",
735 (*it
)->segmentName(), (*it
)->sectionName(),
736 (*it
)->address
, (*it
)->size
, (*it
)->fileOffset
, (*it
)->type());
741 void OutputFile::rangeCheck8(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
743 if ( (displacement
> 127) || (displacement
< -128) ) {
744 // show layout of final image
745 printSectionLayout(state
);
747 const ld::Atom
* target
;
748 throwf("8-bit reference out of range (%lld max is +/-127B): from %s (0x%08llX) to %s (0x%08llX)",
749 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
750 addressOf(state
, fixup
, &target
));
754 void OutputFile::rangeCheck16(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
756 const int64_t thirtyTwoKLimit
= 0x00007FFF;
757 if ( (displacement
> thirtyTwoKLimit
) || (displacement
< (-thirtyTwoKLimit
)) ) {
758 // show layout of final image
759 printSectionLayout(state
);
761 const ld::Atom
* target
;
762 throwf("16-bit reference out of range (%lld max is +/-32KB): from %s (0x%08llX) to %s (0x%08llX)",
763 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
764 addressOf(state
, fixup
, &target
));
768 void OutputFile::rangeCheckBranch32(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
770 const int64_t twoGigLimit
= 0x7FFFFFFF;
771 if ( (displacement
> twoGigLimit
) || (displacement
< (-twoGigLimit
)) ) {
772 // show layout of final image
773 printSectionLayout(state
);
775 const ld::Atom
* target
;
776 throwf("32-bit branch out of range (%lld max is +/-4GB): from %s (0x%08llX) to %s (0x%08llX)",
777 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
778 addressOf(state
, fixup
, &target
));
782 void OutputFile::rangeCheckRIP32(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
784 const int64_t twoGigLimit
= 0x7FFFFFFF;
785 if ( (displacement
> twoGigLimit
) || (displacement
< (-twoGigLimit
)) ) {
786 // show layout of final image
787 printSectionLayout(state
);
789 const ld::Atom
* target
;
790 throwf("32-bit RIP relative reference out of range (%lld max is +/-4GB): from %s (0x%08llX) to %s (0x%08llX)",
791 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
792 addressOf(state
, fixup
, &target
));
796 void OutputFile::rangeCheckARM12(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
798 if ( (displacement
> 4092LL) || (displacement
< (-4092LL)) ) {
799 // show layout of final image
800 printSectionLayout(state
);
802 const ld::Atom
* target
;
803 throwf("ARM ldr 12-bit displacement out of range (%lld max is +/-4096B): from %s (0x%08llX) to %s (0x%08llX)",
804 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
805 addressOf(state
, fixup
, &target
));
810 void OutputFile::rangeCheckARMBranch24(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
812 if ( (displacement
> 33554428LL) || (displacement
< (-33554432LL)) ) {
813 // show layout of final image
814 printSectionLayout(state
);
816 const ld::Atom
* target
;
817 throwf("b/bl/blx ARM branch out of range (%lld max is +/-32MB): from %s (0x%08llX) to %s (0x%08llX)",
818 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
819 addressOf(state
, fixup
, &target
));
823 void OutputFile::rangeCheckThumbBranch22(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
825 // armv7 supports a larger displacement
826 if ( _options
.preferSubArchitecture() && (_options
.subArchitecture() == CPU_SUBTYPE_ARM_V7
) ) {
827 if ( (displacement
> 16777214LL) || (displacement
< (-16777216LL)) ) {
828 // show layout of final image
829 printSectionLayout(state
);
831 const ld::Atom
* target
;
832 throwf("b/bl/blx thumb2 branch out of range (%lld max is +/-16MB): from %s (0x%08llX) to %s (0x%08llX)",
833 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
834 addressOf(state
, fixup
, &target
));
838 if ( (displacement
> 4194302LL) || (displacement
< (-4194304LL)) ) {
839 // show layout of final image
840 printSectionLayout(state
);
842 const ld::Atom
* target
;
843 throwf("b/bl/blx thumb1 branch out of range (%lld max is +/-4MB): from %s (0x%08llX) to %s (0x%08llX)",
844 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
845 addressOf(state
, fixup
, &target
));
850 void OutputFile::rangeCheckPPCBranch24(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
852 const int64_t bl_eightMegLimit
= 0x00FFFFFF;
853 if ( (displacement
> bl_eightMegLimit
) || (displacement
< (-bl_eightMegLimit
)) ) {
854 // show layout of final image
855 printSectionLayout(state
);
857 const ld::Atom
* target
;
858 throwf("bl PPC branch out of range (%lld max is +/-16MB): from %s (0x%08llX) to %s (0x%08llX)",
859 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
860 addressOf(state
, fixup
, &target
));
864 void OutputFile::rangeCheckPPCBranch14(int64_t displacement
, ld::Internal
& state
, const ld::Atom
* atom
, const ld::Fixup
* fixup
)
866 const int64_t b_sixtyFourKiloLimit
= 0x0000FFFF;
867 if ( (displacement
> b_sixtyFourKiloLimit
) || (displacement
< (-b_sixtyFourKiloLimit
)) ) {
868 // show layout of final image
869 printSectionLayout(state
);
871 const ld::Atom
* target
;
872 throwf("bcc PPC branch out of range (%lld max is +/-64KB): from %s (0x%08llX) to %s (0x%08llX)",
873 displacement
, atom
->name(), atom
->finalAddress(), referenceTargetAtomName(state
, fixup
),
874 addressOf(state
, fixup
, &target
));
881 uint16_t OutputFile::get16LE(uint8_t* loc
) { return LittleEndian::get16(*(uint16_t*)loc
); }
882 void OutputFile::set16LE(uint8_t* loc
, uint16_t value
) { LittleEndian::set16(*(uint16_t*)loc
, value
); }
884 uint32_t OutputFile::get32LE(uint8_t* loc
) { return LittleEndian::get32(*(uint32_t*)loc
); }
885 void OutputFile::set32LE(uint8_t* loc
, uint32_t value
) { LittleEndian::set32(*(uint32_t*)loc
, value
); }
887 uint64_t OutputFile::get64LE(uint8_t* loc
) { return LittleEndian::get64(*(uint64_t*)loc
); }
888 void OutputFile::set64LE(uint8_t* loc
, uint64_t value
) { LittleEndian::set64(*(uint64_t*)loc
, value
); }
890 uint16_t OutputFile::get16BE(uint8_t* loc
) { return BigEndian::get16(*(uint16_t*)loc
); }
891 void OutputFile::set16BE(uint8_t* loc
, uint16_t value
) { BigEndian::set16(*(uint16_t*)loc
, value
); }
893 uint32_t OutputFile::get32BE(uint8_t* loc
) { return BigEndian::get32(*(uint32_t*)loc
); }
894 void OutputFile::set32BE(uint8_t* loc
, uint32_t value
) { BigEndian::set32(*(uint32_t*)loc
, value
); }
896 uint64_t OutputFile::get64BE(uint8_t* loc
) { return BigEndian::get64(*(uint64_t*)loc
); }
897 void OutputFile::set64BE(uint8_t* loc
, uint64_t value
) { BigEndian::set64(*(uint64_t*)loc
, value
); }
899 void OutputFile::applyFixUps(ld::Internal
& state
, uint64_t mhAddress
, const ld::Atom
* atom
, uint8_t* buffer
)
901 //fprintf(stderr, "applyFixUps() on %s\n", atom->name());
902 int64_t accumulator
= 0;
903 const ld::Atom
* toTarget
= NULL
;
904 const ld::Atom
* fromTarget
;
906 uint32_t instruction
;
907 uint32_t newInstruction
;
908 uint16_t instructionLowHalf
;
912 bool thumbTarget
= false;
913 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(), end
=atom
->fixupsEnd(); fit
!= end
; ++fit
) {
914 uint8_t* fixUpLocation
= &buffer
[fit
->offsetInAtom
];
915 switch ( (ld::Fixup::Kind
)(fit
->kind
) ) {
916 case ld::Fixup::kindNone
:
917 case ld::Fixup::kindNoneFollowOn
:
918 case ld::Fixup::kindNoneGroupSubordinate
:
919 case ld::Fixup::kindNoneGroupSubordinateFDE
:
920 case ld::Fixup::kindNoneGroupSubordinateLSDA
:
921 case ld::Fixup::kindNoneGroupSubordinatePersonality
:
923 case ld::Fixup::kindSetTargetAddress
:
924 accumulator
= addressOf(state
, fit
, &toTarget
);
925 thumbTarget
= targetIsThumb(state
, fit
);
928 if ( fit
->contentAddendOnly
|| fit
->contentDetlaToAddendOnly
)
931 case ld::Fixup::kindSubtractTargetAddress
:
932 delta
= addressOf(state
, fit
, &fromTarget
);
933 if ( ! fit
->contentAddendOnly
)
934 accumulator
-= delta
;
936 case ld::Fixup::kindAddAddend
:
937 // <rdar://problem/8342028> ARM main executables main contain .long constants pointing
938 // into themselves such as jump tables. These .long should not have thumb bit set
939 // even though the target is a thumb instruction. We can tell it is an interior pointer
940 // because we are processing an addend.
941 if ( thumbTarget
&& (toTarget
== atom
) && ((int32_t)fit
->u
.addend
> 0) ) {
943 //warning("removing thumb bit from intra-atom pointer in %s %s+0x%0X",
944 // atom->section().sectionName(), atom->name(), fit->offsetInAtom);
946 accumulator
+= fit
->u
.addend
;
948 case ld::Fixup::kindSubtractAddend
:
949 accumulator
-= fit
->u
.addend
;
951 case ld::Fixup::kindSetTargetImageOffset
:
952 accumulator
= addressOf(state
, fit
, &toTarget
) - mhAddress
;
954 case ld::Fixup::kindSetTargetSectionOffset
:
955 accumulator
= sectionOffsetOf(state
, fit
);
957 case ld::Fixup::kindSetTargetTLVTemplateOffset
:
958 accumulator
= tlvTemplateOffsetOf(state
, fit
);
960 case ld::Fixup::kindStore8
:
961 *fixUpLocation
+= accumulator
;
963 case ld::Fixup::kindStoreLittleEndian16
:
964 set16LE(fixUpLocation
, accumulator
);
966 case ld::Fixup::kindStoreLittleEndianLow24of32
:
967 set32LE(fixUpLocation
, (get32LE(fixUpLocation
) & 0xFF000000) | (accumulator
& 0x00FFFFFF) );
969 case ld::Fixup::kindStoreLittleEndian32
:
970 set32LE(fixUpLocation
, accumulator
);
972 case ld::Fixup::kindStoreLittleEndian64
:
973 set64LE(fixUpLocation
, accumulator
);
975 case ld::Fixup::kindStoreBigEndian16
:
976 set16BE(fixUpLocation
, accumulator
);
978 case ld::Fixup::kindStoreBigEndianLow24of32
:
979 set32BE(fixUpLocation
, (get32BE(fixUpLocation
) & 0xFF000000) | (accumulator
& 0x00FFFFFF) );
981 case ld::Fixup::kindStoreBigEndian32
:
982 set32BE(fixUpLocation
, accumulator
);
984 case ld::Fixup::kindStoreBigEndian64
:
985 set64BE(fixUpLocation
, accumulator
);
987 case ld::Fixup::kindStoreX86PCRel8
:
988 case ld::Fixup::kindStoreX86BranchPCRel8
:
989 if ( fit
->contentAddendOnly
)
992 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 1);
993 rangeCheck8(delta
, state
, atom
, fit
);
994 *fixUpLocation
= delta
;
996 case ld::Fixup::kindStoreX86PCRel16
:
997 if ( fit
->contentAddendOnly
)
1000 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 2);
1001 rangeCheck16(delta
, state
, atom
, fit
);
1002 set16LE(fixUpLocation
, delta
);
1004 case ld::Fixup::kindStoreX86BranchPCRel32
:
1005 if ( fit
->contentAddendOnly
)
1006 delta
= accumulator
;
1008 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1009 rangeCheckBranch32(delta
, state
, atom
, fit
);
1010 set32LE(fixUpLocation
, delta
);
1012 case ld::Fixup::kindStoreX86PCRel32GOTLoad
:
1013 case ld::Fixup::kindStoreX86PCRel32GOT
:
1014 case ld::Fixup::kindStoreX86PCRel32
:
1015 case ld::Fixup::kindStoreX86PCRel32TLVLoad
:
1016 if ( fit
->contentAddendOnly
)
1017 delta
= accumulator
;
1019 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1020 rangeCheckRIP32(delta
, state
, atom
, fit
);
1021 set32LE(fixUpLocation
, delta
);
1023 case ld::Fixup::kindStoreX86PCRel32_1
:
1024 if ( fit
->contentAddendOnly
)
1025 delta
= accumulator
- 1;
1027 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 5);
1028 rangeCheckRIP32(delta
, state
, atom
, fit
);
1029 set32LE(fixUpLocation
, delta
);
1031 case ld::Fixup::kindStoreX86PCRel32_2
:
1032 if ( fit
->contentAddendOnly
)
1033 delta
= accumulator
- 2;
1035 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 6);
1036 rangeCheckRIP32(delta
, state
, atom
, fit
);
1037 set32LE(fixUpLocation
, delta
);
1039 case ld::Fixup::kindStoreX86PCRel32_4
:
1040 if ( fit
->contentAddendOnly
)
1041 delta
= accumulator
- 4;
1043 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 8);
1044 rangeCheckRIP32(delta
, state
, atom
, fit
);
1045 set32LE(fixUpLocation
, delta
);
1047 case ld::Fixup::kindStoreX86Abs32TLVLoad
:
1048 set32LE(fixUpLocation
, accumulator
);
1050 case ld::Fixup::kindStoreX86Abs32TLVLoadNowLEA
:
1051 assert(_options
.outputKind() != Options::kObjectFile
);
1052 // TLV entry was optimized away, change movl instruction to a leal
1053 if ( fixUpLocation
[-1] != 0xA1 )
1054 throw "TLV load reloc does not point to a movl instruction";
1055 fixUpLocation
[-1] = 0xB8;
1056 set32LE(fixUpLocation
, accumulator
);
1058 case ld::Fixup::kindStoreX86PCRel32GOTLoadNowLEA
:
1059 assert(_options
.outputKind() != Options::kObjectFile
);
1060 // GOT entry was optimized away, change movq instruction to a leaq
1061 if ( fixUpLocation
[-2] != 0x8B )
1062 throw "GOT load reloc does not point to a movq instruction";
1063 fixUpLocation
[-2] = 0x8D;
1064 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1065 rangeCheckRIP32(delta
, state
, atom
, fit
);
1066 set32LE(fixUpLocation
, delta
);
1068 case ld::Fixup::kindStoreX86PCRel32TLVLoadNowLEA
:
1069 assert(_options
.outputKind() != Options::kObjectFile
);
1070 // TLV entry was optimized away, change movq instruction to a leaq
1071 if ( fixUpLocation
[-2] != 0x8B )
1072 throw "TLV load reloc does not point to a movq instruction";
1073 fixUpLocation
[-2] = 0x8D;
1074 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1075 rangeCheckRIP32(delta
, state
, atom
, fit
);
1076 set32LE(fixUpLocation
, delta
);
1078 case ld::Fixup::kindStoreTargetAddressARMLoad12
:
1079 accumulator
= addressOf(state
, fit
, &toTarget
);
1080 // fall into kindStoreARMLoad12 case
1081 case ld::Fixup::kindStoreARMLoad12
:
1082 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 8);
1083 rangeCheckARM12(delta
, state
, atom
, fit
);
1084 instruction
= get32LE(fixUpLocation
);
1086 newInstruction
= instruction
& 0xFFFFF000;
1087 newInstruction
|= ((uint32_t)delta
& 0xFFF);
1090 newInstruction
= instruction
& 0xFF7FF000;
1091 newInstruction
|= ((uint32_t)(-delta
) & 0xFFF);
1093 set32LE(fixUpLocation
, newInstruction
);
1095 case ld::Fixup::kindStorePPCBranch14
:
1096 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
);
1097 rangeCheckPPCBranch14(delta
, state
, atom
, fit
);
1098 instruction
= get32BE(fixUpLocation
);
1099 newInstruction
= (instruction
& 0xFFFF0003) | ((uint32_t)delta
& 0x0000FFFC);
1100 set32BE(fixUpLocation
, newInstruction
);
1102 case ld::Fixup::kindStorePPCPicLow14
:
1103 case ld::Fixup::kindStorePPCAbsLow14
:
1104 instruction
= get32BE(fixUpLocation
);
1105 if ( (accumulator
& 0x3) != 0 )
1106 throwf("bad offset (0x%08X) for lo14 instruction pic-base fix-up", (uint32_t)accumulator
);
1107 newInstruction
= (instruction
& 0xFFFF0003) | (accumulator
& 0xFFFC);
1108 set32BE(fixUpLocation
, newInstruction
);
1110 case ld::Fixup::kindStorePPCAbsLow16
:
1111 case ld::Fixup::kindStorePPCPicLow16
:
1112 instruction
= get32BE(fixUpLocation
);
1113 newInstruction
= (instruction
& 0xFFFF0000) | (accumulator
& 0xFFFF);
1114 set32BE(fixUpLocation
, newInstruction
);
1116 case ld::Fixup::kindStorePPCAbsHigh16AddLow
:
1117 case ld::Fixup::kindStorePPCPicHigh16AddLow
:
1118 instructionLowHalf
= (accumulator
>> 16) & 0xFFFF;
1119 if ( accumulator
& 0x00008000 )
1120 ++instructionLowHalf
;
1121 instruction
= get32BE(fixUpLocation
);
1122 newInstruction
= (instruction
& 0xFFFF0000) | instructionLowHalf
;
1123 set32BE(fixUpLocation
, newInstruction
);
1125 case ld::Fixup::kindStorePPCAbsHigh16
:
1126 instruction
= get32BE(fixUpLocation
);
1127 newInstruction
= (instruction
& 0xFFFF0000) | ((accumulator
>> 16) & 0xFFFF);
1128 set32BE(fixUpLocation
, newInstruction
);
1130 case ld::Fixup::kindDtraceExtra
:
1132 case ld::Fixup::kindStoreX86DtraceCallSiteNop
:
1133 if ( _options
.outputKind() != Options::kObjectFile
) {
1134 // change call site to a NOP
1135 fixUpLocation
[-1] = 0x90; // 1-byte nop
1136 fixUpLocation
[0] = 0x0F; // 4-byte nop
1137 fixUpLocation
[1] = 0x1F;
1138 fixUpLocation
[2] = 0x40;
1139 fixUpLocation
[3] = 0x00;
1142 case ld::Fixup::kindStoreX86DtraceIsEnableSiteClear
:
1143 if ( _options
.outputKind() != Options::kObjectFile
) {
1144 // change call site to a clear eax
1145 fixUpLocation
[-1] = 0x33; // xorl eax,eax
1146 fixUpLocation
[0] = 0xC0;
1147 fixUpLocation
[1] = 0x90; // 1-byte nop
1148 fixUpLocation
[2] = 0x90; // 1-byte nop
1149 fixUpLocation
[3] = 0x90; // 1-byte nop
1152 case ld::Fixup::kindStorePPCDtraceCallSiteNop
:
1153 if ( _options
.outputKind() != Options::kObjectFile
) {
1154 // change call site to a NOP
1155 set32BE(fixUpLocation
, 0x60000000);
1158 case ld::Fixup::kindStorePPCDtraceIsEnableSiteClear
:
1159 if ( _options
.outputKind() != Options::kObjectFile
) {
1160 // change call site to a li r3,0
1161 set32BE(fixUpLocation
, 0x38600000);
1164 case ld::Fixup::kindStoreARMDtraceCallSiteNop
:
1165 if ( _options
.outputKind() != Options::kObjectFile
) {
1166 // change call site to a NOP
1167 set32LE(fixUpLocation
, 0xE1A00000);
1170 case ld::Fixup::kindStoreARMDtraceIsEnableSiteClear
:
1171 if ( _options
.outputKind() != Options::kObjectFile
) {
1172 // change call site to 'eor r0, r0, r0'
1173 set32LE(fixUpLocation
, 0xE0200000);
1176 case ld::Fixup::kindStoreThumbDtraceCallSiteNop
:
1177 if ( _options
.outputKind() != Options::kObjectFile
) {
1178 // change 32-bit blx call site to two thumb NOPs
1179 set32LE(fixUpLocation
, 0x46C046C0);
1182 case ld::Fixup::kindStoreThumbDtraceIsEnableSiteClear
:
1183 if ( _options
.outputKind() != Options::kObjectFile
) {
1184 // change 32-bit blx call site to 'nop', 'eor r0, r0'
1185 set32LE(fixUpLocation
, 0x46C04040);
1188 case ld::Fixup::kindLazyTarget
:
1190 case ld::Fixup::kindSetLazyOffset
:
1191 assert(fit
->binding
== ld::Fixup::bindingDirectlyBound
);
1192 accumulator
= this->lazyBindingInfoOffsetForLazyPointerAddress(fit
->u
.target
->finalAddress());
1194 case ld::Fixup::kindStoreTargetAddressLittleEndian32
:
1195 accumulator
= addressOf(state
, fit
, &toTarget
);
1196 thumbTarget
= targetIsThumb(state
, fit
);
1199 if ( fit
->contentAddendOnly
)
1201 set32LE(fixUpLocation
, accumulator
);
1203 case ld::Fixup::kindStoreTargetAddressLittleEndian64
:
1204 accumulator
= addressOf(state
, fit
, &toTarget
);
1205 if ( fit
->contentAddendOnly
)
1207 set64LE(fixUpLocation
, accumulator
);
1209 case ld::Fixup::kindStoreTargetAddressBigEndian32
:
1210 accumulator
= addressOf(state
, fit
, &toTarget
);
1211 if ( fit
->contentAddendOnly
)
1213 set32BE(fixUpLocation
, accumulator
);
1215 case ld::Fixup::kindStoreTargetAddressBigEndian64
:
1216 accumulator
= addressOf(state
, fit
, &toTarget
);
1217 if ( fit
->contentAddendOnly
)
1219 set64BE(fixUpLocation
, accumulator
);
1221 case ld::Fixup::kindSetTargetTLVTemplateOffsetLittleEndian32
:
1222 accumulator
= tlvTemplateOffsetOf(state
, fit
);
1223 set32LE(fixUpLocation
, accumulator
);
1225 case ld::Fixup::kindSetTargetTLVTemplateOffsetLittleEndian64
:
1226 accumulator
= tlvTemplateOffsetOf(state
, fit
);
1227 set64LE(fixUpLocation
, accumulator
);
1229 case ld::Fixup::kindStoreTargetAddressX86PCRel32
:
1230 case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32
:
1231 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad
:
1232 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoad
:
1233 accumulator
= addressOf(state
, fit
, &toTarget
);
1234 if ( fit
->contentDetlaToAddendOnly
)
1236 if ( fit
->contentAddendOnly
)
1239 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1240 rangeCheckRIP32(delta
, state
, atom
, fit
);
1241 set32LE(fixUpLocation
, delta
);
1243 case ld::Fixup::kindStoreTargetAddressX86Abs32TLVLoad
:
1244 set32LE(fixUpLocation
, accumulator
);
1246 case ld::Fixup::kindStoreTargetAddressX86Abs32TLVLoadNowLEA
:
1247 // TLV entry was optimized away, change movl instruction to a leal
1248 if ( fixUpLocation
[-1] != 0xA1 )
1249 throw "TLV load reloc does not point to a movl <abs-address>,<reg> instruction";
1250 fixUpLocation
[-1] = 0xB8;
1251 accumulator
= addressOf(state
, fit
, &toTarget
);
1252 set32LE(fixUpLocation
, accumulator
);
1254 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA
:
1255 // GOT entry was optimized away, change movq instruction to a leaq
1256 if ( fixUpLocation
[-2] != 0x8B )
1257 throw "GOT load reloc does not point to a movq instruction";
1258 fixUpLocation
[-2] = 0x8D;
1259 accumulator
= addressOf(state
, fit
, &toTarget
);
1260 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1261 rangeCheckRIP32(delta
, state
, atom
, fit
);
1262 set32LE(fixUpLocation
, delta
);
1264 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoadNowLEA
:
1265 // TLV entry was optimized away, change movq instruction to a leaq
1266 if ( fixUpLocation
[-2] != 0x8B )
1267 throw "TLV load reloc does not point to a movq instruction";
1268 fixUpLocation
[-2] = 0x8D;
1269 accumulator
= addressOf(state
, fit
, &toTarget
);
1270 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1271 rangeCheckRIP32(delta
, state
, atom
, fit
);
1272 set32LE(fixUpLocation
, delta
);
1274 case ld::Fixup::kindStoreTargetAddressARMBranch24
:
1275 accumulator
= addressOf(state
, fit
, &toTarget
);
1276 thumbTarget
= targetIsThumb(state
, fit
);
1279 if ( fit
->contentDetlaToAddendOnly
)
1281 // fall into kindStoreARMBranch24 case
1282 case ld::Fixup::kindStoreARMBranch24
:
1283 // The pc added will be +8 from the pc
1284 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 8);
1285 rangeCheckARMBranch24(delta
, state
, atom
, fit
);
1286 instruction
= get32LE(fixUpLocation
);
1287 // Make sure we are calling arm with bl, thumb with blx
1288 is_bl
= ((instruction
& 0xFF000000) == 0xEB000000);
1289 is_blx
= ((instruction
& 0xFE000000) == 0xFA000000);
1290 if ( is_bl
&& thumbTarget
) {
1291 uint32_t opcode
= 0xFA000000;
1292 uint32_t disp
= (uint32_t)(delta
>> 2) & 0x00FFFFFF;
1293 uint32_t h_bit
= (uint32_t)(delta
<< 23) & 0x01000000;
1294 newInstruction
= opcode
| h_bit
| disp
;
1296 else if ( is_blx
&& !thumbTarget
) {
1297 uint32_t opcode
= 0xEB000000;
1298 uint32_t disp
= (uint32_t)(delta
>> 2) & 0x00FFFFFF;
1299 newInstruction
= opcode
| disp
;
1301 else if ( !is_bl
&& !is_blx
&& thumbTarget
) {
1302 throwf("don't know how to convert instruction %x referencing %s to thumb",
1303 instruction
, referenceTargetAtomName(state
, fit
));
1306 newInstruction
= (instruction
& 0xFF000000) | ((uint32_t)(delta
>> 2) & 0x00FFFFFF);
1308 set32LE(fixUpLocation
, newInstruction
);
1310 case ld::Fixup::kindStoreTargetAddressThumbBranch22
:
1311 accumulator
= addressOf(state
, fit
, &toTarget
);
1312 thumbTarget
= targetIsThumb(state
, fit
);
1315 if ( fit
->contentDetlaToAddendOnly
)
1317 // fall into kindStoreThumbBranch22 case
1318 case ld::Fixup::kindStoreThumbBranch22
:
1319 instruction
= get32LE(fixUpLocation
);
1320 is_bl
= ((instruction
& 0xD000F800) == 0xD000F000);
1321 is_blx
= ((instruction
& 0xD000F800) == 0xC000F000);
1322 is_b
= ((instruction
& 0xD000F800) == 0x9000F000);
1323 // If the target is not thumb, we will be generating a blx instruction
1324 // Since blx cannot have the low bit set, set bit[1] of the target to
1325 // bit[1] of the base address, so that the difference is a multiple of
1327 if ( !thumbTarget
) {
1328 accumulator
&= -3ULL;
1329 accumulator
|= ((atom
->finalAddress() + fit
->offsetInAtom
) & 2LL);
1331 // The pc added will be +4 from the pc
1332 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
+ 4);
1333 rangeCheckThumbBranch22(delta
, state
, atom
, fit
);
1334 if ( _options
.preferSubArchitecture() && _options
.subArchitecture() == CPU_SUBTYPE_ARM_V7
) {
1335 // The instruction is really two instructions:
1336 // The lower 16 bits are the first instruction, which contains the high
1337 // 11 bits of the displacement.
1338 // The upper 16 bits are the second instruction, which contains the low
1339 // 11 bits of the displacement, as well as differentiating bl and blx.
1340 uint32_t s
= (uint32_t)(delta
>> 24) & 0x1;
1341 uint32_t i1
= (uint32_t)(delta
>> 23) & 0x1;
1342 uint32_t i2
= (uint32_t)(delta
>> 22) & 0x1;
1343 uint32_t imm10
= (uint32_t)(delta
>> 12) & 0x3FF;
1344 uint32_t imm11
= (uint32_t)(delta
>> 1) & 0x7FF;
1345 uint32_t j1
= (i1
== s
);
1346 uint32_t j2
= (i2
== s
);
1349 instruction
= 0xD000F000; // keep bl
1351 instruction
= 0xC000F000; // change to blx
1353 else if ( is_blx
) {
1355 instruction
= 0xD000F000; // change to bl
1357 instruction
= 0xC000F000; // keep blx
1361 throwf("don't know how to convert instruction %x referencing %s to arm",
1362 instruction
, referenceTargetAtomName(state
, fit
));
1363 instruction
= 0x9000F000; // keep b
1367 throwf("don't know how to convert branch instruction %x referencing %s to bx",
1368 instruction
, referenceTargetAtomName(state
, fit
));
1369 instruction
= 0x9000F000; // keep b
1371 uint32_t nextDisp
= (j1
<< 13) | (j2
<< 11) | imm11
;
1372 uint32_t firstDisp
= (s
<< 10) | imm10
;
1373 newInstruction
= instruction
| (nextDisp
<< 16) | firstDisp
;
1374 //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",
1375 // s, j1, j2, imm10, imm11, opcode, firstDisp, nextDisp, newInstruction, delta, inAtom->getDisplayName(), ref->getTarget().getDisplayName());
1376 set32LE(fixUpLocation
, newInstruction
);
1379 // The instruction is really two instructions:
1380 // The lower 16 bits are the first instruction, which contains the high
1381 // 11 bits of the displacement.
1382 // The upper 16 bits are the second instruction, which contains the low
1383 // 11 bits of the displacement, as well as differentiating bl and blx.
1384 uint32_t firstDisp
= (uint32_t)(delta
>> 12) & 0x7FF;
1385 uint32_t nextDisp
= (uint32_t)(delta
>> 1) & 0x7FF;
1386 if ( is_bl
&& !thumbTarget
) {
1387 instruction
= 0xE800F000;
1389 else if ( is_blx
&& thumbTarget
) {
1390 instruction
= 0xF800F000;
1392 else if ( !is_bl
&& !is_blx
&& !thumbTarget
) {
1393 throwf("don't know how to convert instruction %x referencing %s to arm",
1394 instruction
, referenceTargetAtomName(state
, fit
));
1397 instruction
= instruction
& 0xF800F800;
1399 newInstruction
= instruction
| (nextDisp
<< 16) | firstDisp
;
1400 set32LE(fixUpLocation
, newInstruction
);
1403 case ld::Fixup::kindStoreARMLow16
:
1405 uint32_t imm4
= (accumulator
& 0x0000F000) >> 12;
1406 uint32_t imm12
= accumulator
& 0x00000FFF;
1407 instruction
= get32LE(fixUpLocation
);
1408 newInstruction
= (instruction
& 0xFFF0F000) | (imm4
<< 16) | imm12
;
1409 set32LE(fixUpLocation
, newInstruction
);
1412 case ld::Fixup::kindStoreARMHigh16
:
1414 uint32_t imm4
= (accumulator
& 0xF0000000) >> 28;
1415 uint32_t imm12
= (accumulator
& 0x0FFF0000) >> 16;
1416 instruction
= get32LE(fixUpLocation
);
1417 newInstruction
= (instruction
& 0xFFF0F000) | (imm4
<< 16) | imm12
;
1418 set32LE(fixUpLocation
, newInstruction
);
1421 case ld::Fixup::kindStoreThumbLow16
:
1423 uint32_t imm4
= (accumulator
& 0x0000F000) >> 12;
1424 uint32_t i
= (accumulator
& 0x00000800) >> 11;
1425 uint32_t imm3
= (accumulator
& 0x00000700) >> 8;
1426 uint32_t imm8
= accumulator
& 0x000000FF;
1427 instruction
= get32LE(fixUpLocation
);
1428 newInstruction
= (instruction
& 0x8F00FBF0) | imm4
| (i
<< 10) | (imm3
<< 28) | (imm8
<< 16);
1429 set32LE(fixUpLocation
, newInstruction
);
1432 case ld::Fixup::kindStoreThumbHigh16
:
1434 uint32_t imm4
= (accumulator
& 0xF0000000) >> 28;
1435 uint32_t i
= (accumulator
& 0x08000000) >> 27;
1436 uint32_t imm3
= (accumulator
& 0x07000000) >> 24;
1437 uint32_t imm8
= (accumulator
& 0x00FF0000) >> 16;
1438 instruction
= get32LE(fixUpLocation
);
1439 newInstruction
= (instruction
& 0x8F00FBF0) | imm4
| (i
<< 10) | (imm3
<< 28) | (imm8
<< 16);
1440 set32LE(fixUpLocation
, newInstruction
);
1443 case ld::Fixup::kindStoreTargetAddressPPCBranch24
:
1444 accumulator
= addressOf(state
, fit
, &toTarget
);
1445 if ( fit
->contentDetlaToAddendOnly
)
1447 // fall into kindStorePPCBranch24 case
1448 case ld::Fixup::kindStorePPCBranch24
:
1449 delta
= accumulator
- (atom
->finalAddress() + fit
->offsetInAtom
);
1450 rangeCheckPPCBranch24(delta
, state
, atom
, fit
);
1451 instruction
= get32BE(fixUpLocation
);
1452 newInstruction
= (instruction
& 0xFC000003) | ((uint32_t)delta
& 0x03FFFFFC);
1453 set32BE(fixUpLocation
, newInstruction
);
1459 void OutputFile::copyNoOps(uint8_t* from
, uint8_t* to
)
1461 switch ( _options
.architecture() ) {
1462 case CPU_TYPE_POWERPC
:
1463 for (uint8_t* p
=from
; p
< to
; p
+= 4)
1464 OSWriteBigInt32((uint32_t*)p
, 0, 0x60000000);
1467 case CPU_TYPE_X86_64
:
1468 for (uint8_t* p
=from
; p
< to
; ++p
)
1472 // fixme: need thumb nop?
1473 for (uint8_t* p
=from
; p
< to
; p
+= 4)
1474 OSWriteBigInt32((uint32_t*)p
, 0, 0xe1a00000);
1477 for (uint8_t* p
=from
; p
< to
; ++p
)
1483 bool OutputFile::takesNoDiskSpace(const ld::Section
* sect
)
1485 switch ( sect
->type() ) {
1486 case ld::Section::typeZeroFill
:
1487 case ld::Section::typeTLVZeroFill
:
1488 return _options
.optimizeZeroFill();
1489 case ld::Section::typePageZero
:
1490 case ld::Section::typeStack
:
1491 case ld::Section::typeAbsoluteSymbols
:
1492 case ld::Section::typeTentativeDefs
:
1500 bool OutputFile::hasZeroForFileOffset(const ld::Section
* sect
)
1502 switch ( sect
->type() ) {
1503 case ld::Section::typeZeroFill
:
1504 case ld::Section::typeTLVZeroFill
:
1505 return _options
.optimizeZeroFill();
1506 case ld::Section::typePageZero
:
1507 case ld::Section::typeStack
:
1508 case ld::Section::typeTentativeDefs
:
1517 void OutputFile::writeOutputFile(ld::Internal
& state
)
1519 // for UNIX conformance, error if file exists and is not writable
1520 if ( (access(_options
.outputFilePath(), F_OK
) == 0) && (access(_options
.outputFilePath(), W_OK
) == -1) )
1521 throwf("can't write output file: %s", _options
.outputFilePath());
1523 int permissions
= 0777;
1524 if ( _options
.outputKind() == Options::kObjectFile
)
1526 // Calling unlink first assures the file is gone so that open creates it with correct permissions
1527 // It also handles the case where __options.outputFilePath() file is not writable but its directory is
1528 // And it means we don't have to truncate the file when done writing (in case new is smaller than old)
1529 // Lastly, only delete existing file if it is a normal file (e.g. not /dev/null).
1530 struct stat stat_buf
;
1531 if ( (stat(_options
.outputFilePath(), &stat_buf
) != -1) && (stat_buf
.st_mode
& S_IFREG
) )
1532 (void)unlink(_options
.outputFilePath());
1534 // try to allocate buffer for entire output file content
1535 uint8_t* wholeBuffer
= (uint8_t*)calloc(_fileSize
, 1);
1536 if ( wholeBuffer
== NULL
)
1537 throwf("can't create buffer of %llu bytes for output", _fileSize
);
1539 if ( _options
.UUIDMode() == Options::kUUIDRandom
) {
1541 ::uuid_generate_random(bits
);
1542 _headersAndLoadCommandAtom
->setUUID(bits
);
1545 // have each atom write itself
1546 uint64_t fileOffsetOfEndOfLastAtom
= 0;
1547 uint64_t mhAddress
= 0;
1548 bool lastAtomUsesNoOps
= false;
1549 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
1550 ld::Internal::FinalSection
* sect
= *sit
;
1551 if ( sect
->type() == ld::Section::typeMachHeader
)
1552 mhAddress
= sect
->address
;
1553 if ( takesNoDiskSpace(sect
) )
1555 const bool sectionUsesNops
= (sect
->type() == ld::Section::typeCode
);
1556 //fprintf(stderr, "file offset=0x%08llX, section %s\n", sect->fileOffset, sect->sectionName());
1557 std::vector
<const ld::Atom
*>& atoms
= sect
->atoms
;
1558 for (std::vector
<const ld::Atom
*>::iterator ait
= atoms
.begin(); ait
!= atoms
.end(); ++ait
) {
1559 const ld::Atom
* atom
= *ait
;
1560 if ( atom
->definition() == ld::Atom::definitionProxy
)
1563 uint64_t fileOffset
= atom
->finalAddress() - sect
->address
+ sect
->fileOffset
;
1564 // check for alignment padding between atoms
1565 if ( (fileOffset
!= fileOffsetOfEndOfLastAtom
) && lastAtomUsesNoOps
) {
1566 this->copyNoOps(&wholeBuffer
[fileOffsetOfEndOfLastAtom
], &wholeBuffer
[fileOffset
]);
1568 // copy atom content
1569 atom
->copyRawContent(&wholeBuffer
[fileOffset
]);
1571 this->applyFixUps(state
, mhAddress
, atom
, &wholeBuffer
[fileOffset
]);
1572 fileOffsetOfEndOfLastAtom
= fileOffset
+atom
->size();
1573 lastAtomUsesNoOps
= sectionUsesNops
;
1575 catch (const char* msg
) {
1576 if ( atom
->file() != NULL
)
1577 throwf("%s in %s from %s", msg
, atom
->name(), atom
->file()->path());
1579 throwf("%s in %s", msg
, atom
->name());
1585 if ( _options
.UUIDMode() == Options::kUUIDContent
) {
1586 const bool log
= false;
1587 if ( (_options
.outputKind() != Options::kObjectFile
) || state
.someObjectFileHasDwarf
) {
1588 uint8_t digest
[CC_MD5_DIGEST_LENGTH
];
1589 uint32_t stabsStringsOffsetStart
;
1590 uint32_t tabsStringsOffsetEnd
;
1591 uint32_t stabsOffsetStart
;
1592 uint32_t stabsOffsetEnd
;
1593 if ( _symbolTableAtom
->hasStabs(stabsStringsOffsetStart
, tabsStringsOffsetEnd
, stabsOffsetStart
, stabsOffsetEnd
) ) {
1594 // find two areas of file that are stabs info and should not contribute to checksum
1595 uint64_t stringPoolFileOffset
= 0;
1596 uint64_t symbolTableFileOffset
= 0;
1597 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
1598 ld::Internal::FinalSection
* sect
= *sit
;
1599 if ( sect
->type() == ld::Section::typeLinkEdit
) {
1600 if ( strcmp(sect
->sectionName(), "__string_pool") == 0 )
1601 stringPoolFileOffset
= sect
->fileOffset
;
1602 else if ( strcmp(sect
->sectionName(), "__symbol_table") == 0 )
1603 symbolTableFileOffset
= sect
->fileOffset
;
1606 uint64_t firstStabNlistFileOffset
= symbolTableFileOffset
+ stabsOffsetStart
;
1607 uint64_t lastStabNlistFileOffset
= symbolTableFileOffset
+ stabsOffsetEnd
;
1608 uint64_t firstStabStringFileOffset
= stringPoolFileOffset
+ stabsStringsOffsetStart
;
1609 uint64_t lastStabStringFileOffset
= stringPoolFileOffset
+ tabsStringsOffsetEnd
;
1610 if ( log
) fprintf(stderr
, "firstStabNlistFileOffset=0x%08llX\n", firstStabNlistFileOffset
);
1611 if ( log
) fprintf(stderr
, "lastStabNlistFileOffset=0x%08llX\n", lastStabNlistFileOffset
);
1612 if ( log
) fprintf(stderr
, "firstStabStringFileOffset=0x%08llX\n", firstStabStringFileOffset
);
1613 if ( log
) fprintf(stderr
, "lastStabStringFileOffset=0x%08llX\n", lastStabStringFileOffset
);
1614 assert(firstStabNlistFileOffset
<= firstStabStringFileOffset
);
1616 CC_MD5_CTX md5state
;
1617 CC_MD5_Init(&md5state
);
1618 // checksum everything up to first stabs nlist
1619 if ( log
) fprintf(stderr
, "checksum 0x%08X -> 0x%08llX\n", 0, firstStabNlistFileOffset
);
1620 CC_MD5_Update(&md5state
, &wholeBuffer
[0], firstStabNlistFileOffset
);
1621 // checkusm everything after last stabs nlist and up to first stabs string
1622 if ( log
) fprintf(stderr
, "checksum 0x%08llX -> 0x%08llX\n", lastStabNlistFileOffset
, firstStabStringFileOffset
);
1623 CC_MD5_Update(&md5state
, &wholeBuffer
[lastStabNlistFileOffset
], firstStabStringFileOffset
-lastStabNlistFileOffset
);
1624 // checksum everything after last stabs string to end of file
1625 if ( log
) fprintf(stderr
, "checksum 0x%08llX -> 0x%08llX\n", lastStabStringFileOffset
, _fileSize
);
1626 CC_MD5_Update(&md5state
, &wholeBuffer
[lastStabStringFileOffset
], _fileSize
-lastStabStringFileOffset
);
1627 CC_MD5_Final(digest
, &md5state
);
1628 if ( log
) fprintf(stderr
, "uuid=%02X, %02X, %02X, %02X, %02X, %02X, %02X, %02X\n", digest
[0], digest
[1], digest
[2],
1629 digest
[3], digest
[4], digest
[5], digest
[6], digest
[7]);
1632 CC_MD5(wholeBuffer
, _fileSize
, digest
);
1634 // <rdar://problem/6723729> LC_UUID uuids should conform to RFC 4122 UUID version 4 & UUID version 5 formats
1635 digest
[6] = ( digest
[6] & 0x0F ) | ( 3 << 4 );
1636 digest
[8] = ( digest
[8] & 0x3F ) | 0x80;
1637 // update buffer with new UUID
1638 _headersAndLoadCommandAtom
->setUUID(digest
);
1639 _headersAndLoadCommandAtom
->recopyUUIDCommand();
1643 // write whole output file in one chunk
1644 int fd
= open(_options
.outputFilePath(), O_CREAT
| O_WRONLY
| O_TRUNC
, permissions
);
1646 throwf("can't open output file for writing: %s, errno=%d", _options
.outputFilePath(), errno
);
1647 if ( ::pwrite(fd
, wholeBuffer
, _fileSize
, 0) == -1 )
1648 throwf("can't write to output file: %s, errno=%d", _options
.outputFilePath(), errno
);
1653 struct AtomByNameSorter
1655 bool operator()(const ld::Atom
* left
, const ld::Atom
* right
)
1657 return (strcmp(left
->name(), right
->name()) < 0);
1661 void OutputFile::buildSymbolTable(ld::Internal
& state
)
1663 unsigned int machoSectionIndex
= 0;
1664 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
1665 ld::Internal::FinalSection
* sect
= *sit
;
1666 bool setMachoSectionIndex
= !sect
->isSectionHidden() && (sect
->type() != ld::Section::typeTentativeDefs
);
1667 if ( setMachoSectionIndex
)
1668 ++machoSectionIndex
;
1669 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
1670 const ld::Atom
* atom
= *ait
;
1671 if ( setMachoSectionIndex
)
1672 (const_cast<ld::Atom
*>(atom
))->setMachoSection(machoSectionIndex
);
1673 else if ( sect
->type() == ld::Section::typeMachHeader
)
1674 (const_cast<ld::Atom
*>(atom
))->setMachoSection(1); // __mh_execute_header is not in any section by needs n_sect==1
1675 else if ( sect
->type() == ld::Section::typeLastSection
)
1676 (const_cast<ld::Atom
*>(atom
))->setMachoSection(machoSectionIndex
); // use section index of previous section
1677 else if ( sect
->type() == ld::Section::typeFirstSection
)
1678 (const_cast<ld::Atom
*>(atom
))->setMachoSection(machoSectionIndex
+1); // use section index of next section
1680 // in -r mode, clarify symbolTableNotInFinalLinkedImages
1681 if ( _options
.outputKind() == Options::kObjectFile
) {
1682 if ( _options
.architecture() == CPU_TYPE_X86_64
) {
1683 // x86_64 .o files need labels on anonymous literal strings
1684 if ( (sect
->type() == ld::Section::typeCString
) && (atom
->combine() == ld::Atom::combineByNameAndContent
) ) {
1685 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableIn
);
1686 _localAtoms
.push_back(atom
);
1690 if ( sect
->type() == ld::Section::typeCFI
) {
1691 if ( _options
.removeEHLabels() )
1692 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableNotIn
);
1694 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableIn
);
1696 if ( atom
->symbolTableInclusion() == ld::Atom::symbolTableNotInFinalLinkedImages
)
1697 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableIn
);
1700 // TEMP work around until <rdar://problem/7702923> goes in
1701 if ( (atom
->symbolTableInclusion() == ld::Atom::symbolTableInAndNeverStrip
)
1702 && (atom
->scope() == ld::Atom::scopeLinkageUnit
)
1703 && (_options
.outputKind() == Options::kDynamicLibrary
) ) {
1704 (const_cast<ld::Atom
*>(atom
))->setScope(ld::Atom::scopeGlobal
);
1707 // <rdar://problem/6783167> support auto hidden weak symbols: .weak_def_can_be_hidden
1708 if ( atom
->autoHide() && (_options
.outputKind() != Options::kObjectFile
) ) {
1709 // adding auto-hide symbol to .exp file should keep it global
1710 if ( !_options
.hasExportMaskList() || !_options
.shouldExport(atom
->name()) )
1711 (const_cast<ld::Atom
*>(atom
))->setScope(ld::Atom::scopeLinkageUnit
);
1714 // <rdar://problem/8626058> ld should consistently warn when resolvers are not exported
1715 if ( (atom
->contentType() == ld::Atom::typeResolver
) && (atom
->scope() == ld::Atom::scopeLinkageUnit
) )
1716 warning("resolver functions should be external, but '%s' is hidden", atom
->name());
1718 if ( sect
->type() == ld::Section::typeImportProxies
) {
1719 if ( atom
->combine() == ld::Atom::combineByName
)
1720 this->usesWeakExternalSymbols
= true;
1721 // alias proxy is a re-export with a name change, don't import changed name
1722 if ( ! atom
->isAlias() )
1723 _importedAtoms
.push_back(atom
);
1724 // scope of proxies are usually linkage unit, so done
1725 // if scope is global, we need to re-export it too
1726 if ( atom
->scope() == ld::Atom::scopeGlobal
)
1727 _exportedAtoms
.push_back(atom
);
1730 if ( atom
->symbolTableInclusion() == ld::Atom::symbolTableNotInFinalLinkedImages
) {
1731 assert(_options
.outputKind() != Options::kObjectFile
);
1732 continue; // don't add to symbol table
1734 if ( atom
->symbolTableInclusion() == ld::Atom::symbolTableNotIn
) {
1735 continue; // don't add to symbol table
1738 if ( (atom
->definition() == ld::Atom::definitionTentative
) && (_options
.outputKind() == Options::kObjectFile
) ) {
1739 if ( _options
.makeTentativeDefinitionsReal() ) {
1740 // -r -d turns tentative defintions into real def
1741 _exportedAtoms
.push_back(atom
);
1744 // in mach-o object files tentative defintions are stored like undefined symbols
1745 _importedAtoms
.push_back(atom
);
1750 // <rdar://problem/7977374> Add command line options to control symbol weak-def bit on exported symbols
1751 if ( _options
.hasWeakBitTweaks() && (atom
->definition() == ld::Atom::definitionRegular
) ) {
1752 const char* name
= atom
->name();
1753 if ( atom
->scope() == ld::Atom::scopeGlobal
) {
1754 if ( atom
->combine() == ld::Atom::combineNever
) {
1755 if ( _options
.forceWeak(name
) )
1756 (const_cast<ld::Atom
*>(atom
))->setCombine(ld::Atom::combineByName
);
1758 else if ( atom
->combine() == ld::Atom::combineByName
) {
1759 if ( _options
.forceNotWeak(name
) )
1760 (const_cast<ld::Atom
*>(atom
))->setCombine(ld::Atom::combineNever
);
1764 if ( _options
.forceWeakNonWildCard(name
) )
1765 warning("cannot force to be weak, non-external symbol %s", name
);
1766 else if ( _options
.forceNotWeakNonWildcard(name
) )
1767 warning("cannot force to be not-weak, non-external symbol %s", name
);
1771 switch ( atom
->scope() ) {
1772 case ld::Atom::scopeTranslationUnit
:
1773 if ( _options
.keepLocalSymbol(atom
->name()) ) {
1774 _localAtoms
.push_back(atom
);
1777 if ( _options
.outputKind() == Options::kObjectFile
) {
1778 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableInWithRandomAutoStripLabel
);
1779 _localAtoms
.push_back(atom
);
1782 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableNotIn
);
1785 case ld::Atom::scopeGlobal
:
1786 _exportedAtoms
.push_back(atom
);
1788 case ld::Atom::scopeLinkageUnit
:
1789 if ( _options
.outputKind() == Options::kObjectFile
) {
1790 if ( _options
.keepPrivateExterns() ) {
1791 assert( (atom
->combine() == ld::Atom::combineNever
) || (atom
->combine() == ld::Atom::combineByName
) );
1792 _exportedAtoms
.push_back(atom
);
1794 else if ( _options
.keepLocalSymbol(atom
->name()) ) {
1795 _localAtoms
.push_back(atom
);
1798 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableInWithRandomAutoStripLabel
);
1799 _localAtoms
.push_back(atom
);
1803 if ( _options
.keepLocalSymbol(atom
->name()) )
1804 _localAtoms
.push_back(atom
);
1806 (const_cast<ld::Atom
*>(atom
))->setSymbolTableInclusion(ld::Atom::symbolTableNotIn
);
1814 std::sort(_exportedAtoms
.begin(), _exportedAtoms
.end(), AtomByNameSorter());
1815 std::sort(_importedAtoms
.begin(), _importedAtoms
.end(), AtomByNameSorter());
1819 void OutputFile::addPreloadLinkEdit(ld::Internal
& state
)
1821 switch ( _options
.architecture() ) {
1823 if ( _hasLocalRelocations
) {
1824 _localRelocsAtom
= new LocalRelocationsAtom
<x86
>(_options
, state
, *this);
1825 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
1827 if ( _hasExternalRelocations
) {
1828 _externalRelocsAtom
= new ExternalRelocationsAtom
<x86
>(_options
, state
, *this);
1829 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
1831 if ( _hasSymbolTable
) {
1832 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<x86
>(_options
, state
, *this);
1833 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
1834 _symbolTableAtom
= new SymbolTableAtom
<x86
>(_options
, state
, *this);
1835 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
1836 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 4);
1837 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
1840 case CPU_TYPE_X86_64
:
1841 if ( _hasLocalRelocations
) {
1842 _localRelocsAtom
= new LocalRelocationsAtom
<x86_64
>(_options
, state
, *this);
1843 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
1845 if ( _hasExternalRelocations
) {
1846 _externalRelocsAtom
= new ExternalRelocationsAtom
<x86_64
>(_options
, state
, *this);
1847 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
1849 if ( _hasSymbolTable
) {
1850 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<x86_64
>(_options
, state
, *this);
1851 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
1852 _symbolTableAtom
= new SymbolTableAtom
<x86_64
>(_options
, state
, *this);
1853 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
1854 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 4);
1855 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
1859 if ( _hasLocalRelocations
) {
1860 _localRelocsAtom
= new LocalRelocationsAtom
<arm
>(_options
, state
, *this);
1861 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
1863 if ( _hasExternalRelocations
) {
1864 _externalRelocsAtom
= new ExternalRelocationsAtom
<arm
>(_options
, state
, *this);
1865 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
1867 if ( _hasSymbolTable
) {
1868 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<arm
>(_options
, state
, *this);
1869 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
1870 _symbolTableAtom
= new SymbolTableAtom
<arm
>(_options
, state
, *this);
1871 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
1872 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 4);
1873 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
1877 throw "architecture not supported for -preload";
1883 void OutputFile::addLinkEdit(ld::Internal
& state
)
1885 // for historical reasons, -preload orders LINKEDIT content differently
1886 if ( _options
.outputKind() == Options::kPreload
)
1887 return addPreloadLinkEdit(state
);
1889 switch ( _options
.architecture() ) {
1890 case CPU_TYPE_POWERPC
:
1891 if ( _hasSectionRelocations
) {
1892 _sectionsRelocationsAtom
= new SectionRelocationsAtom
<ppc
>(_options
, state
, *this);
1893 sectionRelocationsSection
= state
.addAtom(*_sectionsRelocationsAtom
);
1895 if ( _hasDyldInfo
) {
1896 _rebasingInfoAtom
= new RebaseInfoAtom
<ppc
>(_options
, state
, *this);
1897 rebaseSection
= state
.addAtom(*_rebasingInfoAtom
);
1899 _bindingInfoAtom
= new BindingInfoAtom
<ppc
>(_options
, state
, *this);
1900 bindingSection
= state
.addAtom(*_bindingInfoAtom
);
1902 _weakBindingInfoAtom
= new WeakBindingInfoAtom
<ppc
>(_options
, state
, *this);
1903 weakBindingSection
= state
.addAtom(*_weakBindingInfoAtom
);
1905 _lazyBindingInfoAtom
= new LazyBindingInfoAtom
<ppc
>(_options
, state
, *this);
1906 lazyBindingSection
= state
.addAtom(*_lazyBindingInfoAtom
);
1908 _exportInfoAtom
= new ExportInfoAtom
<ppc
>(_options
, state
, *this);
1909 exportSection
= state
.addAtom(*_exportInfoAtom
);
1911 if ( _hasLocalRelocations
) {
1912 _localRelocsAtom
= new LocalRelocationsAtom
<ppc
>(_options
, state
, *this);
1913 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
1915 if ( _hasSplitSegInfo
) {
1916 _splitSegInfoAtom
= new SplitSegInfoAtom
<ppc
>(_options
, state
, *this);
1917 splitSegInfoSection
= state
.addAtom(*_splitSegInfoAtom
);
1919 if ( _hasFunctionStartsInfo
) {
1920 _functionStartsAtom
= new FunctionStartsAtom
<ppc
>(_options
, state
, *this);
1921 functionStartsSection
= state
.addAtom(*_functionStartsAtom
);
1923 if ( _hasSymbolTable
) {
1924 _symbolTableAtom
= new SymbolTableAtom
<ppc
>(_options
, state
, *this);
1925 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
1927 if ( _hasExternalRelocations
) {
1928 _externalRelocsAtom
= new ExternalRelocationsAtom
<ppc
>(_options
, state
, *this);
1929 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
1931 if ( _hasSymbolTable
) {
1932 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<ppc
>(_options
, state
, *this);
1933 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
1934 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 4);
1935 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
1939 if ( _hasSectionRelocations
) {
1940 _sectionsRelocationsAtom
= new SectionRelocationsAtom
<x86
>(_options
, state
, *this);
1941 sectionRelocationsSection
= state
.addAtom(*_sectionsRelocationsAtom
);
1943 if ( _hasDyldInfo
) {
1944 _rebasingInfoAtom
= new RebaseInfoAtom
<x86
>(_options
, state
, *this);
1945 rebaseSection
= state
.addAtom(*_rebasingInfoAtom
);
1947 _bindingInfoAtom
= new BindingInfoAtom
<x86
>(_options
, state
, *this);
1948 bindingSection
= state
.addAtom(*_bindingInfoAtom
);
1950 _weakBindingInfoAtom
= new WeakBindingInfoAtom
<x86
>(_options
, state
, *this);
1951 weakBindingSection
= state
.addAtom(*_weakBindingInfoAtom
);
1953 _lazyBindingInfoAtom
= new LazyBindingInfoAtom
<x86
>(_options
, state
, *this);
1954 lazyBindingSection
= state
.addAtom(*_lazyBindingInfoAtom
);
1956 _exportInfoAtom
= new ExportInfoAtom
<x86
>(_options
, state
, *this);
1957 exportSection
= state
.addAtom(*_exportInfoAtom
);
1959 if ( _hasLocalRelocations
) {
1960 _localRelocsAtom
= new LocalRelocationsAtom
<x86
>(_options
, state
, *this);
1961 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
1963 if ( _hasSplitSegInfo
) {
1964 _splitSegInfoAtom
= new SplitSegInfoAtom
<x86
>(_options
, state
, *this);
1965 splitSegInfoSection
= state
.addAtom(*_splitSegInfoAtom
);
1967 if ( _hasFunctionStartsInfo
) {
1968 _functionStartsAtom
= new FunctionStartsAtom
<x86
>(_options
, state
, *this);
1969 functionStartsSection
= state
.addAtom(*_functionStartsAtom
);
1971 if ( _hasSymbolTable
) {
1972 _symbolTableAtom
= new SymbolTableAtom
<x86
>(_options
, state
, *this);
1973 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
1975 if ( _hasExternalRelocations
) {
1976 _externalRelocsAtom
= new ExternalRelocationsAtom
<x86
>(_options
, state
, *this);
1977 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
1979 if ( _hasSymbolTable
) {
1980 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<x86
>(_options
, state
, *this);
1981 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
1982 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 4);
1983 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
1986 case CPU_TYPE_X86_64
:
1987 if ( _hasSectionRelocations
) {
1988 _sectionsRelocationsAtom
= new SectionRelocationsAtom
<x86_64
>(_options
, state
, *this);
1989 sectionRelocationsSection
= state
.addAtom(*_sectionsRelocationsAtom
);
1991 if ( _hasDyldInfo
) {
1992 _rebasingInfoAtom
= new RebaseInfoAtom
<x86_64
>(_options
, state
, *this);
1993 rebaseSection
= state
.addAtom(*_rebasingInfoAtom
);
1995 _bindingInfoAtom
= new BindingInfoAtom
<x86_64
>(_options
, state
, *this);
1996 bindingSection
= state
.addAtom(*_bindingInfoAtom
);
1998 _weakBindingInfoAtom
= new WeakBindingInfoAtom
<x86_64
>(_options
, state
, *this);
1999 weakBindingSection
= state
.addAtom(*_weakBindingInfoAtom
);
2001 _lazyBindingInfoAtom
= new LazyBindingInfoAtom
<x86_64
>(_options
, state
, *this);
2002 lazyBindingSection
= state
.addAtom(*_lazyBindingInfoAtom
);
2004 _exportInfoAtom
= new ExportInfoAtom
<x86_64
>(_options
, state
, *this);
2005 exportSection
= state
.addAtom(*_exportInfoAtom
);
2007 if ( _hasLocalRelocations
) {
2008 _localRelocsAtom
= new LocalRelocationsAtom
<x86_64
>(_options
, state
, *this);
2009 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
2011 if ( _hasSplitSegInfo
) {
2012 _splitSegInfoAtom
= new SplitSegInfoAtom
<x86_64
>(_options
, state
, *this);
2013 splitSegInfoSection
= state
.addAtom(*_splitSegInfoAtom
);
2015 if ( _hasFunctionStartsInfo
) {
2016 _functionStartsAtom
= new FunctionStartsAtom
<x86_64
>(_options
, state
, *this);
2017 functionStartsSection
= state
.addAtom(*_functionStartsAtom
);
2019 if ( _hasSymbolTable
) {
2020 _symbolTableAtom
= new SymbolTableAtom
<x86_64
>(_options
, state
, *this);
2021 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
2023 if ( _hasExternalRelocations
) {
2024 _externalRelocsAtom
= new ExternalRelocationsAtom
<x86_64
>(_options
, state
, *this);
2025 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
2027 if ( _hasSymbolTable
) {
2028 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<x86_64
>(_options
, state
, *this);
2029 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
2030 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 8);
2031 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
2035 if ( _hasSectionRelocations
) {
2036 _sectionsRelocationsAtom
= new SectionRelocationsAtom
<arm
>(_options
, state
, *this);
2037 sectionRelocationsSection
= state
.addAtom(*_sectionsRelocationsAtom
);
2039 if ( _hasDyldInfo
) {
2040 _rebasingInfoAtom
= new RebaseInfoAtom
<arm
>(_options
, state
, *this);
2041 rebaseSection
= state
.addAtom(*_rebasingInfoAtom
);
2043 _bindingInfoAtom
= new BindingInfoAtom
<arm
>(_options
, state
, *this);
2044 bindingSection
= state
.addAtom(*_bindingInfoAtom
);
2046 _weakBindingInfoAtom
= new WeakBindingInfoAtom
<arm
>(_options
, state
, *this);
2047 weakBindingSection
= state
.addAtom(*_weakBindingInfoAtom
);
2049 _lazyBindingInfoAtom
= new LazyBindingInfoAtom
<arm
>(_options
, state
, *this);
2050 lazyBindingSection
= state
.addAtom(*_lazyBindingInfoAtom
);
2052 _exportInfoAtom
= new ExportInfoAtom
<arm
>(_options
, state
, *this);
2053 exportSection
= state
.addAtom(*_exportInfoAtom
);
2055 if ( _hasLocalRelocations
) {
2056 _localRelocsAtom
= new LocalRelocationsAtom
<arm
>(_options
, state
, *this);
2057 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
2059 if ( _hasSplitSegInfo
) {
2060 _splitSegInfoAtom
= new SplitSegInfoAtom
<arm
>(_options
, state
, *this);
2061 splitSegInfoSection
= state
.addAtom(*_splitSegInfoAtom
);
2063 if ( _hasFunctionStartsInfo
) {
2064 _functionStartsAtom
= new FunctionStartsAtom
<arm
>(_options
, state
, *this);
2065 functionStartsSection
= state
.addAtom(*_functionStartsAtom
);
2067 if ( _hasSymbolTable
) {
2068 _symbolTableAtom
= new SymbolTableAtom
<arm
>(_options
, state
, *this);
2069 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
2071 if ( _hasExternalRelocations
) {
2072 _externalRelocsAtom
= new ExternalRelocationsAtom
<arm
>(_options
, state
, *this);
2073 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
2075 if ( _hasSymbolTable
) {
2076 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<arm
>(_options
, state
, *this);
2077 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
2078 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 4);
2079 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
2082 case CPU_TYPE_POWERPC64
:
2083 if ( _hasSectionRelocations
) {
2084 _sectionsRelocationsAtom
= new SectionRelocationsAtom
<ppc64
>(_options
, state
, *this);
2085 sectionRelocationsSection
= state
.addAtom(*_sectionsRelocationsAtom
);
2087 if ( _hasDyldInfo
) {
2088 _rebasingInfoAtom
= new RebaseInfoAtom
<ppc64
>(_options
, state
, *this);
2089 rebaseSection
= state
.addAtom(*_rebasingInfoAtom
);
2091 _bindingInfoAtom
= new BindingInfoAtom
<ppc64
>(_options
, state
, *this);
2092 bindingSection
= state
.addAtom(*_bindingInfoAtom
);
2094 _weakBindingInfoAtom
= new WeakBindingInfoAtom
<ppc64
>(_options
, state
, *this);
2095 weakBindingSection
= state
.addAtom(*_weakBindingInfoAtom
);
2097 _lazyBindingInfoAtom
= new LazyBindingInfoAtom
<ppc64
>(_options
, state
, *this);
2098 lazyBindingSection
= state
.addAtom(*_lazyBindingInfoAtom
);
2100 _exportInfoAtom
= new ExportInfoAtom
<ppc64
>(_options
, state
, *this);
2101 exportSection
= state
.addAtom(*_exportInfoAtom
);
2103 if ( _hasLocalRelocations
) {
2104 _localRelocsAtom
= new LocalRelocationsAtom
<ppc64
>(_options
, state
, *this);
2105 localRelocationsSection
= state
.addAtom(*_localRelocsAtom
);
2107 if ( _hasSplitSegInfo
) {
2108 _splitSegInfoAtom
= new SplitSegInfoAtom
<ppc64
>(_options
, state
, *this);
2109 splitSegInfoSection
= state
.addAtom(*_splitSegInfoAtom
);
2111 if ( _hasFunctionStartsInfo
) {
2112 _functionStartsAtom
= new FunctionStartsAtom
<ppc64
>(_options
, state
, *this);
2113 functionStartsSection
= state
.addAtom(*_functionStartsAtom
);
2115 if ( _hasSymbolTable
) {
2116 _symbolTableAtom
= new SymbolTableAtom
<ppc64
>(_options
, state
, *this);
2117 symbolTableSection
= state
.addAtom(*_symbolTableAtom
);
2119 if ( _hasExternalRelocations
) {
2120 _externalRelocsAtom
= new ExternalRelocationsAtom
<ppc64
>(_options
, state
, *this);
2121 externalRelocationsSection
= state
.addAtom(*_externalRelocsAtom
);
2123 if ( _hasSymbolTable
) {
2124 _indirectSymbolTableAtom
= new IndirectSymbolTableAtom
<ppc64
>(_options
, state
, *this);
2125 indirectSymbolTableSection
= state
.addAtom(*_indirectSymbolTableAtom
);
2126 _stringPoolAtom
= new StringPoolAtom(_options
, state
, *this, 4);
2127 stringPoolSection
= state
.addAtom(*_stringPoolAtom
);
2131 throw "unknown architecture";
2135 void OutputFile::addLoadCommands(ld::Internal
& state
)
2137 switch ( _options
.architecture() ) {
2138 case CPU_TYPE_X86_64
:
2139 _headersAndLoadCommandAtom
= new HeaderAndLoadCommandsAtom
<x86_64
>(_options
, state
, *this);
2140 headerAndLoadCommandsSection
= state
.addAtom(*_headersAndLoadCommandAtom
);
2143 _headersAndLoadCommandAtom
= new HeaderAndLoadCommandsAtom
<arm
>(_options
, state
, *this);
2144 headerAndLoadCommandsSection
= state
.addAtom(*_headersAndLoadCommandAtom
);
2147 _headersAndLoadCommandAtom
= new HeaderAndLoadCommandsAtom
<x86
>(_options
, state
, *this);
2148 headerAndLoadCommandsSection
= state
.addAtom(*_headersAndLoadCommandAtom
);
2150 case CPU_TYPE_POWERPC
:
2151 _headersAndLoadCommandAtom
= new HeaderAndLoadCommandsAtom
<ppc
>(_options
, state
, *this);
2152 headerAndLoadCommandsSection
= state
.addAtom(*_headersAndLoadCommandAtom
);
2154 case CPU_TYPE_POWERPC64
:
2155 _headersAndLoadCommandAtom
= new HeaderAndLoadCommandsAtom
<ppc64
>(_options
, state
, *this);
2156 headerAndLoadCommandsSection
= state
.addAtom(*_headersAndLoadCommandAtom
);
2159 throw "unknown architecture";
2163 uint32_t OutputFile::dylibCount()
2165 return _dylibsToLoad
.size();
2168 const ld::dylib::File
* OutputFile::dylibByOrdinal(unsigned int ordinal
)
2170 assert( ordinal
> 0 );
2171 assert( ordinal
<= _dylibsToLoad
.size() );
2172 return _dylibsToLoad
[ordinal
-1];
2175 bool OutputFile::hasOrdinalForInstallPath(const char* path
, int* ordinal
)
2177 for (std::map
<const ld::dylib::File
*, int>::const_iterator it
= _dylibToOrdinal
.begin(); it
!= _dylibToOrdinal
.end(); ++it
) {
2178 const char* installPath
= it
->first
->installPath();
2179 if ( (installPath
!= NULL
) && (strcmp(path
, installPath
) == 0) ) {
2180 *ordinal
= it
->second
;
2187 uint32_t OutputFile::dylibToOrdinal(const ld::dylib::File
* dylib
)
2189 return _dylibToOrdinal
[dylib
];
2193 void OutputFile::buildDylibOrdinalMapping(ld::Internal
& state
)
2195 // count non-public re-exported dylibs
2196 unsigned int nonPublicReExportCount
= 0;
2197 for (std::vector
<ld::dylib::File
*>::iterator it
= state
.dylibs
.begin(); it
!= state
.dylibs
.end(); ++it
) {
2198 ld::dylib::File
* aDylib
= *it
;
2199 if ( aDylib
->willBeReExported() && ! aDylib
->hasPublicInstallName() )
2200 ++nonPublicReExportCount
;
2203 // look at each dylib supplied in state
2204 bool hasReExports
= false;
2205 bool haveLazyDylibs
= false;
2206 for (std::vector
<ld::dylib::File
*>::iterator it
= state
.dylibs
.begin(); it
!= state
.dylibs
.end(); ++it
) {
2207 ld::dylib::File
* aDylib
= *it
;
2209 if ( aDylib
== state
.bundleLoader
) {
2210 _dylibToOrdinal
[aDylib
] = BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE
;
2212 else if ( this->hasOrdinalForInstallPath(aDylib
->installPath(), &ordinal
) ) {
2213 // already have a dylib with that install path, map all uses to that ordinal
2214 _dylibToOrdinal
[aDylib
] = ordinal
;
2216 else if ( aDylib
->willBeLazyLoadedDylib() ) {
2217 // all lazy dylib need to be at end of ordinals
2218 haveLazyDylibs
= true;
2220 else if ( aDylib
->willBeReExported() && ! aDylib
->hasPublicInstallName() && (nonPublicReExportCount
>= 2) ) {
2221 _dylibsToLoad
.push_back(aDylib
);
2222 _dylibToOrdinal
[aDylib
] = BIND_SPECIAL_DYLIB_SELF
;
2225 // first time this install path seen, create new ordinal
2226 _dylibsToLoad
.push_back(aDylib
);
2227 _dylibToOrdinal
[aDylib
] = _dylibsToLoad
.size();
2229 if ( aDylib
->explicitlyLinked() && aDylib
->willBeReExported() )
2230 hasReExports
= true;
2232 if ( haveLazyDylibs
) {
2233 // second pass to determine ordinals for lazy loaded dylibs
2234 for (std::vector
<ld::dylib::File
*>::iterator it
= state
.dylibs
.begin(); it
!= state
.dylibs
.end(); ++it
) {
2235 ld::dylib::File
* aDylib
= *it
;
2236 if ( aDylib
->willBeLazyLoadedDylib() ) {
2238 if ( this->hasOrdinalForInstallPath(aDylib
->installPath(), &ordinal
) ) {
2239 // already have a dylib with that install path, map all uses to that ordinal
2240 _dylibToOrdinal
[aDylib
] = ordinal
;
2243 // first time this install path seen, create new ordinal
2244 _dylibsToLoad
.push_back(aDylib
);
2245 _dylibToOrdinal
[aDylib
] = _dylibsToLoad
.size();
2250 _noReExportedDylibs
= !hasReExports
;
2251 //fprintf(stderr, "dylibs:\n");
2252 //for (std::map<const ld::dylib::File*, int>::const_iterator it = _dylibToOrdinal.begin(); it != _dylibToOrdinal.end(); ++it) {
2253 // fprintf(stderr, " %p ord=%u, install_name=%s\n",it->first, it->second, it->first->installPath());
2257 uint32_t OutputFile::lazyBindingInfoOffsetForLazyPointerAddress(uint64_t lpAddress
)
2259 return _lazyPointerAddressToInfoOffset
[lpAddress
];
2262 void OutputFile::setLazyBindingInfoOffset(uint64_t lpAddress
, uint32_t lpInfoOffset
)
2264 _lazyPointerAddressToInfoOffset
[lpAddress
] = lpInfoOffset
;
2267 int OutputFile::compressedOrdinalForAtom(const ld::Atom
* target
)
2269 // flat namespace images use zero for all ordinals
2270 if ( _options
.nameSpace() != Options::kTwoLevelNameSpace
)
2271 return BIND_SPECIAL_DYLIB_FLAT_LOOKUP
;
2273 // handle -interposable
2274 if ( target
->definition() == ld::Atom::definitionRegular
)
2275 return BIND_SPECIAL_DYLIB_SELF
;
2278 const ld::dylib::File
* dylib
= dynamic_cast<const ld::dylib::File
*>(target
->file());
2279 if ( dylib
!= NULL
)
2280 return _dylibToOrdinal
[dylib
];
2282 // handle undefined dynamic_lookup
2283 if ( _options
.undefinedTreatment() == Options::kUndefinedDynamicLookup
)
2284 return BIND_SPECIAL_DYLIB_FLAT_LOOKUP
;
2287 if ( _options
.allowedUndefined(target
->name()) )
2288 return BIND_SPECIAL_DYLIB_FLAT_LOOKUP
;
2290 throw "can't find ordinal for imported symbol";
2294 bool OutputFile::isPcRelStore(ld::Fixup::Kind kind
)
2297 case ld::Fixup::kindStoreX86BranchPCRel8
:
2298 case ld::Fixup::kindStoreX86BranchPCRel32
:
2299 case ld::Fixup::kindStoreX86PCRel8
:
2300 case ld::Fixup::kindStoreX86PCRel16
:
2301 case ld::Fixup::kindStoreX86PCRel32
:
2302 case ld::Fixup::kindStoreX86PCRel32_1
:
2303 case ld::Fixup::kindStoreX86PCRel32_2
:
2304 case ld::Fixup::kindStoreX86PCRel32_4
:
2305 case ld::Fixup::kindStoreX86PCRel32GOTLoad
:
2306 case ld::Fixup::kindStoreX86PCRel32GOTLoadNowLEA
:
2307 case ld::Fixup::kindStoreX86PCRel32GOT
:
2308 case ld::Fixup::kindStoreX86PCRel32TLVLoad
:
2309 case ld::Fixup::kindStoreX86PCRel32TLVLoadNowLEA
:
2310 case ld::Fixup::kindStoreARMBranch24
:
2311 case ld::Fixup::kindStoreThumbBranch22
:
2312 case ld::Fixup::kindStoreARMLoad12
:
2313 case ld::Fixup::kindStorePPCBranch24
:
2314 case ld::Fixup::kindStorePPCBranch14
:
2315 case ld::Fixup::kindStorePPCPicLow14
:
2316 case ld::Fixup::kindStorePPCPicLow16
:
2317 case ld::Fixup::kindStorePPCPicHigh16AddLow
:
2318 case ld::Fixup::kindStoreTargetAddressX86PCRel32
:
2319 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad
:
2320 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA
:
2321 case ld::Fixup::kindStoreTargetAddressARMBranch24
:
2322 case ld::Fixup::kindStoreTargetAddressThumbBranch22
:
2323 case ld::Fixup::kindStoreTargetAddressARMLoad12
:
2324 case ld::Fixup::kindStoreTargetAddressPPCBranch24
:
2326 case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32
:
2327 return (_options
.outputKind() != Options::kKextBundle
);
2334 bool OutputFile::isStore(ld::Fixup::Kind kind
)
2337 case ld::Fixup::kindNone
:
2338 case ld::Fixup::kindNoneFollowOn
:
2339 case ld::Fixup::kindNoneGroupSubordinate
:
2340 case ld::Fixup::kindNoneGroupSubordinateFDE
:
2341 case ld::Fixup::kindNoneGroupSubordinateLSDA
:
2342 case ld::Fixup::kindNoneGroupSubordinatePersonality
:
2343 case ld::Fixup::kindSetTargetAddress
:
2344 case ld::Fixup::kindSubtractTargetAddress
:
2345 case ld::Fixup::kindAddAddend
:
2346 case ld::Fixup::kindSubtractAddend
:
2347 case ld::Fixup::kindSetTargetImageOffset
:
2348 case ld::Fixup::kindSetTargetSectionOffset
:
2357 bool OutputFile::setsTarget(ld::Fixup::Kind kind
)
2360 case ld::Fixup::kindSetTargetAddress
:
2361 case ld::Fixup::kindLazyTarget
:
2362 case ld::Fixup::kindStoreTargetAddressLittleEndian32
:
2363 case ld::Fixup::kindStoreTargetAddressLittleEndian64
:
2364 case ld::Fixup::kindStoreTargetAddressBigEndian32
:
2365 case ld::Fixup::kindStoreTargetAddressBigEndian64
:
2366 case ld::Fixup::kindStoreTargetAddressX86PCRel32
:
2367 case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32
:
2368 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad
:
2369 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA
:
2370 case ld::Fixup::kindStoreTargetAddressARMBranch24
:
2371 case ld::Fixup::kindStoreTargetAddressThumbBranch22
:
2372 case ld::Fixup::kindStoreTargetAddressARMLoad12
:
2373 case ld::Fixup::kindStoreTargetAddressPPCBranch24
:
2375 case ld::Fixup::kindStoreX86DtraceCallSiteNop
:
2376 case ld::Fixup::kindStoreX86DtraceIsEnableSiteClear
:
2377 case ld::Fixup::kindStoreARMDtraceCallSiteNop
:
2378 case ld::Fixup::kindStoreARMDtraceIsEnableSiteClear
:
2379 case ld::Fixup::kindStoreThumbDtraceCallSiteNop
:
2380 case ld::Fixup::kindStoreThumbDtraceIsEnableSiteClear
:
2381 case ld::Fixup::kindStorePPCDtraceCallSiteNop
:
2382 case ld::Fixup::kindStorePPCDtraceIsEnableSiteClear
:
2383 return (_options
.outputKind() == Options::kObjectFile
);
2390 bool OutputFile::isPointerToTarget(ld::Fixup::Kind kind
)
2393 case ld::Fixup::kindSetTargetAddress
:
2394 case ld::Fixup::kindStoreTargetAddressLittleEndian32
:
2395 case ld::Fixup::kindStoreTargetAddressLittleEndian64
:
2396 case ld::Fixup::kindStoreTargetAddressBigEndian32
:
2397 case ld::Fixup::kindStoreTargetAddressBigEndian64
:
2398 case ld::Fixup::kindLazyTarget
:
2405 bool OutputFile::isPointerFromTarget(ld::Fixup::Kind kind
)
2408 case ld::Fixup::kindSubtractTargetAddress
:
2417 uint64_t OutputFile::lookBackAddend(ld::Fixup::iterator fit
)
2419 uint64_t addend
= 0;
2420 switch ( fit
->clusterSize
) {
2421 case ld::Fixup::k1of1
:
2422 case ld::Fixup::k1of2
:
2423 case ld::Fixup::k2of2
:
2425 case ld::Fixup::k2of3
:
2427 switch ( fit
->kind
) {
2428 case ld::Fixup::kindAddAddend
:
2429 addend
+= fit
->u
.addend
;
2431 case ld::Fixup::kindSubtractAddend
:
2432 addend
-= fit
->u
.addend
;
2435 throw "unexpected fixup kind for binding";
2438 case ld::Fixup::k1of3
:
2440 switch ( fit
->kind
) {
2441 case ld::Fixup::kindAddAddend
:
2442 addend
+= fit
->u
.addend
;
2444 case ld::Fixup::kindSubtractAddend
:
2445 addend
-= fit
->u
.addend
;
2448 throw "unexpected fixup kind for binding";
2452 throw "unexpected fixup cluster size for binding";
2461 void OutputFile::generateLinkEditInfo(ld::Internal
& state
)
2463 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
2464 ld::Internal::FinalSection
* sect
= *sit
;
2465 bool objc1ClassRefSection
= ( (sect
->type() == ld::Section::typeCStringPointer
)
2466 && (strcmp(sect
->sectionName(), "__cls_refs") == 0)
2467 && (strcmp(sect
->segmentName(), "__OBJC") == 0) );
2468 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
2469 const ld::Atom
* atom
= *ait
;
2471 // Record regular atoms that override a dylib's weak definitions
2472 if ( (atom
->scope() == ld::Atom::scopeGlobal
) && atom
->overridesDylibsWeakDef() ) {
2473 if ( _options
.makeCompressedDyldInfo() ) {
2474 uint8_t wtype
= BIND_TYPE_OVERRIDE_OF_WEAKDEF_IN_DYLIB
;
2475 bool nonWeakDef
= (atom
->combine() == ld::Atom::combineNever
);
2476 _weakBindingInfo
.push_back(BindingInfo(wtype
, atom
->name(), nonWeakDef
, atom
->finalAddress(), 0));
2478 this->overridesWeakExternalSymbols
= true;
2479 if ( _options
.warnWeakExports() )
2480 warning("overrides weak external symbol: %s", atom
->name());
2483 ld::Fixup
* fixupWithTarget
= NULL
;
2484 ld::Fixup
* fixupWithMinusTarget
= NULL
;
2485 ld::Fixup
* fixupWithStore
= NULL
;
2486 const ld::Atom
* target
= NULL
;
2487 const ld::Atom
* minusTarget
= NULL
;
2488 uint64_t targetAddend
= 0;
2489 uint64_t minusTargetAddend
= 0;
2490 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(); fit
!= atom
->fixupsEnd(); ++fit
) {
2491 if ( fit
->firstInCluster() ) {
2492 fixupWithTarget
= NULL
;
2493 fixupWithMinusTarget
= NULL
;
2494 fixupWithStore
= NULL
;
2498 minusTargetAddend
= 0;
2500 if ( this->setsTarget(fit
->kind
) ) {
2501 switch ( fit
->binding
) {
2502 case ld::Fixup::bindingNone
:
2503 case ld::Fixup::bindingByNameUnbound
:
2505 case ld::Fixup::bindingByContentBound
:
2506 case ld::Fixup::bindingDirectlyBound
:
2507 fixupWithTarget
= fit
;
2508 target
= fit
->u
.target
;
2510 case ld::Fixup::bindingsIndirectlyBound
:
2511 fixupWithTarget
= fit
;
2512 target
= state
.indirectBindingTable
[fit
->u
.bindingIndex
];
2515 assert(target
!= NULL
);
2517 switch ( fit
->kind
) {
2518 case ld::Fixup::kindAddAddend
:
2519 targetAddend
= fit
->u
.addend
;
2521 case ld::Fixup::kindSubtractAddend
:
2522 minusTargetAddend
= fit
->u
.addend
;
2524 case ld::Fixup::kindSubtractTargetAddress
:
2525 switch ( fit
->binding
) {
2526 case ld::Fixup::bindingNone
:
2527 case ld::Fixup::bindingByNameUnbound
:
2529 case ld::Fixup::bindingByContentBound
:
2530 case ld::Fixup::bindingDirectlyBound
:
2531 fixupWithMinusTarget
= fit
;
2532 minusTarget
= fit
->u
.target
;
2534 case ld::Fixup::bindingsIndirectlyBound
:
2535 fixupWithMinusTarget
= fit
;
2536 minusTarget
= state
.indirectBindingTable
[fit
->u
.bindingIndex
];
2539 assert(minusTarget
!= NULL
);
2544 if ( this->isStore(fit
->kind
) ) {
2545 fixupWithStore
= fit
;
2547 if ( fit
->lastInCluster() ) {
2548 if ( (fixupWithStore
!= NULL
) && (target
!= NULL
) ) {
2549 if ( _options
.outputKind() == Options::kObjectFile
) {
2550 this->addSectionRelocs(state
, sect
, atom
, fixupWithTarget
, fixupWithMinusTarget
, fixupWithStore
,
2551 target
, minusTarget
, targetAddend
, minusTargetAddend
);
2554 if ( _options
.makeCompressedDyldInfo() ) {
2555 this->addDyldInfo(state
, sect
, atom
, fixupWithTarget
, fixupWithMinusTarget
, fixupWithStore
,
2556 target
, minusTarget
, targetAddend
, minusTargetAddend
);
2559 this->addClassicRelocs(state
, sect
, atom
, fixupWithTarget
, fixupWithMinusTarget
, fixupWithStore
,
2560 target
, minusTarget
, targetAddend
, minusTargetAddend
);
2564 else if ( objc1ClassRefSection
&& (target
!= NULL
) && (fixupWithStore
== NULL
) ) {
2565 // check for class refs to lazy loaded dylibs
2566 const ld::dylib::File
* dylib
= dynamic_cast<const ld::dylib::File
*>(target
->file());
2567 if ( (dylib
!= NULL
) && dylib
->willBeLazyLoadedDylib() )
2568 throwf("illegal class reference to %s in lazy loaded dylib %s", target
->name(), dylib
->path());
2577 void OutputFile::noteTextReloc(const ld::Atom
* atom
, const ld::Atom
* target
)
2579 if ( (atom
->contentType() == ld::Atom::typeStub
) || (atom
->contentType() == ld::Atom::typeStubHelper
) ) {
2580 // silently let stubs (synthesized by linker) use text relocs
2582 else if ( _options
.allowTextRelocs() ) {
2583 if ( _options
.warnAboutTextRelocs() )
2584 warning("text reloc in %s to %s", atom
->name(), target
->name());
2586 else if ( _options
.positionIndependentExecutable() && (_options
.iphoneOSVersionMin() >= ld::iPhone4_3
) ) {
2587 if ( ! this->pieDisabled
) {
2588 warning("PIE disabled. Absolute addressing (perhaps -mdynamic-no-pic) not allowed in code signed PIE, "
2589 "but used in %s from %s. "
2590 "To fix this warning, don't compile with -mdynamic-no-pic or link with -Wl,-no_pie",
2591 atom
->name(), atom
->file()->path());
2593 this->pieDisabled
= true;
2596 throwf("illegal text reloc to %s from %s in %s", target
->name(), target
->file()->path(), atom
->name());
2600 void OutputFile::addDyldInfo(ld::Internal
& state
, ld::Internal::FinalSection
* sect
, const ld::Atom
* atom
,
2601 ld::Fixup
* fixupWithTarget
, ld::Fixup
* fixupWithMinusTarget
, ld::Fixup
* fixupWithStore
,
2602 const ld::Atom
* target
, const ld::Atom
* minusTarget
,
2603 uint64_t targetAddend
, uint64_t minusTargetAddend
)
2605 if ( sect
->isSectionHidden() )
2608 // no need to rebase or bind PCRel stores
2609 if ( this->isPcRelStore(fixupWithStore
->kind
) ) {
2610 // as long as target is in same linkage unit
2611 if ( (target
== NULL
) || (target
->definition() != ld::Atom::definitionProxy
) )
2615 // no need to rebase or bind PIC internal pointer diff
2616 if ( minusTarget
!= NULL
) {
2617 // with pointer diffs, both need to be in same linkage unit
2618 assert(minusTarget
->definition() != ld::Atom::definitionProxy
);
2619 assert(target
!= NULL
);
2620 assert(target
->definition() != ld::Atom::definitionProxy
);
2621 if ( target
== minusTarget
) {
2622 // This is a compile time constant and could have been optimized away by compiler
2626 // make sure target is not global and weak
2627 if ( (target
->scope() == ld::Atom::scopeGlobal
) && (target
->combine() == ld::Atom::combineByName
)
2628 && (atom
->section().type() != ld::Section::typeCFI
)
2629 && (atom
->section().type() != ld::Section::typeDtraceDOF
)
2630 && (atom
->section().type() != ld::Section::typeUnwindInfo
) ) {
2631 // ok for __eh_frame and __uwind_info to use pointer diffs to global weak symbols
2632 throwf("bad codegen, pointer diff in %s to global weak symbol %s", atom
->name(), target
->name());
2637 // no need to rebase or bind an atom's references to itself if the output is not slidable
2638 if ( (atom
== target
) && !_options
.outputSlidable() )
2641 // cluster has no target, so needs no rebasing or binding
2642 if ( target
== NULL
)
2645 bool inReadOnlySeg
= ( strcmp(sect
->segmentName(), "__TEXT") == 0 );
2646 bool needsRebase
= false;
2647 bool needsBinding
= false;
2648 bool needsLazyBinding
= false;
2649 bool needsWeakBinding
= false;
2651 uint8_t rebaseType
= REBASE_TYPE_POINTER
;
2652 uint8_t type
= BIND_TYPE_POINTER
;
2653 const ld::dylib::File
* dylib
= dynamic_cast<const ld::dylib::File
*>(target
->file());
2654 bool weak_import
= ((dylib
!= NULL
) && (fixupWithTarget
->weakImport
|| dylib
->willBeWeakLinked()));
2655 uint64_t address
= atom
->finalAddress() + fixupWithTarget
->offsetInAtom
;
2656 uint64_t addend
= targetAddend
- minusTargetAddend
;
2658 // special case lazy pointers
2659 if ( fixupWithTarget
->kind
== ld::Fixup::kindLazyTarget
) {
2660 assert(fixupWithTarget
->u
.target
== target
);
2661 assert(addend
== 0);
2662 // lazy dylib lazy pointers do not have any dyld info
2663 if ( atom
->section().type() == ld::Section::typeLazyDylibPointer
)
2665 // lazy binding to weak definitions are done differently
2666 // they are directly bound to target, then have a weak bind in case of a collision
2667 if ( target
->combine() == ld::Atom::combineByName
) {
2668 if ( target
->definition() == ld::Atom::definitionProxy
) {
2669 // weak def exported from another dylib
2670 // must non-lazy bind to it plus have weak binding info in case of collision
2671 needsBinding
= true;
2672 needsWeakBinding
= true;
2675 // weak def in this linkage unit.
2676 // just rebase, plus have weak binding info in case of collision
2677 // this will be done by other cluster on lazy pointer atom
2680 else if ( (target
->contentType() == ld::Atom::typeResolver
) && (target
->scope() != ld::Atom::scopeGlobal
) ) {
2681 // <rdar://problem/8553647> Hidden resolver functions should not have lazy binding info
2682 needsLazyBinding
= false;
2685 // normal case of a pointer to non-weak-def symbol, so can lazily bind
2686 needsLazyBinding
= true;
2690 // everything except lazy pointers
2691 switch ( target
->definition() ) {
2692 case ld::Atom::definitionProxy
:
2693 if ( (dylib
!= NULL
) && dylib
->willBeLazyLoadedDylib() )
2694 throwf("illegal data reference to %s in lazy loaded dylib %s", target
->name(), dylib
->path());
2695 if ( target
->contentType() == ld::Atom::typeTLV
) {
2696 if ( sect
->type() != ld::Section::typeTLVPointers
)
2697 throwf("illegal data reference in %s to thread local variable %s in dylib %s",
2698 atom
->name(), target
->name(), dylib
->path());
2700 if ( inReadOnlySeg
)
2701 type
= BIND_TYPE_TEXT_ABSOLUTE32
;
2702 needsBinding
= true;
2703 if ( target
->combine() == ld::Atom::combineByName
)
2704 needsWeakBinding
= true;
2706 case ld::Atom::definitionRegular
:
2707 case ld::Atom::definitionTentative
:
2708 // only slideable images need rebasing info
2709 if ( _options
.outputSlidable() ) {
2712 // references to internal symbol never need binding
2713 if ( target
->scope() != ld::Atom::scopeGlobal
)
2715 // reference to global weak def needs weak binding
2716 if ( (target
->combine() == ld::Atom::combineByName
) && (target
->definition() == ld::Atom::definitionRegular
) )
2717 needsWeakBinding
= true;
2718 else if ( _options
.outputKind() == Options::kDynamicExecutable
) {
2719 // in main executables, the only way regular symbols are indirected is if -interposable is used
2720 if ( _options
.interposable(target
->name()) ) {
2721 needsRebase
= false;
2722 needsBinding
= true;
2726 // for flat-namespace or interposable two-level-namespace
2727 // all references to exported symbols get indirected
2728 if ( (_options
.nameSpace() != Options::kTwoLevelNameSpace
) || _options
.interposable(target
->name()) ) {
2729 // <rdar://problem/5254468> no external relocs for flat objc classes
2730 if ( strncmp(target
->name(), ".objc_class_", 12) == 0 )
2732 // no rebase info for references to global symbols that will have binding info
2733 needsRebase
= false;
2734 needsBinding
= true;
2738 case ld::Atom::definitionAbsolute
:
2743 // record dyld info for this cluster
2744 if ( needsRebase
) {
2745 if ( inReadOnlySeg
) {
2746 noteTextReloc(atom
, target
);
2747 sect
->hasLocalRelocs
= true; // so dyld knows to change permissions on __TEXT segment
2748 rebaseType
= REBASE_TYPE_TEXT_ABSOLUTE32
;
2750 _rebaseInfo
.push_back(RebaseInfo(rebaseType
, address
));
2752 if ( needsBinding
) {
2753 if ( inReadOnlySeg
) {
2754 noteTextReloc(atom
, target
);
2755 sect
->hasExternalRelocs
= true; // so dyld knows to change permissions on __TEXT segment
2757 _bindingInfo
.push_back(BindingInfo(type
, this->compressedOrdinalForAtom(target
), target
->name(), weak_import
, address
, addend
));
2759 if ( needsLazyBinding
) {
2760 if ( _options
.bindAtLoad() )
2761 _bindingInfo
.push_back(BindingInfo(type
, this->compressedOrdinalForAtom(target
), target
->name(), weak_import
, address
, addend
));
2763 _lazyBindingInfo
.push_back(BindingInfo(type
, this->compressedOrdinalForAtom(target
), target
->name(), weak_import
, address
, addend
));
2765 if ( needsWeakBinding
)
2766 _weakBindingInfo
.push_back(BindingInfo(type
, 0, target
->name(), false, address
, addend
));
2768 // record if weak imported
2769 if ( weak_import
&& (target
->definition() == ld::Atom::definitionProxy
) )
2770 (const_cast<ld::Atom
*>(target
))->setWeakImported();
2774 void OutputFile::addClassicRelocs(ld::Internal
& state
, ld::Internal::FinalSection
* sect
, const ld::Atom
* atom
,
2775 ld::Fixup
* fixupWithTarget
, ld::Fixup
* fixupWithMinusTarget
, ld::Fixup
* fixupWithStore
,
2776 const ld::Atom
* target
, const ld::Atom
* minusTarget
,
2777 uint64_t targetAddend
, uint64_t minusTargetAddend
)
2779 if ( sect
->isSectionHidden() )
2782 // non-lazy-pointer section is encoded in indirect symbol table - not using relocations
2783 if ( (sect
->type() == ld::Section::typeNonLazyPointer
) && (_options
.outputKind() != Options::kKextBundle
) ) {
2784 assert(target
!= NULL
);
2785 assert(fixupWithTarget
!= NULL
);
2786 // record if weak imported
2787 const ld::dylib::File
* dylib
= dynamic_cast<const ld::dylib::File
*>(target
->file());
2788 if ( (dylib
!= NULL
) && (fixupWithTarget
->weakImport
|| dylib
->willBeWeakLinked()) )
2789 (const_cast<ld::Atom
*>(target
))->setWeakImported();
2793 // no need to rebase or bind PCRel stores
2794 if ( this->isPcRelStore(fixupWithStore
->kind
) ) {
2795 // as long as target is in same linkage unit
2796 if ( (target
== NULL
) || (target
->definition() != ld::Atom::definitionProxy
) )
2800 // no need to rebase or bind PIC internal pointer diff
2801 if ( minusTarget
!= NULL
) {
2802 // with pointer diffs, both need to be in same linkage unit
2803 assert(minusTarget
->definition() != ld::Atom::definitionProxy
);
2804 assert(target
!= NULL
);
2805 assert(target
->definition() != ld::Atom::definitionProxy
);
2806 // make sure target is not global and weak
2807 if ( (target
->scope() == ld::Atom::scopeGlobal
) && (target
->combine() == ld::Atom::combineByName
)
2808 && (atom
->section().type() != ld::Section::typeCFI
)
2809 && (atom
->section().type() != ld::Section::typeDtraceDOF
)
2810 && (atom
->section().type() != ld::Section::typeUnwindInfo
)
2811 && (minusTarget
!= target
) ) {
2812 // ok for __eh_frame and __uwind_info to use pointer diffs to global weak symbols
2813 throwf("bad codegen, pointer diff in %s to global weak symbol %s", atom
->name(), target
->name());
2818 // cluster has no target, so needs no rebasing or binding
2819 if ( target
== NULL
)
2822 assert(_localRelocsAtom
!= NULL
);
2823 uint64_t relocAddress
= atom
->finalAddress() + fixupWithTarget
->offsetInAtom
- _localRelocsAtom
->relocBaseAddress(state
);
2825 bool inReadOnlySeg
= ( strcmp(sect
->segmentName(), "__TEXT") == 0 );
2826 bool needsLocalReloc
= false;
2827 bool needsExternReloc
= false;
2829 switch ( fixupWithStore
->kind
) {
2830 case ld::Fixup::kindLazyTarget
:
2832 // lazy pointers don't need relocs, but might need weak_import bit set
2833 const ld::dylib::File
* dylib
= dynamic_cast<const ld::dylib::File
*>(target
->file());
2834 if ( (dylib
!= NULL
) && (fixupWithTarget
->weakImport
|| dylib
->willBeWeakLinked()) )
2835 (const_cast<ld::Atom
*>(target
))->setWeakImported();
2838 case ld::Fixup::kindStoreLittleEndian32
:
2839 case ld::Fixup::kindStoreLittleEndian64
:
2840 case ld::Fixup::kindStoreBigEndian32
:
2841 case ld::Fixup::kindStoreBigEndian64
:
2842 case ld::Fixup::kindStoreTargetAddressLittleEndian32
:
2843 case ld::Fixup::kindStoreTargetAddressLittleEndian64
:
2844 case ld::Fixup::kindStoreTargetAddressBigEndian32
:
2845 case ld::Fixup::kindStoreTargetAddressBigEndian64
:
2847 switch ( target
->definition() ) {
2848 case ld::Atom::definitionProxy
:
2849 needsExternReloc
= true;
2851 case ld::Atom::definitionRegular
:
2852 case ld::Atom::definitionTentative
:
2853 // only slideable images need local relocs
2854 if ( _options
.outputSlidable() )
2855 needsLocalReloc
= true;
2856 // references to internal symbol never need binding
2857 if ( target
->scope() != ld::Atom::scopeGlobal
)
2859 // reference to global weak def needs weak binding in dynamic images
2860 if ( (target
->combine() == ld::Atom::combineByName
)
2861 && (target
->definition() == ld::Atom::definitionRegular
)
2862 && (_options
.outputKind() != Options::kStaticExecutable
) ) {
2863 needsExternReloc
= true;
2865 else if ( _options
.outputKind() == Options::kDynamicExecutable
) {
2866 // in main executables, the only way regular symbols are indirected is if -interposable is used
2867 if ( _options
.interposable(target
->name()) )
2868 needsExternReloc
= true;
2871 // for flat-namespace or interposable two-level-namespace
2872 // all references to exported symbols get indirected
2873 if ( (_options
.nameSpace() != Options::kTwoLevelNameSpace
) || _options
.interposable(target
->name()) ) {
2874 // <rdar://problem/5254468> no external relocs for flat objc classes
2875 if ( strncmp(target
->name(), ".objc_class_", 12) == 0 )
2877 // no rebase info for references to global symbols that will have binding info
2878 needsExternReloc
= true;
2881 if ( needsExternReloc
)
2882 needsLocalReloc
= false;
2884 case ld::Atom::definitionAbsolute
:
2887 if ( needsExternReloc
) {
2888 if ( inReadOnlySeg
)
2889 noteTextReloc(atom
, target
);
2890 const ld::dylib::File
* dylib
= dynamic_cast<const ld::dylib::File
*>(target
->file());
2891 if ( (dylib
!= NULL
) && dylib
->willBeLazyLoadedDylib() )
2892 throwf("illegal data reference to %s in lazy loaded dylib %s", target
->name(), dylib
->path());
2893 _externalRelocsAtom
->addExternalPointerReloc(relocAddress
, target
);
2894 sect
->hasExternalRelocs
= true;
2895 fixupWithTarget
->contentAddendOnly
= true;
2896 // record if weak imported
2897 if ( (dylib
!= NULL
) && (fixupWithTarget
->weakImport
|| dylib
->willBeWeakLinked()) )
2898 (const_cast<ld::Atom
*>(target
))->setWeakImported();
2900 else if ( needsLocalReloc
) {
2901 assert(target
!= NULL
);
2902 if ( inReadOnlySeg
)
2903 noteTextReloc(atom
, target
);
2904 _localRelocsAtom
->addPointerReloc(relocAddress
, target
->machoSection());
2905 sect
->hasLocalRelocs
= true;
2908 case ld::Fixup::kindStorePPCAbsLow14
:
2909 case ld::Fixup::kindStorePPCAbsLow16
:
2910 case ld::Fixup::kindStorePPCAbsHigh16AddLow
:
2911 case ld::Fixup::kindStorePPCAbsHigh16
:
2913 assert(target
!= NULL
);
2914 if ( target
->definition() == ld::Atom::definitionProxy
)
2915 throwf("half word text relocs not supported in %s", atom
->name());
2916 if ( _options
.outputSlidable() ) {
2917 if ( inReadOnlySeg
)
2918 noteTextReloc(atom
, target
);
2919 uint32_t machoSectionIndex
= (target
->definition() == ld::Atom::definitionAbsolute
)
2920 ? R_ABS
: target
->machoSection();
2921 _localRelocsAtom
->addTextReloc(relocAddress
, fixupWithTarget
->kind
,
2922 target
->finalAddress(), machoSectionIndex
);
2923 sect
->hasLocalRelocs
= true;
2927 case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32
:
2928 if ( _options
.outputKind() == Options::kKextBundle
) {
2929 assert(target
!= NULL
);
2930 if ( target
->definition() == ld::Atom::definitionProxy
) {
2931 _externalRelocsAtom
->addExternalCallSiteReloc(relocAddress
, target
);
2932 fixupWithStore
->contentAddendOnly
= true;
2942 bool OutputFile::useExternalSectionReloc(const ld::Atom
* atom
, const ld::Atom
* target
, ld::Fixup
* fixupWithTarget
)
2944 if ( _options
.architecture() == CPU_TYPE_X86_64
) {
2945 // x86_64 uses external relocations for everthing that has a symbol
2946 return ( target
->symbolTableInclusion() != ld::Atom::symbolTableNotIn
);
2948 // most architectures use external relocations only for references
2949 // to a symbol in another translation unit or for references to "weak symbols" or tentative definitions
2950 assert(target
!= NULL
);
2951 if ( target
->definition() == ld::Atom::definitionProxy
)
2953 if ( (target
->definition() == ld::Atom::definitionTentative
) && ! _options
.makeTentativeDefinitionsReal() )
2955 if ( target
->scope() != ld::Atom::scopeGlobal
)
2957 if ( (target
->combine() == ld::Atom::combineByName
) && (target
->definition() == ld::Atom::definitionRegular
) )
2965 void OutputFile::addSectionRelocs(ld::Internal
& state
, ld::Internal::FinalSection
* sect
, const ld::Atom
* atom
,
2966 ld::Fixup
* fixupWithTarget
, ld::Fixup
* fixupWithMinusTarget
, ld::Fixup
* fixupWithStore
,
2967 const ld::Atom
* target
, const ld::Atom
* minusTarget
,
2968 uint64_t targetAddend
, uint64_t minusTargetAddend
)
2970 if ( sect
->isSectionHidden() )
2973 // in -r mode where there will be no labels on __eh_frame section, there is no need for relocations
2974 if ( (sect
->type() == ld::Section::typeCFI
) && _options
.removeEHLabels() )
2977 // non-lazy-pointer section is encoded in indirect symbol table - not using relocations
2978 if ( sect
->type() == ld::Section::typeNonLazyPointer
)
2981 // tentative defs don't have any relocations
2982 if ( sect
->type() == ld::Section::typeTentativeDefs
)
2985 assert(target
!= NULL
);
2986 assert(fixupWithTarget
!= NULL
);
2987 bool targetUsesExternalReloc
= this->useExternalSectionReloc(atom
, target
, fixupWithTarget
);
2988 bool minusTargetUsesExternalReloc
= (minusTarget
!= NULL
) && this->useExternalSectionReloc(atom
, minusTarget
, fixupWithMinusTarget
);
2990 // in x86_64 .o files an external reloc means the content contains just the addend
2991 if ( _options
.architecture() == CPU_TYPE_X86_64
) {
2992 if ( targetUsesExternalReloc
) {
2993 fixupWithTarget
->contentAddendOnly
= true;
2994 fixupWithStore
->contentAddendOnly
= true;
2996 if ( minusTargetUsesExternalReloc
)
2997 fixupWithMinusTarget
->contentAddendOnly
= true;
3000 // for other archs, content is addend only with (non pc-rel) pointers
3001 // pc-rel instructions are funny. If the target is _foo+8 and _foo is
3002 // external, then the pc-rel instruction *evalutates* to the address 8.
3003 if ( targetUsesExternalReloc
) {
3004 if ( isPcRelStore(fixupWithStore
->kind
) ) {
3005 fixupWithTarget
->contentDetlaToAddendOnly
= true;
3006 fixupWithStore
->contentDetlaToAddendOnly
= true;
3008 else if ( minusTarget
== NULL
){
3009 fixupWithTarget
->contentAddendOnly
= true;
3010 fixupWithStore
->contentAddendOnly
= true;
3015 if ( fixupWithStore
!= NULL
) {
3016 _sectionsRelocationsAtom
->addSectionReloc(sect
, fixupWithStore
->kind
, atom
, fixupWithStore
->offsetInAtom
,
3017 targetUsesExternalReloc
, minusTargetUsesExternalReloc
,
3018 target
, targetAddend
, minusTarget
, minusTargetAddend
);
3024 void OutputFile::makeSplitSegInfo(ld::Internal
& state
)
3026 if ( !_options
.sharedRegionEligible() )
3029 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
3030 ld::Internal::FinalSection
* sect
= *sit
;
3031 if ( sect
->isSectionHidden() )
3033 if ( strcmp(sect
->segmentName(), "__TEXT") != 0 )
3035 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
3036 const ld::Atom
* atom
= *ait
;
3037 const ld::Atom
* target
= NULL
;
3038 bool hadSubtract
= false;
3039 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(), end
=atom
->fixupsEnd(); fit
!= end
; ++fit
) {
3040 if ( fit
->firstInCluster() )
3042 if ( fit
->kind
== ld::Fixup::kindSubtractTargetAddress
) {
3046 switch ( fit
->binding
) {
3047 case ld::Fixup::bindingNone
:
3048 case ld::Fixup::bindingByNameUnbound
:
3050 case ld::Fixup::bindingByContentBound
:
3051 case ld::Fixup::bindingDirectlyBound
:
3052 target
= fit
->u
.target
;
3054 case ld::Fixup::bindingsIndirectlyBound
:
3055 target
= state
.indirectBindingTable
[fit
->u
.bindingIndex
];
3058 switch ( fit
->kind
) {
3059 case ld::Fixup::kindStoreBigEndian32
:
3060 case ld::Fixup::kindStoreLittleEndian32
:
3061 case ld::Fixup::kindStoreLittleEndian64
:
3062 case ld::Fixup::kindStoreTargetAddressLittleEndian32
:
3063 case ld::Fixup::kindStoreTargetAddressLittleEndian64
:
3064 // if no subtract, then this is an absolute pointer which means
3065 // there is also a text reloc which update_dyld_shared_cache will use.
3066 if ( ! hadSubtract
)
3068 case ld::Fixup::kindStoreX86PCRel32
:
3069 case ld::Fixup::kindStoreX86PCRel32_1
:
3070 case ld::Fixup::kindStoreX86PCRel32_2
:
3071 case ld::Fixup::kindStoreX86PCRel32_4
:
3072 case ld::Fixup::kindStoreX86PCRel32GOTLoad
:
3073 case ld::Fixup::kindStoreX86PCRel32GOTLoadNowLEA
:
3074 case ld::Fixup::kindStoreX86PCRel32GOT
:
3075 case ld::Fixup::kindStorePPCPicHigh16AddLow
:
3076 case ld::Fixup::kindStoreTargetAddressX86PCRel32
:
3077 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad
:
3078 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA
:
3079 assert(target
!= NULL
);
3080 if ( strcmp(sect
->segmentName(), target
->section().segmentName()) != 0 ) {
3081 _splitSegInfos
.push_back(SplitSegInfoEntry(atom
->finalAddress()+fit
->offsetInAtom
,fit
->kind
));
3093 void OutputFile::writeMapFile(ld::Internal
& state
)
3095 if ( _options
.generatedMapPath() != NULL
) {
3096 FILE* mapFile
= fopen(_options
.generatedMapPath(), "w");
3097 if ( mapFile
!= NULL
) {
3098 // write output path
3099 fprintf(mapFile
, "# Path: %s\n", _options
.outputFilePath());
3100 // write output architecure
3101 fprintf(mapFile
, "# Arch: %s\n", _options
.architectureName());
3103 //if ( fUUIDAtom != NULL ) {
3104 // const uint8_t* uuid = fUUIDAtom->getUUID();
3105 // fprintf(mapFile, "# UUID: %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X \n",
3106 // uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
3107 // uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
3109 // write table of object files
3110 std::map
<const ld::File
*, uint32_t> readerToOrdinal
;
3111 std::map
<uint32_t, const ld::File
*> ordinalToReader
;
3112 std::map
<const ld::File
*, uint32_t> readerToFileOrdinal
;
3113 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
3114 ld::Internal::FinalSection
* sect
= *sit
;
3115 if ( sect
->isSectionHidden() )
3117 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
3118 const ld::Atom
* atom
= *ait
;
3119 const ld::File
* reader
= atom
->file();
3120 if ( reader
== NULL
)
3122 uint32_t readerOrdinal
= reader
->ordinal();
3123 std::map
<const ld::File
*, uint32_t>::iterator pos
= readerToOrdinal
.find(reader
);
3124 if ( pos
== readerToOrdinal
.end() ) {
3125 readerToOrdinal
[reader
] = readerOrdinal
;
3126 ordinalToReader
[readerOrdinal
] = reader
;
3130 fprintf(mapFile
, "# Object files:\n");
3131 fprintf(mapFile
, "[%3u] %s\n", 0, "linker synthesized");
3132 uint32_t fileIndex
= 0;
3133 readerToFileOrdinal
[NULL
] = fileIndex
++;
3134 for(std::map
<uint32_t, const ld::File
*>::iterator it
= ordinalToReader
.begin(); it
!= ordinalToReader
.end(); ++it
) {
3135 if ( it
->first
!= 0 ) {
3136 fprintf(mapFile
, "[%3u] %s\n", fileIndex
, it
->second
->path());
3137 readerToFileOrdinal
[it
->second
] = fileIndex
++;
3140 // write table of sections
3141 fprintf(mapFile
, "# Sections:\n");
3142 fprintf(mapFile
, "# Address\tSize \tSegment\tSection\n");
3143 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
3144 ld::Internal::FinalSection
* sect
= *sit
;
3145 if ( sect
->isSectionHidden() )
3147 fprintf(mapFile
, "0x%08llX\t0x%08llX\t%s\t%s\n", sect
->address
, sect
->size
,
3148 sect
->segmentName(), sect
->sectionName());
3150 // write table of symbols
3151 fprintf(mapFile
, "# Symbols:\n");
3152 fprintf(mapFile
, "# Address\tSize \tFile Name\n");
3153 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
3154 ld::Internal::FinalSection
* sect
= *sit
;
3155 if ( sect
->isSectionHidden() )
3157 //bool isCstring = (sect->type() == ld::Section::typeCString);
3158 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
3160 const ld::Atom
* atom
= *ait
;
3161 const char* name
= atom
->name();
3162 if ( atom
->contentType() == ld::Atom::typeCString
) {
3163 strcpy(buffer
, "literal string: ");
3164 strlcat(buffer
, (char*)atom
->rawContentPointer(), 4096);
3167 else if ( (atom
->contentType() == ld::Atom::typeCFI
) && (strcmp(name
, "FDE") == 0) ) {
3168 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(); fit
!= atom
->fixupsEnd(); ++fit
) {
3169 if ( (fit
->kind
== ld::Fixup::kindSetTargetAddress
) && (fit
->clusterSize
== ld::Fixup::k1of4
) ) {
3170 assert(fit
->binding
== ld::Fixup::bindingDirectlyBound
);
3171 if ( fit
->u
.target
->section().type() == ld::Section::typeCode
) {
3172 strcpy(buffer
, "FDE for: ");
3173 strlcat(buffer
, fit
->u
.target
->name(), 4096);
3179 else if ( atom
->contentType() == ld::Atom::typeNonLazyPointer
) {
3180 strcpy(buffer
, "non-lazy-pointer");
3181 for (ld::Fixup::iterator fit
= atom
->fixupsBegin(); fit
!= atom
->fixupsEnd(); ++fit
) {
3182 if ( fit
->binding
== ld::Fixup::bindingsIndirectlyBound
) {
3183 strcpy(buffer
, "non-lazy-pointer-to: ");
3184 strlcat(buffer
, state
.indirectBindingTable
[fit
->u
.bindingIndex
]->name(), 4096);
3187 else if ( fit
->binding
== ld::Fixup::bindingDirectlyBound
) {
3188 strcpy(buffer
, "non-lazy-pointer-to-local: ");
3189 strlcat(buffer
, fit
->u
.target
->name(), 4096);
3195 fprintf(mapFile
, "0x%08llX\t0x%08llX\t[%3u] %s\n", atom
->finalAddress(), atom
->size(),
3196 readerToFileOrdinal
[atom
->file()], name
);
3202 warning("could not write map file: %s\n", _options
.generatedMapPath());
3208 // used to sort atoms with debug notes
3209 class DebugNoteSorter
3212 bool operator()(const ld::Atom
* left
, const ld::Atom
* right
) const
3214 // first sort by reader
3215 uint32_t leftFileOrdinal
= left
->file()->ordinal();
3216 uint32_t rightFileOrdinal
= right
->file()->ordinal();
3217 if ( leftFileOrdinal
!= rightFileOrdinal
)
3218 return (leftFileOrdinal
< rightFileOrdinal
);
3220 // then sort by atom objectAddress
3221 uint64_t leftAddr
= left
->objectAddress();
3222 uint64_t rightAddr
= right
->objectAddress();
3223 return leftAddr
< rightAddr
;
3231 bool operator()(const char* left
, const char* right
) const { return (strcmp(left
, right
) == 0); }
3234 const char* OutputFile::assureFullPath(const char* path
)
3236 if ( path
[0] == '/' )
3238 char cwdbuff
[MAXPATHLEN
];
3239 if ( getcwd(cwdbuff
, MAXPATHLEN
) != NULL
) {
3241 asprintf(&result
, "%s/%s", cwdbuff
, path
);
3242 if ( result
!= NULL
)
3248 void OutputFile::synthesizeDebugNotes(ld::Internal
& state
)
3250 // -S means don't synthesize debug map
3251 if ( _options
.debugInfoStripping() == Options::kDebugInfoNone
)
3253 // make a vector of atoms that come from files compiled with dwarf debug info
3254 std::vector
<const ld::Atom
*> atomsNeedingDebugNotes
;
3255 std::set
<const ld::Atom
*> atomsWithStabs
;
3256 atomsNeedingDebugNotes
.reserve(1024);
3257 const ld::relocatable::File
* objFile
= NULL
;
3258 bool objFileHasDwarf
= false;
3259 bool objFileHasStabs
= false;
3260 for (std::vector
<ld::Internal::FinalSection
*>::iterator sit
= state
.sections
.begin(); sit
!= state
.sections
.end(); ++sit
) {
3261 ld::Internal::FinalSection
* sect
= *sit
;
3262 for (std::vector
<const ld::Atom
*>::iterator ait
= sect
->atoms
.begin(); ait
!= sect
->atoms
.end(); ++ait
) {
3263 const ld::Atom
* atom
= *ait
;
3264 // no stabs for atoms that would not be in the symbol table
3265 if ( atom
->symbolTableInclusion() == ld::Atom::symbolTableNotIn
)
3267 if ( atom
->symbolTableInclusion() == ld::Atom::symbolTableNotInFinalLinkedImages
)
3269 // no stabs for absolute symbols
3270 if ( atom
->definition() == ld::Atom::definitionAbsolute
)
3272 // no stabs for .eh atoms
3273 if ( atom
->contentType() == ld::Atom::typeCFI
)
3275 const ld::File
* file
= atom
->file();
3276 if ( file
!= NULL
) {
3277 if ( file
!= objFile
) {
3278 objFileHasDwarf
= false;
3279 objFileHasStabs
= false;
3280 objFile
= dynamic_cast<const ld::relocatable::File
*>(file
);
3281 if ( objFile
!= NULL
) {
3282 switch ( objFile
->debugInfo() ) {
3283 case ld::relocatable::File::kDebugInfoNone
:
3285 case ld::relocatable::File::kDebugInfoDwarf
:
3286 objFileHasDwarf
= true;
3288 case ld::relocatable::File::kDebugInfoStabs
:
3289 case ld::relocatable::File::kDebugInfoStabsUUID
:
3290 objFileHasStabs
= true;
3295 if ( objFileHasDwarf
)
3296 atomsNeedingDebugNotes
.push_back(atom
);
3297 if ( objFileHasStabs
)
3298 atomsWithStabs
.insert(atom
);
3303 // sort by file ordinal then atom ordinal
3304 std::sort(atomsNeedingDebugNotes
.begin(), atomsNeedingDebugNotes
.end(), DebugNoteSorter());
3306 // synthesize "debug notes" and add them to master stabs vector
3307 const char* dirPath
= NULL
;
3308 const char* filename
= NULL
;
3309 bool wroteStartSO
= false;
3310 state
.stabs
.reserve(atomsNeedingDebugNotes
.size()*4);
3311 __gnu_cxx::hash_set
<const char*, __gnu_cxx::hash
<const char*>, CStringEquals
> seenFiles
;
3312 for (std::vector
<const ld::Atom
*>::iterator it
=atomsNeedingDebugNotes
.begin(); it
!= atomsNeedingDebugNotes
.end(); it
++) {
3313 const ld::Atom
* atom
= *it
;
3314 const ld::File
* atomFile
= atom
->file();
3315 const ld::relocatable::File
* atomObjFile
= dynamic_cast<const ld::relocatable::File
*>(atomFile
);
3316 const char* newDirPath
;
3317 const char* newFilename
;
3318 //fprintf(stderr, "debug note for %s\n", atom->getDisplayName());
3319 if ( atom
->translationUnitSource(&newDirPath
, &newFilename
) ) {
3320 // need SO's whenever the translation unit source file changes
3321 if ( newFilename
!= filename
) {
3322 // gdb like directory SO's to end in '/', but dwarf DW_AT_comp_dir usually does not have trailing '/'
3323 if ( (newDirPath
!= NULL
) && (strlen(newDirPath
) > 1 ) && (newDirPath
[strlen(newDirPath
)-1] != '/') )
3324 asprintf((char**)&newDirPath
, "%s/", newDirPath
);
3325 if ( filename
!= NULL
) {
3326 // translation unit change, emit ending SO
3327 ld::relocatable::File::Stab endFileStab
;
3328 endFileStab
.atom
= NULL
;
3329 endFileStab
.type
= N_SO
;
3330 endFileStab
.other
= 1;
3331 endFileStab
.desc
= 0;
3332 endFileStab
.value
= 0;
3333 endFileStab
.string
= "";
3334 state
.stabs
.push_back(endFileStab
);
3336 // new translation unit, emit start SO's
3337 ld::relocatable::File::Stab dirPathStab
;
3338 dirPathStab
.atom
= NULL
;
3339 dirPathStab
.type
= N_SO
;
3340 dirPathStab
.other
= 0;
3341 dirPathStab
.desc
= 0;
3342 dirPathStab
.value
= 0;
3343 dirPathStab
.string
= newDirPath
;
3344 state
.stabs
.push_back(dirPathStab
);
3345 ld::relocatable::File::Stab fileStab
;
3346 fileStab
.atom
= NULL
;
3347 fileStab
.type
= N_SO
;
3351 fileStab
.string
= newFilename
;
3352 state
.stabs
.push_back(fileStab
);
3353 // Synthesize OSO for start of file
3354 ld::relocatable::File::Stab objStab
;
3355 objStab
.atom
= NULL
;
3356 objStab
.type
= N_OSO
;
3357 // <rdar://problem/6337329> linker should put cpusubtype in n_sect field of nlist entry for N_OSO debug note entries
3358 objStab
.other
= atomFile
->cpuSubType();
3360 if ( atomObjFile
!= NULL
) {
3361 objStab
.string
= assureFullPath(atomObjFile
->debugInfoPath());
3362 objStab
.value
= atomObjFile
->debugInfoModificationTime();
3365 objStab
.string
= assureFullPath(atomFile
->path());
3366 objStab
.value
= atomFile
->modificationTime();
3368 state
.stabs
.push_back(objStab
);
3369 wroteStartSO
= true;
3370 // add the source file path to seenFiles so it does not show up in SOLs
3371 seenFiles
.insert(newFilename
);
3373 asprintf(&fullFilePath
, "%s/%s", newDirPath
, newFilename
);
3374 // add both leaf path and full path
3375 seenFiles
.insert(fullFilePath
);
3377 filename
= newFilename
;
3378 dirPath
= newDirPath
;
3379 if ( atom
->section().type() == ld::Section::typeCode
) {
3380 // Synthesize BNSYM and start FUN stabs
3381 ld::relocatable::File::Stab beginSym
;
3382 beginSym
.atom
= atom
;
3383 beginSym
.type
= N_BNSYM
;
3387 beginSym
.string
= "";
3388 state
.stabs
.push_back(beginSym
);
3389 ld::relocatable::File::Stab startFun
;
3390 startFun
.atom
= atom
;
3391 startFun
.type
= N_FUN
;
3395 startFun
.string
= atom
->name();
3396 state
.stabs
.push_back(startFun
);
3397 // Synthesize any SOL stabs needed
3398 const char* curFile
= NULL
;
3399 for (ld::Atom::LineInfo::iterator lit
= atom
->beginLineInfo(); lit
!= atom
->endLineInfo(); ++lit
) {
3400 if ( lit
->fileName
!= curFile
) {
3401 if ( seenFiles
.count(lit
->fileName
) == 0 ) {
3402 seenFiles
.insert(lit
->fileName
);
3403 ld::relocatable::File::Stab sol
;
3409 sol
.string
= lit
->fileName
;
3410 state
.stabs
.push_back(sol
);
3412 curFile
= lit
->fileName
;
3415 // Synthesize end FUN and ENSYM stabs
3416 ld::relocatable::File::Stab endFun
;
3418 endFun
.type
= N_FUN
;
3423 state
.stabs
.push_back(endFun
);
3424 ld::relocatable::File::Stab endSym
;
3426 endSym
.type
= N_ENSYM
;
3431 state
.stabs
.push_back(endSym
);
3434 ld::relocatable::File::Stab globalsStab
;
3435 const char* name
= atom
->name();
3436 if ( atom
->scope() == ld::Atom::scopeTranslationUnit
) {
3437 // Synthesize STSYM stab for statics
3438 globalsStab
.atom
= atom
;
3439 globalsStab
.type
= N_STSYM
;
3440 globalsStab
.other
= 1;
3441 globalsStab
.desc
= 0;
3442 globalsStab
.value
= 0;
3443 globalsStab
.string
= name
;
3444 state
.stabs
.push_back(globalsStab
);
3447 // Synthesize GSYM stab for other globals
3448 globalsStab
.atom
= atom
;
3449 globalsStab
.type
= N_GSYM
;
3450 globalsStab
.other
= 1;
3451 globalsStab
.desc
= 0;
3452 globalsStab
.value
= 0;
3453 globalsStab
.string
= name
;
3454 state
.stabs
.push_back(globalsStab
);
3460 if ( wroteStartSO
) {
3462 ld::relocatable::File::Stab endFileStab
;
3463 endFileStab
.atom
= NULL
;
3464 endFileStab
.type
= N_SO
;
3465 endFileStab
.other
= 1;
3466 endFileStab
.desc
= 0;
3467 endFileStab
.value
= 0;
3468 endFileStab
.string
= "";
3469 state
.stabs
.push_back(endFileStab
);
3472 // copy any stabs from .o file
3473 std::set
<const ld::File
*> filesSeenWithStabs
;
3474 for (std::set
<const ld::Atom
*>::iterator it
=atomsWithStabs
.begin(); it
!= atomsWithStabs
.end(); it
++) {
3475 const ld::Atom
* atom
= *it
;
3476 objFile
= dynamic_cast<const ld::relocatable::File
*>(atom
->file());
3477 if ( objFile
!= NULL
) {
3478 if ( filesSeenWithStabs
.count(objFile
) == 0 ) {
3479 filesSeenWithStabs
.insert(objFile
);
3480 const std::vector
<ld::relocatable::File::Stab
>* stabs
= objFile
->stabs();
3481 if ( stabs
!= NULL
) {
3482 for(std::vector
<ld::relocatable::File::Stab
>::const_iterator sit
= stabs
->begin(); sit
!= stabs
->end(); ++sit
) {
3483 ld::relocatable::File::Stab stab
= *sit
;
3484 // ignore stabs associated with atoms that were dead stripped or coalesced away
3485 if ( (sit
->atom
!= NULL
) && (atomsWithStabs
.count(sit
->atom
) == 0) )
3487 // <rdar://problem/8284718> Value of N_SO stabs should be address of first atom from translation unit
3488 if ( (stab
.type
== N_SO
) && (stab
.string
!= NULL
) && (stab
.string
[0] != '\0') ) {
3491 state
.stabs
.push_back(stab
);