blob: b99ecc8548ea254cd038e6b15a29778023f9df3d [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#include "ArchHandler.h"
Nick Kledzik8fc67fb2014-08-13 23:55:41 +000012#include "File.h"
Nick Kledzik635f9c72014-09-04 20:08:30 +000013#include "MachONormalizedFile.h"
Nick Kledzik2458bec2014-07-16 19:49:02 +000014#include "MachOPasses.h"
Rui Ueyama0ca149f2013-08-06 22:31:59 +000015#include "lld/Core/PassManager.h"
Nick Kledzik8fc67fb2014-08-13 23:55:41 +000016#include "lld/Driver/DarwinInputGraph.h"
Rui Ueyama0ca149f2013-08-06 22:31:59 +000017#include "lld/Passes/LayoutPass.h"
Shankar Easwaran2bc24922013-10-29 05:12:14 +000018#include "lld/Passes/RoundTripYAMLPass.h"
Shankar Easwaran2b67fca2014-10-18 05:33:55 +000019#include "lld/ReaderWriter/Reader.h"
20#include "lld/ReaderWriter/Writer.h"
Rui Ueyama0ca149f2013-08-06 22:31:59 +000021#include "llvm/ADT/StringExtras.h"
22#include "llvm/ADT/Triple.h"
Nick Kledzikbe43d7e2014-09-30 23:15:39 +000023#include "llvm/Config/config.h"
Tim Northover77d82202014-07-10 11:21:06 +000024#include "llvm/Support/Errc.h"
Nick Kledzike34182f2013-11-06 21:36:55 +000025#include "llvm/Support/Host.h"
Nick Kledzik473933b2013-09-27 22:50:00 +000026#include "llvm/Support/MachO.h"
Tim Northover77d82202014-07-10 11:21:06 +000027#include "llvm/Support/Path.h"
Rui Ueyama57a29532014-08-06 19:37:35 +000028#include <algorithm>
29
Rui Ueyamafccf7ef2014-10-27 07:44:40 +000030#if defined(HAVE_CXXABI_H)
Nick Kledzikbe43d7e2014-09-30 23:15:39 +000031#include <cxxabi.h>
32#endif
33
Nick Kledzik2458bec2014-07-16 19:49:02 +000034using lld::mach_o::ArchHandler;
Nick Kledzik8fc67fb2014-08-13 23:55:41 +000035using lld::mach_o::MachODylibFile;
Nick Kledzike34182f2013-11-06 21:36:55 +000036using namespace llvm::MachO;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000037
38namespace lld {
39
Nick Kledzike850d9d2013-09-10 23:46:57 +000040bool MachOLinkingContext::parsePackedVersion(StringRef str, uint32_t &result) {
41 result = 0;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000042
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;
Nick Kledzike850d9d2013-09-10 23:46:57 +000054 result = num << 16;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000055
56 if (parts.size() > 1) {
57 if (llvm::getAsUnsignedInteger(parts[1], 10, num))
58 return true;
59 if (num > 255)
60 return true;
Nick Kledzike850d9d2013-09-10 23:46:57 +000061 result |= (num << 8);
Rui Ueyama0ca149f2013-08-06 22:31:59 +000062 }
63
64 if (parts.size() > 2) {
65 if (llvm::getAsUnsignedInteger(parts[2], 10, num))
66 return true;
67 if (num > 255)
68 return true;
Nick Kledzike850d9d2013-09-10 23:46:57 +000069 result |= num;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000070 }
71
72 return false;
73}
74
Rui Ueyama0ca149f2013-08-06 22:31:59 +000075
Nick Kledzike34182f2013-11-06 21:36:55 +000076MachOLinkingContext::ArchInfo MachOLinkingContext::_s_archInfos[] = {
77 { "x86_64", arch_x86_64, true, CPU_TYPE_X86_64, CPU_SUBTYPE_X86_64_ALL },
78 { "i386", arch_x86, true, CPU_TYPE_I386, CPU_SUBTYPE_X86_ALL },
79 { "ppc", arch_ppc, false, CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_ALL },
80 { "armv6", arch_armv6, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V6 },
81 { "armv7", arch_armv7, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7 },
82 { "armv7s", arch_armv7s, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7S },
Nick Kledzik1bebb282014-09-09 23:52:59 +000083 { "arm64", arch_arm64, true, CPU_TYPE_ARM64, CPU_SUBTYPE_ARM64_ALL },
Nick Kledzike34182f2013-11-06 21:36:55 +000084 { "", arch_unknown,false, 0, 0 }
Rui Ueyama0ca149f2013-08-06 22:31:59 +000085};
86
87MachOLinkingContext::Arch
88MachOLinkingContext::archFromCpuType(uint32_t cputype, uint32_t cpusubtype) {
Nick Kledzike34182f2013-11-06 21:36:55 +000089 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
90 if ((info->cputype == cputype) && (info->cpusubtype == cpusubtype))
Rui Ueyama0ca149f2013-08-06 22:31:59 +000091 return info->arch;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000092 }
93 return arch_unknown;
94}
95
96MachOLinkingContext::Arch
97MachOLinkingContext::archFromName(StringRef archName) {
Nick Kledzike34182f2013-11-06 21:36:55 +000098 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
99 if (info->archName.equals(archName))
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000100 return info->arch;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000101 }
102 return arch_unknown;
103}
104
Nick Kledzike5552772013-12-19 21:58:00 +0000105StringRef MachOLinkingContext::nameFromArch(Arch arch) {
106 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
107 if (info->arch == arch)
108 return info->archName;
109 }
110 return "<unknown>";
111}
112
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000113uint32_t MachOLinkingContext::cpuTypeFromArch(Arch arch) {
114 assert(arch != arch_unknown);
Nick Kledzike34182f2013-11-06 21:36:55 +0000115 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
116 if (info->arch == arch)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000117 return info->cputype;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000118 }
119 llvm_unreachable("Unknown arch type");
120}
121
122uint32_t MachOLinkingContext::cpuSubtypeFromArch(Arch arch) {
123 assert(arch != arch_unknown);
Nick Kledzike34182f2013-11-06 21:36:55 +0000124 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
125 if (info->arch == arch)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000126 return info->cpusubtype;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000127 }
128 llvm_unreachable("Unknown arch type");
129}
130
Nick Kledzik635f9c72014-09-04 20:08:30 +0000131bool MachOLinkingContext::isThinObjectFile(StringRef path, Arch &arch) {
132 return mach_o::normalized::isThinObjectFile(path, arch);
133}
134
Nick Kledzik14b5d202014-10-08 01:48:10 +0000135bool MachOLinkingContext::sliceFromFatFile(const MemoryBuffer &mb,
136 uint32_t &offset,
137 uint32_t &size) {
138 return mach_o::normalized::sliceFromFatFile(mb, _arch, offset, size);
139}
140
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000141MachOLinkingContext::MachOLinkingContext()
Tim Northoverd30a1f22014-06-20 15:59:00 +0000142 : _outputMachOType(MH_EXECUTE), _outputMachOTypeStatic(false),
Tim Northoveraf3075b2014-09-10 10:39:57 +0000143 _doNothing(false), _pie(false), _arch(arch_unknown), _os(OS::macOSX),
144 _osMinVersion(0), _pageZeroSize(0), _pageSize(4096), _baseAddress(0),
145 _compatibilityVersion(0), _currentVersion(0), _deadStrippableDylib(false),
146 _printAtoms(false), _testingFileUsage(false), _keepPrivateExterns(false),
Nick Kledzikbe43d7e2014-09-30 23:15:39 +0000147 _demangle(false), _archHandler(nullptr),
148 _exportMode(ExportMode::globals) {}
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000149
150MachOLinkingContext::~MachOLinkingContext() {}
151
Nick Kledzik6960b072013-12-21 01:47:17 +0000152void MachOLinkingContext::configure(HeaderFileType type, Arch arch, OS os,
153 uint32_t minOSVersion) {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000154 _outputMachOType = type;
Nick Kledzik6960b072013-12-21 01:47:17 +0000155 _arch = arch;
156 _os = os;
157 _osMinVersion = minOSVersion;
158
Nick Kledzikcb2018f2014-10-09 01:01:16 +0000159 // If min OS not specified on command line, use reasonable defaults.
160 if (minOSVersion == 0) {
161 switch (_arch) {
162 case arch_x86_64:
163 case arch_x86:
164 parsePackedVersion("10.8", _osMinVersion);
165 _os = MachOLinkingContext::OS::macOSX;
166 break;
167 case arch_armv6:
168 case arch_armv7:
169 case arch_armv7s:
170 case arch_arm64:
171 parsePackedVersion("7.0", _osMinVersion);
172 _os = MachOLinkingContext::OS::iOS;
173 break;
174 default:
175 break;
176 }
177 }
178
Tim Northoverd30a1f22014-06-20 15:59:00 +0000179 switch (_outputMachOType) {
Nick Kledzik6960b072013-12-21 01:47:17 +0000180 case llvm::MachO::MH_EXECUTE:
181 // If targeting newer OS, use _main
182 if (minOS("10.8", "6.0")) {
183 _entrySymbolName = "_main";
184 } else {
185 // If targeting older OS, use start (in crt1.o)
186 _entrySymbolName = "start";
187 }
188
189 // __PAGEZERO defaults to 4GB on 64-bit (except for PP64 which lld does not
190 // support) and 4KB on 32-bit.
191 if (is64Bit(_arch)) {
192 _pageZeroSize = 0x100000000;
193 } else {
194 _pageZeroSize = 0x1000;
195 }
196
Nick Kledzikb7035ae2014-09-09 00:17:52 +0000197 // Make PIE by default when targetting newer OSs.
198 switch (os) {
199 case OS::macOSX:
200 if (minOSVersion >= 0x000A0700) // MacOSX 10.7
201 _pie = true;
202 break;
203 case OS::iOS:
204 if (minOSVersion >= 0x00040300) // iOS 4.3
205 _pie = true;
206 break;
207 case OS::iOS_simulator:
208 _pie = true;
209 break;
210 case OS::unknown:
211 break;
212 }
Nick Kledzik6960b072013-12-21 01:47:17 +0000213 break;
214 case llvm::MachO::MH_DYLIB:
215 _globalsAreDeadStripRoots = true;
216 break;
217 case llvm::MachO::MH_BUNDLE:
218 break;
219 case llvm::MachO::MH_OBJECT:
220 _printRemainingUndefines = false;
221 _allowRemainingUndefines = true;
222 default:
223 break;
224 }
Nick Kledzik1bebb282014-09-09 23:52:59 +0000225
226 // Set default segment page sizes based on arch.
227 if (arch == arch_arm64)
228 _pageSize = 4*4096;
Nick Kledzik6960b072013-12-21 01:47:17 +0000229}
230
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000231uint32_t MachOLinkingContext::getCPUType() const {
232 return cpuTypeFromArch(_arch);
233}
234
235uint32_t MachOLinkingContext::getCPUSubType() const {
236 return cpuSubtypeFromArch(_arch);
237}
238
Nick Kledzike34182f2013-11-06 21:36:55 +0000239bool MachOLinkingContext::is64Bit(Arch arch) {
240 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
241 if (info->arch == arch) {
242 return (info->cputype & CPU_ARCH_ABI64);
243 }
244 }
245 // unknown archs are not 64-bit.
246 return false;
247}
248
249bool MachOLinkingContext::isHostEndian(Arch arch) {
250 assert(arch != arch_unknown);
251 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
252 if (info->arch == arch) {
253 return (info->littleEndian == llvm::sys::IsLittleEndianHost);
254 }
255 }
256 llvm_unreachable("Unknown arch type");
257}
258
259bool MachOLinkingContext::isBigEndian(Arch arch) {
260 assert(arch != arch_unknown);
261 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
262 if (info->arch == arch) {
263 return ! info->littleEndian;
264 }
265 }
266 llvm_unreachable("Unknown arch type");
267}
268
269
270
271bool MachOLinkingContext::is64Bit() const {
272 return is64Bit(_arch);
273}
274
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000275bool MachOLinkingContext::outputTypeHasEntry() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000276 switch (_outputMachOType) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000277 case MH_EXECUTE:
278 case MH_DYLINKER:
279 case MH_PRELOAD:
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000280 return true;
281 default:
282 return false;
283 }
284}
285
Nick Kledzik2458bec2014-07-16 19:49:02 +0000286bool MachOLinkingContext::needsStubsPass() const {
287 switch (_outputMachOType) {
288 case MH_EXECUTE:
289 return !_outputMachOTypeStatic;
290 case MH_DYLIB:
291 case MH_BUNDLE:
292 return true;
293 default:
294 return false;
295 }
296}
297
298bool MachOLinkingContext::needsGOTPass() const {
Nick Kledzik1bebb282014-09-09 23:52:59 +0000299 // GOT pass not used in -r mode.
300 if (_outputMachOType == MH_OBJECT)
Nick Kledzik2458bec2014-07-16 19:49:02 +0000301 return false;
Nick Kledzik1bebb282014-09-09 23:52:59 +0000302 // Only some arches use GOT pass.
303 switch (_arch) {
304 case arch_x86_64:
305 case arch_arm64:
306 return true;
307 default:
308 return false;
309 }
Nick Kledzik2458bec2014-07-16 19:49:02 +0000310}
311
Tim Northovercf78d372014-09-30 21:29:54 +0000312bool MachOLinkingContext::needsCompactUnwindPass() const {
313 switch (_outputMachOType) {
314 case MH_EXECUTE:
315 case MH_DYLIB:
316 case MH_BUNDLE:
317 return archHandler().needsCompactUnwind();
318 default:
319 return false;
320 }
321}
Nick Kledzik2458bec2014-07-16 19:49:02 +0000322
Nick Kledzik4121bce2014-10-14 01:51:42 +0000323bool MachOLinkingContext::needsShimPass() const {
324 // Shim pass only used in final executables.
325 if (_outputMachOType == MH_OBJECT)
326 return false;
327 // Only 32-bit arm arches use Shim pass.
328 switch (_arch) {
329 case arch_armv6:
330 case arch_armv7:
331 case arch_armv7s:
332 return true;
333 default:
334 return false;
335 }
336}
337
Nick Kledzik2458bec2014-07-16 19:49:02 +0000338StringRef MachOLinkingContext::binderSymbolName() const {
339 return archHandler().stubInfo().binderSymbolName;
340}
341
342
343
344
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000345bool MachOLinkingContext::minOS(StringRef mac, StringRef iOS) const {
Nick Kledzik30332b12013-10-08 00:43:34 +0000346 uint32_t parsedVersion;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000347 switch (_os) {
Nick Kledzik30332b12013-10-08 00:43:34 +0000348 case OS::macOSX:
Nick Kledzike850d9d2013-09-10 23:46:57 +0000349 if (parsePackedVersion(mac, parsedVersion))
350 return false;
351 return _osMinVersion >= parsedVersion;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000352 case OS::iOS:
Nick Kledzik30332b12013-10-08 00:43:34 +0000353 case OS::iOS_simulator:
Nick Kledzike850d9d2013-09-10 23:46:57 +0000354 if (parsePackedVersion(iOS, parsedVersion))
355 return false;
356 return _osMinVersion >= parsedVersion;
Nick Kledzik30332b12013-10-08 00:43:34 +0000357 case OS::unknown:
358 break;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000359 }
360 llvm_unreachable("target not configured for iOS or MacOSX");
361}
362
363bool MachOLinkingContext::addEntryPointLoadCommand() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000364 if ((_outputMachOType == MH_EXECUTE) && !_outputMachOTypeStatic) {
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000365 return minOS("10.8", "6.0");
366 }
367 return false;
368}
369
370bool MachOLinkingContext::addUnixThreadLoadCommand() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000371 switch (_outputMachOType) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000372 case MH_EXECUTE:
Tim Northoverd30a1f22014-06-20 15:59:00 +0000373 if (_outputMachOTypeStatic)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000374 return true;
375 else
376 return !minOS("10.8", "6.0");
377 break;
Nick Kledzike34182f2013-11-06 21:36:55 +0000378 case MH_DYLINKER:
379 case MH_PRELOAD:
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000380 return true;
381 default:
382 return false;
383 }
384}
385
Tim Northover77d82202014-07-10 11:21:06 +0000386bool MachOLinkingContext::pathExists(StringRef path) const {
Nick Kledzik94174f72014-08-15 19:53:41 +0000387 if (!_testingFileUsage)
Tim Northover77d82202014-07-10 11:21:06 +0000388 return llvm::sys::fs::exists(path.str());
389
390 // Otherwise, we're in test mode: only files explicitly provided on the
391 // command-line exist.
Rui Ueyama57a29532014-08-06 19:37:35 +0000392 std::string key = path.str();
393 std::replace(key.begin(), key.end(), '\\', '/');
394 return _existingPaths.find(key) != _existingPaths.end();
Tim Northover77d82202014-07-10 11:21:06 +0000395}
396
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000397bool MachOLinkingContext::fileExists(StringRef path) const {
398 bool found = pathExists(path);
399 // Log search misses.
400 if (!found)
401 addInputFileNotFound(path);
402
403 // When testing, file is never opened, so logging is done here.
404 if (_testingFileUsage && found)
405 addInputFileDependency(path);
406
407 return found;
408}
409
Nick Kledzik2d835da2014-08-14 22:20:41 +0000410void MachOLinkingContext::setSysLibRoots(const StringRefVector &paths) {
411 _syslibRoots = paths;
412}
413
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000414void MachOLinkingContext::addModifiedSearchDir(StringRef libPath,
415 bool isSystemPath) {
Tim Northover77d82202014-07-10 11:21:06 +0000416 bool addedModifiedPath = false;
417
Nick Kledzik2d835da2014-08-14 22:20:41 +0000418 // -syslibroot only applies to absolute paths.
419 if (libPath.startswith("/")) {
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000420 for (auto syslibRoot : _syslibRoots) {
Tim Northover77d82202014-07-10 11:21:06 +0000421 SmallString<256> path(syslibRoot);
422 llvm::sys::path::append(path, libPath);
423 if (pathExists(path)) {
424 _searchDirs.push_back(path.str().copy(_allocator));
425 addedModifiedPath = true;
426 }
427 }
428 }
429
430 if (addedModifiedPath)
431 return;
432
433 // Finally, if only one -syslibroot is given, system paths which aren't in it
434 // get suppressed.
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000435 if (_syslibRoots.size() != 1 || !isSystemPath) {
Tim Northover77d82202014-07-10 11:21:06 +0000436 if (pathExists(libPath)) {
437 _searchDirs.push_back(libPath);
438 }
439 }
440}
441
Nick Kledzik2d835da2014-08-14 22:20:41 +0000442void MachOLinkingContext::addFrameworkSearchDir(StringRef fwPath,
443 bool isSystemPath) {
444 bool pathAdded = false;
445
446 // -syslibroot only used with to absolute framework search paths.
447 if (fwPath.startswith("/")) {
448 for (auto syslibRoot : _syslibRoots) {
449 SmallString<256> path(syslibRoot);
450 llvm::sys::path::append(path, fwPath);
451 if (pathExists(path)) {
452 _frameworkDirs.push_back(path.str().copy(_allocator));
453 pathAdded = true;
454 }
455 }
456 }
457 // If fwPath found in any -syslibroot, then done.
458 if (pathAdded)
459 return;
460
461 // If only one -syslibroot, system paths not in that SDK are suppressed.
462 if (isSystemPath && (_syslibRoots.size() == 1))
463 return;
464
465 // Only use raw fwPath if that directory exists.
466 if (pathExists(fwPath))
467 _frameworkDirs.push_back(fwPath);
468}
469
470
Tim Northover77d82202014-07-10 11:21:06 +0000471ErrorOr<StringRef>
472MachOLinkingContext::searchDirForLibrary(StringRef path,
473 StringRef libName) const {
474 SmallString<256> fullPath;
475 if (libName.endswith(".o")) {
476 // A request ending in .o is special: just search for the file directly.
477 fullPath.assign(path);
478 llvm::sys::path::append(fullPath, libName);
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000479 if (fileExists(fullPath))
Tim Northover77d82202014-07-10 11:21:06 +0000480 return fullPath.str().copy(_allocator);
481 return make_error_code(llvm::errc::no_such_file_or_directory);
482 }
483
484 // Search for dynamic library
485 fullPath.assign(path);
486 llvm::sys::path::append(fullPath, Twine("lib") + libName + ".dylib");
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000487 if (fileExists(fullPath))
Tim Northover77d82202014-07-10 11:21:06 +0000488 return fullPath.str().copy(_allocator);
489
490 // If not, try for a static library
491 fullPath.assign(path);
492 llvm::sys::path::append(fullPath, Twine("lib") + libName + ".a");
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000493 if (fileExists(fullPath))
Tim Northover77d82202014-07-10 11:21:06 +0000494 return fullPath.str().copy(_allocator);
495
496 return make_error_code(llvm::errc::no_such_file_or_directory);
497}
498
499
500
501ErrorOr<StringRef> MachOLinkingContext::searchLibrary(StringRef libName) const {
502 SmallString<256> path;
503 for (StringRef dir : searchDirs()) {
504 ErrorOr<StringRef> ec = searchDirForLibrary(dir, libName);
505 if (ec)
506 return ec;
507 }
508
509 return make_error_code(llvm::errc::no_such_file_or_directory);
510}
511
Nick Kledzik2d835da2014-08-14 22:20:41 +0000512
513ErrorOr<StringRef> MachOLinkingContext::findPathForFramework(StringRef fwName) const{
514 SmallString<256> fullPath;
515 for (StringRef dir : frameworkDirs()) {
516 fullPath.assign(dir);
517 llvm::sys::path::append(fullPath, Twine(fwName) + ".framework", fwName);
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000518 if (fileExists(fullPath))
Nick Kledzik2d835da2014-08-14 22:20:41 +0000519 return fullPath.str().copy(_allocator);
520 }
521
522 return make_error_code(llvm::errc::no_such_file_or_directory);
523}
524
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000525bool MachOLinkingContext::validateImpl(raw_ostream &diagnostics) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000526 // TODO: if -arch not specified, look at arch of first .o file.
527
Tim Northoverd30a1f22014-06-20 15:59:00 +0000528 if (_currentVersion && _outputMachOType != MH_DYLIB) {
Nick Kledzike773e322013-09-10 23:55:14 +0000529 diagnostics << "error: -current_version can only be used with dylibs\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000530 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000531 }
532
Tim Northoverd30a1f22014-06-20 15:59:00 +0000533 if (_compatibilityVersion && _outputMachOType != MH_DYLIB) {
Nick Kledzike773e322013-09-10 23:55:14 +0000534 diagnostics
535 << "error: -compatibility_version can only be used with dylibs\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000536 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000537 }
538
Tim Northoverd30a1f22014-06-20 15:59:00 +0000539 if (_deadStrippableDylib && _outputMachOType != MH_DYLIB) {
Nick Kledzike773e322013-09-10 23:55:14 +0000540 diagnostics
541 << "error: -mark_dead_strippable_dylib can only be used with dylibs.\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000542 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000543 }
544
Tim Northoverd30a1f22014-06-20 15:59:00 +0000545 if (!_bundleLoader.empty() && outputMachOType() != MH_BUNDLE) {
Nick Kledzike773e322013-09-10 23:55:14 +0000546 diagnostics
547 << "error: -bundle_loader can only be used with Mach-O bundles\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000548 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000549 }
550
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000551 // If -exported_symbols_list used, all exported symbols must be defined.
552 if (_exportMode == ExportMode::whiteList) {
553 for (const auto &symbol : _exportedSymbols)
554 addInitialUndefinedSymbol(symbol.getKey());
555 }
556
Nick Kledzik77afc712014-08-21 20:25:50 +0000557 // If -dead_strip, set up initial live symbols.
558 if (deadStrip()) {
559 // Entry point is live.
560 if (outputTypeHasEntry())
561 addDeadStripRoot(entrySymbolName());
562 // Lazy binding helper is live.
563 if (needsStubsPass())
564 addDeadStripRoot(binderSymbolName());
565 // If using -exported_symbols_list, make all exported symbols live.
566 if (_exportMode == ExportMode::whiteList) {
567 _globalsAreDeadStripRoots = false;
568 for (const auto &symbol : _exportedSymbols)
569 addDeadStripRoot(symbol.getKey());
570 }
571 }
572
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000573 addOutputFileDependency(outputPath());
574
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000575 return true;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000576}
577
Shankar Easwaran2bc24922013-10-29 05:12:14 +0000578void MachOLinkingContext::addPasses(PassManager &pm) {
Nico Rieckb9d84f42014-02-24 21:14:37 +0000579 pm.add(std::unique_ptr<Pass>(new LayoutPass(registry())));
Nick Kledzik2458bec2014-07-16 19:49:02 +0000580 if (needsStubsPass())
581 mach_o::addStubsPass(pm, *this);
Tim Northovercf78d372014-09-30 21:29:54 +0000582 if (needsCompactUnwindPass())
583 mach_o::addCompactUnwindPass(pm, *this);
Nick Kledzik2458bec2014-07-16 19:49:02 +0000584 if (needsGOTPass())
585 mach_o::addGOTPass(pm, *this);
Nick Kledzik4121bce2014-10-14 01:51:42 +0000586 if (needsShimPass())
587 mach_o::addShimPass(pm, *this); // Shim pass must run after stubs pass.
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000588}
589
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000590Writer &MachOLinkingContext::writer() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000591 if (!_writer)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000592 _writer = createWriterMachO(*this);
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000593 return *_writer;
594}
595
Nick Kledzik22c90732014-10-01 20:24:30 +0000596MachODylibFile* MachOLinkingContext::loadIndirectDylib(StringRef path) {
Nick Kledzik51720672014-10-16 19:31:28 +0000597 std::unique_ptr<MachOFileNode> node(new MachOFileNode(path, *this));
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000598 std::error_code ec = node->parse(*this, llvm::errs());
599 if (ec)
600 return nullptr;
601
602 assert(node->files().size() == 1 && "expected one file in dylib");
603 // lld::File object is owned by MachOFileNode object. This method returns
604 // an unowned pointer to the lld::File object.
605 MachODylibFile* result = reinterpret_cast<MachODylibFile*>(
606 node->files().front().get());
607
608 // Node object now owned by _indirectDylibs vector.
609 _indirectDylibs.push_back(std::move(node));
610
611 return result;
612}
613
614
Nick Kledzik22c90732014-10-01 20:24:30 +0000615MachODylibFile* MachOLinkingContext::findIndirectDylib(StringRef path) {
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000616 // See if already loaded.
617 auto pos = _pathToDylibMap.find(path);
618 if (pos != _pathToDylibMap.end())
619 return pos->second;
620
621 // Search -L paths if of the form "libXXX.dylib"
622 std::pair<StringRef, StringRef> split = path.rsplit('/');
623 StringRef leafName = split.second;
624 if (leafName.startswith("lib") && leafName.endswith(".dylib")) {
625 // FIXME: Need to enhance searchLibrary() to only look for .dylib
626 auto libPath = searchLibrary(leafName);
627 if (!libPath.getError()) {
628 return loadIndirectDylib(libPath.get());
629 }
630 }
631
632 // Try full path with sysroot.
633 for (StringRef sysPath : _syslibRoots) {
634 SmallString<256> fullPath;
635 fullPath.assign(sysPath);
636 llvm::sys::path::append(fullPath, path);
637 if (pathExists(fullPath))
638 return loadIndirectDylib(fullPath);
639 }
640
641 // Try full path.
642 if (pathExists(path)) {
643 return loadIndirectDylib(path);
644 }
645
646 return nullptr;
647}
648
649bool MachOLinkingContext::createImplicitFiles(
Nick Kledzik22c90732014-10-01 20:24:30 +0000650 std::vector<std::unique_ptr<File> > &result) {
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000651 // Add indirect dylibs by asking each linked dylib to add its indirects.
652 // Iterate until no more dylibs get loaded.
653 size_t dylibCount = 0;
654 while (dylibCount != _allDylibs.size()) {
655 dylibCount = _allDylibs.size();
656 for (MachODylibFile *dylib : _allDylibs) {
657 dylib->loadReExportedDylibs([this] (StringRef path) -> MachODylibFile* {
658 return findIndirectDylib(path); });
659 }
660 }
661
662 // Let writer add output type specific extras.
663 return writer().createImplicitFiles(result);
664}
665
666
Nick Kledzik51720672014-10-16 19:31:28 +0000667void MachOLinkingContext::registerDylib(MachODylibFile *dylib,
668 bool upward) const {
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000669 _allDylibs.insert(dylib);
670 _pathToDylibMap[dylib->installName()] = dylib;
671 // If path is different than install name, register path too.
672 if (!dylib->path().equals(dylib->installName()))
673 _pathToDylibMap[dylib->path()] = dylib;
Nick Kledzik51720672014-10-16 19:31:28 +0000674 if (upward)
675 _upwardDylibs.insert(dylib);
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000676}
677
678
Nick Kledzik51720672014-10-16 19:31:28 +0000679bool MachOLinkingContext::isUpwardDylib(StringRef installName) const {
680 for (MachODylibFile *dylib : _upwardDylibs) {
681 if (dylib->installName().equals(installName))
682 return true;
683 }
684 return false;
685}
686
Nick Kledzik2458bec2014-07-16 19:49:02 +0000687ArchHandler &MachOLinkingContext::archHandler() const {
688 if (!_archHandler)
689 _archHandler = ArchHandler::create(_arch);
690 return *_archHandler;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000691}
692
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000693
Nick Kledzik2fcbe822014-07-30 00:58:06 +0000694void MachOLinkingContext::addSectionAlignment(StringRef seg, StringRef sect,
695 uint8_t align2) {
696 SectionAlign entry;
697 entry.segmentName = seg;
698 entry.sectionName = sect;
699 entry.align2 = align2;
700 _sectAligns.push_back(entry);
701}
702
703bool MachOLinkingContext::sectionAligned(StringRef seg, StringRef sect,
704 uint8_t &align2) const {
705 for (const SectionAlign &entry : _sectAligns) {
706 if (seg.equals(entry.segmentName) && sect.equals(entry.sectionName)) {
707 align2 = entry.align2;
708 return true;
709 }
710 }
711 return false;
712}
713
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000714
715void MachOLinkingContext::addExportSymbol(StringRef sym) {
Nick Kledzik4183dbc2014-10-24 22:28:54 +0000716 // Support old crufty export lists with bogus entries.
717 if (sym.endswith(".eh") || sym.startswith(".objc_category_name_")) {
718 llvm::errs() << "warning: ignoring " << sym << " in export list\n";
719 return;
720 }
721 // Only i386 MacOSX uses old ABI, so don't change those.
722 if ((_os != OS::macOSX) || (_arch != arch_x86)) {
723 // ObjC has two differnent ABIs. Be nice and allow one export list work for
724 // both ABIs by renaming symbols.
725 if (sym.startswith(".objc_class_name_")) {
726 std::string abi2className("_OBJC_CLASS_$_");
727 abi2className += sym.substr(17);
728 _exportedSymbols.insert(copy(abi2className));
729 std::string abi2metaclassName("_OBJC_METACLASS_$_");
730 abi2metaclassName += sym.substr(17);
731 _exportedSymbols.insert(copy(abi2metaclassName));
732 return;
733 }
734 }
735
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000736 // FIXME: Support wildcards.
737 _exportedSymbols.insert(sym);
738}
739
740bool MachOLinkingContext::exportSymbolNamed(StringRef sym) const {
741 switch (_exportMode) {
742 case ExportMode::globals:
743 llvm_unreachable("exportSymbolNamed() should not be called in this mode");
744 break;
745 case ExportMode::whiteList:
746 return _exportedSymbols.count(sym);
747 case ExportMode::blackList:
748 return !_exportedSymbols.count(sym);
749 }
Yaron Keren9682c852014-09-21 05:07:44 +0000750 llvm_unreachable("_exportMode unknown enum value");
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000751}
752
Nick Kledzikbe43d7e2014-09-30 23:15:39 +0000753std::string MachOLinkingContext::demangle(StringRef symbolName) const {
754 // Only try to demangle symbols if -demangle on command line
755 if (!_demangle)
756 return symbolName;
757
758 // Only try to demangle symbols that look like C++ symbols
759 if (!symbolName.startswith("__Z"))
760 return symbolName;
761
Rui Ueyamafccf7ef2014-10-27 07:44:40 +0000762#if defined(HAVE_CXXABI_H)
Nick Kledzikbe43d7e2014-09-30 23:15:39 +0000763 SmallString<256> symBuff;
764 StringRef nullTermSym = Twine(symbolName).toNullTerminatedStringRef(symBuff);
765 // Mach-O has extra leading underscore that needs to be removed.
766 const char *cstr = nullTermSym.data() + 1;
767 int status;
768 char *demangled = abi::__cxa_demangle(cstr, nullptr, nullptr, &status);
769 if (demangled != NULL) {
770 std::string result(demangled);
771 // __cxa_demangle() always uses a malloc'ed buffer to return the result.
772 free(demangled);
773 return result;
774 }
775#endif
776
777 return symbolName;
778}
779
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000780std::error_code MachOLinkingContext::createDependencyFile(StringRef path) {
781 std::error_code ec;
782 _dependencyInfo = std::unique_ptr<llvm::raw_fd_ostream>(new
783 llvm::raw_fd_ostream(path, ec, llvm::sys::fs::F_None));
784 if (ec) {
785 _dependencyInfo.reset();
786 return ec;
787 }
788
789 char linkerVersionOpcode = 0x00;
790 *_dependencyInfo << linkerVersionOpcode;
791 *_dependencyInfo << "lld"; // FIXME
792 *_dependencyInfo << '\0';
793
794 return std::error_code();
795}
796
797void MachOLinkingContext::addInputFileDependency(StringRef path) const {
798 if (!_dependencyInfo)
799 return;
800
801 char inputFileOpcode = 0x10;
802 *_dependencyInfo << inputFileOpcode;
803 *_dependencyInfo << path;
804 *_dependencyInfo << '\0';
805}
806
807void MachOLinkingContext::addInputFileNotFound(StringRef path) const {
808 if (!_dependencyInfo)
809 return;
810
811 char inputFileOpcode = 0x11;
812 *_dependencyInfo << inputFileOpcode;
813 *_dependencyInfo << path;
814 *_dependencyInfo << '\0';
815}
816
817void MachOLinkingContext::addOutputFileDependency(StringRef path) const {
818 if (!_dependencyInfo)
819 return;
820
821 char outputFileOpcode = 0x40;
822 *_dependencyInfo << outputFileOpcode;
823 *_dependencyInfo << path;
824 *_dependencyInfo << '\0';
825}
826
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000827
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000828} // end namespace lld