• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- lib/ReaderWriter/MachO/MachOLinkingContext.cpp ---------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "lld/Common/ErrorHandler.h"
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/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"
31 #include <algorithm>
32 
33 using lld::mach_o::ArchHandler;
34 using lld::mach_o::MachOFile;
35 using lld::mach_o::MachODylibFile;
36 using namespace llvm::MachO;
37 
38 namespace lld {
39 
parsePackedVersion(StringRef str,uint32_t & result)40 bool MachOLinkingContext::parsePackedVersion(StringRef str, uint32_t &result) {
41   result = 0;
42 
43   if (str.empty())
44     return false;
45 
46   SmallVector<StringRef, 3> parts;
47   llvm::SplitString(str, parts, ".");
48 
49   unsigned long long num;
50   if (llvm::getAsUnsignedInteger(parts[0], 10, num))
51     return true;
52   if (num > 65535)
53     return true;
54   result = num << 16;
55 
56   if (parts.size() > 1) {
57     if (llvm::getAsUnsignedInteger(parts[1], 10, num))
58       return true;
59     if (num > 255)
60       return true;
61     result |= (num << 8);
62   }
63 
64   if (parts.size() > 2) {
65     if (llvm::getAsUnsignedInteger(parts[2], 10, num))
66       return true;
67     if (num > 255)
68       return true;
69     result |= num;
70   }
71 
72   return false;
73 }
74 
parsePackedVersion(StringRef str,uint64_t & result)75 bool MachOLinkingContext::parsePackedVersion(StringRef str, uint64_t &result) {
76   result = 0;
77 
78   if (str.empty())
79     return false;
80 
81   SmallVector<StringRef, 5> parts;
82   llvm::SplitString(str, parts, ".");
83 
84   unsigned long long num;
85   if (llvm::getAsUnsignedInteger(parts[0], 10, num))
86     return true;
87   if (num > 0xFFFFFF)
88     return true;
89   result = num << 40;
90 
91   unsigned Shift = 30;
92   for (StringRef str : llvm::makeArrayRef(parts).slice(1)) {
93     if (llvm::getAsUnsignedInteger(str, 10, num))
94       return true;
95     if (num > 0x3FF)
96       return true;
97     result |= (num << Shift);
98     Shift -= 10;
99   }
100 
101   return false;
102 }
103 
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 }
113 };
114 
115 MachOLinkingContext::Arch
archFromCpuType(uint32_t cputype,uint32_t cpusubtype)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))
119       return info->arch;
120   }
121   return arch_unknown;
122 }
123 
124 MachOLinkingContext::Arch
archFromName(StringRef archName)125 MachOLinkingContext::archFromName(StringRef archName) {
126   for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
127     if (info->archName.equals(archName))
128       return info->arch;
129   }
130   return arch_unknown;
131 }
132 
nameFromArch(Arch arch)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;
137   }
138   return "<unknown>";
139 }
140 
cpuTypeFromArch(Arch arch)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;
146   }
147   llvm_unreachable("Unknown arch type");
148 }
149 
cpuSubtypeFromArch(Arch arch)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;
155   }
156   llvm_unreachable("Unknown arch type");
157 }
158 
isThinObjectFile(StringRef path,Arch & arch)159 bool MachOLinkingContext::isThinObjectFile(StringRef path, Arch &arch) {
160   return mach_o::normalized::isThinObjectFile(path, arch);
161 }
162 
sliceFromFatFile(MemoryBufferRef mb,uint32_t & offset,uint32_t & size)163 bool MachOLinkingContext::sliceFromFatFile(MemoryBufferRef mb, uint32_t &offset,
164                                            uint32_t &size) {
165   return mach_o::normalized::sliceFromFatFile(mb, _arch, offset, size);
166 }
167 
MachOLinkingContext()168 MachOLinkingContext::MachOLinkingContext() {}
169 
~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());
177     if (!node)
178       continue;
179     File *file = node->getFile();
180     file->clearAtoms();
181   }
182 }
183 
configure(HeaderFileType type,Arch arch,OS os,uint32_t minOSVersion,bool exportDynamicSymbols)184 void MachOLinkingContext::configure(HeaderFileType type, Arch arch, OS os,
185                                     uint32_t minOSVersion,
186                                     bool exportDynamicSymbols) {
187   _outputMachOType = type;
188   _arch = arch;
189   _os = os;
190   _osMinVersion = minOSVersion;
191 
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) {
198       switch (_arch) {
199       case arch_x86_64:
200       case arch_x86:
201         parsePackedVersion("10.8", _osMinVersion);
202         _os = MachOLinkingContext::OS::macOSX;
203         break;
204       case arch_armv6:
205       case arch_armv7:
206       case arch_armv7s:
207       case arch_arm64:
208         parsePackedVersion("7.0", _osMinVersion);
209         _os = MachOLinkingContext::OS::iOS;
210         break;
211       default:
212         break;
213       }
214     }
215   }
216 
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";
222     } else {
223       // If targeting older OS, use start (in crt1.o)
224       _entrySymbolName = "start";
225     }
226 
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;
231     } else {
232       _pageZeroSize = 0x1000;
233     }
234 
235     // Initial base address is __PAGEZERO size.
236     _baseAddress = _pageZeroSize;
237 
238     // Make PIE by default when targetting newer OSs.
239     switch (os) {
240       case OS::macOSX:
241         if (minOSVersion >= 0x000A0700) // MacOSX 10.7
242           _pie = true;
243         break;
244       case OS::iOS:
245         if (minOSVersion >= 0x00040300) // iOS 4.3
246           _pie = true;
247        break;
248        case OS::iOS_simulator:
249         _pie = true;
250        break;
251        case OS::unknown:
252        break;
253     }
254     setGlobalsAreDeadStripRoots(exportDynamicSymbols);
255     break;
256   case llvm::MachO::MH_DYLIB:
257     setGlobalsAreDeadStripRoots(exportDynamicSymbols);
258     break;
259   case llvm::MachO::MH_BUNDLE:
260     break;
261   case llvm::MachO::MH_OBJECT:
262     _printRemainingUndefines = false;
263     _allowRemainingUndefines = true;
264     break;
265   default:
266     break;
267   }
268 
269   // Set default segment page sizes based on arch.
270   if (arch == arch_arm64)
271     _pageSize = 4*4096;
272 }
273 
getCPUType() const274 uint32_t MachOLinkingContext::getCPUType() const {
275   return cpuTypeFromArch(_arch);
276 }
277 
getCPUSubType() const278 uint32_t MachOLinkingContext::getCPUSubType() const {
279   return cpuSubtypeFromArch(_arch);
280 }
281 
is64Bit(Arch 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);
286     }
287   }
288   // unknown archs are not 64-bit.
289   return false;
290 }
291 
isHostEndian(Arch arch)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);
297     }
298   }
299   llvm_unreachable("Unknown arch type");
300 }
301 
isBigEndian(Arch arch)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;
307     }
308   }
309   llvm_unreachable("Unknown arch type");
310 }
311 
is64Bit() const312 bool MachOLinkingContext::is64Bit() const {
313   return is64Bit(_arch);
314 }
315 
outputTypeHasEntry() const316 bool MachOLinkingContext::outputTypeHasEntry() const {
317   switch (_outputMachOType) {
318   case MH_EXECUTE:
319   case MH_DYLINKER:
320   case MH_PRELOAD:
321     return true;
322   default:
323     return false;
324   }
325 }
326 
needsStubsPass() const327 bool MachOLinkingContext::needsStubsPass() const {
328   switch (_outputMachOType) {
329   case MH_EXECUTE:
330     return !_outputMachOTypeStatic;
331   case MH_DYLIB:
332   case MH_BUNDLE:
333     return true;
334   default:
335     return false;
336   }
337 }
338 
needsGOTPass() const339 bool MachOLinkingContext::needsGOTPass() const {
340   // GOT pass not used in -r mode.
341   if (_outputMachOType == MH_OBJECT)
342     return false;
343   // Only some arches use GOT pass.
344   switch (_arch) {
345     case arch_x86_64:
346     case arch_arm64:
347       return true;
348     default:
349       return false;
350   }
351 }
352 
needsCompactUnwindPass() const353 bool MachOLinkingContext::needsCompactUnwindPass() const {
354   switch (_outputMachOType) {
355   case MH_EXECUTE:
356   case MH_DYLIB:
357   case MH_BUNDLE:
358     return archHandler().needsCompactUnwind();
359   default:
360     return false;
361   }
362 }
363 
needsObjCPass() const364 bool MachOLinkingContext::needsObjCPass() const {
365   // ObjC pass is only needed if any of the inputs were ObjC.
366   return _objcConstraint != objc_unknown;
367 }
368 
needsShimPass() const369 bool MachOLinkingContext::needsShimPass() const {
370   // Shim pass only used in final executables.
371   if (_outputMachOType == MH_OBJECT)
372     return false;
373   // Only 32-bit arm arches use Shim pass.
374   switch (_arch) {
375   case arch_armv6:
376   case arch_armv7:
377   case arch_armv7s:
378     return true;
379   default:
380     return false;
381   }
382 }
383 
needsTLVPass() const384 bool MachOLinkingContext::needsTLVPass() const {
385   switch (_outputMachOType) {
386   case MH_BUNDLE:
387   case MH_EXECUTE:
388   case MH_DYLIB:
389     return true;
390   default:
391     return false;
392   }
393 }
394 
binderSymbolName() const395 StringRef MachOLinkingContext::binderSymbolName() const {
396   return archHandler().stubInfo().binderSymbolName;
397 }
398 
minOS(StringRef mac,StringRef iOS) const399 bool MachOLinkingContext::minOS(StringRef mac, StringRef iOS) const {
400   uint32_t parsedVersion;
401   switch (_os) {
402   case OS::macOSX:
403     if (parsePackedVersion(mac, parsedVersion))
404       return false;
405     return _osMinVersion >= parsedVersion;
406   case OS::iOS:
407   case OS::iOS_simulator:
408     if (parsePackedVersion(iOS, parsedVersion))
409       return false;
410     return _osMinVersion >= parsedVersion;
411   case OS::unknown:
412     // If we don't know the target, then assume that we don't meet the min OS.
413     // This matches the ld64 behaviour
414     return false;
415   }
416   llvm_unreachable("invalid OS enum");
417 }
418 
addEntryPointLoadCommand() const419 bool MachOLinkingContext::addEntryPointLoadCommand() const {
420   if ((_outputMachOType == MH_EXECUTE) && !_outputMachOTypeStatic) {
421     return minOS("10.8", "6.0");
422   }
423   return false;
424 }
425 
addUnixThreadLoadCommand() const426 bool MachOLinkingContext::addUnixThreadLoadCommand() const {
427   switch (_outputMachOType) {
428   case MH_EXECUTE:
429     if (_outputMachOTypeStatic)
430       return true;
431     else
432       return !minOS("10.8", "6.0");
433     break;
434   case MH_DYLINKER:
435   case MH_PRELOAD:
436     return true;
437   default:
438     return false;
439   }
440 }
441 
pathExists(StringRef path) const442 bool MachOLinkingContext::pathExists(StringRef path) const {
443   if (!_testingFileUsage)
444     return llvm::sys::fs::exists(path.str());
445 
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();
451 }
452 
fileExists(StringRef path) const453 bool MachOLinkingContext::fileExists(StringRef path) const {
454   bool found = pathExists(path);
455   // Log search misses.
456   if (!found)
457     addInputFileNotFound(path);
458 
459   // When testing, file is never opened, so logging is done here.
460   if (_testingFileUsage && found)
461     addInputFileDependency(path);
462 
463   return found;
464 }
465 
setSysLibRoots(const StringRefVector & paths)466 void MachOLinkingContext::setSysLibRoots(const StringRefVector &paths) {
467   _syslibRoots = paths;
468 }
469 
addRpath(StringRef rpath)470 void MachOLinkingContext::addRpath(StringRef rpath) {
471   _rpaths.push_back(rpath);
472 }
473 
addModifiedSearchDir(StringRef libPath,bool isSystemPath)474 void MachOLinkingContext::addModifiedSearchDir(StringRef libPath,
475                                                bool isSystemPath) {
476   bool addedModifiedPath = false;
477 
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;
486       }
487     }
488   }
489 
490   if (addedModifiedPath)
491     return;
492 
493   // Finally, if only one -syslibroot is given, system paths which aren't in it
494   // get suppressed.
495   if (_syslibRoots.size() != 1 || !isSystemPath) {
496     if (pathExists(libPath)) {
497       _searchDirs.push_back(libPath);
498     }
499   }
500 }
501 
addFrameworkSearchDir(StringRef fwPath,bool isSystemPath)502 void MachOLinkingContext::addFrameworkSearchDir(StringRef fwPath,
503                                                 bool isSystemPath) {
504   bool pathAdded = false;
505 
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));
513         pathAdded = true;
514       }
515     }
516   }
517   // If fwPath found in any -syslibroot, then done.
518   if (pathAdded)
519     return;
520 
521   // If only one -syslibroot, system paths not in that SDK are suppressed.
522   if (isSystemPath && (_syslibRoots.size() == 1))
523     return;
524 
525   // Only use raw fwPath if that directory exists.
526   if (pathExists(fwPath))
527     _frameworkDirs.push_back(fwPath);
528 }
529 
530 llvm::Optional<StringRef>
searchDirForLibrary(StringRef path,StringRef libName) const531 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);
540     return llvm::None;
541   }
542 
543   // Search for stub library
544   fullPath.assign(path);
545   llvm::sys::path::append(fullPath, Twine("lib") + libName + ".tbd");
546   if (fileExists(fullPath))
547     return fullPath.str().copy(_allocator);
548 
549   // Search for dynamic library
550   fullPath.assign(path);
551   llvm::sys::path::append(fullPath, Twine("lib") + libName + ".dylib");
552   if (fileExists(fullPath))
553     return fullPath.str().copy(_allocator);
554 
555   // If not, try for a static library
556   fullPath.assign(path);
557   llvm::sys::path::append(fullPath, Twine("lib") + libName + ".a");
558   if (fileExists(fullPath))
559     return fullPath.str().copy(_allocator);
560 
561   return llvm::None;
562 }
563 
564 llvm::Optional<StringRef>
searchLibrary(StringRef libName) const565 MachOLinkingContext::searchLibrary(StringRef libName) const {
566   SmallString<256> path;
567   for (StringRef dir : searchDirs()) {
568     llvm::Optional<StringRef> searchDir = searchDirForLibrary(dir, libName);
569     if (searchDir)
570       return searchDir;
571   }
572 
573   return llvm::None;
574 }
575 
576 llvm::Optional<StringRef>
findPathForFramework(StringRef fwName) const577 MachOLinkingContext::findPathForFramework(StringRef fwName) const{
578   SmallString<256> fullPath;
579   for (StringRef dir : frameworkDirs()) {
580     fullPath.assign(dir);
581     llvm::sys::path::append(fullPath, Twine(fwName) + ".framework", fwName);
582     if (fileExists(fullPath))
583       return fullPath.str().copy(_allocator);
584   }
585 
586   return llvm::None;
587 }
588 
validateImpl()589 bool MachOLinkingContext::validateImpl() {
590   // TODO: if -arch not specified, look at arch of first .o file.
591 
592   if (_currentVersion && _outputMachOType != MH_DYLIB) {
593     error("-current_version can only be used with dylibs");
594     return false;
595   }
596 
597   if (_compatibilityVersion && _outputMachOType != MH_DYLIB) {
598     error("-compatibility_version can only be used with dylibs");
599     return false;
600   }
601 
602   if (_deadStrippableDylib && _outputMachOType != MH_DYLIB) {
603     error("-mark_dead_strippable_dylib can only be used with dylibs");
604     return false;
605   }
606 
607   if (!_bundleLoader.empty() && outputMachOType() != MH_BUNDLE) {
608     error("-bundle_loader can only be used with Mach-O bundles");
609     return false;
610   }
611 
612   // If -exported_symbols_list used, all exported symbols must be defined.
613   if (_exportMode == ExportMode::exported) {
614     for (const auto &symbol : _exportedSymbols)
615       addInitialUndefinedSymbol(symbol.getKey());
616   }
617 
618   // If -dead_strip, set up initial live symbols.
619   if (deadStrip()) {
620     // Entry point is live.
621     if (outputTypeHasEntry())
622       addDeadStripRoot(entrySymbolName());
623     // Lazy binding helper is live.
624     if (needsStubsPass())
625       addDeadStripRoot(binderSymbolName());
626     // If using -exported_symbols_list, make all exported symbols live.
627     if (_exportMode == ExportMode::exported) {
628       setGlobalsAreDeadStripRoots(false);
629       for (const auto &symbol : _exportedSymbols)
630         addDeadStripRoot(symbol.getKey());
631     }
632   }
633 
634   addOutputFileDependency(outputPath());
635 
636   return true;
637 }
638 
addPasses(PassManager & pm)639 void MachOLinkingContext::addPasses(PassManager &pm) {
640   // objc pass should be before layout pass.  Otherwise test cases may contain
641   // no atoms which confuses the layout pass.
642   if (needsObjCPass())
643     mach_o::addObjCPass(pm, *this);
644   mach_o::addLayoutPass(pm, *this);
645   if (needsStubsPass())
646     mach_o::addStubsPass(pm, *this);
647   if (needsCompactUnwindPass())
648     mach_o::addCompactUnwindPass(pm, *this);
649   if (needsGOTPass())
650     mach_o::addGOTPass(pm, *this);
651   if (needsTLVPass())
652     mach_o::addTLVPass(pm, *this);
653   if (needsShimPass())
654     mach_o::addShimPass(pm, *this); // Shim pass must run after stubs pass.
655 }
656 
writer() const657 Writer &MachOLinkingContext::writer() const {
658   if (!_writer)
659     _writer = createWriterMachO(*this);
660   return *_writer;
661 }
662 
663 ErrorOr<std::unique_ptr<MemoryBuffer>>
getMemoryBuffer(StringRef path)664 MachOLinkingContext::getMemoryBuffer(StringRef path) {
665   addInputFileDependency(path);
666 
667   ErrorOr<std::unique_ptr<MemoryBuffer>> mbOrErr =
668     MemoryBuffer::getFileOrSTDIN(path);
669   if (std::error_code ec = mbOrErr.getError())
670     return ec;
671   std::unique_ptr<MemoryBuffer> mb = std::move(mbOrErr.get());
672 
673   // If buffer contains a fat file, find required arch in fat buffer
674   // and switch buffer to point to just that required slice.
675   uint32_t offset;
676   uint32_t size;
677   if (sliceFromFatFile(mb->getMemBufferRef(), offset, size))
678     return MemoryBuffer::getFileSlice(path, size, offset);
679   return std::move(mb);
680 }
681 
loadIndirectDylib(StringRef path)682 MachODylibFile* MachOLinkingContext::loadIndirectDylib(StringRef path) {
683   ErrorOr<std::unique_ptr<MemoryBuffer>> mbOrErr = getMemoryBuffer(path);
684   if (mbOrErr.getError())
685     return nullptr;
686 
687   ErrorOr<std::unique_ptr<File>> fileOrErr =
688       registry().loadFile(std::move(mbOrErr.get()));
689   if (!fileOrErr)
690     return nullptr;
691   std::unique_ptr<File> &file = fileOrErr.get();
692   file->parse();
693   MachODylibFile *result = reinterpret_cast<MachODylibFile *>(file.get());
694   // Node object now owned by _indirectDylibs vector.
695   _indirectDylibs.push_back(std::move(file));
696   return result;
697 }
698 
findIndirectDylib(StringRef path)699 MachODylibFile* MachOLinkingContext::findIndirectDylib(StringRef path) {
700   // See if already loaded.
701   auto pos = _pathToDylibMap.find(path);
702   if (pos != _pathToDylibMap.end())
703     return pos->second;
704 
705   // Search -L paths if of the form "libXXX.dylib"
706   std::pair<StringRef, StringRef> split = path.rsplit('/');
707   StringRef leafName = split.second;
708   if (leafName.startswith("lib") && leafName.endswith(".dylib")) {
709     // FIXME: Need to enhance searchLibrary() to only look for .dylib
710     auto libPath = searchLibrary(leafName);
711     if (libPath)
712       return loadIndirectDylib(libPath.getValue());
713   }
714 
715   // Try full path with sysroot.
716   for (StringRef sysPath : _syslibRoots) {
717     SmallString<256> fullPath;
718     fullPath.assign(sysPath);
719     llvm::sys::path::append(fullPath, path);
720     if (pathExists(fullPath))
721       return loadIndirectDylib(fullPath);
722   }
723 
724   // Try full path.
725   if (pathExists(path)) {
726     return loadIndirectDylib(path);
727   }
728 
729   return nullptr;
730 }
731 
dylibCurrentVersion(StringRef installName) const732 uint32_t MachOLinkingContext::dylibCurrentVersion(StringRef installName) const {
733   auto pos = _pathToDylibMap.find(installName);
734   if (pos != _pathToDylibMap.end())
735     return pos->second->currentVersion();
736   else
737     return 0x10000; // 1.0
738 }
739 
dylibCompatVersion(StringRef installName) const740 uint32_t MachOLinkingContext::dylibCompatVersion(StringRef installName) const {
741   auto pos = _pathToDylibMap.find(installName);
742   if (pos != _pathToDylibMap.end())
743     return pos->second->compatVersion();
744   else
745     return 0x10000; // 1.0
746 }
747 
createImplicitFiles(std::vector<std::unique_ptr<File>> & result)748 void MachOLinkingContext::createImplicitFiles(
749                             std::vector<std::unique_ptr<File> > &result) {
750   // Add indirect dylibs by asking each linked dylib to add its indirects.
751   // Iterate until no more dylibs get loaded.
752   size_t dylibCount = 0;
753   while (dylibCount != _allDylibs.size()) {
754     dylibCount = _allDylibs.size();
755     for (MachODylibFile *dylib : _allDylibs) {
756       dylib->loadReExportedDylibs([this] (StringRef path) -> MachODylibFile* {
757                                   return findIndirectDylib(path); });
758     }
759   }
760 
761   // Let writer add output type specific extras.
762   writer().createImplicitFiles(result);
763 
764   // If undefinedMode is != error, add a FlatNamespaceFile instance. This will
765   // provide a SharedLibraryAtom for symbols that aren't defined elsewhere.
766   if (undefinedMode() != UndefinedMode::error) {
767     result.emplace_back(new mach_o::FlatNamespaceFile(*this));
768     _flatNamespaceFile = result.back().get();
769   }
770 }
771 
registerDylib(MachODylibFile * dylib,bool upward) const772 void MachOLinkingContext::registerDylib(MachODylibFile *dylib,
773                                         bool upward) const {
774   std::lock_guard<std::mutex> lock(_dylibsMutex);
775 
776   if (!llvm::count(_allDylibs, dylib))
777     _allDylibs.push_back(dylib);
778   _pathToDylibMap[dylib->installName()] = dylib;
779   // If path is different than install name, register path too.
780   if (!dylib->path().equals(dylib->installName()))
781     _pathToDylibMap[dylib->path()] = dylib;
782   if (upward)
783     _upwardDylibs.insert(dylib);
784 }
785 
isUpwardDylib(StringRef installName) const786 bool MachOLinkingContext::isUpwardDylib(StringRef installName) const {
787   for (MachODylibFile *dylib : _upwardDylibs) {
788     if (dylib->installName().equals(installName))
789       return true;
790   }
791   return false;
792 }
793 
archHandler() const794 ArchHandler &MachOLinkingContext::archHandler() const {
795   if (!_archHandler)
796     _archHandler = ArchHandler::create(_arch);
797   return *_archHandler;
798 }
799 
addSectionAlignment(StringRef seg,StringRef sect,uint16_t align)800 void MachOLinkingContext::addSectionAlignment(StringRef seg, StringRef sect,
801                                               uint16_t align) {
802   SectionAlign entry = { seg, sect, align };
803   _sectAligns.push_back(entry);
804 }
805 
addSectCreateSection(StringRef seg,StringRef sect,std::unique_ptr<MemoryBuffer> content)806 void MachOLinkingContext::addSectCreateSection(
807                                         StringRef seg, StringRef sect,
808                                         std::unique_ptr<MemoryBuffer> content) {
809 
810   if (!_sectCreateFile) {
811     auto sectCreateFile = std::make_unique<mach_o::SectCreateFile>();
812     _sectCreateFile = sectCreateFile.get();
813     getNodes().push_back(std::make_unique<FileNode>(std::move(sectCreateFile)));
814   }
815 
816   assert(_sectCreateFile && "sectcreate file does not exist.");
817   _sectCreateFile->addSection(seg, sect, std::move(content));
818 }
819 
sectionAligned(StringRef seg,StringRef sect,uint16_t & align) const820 bool MachOLinkingContext::sectionAligned(StringRef seg, StringRef sect,
821                                          uint16_t &align) const {
822   for (const SectionAlign &entry : _sectAligns) {
823     if (seg.equals(entry.segmentName) && sect.equals(entry.sectionName)) {
824       align = entry.align;
825       return true;
826     }
827   }
828   return false;
829 }
830 
addExportSymbol(StringRef sym)831 void MachOLinkingContext::addExportSymbol(StringRef sym) {
832   // Support old crufty export lists with bogus entries.
833   if (sym.endswith(".eh") || sym.startswith(".objc_category_name_")) {
834     llvm::errs() << "warning: ignoring " << sym << " in export list\n";
835     return;
836   }
837   // Only i386 MacOSX uses old ABI, so don't change those.
838   if ((_os != OS::macOSX) || (_arch != arch_x86)) {
839     // ObjC has two different ABIs.  Be nice and allow one export list work for
840     // both ABIs by renaming symbols.
841     if (sym.startswith(".objc_class_name_")) {
842       std::string abi2className("_OBJC_CLASS_$_");
843       abi2className += sym.substr(17);
844       _exportedSymbols.insert(copy(abi2className));
845       std::string abi2metaclassName("_OBJC_METACLASS_$_");
846       abi2metaclassName += sym.substr(17);
847       _exportedSymbols.insert(copy(abi2metaclassName));
848       return;
849     }
850   }
851 
852   // FIXME: Support wildcards.
853   _exportedSymbols.insert(sym);
854 }
855 
exportSymbolNamed(StringRef sym) const856 bool MachOLinkingContext::exportSymbolNamed(StringRef sym) const {
857   switch (_exportMode) {
858   case ExportMode::globals:
859     llvm_unreachable("exportSymbolNamed() should not be called in this mode");
860     break;
861   case ExportMode::exported:
862     return _exportedSymbols.count(sym);
863   case ExportMode::unexported:
864     return !_exportedSymbols.count(sym);
865   }
866   llvm_unreachable("_exportMode unknown enum value");
867 }
868 
demangle(StringRef symbolName) const869 std::string MachOLinkingContext::demangle(StringRef symbolName) const {
870   // Only try to demangle symbols if -demangle on command line
871   if (!demangleSymbols())
872     return std::string(symbolName);
873 
874   // Only try to demangle symbols that look like C++ symbols
875   if (!symbolName.startswith("__Z"))
876     return std::string(symbolName);
877 
878   SmallString<256> symBuff;
879   StringRef nullTermSym = Twine(symbolName).toNullTerminatedStringRef(symBuff);
880   // Mach-O has extra leading underscore that needs to be removed.
881   const char *cstr = nullTermSym.data() + 1;
882   int status;
883   char *demangled = llvm::itaniumDemangle(cstr, nullptr, nullptr, &status);
884   if (demangled) {
885     std::string result(demangled);
886     // __cxa_demangle() always uses a malloc'ed buffer to return the result.
887     free(demangled);
888     return result;
889   }
890 
891   return std::string(symbolName);
892 }
893 
addDependencyInfoHelper(llvm::raw_fd_ostream * DepInfo,char Opcode,StringRef Path)894 static void addDependencyInfoHelper(llvm::raw_fd_ostream *DepInfo,
895                                     char Opcode, StringRef Path) {
896   if (!DepInfo)
897     return;
898 
899   *DepInfo << Opcode;
900   *DepInfo << Path;
901   *DepInfo << '\0';
902 }
903 
createDependencyFile(StringRef path)904 std::error_code MachOLinkingContext::createDependencyFile(StringRef path) {
905   std::error_code ec;
906   _dependencyInfo = std::unique_ptr<llvm::raw_fd_ostream>(
907       new llvm::raw_fd_ostream(path, ec, llvm::sys::fs::OF_None));
908   if (ec) {
909     _dependencyInfo.reset();
910     return ec;
911   }
912 
913   addDependencyInfoHelper(_dependencyInfo.get(), 0x00, "lld" /*FIXME*/);
914   return std::error_code();
915 }
916 
addInputFileDependency(StringRef path) const917 void MachOLinkingContext::addInputFileDependency(StringRef path) const {
918   addDependencyInfoHelper(_dependencyInfo.get(), 0x10, path);
919 }
920 
addInputFileNotFound(StringRef path) const921 void MachOLinkingContext::addInputFileNotFound(StringRef path) const {
922   addDependencyInfoHelper(_dependencyInfo.get(), 0x11, path);
923 }
924 
addOutputFileDependency(StringRef path) const925 void MachOLinkingContext::addOutputFileDependency(StringRef path) const {
926   addDependencyInfoHelper(_dependencyInfo.get(), 0x40, path);
927 }
928 
appendOrderedSymbol(StringRef symbol,StringRef filename)929 void MachOLinkingContext::appendOrderedSymbol(StringRef symbol,
930                                               StringRef filename) {
931   // To support sorting static functions which may have the same name in
932   // multiple .o files, _orderFiles maps the symbol name to a vector
933   // of OrderFileNode each of which can specify a file prefix.
934   OrderFileNode info;
935   if (!filename.empty())
936     info.fileFilter = copy(filename);
937   info.order = _orderFileEntries++;
938   _orderFiles[symbol].push_back(info);
939 }
940 
941 bool
findOrderOrdinal(const std::vector<OrderFileNode> & nodes,const DefinedAtom * atom,unsigned & ordinal)942 MachOLinkingContext::findOrderOrdinal(const std::vector<OrderFileNode> &nodes,
943                                       const DefinedAtom *atom,
944                                       unsigned &ordinal) {
945   const File *objFile = &atom->file();
946   assert(objFile);
947   StringRef objName = objFile->path();
948   std::pair<StringRef, StringRef> dirAndLeaf = objName.rsplit('/');
949   if (!dirAndLeaf.second.empty())
950     objName = dirAndLeaf.second;
951   for (const OrderFileNode &info : nodes) {
952     if (info.fileFilter.empty()) {
953       // Have unprefixed symbol name in order file that matches this atom.
954       ordinal = info.order;
955       return true;
956     }
957     if (info.fileFilter.equals(objName)) {
958       // Have prefixed symbol name in order file that matches atom's path.
959       ordinal = info.order;
960       return true;
961     }
962   }
963   return false;
964 }
965 
customAtomOrderer(const DefinedAtom * left,const DefinedAtom * right,bool & leftBeforeRight) const966 bool MachOLinkingContext::customAtomOrderer(const DefinedAtom *left,
967                                             const DefinedAtom *right,
968                                             bool &leftBeforeRight) const {
969   // No custom sorting if no order file entries.
970   if (!_orderFileEntries)
971     return false;
972 
973   // Order files can only order named atoms.
974   StringRef leftName = left->name();
975   StringRef rightName = right->name();
976   if (leftName.empty() || rightName.empty())
977     return false;
978 
979   // If neither is in order file list, no custom sorter.
980   auto leftPos = _orderFiles.find(leftName);
981   auto rightPos = _orderFiles.find(rightName);
982   bool leftIsOrdered = (leftPos != _orderFiles.end());
983   bool rightIsOrdered = (rightPos != _orderFiles.end());
984   if (!leftIsOrdered && !rightIsOrdered)
985     return false;
986 
987   // There could be multiple symbols with same name but different file prefixes.
988   unsigned leftOrder;
989   unsigned rightOrder;
990   bool foundLeft =
991       leftIsOrdered && findOrderOrdinal(leftPos->getValue(), left, leftOrder);
992   bool foundRight = rightIsOrdered &&
993                     findOrderOrdinal(rightPos->getValue(), right, rightOrder);
994   if (!foundLeft && !foundRight)
995     return false;
996 
997   // If only one is in order file list, ordered one goes first.
998   if (foundLeft != foundRight)
999     leftBeforeRight = foundLeft;
1000   else
1001     leftBeforeRight = (leftOrder < rightOrder);
1002 
1003   return true;
1004 }
1005 
isLibrary(const std::unique_ptr<Node> & elem)1006 static bool isLibrary(const std::unique_ptr<Node> &elem) {
1007   if (FileNode *node = dyn_cast<FileNode>(const_cast<Node *>(elem.get()))) {
1008     File *file = node->getFile();
1009     return isa<SharedLibraryFile>(file) || isa<ArchiveLibraryFile>(file);
1010   }
1011   return false;
1012 }
1013 
1014 // The darwin linker processes input files in two phases.  The first phase
1015 // links in all object (.o) files in command line order. The second phase
1016 // links in libraries in command line order.
1017 // In this function we reorder the input files so that all the object files
1018 // comes before any library file. We also make a group for the library files
1019 // so that the Resolver will reiterate over the libraries as long as we find
1020 // new undefines from libraries.
finalizeInputFiles()1021 void MachOLinkingContext::finalizeInputFiles() {
1022   std::vector<std::unique_ptr<Node>> &elements = getNodes();
1023   llvm::stable_sort(elements, [](const std::unique_ptr<Node> &a,
1024                                  const std::unique_ptr<Node> &b) {
1025     return !isLibrary(a) && isLibrary(b);
1026   });
1027   size_t numLibs = std::count_if(elements.begin(), elements.end(), isLibrary);
1028   elements.push_back(std::make_unique<GroupEnd>(numLibs));
1029 }
1030 
handleLoadedFile(File & file)1031 llvm::Error MachOLinkingContext::handleLoadedFile(File &file) {
1032   auto *machoFile = dyn_cast<MachOFile>(&file);
1033   if (!machoFile)
1034     return llvm::Error::success();
1035 
1036   // Check that the arch of the context matches that of the file.
1037   // Also set the arch of the context if it didn't have one.
1038   if (_arch == arch_unknown) {
1039     _arch = machoFile->arch();
1040   } else if (machoFile->arch() != arch_unknown && machoFile->arch() != _arch) {
1041     // Archs are different.
1042     return llvm::make_error<GenericError>(file.path() +
1043                   Twine(" cannot be linked due to incompatible architecture"));
1044   }
1045 
1046   // Check that the OS of the context matches that of the file.
1047   // Also set the OS of the context if it didn't have one.
1048   if (_os == OS::unknown) {
1049     _os = machoFile->OS();
1050   } else if (machoFile->OS() != OS::unknown && machoFile->OS() != _os) {
1051     // OSes are different.
1052     return llvm::make_error<GenericError>(file.path() +
1053               Twine(" cannot be linked due to incompatible operating systems"));
1054   }
1055 
1056   // Check that if the objc info exists, that it is compatible with the target
1057   // OS.
1058   switch (machoFile->objcConstraint()) {
1059     case objc_unknown:
1060       // The file is not compiled with objc, so skip the checks.
1061       break;
1062     case objc_gc_only:
1063     case objc_supports_gc:
1064       llvm_unreachable("GC support should already have thrown an error");
1065     case objc_retainReleaseForSimulator:
1066       // The file is built with simulator objc, so make sure that the context
1067       // is also building with simulator support.
1068       if (_os != OS::iOS_simulator)
1069         return llvm::make_error<GenericError>(file.path() +
1070           Twine(" cannot be linked.  It contains ObjC built for the simulator"
1071                 " while we are linking a non-simulator target"));
1072       assert((_objcConstraint == objc_unknown ||
1073               _objcConstraint == objc_retainReleaseForSimulator) &&
1074              "Must be linking with retain/release for the simulator");
1075       _objcConstraint = objc_retainReleaseForSimulator;
1076       break;
1077     case objc_retainRelease:
1078       // The file is built without simulator objc, so make sure that the
1079       // context is also building without simulator support.
1080       if (_os == OS::iOS_simulator)
1081         return llvm::make_error<GenericError>(file.path() +
1082           Twine(" cannot be linked.  It contains ObjC built for a non-simulator"
1083                 " target while we are linking a simulator target"));
1084       assert((_objcConstraint == objc_unknown ||
1085               _objcConstraint == objc_retainRelease) &&
1086              "Must be linking with retain/release for a non-simulator target");
1087       _objcConstraint = objc_retainRelease;
1088       break;
1089   }
1090 
1091   // Check that the swift version of the context matches that of the file.
1092   // Also set the swift version of the context if it didn't have one.
1093   if (!_swiftVersion) {
1094     _swiftVersion = machoFile->swiftVersion();
1095   } else if (machoFile->swiftVersion() &&
1096              machoFile->swiftVersion() != _swiftVersion) {
1097     // Swift versions are different.
1098     return llvm::make_error<GenericError>("different swift versions");
1099   }
1100 
1101   return llvm::Error::success();
1102 }
1103 
1104 } // end namespace lld
1105