blob: cbadcfcda74d45e8e22106101af4daccdace195d [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 Ueyamae7bf4292014-10-21 20:02:00 +000030// FreeBSD 10.0 has cxxabi.h but fails to define HAVE_CXXABI_H due to
31// header dependency issues.
Rui Ueyama1d6d08b2014-10-21 21:05:01 +000032#if defined(HAVE_CXXABI_H) || defined(__FreeBSD__)
Nick Kledzikbe43d7e2014-09-30 23:15:39 +000033#include <cxxabi.h>
34#endif
35
Nick Kledzik2458bec2014-07-16 19:49:02 +000036using lld::mach_o::ArchHandler;
Nick Kledzik8fc67fb2014-08-13 23:55:41 +000037using lld::mach_o::MachODylibFile;
Nick Kledzike34182f2013-11-06 21:36:55 +000038using namespace llvm::MachO;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000039
40namespace lld {
41
Nick Kledzike850d9d2013-09-10 23:46:57 +000042bool MachOLinkingContext::parsePackedVersion(StringRef str, uint32_t &result) {
43 result = 0;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000044
45 if (str.empty())
46 return false;
47
48 SmallVector<StringRef, 3> parts;
49 llvm::SplitString(str, parts, ".");
50
51 unsigned long long num;
52 if (llvm::getAsUnsignedInteger(parts[0], 10, num))
53 return true;
54 if (num > 65535)
55 return true;
Nick Kledzike850d9d2013-09-10 23:46:57 +000056 result = num << 16;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000057
58 if (parts.size() > 1) {
59 if (llvm::getAsUnsignedInteger(parts[1], 10, num))
60 return true;
61 if (num > 255)
62 return true;
Nick Kledzike850d9d2013-09-10 23:46:57 +000063 result |= (num << 8);
Rui Ueyama0ca149f2013-08-06 22:31:59 +000064 }
65
66 if (parts.size() > 2) {
67 if (llvm::getAsUnsignedInteger(parts[2], 10, num))
68 return true;
69 if (num > 255)
70 return true;
Nick Kledzike850d9d2013-09-10 23:46:57 +000071 result |= num;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000072 }
73
74 return false;
75}
76
Rui Ueyama0ca149f2013-08-06 22:31:59 +000077
Nick Kledzike34182f2013-11-06 21:36:55 +000078MachOLinkingContext::ArchInfo MachOLinkingContext::_s_archInfos[] = {
79 { "x86_64", arch_x86_64, true, CPU_TYPE_X86_64, CPU_SUBTYPE_X86_64_ALL },
80 { "i386", arch_x86, true, CPU_TYPE_I386, CPU_SUBTYPE_X86_ALL },
81 { "ppc", arch_ppc, false, CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_ALL },
82 { "armv6", arch_armv6, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V6 },
83 { "armv7", arch_armv7, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7 },
84 { "armv7s", arch_armv7s, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7S },
Nick Kledzik1bebb282014-09-09 23:52:59 +000085 { "arm64", arch_arm64, true, CPU_TYPE_ARM64, CPU_SUBTYPE_ARM64_ALL },
Nick Kledzike34182f2013-11-06 21:36:55 +000086 { "", arch_unknown,false, 0, 0 }
Rui Ueyama0ca149f2013-08-06 22:31:59 +000087};
88
89MachOLinkingContext::Arch
90MachOLinkingContext::archFromCpuType(uint32_t cputype, uint32_t cpusubtype) {
Nick Kledzike34182f2013-11-06 21:36:55 +000091 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
92 if ((info->cputype == cputype) && (info->cpusubtype == cpusubtype))
Rui Ueyama0ca149f2013-08-06 22:31:59 +000093 return info->arch;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000094 }
95 return arch_unknown;
96}
97
98MachOLinkingContext::Arch
99MachOLinkingContext::archFromName(StringRef archName) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000100 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
101 if (info->archName.equals(archName))
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000102 return info->arch;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000103 }
104 return arch_unknown;
105}
106
Nick Kledzike5552772013-12-19 21:58:00 +0000107StringRef MachOLinkingContext::nameFromArch(Arch arch) {
108 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
109 if (info->arch == arch)
110 return info->archName;
111 }
112 return "<unknown>";
113}
114
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000115uint32_t MachOLinkingContext::cpuTypeFromArch(Arch arch) {
116 assert(arch != arch_unknown);
Nick Kledzike34182f2013-11-06 21:36:55 +0000117 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
118 if (info->arch == arch)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000119 return info->cputype;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000120 }
121 llvm_unreachable("Unknown arch type");
122}
123
124uint32_t MachOLinkingContext::cpuSubtypeFromArch(Arch arch) {
125 assert(arch != arch_unknown);
Nick Kledzike34182f2013-11-06 21:36:55 +0000126 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
127 if (info->arch == arch)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000128 return info->cpusubtype;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000129 }
130 llvm_unreachable("Unknown arch type");
131}
132
Nick Kledzik635f9c72014-09-04 20:08:30 +0000133bool MachOLinkingContext::isThinObjectFile(StringRef path, Arch &arch) {
134 return mach_o::normalized::isThinObjectFile(path, arch);
135}
136
Nick Kledzik14b5d202014-10-08 01:48:10 +0000137bool MachOLinkingContext::sliceFromFatFile(const MemoryBuffer &mb,
138 uint32_t &offset,
139 uint32_t &size) {
140 return mach_o::normalized::sliceFromFatFile(mb, _arch, offset, size);
141}
142
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000143MachOLinkingContext::MachOLinkingContext()
Tim Northoverd30a1f22014-06-20 15:59:00 +0000144 : _outputMachOType(MH_EXECUTE), _outputMachOTypeStatic(false),
Tim Northoveraf3075b2014-09-10 10:39:57 +0000145 _doNothing(false), _pie(false), _arch(arch_unknown), _os(OS::macOSX),
146 _osMinVersion(0), _pageZeroSize(0), _pageSize(4096), _baseAddress(0),
147 _compatibilityVersion(0), _currentVersion(0), _deadStrippableDylib(false),
148 _printAtoms(false), _testingFileUsage(false), _keepPrivateExterns(false),
Nick Kledzikbe43d7e2014-09-30 23:15:39 +0000149 _demangle(false), _archHandler(nullptr),
150 _exportMode(ExportMode::globals) {}
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000151
152MachOLinkingContext::~MachOLinkingContext() {}
153
Nick Kledzik6960b072013-12-21 01:47:17 +0000154void MachOLinkingContext::configure(HeaderFileType type, Arch arch, OS os,
155 uint32_t minOSVersion) {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000156 _outputMachOType = type;
Nick Kledzik6960b072013-12-21 01:47:17 +0000157 _arch = arch;
158 _os = os;
159 _osMinVersion = minOSVersion;
160
Nick Kledzikcb2018f2014-10-09 01:01:16 +0000161 // If min OS not specified on command line, use reasonable defaults.
162 if (minOSVersion == 0) {
163 switch (_arch) {
164 case arch_x86_64:
165 case arch_x86:
166 parsePackedVersion("10.8", _osMinVersion);
167 _os = MachOLinkingContext::OS::macOSX;
168 break;
169 case arch_armv6:
170 case arch_armv7:
171 case arch_armv7s:
172 case arch_arm64:
173 parsePackedVersion("7.0", _osMinVersion);
174 _os = MachOLinkingContext::OS::iOS;
175 break;
176 default:
177 break;
178 }
179 }
180
Tim Northoverd30a1f22014-06-20 15:59:00 +0000181 switch (_outputMachOType) {
Nick Kledzik6960b072013-12-21 01:47:17 +0000182 case llvm::MachO::MH_EXECUTE:
183 // If targeting newer OS, use _main
184 if (minOS("10.8", "6.0")) {
185 _entrySymbolName = "_main";
186 } else {
187 // If targeting older OS, use start (in crt1.o)
188 _entrySymbolName = "start";
189 }
190
191 // __PAGEZERO defaults to 4GB on 64-bit (except for PP64 which lld does not
192 // support) and 4KB on 32-bit.
193 if (is64Bit(_arch)) {
194 _pageZeroSize = 0x100000000;
195 } else {
196 _pageZeroSize = 0x1000;
197 }
198
Nick Kledzikb7035ae2014-09-09 00:17:52 +0000199 // Make PIE by default when targetting newer OSs.
200 switch (os) {
201 case OS::macOSX:
202 if (minOSVersion >= 0x000A0700) // MacOSX 10.7
203 _pie = true;
204 break;
205 case OS::iOS:
206 if (minOSVersion >= 0x00040300) // iOS 4.3
207 _pie = true;
208 break;
209 case OS::iOS_simulator:
210 _pie = true;
211 break;
212 case OS::unknown:
213 break;
214 }
Nick Kledzik6960b072013-12-21 01:47:17 +0000215 break;
216 case llvm::MachO::MH_DYLIB:
217 _globalsAreDeadStripRoots = true;
218 break;
219 case llvm::MachO::MH_BUNDLE:
220 break;
221 case llvm::MachO::MH_OBJECT:
222 _printRemainingUndefines = false;
223 _allowRemainingUndefines = true;
224 default:
225 break;
226 }
Nick Kledzik1bebb282014-09-09 23:52:59 +0000227
228 // Set default segment page sizes based on arch.
229 if (arch == arch_arm64)
230 _pageSize = 4*4096;
Nick Kledzik6960b072013-12-21 01:47:17 +0000231}
232
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000233uint32_t MachOLinkingContext::getCPUType() const {
234 return cpuTypeFromArch(_arch);
235}
236
237uint32_t MachOLinkingContext::getCPUSubType() const {
238 return cpuSubtypeFromArch(_arch);
239}
240
Nick Kledzike34182f2013-11-06 21:36:55 +0000241bool MachOLinkingContext::is64Bit(Arch arch) {
242 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
243 if (info->arch == arch) {
244 return (info->cputype & CPU_ARCH_ABI64);
245 }
246 }
247 // unknown archs are not 64-bit.
248 return false;
249}
250
251bool MachOLinkingContext::isHostEndian(Arch arch) {
252 assert(arch != arch_unknown);
253 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
254 if (info->arch == arch) {
255 return (info->littleEndian == llvm::sys::IsLittleEndianHost);
256 }
257 }
258 llvm_unreachable("Unknown arch type");
259}
260
261bool MachOLinkingContext::isBigEndian(Arch arch) {
262 assert(arch != arch_unknown);
263 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
264 if (info->arch == arch) {
265 return ! info->littleEndian;
266 }
267 }
268 llvm_unreachable("Unknown arch type");
269}
270
271
272
273bool MachOLinkingContext::is64Bit() const {
274 return is64Bit(_arch);
275}
276
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000277bool MachOLinkingContext::outputTypeHasEntry() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000278 switch (_outputMachOType) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000279 case MH_EXECUTE:
280 case MH_DYLINKER:
281 case MH_PRELOAD:
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000282 return true;
283 default:
284 return false;
285 }
286}
287
Nick Kledzik2458bec2014-07-16 19:49:02 +0000288bool MachOLinkingContext::needsStubsPass() const {
289 switch (_outputMachOType) {
290 case MH_EXECUTE:
291 return !_outputMachOTypeStatic;
292 case MH_DYLIB:
293 case MH_BUNDLE:
294 return true;
295 default:
296 return false;
297 }
298}
299
300bool MachOLinkingContext::needsGOTPass() const {
Nick Kledzik1bebb282014-09-09 23:52:59 +0000301 // GOT pass not used in -r mode.
302 if (_outputMachOType == MH_OBJECT)
Nick Kledzik2458bec2014-07-16 19:49:02 +0000303 return false;
Nick Kledzik1bebb282014-09-09 23:52:59 +0000304 // Only some arches use GOT pass.
305 switch (_arch) {
306 case arch_x86_64:
307 case arch_arm64:
308 return true;
309 default:
310 return false;
311 }
Nick Kledzik2458bec2014-07-16 19:49:02 +0000312}
313
Tim Northovercf78d372014-09-30 21:29:54 +0000314bool MachOLinkingContext::needsCompactUnwindPass() const {
315 switch (_outputMachOType) {
316 case MH_EXECUTE:
317 case MH_DYLIB:
318 case MH_BUNDLE:
319 return archHandler().needsCompactUnwind();
320 default:
321 return false;
322 }
323}
Nick Kledzik2458bec2014-07-16 19:49:02 +0000324
Nick Kledzik4121bce2014-10-14 01:51:42 +0000325bool MachOLinkingContext::needsShimPass() const {
326 // Shim pass only used in final executables.
327 if (_outputMachOType == MH_OBJECT)
328 return false;
329 // Only 32-bit arm arches use Shim pass.
330 switch (_arch) {
331 case arch_armv6:
332 case arch_armv7:
333 case arch_armv7s:
334 return true;
335 default:
336 return false;
337 }
338}
339
Nick Kledzik2458bec2014-07-16 19:49:02 +0000340StringRef MachOLinkingContext::binderSymbolName() const {
341 return archHandler().stubInfo().binderSymbolName;
342}
343
344
345
346
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000347bool MachOLinkingContext::minOS(StringRef mac, StringRef iOS) const {
Nick Kledzik30332b12013-10-08 00:43:34 +0000348 uint32_t parsedVersion;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000349 switch (_os) {
Nick Kledzik30332b12013-10-08 00:43:34 +0000350 case OS::macOSX:
Nick Kledzike850d9d2013-09-10 23:46:57 +0000351 if (parsePackedVersion(mac, parsedVersion))
352 return false;
353 return _osMinVersion >= parsedVersion;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000354 case OS::iOS:
Nick Kledzik30332b12013-10-08 00:43:34 +0000355 case OS::iOS_simulator:
Nick Kledzike850d9d2013-09-10 23:46:57 +0000356 if (parsePackedVersion(iOS, parsedVersion))
357 return false;
358 return _osMinVersion >= parsedVersion;
Nick Kledzik30332b12013-10-08 00:43:34 +0000359 case OS::unknown:
360 break;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000361 }
362 llvm_unreachable("target not configured for iOS or MacOSX");
363}
364
365bool MachOLinkingContext::addEntryPointLoadCommand() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000366 if ((_outputMachOType == MH_EXECUTE) && !_outputMachOTypeStatic) {
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000367 return minOS("10.8", "6.0");
368 }
369 return false;
370}
371
372bool MachOLinkingContext::addUnixThreadLoadCommand() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000373 switch (_outputMachOType) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000374 case MH_EXECUTE:
Tim Northoverd30a1f22014-06-20 15:59:00 +0000375 if (_outputMachOTypeStatic)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000376 return true;
377 else
378 return !minOS("10.8", "6.0");
379 break;
Nick Kledzike34182f2013-11-06 21:36:55 +0000380 case MH_DYLINKER:
381 case MH_PRELOAD:
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000382 return true;
383 default:
384 return false;
385 }
386}
387
Tim Northover77d82202014-07-10 11:21:06 +0000388bool MachOLinkingContext::pathExists(StringRef path) const {
Nick Kledzik94174f72014-08-15 19:53:41 +0000389 if (!_testingFileUsage)
Tim Northover77d82202014-07-10 11:21:06 +0000390 return llvm::sys::fs::exists(path.str());
391
392 // Otherwise, we're in test mode: only files explicitly provided on the
393 // command-line exist.
Rui Ueyama57a29532014-08-06 19:37:35 +0000394 std::string key = path.str();
395 std::replace(key.begin(), key.end(), '\\', '/');
396 return _existingPaths.find(key) != _existingPaths.end();
Tim Northover77d82202014-07-10 11:21:06 +0000397}
398
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000399bool MachOLinkingContext::fileExists(StringRef path) const {
400 bool found = pathExists(path);
401 // Log search misses.
402 if (!found)
403 addInputFileNotFound(path);
404
405 // When testing, file is never opened, so logging is done here.
406 if (_testingFileUsage && found)
407 addInputFileDependency(path);
408
409 return found;
410}
411
Nick Kledzik2d835da2014-08-14 22:20:41 +0000412void MachOLinkingContext::setSysLibRoots(const StringRefVector &paths) {
413 _syslibRoots = paths;
414}
415
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000416void MachOLinkingContext::addModifiedSearchDir(StringRef libPath,
417 bool isSystemPath) {
Tim Northover77d82202014-07-10 11:21:06 +0000418 bool addedModifiedPath = false;
419
Nick Kledzik2d835da2014-08-14 22:20:41 +0000420 // -syslibroot only applies to absolute paths.
421 if (libPath.startswith("/")) {
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000422 for (auto syslibRoot : _syslibRoots) {
Tim Northover77d82202014-07-10 11:21:06 +0000423 SmallString<256> path(syslibRoot);
424 llvm::sys::path::append(path, libPath);
425 if (pathExists(path)) {
426 _searchDirs.push_back(path.str().copy(_allocator));
427 addedModifiedPath = true;
428 }
429 }
430 }
431
432 if (addedModifiedPath)
433 return;
434
435 // Finally, if only one -syslibroot is given, system paths which aren't in it
436 // get suppressed.
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000437 if (_syslibRoots.size() != 1 || !isSystemPath) {
Tim Northover77d82202014-07-10 11:21:06 +0000438 if (pathExists(libPath)) {
439 _searchDirs.push_back(libPath);
440 }
441 }
442}
443
Nick Kledzik2d835da2014-08-14 22:20:41 +0000444void MachOLinkingContext::addFrameworkSearchDir(StringRef fwPath,
445 bool isSystemPath) {
446 bool pathAdded = false;
447
448 // -syslibroot only used with to absolute framework search paths.
449 if (fwPath.startswith("/")) {
450 for (auto syslibRoot : _syslibRoots) {
451 SmallString<256> path(syslibRoot);
452 llvm::sys::path::append(path, fwPath);
453 if (pathExists(path)) {
454 _frameworkDirs.push_back(path.str().copy(_allocator));
455 pathAdded = true;
456 }
457 }
458 }
459 // If fwPath found in any -syslibroot, then done.
460 if (pathAdded)
461 return;
462
463 // If only one -syslibroot, system paths not in that SDK are suppressed.
464 if (isSystemPath && (_syslibRoots.size() == 1))
465 return;
466
467 // Only use raw fwPath if that directory exists.
468 if (pathExists(fwPath))
469 _frameworkDirs.push_back(fwPath);
470}
471
472
Tim Northover77d82202014-07-10 11:21:06 +0000473ErrorOr<StringRef>
474MachOLinkingContext::searchDirForLibrary(StringRef path,
475 StringRef libName) const {
476 SmallString<256> fullPath;
477 if (libName.endswith(".o")) {
478 // A request ending in .o is special: just search for the file directly.
479 fullPath.assign(path);
480 llvm::sys::path::append(fullPath, libName);
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000481 if (fileExists(fullPath))
Tim Northover77d82202014-07-10 11:21:06 +0000482 return fullPath.str().copy(_allocator);
483 return make_error_code(llvm::errc::no_such_file_or_directory);
484 }
485
486 // Search for dynamic library
487 fullPath.assign(path);
488 llvm::sys::path::append(fullPath, Twine("lib") + libName + ".dylib");
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000489 if (fileExists(fullPath))
Tim Northover77d82202014-07-10 11:21:06 +0000490 return fullPath.str().copy(_allocator);
491
492 // If not, try for a static library
493 fullPath.assign(path);
494 llvm::sys::path::append(fullPath, Twine("lib") + libName + ".a");
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000495 if (fileExists(fullPath))
Tim Northover77d82202014-07-10 11:21:06 +0000496 return fullPath.str().copy(_allocator);
497
498 return make_error_code(llvm::errc::no_such_file_or_directory);
499}
500
501
502
503ErrorOr<StringRef> MachOLinkingContext::searchLibrary(StringRef libName) const {
504 SmallString<256> path;
505 for (StringRef dir : searchDirs()) {
506 ErrorOr<StringRef> ec = searchDirForLibrary(dir, libName);
507 if (ec)
508 return ec;
509 }
510
511 return make_error_code(llvm::errc::no_such_file_or_directory);
512}
513
Nick Kledzik2d835da2014-08-14 22:20:41 +0000514
515ErrorOr<StringRef> MachOLinkingContext::findPathForFramework(StringRef fwName) const{
516 SmallString<256> fullPath;
517 for (StringRef dir : frameworkDirs()) {
518 fullPath.assign(dir);
519 llvm::sys::path::append(fullPath, Twine(fwName) + ".framework", fwName);
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000520 if (fileExists(fullPath))
Nick Kledzik2d835da2014-08-14 22:20:41 +0000521 return fullPath.str().copy(_allocator);
522 }
523
524 return make_error_code(llvm::errc::no_such_file_or_directory);
525}
526
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000527bool MachOLinkingContext::validateImpl(raw_ostream &diagnostics) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000528 // TODO: if -arch not specified, look at arch of first .o file.
529
Tim Northoverd30a1f22014-06-20 15:59:00 +0000530 if (_currentVersion && _outputMachOType != MH_DYLIB) {
Nick Kledzike773e322013-09-10 23:55:14 +0000531 diagnostics << "error: -current_version can only be used with dylibs\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000532 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000533 }
534
Tim Northoverd30a1f22014-06-20 15:59:00 +0000535 if (_compatibilityVersion && _outputMachOType != MH_DYLIB) {
Nick Kledzike773e322013-09-10 23:55:14 +0000536 diagnostics
537 << "error: -compatibility_version can only be used with dylibs\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000538 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000539 }
540
Tim Northoverd30a1f22014-06-20 15:59:00 +0000541 if (_deadStrippableDylib && _outputMachOType != MH_DYLIB) {
Nick Kledzike773e322013-09-10 23:55:14 +0000542 diagnostics
543 << "error: -mark_dead_strippable_dylib can only be used with dylibs.\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000544 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000545 }
546
Tim Northoverd30a1f22014-06-20 15:59:00 +0000547 if (!_bundleLoader.empty() && outputMachOType() != MH_BUNDLE) {
Nick Kledzike773e322013-09-10 23:55:14 +0000548 diagnostics
549 << "error: -bundle_loader can only be used with Mach-O bundles\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000550 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000551 }
552
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000553 // If -exported_symbols_list used, all exported symbols must be defined.
554 if (_exportMode == ExportMode::whiteList) {
555 for (const auto &symbol : _exportedSymbols)
556 addInitialUndefinedSymbol(symbol.getKey());
557 }
558
Nick Kledzik77afc712014-08-21 20:25:50 +0000559 // If -dead_strip, set up initial live symbols.
560 if (deadStrip()) {
561 // Entry point is live.
562 if (outputTypeHasEntry())
563 addDeadStripRoot(entrySymbolName());
564 // Lazy binding helper is live.
565 if (needsStubsPass())
566 addDeadStripRoot(binderSymbolName());
567 // If using -exported_symbols_list, make all exported symbols live.
568 if (_exportMode == ExportMode::whiteList) {
569 _globalsAreDeadStripRoots = false;
570 for (const auto &symbol : _exportedSymbols)
571 addDeadStripRoot(symbol.getKey());
572 }
573 }
574
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000575 addOutputFileDependency(outputPath());
576
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000577 return true;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000578}
579
Shankar Easwaran2bc24922013-10-29 05:12:14 +0000580void MachOLinkingContext::addPasses(PassManager &pm) {
Nico Rieckb9d84f42014-02-24 21:14:37 +0000581 pm.add(std::unique_ptr<Pass>(new LayoutPass(registry())));
Nick Kledzik2458bec2014-07-16 19:49:02 +0000582 if (needsStubsPass())
583 mach_o::addStubsPass(pm, *this);
Tim Northovercf78d372014-09-30 21:29:54 +0000584 if (needsCompactUnwindPass())
585 mach_o::addCompactUnwindPass(pm, *this);
Nick Kledzik2458bec2014-07-16 19:49:02 +0000586 if (needsGOTPass())
587 mach_o::addGOTPass(pm, *this);
Nick Kledzik4121bce2014-10-14 01:51:42 +0000588 if (needsShimPass())
589 mach_o::addShimPass(pm, *this); // Shim pass must run after stubs pass.
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000590}
591
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000592Writer &MachOLinkingContext::writer() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000593 if (!_writer)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000594 _writer = createWriterMachO(*this);
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000595 return *_writer;
596}
597
Nick Kledzik22c90732014-10-01 20:24:30 +0000598MachODylibFile* MachOLinkingContext::loadIndirectDylib(StringRef path) {
Nick Kledzik51720672014-10-16 19:31:28 +0000599 std::unique_ptr<MachOFileNode> node(new MachOFileNode(path, *this));
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000600 std::error_code ec = node->parse(*this, llvm::errs());
601 if (ec)
602 return nullptr;
603
604 assert(node->files().size() == 1 && "expected one file in dylib");
605 // lld::File object is owned by MachOFileNode object. This method returns
606 // an unowned pointer to the lld::File object.
607 MachODylibFile* result = reinterpret_cast<MachODylibFile*>(
608 node->files().front().get());
609
610 // Node object now owned by _indirectDylibs vector.
611 _indirectDylibs.push_back(std::move(node));
612
613 return result;
614}
615
616
Nick Kledzik22c90732014-10-01 20:24:30 +0000617MachODylibFile* MachOLinkingContext::findIndirectDylib(StringRef path) {
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000618 // See if already loaded.
619 auto pos = _pathToDylibMap.find(path);
620 if (pos != _pathToDylibMap.end())
621 return pos->second;
622
623 // Search -L paths if of the form "libXXX.dylib"
624 std::pair<StringRef, StringRef> split = path.rsplit('/');
625 StringRef leafName = split.second;
626 if (leafName.startswith("lib") && leafName.endswith(".dylib")) {
627 // FIXME: Need to enhance searchLibrary() to only look for .dylib
628 auto libPath = searchLibrary(leafName);
629 if (!libPath.getError()) {
630 return loadIndirectDylib(libPath.get());
631 }
632 }
633
634 // Try full path with sysroot.
635 for (StringRef sysPath : _syslibRoots) {
636 SmallString<256> fullPath;
637 fullPath.assign(sysPath);
638 llvm::sys::path::append(fullPath, path);
639 if (pathExists(fullPath))
640 return loadIndirectDylib(fullPath);
641 }
642
643 // Try full path.
644 if (pathExists(path)) {
645 return loadIndirectDylib(path);
646 }
647
648 return nullptr;
649}
650
651bool MachOLinkingContext::createImplicitFiles(
Nick Kledzik22c90732014-10-01 20:24:30 +0000652 std::vector<std::unique_ptr<File> > &result) {
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000653 // Add indirect dylibs by asking each linked dylib to add its indirects.
654 // Iterate until no more dylibs get loaded.
655 size_t dylibCount = 0;
656 while (dylibCount != _allDylibs.size()) {
657 dylibCount = _allDylibs.size();
658 for (MachODylibFile *dylib : _allDylibs) {
659 dylib->loadReExportedDylibs([this] (StringRef path) -> MachODylibFile* {
660 return findIndirectDylib(path); });
661 }
662 }
663
664 // Let writer add output type specific extras.
665 return writer().createImplicitFiles(result);
666}
667
668
Nick Kledzik51720672014-10-16 19:31:28 +0000669void MachOLinkingContext::registerDylib(MachODylibFile *dylib,
670 bool upward) const {
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000671 _allDylibs.insert(dylib);
672 _pathToDylibMap[dylib->installName()] = dylib;
673 // If path is different than install name, register path too.
674 if (!dylib->path().equals(dylib->installName()))
675 _pathToDylibMap[dylib->path()] = dylib;
Nick Kledzik51720672014-10-16 19:31:28 +0000676 if (upward)
677 _upwardDylibs.insert(dylib);
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000678}
679
680
Nick Kledzik51720672014-10-16 19:31:28 +0000681bool MachOLinkingContext::isUpwardDylib(StringRef installName) const {
682 for (MachODylibFile *dylib : _upwardDylibs) {
683 if (dylib->installName().equals(installName))
684 return true;
685 }
686 return false;
687}
688
Nick Kledzik2458bec2014-07-16 19:49:02 +0000689ArchHandler &MachOLinkingContext::archHandler() const {
690 if (!_archHandler)
691 _archHandler = ArchHandler::create(_arch);
692 return *_archHandler;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000693}
694
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000695
Nick Kledzik2fcbe822014-07-30 00:58:06 +0000696void MachOLinkingContext::addSectionAlignment(StringRef seg, StringRef sect,
697 uint8_t align2) {
698 SectionAlign entry;
699 entry.segmentName = seg;
700 entry.sectionName = sect;
701 entry.align2 = align2;
702 _sectAligns.push_back(entry);
703}
704
705bool MachOLinkingContext::sectionAligned(StringRef seg, StringRef sect,
706 uint8_t &align2) const {
707 for (const SectionAlign &entry : _sectAligns) {
708 if (seg.equals(entry.segmentName) && sect.equals(entry.sectionName)) {
709 align2 = entry.align2;
710 return true;
711 }
712 }
713 return false;
714}
715
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000716
717void MachOLinkingContext::addExportSymbol(StringRef sym) {
Nick Kledzik4183dbc2014-10-24 22:28:54 +0000718 // Support old crufty export lists with bogus entries.
719 if (sym.endswith(".eh") || sym.startswith(".objc_category_name_")) {
720 llvm::errs() << "warning: ignoring " << sym << " in export list\n";
721 return;
722 }
723 // Only i386 MacOSX uses old ABI, so don't change those.
724 if ((_os != OS::macOSX) || (_arch != arch_x86)) {
725 // ObjC has two differnent ABIs. Be nice and allow one export list work for
726 // both ABIs by renaming symbols.
727 if (sym.startswith(".objc_class_name_")) {
728 std::string abi2className("_OBJC_CLASS_$_");
729 abi2className += sym.substr(17);
730 _exportedSymbols.insert(copy(abi2className));
731 std::string abi2metaclassName("_OBJC_METACLASS_$_");
732 abi2metaclassName += sym.substr(17);
733 _exportedSymbols.insert(copy(abi2metaclassName));
734 return;
735 }
736 }
737
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000738 // FIXME: Support wildcards.
739 _exportedSymbols.insert(sym);
740}
741
742bool MachOLinkingContext::exportSymbolNamed(StringRef sym) const {
743 switch (_exportMode) {
744 case ExportMode::globals:
745 llvm_unreachable("exportSymbolNamed() should not be called in this mode");
746 break;
747 case ExportMode::whiteList:
748 return _exportedSymbols.count(sym);
749 case ExportMode::blackList:
750 return !_exportedSymbols.count(sym);
751 }
Yaron Keren9682c852014-09-21 05:07:44 +0000752 llvm_unreachable("_exportMode unknown enum value");
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000753}
754
Nick Kledzikbe43d7e2014-09-30 23:15:39 +0000755std::string MachOLinkingContext::demangle(StringRef symbolName) const {
756 // Only try to demangle symbols if -demangle on command line
757 if (!_demangle)
758 return symbolName;
759
760 // Only try to demangle symbols that look like C++ symbols
761 if (!symbolName.startswith("__Z"))
762 return symbolName;
763
Rui Ueyama1d6d08b2014-10-21 21:05:01 +0000764#if defined(HAVE_CXXABI_H) || defined(__FreeBSD__)
Nick Kledzikbe43d7e2014-09-30 23:15:39 +0000765 SmallString<256> symBuff;
766 StringRef nullTermSym = Twine(symbolName).toNullTerminatedStringRef(symBuff);
767 // Mach-O has extra leading underscore that needs to be removed.
768 const char *cstr = nullTermSym.data() + 1;
769 int status;
770 char *demangled = abi::__cxa_demangle(cstr, nullptr, nullptr, &status);
771 if (demangled != NULL) {
772 std::string result(demangled);
773 // __cxa_demangle() always uses a malloc'ed buffer to return the result.
774 free(demangled);
775 return result;
776 }
777#endif
778
779 return symbolName;
780}
781
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000782std::error_code MachOLinkingContext::createDependencyFile(StringRef path) {
783 std::error_code ec;
784 _dependencyInfo = std::unique_ptr<llvm::raw_fd_ostream>(new
785 llvm::raw_fd_ostream(path, ec, llvm::sys::fs::F_None));
786 if (ec) {
787 _dependencyInfo.reset();
788 return ec;
789 }
790
791 char linkerVersionOpcode = 0x00;
792 *_dependencyInfo << linkerVersionOpcode;
793 *_dependencyInfo << "lld"; // FIXME
794 *_dependencyInfo << '\0';
795
796 return std::error_code();
797}
798
799void MachOLinkingContext::addInputFileDependency(StringRef path) const {
800 if (!_dependencyInfo)
801 return;
802
803 char inputFileOpcode = 0x10;
804 *_dependencyInfo << inputFileOpcode;
805 *_dependencyInfo << path;
806 *_dependencyInfo << '\0';
807}
808
809void MachOLinkingContext::addInputFileNotFound(StringRef path) const {
810 if (!_dependencyInfo)
811 return;
812
813 char inputFileOpcode = 0x11;
814 *_dependencyInfo << inputFileOpcode;
815 *_dependencyInfo << path;
816 *_dependencyInfo << '\0';
817}
818
819void MachOLinkingContext::addOutputFileDependency(StringRef path) const {
820 if (!_dependencyInfo)
821 return;
822
823 char outputFileOpcode = 0x40;
824 *_dependencyInfo << outputFileOpcode;
825 *_dependencyInfo << path;
826 *_dependencyInfo << '\0';
827}
828
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000829
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000830} // end namespace lld