blob: f23bfc86a6e59cf02a970342074c737ea7d9ca36 [file] [log] [blame]
Rui Ueyama0ca149f2013-08-06 22:31:59 +00001//===- 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"
Nick Kledzik2458bec2014-07-16 19:49:02 +000011
12#include "ArchHandler.h"
Nick Kledzik8fc67fb2014-08-13 23:55:41 +000013#include "File.h"
Nick Kledzik635f9c72014-09-04 20:08:30 +000014#include "MachONormalizedFile.h"
Nick Kledzik2458bec2014-07-16 19:49:02 +000015#include "MachOPasses.h"
Rui Ueyama0ca149f2013-08-06 22:31:59 +000016
17#include "lld/Core/PassManager.h"
Nick Kledzik8fc67fb2014-08-13 23:55:41 +000018#include "lld/Driver/DarwinInputGraph.h"
Rui Ueyama0ca149f2013-08-06 22:31:59 +000019#include "lld/ReaderWriter/Reader.h"
20#include "lld/ReaderWriter/Writer.h"
21#include "lld/Passes/LayoutPass.h"
Shankar Easwaran2bc24922013-10-29 05:12:14 +000022#include "lld/Passes/RoundTripYAMLPass.h"
Rui Ueyama0ca149f2013-08-06 22:31:59 +000023
24#include "llvm/ADT/StringExtras.h"
25#include "llvm/ADT/Triple.h"
Nick Kledzikbe43d7e2014-09-30 23:15:39 +000026#include "llvm/Config/config.h"
Tim Northover77d82202014-07-10 11:21:06 +000027#include "llvm/Support/Errc.h"
Nick Kledzike34182f2013-11-06 21:36:55 +000028#include "llvm/Support/Host.h"
Nick Kledzik473933b2013-09-27 22:50:00 +000029#include "llvm/Support/MachO.h"
Tim Northover77d82202014-07-10 11:21:06 +000030#include "llvm/Support/Path.h"
Rui Ueyama0ca149f2013-08-06 22:31:59 +000031
Rui Ueyama57a29532014-08-06 19:37:35 +000032#include <algorithm>
33
Nick Kledzikbe43d7e2014-09-30 23:15:39 +000034#if HAVE_CXXABI_H
35#include <cxxabi.h>
36#endif
37
Nick Kledzik2458bec2014-07-16 19:49:02 +000038using lld::mach_o::ArchHandler;
Nick Kledzik8fc67fb2014-08-13 23:55:41 +000039using lld::mach_o::MachODylibFile;
Nick Kledzike34182f2013-11-06 21:36:55 +000040using namespace llvm::MachO;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000041
42namespace lld {
43
Nick Kledzike850d9d2013-09-10 23:46:57 +000044bool MachOLinkingContext::parsePackedVersion(StringRef str, uint32_t &result) {
45 result = 0;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000046
47 if (str.empty())
48 return false;
49
50 SmallVector<StringRef, 3> parts;
51 llvm::SplitString(str, parts, ".");
52
53 unsigned long long num;
54 if (llvm::getAsUnsignedInteger(parts[0], 10, num))
55 return true;
56 if (num > 65535)
57 return true;
Nick Kledzike850d9d2013-09-10 23:46:57 +000058 result = num << 16;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000059
60 if (parts.size() > 1) {
61 if (llvm::getAsUnsignedInteger(parts[1], 10, num))
62 return true;
63 if (num > 255)
64 return true;
Nick Kledzike850d9d2013-09-10 23:46:57 +000065 result |= (num << 8);
Rui Ueyama0ca149f2013-08-06 22:31:59 +000066 }
67
68 if (parts.size() > 2) {
69 if (llvm::getAsUnsignedInteger(parts[2], 10, num))
70 return true;
71 if (num > 255)
72 return true;
Nick Kledzike850d9d2013-09-10 23:46:57 +000073 result |= num;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000074 }
75
76 return false;
77}
78
Rui Ueyama0ca149f2013-08-06 22:31:59 +000079
Nick Kledzike34182f2013-11-06 21:36:55 +000080MachOLinkingContext::ArchInfo MachOLinkingContext::_s_archInfos[] = {
81 { "x86_64", arch_x86_64, true, CPU_TYPE_X86_64, CPU_SUBTYPE_X86_64_ALL },
82 { "i386", arch_x86, true, CPU_TYPE_I386, CPU_SUBTYPE_X86_ALL },
83 { "ppc", arch_ppc, false, CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_ALL },
84 { "armv6", arch_armv6, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V6 },
85 { "armv7", arch_armv7, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7 },
86 { "armv7s", arch_armv7s, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7S },
Nick Kledzik1bebb282014-09-09 23:52:59 +000087 { "arm64", arch_arm64, true, CPU_TYPE_ARM64, CPU_SUBTYPE_ARM64_ALL },
Nick Kledzike34182f2013-11-06 21:36:55 +000088 { "", arch_unknown,false, 0, 0 }
Rui Ueyama0ca149f2013-08-06 22:31:59 +000089};
90
91MachOLinkingContext::Arch
92MachOLinkingContext::archFromCpuType(uint32_t cputype, uint32_t cpusubtype) {
Nick Kledzike34182f2013-11-06 21:36:55 +000093 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
94 if ((info->cputype == cputype) && (info->cpusubtype == cpusubtype))
Rui Ueyama0ca149f2013-08-06 22:31:59 +000095 return info->arch;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000096 }
97 return arch_unknown;
98}
99
100MachOLinkingContext::Arch
101MachOLinkingContext::archFromName(StringRef archName) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000102 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
103 if (info->archName.equals(archName))
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000104 return info->arch;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000105 }
106 return arch_unknown;
107}
108
Nick Kledzike5552772013-12-19 21:58:00 +0000109StringRef MachOLinkingContext::nameFromArch(Arch arch) {
110 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
111 if (info->arch == arch)
112 return info->archName;
113 }
114 return "<unknown>";
115}
116
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000117uint32_t MachOLinkingContext::cpuTypeFromArch(Arch arch) {
118 assert(arch != arch_unknown);
Nick Kledzike34182f2013-11-06 21:36:55 +0000119 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
120 if (info->arch == arch)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000121 return info->cputype;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000122 }
123 llvm_unreachable("Unknown arch type");
124}
125
126uint32_t MachOLinkingContext::cpuSubtypeFromArch(Arch arch) {
127 assert(arch != arch_unknown);
Nick Kledzike34182f2013-11-06 21:36:55 +0000128 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
129 if (info->arch == arch)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000130 return info->cpusubtype;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000131 }
132 llvm_unreachable("Unknown arch type");
133}
134
Nick Kledzik635f9c72014-09-04 20:08:30 +0000135bool MachOLinkingContext::isThinObjectFile(StringRef path, Arch &arch) {
136 return mach_o::normalized::isThinObjectFile(path, arch);
137}
138
Nick Kledzik14b5d202014-10-08 01:48:10 +0000139bool MachOLinkingContext::sliceFromFatFile(const MemoryBuffer &mb,
140 uint32_t &offset,
141 uint32_t &size) {
142 return mach_o::normalized::sliceFromFatFile(mb, _arch, offset, size);
143}
144
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000145MachOLinkingContext::MachOLinkingContext()
Tim Northoverd30a1f22014-06-20 15:59:00 +0000146 : _outputMachOType(MH_EXECUTE), _outputMachOTypeStatic(false),
Tim Northoveraf3075b2014-09-10 10:39:57 +0000147 _doNothing(false), _pie(false), _arch(arch_unknown), _os(OS::macOSX),
148 _osMinVersion(0), _pageZeroSize(0), _pageSize(4096), _baseAddress(0),
149 _compatibilityVersion(0), _currentVersion(0), _deadStrippableDylib(false),
150 _printAtoms(false), _testingFileUsage(false), _keepPrivateExterns(false),
Nick Kledzikbe43d7e2014-09-30 23:15:39 +0000151 _demangle(false), _archHandler(nullptr),
152 _exportMode(ExportMode::globals) {}
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000153
154MachOLinkingContext::~MachOLinkingContext() {}
155
Nick Kledzik6960b072013-12-21 01:47:17 +0000156void MachOLinkingContext::configure(HeaderFileType type, Arch arch, OS os,
157 uint32_t minOSVersion) {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000158 _outputMachOType = type;
Nick Kledzik6960b072013-12-21 01:47:17 +0000159 _arch = arch;
160 _os = os;
161 _osMinVersion = minOSVersion;
162
Nick Kledzikcb2018f2014-10-09 01:01:16 +0000163 // 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
Tim Northoverd30a1f22014-06-20 15:59:00 +0000183 switch (_outputMachOType) {
Nick Kledzik6960b072013-12-21 01:47:17 +0000184 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
Nick Kledzikb7035ae2014-09-09 00:17:52 +0000201 // Make PIE by default when targetting newer OSs.
202 switch (os) {
203 case OS::macOSX:
204 if (minOSVersion >= 0x000A0700) // MacOSX 10.7
205 _pie = true;
206 break;
207 case OS::iOS:
208 if (minOSVersion >= 0x00040300) // iOS 4.3
209 _pie = true;
210 break;
211 case OS::iOS_simulator:
212 _pie = true;
213 break;
214 case OS::unknown:
215 break;
216 }
Nick Kledzik6960b072013-12-21 01:47:17 +0000217 break;
218 case llvm::MachO::MH_DYLIB:
219 _globalsAreDeadStripRoots = true;
220 break;
221 case llvm::MachO::MH_BUNDLE:
222 break;
223 case llvm::MachO::MH_OBJECT:
224 _printRemainingUndefines = false;
225 _allowRemainingUndefines = true;
226 default:
227 break;
228 }
Nick Kledzik1bebb282014-09-09 23:52:59 +0000229
230 // Set default segment page sizes based on arch.
231 if (arch == arch_arm64)
232 _pageSize = 4*4096;
Nick Kledzik6960b072013-12-21 01:47:17 +0000233}
234
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000235uint32_t MachOLinkingContext::getCPUType() const {
236 return cpuTypeFromArch(_arch);
237}
238
239uint32_t MachOLinkingContext::getCPUSubType() const {
240 return cpuSubtypeFromArch(_arch);
241}
242
Nick Kledzike34182f2013-11-06 21:36:55 +0000243bool MachOLinkingContext::is64Bit(Arch arch) {
244 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
245 if (info->arch == arch) {
246 return (info->cputype & CPU_ARCH_ABI64);
247 }
248 }
249 // unknown archs are not 64-bit.
250 return false;
251}
252
253bool MachOLinkingContext::isHostEndian(Arch arch) {
254 assert(arch != arch_unknown);
255 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
256 if (info->arch == arch) {
257 return (info->littleEndian == llvm::sys::IsLittleEndianHost);
258 }
259 }
260 llvm_unreachable("Unknown arch type");
261}
262
263bool MachOLinkingContext::isBigEndian(Arch arch) {
264 assert(arch != arch_unknown);
265 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
266 if (info->arch == arch) {
267 return ! info->littleEndian;
268 }
269 }
270 llvm_unreachable("Unknown arch type");
271}
272
273
274
275bool MachOLinkingContext::is64Bit() const {
276 return is64Bit(_arch);
277}
278
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000279bool MachOLinkingContext::outputTypeHasEntry() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000280 switch (_outputMachOType) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000281 case MH_EXECUTE:
282 case MH_DYLINKER:
283 case MH_PRELOAD:
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000284 return true;
285 default:
286 return false;
287 }
288}
289
Nick Kledzik2458bec2014-07-16 19:49:02 +0000290bool MachOLinkingContext::needsStubsPass() const {
291 switch (_outputMachOType) {
292 case MH_EXECUTE:
293 return !_outputMachOTypeStatic;
294 case MH_DYLIB:
295 case MH_BUNDLE:
296 return true;
297 default:
298 return false;
299 }
300}
301
302bool MachOLinkingContext::needsGOTPass() const {
Nick Kledzik1bebb282014-09-09 23:52:59 +0000303 // GOT pass not used in -r mode.
304 if (_outputMachOType == MH_OBJECT)
Nick Kledzik2458bec2014-07-16 19:49:02 +0000305 return false;
Nick Kledzik1bebb282014-09-09 23:52:59 +0000306 // Only some arches use GOT pass.
307 switch (_arch) {
308 case arch_x86_64:
309 case arch_arm64:
310 return true;
311 default:
312 return false;
313 }
Nick Kledzik2458bec2014-07-16 19:49:02 +0000314}
315
Tim Northovercf78d372014-09-30 21:29:54 +0000316bool MachOLinkingContext::needsCompactUnwindPass() const {
317 switch (_outputMachOType) {
318 case MH_EXECUTE:
319 case MH_DYLIB:
320 case MH_BUNDLE:
321 return archHandler().needsCompactUnwind();
322 default:
323 return false;
324 }
325}
Nick Kledzik2458bec2014-07-16 19:49:02 +0000326
Nick Kledzik4121bce2014-10-14 01:51:42 +0000327bool MachOLinkingContext::needsShimPass() const {
328 // Shim pass only used in final executables.
329 if (_outputMachOType == MH_OBJECT)
330 return false;
331 // Only 32-bit arm arches use Shim pass.
332 switch (_arch) {
333 case arch_armv6:
334 case arch_armv7:
335 case arch_armv7s:
336 return true;
337 default:
338 return false;
339 }
340}
341
Nick Kledzik2458bec2014-07-16 19:49:02 +0000342StringRef MachOLinkingContext::binderSymbolName() const {
343 return archHandler().stubInfo().binderSymbolName;
344}
345
346
347
348
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000349bool MachOLinkingContext::minOS(StringRef mac, StringRef iOS) const {
Nick Kledzik30332b12013-10-08 00:43:34 +0000350 uint32_t parsedVersion;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000351 switch (_os) {
Nick Kledzik30332b12013-10-08 00:43:34 +0000352 case OS::macOSX:
Nick Kledzike850d9d2013-09-10 23:46:57 +0000353 if (parsePackedVersion(mac, parsedVersion))
354 return false;
355 return _osMinVersion >= parsedVersion;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000356 case OS::iOS:
Nick Kledzik30332b12013-10-08 00:43:34 +0000357 case OS::iOS_simulator:
Nick Kledzike850d9d2013-09-10 23:46:57 +0000358 if (parsePackedVersion(iOS, parsedVersion))
359 return false;
360 return _osMinVersion >= parsedVersion;
Nick Kledzik30332b12013-10-08 00:43:34 +0000361 case OS::unknown:
362 break;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000363 }
364 llvm_unreachable("target not configured for iOS or MacOSX");
365}
366
367bool MachOLinkingContext::addEntryPointLoadCommand() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000368 if ((_outputMachOType == MH_EXECUTE) && !_outputMachOTypeStatic) {
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000369 return minOS("10.8", "6.0");
370 }
371 return false;
372}
373
374bool MachOLinkingContext::addUnixThreadLoadCommand() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000375 switch (_outputMachOType) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000376 case MH_EXECUTE:
Tim Northoverd30a1f22014-06-20 15:59:00 +0000377 if (_outputMachOTypeStatic)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000378 return true;
379 else
380 return !minOS("10.8", "6.0");
381 break;
Nick Kledzike34182f2013-11-06 21:36:55 +0000382 case MH_DYLINKER:
383 case MH_PRELOAD:
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000384 return true;
385 default:
386 return false;
387 }
388}
389
Tim Northover77d82202014-07-10 11:21:06 +0000390bool MachOLinkingContext::pathExists(StringRef path) const {
Nick Kledzik94174f72014-08-15 19:53:41 +0000391 if (!_testingFileUsage)
Tim Northover77d82202014-07-10 11:21:06 +0000392 return llvm::sys::fs::exists(path.str());
393
394 // Otherwise, we're in test mode: only files explicitly provided on the
395 // command-line exist.
Rui Ueyama57a29532014-08-06 19:37:35 +0000396 std::string key = path.str();
397 std::replace(key.begin(), key.end(), '\\', '/');
398 return _existingPaths.find(key) != _existingPaths.end();
Tim Northover77d82202014-07-10 11:21:06 +0000399}
400
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000401bool MachOLinkingContext::fileExists(StringRef path) const {
402 bool found = pathExists(path);
403 // Log search misses.
404 if (!found)
405 addInputFileNotFound(path);
406
407 // When testing, file is never opened, so logging is done here.
408 if (_testingFileUsage && found)
409 addInputFileDependency(path);
410
411 return found;
412}
413
Nick Kledzik2d835da2014-08-14 22:20:41 +0000414void MachOLinkingContext::setSysLibRoots(const StringRefVector &paths) {
415 _syslibRoots = paths;
416}
417
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000418void MachOLinkingContext::addModifiedSearchDir(StringRef libPath,
419 bool isSystemPath) {
Tim Northover77d82202014-07-10 11:21:06 +0000420 bool addedModifiedPath = false;
421
Nick Kledzik2d835da2014-08-14 22:20:41 +0000422 // -syslibroot only applies to absolute paths.
423 if (libPath.startswith("/")) {
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000424 for (auto syslibRoot : _syslibRoots) {
Tim Northover77d82202014-07-10 11:21:06 +0000425 SmallString<256> path(syslibRoot);
426 llvm::sys::path::append(path, libPath);
427 if (pathExists(path)) {
428 _searchDirs.push_back(path.str().copy(_allocator));
429 addedModifiedPath = true;
430 }
431 }
432 }
433
434 if (addedModifiedPath)
435 return;
436
437 // Finally, if only one -syslibroot is given, system paths which aren't in it
438 // get suppressed.
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000439 if (_syslibRoots.size() != 1 || !isSystemPath) {
Tim Northover77d82202014-07-10 11:21:06 +0000440 if (pathExists(libPath)) {
441 _searchDirs.push_back(libPath);
442 }
443 }
444}
445
Nick Kledzik2d835da2014-08-14 22:20:41 +0000446void MachOLinkingContext::addFrameworkSearchDir(StringRef fwPath,
447 bool isSystemPath) {
448 bool pathAdded = false;
449
450 // -syslibroot only used with to absolute framework search paths.
451 if (fwPath.startswith("/")) {
452 for (auto syslibRoot : _syslibRoots) {
453 SmallString<256> path(syslibRoot);
454 llvm::sys::path::append(path, fwPath);
455 if (pathExists(path)) {
456 _frameworkDirs.push_back(path.str().copy(_allocator));
457 pathAdded = true;
458 }
459 }
460 }
461 // If fwPath found in any -syslibroot, then done.
462 if (pathAdded)
463 return;
464
465 // If only one -syslibroot, system paths not in that SDK are suppressed.
466 if (isSystemPath && (_syslibRoots.size() == 1))
467 return;
468
469 // Only use raw fwPath if that directory exists.
470 if (pathExists(fwPath))
471 _frameworkDirs.push_back(fwPath);
472}
473
474
Tim Northover77d82202014-07-10 11:21:06 +0000475ErrorOr<StringRef>
476MachOLinkingContext::searchDirForLibrary(StringRef path,
477 StringRef libName) const {
478 SmallString<256> fullPath;
479 if (libName.endswith(".o")) {
480 // A request ending in .o is special: just search for the file directly.
481 fullPath.assign(path);
482 llvm::sys::path::append(fullPath, libName);
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000483 if (fileExists(fullPath))
Tim Northover77d82202014-07-10 11:21:06 +0000484 return fullPath.str().copy(_allocator);
485 return make_error_code(llvm::errc::no_such_file_or_directory);
486 }
487
488 // Search for dynamic library
489 fullPath.assign(path);
490 llvm::sys::path::append(fullPath, Twine("lib") + libName + ".dylib");
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000491 if (fileExists(fullPath))
Tim Northover77d82202014-07-10 11:21:06 +0000492 return fullPath.str().copy(_allocator);
493
494 // If not, try for a static library
495 fullPath.assign(path);
496 llvm::sys::path::append(fullPath, Twine("lib") + libName + ".a");
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000497 if (fileExists(fullPath))
Tim Northover77d82202014-07-10 11:21:06 +0000498 return fullPath.str().copy(_allocator);
499
500 return make_error_code(llvm::errc::no_such_file_or_directory);
501}
502
503
504
505ErrorOr<StringRef> MachOLinkingContext::searchLibrary(StringRef libName) const {
506 SmallString<256> path;
507 for (StringRef dir : searchDirs()) {
508 ErrorOr<StringRef> ec = searchDirForLibrary(dir, libName);
509 if (ec)
510 return ec;
511 }
512
513 return make_error_code(llvm::errc::no_such_file_or_directory);
514}
515
Nick Kledzik2d835da2014-08-14 22:20:41 +0000516
517ErrorOr<StringRef> MachOLinkingContext::findPathForFramework(StringRef fwName) const{
518 SmallString<256> fullPath;
519 for (StringRef dir : frameworkDirs()) {
520 fullPath.assign(dir);
521 llvm::sys::path::append(fullPath, Twine(fwName) + ".framework", fwName);
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000522 if (fileExists(fullPath))
Nick Kledzik2d835da2014-08-14 22:20:41 +0000523 return fullPath.str().copy(_allocator);
524 }
525
526 return make_error_code(llvm::errc::no_such_file_or_directory);
527}
528
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000529bool MachOLinkingContext::validateImpl(raw_ostream &diagnostics) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000530 // TODO: if -arch not specified, look at arch of first .o file.
531
Tim Northoverd30a1f22014-06-20 15:59:00 +0000532 if (_currentVersion && _outputMachOType != MH_DYLIB) {
Nick Kledzike773e322013-09-10 23:55:14 +0000533 diagnostics << "error: -current_version can only be used with dylibs\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000534 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000535 }
536
Tim Northoverd30a1f22014-06-20 15:59:00 +0000537 if (_compatibilityVersion && _outputMachOType != MH_DYLIB) {
Nick Kledzike773e322013-09-10 23:55:14 +0000538 diagnostics
539 << "error: -compatibility_version can only be used with dylibs\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000540 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000541 }
542
Tim Northoverd30a1f22014-06-20 15:59:00 +0000543 if (_deadStrippableDylib && _outputMachOType != MH_DYLIB) {
Nick Kledzike773e322013-09-10 23:55:14 +0000544 diagnostics
545 << "error: -mark_dead_strippable_dylib can only be used with dylibs.\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000546 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000547 }
548
Tim Northoverd30a1f22014-06-20 15:59:00 +0000549 if (!_bundleLoader.empty() && outputMachOType() != MH_BUNDLE) {
Nick Kledzike773e322013-09-10 23:55:14 +0000550 diagnostics
551 << "error: -bundle_loader can only be used with Mach-O bundles\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000552 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000553 }
554
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000555 // If -exported_symbols_list used, all exported symbols must be defined.
556 if (_exportMode == ExportMode::whiteList) {
557 for (const auto &symbol : _exportedSymbols)
558 addInitialUndefinedSymbol(symbol.getKey());
559 }
560
Nick Kledzik77afc712014-08-21 20:25:50 +0000561 // If -dead_strip, set up initial live symbols.
562 if (deadStrip()) {
563 // Entry point is live.
564 if (outputTypeHasEntry())
565 addDeadStripRoot(entrySymbolName());
566 // Lazy binding helper is live.
567 if (needsStubsPass())
568 addDeadStripRoot(binderSymbolName());
569 // If using -exported_symbols_list, make all exported symbols live.
570 if (_exportMode == ExportMode::whiteList) {
571 _globalsAreDeadStripRoots = false;
572 for (const auto &symbol : _exportedSymbols)
573 addDeadStripRoot(symbol.getKey());
574 }
575 }
576
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000577 addOutputFileDependency(outputPath());
578
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000579 return true;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000580}
581
Shankar Easwaran2bc24922013-10-29 05:12:14 +0000582void MachOLinkingContext::addPasses(PassManager &pm) {
Nico Rieckb9d84f42014-02-24 21:14:37 +0000583 pm.add(std::unique_ptr<Pass>(new LayoutPass(registry())));
Nick Kledzik2458bec2014-07-16 19:49:02 +0000584 if (needsStubsPass())
585 mach_o::addStubsPass(pm, *this);
Tim Northovercf78d372014-09-30 21:29:54 +0000586 if (needsCompactUnwindPass())
587 mach_o::addCompactUnwindPass(pm, *this);
Nick Kledzik2458bec2014-07-16 19:49:02 +0000588 if (needsGOTPass())
589 mach_o::addGOTPass(pm, *this);
Nick Kledzik4121bce2014-10-14 01:51:42 +0000590 if (needsShimPass())
591 mach_o::addShimPass(pm, *this); // Shim pass must run after stubs pass.
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000592}
593
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000594Writer &MachOLinkingContext::writer() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000595 if (!_writer)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000596 _writer = createWriterMachO(*this);
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000597 return *_writer;
598}
599
Nick Kledzik22c90732014-10-01 20:24:30 +0000600MachODylibFile* MachOLinkingContext::loadIndirectDylib(StringRef path) {
Nick Kledzik51720672014-10-16 19:31:28 +0000601 std::unique_ptr<MachOFileNode> node(new MachOFileNode(path, *this));
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000602 std::error_code ec = node->parse(*this, llvm::errs());
603 if (ec)
604 return nullptr;
605
606 assert(node->files().size() == 1 && "expected one file in dylib");
607 // lld::File object is owned by MachOFileNode object. This method returns
608 // an unowned pointer to the lld::File object.
609 MachODylibFile* result = reinterpret_cast<MachODylibFile*>(
610 node->files().front().get());
611
612 // Node object now owned by _indirectDylibs vector.
613 _indirectDylibs.push_back(std::move(node));
614
615 return result;
616}
617
618
Nick Kledzik22c90732014-10-01 20:24:30 +0000619MachODylibFile* MachOLinkingContext::findIndirectDylib(StringRef path) {
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000620 // See if already loaded.
621 auto pos = _pathToDylibMap.find(path);
622 if (pos != _pathToDylibMap.end())
623 return pos->second;
624
625 // Search -L paths if of the form "libXXX.dylib"
626 std::pair<StringRef, StringRef> split = path.rsplit('/');
627 StringRef leafName = split.second;
628 if (leafName.startswith("lib") && leafName.endswith(".dylib")) {
629 // FIXME: Need to enhance searchLibrary() to only look for .dylib
630 auto libPath = searchLibrary(leafName);
631 if (!libPath.getError()) {
632 return loadIndirectDylib(libPath.get());
633 }
634 }
635
636 // Try full path with sysroot.
637 for (StringRef sysPath : _syslibRoots) {
638 SmallString<256> fullPath;
639 fullPath.assign(sysPath);
640 llvm::sys::path::append(fullPath, path);
641 if (pathExists(fullPath))
642 return loadIndirectDylib(fullPath);
643 }
644
645 // Try full path.
646 if (pathExists(path)) {
647 return loadIndirectDylib(path);
648 }
649
650 return nullptr;
651}
652
653bool MachOLinkingContext::createImplicitFiles(
Nick Kledzik22c90732014-10-01 20:24:30 +0000654 std::vector<std::unique_ptr<File> > &result) {
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000655 // Add indirect dylibs by asking each linked dylib to add its indirects.
656 // Iterate until no more dylibs get loaded.
657 size_t dylibCount = 0;
658 while (dylibCount != _allDylibs.size()) {
659 dylibCount = _allDylibs.size();
660 for (MachODylibFile *dylib : _allDylibs) {
661 dylib->loadReExportedDylibs([this] (StringRef path) -> MachODylibFile* {
662 return findIndirectDylib(path); });
663 }
664 }
665
666 // Let writer add output type specific extras.
667 return writer().createImplicitFiles(result);
668}
669
670
Nick Kledzik51720672014-10-16 19:31:28 +0000671void MachOLinkingContext::registerDylib(MachODylibFile *dylib,
672 bool upward) const {
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000673 _allDylibs.insert(dylib);
674 _pathToDylibMap[dylib->installName()] = dylib;
675 // If path is different than install name, register path too.
676 if (!dylib->path().equals(dylib->installName()))
677 _pathToDylibMap[dylib->path()] = dylib;
Nick Kledzik51720672014-10-16 19:31:28 +0000678 if (upward)
679 _upwardDylibs.insert(dylib);
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000680}
681
682
Nick Kledzik51720672014-10-16 19:31:28 +0000683bool MachOLinkingContext::isUpwardDylib(StringRef installName) const {
684 for (MachODylibFile *dylib : _upwardDylibs) {
685 if (dylib->installName().equals(installName))
686 return true;
687 }
688 return false;
689}
690
Nick Kledzik2458bec2014-07-16 19:49:02 +0000691ArchHandler &MachOLinkingContext::archHandler() const {
692 if (!_archHandler)
693 _archHandler = ArchHandler::create(_arch);
694 return *_archHandler;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000695}
696
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000697
Nick Kledzik2fcbe822014-07-30 00:58:06 +0000698void MachOLinkingContext::addSectionAlignment(StringRef seg, StringRef sect,
699 uint8_t align2) {
700 SectionAlign entry;
701 entry.segmentName = seg;
702 entry.sectionName = sect;
703 entry.align2 = align2;
704 _sectAligns.push_back(entry);
705}
706
707bool MachOLinkingContext::sectionAligned(StringRef seg, StringRef sect,
708 uint8_t &align2) const {
709 for (const SectionAlign &entry : _sectAligns) {
710 if (seg.equals(entry.segmentName) && sect.equals(entry.sectionName)) {
711 align2 = entry.align2;
712 return true;
713 }
714 }
715 return false;
716}
717
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000718
719void MachOLinkingContext::addExportSymbol(StringRef sym) {
720 // FIXME: Support wildcards.
721 _exportedSymbols.insert(sym);
722}
723
724bool MachOLinkingContext::exportSymbolNamed(StringRef sym) const {
725 switch (_exportMode) {
726 case ExportMode::globals:
727 llvm_unreachable("exportSymbolNamed() should not be called in this mode");
728 break;
729 case ExportMode::whiteList:
730 return _exportedSymbols.count(sym);
731 case ExportMode::blackList:
732 return !_exportedSymbols.count(sym);
733 }
Yaron Keren9682c852014-09-21 05:07:44 +0000734 llvm_unreachable("_exportMode unknown enum value");
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000735}
736
Nick Kledzikbe43d7e2014-09-30 23:15:39 +0000737std::string MachOLinkingContext::demangle(StringRef symbolName) const {
738 // Only try to demangle symbols if -demangle on command line
739 if (!_demangle)
740 return symbolName;
741
742 // Only try to demangle symbols that look like C++ symbols
743 if (!symbolName.startswith("__Z"))
744 return symbolName;
745
746#if HAVE_CXXABI_H
747 SmallString<256> symBuff;
748 StringRef nullTermSym = Twine(symbolName).toNullTerminatedStringRef(symBuff);
749 // Mach-O has extra leading underscore that needs to be removed.
750 const char *cstr = nullTermSym.data() + 1;
751 int status;
752 char *demangled = abi::__cxa_demangle(cstr, nullptr, nullptr, &status);
753 if (demangled != NULL) {
754 std::string result(demangled);
755 // __cxa_demangle() always uses a malloc'ed buffer to return the result.
756 free(demangled);
757 return result;
758 }
759#endif
760
761 return symbolName;
762}
763
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000764std::error_code MachOLinkingContext::createDependencyFile(StringRef path) {
765 std::error_code ec;
766 _dependencyInfo = std::unique_ptr<llvm::raw_fd_ostream>(new
767 llvm::raw_fd_ostream(path, ec, llvm::sys::fs::F_None));
768 if (ec) {
769 _dependencyInfo.reset();
770 return ec;
771 }
772
773 char linkerVersionOpcode = 0x00;
774 *_dependencyInfo << linkerVersionOpcode;
775 *_dependencyInfo << "lld"; // FIXME
776 *_dependencyInfo << '\0';
777
778 return std::error_code();
779}
780
781void MachOLinkingContext::addInputFileDependency(StringRef path) const {
782 if (!_dependencyInfo)
783 return;
784
785 char inputFileOpcode = 0x10;
786 *_dependencyInfo << inputFileOpcode;
787 *_dependencyInfo << path;
788 *_dependencyInfo << '\0';
789}
790
791void MachOLinkingContext::addInputFileNotFound(StringRef path) const {
792 if (!_dependencyInfo)
793 return;
794
795 char inputFileOpcode = 0x11;
796 *_dependencyInfo << inputFileOpcode;
797 *_dependencyInfo << path;
798 *_dependencyInfo << '\0';
799}
800
801void MachOLinkingContext::addOutputFileDependency(StringRef path) const {
802 if (!_dependencyInfo)
803 return;
804
805 char outputFileOpcode = 0x40;
806 *_dependencyInfo << outputFileOpcode;
807 *_dependencyInfo << path;
808 *_dependencyInfo << '\0';
809}
810
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000811
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000812} // end namespace lld