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