]> git.saurik.com Git - apple/ld64.git/blob - src/ld/OutputFile.cpp
ld64-224.1.tar.gz
[apple/ld64.git] / src / ld / OutputFile.cpp
1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-*
2 *
3 * Copyright (c) 2009-2011 Apple Inc. All rights reserved.
4 *
5 * @APPLE_LICENSE_HEADER_START@
6 *
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
12 * file.
13 *
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.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24
25
26 #include <stdlib.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <sys/mman.h>
30 #include <sys/sysctl.h>
31 #include <sys/param.h>
32 #include <sys/mount.h>
33 #include <fcntl.h>
34 #include <errno.h>
35 #include <limits.h>
36 #include <unistd.h>
37 #include <mach/mach_time.h>
38 #include <mach/vm_statistics.h>
39 #include <mach/mach_init.h>
40 #include <mach/mach_host.h>
41 #include <uuid/uuid.h>
42 #include <dlfcn.h>
43 #include <mach-o/dyld.h>
44 #include <mach-o/fat.h>
45
46 #include <string>
47 #include <map>
48 #include <set>
49 #include <string>
50 #include <vector>
51 #include <list>
52 #include <algorithm>
53 #include <unordered_set>
54
55 #include <CommonCrypto/CommonDigest.h>
56 #include <AvailabilityMacros.h>
57
58 #include "MachOTrie.hpp"
59
60 #include "Options.h"
61
62 #include "OutputFile.h"
63 #include "Architectures.hpp"
64 #include "HeaderAndLoadCommands.hpp"
65 #include "LinkEdit.hpp"
66 #include "LinkEditClassic.hpp"
67
68
69 namespace ld {
70 namespace tool {
71
72
73 OutputFile::OutputFile(const Options& opts)
74 :
75 hasWeakExternalSymbols(false), usesWeakExternalSymbols(false), overridesWeakExternalSymbols(false),
76 _noReExportedDylibs(false), hasThreadLocalVariableDefinitions(false), pieDisabled(false), hasDataInCode(false),
77 headerAndLoadCommandsSection(NULL),
78 rebaseSection(NULL), bindingSection(NULL), weakBindingSection(NULL),
79 lazyBindingSection(NULL), exportSection(NULL),
80 splitSegInfoSection(NULL), functionStartsSection(NULL),
81 dataInCodeSection(NULL), dependentDRsSection(NULL),
82 symbolTableSection(NULL), stringPoolSection(NULL),
83 localRelocationsSection(NULL), externalRelocationsSection(NULL),
84 sectionRelocationsSection(NULL),
85 indirectSymbolTableSection(NULL),
86 _options(opts),
87 _hasDyldInfo(opts.makeCompressedDyldInfo()),
88 _hasSymbolTable(true),
89 _hasSectionRelocations(opts.outputKind() == Options::kObjectFile),
90 _hasSplitSegInfo(opts.sharedRegionEligible()),
91 _hasFunctionStartsInfo(opts.addFunctionStarts()),
92 _hasDataInCodeInfo(opts.addDataInCodeInfo()),
93 _hasDependentDRInfo(opts.needsDependentDRInfo()),
94 _hasDynamicSymbolTable(true),
95 _hasLocalRelocations(!opts.makeCompressedDyldInfo()),
96 _hasExternalRelocations(!opts.makeCompressedDyldInfo()),
97 _encryptedTEXTstartOffset(0),
98 _encryptedTEXTendOffset(0),
99 _localSymbolsStartIndex(0),
100 _localSymbolsCount(0),
101 _globalSymbolsStartIndex(0),
102 _globalSymbolsCount(0),
103 _importSymbolsStartIndex(0),
104 _importSymbolsCount(0),
105 _sectionsRelocationsAtom(NULL),
106 _localRelocsAtom(NULL),
107 _externalRelocsAtom(NULL),
108 _symbolTableAtom(NULL),
109 _indirectSymbolTableAtom(NULL),
110 _rebasingInfoAtom(NULL),
111 _bindingInfoAtom(NULL),
112 _lazyBindingInfoAtom(NULL),
113 _weakBindingInfoAtom(NULL),
114 _exportInfoAtom(NULL),
115 _splitSegInfoAtom(NULL),
116 _functionStartsAtom(NULL),
117 _dataInCodeAtom(NULL),
118 _dependentDRInfoAtom(NULL)
119 {
120 }
121
122 void OutputFile::dumpAtomsBySection(ld::Internal& state, bool printAtoms)
123 {
124 fprintf(stderr, "SORTED:\n");
125 for (std::vector<ld::Internal::FinalSection*>::iterator it = state.sections.begin(); it != state.sections.end(); ++it) {
126 fprintf(stderr, "final section %p %s/%s %s start addr=0x%08llX, size=0x%08llX, alignment=%02d, fileOffset=0x%08llX\n",
127 (*it), (*it)->segmentName(), (*it)->sectionName(), (*it)->isSectionHidden() ? "(hidden)" : "",
128 (*it)->address, (*it)->size, (*it)->alignment, (*it)->fileOffset);
129 if ( printAtoms ) {
130 std::vector<const ld::Atom*>& atoms = (*it)->atoms;
131 for (std::vector<const ld::Atom*>::iterator ait = atoms.begin(); ait != atoms.end(); ++ait) {
132 fprintf(stderr, " %p (0x%04llX) %s\n", *ait, (*ait)->size(), (*ait)->name());
133 }
134 }
135 }
136 fprintf(stderr, "DYLIBS:\n");
137 for (std::vector<ld::dylib::File*>::iterator it=state.dylibs.begin(); it != state.dylibs.end(); ++it )
138 fprintf(stderr, " %s\n", (*it)->installPath());
139 }
140
141 void OutputFile::write(ld::Internal& state)
142 {
143 this->buildDylibOrdinalMapping(state);
144 this->addLoadCommands(state);
145 this->addLinkEdit(state);
146 this->setSectionSizesAndAlignments(state);
147 this->setLoadCommandsPadding(state);
148 this->assignFileOffsets(state);
149 this->assignAtomAddresses(state);
150 this->synthesizeDebugNotes(state);
151 this->buildSymbolTable(state);
152 this->generateLinkEditInfo(state);
153 this->makeSplitSegInfo(state);
154 this->updateLINKEDITAddresses(state);
155 //this->dumpAtomsBySection(state, false);
156 this->writeOutputFile(state);
157 this->writeMapFile(state);
158 }
159
160 bool OutputFile::findSegment(ld::Internal& state, uint64_t addr, uint64_t* start, uint64_t* end, uint32_t* index)
161 {
162 uint32_t segIndex = 0;
163 ld::Internal::FinalSection* segFirstSection = NULL;
164 ld::Internal::FinalSection* lastSection = NULL;
165 for (std::vector<ld::Internal::FinalSection*>::iterator it = state.sections.begin(); it != state.sections.end(); ++it) {
166 ld::Internal::FinalSection* sect = *it;
167 if ( (segFirstSection == NULL ) || strcmp(segFirstSection->segmentName(), sect->segmentName()) != 0 ) {
168 if ( segFirstSection != NULL ) {
169 //fprintf(stderr, "findSegment(0x%llX) seg changed to %s\n", addr, sect->segmentName());
170 if ( (addr >= segFirstSection->address) && (addr < lastSection->address+lastSection->size) ) {
171 *start = segFirstSection->address;
172 *end = lastSection->address+lastSection->size;
173 *index = segIndex;
174 return true;
175 }
176 ++segIndex;
177 }
178 segFirstSection = sect;
179 }
180 lastSection = sect;
181 }
182 return false;
183 }
184
185
186 void OutputFile::assignAtomAddresses(ld::Internal& state)
187 {
188 const bool log = false;
189 if ( log ) fprintf(stderr, "assignAtomAddresses()\n");
190 for (std::vector<ld::Internal::FinalSection*>::iterator sit = state.sections.begin(); sit != state.sections.end(); ++sit) {
191 ld::Internal::FinalSection* sect = *sit;
192 if ( log ) fprintf(stderr, " section=%s/%s\n", sect->segmentName(), sect->sectionName());
193 for (std::vector<const ld::Atom*>::iterator ait = sect->atoms.begin(); ait != sect->atoms.end(); ++ait) {
194 const ld::Atom* atom = *ait;
195 if ( log ) fprintf(stderr, " atom=%p, name=%s\n", atom, atom->name());
196 switch ( sect-> type() ) {
197 case ld::Section::typeImportProxies:
198 // want finalAddress() of all proxy atoms to be zero
199 (const_cast<ld::Atom*>(atom))->setSectionStartAddress(0);
200 break;
201 case ld::Section::typeAbsoluteSymbols:
202 // want finalAddress() of all absolute atoms to be value of abs symbol
203 (const_cast<ld::Atom*>(atom))->setSectionStartAddress(0);
204 break;
205 case ld::Section::typeLinkEdit:
206 // linkedit layout is assigned later
207 break;
208 default:
209 (const_cast<ld::Atom*>(atom))->setSectionStartAddress(sect->address);
210 break;
211 }
212 }
213 }
214 }
215
216 void OutputFile::updateLINKEDITAddresses(ld::Internal& state)
217 {
218 if ( _options.makeCompressedDyldInfo() ) {
219 // build dylb rebasing info
220 assert(_rebasingInfoAtom != NULL);
221 _rebasingInfoAtom->encode();
222
223 // build dyld binding info
224 assert(_bindingInfoAtom != NULL);
225 _bindingInfoAtom->encode();
226
227 // build dyld lazy binding info
228 assert(_lazyBindingInfoAtom != NULL);
229 _lazyBindingInfoAtom->encode();
230
231 // build dyld weak binding info
232 assert(_weakBindingInfoAtom != NULL);
233 _weakBindingInfoAtom->encode();
234
235 // build dyld export info
236 assert(_exportInfoAtom != NULL);
237 _exportInfoAtom->encode();
238 }
239
240 if ( _options.sharedRegionEligible() ) {
241 // build split seg info
242 assert(_splitSegInfoAtom != NULL);
243 _splitSegInfoAtom->encode();
244 }
245
246 if ( _options.addFunctionStarts() ) {
247 // build function starts info
248 assert(_functionStartsAtom != NULL);
249 _functionStartsAtom->encode();
250 }
251
252 if ( _options.addDataInCodeInfo() ) {
253 // build data-in-code info
254 assert(_dataInCodeAtom != NULL);
255 _dataInCodeAtom->encode();
256 }
257
258 if ( _options.needsDependentDRInfo() ) {
259 // build dependent dylib DR info
260 assert(_dependentDRInfoAtom != NULL);
261 _dependentDRInfoAtom->encode();
262 }
263
264 // build classic symbol table
265 assert(_symbolTableAtom != NULL);
266 _symbolTableAtom->encode();
267 assert(_indirectSymbolTableAtom != NULL);
268 _indirectSymbolTableAtom->encode();
269
270 // add relocations to .o files
271 if ( _options.outputKind() == Options::kObjectFile ) {
272 assert(_sectionsRelocationsAtom != NULL);
273 _sectionsRelocationsAtom->encode();
274 }
275
276 if ( ! _options.makeCompressedDyldInfo() ) {
277 // build external relocations
278 assert(_externalRelocsAtom != NULL);
279 _externalRelocsAtom->encode();
280 // build local relocations
281 assert(_localRelocsAtom != NULL);
282 _localRelocsAtom->encode();
283 }
284
285 // update address and file offsets now that linkedit content has been generated
286 uint64_t curLinkEditAddress = 0;
287 uint64_t curLinkEditfileOffset = 0;
288 for (std::vector<ld::Internal::FinalSection*>::iterator sit = state.sections.begin(); sit != state.sections.end(); ++sit) {
289 ld::Internal::FinalSection* sect = *sit;
290 if ( sect->type() != ld::Section::typeLinkEdit )
291 continue;
292 if ( curLinkEditAddress == 0 ) {
293 curLinkEditAddress = sect->address;
294 curLinkEditfileOffset = sect->fileOffset;
295 }
296 uint16_t maxAlignment = 0;
297 uint64_t offset = 0;
298 for (std::vector<const ld::Atom*>::iterator ait = sect->atoms.begin(); ait != sect->atoms.end(); ++ait) {
299 const ld::Atom* atom = *ait;
300 //fprintf(stderr, "setting linkedit atom offset for %s\n", atom->name());
301 if ( atom->alignment().powerOf2 > maxAlignment )
302 maxAlignment = atom->alignment().powerOf2;
303 // calculate section offset for this atom
304 uint64_t alignment = 1 << atom->alignment().powerOf2;
305 uint64_t currentModulus = (offset % alignment);
306 uint64_t requiredModulus = atom->alignment().modulus;
307 if ( currentModulus != requiredModulus ) {
308 if ( requiredModulus > currentModulus )
309 offset += requiredModulus-currentModulus;
310 else
311 offset += requiredModulus+alignment-currentModulus;
312 }
313 (const_cast<ld::Atom*>(atom))->setSectionOffset(offset);
314 (const_cast<ld::Atom*>(atom))->setSectionStartAddress(curLinkEditAddress);
315 offset += atom->size();
316 }
317 sect->size = offset;
318 // section alignment is that of a contained atom with the greatest alignment
319 sect->alignment = maxAlignment;
320 sect->address = curLinkEditAddress;
321 sect->fileOffset = curLinkEditfileOffset;
322 curLinkEditAddress += sect->size;
323 curLinkEditfileOffset += sect->size;
324 }
325
326 _fileSize = state.sections.back()->fileOffset + state.sections.back()->size;
327 }
328
329 void OutputFile::setSectionSizesAndAlignments(ld::Internal& state)
330 {
331 for (std::vector<ld::Internal::FinalSection*>::iterator sit = state.sections.begin(); sit != state.sections.end(); ++sit) {
332 ld::Internal::FinalSection* sect = *sit;
333 if ( sect->type() == ld::Section::typeAbsoluteSymbols ) {
334 // absolute symbols need their finalAddress() to their value
335 for (std::vector<const ld::Atom*>::iterator ait = sect->atoms.begin(); ait != sect->atoms.end(); ++ait) {
336 const ld::Atom* atom = *ait;
337 (const_cast<ld::Atom*>(atom))->setSectionOffset(atom->objectAddress());
338 }
339 }
340 else {
341 uint16_t maxAlignment = 0;
342 uint64_t offset = 0;
343 for (std::vector<const ld::Atom*>::iterator ait = sect->atoms.begin(); ait != sect->atoms.end(); ++ait) {
344 const ld::Atom* atom = *ait;
345 bool pagePerAtom = false;
346 uint32_t atomAlignmentPowerOf2 = atom->alignment().powerOf2;
347 uint32_t atomModulus = atom->alignment().modulus;
348 if ( _options.pageAlignDataAtoms() && ( strcmp(atom->section().segmentName(), "__DATA") == 0) ) {
349 // most objc sections cannot be padded
350 bool contiguousObjCSection = ( strncmp(atom->section().sectionName(), "__objc_", 7) == 0 );
351 if ( strcmp(atom->section().sectionName(), "__objc_const") == 0 )
352 contiguousObjCSection = false;
353 if ( strcmp(atom->section().sectionName(), "__objc_data") == 0 )
354 contiguousObjCSection = false;
355 switch ( atom->section().type() ) {
356 case ld::Section::typeUnclassified:
357 case ld::Section::typeTentativeDefs:
358 case ld::Section::typeZeroFill:
359 if ( contiguousObjCSection )
360 break;
361 pagePerAtom = true;
362 if ( atomAlignmentPowerOf2 < 12 ) {
363 atomAlignmentPowerOf2 = 12;
364 atomModulus = 0;
365 }
366 break;
367 default:
368 break;
369 }
370 }
371 if ( atomAlignmentPowerOf2 > maxAlignment )
372 maxAlignment = atomAlignmentPowerOf2;
373 // calculate section offset for this atom
374 uint64_t alignment = 1 << atomAlignmentPowerOf2;
375 uint64_t currentModulus = (offset % alignment);
376 uint64_t requiredModulus = atomModulus;
377 if ( currentModulus != requiredModulus ) {
378 if ( requiredModulus > currentModulus )
379 offset += requiredModulus-currentModulus;
380 else
381 offset += requiredModulus+alignment-currentModulus;
382 }
383 // LINKEDIT atoms are laid out later
384 if ( sect->type() != ld::Section::typeLinkEdit ) {
385 (const_cast<ld::Atom*>(atom))->setSectionOffset(offset);
386 offset += atom->size();
387 if ( pagePerAtom ) {
388 offset = (offset + 4095) & (-4096); // round up to end of page
389 }
390 }
391 if ( (atom->scope() == ld::Atom::scopeGlobal)
392 && (atom->definition() == ld::Atom::definitionRegular)
393 && (atom->combine() == ld::Atom::combineByName)
394 && ((atom->symbolTableInclusion() == ld::Atom::symbolTableIn)
395 || (atom->symbolTableInclusion() == ld::Atom::symbolTableInAndNeverStrip)) ) {
396 this->hasWeakExternalSymbols = true;
397 if ( _options.warnWeakExports() )
398 warning("weak external symbol: %s", atom->name());
399 }
400 }
401 sect->size = offset;
402 // section alignment is that of a contained atom with the greatest alignment
403 sect->alignment = maxAlignment;
404 // unless -sectalign command line option overrides
405 if ( _options.hasCustomSectionAlignment(sect->segmentName(), sect->sectionName()) )
406 sect->alignment = _options.customSectionAlignment(sect->segmentName(), sect->sectionName());
407 // each atom in __eh_frame has zero alignment to assure they pack together,
408 // but compilers usually make the CFIs pointer sized, so we want whole section
409 // to start on pointer sized boundary.
410 if ( sect->type() == ld::Section::typeCFI )
411 sect->alignment = 3;
412 if ( sect->type() == ld::Section::typeTLVDefs )
413 this->hasThreadLocalVariableDefinitions = true;
414 }
415 }
416 }
417
418 void OutputFile::setLoadCommandsPadding(ld::Internal& state)
419 {
420 // In other sections, any extra space is put and end of segment.
421 // In __TEXT segment, any extra space is put after load commands to allow post-processing of load commands
422 // Do a reverse layout of __TEXT segment to determine padding size and adjust section size
423 uint64_t paddingSize = 0;
424 switch ( _options.outputKind() ) {
425 case Options::kDyld:
426 // dyld itself has special padding requirements. We want the beginning __text section to start at a stable address
427 assert(strcmp(state.sections[1]->sectionName(),"__text") == 0);
428 state.sections[1]->alignment = 12; // page align __text
429 break;
430 case Options::kObjectFile:
431 // mach-o .o files need no padding between load commands and first section
432 // but leave enough room that the object file could be signed
433 paddingSize = 32;
434 break;
435 case Options::kPreload:
436 // mach-o MH_PRELOAD files need no padding between load commands and first section
437 paddingSize = 0;
438 default:
439 // work backwards from end of segment and lay out sections so that extra room goes to padding atom
440 uint64_t addr = 0;
441 for (std::vector<ld::Internal::FinalSection*>::reverse_iterator it = state.sections.rbegin(); it != state.sections.rend(); ++it) {
442 ld::Internal::FinalSection* sect = *it;
443 if ( strcmp(sect->segmentName(), "__TEXT") != 0 )
444 continue;
445 if ( sect == headerAndLoadCommandsSection ) {
446 addr -= headerAndLoadCommandsSection->size;
447 paddingSize = addr % _options.segmentAlignment();
448 break;
449 }
450 addr -= sect->size;
451 addr = addr & (0 - (1 << sect->alignment));
452 }
453
454 // if command line requires more padding than this
455 uint32_t minPad = _options.minimumHeaderPad();
456 if ( _options.maxMminimumHeaderPad() ) {
457 // -headerpad_max_install_names means there should be room for every path load command to grow to 1204 bytes
458 uint32_t altMin = _dylibsToLoad.size() * MAXPATHLEN;
459 if ( _options.outputKind() == Options::kDynamicLibrary )
460 altMin += MAXPATHLEN;
461 if ( altMin > minPad )
462 minPad = altMin;
463 }
464 if ( paddingSize < minPad ) {
465 int extraPages = (minPad - paddingSize + _options.segmentAlignment() - 1)/_options.segmentAlignment();
466 paddingSize += extraPages * _options.segmentAlignment();
467 }
468
469 if ( _options.makeEncryptable() ) {
470 // load commands must be on a separate non-encrypted page
471 int loadCommandsPage = (headerAndLoadCommandsSection->size + minPad)/_options.segmentAlignment();
472 int textPage = (headerAndLoadCommandsSection->size + paddingSize)/_options.segmentAlignment();
473 if ( loadCommandsPage == textPage ) {
474 paddingSize += _options.segmentAlignment();
475 textPage += 1;
476 }
477 // remember start for later use by load command
478 _encryptedTEXTstartOffset = textPage*_options.segmentAlignment();
479 }
480 break;
481 }
482 // add padding to size of section
483 headerAndLoadCommandsSection->size += paddingSize;
484 }
485
486
487 uint64_t OutputFile::pageAlign(uint64_t addr)
488 {
489 const uint64_t alignment = _options.segmentAlignment();
490 return ((addr+alignment-1) & (-alignment));
491 }
492
493 uint64_t OutputFile::pageAlign(uint64_t addr, uint64_t pageSize)
494 {
495 return ((addr+pageSize-1) & (-pageSize));
496 }
497
498
499 void OutputFile::assignFileOffsets(ld::Internal& state)
500 {
501 const bool log = false;
502 const bool hiddenSectionsOccupyAddressSpace = ((_options.outputKind() != Options::kObjectFile)
503 && (_options.outputKind() != Options::kPreload));
504 const bool segmentsArePageAligned = (_options.outputKind() != Options::kObjectFile);
505
506 uint64_t address = 0;
507 const char* lastSegName = "";
508 uint64_t floatingAddressStart = _options.baseAddress();
509
510 // first pass, assign addresses to sections in segments with fixed start addresses
511 if ( log ) fprintf(stderr, "Fixed address segments:\n");
512 for (std::vector<ld::Internal::FinalSection*>::iterator it = state.sections.begin(); it != state.sections.end(); ++it) {
513 ld::Internal::FinalSection* sect = *it;
514 if ( ! _options.hasCustomSegmentAddress(sect->segmentName()) )
515 continue;
516 if ( segmentsArePageAligned ) {
517 if ( strcmp(lastSegName, sect->segmentName()) != 0 ) {
518 address = _options.customSegmentAddress(sect->segmentName());
519 lastSegName = sect->segmentName();
520 }
521 }
522 // adjust section address based on alignment
523 uint64_t unalignedAddress = address;
524 uint64_t alignment = (1 << sect->alignment);
525 address = ( (unalignedAddress+alignment-1) & (-alignment) );
526
527 // update section info
528 sect->address = address;
529 sect->alignmentPaddingBytes = (address - unalignedAddress);
530
531 // sanity check size
532 if ( ((address + sect->size) > _options.maxAddress()) && (_options.outputKind() != Options::kObjectFile)
533 && (_options.outputKind() != Options::kStaticExecutable) )
534 throwf("section %s (address=0x%08llX, size=%llu) would make the output executable exceed available address range",
535 sect->sectionName(), address, sect->size);
536
537 if ( log ) fprintf(stderr, " address=0x%08llX, hidden=%d, alignment=%02d, section=%s,%s\n",
538 sect->address, sect->isSectionHidden(), sect->alignment, sect->segmentName(), sect->sectionName());
539 // update running totals
540 if ( !sect->isSectionHidden() || hiddenSectionsOccupyAddressSpace )
541 address += sect->size;
542
543 // if TEXT segment address is fixed, then flow other segments after it
544 if ( strcmp(sect->segmentName(), "__TEXT") == 0 ) {
545 floatingAddressStart = address;
546 }
547 }
548
549 // second pass, assign section address to sections in segments that are contiguous with previous segment
550 address = floatingAddressStart;
551 lastSegName = "";
552 ld::Internal::FinalSection* overlappingFixedSection = NULL;
553 ld::Internal::FinalSection* overlappingFlowSection = NULL;
554 if ( log ) fprintf(stderr, "Regular layout segments:\n");
555 for (std::vector<ld::Internal::FinalSection*>::iterator it = state.sections.begin(); it != state.sections.end(); ++it) {
556 ld::Internal::FinalSection* sect = *it;
557 if ( _options.hasCustomSegmentAddress(sect->segmentName()) )
558 continue;
559 if ( (_options.outputKind() == Options::kPreload) && (sect->type() == ld::Section::typeMachHeader) ) {
560 sect->alignmentPaddingBytes = 0;
561 continue;
562 }
563 if ( segmentsArePageAligned ) {
564 if ( strcmp(lastSegName, sect->segmentName()) != 0 ) {
565 // round up size of last segment if needed
566 if ( *lastSegName != '\0' ) {
567 address = pageAlign(address, _options.segPageSize(lastSegName));
568 }
569 // set segment address based on end of last segment
570 address = pageAlign(address);
571 lastSegName = sect->segmentName();
572 }
573 }
574 // adjust section address based on alignment
575 uint64_t unalignedAddress = address;
576 uint64_t alignment = (1 << sect->alignment);
577 address = ( (unalignedAddress+alignment-1) & (-alignment) );
578
579 // update section info
580 sect->address = address;
581 sect->alignmentPaddingBytes = (address - unalignedAddress);
582
583 // sanity check size
584 if ( ((address + sect->size) > _options.maxAddress()) && (_options.outputKind() != Options::kObjectFile)
585 && (_options.outputKind() != Options::kStaticExecutable) )
586 throwf("section %s (address=0x%08llX, size=%llu) would make the output executable exceed available address range",
587 sect->sectionName(), address, sect->size);
588
589 // sanity check it does not overlap a fixed address segment
590 for (std::vector<ld::Internal::FinalSection*>::iterator sit = state.sections.begin(); sit != state.sections.end(); ++sit) {
591 ld::Internal::FinalSection* otherSect = *sit;
592 if ( ! _options.hasCustomSegmentAddress(otherSect->segmentName()) )
593 continue;
594 if ( sect->address > otherSect->address ) {
595 if ( (otherSect->address+otherSect->size) > sect->address ) {
596 overlappingFixedSection = otherSect;
597 overlappingFlowSection = sect;
598 }
599 }
600 else {
601 if ( (sect->address+sect->size) > otherSect->address ) {
602 overlappingFixedSection = otherSect;
603 overlappingFlowSection = sect;
604 }
605 }
606 }
607
608 if ( log ) fprintf(stderr, " address=0x%08llX, size=0x%08llX, hidden=%d, alignment=%02d, padBytes=%d, section=%s,%s\n",
609 sect->address, sect->size, sect->isSectionHidden(), sect->alignment, sect->alignmentPaddingBytes,
610 sect->segmentName(), sect->sectionName());
611 // update running totals
612 if ( !sect->isSectionHidden() || hiddenSectionsOccupyAddressSpace )
613 address += sect->size;
614 }
615 if ( overlappingFixedSection != NULL ) {
616 fprintf(stderr, "Section layout:\n");
617 for (std::vector<ld::Internal::FinalSection*>::iterator it = state.sections.begin(); it != state.sections.end(); ++it) {
618 ld::Internal::FinalSection* sect = *it;
619 if ( sect->isSectionHidden() )
620 continue;
621 fprintf(stderr, " address:0x%08llX, alignment:2^%d, size:0x%08llX, padBytes:%d, section:%s/%s\n",
622 sect->address, sect->alignment, sect->size, sect->alignmentPaddingBytes,
623 sect->segmentName(), sect->sectionName());
624
625 }
626 throwf("Section (%s/%s) overlaps fixed address section (%s/%s)",
627 overlappingFlowSection->segmentName(), overlappingFlowSection->sectionName(),
628 overlappingFixedSection->segmentName(), overlappingFixedSection->sectionName());
629 }
630
631
632 // third pass, assign section file offsets
633 uint64_t fileOffset = 0;
634 lastSegName = "";
635 if ( log ) fprintf(stderr, "All segments with file offsets:\n");
636 for (std::vector<ld::Internal::FinalSection*>::iterator it = state.sections.begin(); it != state.sections.end(); ++it) {
637 ld::Internal::FinalSection* sect = *it;
638 if ( hasZeroForFileOffset(sect) ) {
639 // fileoff of zerofill sections is moot, but historically it is set to zero
640 sect->fileOffset = 0;
641
642 // <rdar://problem/10445047> align file offset with address layout
643 fileOffset += sect->alignmentPaddingBytes;
644 }
645 else {
646 // page align file offset at start of each segment
647 if ( segmentsArePageAligned && (*lastSegName != '\0') && (strcmp(lastSegName, sect->segmentName()) != 0) ) {
648 fileOffset = pageAlign(fileOffset, _options.segPageSize(lastSegName));
649 }
650 lastSegName = sect->segmentName();
651
652 // align file offset with address layout
653 fileOffset += sect->alignmentPaddingBytes;
654
655 // update section info
656 sect->fileOffset = fileOffset;
657
658 // update running total
659 fileOffset += sect->size;
660 }
661
662 if ( log ) fprintf(stderr, " fileoffset=0x%08llX, address=0x%08llX, hidden=%d, size=%lld, alignment=%02d, section=%s,%s\n",
663 sect->fileOffset, sect->address, sect->isSectionHidden(), sect->size, sect->alignment,
664 sect->segmentName(), sect->sectionName());
665 }
666
667
668 // for encrypted iPhoneOS apps
669 if ( _options.makeEncryptable() ) {
670 // remember end of __TEXT for later use by load command
671 for (std::vector<ld::Internal::FinalSection*>::iterator it = state.sections.begin(); it != state.sections.end(); ++it) {
672 ld::Internal::FinalSection* sect = *it;
673 if ( strcmp(sect->segmentName(), "__TEXT") == 0 ) {
674 _encryptedTEXTendOffset = pageAlign(sect->fileOffset + sect->size);
675 }
676 }
677 }
678
679 // remember total file size
680 _fileSize = fileOffset;
681 }
682
683
684 static const char* makeName(const ld::Atom& atom)
685 {
686 static char buffer[4096];
687 switch ( atom.symbolTableInclusion() ) {
688 case ld::Atom::symbolTableNotIn:
689 case ld::Atom::symbolTableNotInFinalLinkedImages:
690 sprintf(buffer, "%s@0x%08llX", atom.name(), atom.objectAddress());
691 break;
692 case ld::Atom::symbolTableIn:
693 case ld::Atom::symbolTableInAndNeverStrip:
694 case ld::Atom::symbolTableInAsAbsolute:
695 case ld::Atom::symbolTableInWithRandomAutoStripLabel:
696 strlcpy(buffer, atom.name(), 4096);
697 break;
698 }
699 return buffer;
700 }
701
702 static const char* referenceTargetAtomName(ld::Internal& state, const ld::Fixup* ref)
703 {
704 switch ( ref->binding ) {
705 case ld::Fixup::bindingNone:
706 return "NO BINDING";
707 case ld::Fixup::bindingByNameUnbound:
708 return (char*)(ref->u.target);
709 case ld::Fixup::bindingByContentBound:
710 case ld::Fixup::bindingDirectlyBound:
711 return makeName(*((ld::Atom*)(ref->u.target)));
712 case ld::Fixup::bindingsIndirectlyBound:
713 return makeName(*state.indirectBindingTable[ref->u.bindingIndex]);
714 }
715 return "BAD BINDING";
716 }
717
718 bool OutputFile::targetIsThumb(ld::Internal& state, const ld::Fixup* fixup)
719 {
720 switch ( fixup->binding ) {
721 case ld::Fixup::bindingByContentBound:
722 case ld::Fixup::bindingDirectlyBound:
723 return fixup->u.target->isThumb();
724 case ld::Fixup::bindingsIndirectlyBound:
725 return state.indirectBindingTable[fixup->u.bindingIndex]->isThumb();
726 default:
727 break;
728 }
729 throw "unexpected binding";
730 }
731
732 uint64_t OutputFile::addressOf(const ld::Internal& state, const ld::Fixup* fixup, const ld::Atom** target)
733 {
734 if ( !_options.makeCompressedDyldInfo() ) {
735 // For external relocations the classic mach-o format
736 // has addend only stored in the content. That means
737 // that the address of the target is not used.
738 if ( fixup->contentAddendOnly )
739 return 0;
740 }
741 switch ( fixup->binding ) {
742 case ld::Fixup::bindingNone:
743 throw "unexpected bindingNone";
744 case ld::Fixup::bindingByNameUnbound:
745 throw "unexpected bindingByNameUnbound";
746 case ld::Fixup::bindingByContentBound:
747 case ld::Fixup::bindingDirectlyBound:
748 *target = fixup->u.target;
749 return (*target)->finalAddress();
750 case ld::Fixup::bindingsIndirectlyBound:
751 *target = state.indirectBindingTable[fixup->u.bindingIndex];
752 #ifndef NDEBUG
753 if ( ! (*target)->finalAddressMode() ) {
754 throwf("reference to symbol (which has not been assigned an address) %s", (*target)->name());
755 }
756 #endif
757 return (*target)->finalAddress();
758 }
759 throw "unexpected binding";
760 }
761
762 uint64_t OutputFile::sectionOffsetOf(const ld::Internal& state, const ld::Fixup* fixup)
763 {
764 const ld::Atom* target = NULL;
765 switch ( fixup->binding ) {
766 case ld::Fixup::bindingNone:
767 throw "unexpected bindingNone";
768 case ld::Fixup::bindingByNameUnbound:
769 throw "unexpected bindingByNameUnbound";
770 case ld::Fixup::bindingByContentBound:
771 case ld::Fixup::bindingDirectlyBound:
772 target = fixup->u.target;
773 break;
774 case ld::Fixup::bindingsIndirectlyBound:
775 target = state.indirectBindingTable[fixup->u.bindingIndex];
776 break;
777 }
778 assert(target != NULL);
779
780 uint64_t targetAddress = target->finalAddress();
781 for (std::vector<ld::Internal::FinalSection*>::const_iterator it = state.sections.begin(); it != state.sections.end(); ++it) {
782 const ld::Internal::FinalSection* sect = *it;
783 if ( (sect->address <= targetAddress) && (targetAddress < (sect->address+sect->size)) )
784 return targetAddress - sect->address;
785 }
786 throw "section not found for section offset";
787 }
788
789
790
791 uint64_t OutputFile::tlvTemplateOffsetOf(const ld::Internal& state, const ld::Fixup* fixup)
792 {
793 const ld::Atom* target = NULL;
794 switch ( fixup->binding ) {
795 case ld::Fixup::bindingNone:
796 throw "unexpected bindingNone";
797 case ld::Fixup::bindingByNameUnbound:
798 throw "unexpected bindingByNameUnbound";
799 case ld::Fixup::bindingByContentBound:
800 case ld::Fixup::bindingDirectlyBound:
801 target = fixup->u.target;
802 break;
803 case ld::Fixup::bindingsIndirectlyBound:
804 target = state.indirectBindingTable[fixup->u.bindingIndex];
805 break;
806 }
807 assert(target != NULL);
808
809 for (std::vector<ld::Internal::FinalSection*>::const_iterator it = state.sections.begin(); it != state.sections.end(); ++it) {
810 const ld::Internal::FinalSection* sect = *it;
811 switch ( sect->type() ) {
812 case ld::Section::typeTLVInitialValues:
813 case ld::Section::typeTLVZeroFill:
814 return target->finalAddress() - sect->address;
815 default:
816 break;
817 }
818 }
819 throw "section not found for tlvTemplateOffsetOf";
820 }
821
822 void OutputFile::printSectionLayout(ld::Internal& state)
823 {
824 // show layout of final image
825 fprintf(stderr, "final section layout:\n");
826 for (std::vector<ld::Internal::FinalSection*>::iterator it = state.sections.begin(); it != state.sections.end(); ++it) {
827 if ( (*it)->isSectionHidden() )
828 continue;
829 fprintf(stderr, " %s/%s addr=0x%08llX, size=0x%08llX, fileOffset=0x%08llX, type=%d\n",
830 (*it)->segmentName(), (*it)->sectionName(),
831 (*it)->address, (*it)->size, (*it)->fileOffset, (*it)->type());
832 }
833 }
834
835
836 void OutputFile::rangeCheck8(int64_t displacement, ld::Internal& state, const ld::Atom* atom, const ld::Fixup* fixup)
837 {
838 if ( (displacement > 127) || (displacement < -128) ) {
839 // show layout of final image
840 printSectionLayout(state);
841
842 const ld::Atom* target;
843 throwf("8-bit reference out of range (%lld max is +/-127B): from %s (0x%08llX) to %s (0x%08llX)",
844 displacement, atom->name(), atom->finalAddress(), referenceTargetAtomName(state, fixup),
845 addressOf(state, fixup, &target));
846 }
847 }
848
849 void OutputFile::rangeCheck16(int64_t displacement, ld::Internal& state, const ld::Atom* atom, const ld::Fixup* fixup)
850 {
851 const int64_t thirtyTwoKLimit = 0x00007FFF;
852 if ( (displacement > thirtyTwoKLimit) || (displacement < (-thirtyTwoKLimit)) ) {
853 // show layout of final image
854 printSectionLayout(state);
855
856 const ld::Atom* target;
857 throwf("16-bit reference out of range (%lld max is +/-32KB): from %s (0x%08llX) to %s (0x%08llX)",
858 displacement, atom->name(), atom->finalAddress(), referenceTargetAtomName(state, fixup),
859 addressOf(state, fixup, &target));
860 }
861 }
862
863 void OutputFile::rangeCheckBranch32(int64_t displacement, ld::Internal& state, const ld::Atom* atom, const ld::Fixup* fixup)
864 {
865 const int64_t twoGigLimit = 0x7FFFFFFF;
866 if ( (displacement > twoGigLimit) || (displacement < (-twoGigLimit)) ) {
867 // show layout of final image
868 printSectionLayout(state);
869
870 const ld::Atom* target;
871 throwf("32-bit branch out of range (%lld max is +/-2GB): from %s (0x%08llX) to %s (0x%08llX)",
872 displacement, atom->name(), atom->finalAddress(), referenceTargetAtomName(state, fixup),
873 addressOf(state, fixup, &target));
874 }
875 }
876
877
878 void OutputFile::rangeCheckAbsolute32(int64_t displacement, ld::Internal& state, const ld::Atom* atom, const ld::Fixup* fixup)
879 {
880 const int64_t fourGigLimit = 0xFFFFFFFF;
881 if ( displacement > fourGigLimit ) {
882 // <rdar://problem/9610466> cannot enforce 32-bit range checks on 32-bit archs because assembler loses sign information
883 // .long _foo - 0xC0000000
884 // is encoded in mach-o the same as:
885 // .long _foo + 0x40000000
886 // so if _foo lays out to 0xC0000100, the first is ok, but the second is not.
887 if ( (_options.architecture() == CPU_TYPE_ARM) || (_options.architecture() == CPU_TYPE_I386) ) {
888 // Unlikely userland code does funky stuff like this, so warn for them, but not warn for -preload or -static
889 if ( (_options.outputKind() != Options::kPreload) && (_options.outputKind() != Options::kStaticExecutable) ) {
890 warning("32-bit absolute address out of range (0x%08llX max is 4GB): from %s + 0x%08X (0x%08llX) to 0x%08llX",
891 displacement, atom->name(), fixup->offsetInAtom, atom->finalAddress(), displacement);
892 }
893 return;
894 }
895 // show layout of final image
896 printSectionLayout(state);
897
898 const ld::Atom* target;
899 if ( fixup->binding == ld::Fixup::bindingNone )
900 throwf("32-bit absolute address out of range (0x%08llX max is 4GB): from %s + 0x%08X (0x%08llX) to 0x%08llX",
901 displacement, atom->name(), fixup->offsetInAtom, atom->finalAddress(), displacement);
902 else
903 throwf("32-bit absolute address out of range (0x%08llX max is 4GB): from %s + 0x%08X (0x%08llX) to %s (0x%08llX)",
904 displacement, atom->name(), fixup->offsetInAtom, atom->finalAddress(), referenceTargetAtomName(state, fixup),
905 addressOf(state, fixup, &target));
906 }
907 }
908
909
910 void OutputFile::rangeCheckRIP32(int64_t displacement, ld::Internal& state, const ld::Atom* atom, const ld::Fixup* fixup)
911 {
912 const int64_t twoGigLimit = 0x7FFFFFFF;
913 if ( (displacement > twoGigLimit) || (displacement < (-twoGigLimit)) ) {
914 // show layout of final image
915 printSectionLayout(state);
916
917 const ld::Atom* target;
918 throwf("32-bit RIP relative reference out of range (%lld max is +/-4GB): from %s (0x%08llX) to %s (0x%08llX)",
919 displacement, atom->name(), atom->finalAddress(), referenceTargetAtomName(state, fixup),
920 addressOf(state, fixup, &target));
921 }
922 }
923
924 void OutputFile::rangeCheckARM12(int64_t displacement, ld::Internal& state, const ld::Atom* atom, const ld::Fixup* fixup)
925 {
926 if ( (displacement > 4092LL) || (displacement < (-4092LL)) ) {
927 // show layout of final image
928 printSectionLayout(state);
929
930 const ld::Atom* target;
931 throwf("ARM ldr 12-bit displacement out of range (%lld max is +/-4096B): from %s (0x%08llX) to %s (0x%08llX)",
932 displacement, atom->name(), atom->finalAddress(), referenceTargetAtomName(state, fixup),
933 addressOf(state, fixup, &target));
934 }
935 }
936
937
938 void OutputFile::rangeCheckARMBranch24(int64_t displacement, ld::Internal& state, const ld::Atom* atom, const ld::Fixup* fixup)
939 {
940 if ( (displacement > 33554428LL) || (displacement < (-33554432LL)) ) {
941 // show layout of final image
942 printSectionLayout(state);
943
944 const ld::Atom* target;
945 throwf("b/bl/blx ARM branch out of range (%lld max is +/-32MB): from %s (0x%08llX) to %s (0x%08llX)",
946 displacement, atom->name(), atom->finalAddress(), referenceTargetAtomName(state, fixup),
947 addressOf(state, fixup, &target));
948 }
949 }
950
951 void OutputFile::rangeCheckThumbBranch22(int64_t displacement, ld::Internal& state, const ld::Atom* atom, const ld::Fixup* fixup)
952 {
953 // thumb2 supports a larger displacement
954 if ( _options.preferSubArchitecture() && _options.archSupportsThumb2() ) {
955 if ( (displacement > 16777214LL) || (displacement < (-16777216LL)) ) {
956 // show layout of final image
957 printSectionLayout(state);
958
959 const ld::Atom* target;
960 throwf("b/bl/blx thumb2 branch out of range (%lld max is +/-16MB): from %s (0x%08llX) to %s (0x%08llX)",
961 displacement, atom->name(), atom->finalAddress(), referenceTargetAtomName(state, fixup),
962 addressOf(state, fixup, &target));
963 }
964 }
965 else {
966 if ( (displacement > 4194302LL) || (displacement < (-4194304LL)) ) {
967 // show layout of final image
968 printSectionLayout(state);
969
970 const ld::Atom* target;
971 throwf("b/bl/blx thumb1 branch out of range (%lld max is +/-4MB): from %s (0x%08llX) to %s (0x%08llX)",
972 displacement, atom->name(), atom->finalAddress(), referenceTargetAtomName(state, fixup),
973 addressOf(state, fixup, &target));
974 }
975 }
976 }
977
978
979 void OutputFile::rangeCheckARM64Branch26(int64_t displacement, ld::Internal& state, const ld::Atom* atom, const ld::Fixup* fixup)
980 {
981 const int64_t bl_128MegLimit = 0x07FFFFFF;
982 if ( (displacement > bl_128MegLimit) || (displacement < (-bl_128MegLimit)) ) {
983 // show layout of final image
984 printSectionLayout(state);
985
986 const ld::Atom* target;
987 throwf("b(l) ARM64 branch out of range (%lld max is +/-128MB): from %s (0x%08llX) to %s (0x%08llX)",
988 displacement, atom->name(), atom->finalAddress(), referenceTargetAtomName(state, fixup),
989 addressOf(state, fixup, &target));
990 }
991 }
992
993 void OutputFile::rangeCheckARM64Page21(int64_t displacement, ld::Internal& state, const ld::Atom* atom, const ld::Fixup* fixup)
994 {
995 const int64_t adrp_4GigLimit = 0x100000000ULL;
996 if ( (displacement > adrp_4GigLimit) || (displacement < (-adrp_4GigLimit)) ) {
997 // show layout of final image
998 printSectionLayout(state);
999
1000 const ld::Atom* target;
1001 throwf("ARM64 ADRP out of range (%lld max is +/-4GB): from %s (0x%08llX) to %s (0x%08llX)",
1002 displacement, atom->name(), atom->finalAddress(), referenceTargetAtomName(state, fixup),
1003 addressOf(state, fixup, &target));
1004 }
1005 }
1006
1007
1008 uint16_t OutputFile::get16LE(uint8_t* loc) { return LittleEndian::get16(*(uint16_t*)loc); }
1009 void OutputFile::set16LE(uint8_t* loc, uint16_t value) { LittleEndian::set16(*(uint16_t*)loc, value); }
1010
1011 uint32_t OutputFile::get32LE(uint8_t* loc) { return LittleEndian::get32(*(uint32_t*)loc); }
1012 void OutputFile::set32LE(uint8_t* loc, uint32_t value) { LittleEndian::set32(*(uint32_t*)loc, value); }
1013
1014 uint64_t OutputFile::get64LE(uint8_t* loc) { return LittleEndian::get64(*(uint64_t*)loc); }
1015 void OutputFile::set64LE(uint8_t* loc, uint64_t value) { LittleEndian::set64(*(uint64_t*)loc, value); }
1016
1017 uint16_t OutputFile::get16BE(uint8_t* loc) { return BigEndian::get16(*(uint16_t*)loc); }
1018 void OutputFile::set16BE(uint8_t* loc, uint16_t value) { BigEndian::set16(*(uint16_t*)loc, value); }
1019
1020 uint32_t OutputFile::get32BE(uint8_t* loc) { return BigEndian::get32(*(uint32_t*)loc); }
1021 void OutputFile::set32BE(uint8_t* loc, uint32_t value) { BigEndian::set32(*(uint32_t*)loc, value); }
1022
1023 uint64_t OutputFile::get64BE(uint8_t* loc) { return BigEndian::get64(*(uint64_t*)loc); }
1024 void OutputFile::set64BE(uint8_t* loc, uint64_t value) { BigEndian::set64(*(uint64_t*)loc, value); }
1025
1026 void OutputFile::applyFixUps(ld::Internal& state, uint64_t mhAddress, const ld::Atom* atom, uint8_t* buffer)
1027 {
1028 //fprintf(stderr, "applyFixUps() on %s\n", atom->name());
1029 int64_t accumulator = 0;
1030 const ld::Atom* toTarget = NULL;
1031 const ld::Atom* fromTarget;
1032 int64_t delta;
1033 uint32_t instruction;
1034 uint32_t newInstruction;
1035 bool is_bl;
1036 bool is_blx;
1037 bool is_b;
1038 bool thumbTarget = false;
1039 for (ld::Fixup::iterator fit = atom->fixupsBegin(), end=atom->fixupsEnd(); fit != end; ++fit) {
1040 uint8_t* fixUpLocation = &buffer[fit->offsetInAtom];
1041 switch ( (ld::Fixup::Kind)(fit->kind) ) {
1042 case ld::Fixup::kindNone:
1043 case ld::Fixup::kindNoneFollowOn:
1044 case ld::Fixup::kindNoneGroupSubordinate:
1045 case ld::Fixup::kindNoneGroupSubordinateFDE:
1046 case ld::Fixup::kindNoneGroupSubordinateLSDA:
1047 case ld::Fixup::kindNoneGroupSubordinatePersonality:
1048 break;
1049 case ld::Fixup::kindSetTargetAddress:
1050 accumulator = addressOf(state, fit, &toTarget);
1051 thumbTarget = targetIsThumb(state, fit);
1052 if ( thumbTarget )
1053 accumulator |= 1;
1054 if ( fit->contentAddendOnly || fit->contentDetlaToAddendOnly )
1055 accumulator = 0;
1056 break;
1057 case ld::Fixup::kindSubtractTargetAddress:
1058 delta = addressOf(state, fit, &fromTarget);
1059 if ( ! fit->contentAddendOnly )
1060 accumulator -= delta;
1061 break;
1062 case ld::Fixup::kindAddAddend:
1063 if ( ! fit->contentIgnoresAddend ) {
1064 // <rdar://problem/8342028> ARM main executables main contain .long constants pointing
1065 // into themselves such as jump tables. These .long should not have thumb bit set
1066 // even though the target is a thumb instruction. We can tell it is an interior pointer
1067 // because we are processing an addend.
1068 if ( thumbTarget && (toTarget == atom) && ((int32_t)fit->u.addend > 0) ) {
1069 accumulator &= (-2);
1070 //warning("removing thumb bit from intra-atom pointer in %s %s+0x%0X",
1071 // atom->section().sectionName(), atom->name(), fit->offsetInAtom);
1072 }
1073 accumulator += fit->u.addend;
1074 }
1075 break;
1076 case ld::Fixup::kindSubtractAddend:
1077 accumulator -= fit->u.addend;
1078 break;
1079 case ld::Fixup::kindSetTargetImageOffset:
1080 accumulator = addressOf(state, fit, &toTarget) - mhAddress;
1081 break;
1082 case ld::Fixup::kindSetTargetSectionOffset:
1083 accumulator = sectionOffsetOf(state, fit);
1084 break;
1085 case ld::Fixup::kindSetTargetTLVTemplateOffset:
1086 accumulator = tlvTemplateOffsetOf(state, fit);
1087 break;
1088 case ld::Fixup::kindStore8:
1089 *fixUpLocation += accumulator;
1090 break;
1091 case ld::Fixup::kindStoreLittleEndian16:
1092 set16LE(fixUpLocation, accumulator);
1093 break;
1094 case ld::Fixup::kindStoreLittleEndianLow24of32:
1095 set32LE(fixUpLocation, (get32LE(fixUpLocation) & 0xFF000000) | (accumulator & 0x00FFFFFF) );
1096 break;
1097 case ld::Fixup::kindStoreLittleEndian32:
1098 rangeCheckAbsolute32(accumulator, state, atom, fit);
1099 set32LE(fixUpLocation, accumulator);
1100 break;
1101 case ld::Fixup::kindStoreLittleEndian64:
1102 set64LE(fixUpLocation, accumulator);
1103 break;
1104 case ld::Fixup::kindStoreBigEndian16:
1105 set16BE(fixUpLocation, accumulator);
1106 break;
1107 case ld::Fixup::kindStoreBigEndianLow24of32:
1108 set32BE(fixUpLocation, (get32BE(fixUpLocation) & 0xFF000000) | (accumulator & 0x00FFFFFF) );
1109 break;
1110 case ld::Fixup::kindStoreBigEndian32:
1111 rangeCheckAbsolute32(accumulator, state, atom, fit);
1112 set32BE(fixUpLocation, accumulator);
1113 break;
1114 case ld::Fixup::kindStoreBigEndian64:
1115 set64BE(fixUpLocation, accumulator);
1116 break;
1117 case ld::Fixup::kindStoreX86PCRel8:
1118 case ld::Fixup::kindStoreX86BranchPCRel8:
1119 if ( fit->contentAddendOnly )
1120 delta = accumulator;
1121 else
1122 delta = accumulator - (atom->finalAddress() + fit->offsetInAtom + 1);
1123 rangeCheck8(delta, state, atom, fit);
1124 *fixUpLocation = delta;
1125 break;
1126 case ld::Fixup::kindStoreX86PCRel16:
1127 if ( fit->contentAddendOnly )
1128 delta = accumulator;
1129 else
1130 delta = accumulator - (atom->finalAddress() + fit->offsetInAtom + 2);
1131 rangeCheck16(delta, state, atom, fit);
1132 set16LE(fixUpLocation, delta);
1133 break;
1134 case ld::Fixup::kindStoreX86BranchPCRel32:
1135 if ( fit->contentAddendOnly )
1136 delta = accumulator;
1137 else
1138 delta = accumulator - (atom->finalAddress() + fit->offsetInAtom + 4);
1139 rangeCheckBranch32(delta, state, atom, fit);
1140 set32LE(fixUpLocation, delta);
1141 break;
1142 case ld::Fixup::kindStoreX86PCRel32GOTLoad:
1143 case ld::Fixup::kindStoreX86PCRel32GOT:
1144 case ld::Fixup::kindStoreX86PCRel32:
1145 case ld::Fixup::kindStoreX86PCRel32TLVLoad:
1146 if ( fit->contentAddendOnly )
1147 delta = accumulator;
1148 else
1149 delta = accumulator - (atom->finalAddress() + fit->offsetInAtom + 4);
1150 rangeCheckRIP32(delta, state, atom, fit);
1151 set32LE(fixUpLocation, delta);
1152 break;
1153 case ld::Fixup::kindStoreX86PCRel32_1:
1154 if ( fit->contentAddendOnly )
1155 delta = accumulator - 1;
1156 else
1157 delta = accumulator - (atom->finalAddress() + fit->offsetInAtom + 5);
1158 rangeCheckRIP32(delta, state, atom, fit);
1159 set32LE(fixUpLocation, delta);
1160 break;
1161 case ld::Fixup::kindStoreX86PCRel32_2:
1162 if ( fit->contentAddendOnly )
1163 delta = accumulator - 2;
1164 else
1165 delta = accumulator - (atom->finalAddress() + fit->offsetInAtom + 6);
1166 rangeCheckRIP32(delta, state, atom, fit);
1167 set32LE(fixUpLocation, delta);
1168 break;
1169 case ld::Fixup::kindStoreX86PCRel32_4:
1170 if ( fit->contentAddendOnly )
1171 delta = accumulator - 4;
1172 else
1173 delta = accumulator - (atom->finalAddress() + fit->offsetInAtom + 8);
1174 rangeCheckRIP32(delta, state, atom, fit);
1175 set32LE(fixUpLocation, delta);
1176 break;
1177 case ld::Fixup::kindStoreX86Abs32TLVLoad:
1178 set32LE(fixUpLocation, accumulator);
1179 break;
1180 case ld::Fixup::kindStoreX86Abs32TLVLoadNowLEA:
1181 assert(_options.outputKind() != Options::kObjectFile);
1182 // TLV entry was optimized away, change movl instruction to a leal
1183 if ( fixUpLocation[-1] != 0xA1 )
1184 throw "TLV load reloc does not point to a movl instruction";
1185 fixUpLocation[-1] = 0xB8;
1186 set32LE(fixUpLocation, accumulator);
1187 break;
1188 case ld::Fixup::kindStoreX86PCRel32GOTLoadNowLEA:
1189 assert(_options.outputKind() != Options::kObjectFile);
1190 // GOT entry was optimized away, change movq instruction to a leaq
1191 if ( fixUpLocation[-2] != 0x8B )
1192 throw "GOT load reloc does not point to a movq instruction";
1193 fixUpLocation[-2] = 0x8D;
1194 delta = accumulator - (atom->finalAddress() + fit->offsetInAtom + 4);
1195 rangeCheckRIP32(delta, state, atom, fit);
1196 set32LE(fixUpLocation, delta);
1197 break;
1198 case ld::Fixup::kindStoreX86PCRel32TLVLoadNowLEA:
1199 assert(_options.outputKind() != Options::kObjectFile);
1200 // TLV entry was optimized away, change movq instruction to a leaq
1201 if ( fixUpLocation[-2] != 0x8B )
1202 throw "TLV load reloc does not point to a movq instruction";
1203 fixUpLocation[-2] = 0x8D;
1204 delta = accumulator - (atom->finalAddress() + fit->offsetInAtom + 4);
1205 rangeCheckRIP32(delta, state, atom, fit);
1206 set32LE(fixUpLocation, delta);
1207 break;
1208 case ld::Fixup::kindStoreTargetAddressARMLoad12:
1209 accumulator = addressOf(state, fit, &toTarget);
1210 // fall into kindStoreARMLoad12 case
1211 case ld::Fixup::kindStoreARMLoad12:
1212 delta = accumulator - (atom->finalAddress() + fit->offsetInAtom + 8);
1213 rangeCheckARM12(delta, state, atom, fit);
1214 instruction = get32LE(fixUpLocation);
1215 if ( delta >= 0 ) {
1216 newInstruction = instruction & 0xFFFFF000;
1217 newInstruction |= ((uint32_t)delta & 0xFFF);
1218 }
1219 else {
1220 newInstruction = instruction & 0xFF7FF000;
1221 newInstruction |= ((uint32_t)(-delta) & 0xFFF);
1222 }
1223 set32LE(fixUpLocation, newInstruction);
1224 break;
1225 case ld::Fixup::kindDtraceExtra:
1226 break;
1227 case ld::Fixup::kindStoreX86DtraceCallSiteNop:
1228 if ( _options.outputKind() != Options::kObjectFile ) {
1229 // change call site to a NOP
1230 fixUpLocation[-1] = 0x90; // 1-byte nop
1231 fixUpLocation[0] = 0x0F; // 4-byte nop
1232 fixUpLocation[1] = 0x1F;
1233 fixUpLocation[2] = 0x40;
1234 fixUpLocation[3] = 0x00;
1235 }
1236 break;
1237 case ld::Fixup::kindStoreX86DtraceIsEnableSiteClear:
1238 if ( _options.outputKind() != Options::kObjectFile ) {
1239 // change call site to a clear eax
1240 fixUpLocation[-1] = 0x33; // xorl eax,eax
1241 fixUpLocation[0] = 0xC0;
1242 fixUpLocation[1] = 0x90; // 1-byte nop
1243 fixUpLocation[2] = 0x90; // 1-byte nop
1244 fixUpLocation[3] = 0x90; // 1-byte nop
1245 }
1246 break;
1247 case ld::Fixup::kindStoreARMDtraceCallSiteNop:
1248 if ( _options.outputKind() != Options::kObjectFile ) {
1249 // change call site to a NOP
1250 set32LE(fixUpLocation, 0xE1A00000);
1251 }
1252 break;
1253 case ld::Fixup::kindStoreARMDtraceIsEnableSiteClear:
1254 if ( _options.outputKind() != Options::kObjectFile ) {
1255 // change call site to 'eor r0, r0, r0'
1256 set32LE(fixUpLocation, 0xE0200000);
1257 }
1258 break;
1259 case ld::Fixup::kindStoreThumbDtraceCallSiteNop:
1260 if ( _options.outputKind() != Options::kObjectFile ) {
1261 // change 32-bit blx call site to two thumb NOPs
1262 set32LE(fixUpLocation, 0x46C046C0);
1263 }
1264 break;
1265 case ld::Fixup::kindStoreThumbDtraceIsEnableSiteClear:
1266 if ( _options.outputKind() != Options::kObjectFile ) {
1267 // change 32-bit blx call site to 'nop', 'eor r0, r0'
1268 set32LE(fixUpLocation, 0x46C04040);
1269 }
1270 break;
1271 case ld::Fixup::kindStoreARM64DtraceCallSiteNop:
1272 if ( _options.outputKind() != Options::kObjectFile ) {
1273 // change call site to a NOP
1274 set32LE(fixUpLocation, 0xD503201F);
1275 }
1276 break;
1277 case ld::Fixup::kindStoreARM64DtraceIsEnableSiteClear:
1278 if ( _options.outputKind() != Options::kObjectFile ) {
1279 // change call site to 'MOVZ X0,0'
1280 set32LE(fixUpLocation, 0xD2800000);
1281 }
1282 break;
1283 case ld::Fixup::kindLazyTarget:
1284 break;
1285 case ld::Fixup::kindSetLazyOffset:
1286 assert(fit->binding == ld::Fixup::bindingDirectlyBound);
1287 accumulator = this->lazyBindingInfoOffsetForLazyPointerAddress(fit->u.target->finalAddress());
1288 break;
1289 case ld::Fixup::kindDataInCodeStartData:
1290 case ld::Fixup::kindDataInCodeStartJT8:
1291 case ld::Fixup::kindDataInCodeStartJT16:
1292 case ld::Fixup::kindDataInCodeStartJT32:
1293 case ld::Fixup::kindDataInCodeStartJTA32:
1294 case ld::Fixup::kindDataInCodeEnd:
1295 break;
1296 case ld::Fixup::kindStoreTargetAddressLittleEndian32:
1297 accumulator = addressOf(state, fit, &toTarget);
1298 thumbTarget = targetIsThumb(state, fit);
1299 if ( thumbTarget )
1300 accumulator |= 1;
1301 if ( fit->contentAddendOnly )
1302 accumulator = 0;
1303 rangeCheckAbsolute32(accumulator, state, atom, fit);
1304 set32LE(fixUpLocation, accumulator);
1305 break;
1306 case ld::Fixup::kindStoreTargetAddressLittleEndian64:
1307 accumulator = addressOf(state, fit, &toTarget);
1308 if ( fit->contentAddendOnly )
1309 accumulator = 0;
1310 set64LE(fixUpLocation, accumulator);
1311 break;
1312 case ld::Fixup::kindStoreTargetAddressBigEndian32:
1313 accumulator = addressOf(state, fit, &toTarget);
1314 if ( fit->contentAddendOnly )
1315 accumulator = 0;
1316 set32BE(fixUpLocation, accumulator);
1317 break;
1318 case ld::Fixup::kindStoreTargetAddressBigEndian64:
1319 accumulator = addressOf(state, fit, &toTarget);
1320 if ( fit->contentAddendOnly )
1321 accumulator = 0;
1322 set64BE(fixUpLocation, accumulator);
1323 break;
1324 case ld::Fixup::kindSetTargetTLVTemplateOffsetLittleEndian32:
1325 accumulator = tlvTemplateOffsetOf(state, fit);
1326 set32LE(fixUpLocation, accumulator);
1327 break;
1328 case ld::Fixup::kindSetTargetTLVTemplateOffsetLittleEndian64:
1329 accumulator = tlvTemplateOffsetOf(state, fit);
1330 set64LE(fixUpLocation, accumulator);
1331 break;
1332 case ld::Fixup::kindStoreTargetAddressX86PCRel32:
1333 case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32:
1334 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad:
1335 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoad:
1336 accumulator = addressOf(state, fit, &toTarget);
1337 if ( fit->contentDetlaToAddendOnly )
1338 accumulator = 0;
1339 if ( fit->contentAddendOnly )
1340 delta = 0;
1341 else
1342 delta = accumulator - (atom->finalAddress() + fit->offsetInAtom + 4);
1343 rangeCheckRIP32(delta, state, atom, fit);
1344 set32LE(fixUpLocation, delta);
1345 break;
1346 case ld::Fixup::kindStoreTargetAddressX86Abs32TLVLoad:
1347 set32LE(fixUpLocation, accumulator);
1348 break;
1349 case ld::Fixup::kindStoreTargetAddressX86Abs32TLVLoadNowLEA:
1350 // TLV entry was optimized away, change movl instruction to a leal
1351 if ( fixUpLocation[-1] != 0xA1 )
1352 throw "TLV load reloc does not point to a movl <abs-address>,<reg> instruction";
1353 fixUpLocation[-1] = 0xB8;
1354 accumulator = addressOf(state, fit, &toTarget);
1355 set32LE(fixUpLocation, accumulator);
1356 break;
1357 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA:
1358 // GOT entry was optimized away, change movq instruction to a leaq
1359 if ( fixUpLocation[-2] != 0x8B )
1360 throw "GOT load reloc does not point to a movq instruction";
1361 fixUpLocation[-2] = 0x8D;
1362 accumulator = addressOf(state, fit, &toTarget);
1363 delta = accumulator - (atom->finalAddress() + fit->offsetInAtom + 4);
1364 rangeCheckRIP32(delta, state, atom, fit);
1365 set32LE(fixUpLocation, delta);
1366 break;
1367 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoadNowLEA:
1368 // TLV entry was optimized away, change movq instruction to a leaq
1369 if ( fixUpLocation[-2] != 0x8B )
1370 throw "TLV load reloc does not point to a movq instruction";
1371 fixUpLocation[-2] = 0x8D;
1372 accumulator = addressOf(state, fit, &toTarget);
1373 delta = accumulator - (atom->finalAddress() + fit->offsetInAtom + 4);
1374 rangeCheckRIP32(delta, state, atom, fit);
1375 set32LE(fixUpLocation, delta);
1376 break;
1377 case ld::Fixup::kindStoreTargetAddressARMBranch24:
1378 accumulator = addressOf(state, fit, &toTarget);
1379 thumbTarget = targetIsThumb(state, fit);
1380 if ( thumbTarget )
1381 accumulator |= 1;
1382 if ( fit->contentDetlaToAddendOnly )
1383 accumulator = 0;
1384 // fall into kindStoreARMBranch24 case
1385 case ld::Fixup::kindStoreARMBranch24:
1386 // The pc added will be +8 from the pc
1387 delta = accumulator - (atom->finalAddress() + fit->offsetInAtom + 8);
1388 rangeCheckARMBranch24(delta, state, atom, fit);
1389 instruction = get32LE(fixUpLocation);
1390 // Make sure we are calling arm with bl, thumb with blx
1391 is_bl = ((instruction & 0xFF000000) == 0xEB000000);
1392 is_blx = ((instruction & 0xFE000000) == 0xFA000000);
1393 is_b = !is_blx && ((instruction & 0x0F000000) == 0x0A000000);
1394 if ( is_bl && thumbTarget ) {
1395 uint32_t opcode = 0xFA000000;
1396 uint32_t disp = (uint32_t)(delta >> 2) & 0x00FFFFFF;
1397 uint32_t h_bit = (uint32_t)(delta << 23) & 0x01000000;
1398 newInstruction = opcode | h_bit | disp;
1399 }
1400 else if ( is_blx && !thumbTarget ) {
1401 uint32_t opcode = 0xEB000000;
1402 uint32_t disp = (uint32_t)(delta >> 2) & 0x00FFFFFF;
1403 newInstruction = opcode | disp;
1404 }
1405 else if ( is_b && thumbTarget ) {
1406 if ( fit->contentDetlaToAddendOnly )
1407 newInstruction = (instruction & 0xFF000000) | ((uint32_t)(delta >> 2) & 0x00FFFFFF);
1408 else
1409 throwf("no pc-rel bx arm instruction. Can't fix up branch to %s in %s",
1410 referenceTargetAtomName(state, fit), atom->name());
1411 }
1412 else if ( !is_bl && !is_blx && thumbTarget ) {
1413 throwf("don't know how to convert instruction %x referencing %s to thumb",
1414 instruction, referenceTargetAtomName(state, fit));
1415 }
1416 else {
1417 newInstruction = (instruction & 0xFF000000) | ((uint32_t)(delta >> 2) & 0x00FFFFFF);
1418 }
1419 set32LE(fixUpLocation, newInstruction);
1420 break;
1421 case ld::Fixup::kindStoreTargetAddressThumbBranch22:
1422 accumulator = addressOf(state, fit, &toTarget);
1423 thumbTarget = targetIsThumb(state, fit);
1424 if ( thumbTarget )
1425 accumulator |= 1;
1426 if ( fit->contentDetlaToAddendOnly )
1427 accumulator = 0;
1428 // fall into kindStoreThumbBranch22 case
1429 case ld::Fixup::kindStoreThumbBranch22:
1430 instruction = get32LE(fixUpLocation);
1431 is_bl = ((instruction & 0xD000F800) == 0xD000F000);
1432 is_blx = ((instruction & 0xD000F800) == 0xC000F000);
1433 is_b = ((instruction & 0xD000F800) == 0x9000F000);
1434 // If the target is not thumb, we will be generating a blx instruction
1435 // Since blx cannot have the low bit set, set bit[1] of the target to
1436 // bit[1] of the base address, so that the difference is a multiple of
1437 // 4 bytes.
1438 if ( !thumbTarget && !fit->contentDetlaToAddendOnly ) {
1439 accumulator &= -3ULL;
1440 accumulator |= ((atom->finalAddress() + fit->offsetInAtom ) & 2LL);
1441 }
1442 // The pc added will be +4 from the pc
1443 delta = accumulator - (atom->finalAddress() + fit->offsetInAtom + 4);
1444 rangeCheckThumbBranch22(delta, state, atom, fit);
1445 if ( _options.preferSubArchitecture() && _options.archSupportsThumb2() ) {
1446 // The instruction is really two instructions:
1447 // The lower 16 bits are the first instruction, which contains the high
1448 // 11 bits of the displacement.
1449 // The upper 16 bits are the second instruction, which contains the low
1450 // 11 bits of the displacement, as well as differentiating bl and blx.
1451 uint32_t s = (uint32_t)(delta >> 24) & 0x1;
1452 uint32_t i1 = (uint32_t)(delta >> 23) & 0x1;
1453 uint32_t i2 = (uint32_t)(delta >> 22) & 0x1;
1454 uint32_t imm10 = (uint32_t)(delta >> 12) & 0x3FF;
1455 uint32_t imm11 = (uint32_t)(delta >> 1) & 0x7FF;
1456 uint32_t j1 = (i1 == s);
1457 uint32_t j2 = (i2 == s);
1458 if ( is_bl ) {
1459 if ( thumbTarget )
1460 instruction = 0xD000F000; // keep bl
1461 else
1462 instruction = 0xC000F000; // change to blx
1463 }
1464 else if ( is_blx ) {
1465 if ( thumbTarget )
1466 instruction = 0xD000F000; // change to bl
1467 else
1468 instruction = 0xC000F000; // keep blx
1469 }
1470 else if ( is_b ) {
1471 instruction = 0x9000F000; // keep b
1472 if ( !thumbTarget && !fit->contentDetlaToAddendOnly ) {
1473 throwf("armv7 has no pc-rel bx thumb instruction. Can't fix up branch to %s in %s",
1474 referenceTargetAtomName(state, fit), atom->name());
1475 }
1476 }
1477 else {
1478 if ( !thumbTarget )
1479 throwf("don't know how to convert branch instruction %x referencing %s to bx",
1480 instruction, referenceTargetAtomName(state, fit));
1481 instruction = 0x9000F000; // keep b
1482 }
1483 uint32_t nextDisp = (j1 << 13) | (j2 << 11) | imm11;
1484 uint32_t firstDisp = (s << 10) | imm10;
1485 newInstruction = instruction | (nextDisp << 16) | firstDisp;
1486 //warning("s=%d, j1=%d, j2=%d, imm10=0x%0X, imm11=0x%0X, instruction=0x%08X, first=0x%04X, next=0x%04X, new=0x%08X, disp=0x%llX for %s to %s\n",
1487 // s, j1, j2, imm10, imm11, instruction, firstDisp, nextDisp, newInstruction, delta, atom->name(), toTarget->name());
1488 set32LE(fixUpLocation, newInstruction);
1489 }
1490 else {
1491 // The instruction is really two instructions:
1492 // The lower 16 bits are the first instruction, which contains the high
1493 // 11 bits of the displacement.
1494 // The upper 16 bits are the second instruction, which contains the low
1495 // 11 bits of the displacement, as well as differentiating bl and blx.
1496 uint32_t firstDisp = (uint32_t)(delta >> 12) & 0x7FF;
1497 uint32_t nextDisp = (uint32_t)(delta >> 1) & 0x7FF;
1498 if ( is_bl && !thumbTarget ) {
1499 instruction = 0xE800F000;
1500 }
1501 else if ( is_blx && thumbTarget ) {
1502 instruction = 0xF800F000;
1503 }
1504 else if ( is_b ) {
1505 instruction = 0x9000F000; // keep b
1506 if ( !thumbTarget && !fit->contentDetlaToAddendOnly ) {
1507 throwf("armv6 has no pc-rel bx thumb instruction. Can't fix up branch to %s in %s",
1508 referenceTargetAtomName(state, fit), atom->name());
1509 }
1510 }
1511 else {
1512 instruction = instruction & 0xF800F800;
1513 }
1514 newInstruction = instruction | (nextDisp << 16) | firstDisp;
1515 set32LE(fixUpLocation, newInstruction);
1516 }
1517 break;
1518 case ld::Fixup::kindStoreARMLow16:
1519 {
1520 uint32_t imm4 = (accumulator & 0x0000F000) >> 12;
1521 uint32_t imm12 = accumulator & 0x00000FFF;
1522 instruction = get32LE(fixUpLocation);
1523 newInstruction = (instruction & 0xFFF0F000) | (imm4 << 16) | imm12;
1524 set32LE(fixUpLocation, newInstruction);
1525 }
1526 break;
1527 case ld::Fixup::kindStoreARMHigh16:
1528 {
1529 uint32_t imm4 = (accumulator & 0xF0000000) >> 28;
1530 uint32_t imm12 = (accumulator & 0x0FFF0000) >> 16;
1531 instruction = get32LE(fixUpLocation);
1532 newInstruction = (instruction & 0xFFF0F000) | (imm4 << 16) | imm12;
1533 set32LE(fixUpLocation, newInstruction);
1534 }
1535 break;
1536 case ld::Fixup::kindStoreThumbLow16:
1537 {
1538 uint32_t imm4 = (accumulator & 0x0000F000) >> 12;
1539 uint32_t i = (accumulator & 0x00000800) >> 11;
1540 uint32_t imm3 = (accumulator & 0x00000700) >> 8;
1541 uint32_t imm8 = accumulator & 0x000000FF;
1542 instruction = get32LE(fixUpLocation);
1543 newInstruction = (instruction & 0x8F00FBF0) | imm4 | (i << 10) | (imm3 << 28) | (imm8 << 16);
1544 set32LE(fixUpLocation, newInstruction);
1545 }
1546 break;
1547 case ld::Fixup::kindStoreThumbHigh16:
1548 {
1549 uint32_t imm4 = (accumulator & 0xF0000000) >> 28;
1550 uint32_t i = (accumulator & 0x08000000) >> 27;
1551 uint32_t imm3 = (accumulator & 0x07000000) >> 24;
1552 uint32_t imm8 = (accumulator & 0x00FF0000) >> 16;
1553 instruction = get32LE(fixUpLocation);
1554 newInstruction = (instruction & 0x8F00FBF0) | imm4 | (i << 10) | (imm3 << 28) | (imm8 << 16);
1555 set32LE(fixUpLocation, newInstruction);
1556 }
1557 break;
1558 #if SUPPORT_ARCH_arm64
1559 case ld::Fixup::kindStoreTargetAddressARM64Branch26:
1560 accumulator = addressOf(state, fit, &toTarget);
1561 // fall into kindStoreARM64Branch26 case
1562 case ld::Fixup::kindStoreARM64Branch26:
1563 if ( fit->contentAddendOnly )
1564 delta = accumulator;
1565 else
1566 delta = accumulator - (atom->finalAddress() + fit->offsetInAtom);
1567 rangeCheckARM64Branch26(delta, state, atom, fit);
1568 instruction = get32LE(fixUpLocation);
1569 newInstruction = (instruction & 0xFC000000) | ((uint32_t)(delta >> 2) & 0x03FFFFFF);
1570 set32LE(fixUpLocation, newInstruction);
1571 break;
1572 case ld::Fixup::kindStoreTargetAddressARM64GOTLeaPage21:
1573 case ld::Fixup::kindStoreTargetAddressARM64GOTLoadPage21:
1574 case ld::Fixup::kindStoreTargetAddressARM64Page21:
1575 accumulator = addressOf(state, fit, &toTarget);
1576 // fall into kindStoreARM64Branch26 case
1577 case ld::Fixup::kindStoreARM64GOTLeaPage21:
1578 case ld::Fixup::kindStoreARM64GOTLoadPage21:
1579 case ld::Fixup::kindStoreARM64TLVPLoadPage21:
1580 case ld::Fixup::kindStoreARM64Page21:
1581 {
1582 // the ADRP instruction adds the imm << 12 to the page that the pc is on
1583 if ( fit->contentAddendOnly )
1584 delta = 0;
1585 else
1586 delta = (accumulator & (-4096)) - ((atom->finalAddress() + fit->offsetInAtom) & (-4096));
1587 rangeCheckARM64Page21(delta, state, atom, fit);
1588 instruction = get32LE(fixUpLocation);
1589 uint32_t immhi = (delta >> 9) & (0x00FFFFE0);
1590 uint32_t immlo = (delta << 17) & (0x60000000);
1591 newInstruction = (instruction & 0x9F00001F) | immlo | immhi;
1592 set32LE(fixUpLocation, newInstruction);
1593 }
1594 break;
1595 case ld::Fixup::kindStoreTargetAddressARM64GOTLoadPageOff12:
1596 case ld::Fixup::kindStoreTargetAddressARM64PageOff12:
1597 accumulator = addressOf(state, fit, &toTarget);
1598 // fall into kindAddressARM64PageOff12 case
1599 case ld::Fixup::kindStoreARM64TLVPLoadPageOff12:
1600 case ld::Fixup::kindStoreARM64GOTLoadPageOff12:
1601 case ld::Fixup::kindStoreARM64PageOff12:
1602 {
1603 uint32_t offset = accumulator & 0x00000FFF;
1604 instruction = get32LE(fixUpLocation);
1605 // LDR/STR instruction have implicit scale factor, need to compensate for that
1606 if ( instruction & 0x08000000 ) {
1607 uint32_t implictShift = ((instruction >> 30) & 0x3);
1608 switch ( implictShift ) {
1609 case 0:
1610 if ( (instruction & 0x04800000) == 0x04800000 ) {
1611 // vector and byte LDR/STR have same "size" bits, need to check other bits to differenciate
1612 implictShift = 4;
1613 if ( (offset & 0xF) != 0 ) {
1614 throwf("128-bit LDR/STR not 16-byte aligned: from %s (0x%08llX) to %s (0x%08llX)",
1615 atom->name(), atom->finalAddress(), referenceTargetAtomName(state, fit),
1616 addressOf(state, fit, &toTarget));
1617 }
1618 }
1619 break;
1620 case 1:
1621 if ( (offset & 0x1) != 0 ) {
1622 throwf("16-bit LDR/STR not 2-byte aligned: from %s (0x%08llX) to %s (0x%08llX)",
1623 atom->name(), atom->finalAddress(), referenceTargetAtomName(state, fit),
1624 addressOf(state, fit, &toTarget));
1625 }
1626 break;
1627 case 2:
1628 if ( (offset & 0x3) != 0 ) {
1629 throwf("32-bit LDR/STR not 4-byte aligned: from %s (0x%08llX) to %s (0x%08llX)",
1630 atom->name(), atom->finalAddress(), referenceTargetAtomName(state, fit),
1631 addressOf(state, fit, &toTarget));
1632 }
1633 break;
1634 case 3:
1635 if ( (offset & 0x7) != 0 ) {
1636 throwf("64-bit LDR/STR not 8-byte aligned: from %s (0x%08llX) to %s (0x%08llX)",
1637 atom->name(), atom->finalAddress(), referenceTargetAtomName(state, fit),
1638 addressOf(state, fit, &toTarget));
1639 }
1640 break;
1641 }
1642 // compensate for implicit scale
1643 offset >>= implictShift;
1644 }
1645 if ( fit->contentAddendOnly )
1646 offset = 0;
1647 uint32_t imm12 = offset << 10;
1648 newInstruction = (instruction & 0xFFC003FF) | imm12;
1649 set32LE(fixUpLocation, newInstruction);
1650 }
1651 break;
1652 case ld::Fixup::kindStoreTargetAddressARM64GOTLeaPageOff12:
1653 accumulator = addressOf(state, fit, &toTarget);
1654 // fall into kindStoreARM64GOTLoadPage21 case
1655 case ld::Fixup::kindStoreARM64GOTLeaPageOff12:
1656 {
1657 // GOT entry was optimized away, change LDR instruction to a ADD
1658 instruction = get32LE(fixUpLocation);
1659 if ( (instruction & 0xFFC00000) != 0xF9400000 )
1660 throwf("GOT load reloc does not point to a LDR instruction in %s", atom->name());
1661 uint32_t offset = accumulator & 0x00000FFF;
1662 uint32_t imm12 = offset << 10;
1663 newInstruction = 0x91000000 | imm12 | (instruction & 0x000003FF);
1664 set32LE(fixUpLocation, newInstruction);
1665 }
1666 break;
1667 case ld::Fixup::kindStoreARM64PointerToGOT:
1668 set64LE(fixUpLocation, accumulator);
1669 break;
1670 case ld::Fixup::kindStoreARM64PCRelToGOT:
1671 if ( fit->contentAddendOnly )
1672 delta = accumulator;
1673 else
1674 delta = accumulator - (atom->finalAddress() + fit->offsetInAtom);
1675 set32LE(fixUpLocation, delta);
1676 break;
1677 #endif
1678 }
1679 }
1680 }
1681
1682 void OutputFile::copyNoOps(uint8_t* from, uint8_t* to, bool thumb)
1683 {
1684 switch ( _options.architecture() ) {
1685 case CPU_TYPE_I386:
1686 case CPU_TYPE_X86_64:
1687 for (uint8_t* p=from; p < to; ++p)
1688 *p = 0x90;
1689 break;
1690 case CPU_TYPE_ARM:
1691 if ( thumb ) {
1692 for (uint8_t* p=from; p < to; p += 2)
1693 OSWriteLittleInt16((uint16_t*)p, 0, 0x46c0);
1694 }
1695 else {
1696 for (uint8_t* p=from; p < to; p += 4)
1697 OSWriteLittleInt32((uint32_t*)p, 0, 0xe1a00000);
1698 }
1699 break;
1700 default:
1701 for (uint8_t* p=from; p < to; ++p)
1702 *p = 0x00;
1703 break;
1704 }
1705 }
1706
1707 bool OutputFile::takesNoDiskSpace(const ld::Section* sect)
1708 {
1709 switch ( sect->type() ) {
1710 case ld::Section::typeZeroFill:
1711 case ld::Section::typeTLVZeroFill:
1712 return _options.optimizeZeroFill();
1713 case ld::Section::typePageZero:
1714 case ld::Section::typeStack:
1715 case ld::Section::typeAbsoluteSymbols:
1716 case ld::Section::typeTentativeDefs:
1717 return true;
1718 default:
1719 break;
1720 }
1721 return false;
1722 }
1723
1724 bool OutputFile::hasZeroForFileOffset(const ld::Section* sect)
1725 {
1726 switch ( sect->type() ) {
1727 case ld::Section::typeZeroFill:
1728 case ld::Section::typeTLVZeroFill:
1729 return _options.optimizeZeroFill();
1730 case ld::Section::typePageZero:
1731 case ld::Section::typeStack:
1732 case ld::Section::typeTentativeDefs:
1733 return true;
1734 default:
1735 break;
1736 }
1737 return false;
1738 }
1739
1740 void OutputFile::writeAtoms(ld::Internal& state, uint8_t* wholeBuffer)
1741 {
1742 // have each atom write itself
1743 uint64_t fileOffsetOfEndOfLastAtom = 0;
1744 uint64_t mhAddress = 0;
1745 bool lastAtomUsesNoOps = false;
1746 for (std::vector<ld::Internal::FinalSection*>::iterator sit = state.sections.begin(); sit != state.sections.end(); ++sit) {
1747 ld::Internal::FinalSection* sect = *sit;
1748 if ( sect->type() == ld::Section::typeMachHeader )
1749 mhAddress = sect->address;
1750 if ( takesNoDiskSpace(sect) )
1751 continue;
1752 const bool sectionUsesNops = (sect->type() == ld::Section::typeCode);
1753 //fprintf(stderr, "file offset=0x%08llX, section %s\n", sect->fileOffset, sect->sectionName());
1754 std::vector<const ld::Atom*>& atoms = sect->atoms;
1755 bool lastAtomWasThumb = false;
1756 for (std::vector<const ld::Atom*>::iterator ait = atoms.begin(); ait != atoms.end(); ++ait) {
1757 const ld::Atom* atom = *ait;
1758 if ( atom->definition() == ld::Atom::definitionProxy )
1759 continue;
1760 try {
1761 uint64_t fileOffset = atom->finalAddress() - sect->address + sect->fileOffset;
1762 // check for alignment padding between atoms
1763 if ( (fileOffset != fileOffsetOfEndOfLastAtom) && lastAtomUsesNoOps ) {
1764 this->copyNoOps(&wholeBuffer[fileOffsetOfEndOfLastAtom], &wholeBuffer[fileOffset], lastAtomWasThumb);
1765 }
1766 // copy atom content
1767 atom->copyRawContent(&wholeBuffer[fileOffset]);
1768 // apply fix ups
1769 this->applyFixUps(state, mhAddress, atom, &wholeBuffer[fileOffset]);
1770 fileOffsetOfEndOfLastAtom = fileOffset+atom->size();
1771 lastAtomUsesNoOps = sectionUsesNops;
1772 lastAtomWasThumb = atom->isThumb();
1773 }
1774 catch (const char* msg) {
1775 if ( atom->file() != NULL )
1776 throwf("%s in '%s' from %s", msg, atom->name(), atom->file()->path());
1777 else
1778 throwf("%s in '%s'", msg, atom->name());
1779 }
1780 }
1781 }
1782 }
1783
1784
1785 void OutputFile::computeContentUUID(ld::Internal& state, uint8_t* wholeBuffer)
1786 {
1787 const bool log = false;
1788 if ( (_options.outputKind() != Options::kObjectFile) || state.someObjectFileHasDwarf ) {
1789 uint8_t digest[CC_MD5_DIGEST_LENGTH];
1790 uint32_t stabsStringsOffsetStart;
1791 uint32_t tabsStringsOffsetEnd;
1792 uint32_t stabsOffsetStart;
1793 uint32_t stabsOffsetEnd;
1794 if ( _symbolTableAtom->hasStabs(stabsStringsOffsetStart, tabsStringsOffsetEnd, stabsOffsetStart, stabsOffsetEnd) ) {
1795 // find two areas of file that are stabs info and should not contribute to checksum
1796 uint64_t stringPoolFileOffset = 0;
1797 uint64_t symbolTableFileOffset = 0;
1798 for (std::vector<ld::Internal::FinalSection*>::iterator sit = state.sections.begin(); sit != state.sections.end(); ++sit) {
1799 ld::Internal::FinalSection* sect = *sit;
1800 if ( sect->type() == ld::Section::typeLinkEdit ) {
1801 if ( strcmp(sect->sectionName(), "__string_pool") == 0 )
1802 stringPoolFileOffset = sect->fileOffset;
1803 else if ( strcmp(sect->sectionName(), "__symbol_table") == 0 )
1804 symbolTableFileOffset = sect->fileOffset;
1805 }
1806 }
1807 uint64_t firstStabNlistFileOffset = symbolTableFileOffset + stabsOffsetStart;
1808 uint64_t lastStabNlistFileOffset = symbolTableFileOffset + stabsOffsetEnd;
1809 uint64_t firstStabStringFileOffset = stringPoolFileOffset + stabsStringsOffsetStart;
1810 uint64_t lastStabStringFileOffset = stringPoolFileOffset + tabsStringsOffsetEnd;
1811 if ( log ) fprintf(stderr, "firstStabNlistFileOffset=0x%08llX\n", firstStabNlistFileOffset);
1812 if ( log ) fprintf(stderr, "lastStabNlistFileOffset=0x%08llX\n", lastStabNlistFileOffset);
1813 if ( log ) fprintf(stderr, "firstStabStringFileOffset=0x%08llX\n", firstStabStringFileOffset);
1814 if ( log ) fprintf(stderr, "lastStabStringFileOffset=0x%08llX\n", lastStabStringFileOffset);
1815 assert(firstStabNlistFileOffset <= firstStabStringFileOffset);
1816
1817 CC_MD5_CTX md5state;
1818 CC_MD5_Init(&md5state);
1819 // checksum everything up to first stabs nlist
1820 if ( log ) fprintf(stderr, "checksum 0x%08X -> 0x%08llX\n", 0, firstStabNlistFileOffset);
1821 CC_MD5_Update(&md5state, &wholeBuffer[0], firstStabNlistFileOffset);
1822 // checkusm everything after last stabs nlist and up to first stabs string
1823 if ( log ) fprintf(stderr, "checksum 0x%08llX -> 0x%08llX\n", lastStabNlistFileOffset, firstStabStringFileOffset);
1824 CC_MD5_Update(&md5state, &wholeBuffer[lastStabNlistFileOffset], firstStabStringFileOffset-lastStabNlistFileOffset);
1825 // checksum everything after last stabs string to end of file
1826 if ( log ) fprintf(stderr, "checksum 0x%08llX -> 0x%08llX\n", lastStabStringFileOffset, _fileSize);
1827 CC_MD5_Update(&md5state, &wholeBuffer[lastStabStringFileOffset], _fileSize-lastStabStringFileOffset);
1828 CC_MD5_Final(digest, &md5state);
1829 if ( log ) fprintf(stderr, "uuid=%02X, %02X, %02X, %02X, %02X, %02X, %02X, %02X\n", digest[0], digest[1], digest[2],
1830 digest[3], digest[4], digest[5], digest[6], digest[7]);
1831 }
1832 else {
1833 CC_MD5(wholeBuffer, _fileSize, digest);
1834 }
1835 // <rdar://problem/6723729> LC_UUID uuids should conform to RFC 4122 UUID version 4 & UUID version 5 formats
1836 digest[6] = ( digest[6] & 0x0F ) | ( 3 << 4 );
1837 digest[8] = ( digest[8] & 0x3F ) | 0x80;
1838 // update buffer with new UUID
1839 _headersAndLoadCommandAtom->setUUID(digest);
1840 _headersAndLoadCommandAtom->recopyUUIDCommand();
1841 }
1842 }
1843
1844
1845 void OutputFile::writeOutputFile(ld::Internal& state)
1846 {
1847 // for UNIX conformance, error if file exists and is not writable
1848 if ( (access(_options.outputFilePath(), F_OK) == 0) && (access(_options.outputFilePath(), W_OK) == -1) )
1849 throwf("can't write output file: %s", _options.outputFilePath());
1850
1851 mode_t permissions = 0777;
1852 if ( _options.outputKind() == Options::kObjectFile )
1853 permissions = 0666;
1854 mode_t umask = ::umask(0);
1855 ::umask(umask); // put back the original umask
1856 permissions &= ~umask;
1857 // Calling unlink first assures the file is gone so that open creates it with correct permissions
1858 // It also handles the case where __options.outputFilePath() file is not writable but its directory is
1859 // And it means we don't have to truncate the file when done writing (in case new is smaller than old)
1860 // Lastly, only delete existing file if it is a normal file (e.g. not /dev/null).
1861 struct stat stat_buf;
1862 bool outputIsRegularFile = false;
1863 bool outputIsMappableFile = false;
1864 if ( stat(_options.outputFilePath(), &stat_buf) != -1 ) {
1865 if (stat_buf.st_mode & S_IFREG) {
1866 outputIsRegularFile = true;
1867 // <rdar://problem/12264302> Don't use mmap on non-hfs volumes
1868 struct statfs fsInfo;
1869 if ( statfs(_options.outputFilePath(), &fsInfo) != -1 ) {
1870 if ( strcmp(fsInfo.f_fstypename, "hfs") == 0) {
1871 (void)unlink(_options.outputFilePath());
1872 outputIsMappableFile = true;
1873 }
1874 }
1875 else {
1876 outputIsMappableFile = false;
1877 }
1878 }
1879 else {
1880 outputIsRegularFile = false;
1881 }
1882 }
1883 else {
1884 // special files (pipes, devices, etc) must already exist
1885 outputIsRegularFile = true;
1886 // output file does not exist yet
1887 char dirPath[PATH_MAX];
1888 strcpy(dirPath, _options.outputFilePath());
1889 char* end = strrchr(dirPath, '/');
1890 if ( end != NULL ) {
1891 end[1] = '\0';
1892 struct statfs fsInfo;
1893 if ( statfs(dirPath, &fsInfo) != -1 ) {
1894 if ( strcmp(fsInfo.f_fstypename, "hfs") == 0) {
1895 outputIsMappableFile = true;
1896 }
1897 }
1898 }
1899 }
1900
1901 //fprintf(stderr, "outputIsMappableFile=%d, outputIsRegularFile=%d, path=%s\n", outputIsMappableFile, outputIsRegularFile, _options.outputFilePath());
1902
1903 int fd;
1904 // Construct a temporary path of the form {outputFilePath}.ld_XXXXXX
1905 const char filenameTemplate[] = ".ld_XXXXXX";
1906 char tmpOutput[PATH_MAX];
1907 uint8_t *wholeBuffer;
1908 if ( outputIsRegularFile && outputIsMappableFile ) {
1909 strcpy(tmpOutput, _options.outputFilePath());
1910 // If the path is too long to add a suffix for a temporary name then
1911 // just fall back to using the output path.
1912 if (strlen(tmpOutput)+strlen(filenameTemplate) < PATH_MAX) {
1913 strcat(tmpOutput, filenameTemplate);
1914 fd = mkstemp(tmpOutput);
1915 }
1916 else {
1917 fd = open(tmpOutput, O_RDWR|O_CREAT, permissions);
1918 }
1919 if ( fd == -1 )
1920 throwf("can't open output file for writing '%s', errno=%d", tmpOutput, errno);
1921 if ( ftruncate(fd, _fileSize) == -1 ) {
1922 int err = errno;
1923 unlink(tmpOutput);
1924 if ( err == ENOSPC )
1925 throwf("not enough disk space for writing '%s'", _options.outputFilePath());
1926 else
1927 throwf("can't grow file for writing '%s', errno=%d", _options.outputFilePath(), err);
1928 }
1929
1930 wholeBuffer = (uint8_t *)mmap(NULL, _fileSize, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0);
1931 if ( wholeBuffer == MAP_FAILED )
1932 throwf("can't create buffer of %llu bytes for output", _fileSize);
1933 }
1934 else {
1935 if ( outputIsRegularFile )
1936 fd = open(_options.outputFilePath(), O_RDWR|O_CREAT, permissions);
1937 else
1938 fd = open(_options.outputFilePath(), O_WRONLY);
1939 if ( fd == -1 )
1940 throwf("can't open output file for writing: %s, errno=%d", _options.outputFilePath(), errno);
1941 // try to allocate buffer for entire output file content
1942 wholeBuffer = (uint8_t*)calloc(_fileSize, 1);
1943 if ( wholeBuffer == NULL )
1944 throwf("can't create buffer of %llu bytes for output", _fileSize);
1945 }
1946
1947 if ( _options.UUIDMode() == Options::kUUIDRandom ) {
1948 uint8_t bits[16];
1949 ::uuid_generate_random(bits);
1950 _headersAndLoadCommandAtom->setUUID(bits);
1951 }
1952
1953 writeAtoms(state, wholeBuffer);
1954
1955 // compute UUID
1956 if ( _options.UUIDMode() == Options::kUUIDContent )
1957 computeContentUUID(state, wholeBuffer);
1958
1959 if ( outputIsRegularFile && outputIsMappableFile ) {
1960 if ( ::chmod(tmpOutput, permissions) == -1 ) {
1961 unlink(tmpOutput);
1962 throwf("can't set permissions on output file: %s, errno=%d", tmpOutput, errno);
1963 }
1964 if ( ::rename(tmpOutput, _options.outputFilePath()) == -1 && strcmp(tmpOutput, _options.outputFilePath()) != 0) {
1965 unlink(tmpOutput);
1966 throwf("can't move output file in place, errno=%d", errno);
1967 }
1968 }
1969 else {
1970 if ( ::write(fd, wholeBuffer, _fileSize) == -1 ) {
1971 throwf("can't write to output file: %s, errno=%d", _options.outputFilePath(), errno);
1972 }
1973 ::close(fd);
1974 // <rdar://problem/13118223> NFS: iOS incremental builds in Xcode 4.6 fail with codesign error
1975 // NFS seems to pad the end of the file sometimes. Calling trunc seems to correct it...
1976 ::truncate(_options.outputFilePath(), _fileSize);
1977 }
1978 }
1979
1980 struct AtomByNameSorter
1981 {
1982 bool operator()(const ld::Atom* left, const ld::Atom* right)
1983 {
1984 return (strcmp(left->name(), right->name()) < 0);
1985 }
1986 };
1987
1988 class NotInSet
1989 {
1990 public:
1991 NotInSet(const std::set<const ld::Atom*>& theSet) : _set(theSet) {}
1992
1993 bool operator()(const ld::Atom* atom) const {
1994 return ( _set.count(atom) == 0 );
1995 }
1996 private:
1997 const std::set<const ld::Atom*>& _set;
1998 };
1999
2000
2001 void OutputFile::buildSymbolTable(ld::Internal& state)
2002 {
2003 unsigned int machoSectionIndex = 0;
2004 for (std::vector<ld::Internal::FinalSection*>::iterator sit = state.sections.begin(); sit != state.sections.end(); ++sit) {
2005 ld::Internal::FinalSection* sect = *sit;
2006 bool setMachoSectionIndex = !sect->isSectionHidden() && (sect->type() != ld::Section::typeTentativeDefs);
2007 if ( setMachoSectionIndex )
2008 ++machoSectionIndex;
2009 for (std::vector<const ld::Atom*>::iterator ait = sect->atoms.begin(); ait != sect->atoms.end(); ++ait) {
2010 const ld::Atom* atom = *ait;
2011 if ( setMachoSectionIndex )
2012 (const_cast<ld::Atom*>(atom))->setMachoSection(machoSectionIndex);
2013 else if ( sect->type() == ld::Section::typeMachHeader )
2014 (const_cast<ld::Atom*>(atom))->setMachoSection(1); // __mh_execute_header is not in any section by needs n_sect==1
2015 else if ( sect->type() == ld::Section::typeLastSection )
2016 (const_cast<ld::Atom*>(atom))->setMachoSection(machoSectionIndex); // use section index of previous section
2017 else if ( sect->type() == ld::Section::typeFirstSection )
2018 (const_cast<ld::Atom*>(atom))->setMachoSection(machoSectionIndex+1); // use section index of next section
2019
2020 // in -r mode, clarify symbolTableNotInFinalLinkedImages
2021 if ( _options.outputKind() == Options::kObjectFile ) {
2022 if ( (_options.architecture() == CPU_TYPE_X86_64) || (_options.architecture() == CPU_TYPE_ARM64) ) {
2023 // x86_64 .o files need labels on anonymous literal strings
2024 if ( (sect->type() == ld::Section::typeCString) && (atom->combine() == ld::Atom::combineByNameAndContent) ) {
2025 (const_cast<ld::Atom*>(atom))->setSymbolTableInclusion(ld::Atom::symbolTableIn);
2026 _localAtoms.push_back(atom);
2027 continue;
2028 }
2029 }
2030 if ( sect->type() == ld::Section::typeCFI ) {
2031 if ( _options.removeEHLabels() )
2032 (const_cast<ld::Atom*>(atom))->setSymbolTableInclusion(ld::Atom::symbolTableNotIn);
2033 else
2034 (const_cast<ld::Atom*>(atom))->setSymbolTableInclusion(ld::Atom::symbolTableIn);
2035 }
2036 if ( atom->symbolTableInclusion() == ld::Atom::symbolTableNotInFinalLinkedImages )
2037 (const_cast<ld::Atom*>(atom))->setSymbolTableInclusion(ld::Atom::symbolTableIn);
2038 }
2039
2040 // TEMP work around until <rdar://problem/7702923> goes in
2041 if ( (atom->symbolTableInclusion() == ld::Atom::symbolTableInAndNeverStrip)
2042 && (atom->scope() == ld::Atom::scopeLinkageUnit)
2043 && (_options.outputKind() == Options::kDynamicLibrary) ) {
2044 (const_cast<ld::Atom*>(atom))->setScope(ld::Atom::scopeGlobal);
2045 }
2046
2047 // <rdar://problem/6783167> support auto hidden weak symbols: .weak_def_can_be_hidden
2048 if ( atom->autoHide() && (_options.outputKind() != Options::kObjectFile) ) {
2049 // adding auto-hide symbol to .exp file should keep it global
2050 if ( !_options.hasExportMaskList() || !_options.shouldExport(atom->name()) )
2051 (const_cast<ld::Atom*>(atom))->setScope(ld::Atom::scopeLinkageUnit);
2052 }
2053
2054 // <rdar://problem/8626058> ld should consistently warn when resolvers are not exported
2055 if ( (atom->contentType() == ld::Atom::typeResolver) && (atom->scope() == ld::Atom::scopeLinkageUnit) )
2056 warning("resolver functions should be external, but '%s' is hidden", atom->name());
2057
2058 if ( sect->type() == ld::Section::typeImportProxies ) {
2059 if ( atom->combine() == ld::Atom::combineByName )
2060 this->usesWeakExternalSymbols = true;
2061 // alias proxy is a re-export with a name change, don't import changed name
2062 if ( ! atom->isAlias() )
2063 _importedAtoms.push_back(atom);
2064 // scope of proxies are usually linkage unit, so done
2065 // if scope is global, we need to re-export it too
2066 if ( atom->scope() == ld::Atom::scopeGlobal )
2067 _exportedAtoms.push_back(atom);
2068 continue;
2069 }
2070 if ( atom->symbolTableInclusion() == ld::Atom::symbolTableNotInFinalLinkedImages ) {
2071 assert(_options.outputKind() != Options::kObjectFile);
2072 continue; // don't add to symbol table
2073 }
2074 if ( atom->symbolTableInclusion() == ld::Atom::symbolTableNotIn ) {
2075 continue; // don't add to symbol table
2076 }
2077 if ( (atom->symbolTableInclusion() == ld::Atom::symbolTableInWithRandomAutoStripLabel)
2078 && (_options.outputKind() != Options::kObjectFile) ) {
2079 continue; // don't add to symbol table
2080 }
2081
2082 if ( (atom->definition() == ld::Atom::definitionTentative) && (_options.outputKind() == Options::kObjectFile) ) {
2083 if ( _options.makeTentativeDefinitionsReal() ) {
2084 // -r -d turns tentative defintions into real def
2085 _exportedAtoms.push_back(atom);
2086 }
2087 else {
2088 // in mach-o object files tentative defintions are stored like undefined symbols
2089 _importedAtoms.push_back(atom);
2090 }
2091 continue;
2092 }
2093
2094 switch ( atom->scope() ) {
2095 case ld::Atom::scopeTranslationUnit:
2096 if ( _options.keepLocalSymbol(atom->name()) ) {
2097 _localAtoms.push_back(atom);
2098 }
2099 else {
2100 if ( _options.outputKind() == Options::kObjectFile ) {
2101 (const_cast<ld::Atom*>(atom))->setSymbolTableInclusion(ld::Atom::symbolTableInWithRandomAutoStripLabel);
2102 _localAtoms.push_back(atom);
2103 }
2104 else
2105 (const_cast<ld::Atom*>(atom))->setSymbolTableInclusion(ld::Atom::symbolTableNotIn);
2106 }
2107 break;
2108 case ld::Atom::scopeGlobal:
2109 _exportedAtoms.push_back(atom);
2110 break;
2111 case ld::Atom::scopeLinkageUnit:
2112 if ( _options.outputKind() == Options::kObjectFile ) {
2113 if ( _options.keepPrivateExterns() ) {
2114 _exportedAtoms.push_back(atom);
2115 }
2116 else if ( _options.keepLocalSymbol(atom->name()) ) {
2117 _localAtoms.push_back(atom);
2118 }
2119 else {
2120 (const_cast<ld::Atom*>(atom))->setSymbolTableInclusion(ld::Atom::symbolTableInWithRandomAutoStripLabel);
2121 _localAtoms.push_back(atom);
2122 }
2123 }
2124 else {
2125 if ( _options.keepLocalSymbol(atom->name()) )
2126 _localAtoms.push_back(atom);
2127 // <rdar://problem/5804214> ld should never have a symbol in the non-lazy indirect symbol table with index 0
2128 // this works by making __mh_execute_header be a local symbol which takes symbol index 0
2129 else if ( (atom->symbolTableInclusion() == ld::Atom::symbolTableInAndNeverStrip) && !_options.makeCompressedDyldInfo() )
2130 _localAtoms.push_back(atom);
2131 else
2132 (const_cast<ld::Atom*>(atom))->setSymbolTableInclusion(ld::Atom::symbolTableNotIn);
2133 }
2134 break;
2135 }
2136 }
2137 }
2138
2139 // <rdar://problem/6978069> ld adds undefined symbol from .exp file to binary
2140 if ( (_options.outputKind() == Options::kKextBundle) && _options.hasExportRestrictList() ) {
2141 // search for referenced undefines
2142 std::set<const ld::Atom*> referencedProxyAtoms;
2143 for (std::vector<ld::Internal::FinalSection*>::iterator sit=state.sections.begin(); sit != state.sections.end(); ++sit) {
2144 ld::Internal::FinalSection* sect = *sit;
2145 for (std::vector<const ld::Atom*>::iterator ait=sect->atoms.begin(); ait != sect->atoms.end(); ++ait) {
2146 const ld::Atom* atom = *ait;
2147 for (ld::Fixup::iterator fit = atom->fixupsBegin(), end=atom->fixupsEnd(); fit != end; ++fit) {
2148 switch ( fit->binding ) {
2149 case ld::Fixup::bindingsIndirectlyBound:
2150 referencedProxyAtoms.insert(state.indirectBindingTable[fit->u.bindingIndex]);
2151 break;
2152 case ld::Fixup::bindingDirectlyBound:
2153 referencedProxyAtoms.insert(fit->u.target);
2154 break;
2155 default:
2156 break;
2157 }
2158 }
2159 }
2160 }
2161 // remove any unreferenced _importedAtoms
2162 _importedAtoms.erase(std::remove_if(_importedAtoms.begin(), _importedAtoms.end(), NotInSet(referencedProxyAtoms)), _importedAtoms.end());
2163 }
2164
2165 // sort by name
2166 std::sort(_exportedAtoms.begin(), _exportedAtoms.end(), AtomByNameSorter());
2167 std::sort(_importedAtoms.begin(), _importedAtoms.end(), AtomByNameSorter());
2168 }
2169
2170 void OutputFile::addPreloadLinkEdit(ld::Internal& state)
2171 {
2172 switch ( _options.architecture() ) {
2173 #if SUPPORT_ARCH_i386
2174 case CPU_TYPE_I386:
2175 if ( _hasLocalRelocations ) {
2176 _localRelocsAtom = new LocalRelocationsAtom<x86>(_options, state, *this);
2177 localRelocationsSection = state.addAtom(*_localRelocsAtom);
2178 }
2179 if ( _hasExternalRelocations ) {
2180 _externalRelocsAtom = new ExternalRelocationsAtom<x86>(_options, state, *this);
2181 externalRelocationsSection = state.addAtom(*_externalRelocsAtom);
2182 }
2183 if ( _hasSymbolTable ) {
2184 _indirectSymbolTableAtom = new IndirectSymbolTableAtom<x86>(_options, state, *this);
2185 indirectSymbolTableSection = state.addAtom(*_indirectSymbolTableAtom);
2186 _symbolTableAtom = new SymbolTableAtom<x86>(_options, state, *this);
2187 symbolTableSection = state.addAtom(*_symbolTableAtom);
2188 _stringPoolAtom = new StringPoolAtom(_options, state, *this, 4);
2189 stringPoolSection = state.addAtom(*_stringPoolAtom);
2190 }
2191 break;
2192 #endif
2193 #if SUPPORT_ARCH_x86_64
2194 case CPU_TYPE_X86_64:
2195 if ( _hasLocalRelocations ) {
2196 _localRelocsAtom = new LocalRelocationsAtom<x86_64>(_options, state, *this);
2197 localRelocationsSection = state.addAtom(*_localRelocsAtom);
2198 }
2199 if ( _hasExternalRelocations ) {
2200 _externalRelocsAtom = new ExternalRelocationsAtom<x86_64>(_options, state, *this);
2201 externalRelocationsSection = state.addAtom(*_externalRelocsAtom);
2202 }
2203 if ( _hasSymbolTable ) {
2204 _indirectSymbolTableAtom = new IndirectSymbolTableAtom<x86_64>(_options, state, *this);
2205 indirectSymbolTableSection = state.addAtom(*_indirectSymbolTableAtom);
2206 _symbolTableAtom = new SymbolTableAtom<x86_64>(_options, state, *this);
2207 symbolTableSection = state.addAtom(*_symbolTableAtom);
2208 _stringPoolAtom = new StringPoolAtom(_options, state, *this, 4);
2209 stringPoolSection = state.addAtom(*_stringPoolAtom);
2210 }
2211 break;
2212 #endif
2213 #if SUPPORT_ARCH_arm_any
2214 case CPU_TYPE_ARM:
2215 if ( _hasLocalRelocations ) {
2216 _localRelocsAtom = new LocalRelocationsAtom<arm>(_options, state, *this);
2217 localRelocationsSection = state.addAtom(*_localRelocsAtom);
2218 }
2219 if ( _hasExternalRelocations ) {
2220 _externalRelocsAtom = new ExternalRelocationsAtom<arm>(_options, state, *this);
2221 externalRelocationsSection = state.addAtom(*_externalRelocsAtom);
2222 }
2223 if ( _hasSymbolTable ) {
2224 _indirectSymbolTableAtom = new IndirectSymbolTableAtom<arm>(_options, state, *this);
2225 indirectSymbolTableSection = state.addAtom(*_indirectSymbolTableAtom);
2226 _symbolTableAtom = new SymbolTableAtom<arm>(_options, state, *this);
2227 symbolTableSection = state.addAtom(*_symbolTableAtom);
2228 _stringPoolAtom = new StringPoolAtom(_options, state, *this, 4);
2229 stringPoolSection = state.addAtom(*_stringPoolAtom);
2230 }
2231 break;
2232 #endif
2233 #if SUPPORT_ARCH_arm64
2234 case CPU_TYPE_ARM64:
2235 if ( _hasLocalRelocations ) {
2236 _localRelocsAtom = new LocalRelocationsAtom<arm64>(_options, state, *this);
2237 localRelocationsSection = state.addAtom(*_localRelocsAtom);
2238 }
2239 if ( _hasExternalRelocations ) {
2240 _externalRelocsAtom = new ExternalRelocationsAtom<arm64>(_options, state, *this);
2241 externalRelocationsSection = state.addAtom(*_externalRelocsAtom);
2242 }
2243 if ( _hasSymbolTable ) {
2244 _indirectSymbolTableAtom = new IndirectSymbolTableAtom<arm64>(_options, state, *this);
2245 indirectSymbolTableSection = state.addAtom(*_indirectSymbolTableAtom);
2246 _symbolTableAtom = new SymbolTableAtom<arm64>(_options, state, *this);
2247 symbolTableSection = state.addAtom(*_symbolTableAtom);
2248 _stringPoolAtom = new StringPoolAtom(_options, state, *this, 4);
2249 stringPoolSection = state.addAtom(*_stringPoolAtom);
2250 }
2251 break;
2252 #endif
2253 default:
2254 throw "-preload not supported";
2255 }
2256
2257 }
2258
2259
2260 void OutputFile::addLinkEdit(ld::Internal& state)
2261 {
2262 // for historical reasons, -preload orders LINKEDIT content differently
2263 if ( _options.outputKind() == Options::kPreload )
2264 return addPreloadLinkEdit(state);
2265
2266 switch ( _options.architecture() ) {
2267 #if SUPPORT_ARCH_i386
2268 case CPU_TYPE_I386:
2269 if ( _hasSectionRelocations ) {
2270 _sectionsRelocationsAtom = new SectionRelocationsAtom<x86>(_options, state, *this);
2271 sectionRelocationsSection = state.addAtom(*_sectionsRelocationsAtom);
2272 }
2273 if ( _hasDyldInfo ) {
2274 _rebasingInfoAtom = new RebaseInfoAtom<x86>(_options, state, *this);
2275 rebaseSection = state.addAtom(*_rebasingInfoAtom);
2276
2277 _bindingInfoAtom = new BindingInfoAtom<x86>(_options, state, *this);
2278 bindingSection = state.addAtom(*_bindingInfoAtom);
2279
2280 _weakBindingInfoAtom = new WeakBindingInfoAtom<x86>(_options, state, *this);
2281 weakBindingSection = state.addAtom(*_weakBindingInfoAtom);
2282
2283 _lazyBindingInfoAtom = new LazyBindingInfoAtom<x86>(_options, state, *this);
2284 lazyBindingSection = state.addAtom(*_lazyBindingInfoAtom);
2285
2286 _exportInfoAtom = new ExportInfoAtom<x86>(_options, state, *this);
2287 exportSection = state.addAtom(*_exportInfoAtom);
2288 }
2289 if ( _hasLocalRelocations ) {
2290 _localRelocsAtom = new LocalRelocationsAtom<x86>(_options, state, *this);
2291 localRelocationsSection = state.addAtom(*_localRelocsAtom);
2292 }
2293 if ( _hasSplitSegInfo ) {
2294 _splitSegInfoAtom = new SplitSegInfoAtom<x86>(_options, state, *this);
2295 splitSegInfoSection = state.addAtom(*_splitSegInfoAtom);
2296 }
2297 if ( _hasFunctionStartsInfo ) {
2298 _functionStartsAtom = new FunctionStartsAtom<x86>(_options, state, *this);
2299 functionStartsSection = state.addAtom(*_functionStartsAtom);
2300 }
2301 if ( _hasDataInCodeInfo ) {
2302 _dataInCodeAtom = new DataInCodeAtom<x86>(_options, state, *this);
2303 dataInCodeSection = state.addAtom(*_dataInCodeAtom);
2304 }
2305 if ( _hasDependentDRInfo ) {
2306 _dependentDRInfoAtom = new DependentDRAtom<x86>(_options, state, *this);
2307 dependentDRsSection = state.addAtom(*_dependentDRInfoAtom);
2308 }
2309 if ( _hasSymbolTable ) {
2310 _symbolTableAtom = new SymbolTableAtom<x86>(_options, state, *this);
2311 symbolTableSection = state.addAtom(*_symbolTableAtom);
2312 }
2313 if ( _hasExternalRelocations ) {
2314 _externalRelocsAtom = new ExternalRelocationsAtom<x86>(_options, state, *this);
2315 externalRelocationsSection = state.addAtom(*_externalRelocsAtom);
2316 }
2317 if ( _hasSymbolTable ) {
2318 _indirectSymbolTableAtom = new IndirectSymbolTableAtom<x86>(_options, state, *this);
2319 indirectSymbolTableSection = state.addAtom(*_indirectSymbolTableAtom);
2320 _stringPoolAtom = new StringPoolAtom(_options, state, *this, 4);
2321 stringPoolSection = state.addAtom(*_stringPoolAtom);
2322 }
2323 break;
2324 #endif
2325 #if SUPPORT_ARCH_x86_64
2326 case CPU_TYPE_X86_64:
2327 if ( _hasSectionRelocations ) {
2328 _sectionsRelocationsAtom = new SectionRelocationsAtom<x86_64>(_options, state, *this);
2329 sectionRelocationsSection = state.addAtom(*_sectionsRelocationsAtom);
2330 }
2331 if ( _hasDyldInfo ) {
2332 _rebasingInfoAtom = new RebaseInfoAtom<x86_64>(_options, state, *this);
2333 rebaseSection = state.addAtom(*_rebasingInfoAtom);
2334
2335 _bindingInfoAtom = new BindingInfoAtom<x86_64>(_options, state, *this);
2336 bindingSection = state.addAtom(*_bindingInfoAtom);
2337
2338 _weakBindingInfoAtom = new WeakBindingInfoAtom<x86_64>(_options, state, *this);
2339 weakBindingSection = state.addAtom(*_weakBindingInfoAtom);
2340
2341 _lazyBindingInfoAtom = new LazyBindingInfoAtom<x86_64>(_options, state, *this);
2342 lazyBindingSection = state.addAtom(*_lazyBindingInfoAtom);
2343
2344 _exportInfoAtom = new ExportInfoAtom<x86_64>(_options, state, *this);
2345 exportSection = state.addAtom(*_exportInfoAtom);
2346 }
2347 if ( _hasLocalRelocations ) {
2348 _localRelocsAtom = new LocalRelocationsAtom<x86_64>(_options, state, *this);
2349 localRelocationsSection = state.addAtom(*_localRelocsAtom);
2350 }
2351 if ( _hasSplitSegInfo ) {
2352 _splitSegInfoAtom = new SplitSegInfoAtom<x86_64>(_options, state, *this);
2353 splitSegInfoSection = state.addAtom(*_splitSegInfoAtom);
2354 }
2355 if ( _hasFunctionStartsInfo ) {
2356 _functionStartsAtom = new FunctionStartsAtom<x86_64>(_options, state, *this);
2357 functionStartsSection = state.addAtom(*_functionStartsAtom);
2358 }
2359 if ( _hasDataInCodeInfo ) {
2360 _dataInCodeAtom = new DataInCodeAtom<x86_64>(_options, state, *this);
2361 dataInCodeSection = state.addAtom(*_dataInCodeAtom);
2362 }
2363 if ( _hasDependentDRInfo ) {
2364 _dependentDRInfoAtom = new DependentDRAtom<x86_64>(_options, state, *this);
2365 dependentDRsSection = state.addAtom(*_dependentDRInfoAtom);
2366 }
2367 if ( _hasSymbolTable ) {
2368 _symbolTableAtom = new SymbolTableAtom<x86_64>(_options, state, *this);
2369 symbolTableSection = state.addAtom(*_symbolTableAtom);
2370 }
2371 if ( _hasExternalRelocations ) {
2372 _externalRelocsAtom = new ExternalRelocationsAtom<x86_64>(_options, state, *this);
2373 externalRelocationsSection = state.addAtom(*_externalRelocsAtom);
2374 }
2375 if ( _hasSymbolTable ) {
2376 _indirectSymbolTableAtom = new IndirectSymbolTableAtom<x86_64>(_options, state, *this);
2377 indirectSymbolTableSection = state.addAtom(*_indirectSymbolTableAtom);
2378 _stringPoolAtom = new StringPoolAtom(_options, state, *this, 8);
2379 stringPoolSection = state.addAtom(*_stringPoolAtom);
2380 }
2381 break;
2382 #endif
2383 #if SUPPORT_ARCH_arm_any
2384 case CPU_TYPE_ARM:
2385 if ( _hasSectionRelocations ) {
2386 _sectionsRelocationsAtom = new SectionRelocationsAtom<arm>(_options, state, *this);
2387 sectionRelocationsSection = state.addAtom(*_sectionsRelocationsAtom);
2388 }
2389 if ( _hasDyldInfo ) {
2390 _rebasingInfoAtom = new RebaseInfoAtom<arm>(_options, state, *this);
2391 rebaseSection = state.addAtom(*_rebasingInfoAtom);
2392
2393 _bindingInfoAtom = new BindingInfoAtom<arm>(_options, state, *this);
2394 bindingSection = state.addAtom(*_bindingInfoAtom);
2395
2396 _weakBindingInfoAtom = new WeakBindingInfoAtom<arm>(_options, state, *this);
2397 weakBindingSection = state.addAtom(*_weakBindingInfoAtom);
2398
2399 _lazyBindingInfoAtom = new LazyBindingInfoAtom<arm>(_options, state, *this);
2400 lazyBindingSection = state.addAtom(*_lazyBindingInfoAtom);
2401
2402 _exportInfoAtom = new ExportInfoAtom<arm>(_options, state, *this);
2403 exportSection = state.addAtom(*_exportInfoAtom);
2404 }
2405 if ( _hasLocalRelocations ) {
2406 _localRelocsAtom = new LocalRelocationsAtom<arm>(_options, state, *this);
2407 localRelocationsSection = state.addAtom(*_localRelocsAtom);
2408 }
2409 if ( _hasSplitSegInfo ) {
2410 _splitSegInfoAtom = new SplitSegInfoAtom<arm>(_options, state, *this);
2411 splitSegInfoSection = state.addAtom(*_splitSegInfoAtom);
2412 }
2413 if ( _hasFunctionStartsInfo ) {
2414 _functionStartsAtom = new FunctionStartsAtom<arm>(_options, state, *this);
2415 functionStartsSection = state.addAtom(*_functionStartsAtom);
2416 }
2417 if ( _hasDataInCodeInfo ) {
2418 _dataInCodeAtom = new DataInCodeAtom<arm>(_options, state, *this);
2419 dataInCodeSection = state.addAtom(*_dataInCodeAtom);
2420 }
2421 if ( _hasDependentDRInfo ) {
2422 _dependentDRInfoAtom = new DependentDRAtom<arm>(_options, state, *this);
2423 dependentDRsSection = state.addAtom(*_dependentDRInfoAtom);
2424 }
2425 if ( _hasSymbolTable ) {
2426 _symbolTableAtom = new SymbolTableAtom<arm>(_options, state, *this);
2427 symbolTableSection = state.addAtom(*_symbolTableAtom);
2428 }
2429 if ( _hasExternalRelocations ) {
2430 _externalRelocsAtom = new ExternalRelocationsAtom<arm>(_options, state, *this);
2431 externalRelocationsSection = state.addAtom(*_externalRelocsAtom);
2432 }
2433 if ( _hasSymbolTable ) {
2434 _indirectSymbolTableAtom = new IndirectSymbolTableAtom<arm>(_options, state, *this);
2435 indirectSymbolTableSection = state.addAtom(*_indirectSymbolTableAtom);
2436 _stringPoolAtom = new StringPoolAtom(_options, state, *this, 4);
2437 stringPoolSection = state.addAtom(*_stringPoolAtom);
2438 }
2439 break;
2440 #endif
2441 #if SUPPORT_ARCH_arm64
2442 case CPU_TYPE_ARM64:
2443 if ( _hasSectionRelocations ) {
2444 _sectionsRelocationsAtom = new SectionRelocationsAtom<arm64>(_options, state, *this);
2445 sectionRelocationsSection = state.addAtom(*_sectionsRelocationsAtom);
2446 }
2447 if ( _hasDyldInfo ) {
2448 _rebasingInfoAtom = new RebaseInfoAtom<arm64>(_options, state, *this);
2449 rebaseSection = state.addAtom(*_rebasingInfoAtom);
2450
2451 _bindingInfoAtom = new BindingInfoAtom<arm64>(_options, state, *this);
2452 bindingSection = state.addAtom(*_bindingInfoAtom);
2453
2454 _weakBindingInfoAtom = new WeakBindingInfoAtom<arm64>(_options, state, *this);
2455 weakBindingSection = state.addAtom(*_weakBindingInfoAtom);
2456
2457 _lazyBindingInfoAtom = new LazyBindingInfoAtom<arm64>(_options, state, *this);
2458 lazyBindingSection = state.addAtom(*_lazyBindingInfoAtom);
2459
2460 _exportInfoAtom = new ExportInfoAtom<arm64>(_options, state, *this);
2461 exportSection = state.addAtom(*_exportInfoAtom);
2462 }
2463 if ( _hasLocalRelocations ) {
2464 _localRelocsAtom = new LocalRelocationsAtom<arm64>(_options, state, *this);
2465 localRelocationsSection = state.addAtom(*_localRelocsAtom);
2466 }
2467 if ( _hasSplitSegInfo ) {
2468 _splitSegInfoAtom = new SplitSegInfoAtom<arm64>(_options, state, *this);
2469 splitSegInfoSection = state.addAtom(*_splitSegInfoAtom);
2470 }
2471 if ( _hasFunctionStartsInfo ) {
2472 _functionStartsAtom = new FunctionStartsAtom<arm64>(_options, state, *this);
2473 functionStartsSection = state.addAtom(*_functionStartsAtom);
2474 }
2475 if ( _hasDataInCodeInfo ) {
2476 _dataInCodeAtom = new DataInCodeAtom<arm64>(_options, state, *this);
2477 dataInCodeSection = state.addAtom(*_dataInCodeAtom);
2478 }
2479 if ( _hasDependentDRInfo ) {
2480 _dependentDRInfoAtom = new DependentDRAtom<arm64>(_options, state, *this);
2481 dependentDRsSection = state.addAtom(*_dependentDRInfoAtom);
2482 }
2483 if ( _hasSymbolTable ) {
2484 _symbolTableAtom = new SymbolTableAtom<arm64>(_options, state, *this);
2485 symbolTableSection = state.addAtom(*_symbolTableAtom);
2486 }
2487 if ( _hasExternalRelocations ) {
2488 _externalRelocsAtom = new ExternalRelocationsAtom<arm64>(_options, state, *this);
2489 externalRelocationsSection = state.addAtom(*_externalRelocsAtom);
2490 }
2491 if ( _hasSymbolTable ) {
2492 _indirectSymbolTableAtom = new IndirectSymbolTableAtom<arm64>(_options, state, *this);
2493 indirectSymbolTableSection = state.addAtom(*_indirectSymbolTableAtom);
2494 _stringPoolAtom = new StringPoolAtom(_options, state, *this, 4);
2495 stringPoolSection = state.addAtom(*_stringPoolAtom);
2496 }
2497 break;
2498 #endif
2499 default:
2500 throw "unknown architecture";
2501 }
2502 }
2503
2504 void OutputFile::addLoadCommands(ld::Internal& state)
2505 {
2506 switch ( _options.architecture() ) {
2507 #if SUPPORT_ARCH_x86_64
2508 case CPU_TYPE_X86_64:
2509 _headersAndLoadCommandAtom = new HeaderAndLoadCommandsAtom<x86_64>(_options, state, *this);
2510 headerAndLoadCommandsSection = state.addAtom(*_headersAndLoadCommandAtom);
2511 break;
2512 #endif
2513 #if SUPPORT_ARCH_arm_any
2514 case CPU_TYPE_ARM:
2515 _headersAndLoadCommandAtom = new HeaderAndLoadCommandsAtom<arm>(_options, state, *this);
2516 headerAndLoadCommandsSection = state.addAtom(*_headersAndLoadCommandAtom);
2517 break;
2518 #endif
2519 #if SUPPORT_ARCH_arm64
2520 case CPU_TYPE_ARM64:
2521 _headersAndLoadCommandAtom = new HeaderAndLoadCommandsAtom<arm64>(_options, state, *this);
2522 headerAndLoadCommandsSection = state.addAtom(*_headersAndLoadCommandAtom);
2523 break;
2524 #endif
2525 #if SUPPORT_ARCH_i386
2526 case CPU_TYPE_I386:
2527 _headersAndLoadCommandAtom = new HeaderAndLoadCommandsAtom<x86>(_options, state, *this);
2528 headerAndLoadCommandsSection = state.addAtom(*_headersAndLoadCommandAtom);
2529 break;
2530 #endif
2531 default:
2532 throw "unknown architecture";
2533 }
2534 }
2535
2536 uint32_t OutputFile::dylibCount()
2537 {
2538 return _dylibsToLoad.size();
2539 }
2540
2541 const ld::dylib::File* OutputFile::dylibByOrdinal(unsigned int ordinal)
2542 {
2543 assert( ordinal > 0 );
2544 assert( ordinal <= _dylibsToLoad.size() );
2545 return _dylibsToLoad[ordinal-1];
2546 }
2547
2548 bool OutputFile::hasOrdinalForInstallPath(const char* path, int* ordinal)
2549 {
2550 for (std::map<const ld::dylib::File*, int>::const_iterator it = _dylibToOrdinal.begin(); it != _dylibToOrdinal.end(); ++it) {
2551 const char* installPath = it->first->installPath();
2552 if ( (installPath != NULL) && (strcmp(path, installPath) == 0) ) {
2553 *ordinal = it->second;
2554 return true;
2555 }
2556 }
2557 return false;
2558 }
2559
2560 uint32_t OutputFile::dylibToOrdinal(const ld::dylib::File* dylib)
2561 {
2562 return _dylibToOrdinal[dylib];
2563 }
2564
2565
2566 void OutputFile::buildDylibOrdinalMapping(ld::Internal& state)
2567 {
2568 // count non-public re-exported dylibs
2569 unsigned int nonPublicReExportCount = 0;
2570 for (std::vector<ld::dylib::File*>::iterator it = state.dylibs.begin(); it != state.dylibs.end(); ++it) {
2571 ld::dylib::File* aDylib = *it;
2572 if ( aDylib->willBeReExported() && ! aDylib->hasPublicInstallName() )
2573 ++nonPublicReExportCount;
2574 }
2575
2576 // look at each dylib supplied in state
2577 bool hasReExports = false;
2578 bool haveLazyDylibs = false;
2579 for (std::vector<ld::dylib::File*>::iterator it = state.dylibs.begin(); it != state.dylibs.end(); ++it) {
2580 ld::dylib::File* aDylib = *it;
2581 int ordinal;
2582 if ( aDylib == state.bundleLoader ) {
2583 _dylibToOrdinal[aDylib] = BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE;
2584 }
2585 else if ( this->hasOrdinalForInstallPath(aDylib->installPath(), &ordinal) ) {
2586 // already have a dylib with that install path, map all uses to that ordinal
2587 _dylibToOrdinal[aDylib] = ordinal;
2588 }
2589 else if ( aDylib->willBeLazyLoadedDylib() ) {
2590 // all lazy dylib need to be at end of ordinals
2591 haveLazyDylibs = true;
2592 }
2593 else if ( aDylib->willBeReExported() && ! aDylib->hasPublicInstallName() && (nonPublicReExportCount >= 2) ) {
2594 _dylibsToLoad.push_back(aDylib);
2595 _dylibToOrdinal[aDylib] = BIND_SPECIAL_DYLIB_SELF;
2596 }
2597 else {
2598 // first time this install path seen, create new ordinal
2599 _dylibsToLoad.push_back(aDylib);
2600 _dylibToOrdinal[aDylib] = _dylibsToLoad.size();
2601 }
2602 if ( aDylib->explicitlyLinked() && aDylib->willBeReExported() )
2603 hasReExports = true;
2604 }
2605 if ( haveLazyDylibs ) {
2606 // second pass to determine ordinals for lazy loaded dylibs
2607 for (std::vector<ld::dylib::File*>::iterator it = state.dylibs.begin(); it != state.dylibs.end(); ++it) {
2608 ld::dylib::File* aDylib = *it;
2609 if ( aDylib->willBeLazyLoadedDylib() ) {
2610 int ordinal;
2611 if ( this->hasOrdinalForInstallPath(aDylib->installPath(), &ordinal) ) {
2612 // already have a dylib with that install path, map all uses to that ordinal
2613 _dylibToOrdinal[aDylib] = ordinal;
2614 }
2615 else {
2616 // first time this install path seen, create new ordinal
2617 _dylibsToLoad.push_back(aDylib);
2618 _dylibToOrdinal[aDylib] = _dylibsToLoad.size();
2619 }
2620 }
2621 }
2622 }
2623 _noReExportedDylibs = !hasReExports;
2624 //fprintf(stderr, "dylibs:\n");
2625 //for (std::map<const ld::dylib::File*, int>::const_iterator it = _dylibToOrdinal.begin(); it != _dylibToOrdinal.end(); ++it) {
2626 // fprintf(stderr, " %p ord=%u, install_name=%s\n",it->first, it->second, it->first->installPath());
2627 //}
2628 }
2629
2630 uint32_t OutputFile::lazyBindingInfoOffsetForLazyPointerAddress(uint64_t lpAddress)
2631 {
2632 return _lazyPointerAddressToInfoOffset[lpAddress];
2633 }
2634
2635 void OutputFile::setLazyBindingInfoOffset(uint64_t lpAddress, uint32_t lpInfoOffset)
2636 {
2637 _lazyPointerAddressToInfoOffset[lpAddress] = lpInfoOffset;
2638 }
2639
2640 int OutputFile::compressedOrdinalForAtom(const ld::Atom* target)
2641 {
2642 // flat namespace images use zero for all ordinals
2643 if ( _options.nameSpace() != Options::kTwoLevelNameSpace )
2644 return BIND_SPECIAL_DYLIB_FLAT_LOOKUP;
2645
2646 // handle -interposable
2647 if ( target->definition() == ld::Atom::definitionRegular )
2648 return BIND_SPECIAL_DYLIB_SELF;
2649
2650 // regular ordinal
2651 const ld::dylib::File* dylib = dynamic_cast<const ld::dylib::File*>(target->file());
2652 if ( dylib != NULL ) {
2653 std::map<const ld::dylib::File*, int>::iterator pos = _dylibToOrdinal.find(dylib);
2654 if ( pos != _dylibToOrdinal.end() )
2655 return pos->second;
2656 assert(0 && "dylib not assigned ordinal");
2657 }
2658
2659 // handle undefined dynamic_lookup
2660 if ( _options.undefinedTreatment() == Options::kUndefinedDynamicLookup )
2661 return BIND_SPECIAL_DYLIB_FLAT_LOOKUP;
2662
2663 // handle -U _foo
2664 if ( _options.allowedUndefined(target->name()) )
2665 return BIND_SPECIAL_DYLIB_FLAT_LOOKUP;
2666
2667 throw "can't find ordinal for imported symbol";
2668 }
2669
2670
2671 bool OutputFile::isPcRelStore(ld::Fixup::Kind kind)
2672 {
2673 switch ( kind ) {
2674 case ld::Fixup::kindStoreX86BranchPCRel8:
2675 case ld::Fixup::kindStoreX86BranchPCRel32:
2676 case ld::Fixup::kindStoreX86PCRel8:
2677 case ld::Fixup::kindStoreX86PCRel16:
2678 case ld::Fixup::kindStoreX86PCRel32:
2679 case ld::Fixup::kindStoreX86PCRel32_1:
2680 case ld::Fixup::kindStoreX86PCRel32_2:
2681 case ld::Fixup::kindStoreX86PCRel32_4:
2682 case ld::Fixup::kindStoreX86PCRel32GOTLoad:
2683 case ld::Fixup::kindStoreX86PCRel32GOTLoadNowLEA:
2684 case ld::Fixup::kindStoreX86PCRel32GOT:
2685 case ld::Fixup::kindStoreX86PCRel32TLVLoad:
2686 case ld::Fixup::kindStoreX86PCRel32TLVLoadNowLEA:
2687 case ld::Fixup::kindStoreARMBranch24:
2688 case ld::Fixup::kindStoreThumbBranch22:
2689 case ld::Fixup::kindStoreARMLoad12:
2690 case ld::Fixup::kindStoreTargetAddressX86PCRel32:
2691 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad:
2692 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA:
2693 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoad:
2694 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoadNowLEA:
2695 case ld::Fixup::kindStoreTargetAddressARMBranch24:
2696 case ld::Fixup::kindStoreTargetAddressThumbBranch22:
2697 case ld::Fixup::kindStoreTargetAddressARMLoad12:
2698 #if SUPPORT_ARCH_arm64
2699 case ld::Fixup::kindStoreARM64Page21:
2700 case ld::Fixup::kindStoreARM64PageOff12:
2701 case ld::Fixup::kindStoreARM64GOTLoadPage21:
2702 case ld::Fixup::kindStoreARM64GOTLoadPageOff12:
2703 case ld::Fixup::kindStoreARM64GOTLeaPage21:
2704 case ld::Fixup::kindStoreARM64GOTLeaPageOff12:
2705 case ld::Fixup::kindStoreARM64PCRelToGOT:
2706 case ld::Fixup::kindStoreTargetAddressARM64Page21:
2707 case ld::Fixup::kindStoreTargetAddressARM64PageOff12:
2708 case ld::Fixup::kindStoreTargetAddressARM64GOTLoadPage21:
2709 case ld::Fixup::kindStoreTargetAddressARM64GOTLoadPageOff12:
2710 case ld::Fixup::kindStoreTargetAddressARM64GOTLeaPage21:
2711 case ld::Fixup::kindStoreTargetAddressARM64GOTLeaPageOff12:
2712 #endif
2713 return true;
2714 case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32:
2715 #if SUPPORT_ARCH_arm64
2716 case ld::Fixup::kindStoreTargetAddressARM64Branch26:
2717 #endif
2718 return (_options.outputKind() != Options::kKextBundle);
2719 default:
2720 break;
2721 }
2722 return false;
2723 }
2724
2725 bool OutputFile::isStore(ld::Fixup::Kind kind)
2726 {
2727 switch ( kind ) {
2728 case ld::Fixup::kindNone:
2729 case ld::Fixup::kindNoneFollowOn:
2730 case ld::Fixup::kindNoneGroupSubordinate:
2731 case ld::Fixup::kindNoneGroupSubordinateFDE:
2732 case ld::Fixup::kindNoneGroupSubordinateLSDA:
2733 case ld::Fixup::kindNoneGroupSubordinatePersonality:
2734 case ld::Fixup::kindSetTargetAddress:
2735 case ld::Fixup::kindSubtractTargetAddress:
2736 case ld::Fixup::kindAddAddend:
2737 case ld::Fixup::kindSubtractAddend:
2738 case ld::Fixup::kindSetTargetImageOffset:
2739 case ld::Fixup::kindSetTargetSectionOffset:
2740 return false;
2741 default:
2742 break;
2743 }
2744 return true;
2745 }
2746
2747
2748 bool OutputFile::setsTarget(ld::Fixup::Kind kind)
2749 {
2750 switch ( kind ) {
2751 case ld::Fixup::kindSetTargetAddress:
2752 case ld::Fixup::kindLazyTarget:
2753 case ld::Fixup::kindStoreTargetAddressLittleEndian32:
2754 case ld::Fixup::kindStoreTargetAddressLittleEndian64:
2755 case ld::Fixup::kindStoreTargetAddressBigEndian32:
2756 case ld::Fixup::kindStoreTargetAddressBigEndian64:
2757 case ld::Fixup::kindStoreTargetAddressX86PCRel32:
2758 case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32:
2759 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad:
2760 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA:
2761 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoad:
2762 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoadNowLEA:
2763 case ld::Fixup::kindStoreTargetAddressX86Abs32TLVLoad:
2764 case ld::Fixup::kindStoreTargetAddressARMBranch24:
2765 case ld::Fixup::kindStoreTargetAddressThumbBranch22:
2766 case ld::Fixup::kindStoreTargetAddressARMLoad12:
2767 #if SUPPORT_ARCH_arm64
2768 case ld::Fixup::kindStoreTargetAddressARM64Branch26:
2769 case ld::Fixup::kindStoreTargetAddressARM64Page21:
2770 case ld::Fixup::kindStoreTargetAddressARM64PageOff12:
2771 case ld::Fixup::kindStoreTargetAddressARM64GOTLoadPage21:
2772 case ld::Fixup::kindStoreTargetAddressARM64GOTLoadPageOff12:
2773 case ld::Fixup::kindStoreTargetAddressARM64GOTLeaPage21:
2774 case ld::Fixup::kindStoreTargetAddressARM64GOTLeaPageOff12:
2775 #endif
2776 return true;
2777 case ld::Fixup::kindStoreX86DtraceCallSiteNop:
2778 case ld::Fixup::kindStoreX86DtraceIsEnableSiteClear:
2779 case ld::Fixup::kindStoreARMDtraceCallSiteNop:
2780 case ld::Fixup::kindStoreARMDtraceIsEnableSiteClear:
2781 case ld::Fixup::kindStoreARM64DtraceCallSiteNop:
2782 case ld::Fixup::kindStoreARM64DtraceIsEnableSiteClear:
2783 case ld::Fixup::kindStoreThumbDtraceCallSiteNop:
2784 case ld::Fixup::kindStoreThumbDtraceIsEnableSiteClear:
2785 return (_options.outputKind() == Options::kObjectFile);
2786 default:
2787 break;
2788 }
2789 return false;
2790 }
2791
2792 bool OutputFile::isPointerToTarget(ld::Fixup::Kind kind)
2793 {
2794 switch ( kind ) {
2795 case ld::Fixup::kindSetTargetAddress:
2796 case ld::Fixup::kindStoreTargetAddressLittleEndian32:
2797 case ld::Fixup::kindStoreTargetAddressLittleEndian64:
2798 case ld::Fixup::kindStoreTargetAddressBigEndian32:
2799 case ld::Fixup::kindStoreTargetAddressBigEndian64:
2800 case ld::Fixup::kindLazyTarget:
2801 return true;
2802 default:
2803 break;
2804 }
2805 return false;
2806 }
2807 bool OutputFile::isPointerFromTarget(ld::Fixup::Kind kind)
2808 {
2809 switch ( kind ) {
2810 case ld::Fixup::kindSubtractTargetAddress:
2811 return true;
2812 default:
2813 break;
2814 }
2815 return false;
2816 }
2817
2818
2819 uint64_t OutputFile::lookBackAddend(ld::Fixup::iterator fit)
2820 {
2821 uint64_t addend = 0;
2822 switch ( fit->clusterSize ) {
2823 case ld::Fixup::k1of1:
2824 case ld::Fixup::k1of2:
2825 case ld::Fixup::k2of2:
2826 break;
2827 case ld::Fixup::k2of3:
2828 --fit;
2829 switch ( fit->kind ) {
2830 case ld::Fixup::kindAddAddend:
2831 addend += fit->u.addend;
2832 break;
2833 case ld::Fixup::kindSubtractAddend:
2834 addend -= fit->u.addend;
2835 break;
2836 default:
2837 throw "unexpected fixup kind for binding";
2838 }
2839 break;
2840 case ld::Fixup::k1of3:
2841 ++fit;
2842 switch ( fit->kind ) {
2843 case ld::Fixup::kindAddAddend:
2844 addend += fit->u.addend;
2845 break;
2846 case ld::Fixup::kindSubtractAddend:
2847 addend -= fit->u.addend;
2848 break;
2849 default:
2850 throw "unexpected fixup kind for binding";
2851 }
2852 break;
2853 default:
2854 throw "unexpected fixup cluster size for binding";
2855 }
2856 return addend;
2857 }
2858
2859
2860
2861
2862
2863 void OutputFile::generateLinkEditInfo(ld::Internal& state)
2864 {
2865 for (std::vector<ld::Internal::FinalSection*>::iterator sit = state.sections.begin(); sit != state.sections.end(); ++sit) {
2866 ld::Internal::FinalSection* sect = *sit;
2867 bool objc1ClassRefSection = ( (sect->type() == ld::Section::typeCStringPointer)
2868 && (strcmp(sect->sectionName(), "__cls_refs") == 0)
2869 && (strcmp(sect->segmentName(), "__OBJC") == 0) );
2870 for (std::vector<const ld::Atom*>::iterator ait = sect->atoms.begin(); ait != sect->atoms.end(); ++ait) {
2871 const ld::Atom* atom = *ait;
2872
2873 // Record regular atoms that override a dylib's weak definitions
2874 if ( (atom->scope() == ld::Atom::scopeGlobal) && atom->overridesDylibsWeakDef() ) {
2875 if ( _options.makeCompressedDyldInfo() ) {
2876 uint8_t wtype = BIND_TYPE_OVERRIDE_OF_WEAKDEF_IN_DYLIB;
2877 bool nonWeakDef = (atom->combine() == ld::Atom::combineNever);
2878 _weakBindingInfo.push_back(BindingInfo(wtype, atom->name(), nonWeakDef, atom->finalAddress(), 0));
2879 }
2880 this->overridesWeakExternalSymbols = true;
2881 if ( _options.warnWeakExports() )
2882 warning("overrides weak external symbol: %s", atom->name());
2883 }
2884
2885 ld::Fixup* fixupWithTarget = NULL;
2886 ld::Fixup* fixupWithMinusTarget = NULL;
2887 ld::Fixup* fixupWithStore = NULL;
2888 ld::Fixup* fixupWithAddend = NULL;
2889 const ld::Atom* target = NULL;
2890 const ld::Atom* minusTarget = NULL;
2891 uint64_t targetAddend = 0;
2892 uint64_t minusTargetAddend = 0;
2893 for (ld::Fixup::iterator fit = atom->fixupsBegin(); fit != atom->fixupsEnd(); ++fit) {
2894 if ( fit->firstInCluster() ) {
2895 fixupWithTarget = NULL;
2896 fixupWithMinusTarget = NULL;
2897 fixupWithStore = NULL;
2898 target = NULL;
2899 minusTarget = NULL;
2900 targetAddend = 0;
2901 minusTargetAddend = 0;
2902 }
2903 if ( this->setsTarget(fit->kind) ) {
2904 switch ( fit->binding ) {
2905 case ld::Fixup::bindingNone:
2906 case ld::Fixup::bindingByNameUnbound:
2907 break;
2908 case ld::Fixup::bindingByContentBound:
2909 case ld::Fixup::bindingDirectlyBound:
2910 fixupWithTarget = fit;
2911 target = fit->u.target;
2912 break;
2913 case ld::Fixup::bindingsIndirectlyBound:
2914 fixupWithTarget = fit;
2915 target = state.indirectBindingTable[fit->u.bindingIndex];
2916 break;
2917 }
2918 assert(target != NULL);
2919 }
2920 switch ( fit->kind ) {
2921 case ld::Fixup::kindAddAddend:
2922 targetAddend = fit->u.addend;
2923 fixupWithAddend = fit;
2924 break;
2925 case ld::Fixup::kindSubtractAddend:
2926 minusTargetAddend = fit->u.addend;
2927 fixupWithAddend = fit;
2928 break;
2929 case ld::Fixup::kindSubtractTargetAddress:
2930 switch ( fit->binding ) {
2931 case ld::Fixup::bindingNone:
2932 case ld::Fixup::bindingByNameUnbound:
2933 break;
2934 case ld::Fixup::bindingByContentBound:
2935 case ld::Fixup::bindingDirectlyBound:
2936 fixupWithMinusTarget = fit;
2937 minusTarget = fit->u.target;
2938 break;
2939 case ld::Fixup::bindingsIndirectlyBound:
2940 fixupWithMinusTarget = fit;
2941 minusTarget = state.indirectBindingTable[fit->u.bindingIndex];
2942 break;
2943 }
2944 assert(minusTarget != NULL);
2945 break;
2946 case ld::Fixup::kindDataInCodeStartData:
2947 case ld::Fixup::kindDataInCodeStartJT8:
2948 case ld::Fixup::kindDataInCodeStartJT16:
2949 case ld::Fixup::kindDataInCodeStartJT32:
2950 case ld::Fixup::kindDataInCodeStartJTA32:
2951 case ld::Fixup::kindDataInCodeEnd:
2952 hasDataInCode = true;
2953 break;
2954 default:
2955 break;
2956 }
2957 if ( this->isStore(fit->kind) ) {
2958 fixupWithStore = fit;
2959 }
2960 if ( fit->lastInCluster() ) {
2961 if ( (fixupWithStore != NULL) && (target != NULL) ) {
2962 if ( _options.outputKind() == Options::kObjectFile ) {
2963 this->addSectionRelocs(state, sect, atom, fixupWithTarget, fixupWithMinusTarget, fixupWithAddend, fixupWithStore,
2964 target, minusTarget, targetAddend, minusTargetAddend);
2965 }
2966 else {
2967 if ( _options.makeCompressedDyldInfo() ) {
2968 this->addDyldInfo(state, sect, atom, fixupWithTarget, fixupWithMinusTarget, fixupWithStore,
2969 target, minusTarget, targetAddend, minusTargetAddend);
2970 }
2971 else {
2972 this->addClassicRelocs(state, sect, atom, fixupWithTarget, fixupWithMinusTarget, fixupWithStore,
2973 target, minusTarget, targetAddend, minusTargetAddend);
2974 }
2975 }
2976 }
2977 else if ( objc1ClassRefSection && (target != NULL) && (fixupWithStore == NULL) ) {
2978 // check for class refs to lazy loaded dylibs
2979 const ld::dylib::File* dylib = dynamic_cast<const ld::dylib::File*>(target->file());
2980 if ( (dylib != NULL) && dylib->willBeLazyLoadedDylib() )
2981 throwf("illegal class reference to %s in lazy loaded dylib %s", target->name(), dylib->path());
2982 }
2983 }
2984 }
2985 }
2986 }
2987 }
2988
2989
2990 void OutputFile::noteTextReloc(const ld::Atom* atom, const ld::Atom* target)
2991 {
2992 if ( (atom->contentType() == ld::Atom::typeStub) || (atom->contentType() == ld::Atom::typeStubHelper) ) {
2993 // silently let stubs (synthesized by linker) use text relocs
2994 }
2995 else if ( _options.allowTextRelocs() ) {
2996 if ( _options.warnAboutTextRelocs() )
2997 warning("text reloc in %s to %s", atom->name(), target->name());
2998 }
2999 else if ( _options.positionIndependentExecutable() && (_options.outputKind() == Options::kDynamicExecutable)
3000 && ((_options.iOSVersionMin() >= ld::iOS_4_3) || (_options.macosxVersionMin() >= ld::mac10_7)) ) {
3001 if ( ! this->pieDisabled ) {
3002 #if SUPPORT_ARCH_arm64
3003 if ( _options.architecture() == CPU_TYPE_ARM64 ) {
3004 const char* demangledName = strdup(_options.demangleSymbol(atom->name()));
3005 throwf("Absolute addressing not allowed in arm64 code but used in '%s' referencing '%s'", demangledName, _options.demangleSymbol(target->name()));
3006 }
3007 else
3008 #endif
3009 {
3010 warning("PIE disabled. Absolute addressing (perhaps -mdynamic-no-pic) not allowed in code signed PIE, "
3011 "but used in %s from %s. "
3012 "To fix this warning, don't compile with -mdynamic-no-pic or link with -Wl,-no_pie",
3013 atom->name(), atom->file()->path());
3014 }
3015 }
3016 this->pieDisabled = true;
3017 }
3018 else if ( (target->scope() == ld::Atom::scopeGlobal) && (target->combine() == ld::Atom::combineByName) ) {
3019 throwf("illegal text-relocoation (direct reference) to (global,weak) %s in %s from %s in %s", target->name(), target->file()->path(), atom->name(), atom->file()->path());
3020 }
3021 else {
3022 if ( (target->file() != NULL) && (atom->file() != NULL) )
3023 throwf("illegal text-relocation to '%s' in %s from '%s' in %s", target->name(), target->file()->path(), atom->name(), atom->file()->path());
3024 else
3025 throwf("illegal text reloc in '%s' to '%s'", atom->name(), target->name());
3026 }
3027 }
3028
3029 void OutputFile::addDyldInfo(ld::Internal& state, ld::Internal::FinalSection* sect, const ld::Atom* atom,
3030 ld::Fixup* fixupWithTarget, ld::Fixup* fixupWithMinusTarget, ld::Fixup* fixupWithStore,
3031 const ld::Atom* target, const ld::Atom* minusTarget,
3032 uint64_t targetAddend, uint64_t minusTargetAddend)
3033 {
3034 if ( sect->isSectionHidden() )
3035 return;
3036
3037 // no need to rebase or bind PCRel stores
3038 if ( this->isPcRelStore(fixupWithStore->kind) ) {
3039 // as long as target is in same linkage unit
3040 if ( (target == NULL) || (target->definition() != ld::Atom::definitionProxy) ) {
3041 // make sure target is not global and weak
3042 if ( (target->scope() == ld::Atom::scopeGlobal) && (target->combine() == ld::Atom::combineByName) && (target->definition() == ld::Atom::definitionRegular)) {
3043 if ( (atom->section().type() == ld::Section::typeCFI)
3044 || (atom->section().type() == ld::Section::typeDtraceDOF)
3045 || (atom->section().type() == ld::Section::typeUnwindInfo) ) {
3046 // ok for __eh_frame and __uwind_info to use pointer diffs to global weak symbols
3047 return;
3048 }
3049 // <rdar://problem/13700961> spurious warning when weak function has reference to itself
3050 if ( fixupWithTarget->binding == ld::Fixup::bindingDirectlyBound ) {
3051 // ok to ignore pc-rel references within a weak function to itself
3052 return;
3053 }
3054 // Have direct reference to weak-global. This should be an indrect reference
3055 const char* demangledName = strdup(_options.demangleSymbol(atom->name()));
3056 warning("direct access in %s to global weak symbol %s means the weak symbol cannot be overridden at runtime. "
3057 "This was likely caused by different translation units being compiled with different visibility settings.",
3058 demangledName, _options.demangleSymbol(target->name()));
3059 }
3060 return;
3061 }
3062 }
3063
3064 // no need to rebase or bind PIC internal pointer diff
3065 if ( minusTarget != NULL ) {
3066 // with pointer diffs, both need to be in same linkage unit
3067 assert(minusTarget->definition() != ld::Atom::definitionProxy);
3068 assert(target != NULL);
3069 assert(target->definition() != ld::Atom::definitionProxy);
3070 if ( target == minusTarget ) {
3071 // This is a compile time constant and could have been optimized away by compiler
3072 return;
3073 }
3074
3075 // check if target of pointer-diff is global and weak
3076 if ( (target->scope() == ld::Atom::scopeGlobal) && (target->combine() == ld::Atom::combineByName) && (target->definition() == ld::Atom::definitionRegular) ) {
3077 if ( (atom->section().type() == ld::Section::typeCFI)
3078 || (atom->section().type() == ld::Section::typeDtraceDOF)
3079 || (atom->section().type() == ld::Section::typeUnwindInfo) ) {
3080 // ok for __eh_frame and __uwind_info to use pointer diffs to global weak symbols
3081 return;
3082 }
3083 // Have direct reference to weak-global. This should be an indrect reference
3084 const char* demangledName = strdup(_options.demangleSymbol(atom->name()));
3085 warning("direct access in %s to global weak symbol %s means the weak symbol cannot be overridden at runtime. "
3086 "This was likely caused by different translation units being compiled with different visibility settings.",
3087 demangledName, _options.demangleSymbol(target->name()));
3088 }
3089 return;
3090 }
3091
3092 // no need to rebase or bind an atom's references to itself if the output is not slidable
3093 if ( (atom == target) && !_options.outputSlidable() )
3094 return;
3095
3096 // cluster has no target, so needs no rebasing or binding
3097 if ( target == NULL )
3098 return;
3099
3100 bool inReadOnlySeg = ( strcmp(sect->segmentName(), "__TEXT") == 0 );
3101 bool needsRebase = false;
3102 bool needsBinding = false;
3103 bool needsLazyBinding = false;
3104 bool needsWeakBinding = false;
3105
3106 uint8_t rebaseType = REBASE_TYPE_POINTER;
3107 uint8_t type = BIND_TYPE_POINTER;
3108 const ld::dylib::File* dylib = dynamic_cast<const ld::dylib::File*>(target->file());
3109 bool weak_import = (fixupWithTarget->weakImport || ((dylib != NULL) && dylib->forcedWeakLinked()));
3110 uint64_t address = atom->finalAddress() + fixupWithTarget->offsetInAtom;
3111 uint64_t addend = targetAddend - minusTargetAddend;
3112
3113 // special case lazy pointers
3114 if ( fixupWithTarget->kind == ld::Fixup::kindLazyTarget ) {
3115 assert(fixupWithTarget->u.target == target);
3116 assert(addend == 0);
3117 // lazy dylib lazy pointers do not have any dyld info
3118 if ( atom->section().type() == ld::Section::typeLazyDylibPointer )
3119 return;
3120 // lazy binding to weak definitions are done differently
3121 // they are directly bound to target, then have a weak bind in case of a collision
3122 if ( target->combine() == ld::Atom::combineByName ) {
3123 if ( target->definition() == ld::Atom::definitionProxy ) {
3124 // weak def exported from another dylib
3125 // must non-lazy bind to it plus have weak binding info in case of collision
3126 needsBinding = true;
3127 needsWeakBinding = true;
3128 }
3129 else {
3130 // weak def in this linkage unit.
3131 // just rebase, plus have weak binding info in case of collision
3132 // this will be done by other cluster on lazy pointer atom
3133 }
3134 }
3135 else if ( target->contentType() == ld::Atom::typeResolver ) {
3136 // <rdar://problem/8553647> Hidden resolver functions should not have lazy binding info
3137 // <rdar://problem/12629331> Resolver function run before initializers when overriding the dyld shared cache
3138 // The lazy pointers used by stubs used when non-lazy binding to a resolver are not normal lazy pointers
3139 // and should not be in lazy binding info.
3140 needsLazyBinding = false;
3141 }
3142 else {
3143 // normal case of a pointer to non-weak-def symbol, so can lazily bind
3144 needsLazyBinding = true;
3145 }
3146 }
3147 else {
3148 // everything except lazy pointers
3149 switch ( target->definition() ) {
3150 case ld::Atom::definitionProxy:
3151 if ( (dylib != NULL) && dylib->willBeLazyLoadedDylib() )
3152 throwf("illegal data reference to %s in lazy loaded dylib %s", target->name(), dylib->path());
3153 if ( target->contentType() == ld::Atom::typeTLV ) {
3154 if ( sect->type() != ld::Section::typeTLVPointers )
3155 throwf("illegal data reference in %s to thread local variable %s in dylib %s",
3156 atom->name(), target->name(), dylib->path());
3157 }
3158 if ( inReadOnlySeg )
3159 type = BIND_TYPE_TEXT_ABSOLUTE32;
3160 needsBinding = true;
3161 if ( target->combine() == ld::Atom::combineByName )
3162 needsWeakBinding = true;
3163 break;
3164 case ld::Atom::definitionRegular:
3165 case ld::Atom::definitionTentative:
3166 // only slideable images need rebasing info
3167 if ( _options.outputSlidable() ) {
3168 needsRebase = true;
3169 }
3170 // references to internal symbol never need binding
3171 if ( target->scope() != ld::Atom::scopeGlobal )
3172 break;
3173 // reference to global weak def needs weak binding
3174 if ( (target->combine() == ld::Atom::combineByName) && (target->definition() == ld::Atom::definitionRegular) )
3175 needsWeakBinding = true;
3176 else if ( _options.outputKind() == Options::kDynamicExecutable ) {
3177 // in main executables, the only way regular symbols are indirected is if -interposable is used
3178 if ( _options.interposable(target->name()) ) {
3179 needsRebase = false;
3180 needsBinding = true;
3181 }
3182 }
3183 else {
3184 // for flat-namespace or interposable two-level-namespace
3185 // all references to exported symbols get indirected
3186 if ( (_options.nameSpace() != Options::kTwoLevelNameSpace) || _options.interposable(target->name()) ) {
3187 // <rdar://problem/5254468> no external relocs for flat objc classes
3188 if ( strncmp(target->name(), ".objc_class_", 12) == 0 )
3189 break;
3190 // no rebase info for references to global symbols that will have binding info
3191 needsRebase = false;
3192 needsBinding = true;
3193 }
3194 else if ( _options.forceCoalesce(target->name()) ) {
3195 needsWeakBinding = true;
3196 }
3197 }
3198 break;
3199 case ld::Atom::definitionAbsolute:
3200 break;
3201 }
3202 }
3203
3204 // <rdar://problem/13828711> if target is an import alias, use base of alias
3205 if ( target->isAlias() && (target->definition() == ld::Atom::definitionProxy) ) {
3206 for (ld::Fixup::iterator fit = target->fixupsBegin(), end=target->fixupsEnd(); fit != end; ++fit) {
3207 if ( fit->firstInCluster() ) {
3208 if ( fit->kind == ld::Fixup::kindNoneFollowOn ) {
3209 if ( fit->binding == ld::Fixup::bindingDirectlyBound ) {
3210 //fprintf(stderr, "switching import of %s to import of %s\n", target->name(), fit->u.target->name());
3211 target = fit->u.target;
3212 }
3213 }
3214 }
3215 }
3216 }
3217
3218 // record dyld info for this cluster
3219 if ( needsRebase ) {
3220 if ( inReadOnlySeg ) {
3221 noteTextReloc(atom, target);
3222 sect->hasLocalRelocs = true; // so dyld knows to change permissions on __TEXT segment
3223 rebaseType = REBASE_TYPE_TEXT_ABSOLUTE32;
3224 }
3225 if ( _options.sharedRegionEligible() ) {
3226 // <rdar://problem/13287063> when range checking, ignore high byte of arm64 addends
3227 uint64_t checkAddend = addend;
3228 if ( _options.architecture() == CPU_TYPE_ARM64 )
3229 checkAddend &= 0x0FFFFFFFFFFFFFFFULL;
3230 if ( checkAddend != 0 ) {
3231 // make sure the addend does not cause the pointer to point outside the target's segment
3232 // if it does, update_dyld_shared_cache will not be able to put this dylib into the shared cache
3233 uint64_t targetAddress = target->finalAddress();
3234 for (std::vector<ld::Internal::FinalSection*>::iterator sit = state.sections.begin(); sit != state.sections.end(); ++sit) {
3235 ld::Internal::FinalSection* sct = *sit;
3236 uint64_t sctEnd = (sct->address+sct->size);
3237 if ( (sct->address <= targetAddress) && (targetAddress < sctEnd) ) {
3238 if ( (targetAddress+checkAddend) > sctEnd ) {
3239 warning("data symbol %s from %s has pointer to %s + 0x%08llX. "
3240 "That large of an addend may disable %s from being put in the dyld shared cache.",
3241 atom->name(), atom->file()->path(), target->name(), addend, _options.installPath() );
3242 }
3243 }
3244 }
3245 }
3246 }
3247 _rebaseInfo.push_back(RebaseInfo(rebaseType, address));
3248 }
3249 if ( needsBinding ) {
3250 if ( inReadOnlySeg ) {
3251 noteTextReloc(atom, target);
3252 sect->hasExternalRelocs = true; // so dyld knows to change permissions on __TEXT segment
3253 }
3254 _bindingInfo.push_back(BindingInfo(type, this->compressedOrdinalForAtom(target), target->name(), weak_import, address, addend));
3255 }
3256 if ( needsLazyBinding ) {
3257 if ( _options.bindAtLoad() )
3258 _bindingInfo.push_back(BindingInfo(type, this->compressedOrdinalForAtom(target), target->name(), weak_import, address, addend));
3259 else
3260 _lazyBindingInfo.push_back(BindingInfo(type, this->compressedOrdinalForAtom(target), target->name(), weak_import, address, addend));
3261 }
3262 if ( needsWeakBinding )
3263 _weakBindingInfo.push_back(BindingInfo(type, 0, target->name(), false, address, addend));
3264 }
3265
3266
3267 void OutputFile::addClassicRelocs(ld::Internal& state, ld::Internal::FinalSection* sect, const ld::Atom* atom,
3268 ld::Fixup* fixupWithTarget, ld::Fixup* fixupWithMinusTarget, ld::Fixup* fixupWithStore,
3269 const ld::Atom* target, const ld::Atom* minusTarget,
3270 uint64_t targetAddend, uint64_t minusTargetAddend)
3271 {
3272 if ( sect->isSectionHidden() )
3273 return;
3274
3275 // non-lazy-pointer section is encoded in indirect symbol table - not using relocations
3276 if ( sect->type() == ld::Section::typeNonLazyPointer ) {
3277 // except kexts and static pie which *do* use relocations
3278 switch (_options.outputKind()) {
3279 case Options::kKextBundle:
3280 break;
3281 case Options::kStaticExecutable:
3282 if ( _options.positionIndependentExecutable() )
3283 break;
3284 // else fall into default case
3285 default:
3286 assert(target != NULL);
3287 assert(fixupWithTarget != NULL);
3288 return;
3289 }
3290 }
3291
3292 // no need to rebase or bind PCRel stores
3293 if ( this->isPcRelStore(fixupWithStore->kind) ) {
3294 // as long as target is in same linkage unit
3295 if ( (target == NULL) || (target->definition() != ld::Atom::definitionProxy) )
3296 return;
3297 }
3298
3299 // no need to rebase or bind PIC internal pointer diff
3300 if ( minusTarget != NULL ) {
3301 // with pointer diffs, both need to be in same linkage unit
3302 assert(minusTarget->definition() != ld::Atom::definitionProxy);
3303 assert(target != NULL);
3304 assert(target->definition() != ld::Atom::definitionProxy);
3305 // make sure target is not global and weak
3306 if ( (target->scope() == ld::Atom::scopeGlobal) && (target->combine() == ld::Atom::combineByName)
3307 && (atom->section().type() != ld::Section::typeCFI)
3308 && (atom->section().type() != ld::Section::typeDtraceDOF)
3309 && (atom->section().type() != ld::Section::typeUnwindInfo)
3310 && (minusTarget != target) ) {
3311 // ok for __eh_frame and __uwind_info to use pointer diffs to global weak symbols
3312 throwf("bad codegen, pointer diff in %s to global weak symbol %s", atom->name(), target->name());
3313 }
3314 return;
3315 }
3316
3317 // cluster has no target, so needs no rebasing or binding
3318 if ( target == NULL )
3319 return;
3320
3321 assert(_localRelocsAtom != NULL);
3322 uint64_t relocAddress = atom->finalAddress() + fixupWithTarget->offsetInAtom - _localRelocsAtom->relocBaseAddress(state);
3323
3324 bool inReadOnlySeg = ( strcmp(sect->segmentName(), "__TEXT") == 0 );
3325 bool needsLocalReloc = false;
3326 bool needsExternReloc = false;
3327
3328 switch ( fixupWithStore->kind ) {
3329 case ld::Fixup::kindLazyTarget:
3330 // lazy pointers don't need relocs
3331 break;
3332 case ld::Fixup::kindStoreLittleEndian32:
3333 case ld::Fixup::kindStoreLittleEndian64:
3334 case ld::Fixup::kindStoreBigEndian32:
3335 case ld::Fixup::kindStoreBigEndian64:
3336 case ld::Fixup::kindStoreTargetAddressLittleEndian32:
3337 case ld::Fixup::kindStoreTargetAddressLittleEndian64:
3338 case ld::Fixup::kindStoreTargetAddressBigEndian32:
3339 case ld::Fixup::kindStoreTargetAddressBigEndian64:
3340 // is pointer
3341 switch ( target->definition() ) {
3342 case ld::Atom::definitionProxy:
3343 needsExternReloc = true;
3344 break;
3345 case ld::Atom::definitionRegular:
3346 case ld::Atom::definitionTentative:
3347 // only slideable images need local relocs
3348 if ( _options.outputSlidable() )
3349 needsLocalReloc = true;
3350 // references to internal symbol never need binding
3351 if ( target->scope() != ld::Atom::scopeGlobal )
3352 break;
3353 // reference to global weak def needs weak binding in dynamic images
3354 if ( (target->combine() == ld::Atom::combineByName)
3355 && (target->definition() == ld::Atom::definitionRegular)
3356 && (_options.outputKind() != Options::kStaticExecutable)
3357 && (_options.outputKind() != Options::kPreload)
3358 && (atom != target) ) {
3359 needsExternReloc = true;
3360 }
3361 else if ( _options.outputKind() == Options::kDynamicExecutable ) {
3362 // in main executables, the only way regular symbols are indirected is if -interposable is used
3363 if ( _options.interposable(target->name()) )
3364 needsExternReloc = true;
3365 }
3366 else {
3367 // for flat-namespace or interposable two-level-namespace
3368 // all references to exported symbols get indirected
3369 if ( (_options.nameSpace() != Options::kTwoLevelNameSpace) || _options.interposable(target->name()) ) {
3370 // <rdar://problem/5254468> no external relocs for flat objc classes
3371 if ( strncmp(target->name(), ".objc_class_", 12) == 0 )
3372 break;
3373 // no rebase info for references to global symbols that will have binding info
3374 needsExternReloc = true;
3375 }
3376 }
3377 if ( needsExternReloc )
3378 needsLocalReloc = false;
3379 break;
3380 case ld::Atom::definitionAbsolute:
3381 break;
3382 }
3383 if ( needsExternReloc ) {
3384 if ( inReadOnlySeg )
3385 noteTextReloc(atom, target);
3386 const ld::dylib::File* dylib = dynamic_cast<const ld::dylib::File*>(target->file());
3387 if ( (dylib != NULL) && dylib->willBeLazyLoadedDylib() )
3388 throwf("illegal data reference to %s in lazy loaded dylib %s", target->name(), dylib->path());
3389 _externalRelocsAtom->addExternalPointerReloc(relocAddress, target);
3390 sect->hasExternalRelocs = true;
3391 fixupWithTarget->contentAddendOnly = true;
3392 }
3393 else if ( needsLocalReloc ) {
3394 assert(target != NULL);
3395 if ( inReadOnlySeg )
3396 noteTextReloc(atom, target);
3397 _localRelocsAtom->addPointerReloc(relocAddress, target->machoSection());
3398 sect->hasLocalRelocs = true;
3399 }
3400 break;
3401 case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32:
3402 #if SUPPORT_ARCH_arm64
3403 case ld::Fixup::kindStoreTargetAddressARM64Branch26:
3404 #endif
3405 if ( _options.outputKind() == Options::kKextBundle ) {
3406 assert(target != NULL);
3407 if ( target->definition() == ld::Atom::definitionProxy ) {
3408 _externalRelocsAtom->addExternalCallSiteReloc(relocAddress, target);
3409 fixupWithStore->contentAddendOnly = true;
3410 }
3411 }
3412 break;
3413
3414 case ld::Fixup::kindStoreARMLow16:
3415 case ld::Fixup::kindStoreThumbLow16:
3416 // no way to encode rebasing of binding for these instructions
3417 if ( _options.outputSlidable() || (target->definition() == ld::Atom::definitionProxy) )
3418 throwf("no supported runtime lo16 relocation in %s from %s to %s", atom->name(), atom->file()->path(), target->name());
3419 break;
3420
3421 case ld::Fixup::kindStoreARMHigh16:
3422 case ld::Fixup::kindStoreThumbHigh16:
3423 // no way to encode rebasing of binding for these instructions
3424 if ( _options.outputSlidable() || (target->definition() == ld::Atom::definitionProxy) )
3425 throwf("no supported runtime hi16 relocation in %s from %s to %s", atom->name(), atom->file()->path(), target->name());
3426 break;
3427
3428 default:
3429 break;
3430 }
3431 }
3432
3433
3434 bool OutputFile::useExternalSectionReloc(const ld::Atom* atom, const ld::Atom* target, ld::Fixup* fixupWithTarget)
3435 {
3436 if ( (_options.architecture() == CPU_TYPE_X86_64) || (_options.architecture() == CPU_TYPE_ARM64) ) {
3437 // x86_64 and ARM64 use external relocations for everthing that has a symbol
3438 return ( target->symbolTableInclusion() != ld::Atom::symbolTableNotIn );
3439 }
3440
3441 // <rdar://problem/9513487> support arm branch interworking in -r mode
3442 if ( (_options.architecture() == CPU_TYPE_ARM) && (_options.outputKind() == Options::kObjectFile) ) {
3443 if ( atom->isThumb() != target->isThumb() ) {
3444 switch ( fixupWithTarget->kind ) {
3445 // have branch that switches mode, then might be 'b' not 'bl'
3446 // Force external relocation, since no way to do local reloc for 'b'
3447 case ld::Fixup::kindStoreTargetAddressThumbBranch22 :
3448 case ld::Fixup::kindStoreTargetAddressARMBranch24:
3449 return true;
3450 default:
3451 break;
3452 }
3453 }
3454 }
3455
3456 if ( (_options.architecture() == CPU_TYPE_I386) && (_options.outputKind() == Options::kObjectFile) ) {
3457 if ( target->contentType() == ld::Atom::typeTLV )
3458 return true;
3459 }
3460
3461 // most architectures use external relocations only for references
3462 // to a symbol in another translation unit or for references to "weak symbols" or tentative definitions
3463 assert(target != NULL);
3464 if ( target->definition() == ld::Atom::definitionProxy )
3465 return true;
3466 if ( (target->definition() == ld::Atom::definitionTentative) && ! _options.makeTentativeDefinitionsReal() )
3467 return true;
3468 if ( target->scope() != ld::Atom::scopeGlobal )
3469 return false;
3470 if ( (target->combine() == ld::Atom::combineByName) && (target->definition() == ld::Atom::definitionRegular) )
3471 return true;
3472 return false;
3473 }
3474
3475 bool OutputFile::useSectionRelocAddend(ld::Fixup* fixupWithTarget)
3476 {
3477 #if SUPPORT_ARCH_arm64
3478 if ( _options.architecture() == CPU_TYPE_ARM64 ) {
3479 switch ( fixupWithTarget->kind ) {
3480 case ld::Fixup::kindStoreARM64Branch26:
3481 case ld::Fixup::kindStoreARM64Page21:
3482 case ld::Fixup::kindStoreARM64PageOff12:
3483 return true;
3484 default:
3485 return false;
3486 }
3487 }
3488 #endif
3489 return false;
3490 }
3491
3492
3493
3494
3495 void OutputFile::addSectionRelocs(ld::Internal& state, ld::Internal::FinalSection* sect, const ld::Atom* atom,
3496 ld::Fixup* fixupWithTarget, ld::Fixup* fixupWithMinusTarget,
3497 ld::Fixup* fixupWithAddend, ld::Fixup* fixupWithStore,
3498 const ld::Atom* target, const ld::Atom* minusTarget,
3499 uint64_t targetAddend, uint64_t minusTargetAddend)
3500 {
3501 if ( sect->isSectionHidden() )
3502 return;
3503
3504 // in -r mode where there will be no labels on __eh_frame section, there is no need for relocations
3505 if ( (sect->type() == ld::Section::typeCFI) && _options.removeEHLabels() )
3506 return;
3507
3508 // non-lazy-pointer section is encoded in indirect symbol table - not using relocations
3509 if ( sect->type() == ld::Section::typeNonLazyPointer )
3510 return;
3511
3512 // tentative defs don't have any relocations
3513 if ( sect->type() == ld::Section::typeTentativeDefs )
3514 return;
3515
3516 assert(target != NULL);
3517 assert(fixupWithTarget != NULL);
3518 bool targetUsesExternalReloc = this->useExternalSectionReloc(atom, target, fixupWithTarget);
3519 bool minusTargetUsesExternalReloc = (minusTarget != NULL) && this->useExternalSectionReloc(atom, minusTarget, fixupWithMinusTarget);
3520
3521 // in x86_64 and arm64 .o files an external reloc means the content contains just the addend
3522 if ( (_options.architecture() == CPU_TYPE_X86_64) ||(_options.architecture() == CPU_TYPE_ARM64) ) {
3523 if ( targetUsesExternalReloc ) {
3524 fixupWithTarget->contentAddendOnly = true;
3525 fixupWithStore->contentAddendOnly = true;
3526 if ( this->useSectionRelocAddend(fixupWithStore) && (fixupWithAddend != NULL) )
3527 fixupWithAddend->contentIgnoresAddend = true;
3528 }
3529 if ( minusTargetUsesExternalReloc )
3530 fixupWithMinusTarget->contentAddendOnly = true;
3531 }
3532 else {
3533 // for other archs, content is addend only with (non pc-rel) pointers
3534 // pc-rel instructions are funny. If the target is _foo+8 and _foo is
3535 // external, then the pc-rel instruction *evalutates* to the address 8.
3536 if ( targetUsesExternalReloc ) {
3537 // TLV support for i386 acts like RIP relative addressing
3538 // The addend is the offset from the PICBase to the end of the instruction
3539 if ( (_options.architecture() == CPU_TYPE_I386)
3540 && (_options.outputKind() == Options::kObjectFile)
3541 && (fixupWithStore->kind == ld::Fixup::kindStoreX86PCRel32TLVLoad) ) {
3542 fixupWithTarget->contentAddendOnly = true;
3543 fixupWithStore->contentAddendOnly = true;
3544 }
3545 else if ( isPcRelStore(fixupWithStore->kind) ) {
3546 fixupWithTarget->contentDetlaToAddendOnly = true;
3547 fixupWithStore->contentDetlaToAddendOnly = true;
3548 }
3549 else if ( minusTarget == NULL ){
3550 fixupWithTarget->contentAddendOnly = true;
3551 fixupWithStore->contentAddendOnly = true;
3552 }
3553 }
3554 }
3555
3556 if ( fixupWithStore != NULL ) {
3557 _sectionsRelocationsAtom->addSectionReloc(sect, fixupWithStore->kind, atom, fixupWithStore->offsetInAtom,
3558 targetUsesExternalReloc, minusTargetUsesExternalReloc,
3559 target, targetAddend, minusTarget, minusTargetAddend);
3560 }
3561
3562 }
3563
3564
3565 void OutputFile::makeSplitSegInfo(ld::Internal& state)
3566 {
3567 if ( !_options.sharedRegionEligible() )
3568 return;
3569
3570 for (std::vector<ld::Internal::FinalSection*>::iterator sit = state.sections.begin(); sit != state.sections.end(); ++sit) {
3571 ld::Internal::FinalSection* sect = *sit;
3572 if ( sect->isSectionHidden() )
3573 continue;
3574 if ( strcmp(sect->segmentName(), "__TEXT") != 0 )
3575 continue;
3576 for (std::vector<const ld::Atom*>::iterator ait = sect->atoms.begin(); ait != sect->atoms.end(); ++ait) {
3577 const ld::Atom* atom = *ait;
3578 const ld::Atom* target = NULL;
3579 const ld::Atom* fromTarget = NULL;
3580 uint64_t accumulator = 0;
3581 bool thumbTarget;
3582 bool hadSubtract = false;
3583 for (ld::Fixup::iterator fit = atom->fixupsBegin(), end=atom->fixupsEnd(); fit != end; ++fit) {
3584 if ( fit->firstInCluster() )
3585 target = NULL;
3586 if ( this->setsTarget(fit->kind) ) {
3587 accumulator = addressOf(state, fit, &target);
3588 thumbTarget = targetIsThumb(state, fit);
3589 if ( thumbTarget )
3590 accumulator |= 1;
3591 }
3592 switch ( fit->kind ) {
3593 case ld::Fixup::kindSubtractTargetAddress:
3594 accumulator -= addressOf(state, fit, &fromTarget);
3595 hadSubtract = true;
3596 break;
3597 case ld::Fixup::kindAddAddend:
3598 accumulator += fit->u.addend;
3599 break;
3600 case ld::Fixup::kindSubtractAddend:
3601 accumulator -= fit->u.addend;
3602 break;
3603 case ld::Fixup::kindStoreBigEndian32:
3604 case ld::Fixup::kindStoreLittleEndian32:
3605 case ld::Fixup::kindStoreLittleEndian64:
3606 case ld::Fixup::kindStoreTargetAddressLittleEndian32:
3607 case ld::Fixup::kindStoreTargetAddressLittleEndian64:
3608 // if no subtract, then this is an absolute pointer which means
3609 // there is also a text reloc which update_dyld_shared_cache will use.
3610 if ( ! hadSubtract )
3611 break;
3612 // fall through
3613 case ld::Fixup::kindStoreX86PCRel32:
3614 case ld::Fixup::kindStoreX86PCRel32_1:
3615 case ld::Fixup::kindStoreX86PCRel32_2:
3616 case ld::Fixup::kindStoreX86PCRel32_4:
3617 case ld::Fixup::kindStoreX86PCRel32GOTLoad:
3618 case ld::Fixup::kindStoreX86PCRel32GOTLoadNowLEA:
3619 case ld::Fixup::kindStoreX86PCRel32GOT:
3620 case ld::Fixup::kindStoreX86PCRel32TLVLoad:
3621 case ld::Fixup::kindStoreX86PCRel32TLVLoadNowLEA:
3622 case ld::Fixup::kindStoreTargetAddressX86PCRel32:
3623 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad:
3624 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA:
3625 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoad:
3626 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoadNowLEA:
3627 case ld::Fixup::kindStoreARMLow16:
3628 case ld::Fixup::kindStoreThumbLow16:
3629 #if SUPPORT_ARCH_arm64
3630 case ld::Fixup::kindStoreARM64Page21:
3631 case ld::Fixup::kindStoreARM64GOTLoadPage21:
3632 case ld::Fixup::kindStoreARM64GOTLeaPage21:
3633 case ld::Fixup::kindStoreARM64TLVPLoadPage21:
3634 case ld::Fixup::kindStoreTargetAddressARM64Page21:
3635 case ld::Fixup::kindStoreTargetAddressARM64GOTLoadPage21:
3636 case ld::Fixup::kindStoreTargetAddressARM64GOTLeaPage21:
3637 case ld::Fixup::kindStoreARM64PCRelToGOT:
3638 #endif
3639 assert(target != NULL);
3640 if ( strcmp(sect->segmentName(), target->section().segmentName()) != 0 ) {
3641 _splitSegInfos.push_back(SplitSegInfoEntry(atom->finalAddress()+fit->offsetInAtom,fit->kind));
3642 }
3643 break;
3644 case ld::Fixup::kindStoreARMHigh16:
3645 case ld::Fixup::kindStoreThumbHigh16:
3646 assert(target != NULL);
3647 if ( strcmp(sect->segmentName(), target->section().segmentName()) != 0 ) {
3648 // hi16 needs to know upper 4-bits of low16 to compute carry
3649 uint32_t extra = (accumulator >> 12) & 0xF;
3650 _splitSegInfos.push_back(SplitSegInfoEntry(atom->finalAddress()+fit->offsetInAtom,fit->kind, extra));
3651 }
3652 break;
3653 case ld::Fixup::kindSetTargetImageOffset:
3654 accumulator = addressOf(state, fit, &target);
3655 assert(target != NULL);
3656 hadSubtract = true;
3657 break;
3658 default:
3659 break;
3660 }
3661 }
3662 }
3663 }
3664 }
3665
3666
3667 void OutputFile::writeMapFile(ld::Internal& state)
3668 {
3669 if ( _options.generatedMapPath() != NULL ) {
3670 FILE* mapFile = fopen(_options.generatedMapPath(), "w");
3671 if ( mapFile != NULL ) {
3672 // write output path
3673 fprintf(mapFile, "# Path: %s\n", _options.outputFilePath());
3674 // write output architecure
3675 fprintf(mapFile, "# Arch: %s\n", _options.architectureName());
3676 // write UUID
3677 //if ( fUUIDAtom != NULL ) {
3678 // const uint8_t* uuid = fUUIDAtom->getUUID();
3679 // fprintf(mapFile, "# UUID: %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X \n",
3680 // uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
3681 // uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
3682 //}
3683 // write table of object files
3684 std::map<const ld::File*, ld::File::Ordinal> readerToOrdinal;
3685 std::map<ld::File::Ordinal, const ld::File*> ordinalToReader;
3686 std::map<const ld::File*, uint32_t> readerToFileOrdinal;
3687 for (std::vector<ld::Internal::FinalSection*>::iterator sit = state.sections.begin(); sit != state.sections.end(); ++sit) {
3688 ld::Internal::FinalSection* sect = *sit;
3689 if ( sect->isSectionHidden() )
3690 continue;
3691 for (std::vector<const ld::Atom*>::iterator ait = sect->atoms.begin(); ait != sect->atoms.end(); ++ait) {
3692 const ld::Atom* atom = *ait;
3693 const ld::File* reader = atom->file();
3694 if ( reader == NULL )
3695 continue;
3696 ld::File::Ordinal readerOrdinal = reader->ordinal();
3697 std::map<const ld::File*, ld::File::Ordinal>::iterator pos = readerToOrdinal.find(reader);
3698 if ( pos == readerToOrdinal.end() ) {
3699 readerToOrdinal[reader] = readerOrdinal;
3700 ordinalToReader[readerOrdinal] = reader;
3701 }
3702 }
3703 }
3704 fprintf(mapFile, "# Object files:\n");
3705 fprintf(mapFile, "[%3u] %s\n", 0, "linker synthesized");
3706 uint32_t fileIndex = 1;
3707 for(std::map<ld::File::Ordinal, const ld::File*>::iterator it = ordinalToReader.begin(); it != ordinalToReader.end(); ++it) {
3708 fprintf(mapFile, "[%3u] %s\n", fileIndex, it->second->path());
3709 readerToFileOrdinal[it->second] = fileIndex++;
3710 }
3711 // write table of sections
3712 fprintf(mapFile, "# Sections:\n");
3713 fprintf(mapFile, "# Address\tSize \tSegment\tSection\n");
3714 for (std::vector<ld::Internal::FinalSection*>::iterator sit = state.sections.begin(); sit != state.sections.end(); ++sit) {
3715 ld::Internal::FinalSection* sect = *sit;
3716 if ( sect->isSectionHidden() )
3717 continue;
3718 fprintf(mapFile, "0x%08llX\t0x%08llX\t%s\t%s\n", sect->address, sect->size,
3719 sect->segmentName(), sect->sectionName());
3720 }
3721 // write table of symbols
3722 fprintf(mapFile, "# Symbols:\n");
3723 fprintf(mapFile, "# Address\tSize \tFile Name\n");
3724 for (std::vector<ld::Internal::FinalSection*>::iterator sit = state.sections.begin(); sit != state.sections.end(); ++sit) {
3725 ld::Internal::FinalSection* sect = *sit;
3726 if ( sect->isSectionHidden() )
3727 continue;
3728 //bool isCstring = (sect->type() == ld::Section::typeCString);
3729 for (std::vector<const ld::Atom*>::iterator ait = sect->atoms.begin(); ait != sect->atoms.end(); ++ait) {
3730 char buffer[4096];
3731 const ld::Atom* atom = *ait;
3732 const char* name = atom->name();
3733 // don't add auto-stripped aliases to .map file
3734 if ( (atom->size() == 0) && (atom->symbolTableInclusion() == ld::Atom::symbolTableNotInFinalLinkedImages) )
3735 continue;
3736 if ( atom->contentType() == ld::Atom::typeCString ) {
3737 strcpy(buffer, "literal string: ");
3738 strlcat(buffer, (char*)atom->rawContentPointer(), 4096);
3739 name = buffer;
3740 }
3741 else if ( (atom->contentType() == ld::Atom::typeCFI) && (strcmp(name, "FDE") == 0) ) {
3742 for (ld::Fixup::iterator fit = atom->fixupsBegin(); fit != atom->fixupsEnd(); ++fit) {
3743 if ( (fit->kind == ld::Fixup::kindSetTargetAddress) && (fit->clusterSize == ld::Fixup::k1of4) ) {
3744 assert(fit->binding == ld::Fixup::bindingDirectlyBound);
3745 if ( fit->u.target->section().type() == ld::Section::typeCode) {
3746 strcpy(buffer, "FDE for: ");
3747 strlcat(buffer, fit->u.target->name(), 4096);
3748 name = buffer;
3749 }
3750 }
3751 }
3752 }
3753 else if ( atom->contentType() == ld::Atom::typeNonLazyPointer ) {
3754 strcpy(buffer, "non-lazy-pointer");
3755 for (ld::Fixup::iterator fit = atom->fixupsBegin(); fit != atom->fixupsEnd(); ++fit) {
3756 if ( fit->binding == ld::Fixup::bindingsIndirectlyBound ) {
3757 strcpy(buffer, "non-lazy-pointer-to: ");
3758 strlcat(buffer, state.indirectBindingTable[fit->u.bindingIndex]->name(), 4096);
3759 break;
3760 }
3761 else if ( fit->binding == ld::Fixup::bindingDirectlyBound ) {
3762 strcpy(buffer, "non-lazy-pointer-to-local: ");
3763 strlcat(buffer, fit->u.target->name(), 4096);
3764 break;
3765 }
3766 }
3767 name = buffer;
3768 }
3769 fprintf(mapFile, "0x%08llX\t0x%08llX\t[%3u] %s\n", atom->finalAddress(), atom->size(),
3770 readerToFileOrdinal[atom->file()], name);
3771 }
3772 }
3773 fclose(mapFile);
3774 }
3775 else {
3776 warning("could not write map file: %s\n", _options.generatedMapPath());
3777 }
3778 }
3779 }
3780
3781
3782 // used to sort atoms with debug notes
3783 class DebugNoteSorter
3784 {
3785 public:
3786 bool operator()(const ld::Atom* left, const ld::Atom* right) const
3787 {
3788 // first sort by reader
3789 ld::File::Ordinal leftFileOrdinal = left->file()->ordinal();
3790 ld::File::Ordinal rightFileOrdinal = right->file()->ordinal();
3791 if ( leftFileOrdinal!= rightFileOrdinal)
3792 return (leftFileOrdinal < rightFileOrdinal);
3793
3794 // then sort by atom objectAddress
3795 uint64_t leftAddr = left->finalAddress();
3796 uint64_t rightAddr = right->finalAddress();
3797 return leftAddr < rightAddr;
3798 }
3799 };
3800
3801
3802 const char* OutputFile::assureFullPath(const char* path)
3803 {
3804 if ( path[0] == '/' )
3805 return path;
3806 char cwdbuff[MAXPATHLEN];
3807 if ( getcwd(cwdbuff, MAXPATHLEN) != NULL ) {
3808 char* result;
3809 asprintf(&result, "%s/%s", cwdbuff, path);
3810 if ( result != NULL )
3811 return result;
3812 }
3813 return path;
3814 }
3815
3816 void OutputFile::synthesizeDebugNotes(ld::Internal& state)
3817 {
3818 // -S means don't synthesize debug map
3819 if ( _options.debugInfoStripping() == Options::kDebugInfoNone )
3820 return;
3821 // make a vector of atoms that come from files compiled with dwarf debug info
3822 std::vector<const ld::Atom*> atomsNeedingDebugNotes;
3823 std::set<const ld::Atom*> atomsWithStabs;
3824 atomsNeedingDebugNotes.reserve(1024);
3825 const ld::relocatable::File* objFile = NULL;
3826 bool objFileHasDwarf = false;
3827 bool objFileHasStabs = false;
3828 for (std::vector<ld::Internal::FinalSection*>::iterator sit = state.sections.begin(); sit != state.sections.end(); ++sit) {
3829 ld::Internal::FinalSection* sect = *sit;
3830 for (std::vector<const ld::Atom*>::iterator ait = sect->atoms.begin(); ait != sect->atoms.end(); ++ait) {
3831 const ld::Atom* atom = *ait;
3832 // no stabs for atoms that would not be in the symbol table
3833 if ( atom->symbolTableInclusion() == ld::Atom::symbolTableNotIn )
3834 continue;
3835 if ( atom->symbolTableInclusion() == ld::Atom::symbolTableNotInFinalLinkedImages )
3836 continue;
3837 if ( atom->symbolTableInclusion() == ld::Atom::symbolTableInWithRandomAutoStripLabel )
3838 continue;
3839 // no stabs for absolute symbols
3840 if ( atom->definition() == ld::Atom::definitionAbsolute )
3841 continue;
3842 // no stabs for .eh atoms
3843 if ( atom->contentType() == ld::Atom::typeCFI )
3844 continue;
3845 // no stabs for string literal atoms
3846 if ( atom->contentType() == ld::Atom::typeCString )
3847 continue;
3848 // no stabs for kernel dtrace probes
3849 if ( (_options.outputKind() == Options::kStaticExecutable) && (strncmp(atom->name(), "__dtrace_probe$", 15) == 0) )
3850 continue;
3851 const ld::File* file = atom->file();
3852 if ( file != NULL ) {
3853 if ( file != objFile ) {
3854 objFileHasDwarf = false;
3855 objFileHasStabs = false;
3856 objFile = dynamic_cast<const ld::relocatable::File*>(file);
3857 if ( objFile != NULL ) {
3858 switch ( objFile->debugInfo() ) {
3859 case ld::relocatable::File::kDebugInfoNone:
3860 break;
3861 case ld::relocatable::File::kDebugInfoDwarf:
3862 objFileHasDwarf = true;
3863 break;
3864 case ld::relocatable::File::kDebugInfoStabs:
3865 case ld::relocatable::File::kDebugInfoStabsUUID:
3866 objFileHasStabs = true;
3867 break;
3868 }
3869 }
3870 }
3871 if ( objFileHasDwarf )
3872 atomsNeedingDebugNotes.push_back(atom);
3873 if ( objFileHasStabs )
3874 atomsWithStabs.insert(atom);
3875 }
3876 }
3877 }
3878
3879 // sort by file ordinal then atom ordinal
3880 std::sort(atomsNeedingDebugNotes.begin(), atomsNeedingDebugNotes.end(), DebugNoteSorter());
3881
3882 // synthesize "debug notes" and add them to master stabs vector
3883 const char* dirPath = NULL;
3884 const char* filename = NULL;
3885 bool wroteStartSO = false;
3886 state.stabs.reserve(atomsNeedingDebugNotes.size()*4);
3887 std::unordered_set<const char*, CStringHash, CStringEquals> seenFiles;
3888 for (std::vector<const ld::Atom*>::iterator it=atomsNeedingDebugNotes.begin(); it != atomsNeedingDebugNotes.end(); it++) {
3889 const ld::Atom* atom = *it;
3890 const ld::File* atomFile = atom->file();
3891 const ld::relocatable::File* atomObjFile = dynamic_cast<const ld::relocatable::File*>(atomFile);
3892 //fprintf(stderr, "debug note for %s\n", atom->name());
3893 const char* newPath = atom->translationUnitSource();
3894 if ( newPath != NULL ) {
3895 const char* newDirPath;
3896 const char* newFilename;
3897 const char* lastSlash = strrchr(newPath, '/');
3898 if ( lastSlash == NULL )
3899 continue;
3900 newFilename = lastSlash+1;
3901 char* temp = strdup(newPath);
3902 newDirPath = temp;
3903 // gdb like directory SO's to end in '/', but dwarf DW_AT_comp_dir usually does not have trailing '/'
3904 temp[lastSlash-newPath+1] = '\0';
3905 // need SO's whenever the translation unit source file changes
3906 if ( (filename == NULL) || (strcmp(newFilename,filename) != 0) ) {
3907 if ( filename != NULL ) {
3908 // translation unit change, emit ending SO
3909 ld::relocatable::File::Stab endFileStab;
3910 endFileStab.atom = NULL;
3911 endFileStab.type = N_SO;
3912 endFileStab.other = 1;
3913 endFileStab.desc = 0;
3914 endFileStab.value = 0;
3915 endFileStab.string = "";
3916 state.stabs.push_back(endFileStab);
3917 }
3918 // new translation unit, emit start SO's
3919 ld::relocatable::File::Stab dirPathStab;
3920 dirPathStab.atom = NULL;
3921 dirPathStab.type = N_SO;
3922 dirPathStab.other = 0;
3923 dirPathStab.desc = 0;
3924 dirPathStab.value = 0;
3925 dirPathStab.string = newDirPath;
3926 state.stabs.push_back(dirPathStab);
3927 ld::relocatable::File::Stab fileStab;
3928 fileStab.atom = NULL;
3929 fileStab.type = N_SO;
3930 fileStab.other = 0;
3931 fileStab.desc = 0;
3932 fileStab.value = 0;
3933 fileStab.string = newFilename;
3934 state.stabs.push_back(fileStab);
3935 // Synthesize OSO for start of file
3936 ld::relocatable::File::Stab objStab;
3937 objStab.atom = NULL;
3938 objStab.type = N_OSO;
3939 // <rdar://problem/6337329> linker should put cpusubtype in n_sect field of nlist entry for N_OSO debug note entries
3940 objStab.other = atomFile->cpuSubType();
3941 objStab.desc = 1;
3942 if ( atomObjFile != NULL ) {
3943 objStab.string = assureFullPath(atomObjFile->debugInfoPath());
3944 objStab.value = atomObjFile->debugInfoModificationTime();
3945 }
3946 else {
3947 objStab.string = assureFullPath(atomFile->path());
3948 objStab.value = atomFile->modificationTime();
3949 }
3950 state.stabs.push_back(objStab);
3951 wroteStartSO = true;
3952 // add the source file path to seenFiles so it does not show up in SOLs
3953 seenFiles.insert(newFilename);
3954 char* fullFilePath;
3955 asprintf(&fullFilePath, "%s%s", newDirPath, newFilename);
3956 // add both leaf path and full path
3957 seenFiles.insert(fullFilePath);
3958 }
3959 filename = newFilename;
3960 dirPath = newDirPath;
3961 if ( atom->section().type() == ld::Section::typeCode ) {
3962 // Synthesize BNSYM and start FUN stabs
3963 ld::relocatable::File::Stab beginSym;
3964 beginSym.atom = atom;
3965 beginSym.type = N_BNSYM;
3966 beginSym.other = 1;
3967 beginSym.desc = 0;
3968 beginSym.value = 0;
3969 beginSym.string = "";
3970 state.stabs.push_back(beginSym);
3971 ld::relocatable::File::Stab startFun;
3972 startFun.atom = atom;
3973 startFun.type = N_FUN;
3974 startFun.other = 1;
3975 startFun.desc = 0;
3976 startFun.value = 0;
3977 startFun.string = atom->name();
3978 state.stabs.push_back(startFun);
3979 // Synthesize any SOL stabs needed
3980 const char* curFile = NULL;
3981 for (ld::Atom::LineInfo::iterator lit = atom->beginLineInfo(); lit != atom->endLineInfo(); ++lit) {
3982 if ( lit->fileName != curFile ) {
3983 if ( seenFiles.count(lit->fileName) == 0 ) {
3984 seenFiles.insert(lit->fileName);
3985 ld::relocatable::File::Stab sol;
3986 sol.atom = 0;
3987 sol.type = N_SOL;
3988 sol.other = 0;
3989 sol.desc = 0;
3990 sol.value = 0;
3991 sol.string = lit->fileName;
3992 state.stabs.push_back(sol);
3993 }
3994 curFile = lit->fileName;
3995 }
3996 }
3997 // Synthesize end FUN and ENSYM stabs
3998 ld::relocatable::File::Stab endFun;
3999 endFun.atom = atom;
4000 endFun.type = N_FUN;
4001 endFun.other = 0;
4002 endFun.desc = 0;
4003 endFun.value = 0;
4004 endFun.string = "";
4005 state.stabs.push_back(endFun);
4006 ld::relocatable::File::Stab endSym;
4007 endSym.atom = atom;
4008 endSym.type = N_ENSYM;
4009 endSym.other = 1;
4010 endSym.desc = 0;
4011 endSym.value = 0;
4012 endSym.string = "";
4013 state.stabs.push_back(endSym);
4014 }
4015 else {
4016 ld::relocatable::File::Stab globalsStab;
4017 const char* name = atom->name();
4018 if ( atom->scope() == ld::Atom::scopeTranslationUnit ) {
4019 // Synthesize STSYM stab for statics
4020 globalsStab.atom = atom;
4021 globalsStab.type = N_STSYM;
4022 globalsStab.other = 1;
4023 globalsStab.desc = 0;
4024 globalsStab.value = 0;
4025 globalsStab.string = name;
4026 state.stabs.push_back(globalsStab);
4027 }
4028 else {
4029 // Synthesize GSYM stab for other globals
4030 globalsStab.atom = atom;
4031 globalsStab.type = N_GSYM;
4032 globalsStab.other = 1;
4033 globalsStab.desc = 0;
4034 globalsStab.value = 0;
4035 globalsStab.string = name;
4036 state.stabs.push_back(globalsStab);
4037 }
4038 }
4039 }
4040 }
4041
4042 if ( wroteStartSO ) {
4043 // emit ending SO
4044 ld::relocatable::File::Stab endFileStab;
4045 endFileStab.atom = NULL;
4046 endFileStab.type = N_SO;
4047 endFileStab.other = 1;
4048 endFileStab.desc = 0;
4049 endFileStab.value = 0;
4050 endFileStab.string = "";
4051 state.stabs.push_back(endFileStab);
4052 }
4053
4054 // copy any stabs from .o file
4055 std::set<const ld::File*> filesSeenWithStabs;
4056 for (std::set<const ld::Atom*>::iterator it=atomsWithStabs.begin(); it != atomsWithStabs.end(); it++) {
4057 const ld::Atom* atom = *it;
4058 objFile = dynamic_cast<const ld::relocatable::File*>(atom->file());
4059 if ( objFile != NULL ) {
4060 if ( filesSeenWithStabs.count(objFile) == 0 ) {
4061 filesSeenWithStabs.insert(objFile);
4062 const std::vector<ld::relocatable::File::Stab>* stabs = objFile->stabs();
4063 if ( stabs != NULL ) {
4064 for(std::vector<ld::relocatable::File::Stab>::const_iterator sit = stabs->begin(); sit != stabs->end(); ++sit) {
4065 ld::relocatable::File::Stab stab = *sit;
4066 // ignore stabs associated with atoms that were dead stripped or coalesced away
4067 if ( (sit->atom != NULL) && (atomsWithStabs.count(sit->atom) == 0) )
4068 continue;
4069 // <rdar://problem/8284718> Value of N_SO stabs should be address of first atom from translation unit
4070 if ( (stab.type == N_SO) && (stab.string != NULL) && (stab.string[0] != '\0') ) {
4071 stab.atom = atom;
4072 }
4073 state.stabs.push_back(stab);
4074 }
4075 }
4076 }
4077 }
4078 }
4079
4080 }
4081
4082
4083 } // namespace tool
4084 } // namespace ld
4085