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