1 //===- lib/ReaderWriter/MachO/MachOLinkingContext.cpp ---------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "lld/Common/ErrorHandler.h"
10 #include "lld/ReaderWriter/MachOLinkingContext.h"
11 #include "ArchHandler.h"
13 #include "FlatNamespaceFile.h"
14 #include "MachONormalizedFile.h"
15 #include "MachOPasses.h"
16 #include "SectCreateFile.h"
17 #include "lld/Common/Driver.h"
18 #include "lld/Core/ArchiveLibraryFile.h"
19 #include "lld/Core/PassManager.h"
20 #include "lld/Core/Reader.h"
21 #include "lld/Core/Writer.h"
22 #include "llvm/ADT/STLExtras.h"
23 #include "llvm/ADT/StringExtras.h"
24 #include "llvm/ADT/Triple.h"
25 #include "llvm/BinaryFormat/MachO.h"
26 #include "llvm/Demangle/Demangle.h"
27 #include "llvm/Support/Debug.h"
28 #include "llvm/Support/Errc.h"
29 #include "llvm/Support/Host.h"
30 #include "llvm/Support/Path.h"
33 using lld::mach_o::ArchHandler;
34 using lld::mach_o::MachOFile;
35 using lld::mach_o::MachODylibFile;
36 using namespace llvm::MachO;
40 bool MachOLinkingContext::parsePackedVersion(StringRef str, uint32_t &result) {
46 SmallVector<StringRef, 3> parts;
47 llvm::SplitString(str, parts, ".");
49 unsigned long long num;
50 if (llvm::getAsUnsignedInteger(parts[0], 10, num))
56 if (parts.size() > 1) {
57 if (llvm::getAsUnsignedInteger(parts[1], 10, num))
64 if (parts.size() > 2) {
65 if (llvm::getAsUnsignedInteger(parts[2], 10, num))
75 bool MachOLinkingContext::parsePackedVersion(StringRef str, uint64_t &result) {
81 SmallVector<StringRef, 5> parts;
82 llvm::SplitString(str, parts, ".");
84 unsigned long long num;
85 if (llvm::getAsUnsignedInteger(parts[0], 10, num))
92 for (StringRef str : llvm::makeArrayRef(parts).slice(1)) {
93 if (llvm::getAsUnsignedInteger(str, 10, num))
97 result |= (num << Shift);
104 MachOLinkingContext::ArchInfo MachOLinkingContext::_s_archInfos[] = {
105 { "x86_64", arch_x86_64, true, CPU_TYPE_X86_64, CPU_SUBTYPE_X86_64_ALL },
106 { "i386", arch_x86, true, CPU_TYPE_I386, CPU_SUBTYPE_X86_ALL },
107 { "ppc", arch_ppc, false, CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_ALL },
108 { "armv6", arch_armv6, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V6 },
109 { "armv7", arch_armv7, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7 },
110 { "armv7s", arch_armv7s, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7S },
111 { "arm64", arch_arm64, true, CPU_TYPE_ARM64, CPU_SUBTYPE_ARM64_ALL },
112 { "", arch_unknown,false, 0, 0 }
115 MachOLinkingContext::Arch
116 MachOLinkingContext::archFromCpuType(uint32_t cputype, uint32_t cpusubtype) {
117 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
118 if ((info->cputype == cputype) && (info->cpusubtype == cpusubtype))
124 MachOLinkingContext::Arch
125 MachOLinkingContext::archFromName(StringRef archName) {
126 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
127 if (info->archName.equals(archName))
133 StringRef MachOLinkingContext::nameFromArch(Arch arch) {
134 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
135 if (info->arch == arch)
136 return info->archName;
141 uint32_t MachOLinkingContext::cpuTypeFromArch(Arch arch) {
142 assert(arch != arch_unknown);
143 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
144 if (info->arch == arch)
145 return info->cputype;
147 llvm_unreachable("Unknown arch type");
150 uint32_t MachOLinkingContext::cpuSubtypeFromArch(Arch arch) {
151 assert(arch != arch_unknown);
152 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
153 if (info->arch == arch)
154 return info->cpusubtype;
156 llvm_unreachable("Unknown arch type");
159 bool MachOLinkingContext::isThinObjectFile(StringRef path, Arch &arch) {
160 return mach_o::normalized::isThinObjectFile(path, arch);
163 bool MachOLinkingContext::sliceFromFatFile(MemoryBufferRef mb, uint32_t &offset,
165 return mach_o::normalized::sliceFromFatFile(mb, _arch, offset, size);
168 MachOLinkingContext::MachOLinkingContext() {}
170 MachOLinkingContext::~MachOLinkingContext() {
171 // Atoms are allocated on BumpPtrAllocator's on File's.
172 // As we transfer atoms from one file to another, we need to clear all of the
173 // atoms before we remove any of the BumpPtrAllocator's.
174 auto &nodes = getNodes();
175 for (unsigned i = 0, e = nodes.size(); i != e; ++i) {
176 FileNode *node = dyn_cast<FileNode>(nodes[i].get());
179 File *file = node->getFile();
184 void MachOLinkingContext::configure(HeaderFileType type, Arch arch, OS os,
185 uint32_t minOSVersion,
186 bool exportDynamicSymbols) {
187 _outputMachOType = type;
190 _osMinVersion = minOSVersion;
192 // If min OS not specified on command line, use reasonable defaults.
193 // Note that we only do sensible defaults when emitting something other than
194 // object and preload.
195 if (_outputMachOType != llvm::MachO::MH_OBJECT &&
196 _outputMachOType != llvm::MachO::MH_PRELOAD) {
197 if (minOSVersion == 0) {
201 parsePackedVersion("10.8", _osMinVersion);
202 _os = MachOLinkingContext::OS::macOSX;
208 parsePackedVersion("7.0", _osMinVersion);
209 _os = MachOLinkingContext::OS::iOS;
217 switch (_outputMachOType) {
218 case llvm::MachO::MH_EXECUTE:
219 // If targeting newer OS, use _main
220 if (minOS("10.8", "6.0")) {
221 _entrySymbolName = "_main";
223 // If targeting older OS, use start (in crt1.o)
224 _entrySymbolName = "start";
227 // __PAGEZERO defaults to 4GB on 64-bit (except for PP64 which lld does not
228 // support) and 4KB on 32-bit.
229 if (is64Bit(_arch)) {
230 _pageZeroSize = 0x100000000;
232 _pageZeroSize = 0x1000;
235 // Initial base address is __PAGEZERO size.
236 _baseAddress = _pageZeroSize;
238 // Make PIE by default when targetting newer OSs.
241 if (minOSVersion >= 0x000A0700) // MacOSX 10.7
245 if (minOSVersion >= 0x00040300) // iOS 4.3
248 case OS::iOS_simulator:
254 setGlobalsAreDeadStripRoots(exportDynamicSymbols);
256 case llvm::MachO::MH_DYLIB:
257 setGlobalsAreDeadStripRoots(exportDynamicSymbols);
259 case llvm::MachO::MH_BUNDLE:
261 case llvm::MachO::MH_OBJECT:
262 _printRemainingUndefines = false;
263 _allowRemainingUndefines = true;
269 // Set default segment page sizes based on arch.
270 if (arch == arch_arm64)
274 uint32_t MachOLinkingContext::getCPUType() const {
275 return cpuTypeFromArch(_arch);
278 uint32_t MachOLinkingContext::getCPUSubType() const {
279 return cpuSubtypeFromArch(_arch);
282 bool MachOLinkingContext::is64Bit(Arch arch) {
283 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
284 if (info->arch == arch) {
285 return (info->cputype & CPU_ARCH_ABI64);
288 // unknown archs are not 64-bit.
292 bool MachOLinkingContext::isHostEndian(Arch arch) {
293 assert(arch != arch_unknown);
294 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
295 if (info->arch == arch) {
296 return (info->littleEndian == llvm::sys::IsLittleEndianHost);
299 llvm_unreachable("Unknown arch type");
302 bool MachOLinkingContext::isBigEndian(Arch arch) {
303 assert(arch != arch_unknown);
304 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
305 if (info->arch == arch) {
306 return ! info->littleEndian;
309 llvm_unreachable("Unknown arch type");
312 bool MachOLinkingContext::is64Bit() const {
313 return is64Bit(_arch);
316 bool MachOLinkingContext::outputTypeHasEntry() const {
317 switch (_outputMachOType) {
327 bool MachOLinkingContext::needsStubsPass() const {
328 switch (_outputMachOType) {
330 return !_outputMachOTypeStatic;
339 bool MachOLinkingContext::needsGOTPass() const {
340 // GOT pass not used in -r mode.
341 if (_outputMachOType == MH_OBJECT)
343 // Only some arches use GOT pass.
353 bool MachOLinkingContext::needsCompactUnwindPass() const {
354 switch (_outputMachOType) {
358 return archHandler().needsCompactUnwind();
364 bool MachOLinkingContext::needsObjCPass() const {
365 // ObjC pass is only needed if any of the inputs were ObjC.
366 return _objcConstraint != objc_unknown;
369 bool MachOLinkingContext::needsShimPass() const {
370 // Shim pass only used in final executables.
371 if (_outputMachOType == MH_OBJECT)
373 // Only 32-bit arm arches use Shim pass.
384 bool MachOLinkingContext::needsTLVPass() const {
385 switch (_outputMachOType) {
395 StringRef MachOLinkingContext::binderSymbolName() const {
396 return archHandler().stubInfo().binderSymbolName;
399 bool MachOLinkingContext::minOS(StringRef mac, StringRef iOS) const {
400 uint32_t parsedVersion;
403 if (parsePackedVersion(mac, parsedVersion))
405 return _osMinVersion >= parsedVersion;
407 case OS::iOS_simulator:
408 if (parsePackedVersion(iOS, parsedVersion))
410 return _osMinVersion >= parsedVersion;
412 // If we don't know the target, then assume that we don't meet the min OS.
413 // This matches the ld64 behaviour
416 llvm_unreachable("invalid OS enum");
419 bool MachOLinkingContext::addEntryPointLoadCommand() const {
420 if ((_outputMachOType == MH_EXECUTE) && !_outputMachOTypeStatic) {
421 return minOS("10.8", "6.0");
426 bool MachOLinkingContext::addUnixThreadLoadCommand() const {
427 switch (_outputMachOType) {
429 if (_outputMachOTypeStatic)
432 return !minOS("10.8", "6.0");
442 bool MachOLinkingContext::pathExists(StringRef path) const {
443 if (!_testingFileUsage)
444 return llvm::sys::fs::exists(path.str());
446 // Otherwise, we're in test mode: only files explicitly provided on the
447 // command-line exist.
448 std::string key = path.str();
449 std::replace(key.begin(), key.end(), '\\', '/');
450 return _existingPaths.find(key) != _existingPaths.end();
453 bool MachOLinkingContext::fileExists(StringRef path) const {
454 bool found = pathExists(path);
455 // Log search misses.
457 addInputFileNotFound(path);
459 // When testing, file is never opened, so logging is done here.
460 if (_testingFileUsage && found)
461 addInputFileDependency(path);
466 void MachOLinkingContext::setSysLibRoots(const StringRefVector &paths) {
467 _syslibRoots = paths;
470 void MachOLinkingContext::addRpath(StringRef rpath) {
471 _rpaths.push_back(rpath);
474 void MachOLinkingContext::addModifiedSearchDir(StringRef libPath,
476 bool addedModifiedPath = false;
478 // -syslibroot only applies to absolute paths.
479 if (libPath.startswith("/")) {
480 for (auto syslibRoot : _syslibRoots) {
481 SmallString<256> path(syslibRoot);
482 llvm::sys::path::append(path, libPath);
483 if (pathExists(path)) {
484 _searchDirs.push_back(path.str().copy(_allocator));
485 addedModifiedPath = true;
490 if (addedModifiedPath)
493 // Finally, if only one -syslibroot is given, system paths which aren't in it
495 if (_syslibRoots.size() != 1 || !isSystemPath) {
496 if (pathExists(libPath)) {
497 _searchDirs.push_back(libPath);
502 void MachOLinkingContext::addFrameworkSearchDir(StringRef fwPath,
504 bool pathAdded = false;
506 // -syslibroot only used with to absolute framework search paths.
507 if (fwPath.startswith("/")) {
508 for (auto syslibRoot : _syslibRoots) {
509 SmallString<256> path(syslibRoot);
510 llvm::sys::path::append(path, fwPath);
511 if (pathExists(path)) {
512 _frameworkDirs.push_back(path.str().copy(_allocator));
517 // If fwPath found in any -syslibroot, then done.
521 // If only one -syslibroot, system paths not in that SDK are suppressed.
522 if (isSystemPath && (_syslibRoots.size() == 1))
525 // Only use raw fwPath if that directory exists.
526 if (pathExists(fwPath))
527 _frameworkDirs.push_back(fwPath);
530 llvm::Optional<StringRef>
531 MachOLinkingContext::searchDirForLibrary(StringRef path,
532 StringRef libName) const {
533 SmallString<256> fullPath;
534 if (libName.endswith(".o")) {
535 // A request ending in .o is special: just search for the file directly.
536 fullPath.assign(path);
537 llvm::sys::path::append(fullPath, libName);
538 if (fileExists(fullPath))
539 return fullPath.str().copy(_allocator);
543 // Search for dynamic library
544 fullPath.assign(path);
545 llvm::sys::path::append(fullPath, Twine("lib") + libName + ".dylib");
546 if (fileExists(fullPath))
547 return fullPath.str().copy(_allocator);
549 // If not, try for a static library
550 fullPath.assign(path);
551 llvm::sys::path::append(fullPath, Twine("lib") + libName + ".a");
552 if (fileExists(fullPath))
553 return fullPath.str().copy(_allocator);
558 llvm::Optional<StringRef>
559 MachOLinkingContext::searchLibrary(StringRef libName) const {
560 SmallString<256> path;
561 for (StringRef dir : searchDirs()) {
562 llvm::Optional<StringRef> searchDir = searchDirForLibrary(dir, libName);
570 llvm::Optional<StringRef>
571 MachOLinkingContext::findPathForFramework(StringRef fwName) const{
572 SmallString<256> fullPath;
573 for (StringRef dir : frameworkDirs()) {
574 fullPath.assign(dir);
575 llvm::sys::path::append(fullPath, Twine(fwName) + ".framework", fwName);
576 if (fileExists(fullPath))
577 return fullPath.str().copy(_allocator);
583 bool MachOLinkingContext::validateImpl() {
584 // TODO: if -arch not specified, look at arch of first .o file.
586 if (_currentVersion && _outputMachOType != MH_DYLIB) {
587 error("-current_version can only be used with dylibs");
591 if (_compatibilityVersion && _outputMachOType != MH_DYLIB) {
592 error("-compatibility_version can only be used with dylibs");
596 if (_deadStrippableDylib && _outputMachOType != MH_DYLIB) {
597 error("-mark_dead_strippable_dylib can only be used with dylibs");
601 if (!_bundleLoader.empty() && outputMachOType() != MH_BUNDLE) {
602 error("-bundle_loader can only be used with Mach-O bundles");
606 // If -exported_symbols_list used, all exported symbols must be defined.
607 if (_exportMode == ExportMode::whiteList) {
608 for (const auto &symbol : _exportedSymbols)
609 addInitialUndefinedSymbol(symbol.getKey());
612 // If -dead_strip, set up initial live symbols.
614 // Entry point is live.
615 if (outputTypeHasEntry())
616 addDeadStripRoot(entrySymbolName());
617 // Lazy binding helper is live.
618 if (needsStubsPass())
619 addDeadStripRoot(binderSymbolName());
620 // If using -exported_symbols_list, make all exported symbols live.
621 if (_exportMode == ExportMode::whiteList) {
622 setGlobalsAreDeadStripRoots(false);
623 for (const auto &symbol : _exportedSymbols)
624 addDeadStripRoot(symbol.getKey());
628 addOutputFileDependency(outputPath());
633 void MachOLinkingContext::addPasses(PassManager &pm) {
634 // objc pass should be before layout pass. Otherwise test cases may contain
635 // no atoms which confuses the layout pass.
637 mach_o::addObjCPass(pm, *this);
638 mach_o::addLayoutPass(pm, *this);
639 if (needsStubsPass())
640 mach_o::addStubsPass(pm, *this);
641 if (needsCompactUnwindPass())
642 mach_o::addCompactUnwindPass(pm, *this);
644 mach_o::addGOTPass(pm, *this);
646 mach_o::addTLVPass(pm, *this);
648 mach_o::addShimPass(pm, *this); // Shim pass must run after stubs pass.
651 Writer &MachOLinkingContext::writer() const {
653 _writer = createWriterMachO(*this);
657 ErrorOr<std::unique_ptr<MemoryBuffer>>
658 MachOLinkingContext::getMemoryBuffer(StringRef path) {
659 addInputFileDependency(path);
661 ErrorOr<std::unique_ptr<MemoryBuffer>> mbOrErr =
662 MemoryBuffer::getFileOrSTDIN(path);
663 if (std::error_code ec = mbOrErr.getError())
665 std::unique_ptr<MemoryBuffer> mb = std::move(mbOrErr.get());
667 // If buffer contains a fat file, find required arch in fat buffer
668 // and switch buffer to point to just that required slice.
671 if (sliceFromFatFile(mb->getMemBufferRef(), offset, size))
672 return MemoryBuffer::getFileSlice(path, size, offset);
673 return std::move(mb);
676 MachODylibFile* MachOLinkingContext::loadIndirectDylib(StringRef path) {
677 ErrorOr<std::unique_ptr<MemoryBuffer>> mbOrErr = getMemoryBuffer(path);
678 if (mbOrErr.getError())
681 ErrorOr<std::unique_ptr<File>> fileOrErr =
682 registry().loadFile(std::move(mbOrErr.get()));
685 std::unique_ptr<File> &file = fileOrErr.get();
687 MachODylibFile *result = reinterpret_cast<MachODylibFile *>(file.get());
688 // Node object now owned by _indirectDylibs vector.
689 _indirectDylibs.push_back(std::move(file));
693 MachODylibFile* MachOLinkingContext::findIndirectDylib(StringRef path) {
694 // See if already loaded.
695 auto pos = _pathToDylibMap.find(path);
696 if (pos != _pathToDylibMap.end())
699 // Search -L paths if of the form "libXXX.dylib"
700 std::pair<StringRef, StringRef> split = path.rsplit('/');
701 StringRef leafName = split.second;
702 if (leafName.startswith("lib") && leafName.endswith(".dylib")) {
703 // FIXME: Need to enhance searchLibrary() to only look for .dylib
704 auto libPath = searchLibrary(leafName);
706 return loadIndirectDylib(libPath.getValue());
709 // Try full path with sysroot.
710 for (StringRef sysPath : _syslibRoots) {
711 SmallString<256> fullPath;
712 fullPath.assign(sysPath);
713 llvm::sys::path::append(fullPath, path);
714 if (pathExists(fullPath))
715 return loadIndirectDylib(fullPath);
719 if (pathExists(path)) {
720 return loadIndirectDylib(path);
726 uint32_t MachOLinkingContext::dylibCurrentVersion(StringRef installName) const {
727 auto pos = _pathToDylibMap.find(installName);
728 if (pos != _pathToDylibMap.end())
729 return pos->second->currentVersion();
731 return 0x10000; // 1.0
734 uint32_t MachOLinkingContext::dylibCompatVersion(StringRef installName) const {
735 auto pos = _pathToDylibMap.find(installName);
736 if (pos != _pathToDylibMap.end())
737 return pos->second->compatVersion();
739 return 0x10000; // 1.0
742 void MachOLinkingContext::createImplicitFiles(
743 std::vector<std::unique_ptr<File> > &result) {
744 // Add indirect dylibs by asking each linked dylib to add its indirects.
745 // Iterate until no more dylibs get loaded.
746 size_t dylibCount = 0;
747 while (dylibCount != _allDylibs.size()) {
748 dylibCount = _allDylibs.size();
749 for (MachODylibFile *dylib : _allDylibs) {
750 dylib->loadReExportedDylibs([this] (StringRef path) -> MachODylibFile* {
751 return findIndirectDylib(path); });
755 // Let writer add output type specific extras.
756 writer().createImplicitFiles(result);
758 // If undefinedMode is != error, add a FlatNamespaceFile instance. This will
759 // provide a SharedLibraryAtom for symbols that aren't defined elsewhere.
760 if (undefinedMode() != UndefinedMode::error) {
761 result.emplace_back(new mach_o::FlatNamespaceFile(*this));
762 _flatNamespaceFile = result.back().get();
766 void MachOLinkingContext::registerDylib(MachODylibFile *dylib,
768 std::lock_guard<std::mutex> lock(_dylibsMutex);
770 if (!llvm::count(_allDylibs, dylib))
771 _allDylibs.push_back(dylib);
772 _pathToDylibMap[dylib->installName()] = dylib;
773 // If path is different than install name, register path too.
774 if (!dylib->path().equals(dylib->installName()))
775 _pathToDylibMap[dylib->path()] = dylib;
777 _upwardDylibs.insert(dylib);
780 bool MachOLinkingContext::isUpwardDylib(StringRef installName) const {
781 for (MachODylibFile *dylib : _upwardDylibs) {
782 if (dylib->installName().equals(installName))
788 ArchHandler &MachOLinkingContext::archHandler() const {
790 _archHandler = ArchHandler::create(_arch);
791 return *_archHandler;
794 void MachOLinkingContext::addSectionAlignment(StringRef seg, StringRef sect,
796 SectionAlign entry = { seg, sect, align };
797 _sectAligns.push_back(entry);
800 void MachOLinkingContext::addSectCreateSection(
801 StringRef seg, StringRef sect,
802 std::unique_ptr<MemoryBuffer> content) {
804 if (!_sectCreateFile) {
805 auto sectCreateFile = std::make_unique<mach_o::SectCreateFile>();
806 _sectCreateFile = sectCreateFile.get();
807 getNodes().push_back(std::make_unique<FileNode>(std::move(sectCreateFile)));
810 assert(_sectCreateFile && "sectcreate file does not exist.");
811 _sectCreateFile->addSection(seg, sect, std::move(content));
814 bool MachOLinkingContext::sectionAligned(StringRef seg, StringRef sect,
815 uint16_t &align) const {
816 for (const SectionAlign &entry : _sectAligns) {
817 if (seg.equals(entry.segmentName) && sect.equals(entry.sectionName)) {
825 void MachOLinkingContext::addExportSymbol(StringRef sym) {
826 // Support old crufty export lists with bogus entries.
827 if (sym.endswith(".eh") || sym.startswith(".objc_category_name_")) {
828 llvm::errs() << "warning: ignoring " << sym << " in export list\n";
831 // Only i386 MacOSX uses old ABI, so don't change those.
832 if ((_os != OS::macOSX) || (_arch != arch_x86)) {
833 // ObjC has two different ABIs. Be nice and allow one export list work for
834 // both ABIs by renaming symbols.
835 if (sym.startswith(".objc_class_name_")) {
836 std::string abi2className("_OBJC_CLASS_$_");
837 abi2className += sym.substr(17);
838 _exportedSymbols.insert(copy(abi2className));
839 std::string abi2metaclassName("_OBJC_METACLASS_$_");
840 abi2metaclassName += sym.substr(17);
841 _exportedSymbols.insert(copy(abi2metaclassName));
846 // FIXME: Support wildcards.
847 _exportedSymbols.insert(sym);
850 bool MachOLinkingContext::exportSymbolNamed(StringRef sym) const {
851 switch (_exportMode) {
852 case ExportMode::globals:
853 llvm_unreachable("exportSymbolNamed() should not be called in this mode");
855 case ExportMode::whiteList:
856 return _exportedSymbols.count(sym);
857 case ExportMode::blackList:
858 return !_exportedSymbols.count(sym);
860 llvm_unreachable("_exportMode unknown enum value");
863 std::string MachOLinkingContext::demangle(StringRef symbolName) const {
864 // Only try to demangle symbols if -demangle on command line
865 if (!demangleSymbols())
868 // Only try to demangle symbols that look like C++ symbols
869 if (!symbolName.startswith("__Z"))
872 SmallString<256> symBuff;
873 StringRef nullTermSym = Twine(symbolName).toNullTerminatedStringRef(symBuff);
874 // Mach-O has extra leading underscore that needs to be removed.
875 const char *cstr = nullTermSym.data() + 1;
877 char *demangled = llvm::itaniumDemangle(cstr, nullptr, nullptr, &status);
879 std::string result(demangled);
880 // __cxa_demangle() always uses a malloc'ed buffer to return the result.
888 static void addDependencyInfoHelper(llvm::raw_fd_ostream *DepInfo,
889 char Opcode, StringRef Path) {
898 std::error_code MachOLinkingContext::createDependencyFile(StringRef path) {
900 _dependencyInfo = std::unique_ptr<llvm::raw_fd_ostream>(
901 new llvm::raw_fd_ostream(path, ec, llvm::sys::fs::OF_None));
903 _dependencyInfo.reset();
907 addDependencyInfoHelper(_dependencyInfo.get(), 0x00, "lld" /*FIXME*/);
908 return std::error_code();
911 void MachOLinkingContext::addInputFileDependency(StringRef path) const {
912 addDependencyInfoHelper(_dependencyInfo.get(), 0x10, path);
915 void MachOLinkingContext::addInputFileNotFound(StringRef path) const {
916 addDependencyInfoHelper(_dependencyInfo.get(), 0x11, path);
919 void MachOLinkingContext::addOutputFileDependency(StringRef path) const {
920 addDependencyInfoHelper(_dependencyInfo.get(), 0x40, path);
923 void MachOLinkingContext::appendOrderedSymbol(StringRef symbol,
924 StringRef filename) {
925 // To support sorting static functions which may have the same name in
926 // multiple .o files, _orderFiles maps the symbol name to a vector
927 // of OrderFileNode each of which can specify a file prefix.
929 if (!filename.empty())
930 info.fileFilter = copy(filename);
931 info.order = _orderFileEntries++;
932 _orderFiles[symbol].push_back(info);
936 MachOLinkingContext::findOrderOrdinal(const std::vector<OrderFileNode> &nodes,
937 const DefinedAtom *atom,
939 const File *objFile = &atom->file();
941 StringRef objName = objFile->path();
942 std::pair<StringRef, StringRef> dirAndLeaf = objName.rsplit('/');
943 if (!dirAndLeaf.second.empty())
944 objName = dirAndLeaf.second;
945 for (const OrderFileNode &info : nodes) {
946 if (info.fileFilter.empty()) {
947 // Have unprefixed symbol name in order file that matches this atom.
948 ordinal = info.order;
951 if (info.fileFilter.equals(objName)) {
952 // Have prefixed symbol name in order file that matches atom's path.
953 ordinal = info.order;
960 bool MachOLinkingContext::customAtomOrderer(const DefinedAtom *left,
961 const DefinedAtom *right,
962 bool &leftBeforeRight) const {
963 // No custom sorting if no order file entries.
964 if (!_orderFileEntries)
967 // Order files can only order named atoms.
968 StringRef leftName = left->name();
969 StringRef rightName = right->name();
970 if (leftName.empty() || rightName.empty())
973 // If neither is in order file list, no custom sorter.
974 auto leftPos = _orderFiles.find(leftName);
975 auto rightPos = _orderFiles.find(rightName);
976 bool leftIsOrdered = (leftPos != _orderFiles.end());
977 bool rightIsOrdered = (rightPos != _orderFiles.end());
978 if (!leftIsOrdered && !rightIsOrdered)
981 // There could be multiple symbols with same name but different file prefixes.
985 leftIsOrdered && findOrderOrdinal(leftPos->getValue(), left, leftOrder);
986 bool foundRight = rightIsOrdered &&
987 findOrderOrdinal(rightPos->getValue(), right, rightOrder);
988 if (!foundLeft && !foundRight)
991 // If only one is in order file list, ordered one goes first.
992 if (foundLeft != foundRight)
993 leftBeforeRight = foundLeft;
995 leftBeforeRight = (leftOrder < rightOrder);
1000 static bool isLibrary(const std::unique_ptr<Node> &elem) {
1001 if (FileNode *node = dyn_cast<FileNode>(const_cast<Node *>(elem.get()))) {
1002 File *file = node->getFile();
1003 return isa<SharedLibraryFile>(file) || isa<ArchiveLibraryFile>(file);
1008 // The darwin linker processes input files in two phases. The first phase
1009 // links in all object (.o) files in command line order. The second phase
1010 // links in libraries in command line order.
1011 // In this function we reorder the input files so that all the object files
1012 // comes before any library file. We also make a group for the library files
1013 // so that the Resolver will reiterate over the libraries as long as we find
1014 // new undefines from libraries.
1015 void MachOLinkingContext::finalizeInputFiles() {
1016 std::vector<std::unique_ptr<Node>> &elements = getNodes();
1017 llvm::stable_sort(elements, [](const std::unique_ptr<Node> &a,
1018 const std::unique_ptr<Node> &b) {
1019 return !isLibrary(a) && isLibrary(b);
1021 size_t numLibs = std::count_if(elements.begin(), elements.end(), isLibrary);
1022 elements.push_back(std::make_unique<GroupEnd>(numLibs));
1025 llvm::Error MachOLinkingContext::handleLoadedFile(File &file) {
1026 auto *machoFile = dyn_cast<MachOFile>(&file);
1028 return llvm::Error::success();
1030 // Check that the arch of the context matches that of the file.
1031 // Also set the arch of the context if it didn't have one.
1032 if (_arch == arch_unknown) {
1033 _arch = machoFile->arch();
1034 } else if (machoFile->arch() != arch_unknown && machoFile->arch() != _arch) {
1035 // Archs are different.
1036 return llvm::make_error<GenericError>(file.path() +
1037 Twine(" cannot be linked due to incompatible architecture"));
1040 // Check that the OS of the context matches that of the file.
1041 // Also set the OS of the context if it didn't have one.
1042 if (_os == OS::unknown) {
1043 _os = machoFile->OS();
1044 } else if (machoFile->OS() != OS::unknown && machoFile->OS() != _os) {
1045 // OSes are different.
1046 return llvm::make_error<GenericError>(file.path() +
1047 Twine(" cannot be linked due to incompatible operating systems"));
1050 // Check that if the objc info exists, that it is compatible with the target
1052 switch (machoFile->objcConstraint()) {
1054 // The file is not compiled with objc, so skip the checks.
1057 case objc_supports_gc:
1058 llvm_unreachable("GC support should already have thrown an error");
1059 case objc_retainReleaseForSimulator:
1060 // The file is built with simulator objc, so make sure that the context
1061 // is also building with simulator support.
1062 if (_os != OS::iOS_simulator)
1063 return llvm::make_error<GenericError>(file.path() +
1064 Twine(" cannot be linked. It contains ObjC built for the simulator"
1065 " while we are linking a non-simulator target"));
1066 assert((_objcConstraint == objc_unknown ||
1067 _objcConstraint == objc_retainReleaseForSimulator) &&
1068 "Must be linking with retain/release for the simulator");
1069 _objcConstraint = objc_retainReleaseForSimulator;
1071 case objc_retainRelease:
1072 // The file is built without simulator objc, so make sure that the
1073 // context is also building without simulator support.
1074 if (_os == OS::iOS_simulator)
1075 return llvm::make_error<GenericError>(file.path() +
1076 Twine(" cannot be linked. It contains ObjC built for a non-simulator"
1077 " target while we are linking a simulator target"));
1078 assert((_objcConstraint == objc_unknown ||
1079 _objcConstraint == objc_retainRelease) &&
1080 "Must be linking with retain/release for a non-simulator target");
1081 _objcConstraint = objc_retainRelease;
1085 // Check that the swift version of the context matches that of the file.
1086 // Also set the swift version of the context if it didn't have one.
1087 if (!_swiftVersion) {
1088 _swiftVersion = machoFile->swiftVersion();
1089 } else if (machoFile->swiftVersion() &&
1090 machoFile->swiftVersion() != _swiftVersion) {
1091 // Swift versions are different.
1092 return llvm::make_error<GenericError>("different swift versions");
1095 return llvm::Error::success();
1098 } // end namespace lld