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