MachOLinkingContext.cpp revision 292934
1//===- lib/ReaderWriter/MachO/MachOLinkingContext.cpp ---------------------===// 2// 3// The LLVM Linker 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include "lld/ReaderWriter/MachOLinkingContext.h" 11#include "ArchHandler.h" 12#include "File.h" 13#include "FlatNamespaceFile.h" 14#include "MachONormalizedFile.h" 15#include "MachOPasses.h" 16#include "SectCreateFile.h" 17#include "lld/Core/ArchiveLibraryFile.h" 18#include "lld/Core/PassManager.h" 19#include "lld/Core/Reader.h" 20#include "lld/Core/Writer.h" 21#include "lld/Driver/Driver.h" 22#include "llvm/ADT/STLExtras.h" 23#include "llvm/ADT/StringExtras.h" 24#include "llvm/ADT/Triple.h" 25#include "llvm/Config/config.h" 26#include "llvm/Support/Debug.h" 27#include "llvm/Support/Errc.h" 28#include "llvm/Support/Host.h" 29#include "llvm/Support/MachO.h" 30#include "llvm/Support/Path.h" 31#include <algorithm> 32 33#if defined(HAVE_CXXABI_H) 34#include <cxxabi.h> 35#endif 36 37using lld::mach_o::ArchHandler; 38using lld::mach_o::MachODylibFile; 39using namespace llvm::MachO; 40 41namespace lld { 42 43bool MachOLinkingContext::parsePackedVersion(StringRef str, uint32_t &result) { 44 result = 0; 45 46 if (str.empty()) 47 return false; 48 49 SmallVector<StringRef, 3> parts; 50 llvm::SplitString(str, parts, "."); 51 52 unsigned long long num; 53 if (llvm::getAsUnsignedInteger(parts[0], 10, num)) 54 return true; 55 if (num > 65535) 56 return true; 57 result = num << 16; 58 59 if (parts.size() > 1) { 60 if (llvm::getAsUnsignedInteger(parts[1], 10, num)) 61 return true; 62 if (num > 255) 63 return true; 64 result |= (num << 8); 65 } 66 67 if (parts.size() > 2) { 68 if (llvm::getAsUnsignedInteger(parts[2], 10, num)) 69 return true; 70 if (num > 255) 71 return true; 72 result |= num; 73 } 74 75 return false; 76} 77 78MachOLinkingContext::ArchInfo MachOLinkingContext::_s_archInfos[] = { 79 { "x86_64", arch_x86_64, true, CPU_TYPE_X86_64, CPU_SUBTYPE_X86_64_ALL }, 80 { "i386", arch_x86, true, CPU_TYPE_I386, CPU_SUBTYPE_X86_ALL }, 81 { "ppc", arch_ppc, false, CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_ALL }, 82 { "armv6", arch_armv6, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V6 }, 83 { "armv7", arch_armv7, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7 }, 84 { "armv7s", arch_armv7s, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7S }, 85 { "arm64", arch_arm64, true, CPU_TYPE_ARM64, CPU_SUBTYPE_ARM64_ALL }, 86 { "", arch_unknown,false, 0, 0 } 87}; 88 89MachOLinkingContext::Arch 90MachOLinkingContext::archFromCpuType(uint32_t cputype, uint32_t cpusubtype) { 91 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) { 92 if ((info->cputype == cputype) && (info->cpusubtype == cpusubtype)) 93 return info->arch; 94 } 95 return arch_unknown; 96} 97 98MachOLinkingContext::Arch 99MachOLinkingContext::archFromName(StringRef archName) { 100 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) { 101 if (info->archName.equals(archName)) 102 return info->arch; 103 } 104 return arch_unknown; 105} 106 107StringRef MachOLinkingContext::nameFromArch(Arch arch) { 108 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) { 109 if (info->arch == arch) 110 return info->archName; 111 } 112 return "<unknown>"; 113} 114 115uint32_t MachOLinkingContext::cpuTypeFromArch(Arch arch) { 116 assert(arch != arch_unknown); 117 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) { 118 if (info->arch == arch) 119 return info->cputype; 120 } 121 llvm_unreachable("Unknown arch type"); 122} 123 124uint32_t MachOLinkingContext::cpuSubtypeFromArch(Arch arch) { 125 assert(arch != arch_unknown); 126 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) { 127 if (info->arch == arch) 128 return info->cpusubtype; 129 } 130 llvm_unreachable("Unknown arch type"); 131} 132 133bool MachOLinkingContext::isThinObjectFile(StringRef path, Arch &arch) { 134 return mach_o::normalized::isThinObjectFile(path, arch); 135} 136 137bool MachOLinkingContext::sliceFromFatFile(MemoryBufferRef mb, uint32_t &offset, 138 uint32_t &size) { 139 return mach_o::normalized::sliceFromFatFile(mb, _arch, offset, size); 140} 141 142MachOLinkingContext::MachOLinkingContext() 143 : _outputMachOType(MH_EXECUTE), _outputMachOTypeStatic(false), 144 _doNothing(false), _pie(false), _arch(arch_unknown), _os(OS::macOSX), 145 _osMinVersion(0), _pageZeroSize(0), _pageSize(4096), _baseAddress(0), 146 _stackSize(0), _compatibilityVersion(0), _currentVersion(0), 147 _flatNamespace(false), _undefinedMode(UndefinedMode::error), 148 _deadStrippableDylib(false), _printAtoms(false), _testingFileUsage(false), 149 _keepPrivateExterns(false), _demangle(false), _archHandler(nullptr), 150 _exportMode(ExportMode::globals), 151 _debugInfoMode(DebugInfoMode::addDebugMap), _orderFileEntries(0), 152 _flatNamespaceFile(nullptr) {} 153 154MachOLinkingContext::~MachOLinkingContext() {} 155 156void MachOLinkingContext::configure(HeaderFileType type, Arch arch, OS os, 157 uint32_t minOSVersion) { 158 _outputMachOType = type; 159 _arch = arch; 160 _os = os; 161 _osMinVersion = minOSVersion; 162 163 // If min OS not specified on command line, use reasonable defaults. 164 if (minOSVersion == 0) { 165 switch (_arch) { 166 case arch_x86_64: 167 case arch_x86: 168 parsePackedVersion("10.8", _osMinVersion); 169 _os = MachOLinkingContext::OS::macOSX; 170 break; 171 case arch_armv6: 172 case arch_armv7: 173 case arch_armv7s: 174 case arch_arm64: 175 parsePackedVersion("7.0", _osMinVersion); 176 _os = MachOLinkingContext::OS::iOS; 177 break; 178 default: 179 break; 180 } 181 } 182 183 switch (_outputMachOType) { 184 case llvm::MachO::MH_EXECUTE: 185 // If targeting newer OS, use _main 186 if (minOS("10.8", "6.0")) { 187 _entrySymbolName = "_main"; 188 } else { 189 // If targeting older OS, use start (in crt1.o) 190 _entrySymbolName = "start"; 191 } 192 193 // __PAGEZERO defaults to 4GB on 64-bit (except for PP64 which lld does not 194 // support) and 4KB on 32-bit. 195 if (is64Bit(_arch)) { 196 _pageZeroSize = 0x100000000; 197 } else { 198 _pageZeroSize = 0x1000; 199 } 200 201 // Initial base address is __PAGEZERO size. 202 _baseAddress = _pageZeroSize; 203 204 // Make PIE by default when targetting newer OSs. 205 switch (os) { 206 case OS::macOSX: 207 if (minOSVersion >= 0x000A0700) // MacOSX 10.7 208 _pie = true; 209 break; 210 case OS::iOS: 211 if (minOSVersion >= 0x00040300) // iOS 4.3 212 _pie = true; 213 break; 214 case OS::iOS_simulator: 215 _pie = true; 216 break; 217 case OS::unknown: 218 break; 219 } 220 break; 221 case llvm::MachO::MH_DYLIB: 222 setGlobalsAreDeadStripRoots(true); 223 break; 224 case llvm::MachO::MH_BUNDLE: 225 break; 226 case llvm::MachO::MH_OBJECT: 227 _printRemainingUndefines = false; 228 _allowRemainingUndefines = true; 229 default: 230 break; 231 } 232 233 // Set default segment page sizes based on arch. 234 if (arch == arch_arm64) 235 _pageSize = 4*4096; 236} 237 238uint32_t MachOLinkingContext::getCPUType() const { 239 return cpuTypeFromArch(_arch); 240} 241 242uint32_t MachOLinkingContext::getCPUSubType() const { 243 return cpuSubtypeFromArch(_arch); 244} 245 246bool MachOLinkingContext::is64Bit(Arch arch) { 247 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) { 248 if (info->arch == arch) { 249 return (info->cputype & CPU_ARCH_ABI64); 250 } 251 } 252 // unknown archs are not 64-bit. 253 return false; 254} 255 256bool MachOLinkingContext::isHostEndian(Arch arch) { 257 assert(arch != arch_unknown); 258 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) { 259 if (info->arch == arch) { 260 return (info->littleEndian == llvm::sys::IsLittleEndianHost); 261 } 262 } 263 llvm_unreachable("Unknown arch type"); 264} 265 266bool MachOLinkingContext::isBigEndian(Arch arch) { 267 assert(arch != arch_unknown); 268 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) { 269 if (info->arch == arch) { 270 return ! info->littleEndian; 271 } 272 } 273 llvm_unreachable("Unknown arch type"); 274} 275 276bool MachOLinkingContext::is64Bit() const { 277 return is64Bit(_arch); 278} 279 280bool MachOLinkingContext::outputTypeHasEntry() const { 281 switch (_outputMachOType) { 282 case MH_EXECUTE: 283 case MH_DYLINKER: 284 case MH_PRELOAD: 285 return true; 286 default: 287 return false; 288 } 289} 290 291bool MachOLinkingContext::needsStubsPass() const { 292 switch (_outputMachOType) { 293 case MH_EXECUTE: 294 return !_outputMachOTypeStatic; 295 case MH_DYLIB: 296 case MH_BUNDLE: 297 return true; 298 default: 299 return false; 300 } 301} 302 303bool MachOLinkingContext::needsGOTPass() const { 304 // GOT pass not used in -r mode. 305 if (_outputMachOType == MH_OBJECT) 306 return false; 307 // Only some arches use GOT pass. 308 switch (_arch) { 309 case arch_x86_64: 310 case arch_arm64: 311 return true; 312 default: 313 return false; 314 } 315} 316 317bool MachOLinkingContext::needsCompactUnwindPass() const { 318 switch (_outputMachOType) { 319 case MH_EXECUTE: 320 case MH_DYLIB: 321 case MH_BUNDLE: 322 return archHandler().needsCompactUnwind(); 323 default: 324 return false; 325 } 326} 327 328bool MachOLinkingContext::needsShimPass() const { 329 // Shim pass only used in final executables. 330 if (_outputMachOType == MH_OBJECT) 331 return false; 332 // Only 32-bit arm arches use Shim pass. 333 switch (_arch) { 334 case arch_armv6: 335 case arch_armv7: 336 case arch_armv7s: 337 return true; 338 default: 339 return false; 340 } 341} 342 343bool MachOLinkingContext::needsTLVPass() const { 344 switch (_outputMachOType) { 345 case MH_BUNDLE: 346 case MH_EXECUTE: 347 case MH_DYLIB: 348 return true; 349 default: 350 return false; 351 } 352} 353 354StringRef MachOLinkingContext::binderSymbolName() const { 355 return archHandler().stubInfo().binderSymbolName; 356} 357 358bool MachOLinkingContext::minOS(StringRef mac, StringRef iOS) const { 359 uint32_t parsedVersion; 360 switch (_os) { 361 case OS::macOSX: 362 if (parsePackedVersion(mac, parsedVersion)) 363 return false; 364 return _osMinVersion >= parsedVersion; 365 case OS::iOS: 366 case OS::iOS_simulator: 367 if (parsePackedVersion(iOS, parsedVersion)) 368 return false; 369 return _osMinVersion >= parsedVersion; 370 case OS::unknown: 371 break; 372 } 373 llvm_unreachable("target not configured for iOS or MacOSX"); 374} 375 376bool MachOLinkingContext::addEntryPointLoadCommand() const { 377 if ((_outputMachOType == MH_EXECUTE) && !_outputMachOTypeStatic) { 378 return minOS("10.8", "6.0"); 379 } 380 return false; 381} 382 383bool MachOLinkingContext::addUnixThreadLoadCommand() const { 384 switch (_outputMachOType) { 385 case MH_EXECUTE: 386 if (_outputMachOTypeStatic) 387 return true; 388 else 389 return !minOS("10.8", "6.0"); 390 break; 391 case MH_DYLINKER: 392 case MH_PRELOAD: 393 return true; 394 default: 395 return false; 396 } 397} 398 399bool MachOLinkingContext::pathExists(StringRef path) const { 400 if (!_testingFileUsage) 401 return llvm::sys::fs::exists(path.str()); 402 403 // Otherwise, we're in test mode: only files explicitly provided on the 404 // command-line exist. 405 std::string key = path.str(); 406 std::replace(key.begin(), key.end(), '\\', '/'); 407 return _existingPaths.find(key) != _existingPaths.end(); 408} 409 410bool MachOLinkingContext::fileExists(StringRef path) const { 411 bool found = pathExists(path); 412 // Log search misses. 413 if (!found) 414 addInputFileNotFound(path); 415 416 // When testing, file is never opened, so logging is done here. 417 if (_testingFileUsage && found) 418 addInputFileDependency(path); 419 420 return found; 421} 422 423void MachOLinkingContext::setSysLibRoots(const StringRefVector &paths) { 424 _syslibRoots = paths; 425} 426 427void MachOLinkingContext::addRpath(StringRef rpath) { 428 _rpaths.push_back(rpath); 429} 430 431void MachOLinkingContext::addModifiedSearchDir(StringRef libPath, 432 bool isSystemPath) { 433 bool addedModifiedPath = false; 434 435 // -syslibroot only applies to absolute paths. 436 if (libPath.startswith("/")) { 437 for (auto syslibRoot : _syslibRoots) { 438 SmallString<256> path(syslibRoot); 439 llvm::sys::path::append(path, libPath); 440 if (pathExists(path)) { 441 _searchDirs.push_back(path.str().copy(_allocator)); 442 addedModifiedPath = true; 443 } 444 } 445 } 446 447 if (addedModifiedPath) 448 return; 449 450 // Finally, if only one -syslibroot is given, system paths which aren't in it 451 // get suppressed. 452 if (_syslibRoots.size() != 1 || !isSystemPath) { 453 if (pathExists(libPath)) { 454 _searchDirs.push_back(libPath); 455 } 456 } 457} 458 459void MachOLinkingContext::addFrameworkSearchDir(StringRef fwPath, 460 bool isSystemPath) { 461 bool pathAdded = false; 462 463 // -syslibroot only used with to absolute framework search paths. 464 if (fwPath.startswith("/")) { 465 for (auto syslibRoot : _syslibRoots) { 466 SmallString<256> path(syslibRoot); 467 llvm::sys::path::append(path, fwPath); 468 if (pathExists(path)) { 469 _frameworkDirs.push_back(path.str().copy(_allocator)); 470 pathAdded = true; 471 } 472 } 473 } 474 // If fwPath found in any -syslibroot, then done. 475 if (pathAdded) 476 return; 477 478 // If only one -syslibroot, system paths not in that SDK are suppressed. 479 if (isSystemPath && (_syslibRoots.size() == 1)) 480 return; 481 482 // Only use raw fwPath if that directory exists. 483 if (pathExists(fwPath)) 484 _frameworkDirs.push_back(fwPath); 485} 486 487ErrorOr<StringRef> 488MachOLinkingContext::searchDirForLibrary(StringRef path, 489 StringRef libName) const { 490 SmallString<256> fullPath; 491 if (libName.endswith(".o")) { 492 // A request ending in .o is special: just search for the file directly. 493 fullPath.assign(path); 494 llvm::sys::path::append(fullPath, libName); 495 if (fileExists(fullPath)) 496 return fullPath.str().copy(_allocator); 497 return make_error_code(llvm::errc::no_such_file_or_directory); 498 } 499 500 // Search for dynamic library 501 fullPath.assign(path); 502 llvm::sys::path::append(fullPath, Twine("lib") + libName + ".dylib"); 503 if (fileExists(fullPath)) 504 return fullPath.str().copy(_allocator); 505 506 // If not, try for a static library 507 fullPath.assign(path); 508 llvm::sys::path::append(fullPath, Twine("lib") + libName + ".a"); 509 if (fileExists(fullPath)) 510 return fullPath.str().copy(_allocator); 511 512 return make_error_code(llvm::errc::no_such_file_or_directory); 513} 514 515ErrorOr<StringRef> MachOLinkingContext::searchLibrary(StringRef libName) const { 516 SmallString<256> path; 517 for (StringRef dir : searchDirs()) { 518 ErrorOr<StringRef> ec = searchDirForLibrary(dir, libName); 519 if (ec) 520 return ec; 521 } 522 523 return make_error_code(llvm::errc::no_such_file_or_directory); 524} 525 526ErrorOr<StringRef> MachOLinkingContext::findPathForFramework(StringRef fwName) const{ 527 SmallString<256> fullPath; 528 for (StringRef dir : frameworkDirs()) { 529 fullPath.assign(dir); 530 llvm::sys::path::append(fullPath, Twine(fwName) + ".framework", fwName); 531 if (fileExists(fullPath)) 532 return fullPath.str().copy(_allocator); 533 } 534 535 return make_error_code(llvm::errc::no_such_file_or_directory); 536} 537 538bool MachOLinkingContext::validateImpl(raw_ostream &diagnostics) { 539 // TODO: if -arch not specified, look at arch of first .o file. 540 541 if (_currentVersion && _outputMachOType != MH_DYLIB) { 542 diagnostics << "error: -current_version can only be used with dylibs\n"; 543 return false; 544 } 545 546 if (_compatibilityVersion && _outputMachOType != MH_DYLIB) { 547 diagnostics 548 << "error: -compatibility_version can only be used with dylibs\n"; 549 return false; 550 } 551 552 if (_deadStrippableDylib && _outputMachOType != MH_DYLIB) { 553 diagnostics 554 << "error: -mark_dead_strippable_dylib can only be used with dylibs.\n"; 555 return false; 556 } 557 558 if (!_bundleLoader.empty() && outputMachOType() != MH_BUNDLE) { 559 diagnostics 560 << "error: -bundle_loader can only be used with Mach-O bundles\n"; 561 return false; 562 } 563 564 // If -exported_symbols_list used, all exported symbols must be defined. 565 if (_exportMode == ExportMode::whiteList) { 566 for (const auto &symbol : _exportedSymbols) 567 addInitialUndefinedSymbol(symbol.getKey()); 568 } 569 570 // If -dead_strip, set up initial live symbols. 571 if (deadStrip()) { 572 // Entry point is live. 573 if (outputTypeHasEntry()) 574 addDeadStripRoot(entrySymbolName()); 575 // Lazy binding helper is live. 576 if (needsStubsPass()) 577 addDeadStripRoot(binderSymbolName()); 578 // If using -exported_symbols_list, make all exported symbols live. 579 if (_exportMode == ExportMode::whiteList) { 580 setGlobalsAreDeadStripRoots(false); 581 for (const auto &symbol : _exportedSymbols) 582 addDeadStripRoot(symbol.getKey()); 583 } 584 } 585 586 addOutputFileDependency(outputPath()); 587 588 return true; 589} 590 591void MachOLinkingContext::addPasses(PassManager &pm) { 592 mach_o::addLayoutPass(pm, *this); 593 if (needsStubsPass()) 594 mach_o::addStubsPass(pm, *this); 595 if (needsCompactUnwindPass()) 596 mach_o::addCompactUnwindPass(pm, *this); 597 if (needsGOTPass()) 598 mach_o::addGOTPass(pm, *this); 599 if (needsTLVPass()) 600 mach_o::addTLVPass(pm, *this); 601 if (needsShimPass()) 602 mach_o::addShimPass(pm, *this); // Shim pass must run after stubs pass. 603} 604 605Writer &MachOLinkingContext::writer() const { 606 if (!_writer) 607 _writer = createWriterMachO(*this); 608 return *_writer; 609} 610 611ErrorOr<std::unique_ptr<MemoryBuffer>> 612MachOLinkingContext::getMemoryBuffer(StringRef path) { 613 addInputFileDependency(path); 614 615 ErrorOr<std::unique_ptr<MemoryBuffer>> mbOrErr = 616 MemoryBuffer::getFileOrSTDIN(path); 617 if (std::error_code ec = mbOrErr.getError()) 618 return ec; 619 std::unique_ptr<MemoryBuffer> mb = std::move(mbOrErr.get()); 620 621 // If buffer contains a fat file, find required arch in fat buffer 622 // and switch buffer to point to just that required slice. 623 uint32_t offset; 624 uint32_t size; 625 if (sliceFromFatFile(mb->getMemBufferRef(), offset, size)) 626 return MemoryBuffer::getFileSlice(path, size, offset); 627 return std::move(mb); 628} 629 630MachODylibFile* MachOLinkingContext::loadIndirectDylib(StringRef path) { 631 ErrorOr<std::unique_ptr<MemoryBuffer>> mbOrErr = getMemoryBuffer(path); 632 if (mbOrErr.getError()) 633 return nullptr; 634 635 ErrorOr<std::unique_ptr<File>> fileOrErr = 636 registry().loadFile(std::move(mbOrErr.get())); 637 if (!fileOrErr) 638 return nullptr; 639 std::unique_ptr<File> &file = fileOrErr.get(); 640 file->parse(); 641 MachODylibFile *result = reinterpret_cast<MachODylibFile *>(file.get()); 642 // Node object now owned by _indirectDylibs vector. 643 _indirectDylibs.push_back(std::move(file)); 644 return result; 645} 646 647MachODylibFile* MachOLinkingContext::findIndirectDylib(StringRef path) { 648 // See if already loaded. 649 auto pos = _pathToDylibMap.find(path); 650 if (pos != _pathToDylibMap.end()) 651 return pos->second; 652 653 // Search -L paths if of the form "libXXX.dylib" 654 std::pair<StringRef, StringRef> split = path.rsplit('/'); 655 StringRef leafName = split.second; 656 if (leafName.startswith("lib") && leafName.endswith(".dylib")) { 657 // FIXME: Need to enhance searchLibrary() to only look for .dylib 658 auto libPath = searchLibrary(leafName); 659 if (!libPath.getError()) { 660 return loadIndirectDylib(libPath.get()); 661 } 662 } 663 664 // Try full path with sysroot. 665 for (StringRef sysPath : _syslibRoots) { 666 SmallString<256> fullPath; 667 fullPath.assign(sysPath); 668 llvm::sys::path::append(fullPath, path); 669 if (pathExists(fullPath)) 670 return loadIndirectDylib(fullPath); 671 } 672 673 // Try full path. 674 if (pathExists(path)) { 675 return loadIndirectDylib(path); 676 } 677 678 return nullptr; 679} 680 681uint32_t MachOLinkingContext::dylibCurrentVersion(StringRef installName) const { 682 auto pos = _pathToDylibMap.find(installName); 683 if (pos != _pathToDylibMap.end()) 684 return pos->second->currentVersion(); 685 else 686 return 0x1000; // 1.0 687} 688 689uint32_t MachOLinkingContext::dylibCompatVersion(StringRef installName) const { 690 auto pos = _pathToDylibMap.find(installName); 691 if (pos != _pathToDylibMap.end()) 692 return pos->second->compatVersion(); 693 else 694 return 0x1000; // 1.0 695} 696 697void MachOLinkingContext::createImplicitFiles( 698 std::vector<std::unique_ptr<File> > &result) { 699 // Add indirect dylibs by asking each linked dylib to add its indirects. 700 // Iterate until no more dylibs get loaded. 701 size_t dylibCount = 0; 702 while (dylibCount != _allDylibs.size()) { 703 dylibCount = _allDylibs.size(); 704 for (MachODylibFile *dylib : _allDylibs) { 705 dylib->loadReExportedDylibs([this] (StringRef path) -> MachODylibFile* { 706 return findIndirectDylib(path); }); 707 } 708 } 709 710 // Let writer add output type specific extras. 711 writer().createImplicitFiles(result); 712 713 // If undefinedMode is != error, add a FlatNamespaceFile instance. This will 714 // provide a SharedLibraryAtom for symbols that aren't defined elsewhere. 715 if (undefinedMode() != UndefinedMode::error) { 716 result.emplace_back(new mach_o::FlatNamespaceFile(*this)); 717 _flatNamespaceFile = result.back().get(); 718 } 719} 720 721void MachOLinkingContext::registerDylib(MachODylibFile *dylib, 722 bool upward) const { 723 std::lock_guard<std::mutex> lock(_dylibsMutex); 724 _allDylibs.insert(dylib); 725 _pathToDylibMap[dylib->installName()] = dylib; 726 // If path is different than install name, register path too. 727 if (!dylib->path().equals(dylib->installName())) 728 _pathToDylibMap[dylib->path()] = dylib; 729 if (upward) 730 _upwardDylibs.insert(dylib); 731} 732 733bool MachOLinkingContext::isUpwardDylib(StringRef installName) const { 734 for (MachODylibFile *dylib : _upwardDylibs) { 735 if (dylib->installName().equals(installName)) 736 return true; 737 } 738 return false; 739} 740 741ArchHandler &MachOLinkingContext::archHandler() const { 742 if (!_archHandler) 743 _archHandler = ArchHandler::create(_arch); 744 return *_archHandler; 745} 746 747void MachOLinkingContext::addSectionAlignment(StringRef seg, StringRef sect, 748 uint16_t align) { 749 SectionAlign entry = { seg, sect, align }; 750 _sectAligns.push_back(entry); 751} 752 753void MachOLinkingContext::addSectCreateSection( 754 StringRef seg, StringRef sect, 755 std::unique_ptr<MemoryBuffer> content) { 756 757 if (!_sectCreateFile) { 758 auto sectCreateFile = llvm::make_unique<mach_o::SectCreateFile>(); 759 _sectCreateFile = sectCreateFile.get(); 760 getNodes().push_back(llvm::make_unique<FileNode>(std::move(sectCreateFile))); 761 } 762 763 assert(_sectCreateFile && "sectcreate file does not exist."); 764 _sectCreateFile->addSection(seg, sect, std::move(content)); 765} 766 767bool MachOLinkingContext::sectionAligned(StringRef seg, StringRef sect, 768 uint16_t &align) const { 769 for (const SectionAlign &entry : _sectAligns) { 770 if (seg.equals(entry.segmentName) && sect.equals(entry.sectionName)) { 771 align = entry.align; 772 return true; 773 } 774 } 775 return false; 776} 777 778void MachOLinkingContext::addExportSymbol(StringRef sym) { 779 // Support old crufty export lists with bogus entries. 780 if (sym.endswith(".eh") || sym.startswith(".objc_category_name_")) { 781 llvm::errs() << "warning: ignoring " << sym << " in export list\n"; 782 return; 783 } 784 // Only i386 MacOSX uses old ABI, so don't change those. 785 if ((_os != OS::macOSX) || (_arch != arch_x86)) { 786 // ObjC has two differnent ABIs. Be nice and allow one export list work for 787 // both ABIs by renaming symbols. 788 if (sym.startswith(".objc_class_name_")) { 789 std::string abi2className("_OBJC_CLASS_$_"); 790 abi2className += sym.substr(17); 791 _exportedSymbols.insert(copy(abi2className)); 792 std::string abi2metaclassName("_OBJC_METACLASS_$_"); 793 abi2metaclassName += sym.substr(17); 794 _exportedSymbols.insert(copy(abi2metaclassName)); 795 return; 796 } 797 } 798 799 // FIXME: Support wildcards. 800 _exportedSymbols.insert(sym); 801} 802 803bool MachOLinkingContext::exportSymbolNamed(StringRef sym) const { 804 switch (_exportMode) { 805 case ExportMode::globals: 806 llvm_unreachable("exportSymbolNamed() should not be called in this mode"); 807 break; 808 case ExportMode::whiteList: 809 return _exportedSymbols.count(sym); 810 case ExportMode::blackList: 811 return !_exportedSymbols.count(sym); 812 } 813 llvm_unreachable("_exportMode unknown enum value"); 814} 815 816std::string MachOLinkingContext::demangle(StringRef symbolName) const { 817 // Only try to demangle symbols if -demangle on command line 818 if (!demangleSymbols()) 819 return symbolName; 820 821 // Only try to demangle symbols that look like C++ symbols 822 if (!symbolName.startswith("__Z")) 823 return symbolName; 824 825#if defined(HAVE_CXXABI_H) 826 SmallString<256> symBuff; 827 StringRef nullTermSym = Twine(symbolName).toNullTerminatedStringRef(symBuff); 828 // Mach-O has extra leading underscore that needs to be removed. 829 const char *cstr = nullTermSym.data() + 1; 830 int status; 831 char *demangled = abi::__cxa_demangle(cstr, nullptr, nullptr, &status); 832 if (demangled) { 833 std::string result(demangled); 834 // __cxa_demangle() always uses a malloc'ed buffer to return the result. 835 free(demangled); 836 return result; 837 } 838#endif 839 840 return symbolName; 841} 842 843std::error_code MachOLinkingContext::createDependencyFile(StringRef path) { 844 std::error_code ec; 845 _dependencyInfo = std::unique_ptr<llvm::raw_fd_ostream>(new 846 llvm::raw_fd_ostream(path, ec, llvm::sys::fs::F_None)); 847 if (ec) { 848 _dependencyInfo.reset(); 849 return ec; 850 } 851 852 char linkerVersionOpcode = 0x00; 853 *_dependencyInfo << linkerVersionOpcode; 854 *_dependencyInfo << "lld"; // FIXME 855 *_dependencyInfo << '\0'; 856 857 return std::error_code(); 858} 859 860void MachOLinkingContext::addInputFileDependency(StringRef path) const { 861 if (!_dependencyInfo) 862 return; 863 864 char inputFileOpcode = 0x10; 865 *_dependencyInfo << inputFileOpcode; 866 *_dependencyInfo << path; 867 *_dependencyInfo << '\0'; 868} 869 870void MachOLinkingContext::addInputFileNotFound(StringRef path) const { 871 if (!_dependencyInfo) 872 return; 873 874 char inputFileOpcode = 0x11; 875 *_dependencyInfo << inputFileOpcode; 876 *_dependencyInfo << path; 877 *_dependencyInfo << '\0'; 878} 879 880void MachOLinkingContext::addOutputFileDependency(StringRef path) const { 881 if (!_dependencyInfo) 882 return; 883 884 char outputFileOpcode = 0x40; 885 *_dependencyInfo << outputFileOpcode; 886 *_dependencyInfo << path; 887 *_dependencyInfo << '\0'; 888} 889 890void MachOLinkingContext::appendOrderedSymbol(StringRef symbol, 891 StringRef filename) { 892 // To support sorting static functions which may have the same name in 893 // multiple .o files, _orderFiles maps the symbol name to a vector 894 // of OrderFileNode each of which can specify a file prefix. 895 OrderFileNode info; 896 if (!filename.empty()) 897 info.fileFilter = copy(filename); 898 info.order = _orderFileEntries++; 899 _orderFiles[symbol].push_back(info); 900} 901 902bool 903MachOLinkingContext::findOrderOrdinal(const std::vector<OrderFileNode> &nodes, 904 const DefinedAtom *atom, 905 unsigned &ordinal) { 906 const File *objFile = &atom->file(); 907 assert(objFile); 908 StringRef objName = objFile->path(); 909 std::pair<StringRef, StringRef> dirAndLeaf = objName.rsplit('/'); 910 if (!dirAndLeaf.second.empty()) 911 objName = dirAndLeaf.second; 912 for (const OrderFileNode &info : nodes) { 913 if (info.fileFilter.empty()) { 914 // Have unprefixed symbol name in order file that matches this atom. 915 ordinal = info.order; 916 return true; 917 } 918 if (info.fileFilter.equals(objName)) { 919 // Have prefixed symbol name in order file that matches atom's path. 920 ordinal = info.order; 921 return true; 922 } 923 } 924 return false; 925} 926 927bool MachOLinkingContext::customAtomOrderer(const DefinedAtom *left, 928 const DefinedAtom *right, 929 bool &leftBeforeRight) const { 930 // No custom sorting if no order file entries. 931 if (!_orderFileEntries) 932 return false; 933 934 // Order files can only order named atoms. 935 StringRef leftName = left->name(); 936 StringRef rightName = right->name(); 937 if (leftName.empty() || rightName.empty()) 938 return false; 939 940 // If neither is in order file list, no custom sorter. 941 auto leftPos = _orderFiles.find(leftName); 942 auto rightPos = _orderFiles.find(rightName); 943 bool leftIsOrdered = (leftPos != _orderFiles.end()); 944 bool rightIsOrdered = (rightPos != _orderFiles.end()); 945 if (!leftIsOrdered && !rightIsOrdered) 946 return false; 947 948 // There could be multiple symbols with same name but different file prefixes. 949 unsigned leftOrder; 950 unsigned rightOrder; 951 bool foundLeft = 952 leftIsOrdered && findOrderOrdinal(leftPos->getValue(), left, leftOrder); 953 bool foundRight = rightIsOrdered && 954 findOrderOrdinal(rightPos->getValue(), right, rightOrder); 955 if (!foundLeft && !foundRight) 956 return false; 957 958 // If only one is in order file list, ordered one goes first. 959 if (foundLeft != foundRight) 960 leftBeforeRight = foundLeft; 961 else 962 leftBeforeRight = (leftOrder < rightOrder); 963 964 return true; 965} 966 967static bool isLibrary(const std::unique_ptr<Node> &elem) { 968 if (FileNode *node = dyn_cast<FileNode>(const_cast<Node *>(elem.get()))) { 969 File *file = node->getFile(); 970 return isa<SharedLibraryFile>(file) || isa<ArchiveLibraryFile>(file); 971 } 972 return false; 973} 974 975// The darwin linker processes input files in two phases. The first phase 976// links in all object (.o) files in command line order. The second phase 977// links in libraries in command line order. 978// In this function we reorder the input files so that all the object files 979// comes before any library file. We also make a group for the library files 980// so that the Resolver will reiterate over the libraries as long as we find 981// new undefines from libraries. 982void MachOLinkingContext::finalizeInputFiles() { 983 std::vector<std::unique_ptr<Node>> &elements = getNodes(); 984 std::stable_sort(elements.begin(), elements.end(), 985 [](const std::unique_ptr<Node> &a, 986 const std::unique_ptr<Node> &b) { 987 return !isLibrary(a) && isLibrary(b); 988 }); 989 size_t numLibs = std::count_if(elements.begin(), elements.end(), isLibrary); 990 elements.push_back(llvm::make_unique<GroupEnd>(numLibs)); 991} 992 993} // end namespace lld 994