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