blob: b6f5c3f4fc254431e775602e52217c82cf37380e [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 Ueyamadf230b22015-01-15 04:34:31 +000015#include "lld/Core/ArchiveLibraryFile.h"
Rui Ueyama0ca149f2013-08-06 22:31:59 +000016#include "lld/Core/PassManager.h"
Greg Fitzgerald4b6a7e32015-01-21 22:54:56 +000017#include "lld/Core/Reader.h"
18#include "lld/Core/Writer.h"
Rui Ueyamadf230b22015-01-15 04:34:31 +000019#include "lld/Driver/Driver.h"
Benjamin Kramer06a42af2015-03-02 00:48:06 +000020#include "llvm/ADT/STLExtras.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"
Rui Ueyama00eb2572014-12-10 00:33:00 +000024#include "llvm/Support/Debug.h"
Chandler Carruth89642a72015-01-14 11:26:52 +000025#include "llvm/Support/Errc.h"
Nick Kledzike34182f2013-11-06 21:36:55 +000026#include "llvm/Support/Host.h"
Nick Kledzik473933b2013-09-27 22:50:00 +000027#include "llvm/Support/MachO.h"
Tim Northover77d82202014-07-10 11:21:06 +000028#include "llvm/Support/Path.h"
Rui Ueyama57a29532014-08-06 19:37:35 +000029#include <algorithm>
30
Rui Ueyamafccf7ef2014-10-27 07:44:40 +000031#if defined(HAVE_CXXABI_H)
Nick Kledzikbe43d7e2014-09-30 23:15:39 +000032#include <cxxabi.h>
33#endif
34
Nick Kledzik2458bec2014-07-16 19:49:02 +000035using lld::mach_o::ArchHandler;
Nick Kledzik8fc67fb2014-08-13 23:55:41 +000036using lld::mach_o::MachODylibFile;
Nick Kledzike34182f2013-11-06 21:36:55 +000037using namespace llvm::MachO;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000038
39namespace lld {
40
Nick Kledzike850d9d2013-09-10 23:46:57 +000041bool MachOLinkingContext::parsePackedVersion(StringRef str, uint32_t &result) {
42 result = 0;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000043
44 if (str.empty())
45 return false;
46
47 SmallVector<StringRef, 3> parts;
48 llvm::SplitString(str, parts, ".");
49
50 unsigned long long num;
51 if (llvm::getAsUnsignedInteger(parts[0], 10, num))
52 return true;
53 if (num > 65535)
54 return true;
Nick Kledzike850d9d2013-09-10 23:46:57 +000055 result = num << 16;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000056
57 if (parts.size() > 1) {
58 if (llvm::getAsUnsignedInteger(parts[1], 10, num))
59 return true;
60 if (num > 255)
61 return true;
Nick Kledzike850d9d2013-09-10 23:46:57 +000062 result |= (num << 8);
Rui Ueyama0ca149f2013-08-06 22:31:59 +000063 }
64
65 if (parts.size() > 2) {
66 if (llvm::getAsUnsignedInteger(parts[2], 10, num))
67 return true;
68 if (num > 255)
69 return true;
Nick Kledzike850d9d2013-09-10 23:46:57 +000070 result |= num;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000071 }
72
73 return false;
74}
75
Rui Ueyama0ca149f2013-08-06 22:31:59 +000076
Nick Kledzike34182f2013-11-06 21:36:55 +000077MachOLinkingContext::ArchInfo MachOLinkingContext::_s_archInfos[] = {
78 { "x86_64", arch_x86_64, true, CPU_TYPE_X86_64, CPU_SUBTYPE_X86_64_ALL },
79 { "i386", arch_x86, true, CPU_TYPE_I386, CPU_SUBTYPE_X86_ALL },
80 { "ppc", arch_ppc, false, CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_ALL },
81 { "armv6", arch_armv6, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V6 },
82 { "armv7", arch_armv7, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7 },
83 { "armv7s", arch_armv7s, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7S },
Nick Kledzik1bebb282014-09-09 23:52:59 +000084 { "arm64", arch_arm64, true, CPU_TYPE_ARM64, CPU_SUBTYPE_ARM64_ALL },
Nick Kledzike34182f2013-11-06 21:36:55 +000085 { "", arch_unknown,false, 0, 0 }
Rui Ueyama0ca149f2013-08-06 22:31:59 +000086};
87
88MachOLinkingContext::Arch
89MachOLinkingContext::archFromCpuType(uint32_t cputype, uint32_t cpusubtype) {
Nick Kledzike34182f2013-11-06 21:36:55 +000090 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
91 if ((info->cputype == cputype) && (info->cpusubtype == cpusubtype))
Rui Ueyama0ca149f2013-08-06 22:31:59 +000092 return info->arch;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000093 }
94 return arch_unknown;
95}
96
97MachOLinkingContext::Arch
98MachOLinkingContext::archFromName(StringRef archName) {
Nick Kledzike34182f2013-11-06 21:36:55 +000099 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
100 if (info->archName.equals(archName))
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000101 return info->arch;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000102 }
103 return arch_unknown;
104}
105
Nick Kledzike5552772013-12-19 21:58:00 +0000106StringRef MachOLinkingContext::nameFromArch(Arch arch) {
107 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
108 if (info->arch == arch)
109 return info->archName;
110 }
111 return "<unknown>";
112}
113
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000114uint32_t MachOLinkingContext::cpuTypeFromArch(Arch arch) {
115 assert(arch != arch_unknown);
Nick Kledzike34182f2013-11-06 21:36:55 +0000116 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
117 if (info->arch == arch)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000118 return info->cputype;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000119 }
120 llvm_unreachable("Unknown arch type");
121}
122
123uint32_t MachOLinkingContext::cpuSubtypeFromArch(Arch arch) {
124 assert(arch != arch_unknown);
Nick Kledzike34182f2013-11-06 21:36:55 +0000125 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
126 if (info->arch == arch)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000127 return info->cpusubtype;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000128 }
129 llvm_unreachable("Unknown arch type");
130}
131
Nick Kledzik635f9c72014-09-04 20:08:30 +0000132bool MachOLinkingContext::isThinObjectFile(StringRef path, Arch &arch) {
133 return mach_o::normalized::isThinObjectFile(path, arch);
134}
135
Rafael Espindolaed48e532015-04-27 22:48:51 +0000136bool MachOLinkingContext::sliceFromFatFile(MemoryBufferRef mb, uint32_t &offset,
Nick Kledzik14b5d202014-10-08 01:48:10 +0000137 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),
Lang Hames65a64c92015-05-20 22:10:50 +0000145 _stackSize(0x800000), _compatibilityVersion(0), _currentVersion(0),
146 _deadStrippableDylib(false), _printAtoms(false), _testingFileUsage(false),
147 _keepPrivateExterns(false), _demangle(false), _archHandler(nullptr),
Nick Kledzik8f75da02014-11-06 03:03:42 +0000148 _exportMode(ExportMode::globals),
Nick Kledzik82d24bc2014-11-07 21:01:21 +0000149 _debugInfoMode(DebugInfoMode::addDebugMap), _orderFileEntries(0) {}
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000150
151MachOLinkingContext::~MachOLinkingContext() {}
152
Nick Kledzik6960b072013-12-21 01:47:17 +0000153void MachOLinkingContext::configure(HeaderFileType type, Arch arch, OS os,
154 uint32_t minOSVersion) {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000155 _outputMachOType = type;
Nick Kledzik6960b072013-12-21 01:47:17 +0000156 _arch = arch;
157 _os = os;
158 _osMinVersion = minOSVersion;
159
Nick Kledzikcb2018f2014-10-09 01:01:16 +0000160 // If min OS not specified on command line, use reasonable defaults.
161 if (minOSVersion == 0) {
162 switch (_arch) {
163 case arch_x86_64:
164 case arch_x86:
165 parsePackedVersion("10.8", _osMinVersion);
166 _os = MachOLinkingContext::OS::macOSX;
167 break;
168 case arch_armv6:
169 case arch_armv7:
170 case arch_armv7s:
171 case arch_arm64:
172 parsePackedVersion("7.0", _osMinVersion);
173 _os = MachOLinkingContext::OS::iOS;
174 break;
175 default:
176 break;
177 }
178 }
179
Tim Northoverd30a1f22014-06-20 15:59:00 +0000180 switch (_outputMachOType) {
Nick Kledzik6960b072013-12-21 01:47:17 +0000181 case llvm::MachO::MH_EXECUTE:
182 // If targeting newer OS, use _main
183 if (minOS("10.8", "6.0")) {
184 _entrySymbolName = "_main";
185 } else {
186 // If targeting older OS, use start (in crt1.o)
187 _entrySymbolName = "start";
188 }
189
190 // __PAGEZERO defaults to 4GB on 64-bit (except for PP64 which lld does not
191 // support) and 4KB on 32-bit.
192 if (is64Bit(_arch)) {
193 _pageZeroSize = 0x100000000;
194 } else {
195 _pageZeroSize = 0x1000;
196 }
197
Nick Kledzikb7035ae2014-09-09 00:17:52 +0000198 // Make PIE by default when targetting newer OSs.
199 switch (os) {
200 case OS::macOSX:
201 if (minOSVersion >= 0x000A0700) // MacOSX 10.7
202 _pie = true;
203 break;
204 case OS::iOS:
205 if (minOSVersion >= 0x00040300) // iOS 4.3
206 _pie = true;
207 break;
208 case OS::iOS_simulator:
209 _pie = true;
210 break;
211 case OS::unknown:
212 break;
213 }
Nick Kledzik6960b072013-12-21 01:47:17 +0000214 break;
215 case llvm::MachO::MH_DYLIB:
Davide Italiano7b68b902015-03-09 06:05:42 +0000216 setGlobalsAreDeadStripRoots(true);
Nick Kledzik6960b072013-12-21 01:47:17 +0000217 break;
218 case llvm::MachO::MH_BUNDLE:
219 break;
220 case llvm::MachO::MH_OBJECT:
221 _printRemainingUndefines = false;
222 _allowRemainingUndefines = true;
223 default:
224 break;
225 }
Nick Kledzik1bebb282014-09-09 23:52:59 +0000226
227 // Set default segment page sizes based on arch.
228 if (arch == arch_arm64)
229 _pageSize = 4*4096;
Nick Kledzik6960b072013-12-21 01:47:17 +0000230}
231
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000232uint32_t MachOLinkingContext::getCPUType() const {
233 return cpuTypeFromArch(_arch);
234}
235
236uint32_t MachOLinkingContext::getCPUSubType() const {
237 return cpuSubtypeFromArch(_arch);
238}
239
Nick Kledzike34182f2013-11-06 21:36:55 +0000240bool MachOLinkingContext::is64Bit(Arch arch) {
241 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
242 if (info->arch == arch) {
243 return (info->cputype & CPU_ARCH_ABI64);
244 }
245 }
246 // unknown archs are not 64-bit.
247 return false;
248}
249
250bool MachOLinkingContext::isHostEndian(Arch arch) {
251 assert(arch != arch_unknown);
252 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
253 if (info->arch == arch) {
254 return (info->littleEndian == llvm::sys::IsLittleEndianHost);
255 }
256 }
257 llvm_unreachable("Unknown arch type");
258}
259
260bool MachOLinkingContext::isBigEndian(Arch arch) {
261 assert(arch != arch_unknown);
262 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
263 if (info->arch == arch) {
264 return ! info->littleEndian;
265 }
266 }
267 llvm_unreachable("Unknown arch type");
268}
269
270
271
272bool MachOLinkingContext::is64Bit() const {
273 return is64Bit(_arch);
274}
275
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000276bool MachOLinkingContext::outputTypeHasEntry() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000277 switch (_outputMachOType) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000278 case MH_EXECUTE:
279 case MH_DYLINKER:
280 case MH_PRELOAD:
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000281 return true;
282 default:
283 return false;
284 }
285}
286
Nick Kledzik2458bec2014-07-16 19:49:02 +0000287bool MachOLinkingContext::needsStubsPass() const {
288 switch (_outputMachOType) {
289 case MH_EXECUTE:
290 return !_outputMachOTypeStatic;
291 case MH_DYLIB:
292 case MH_BUNDLE:
293 return true;
294 default:
295 return false;
296 }
297}
298
299bool MachOLinkingContext::needsGOTPass() const {
Nick Kledzik1bebb282014-09-09 23:52:59 +0000300 // GOT pass not used in -r mode.
301 if (_outputMachOType == MH_OBJECT)
Nick Kledzik2458bec2014-07-16 19:49:02 +0000302 return false;
Nick Kledzik1bebb282014-09-09 23:52:59 +0000303 // Only some arches use GOT pass.
304 switch (_arch) {
305 case arch_x86_64:
306 case arch_arm64:
307 return true;
308 default:
309 return false;
310 }
Nick Kledzik2458bec2014-07-16 19:49:02 +0000311}
312
Tim Northovercf78d372014-09-30 21:29:54 +0000313bool MachOLinkingContext::needsCompactUnwindPass() const {
314 switch (_outputMachOType) {
315 case MH_EXECUTE:
316 case MH_DYLIB:
317 case MH_BUNDLE:
318 return archHandler().needsCompactUnwind();
319 default:
320 return false;
321 }
322}
Nick Kledzik2458bec2014-07-16 19:49:02 +0000323
Nick Kledzik4121bce2014-10-14 01:51:42 +0000324bool MachOLinkingContext::needsShimPass() const {
325 // Shim pass only used in final executables.
326 if (_outputMachOType == MH_OBJECT)
327 return false;
328 // Only 32-bit arm arches use Shim pass.
329 switch (_arch) {
330 case arch_armv6:
331 case arch_armv7:
332 case arch_armv7s:
333 return true;
334 default:
335 return false;
336 }
337}
338
Nick Kledzik2458bec2014-07-16 19:49:02 +0000339StringRef MachOLinkingContext::binderSymbolName() const {
340 return archHandler().stubInfo().binderSymbolName;
341}
342
343
344
345
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000346bool MachOLinkingContext::minOS(StringRef mac, StringRef iOS) const {
Nick Kledzik30332b12013-10-08 00:43:34 +0000347 uint32_t parsedVersion;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000348 switch (_os) {
Nick Kledzik30332b12013-10-08 00:43:34 +0000349 case OS::macOSX:
Nick Kledzike850d9d2013-09-10 23:46:57 +0000350 if (parsePackedVersion(mac, parsedVersion))
351 return false;
352 return _osMinVersion >= parsedVersion;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000353 case OS::iOS:
Nick Kledzik30332b12013-10-08 00:43:34 +0000354 case OS::iOS_simulator:
Nick Kledzike850d9d2013-09-10 23:46:57 +0000355 if (parsePackedVersion(iOS, parsedVersion))
356 return false;
357 return _osMinVersion >= parsedVersion;
Nick Kledzik30332b12013-10-08 00:43:34 +0000358 case OS::unknown:
359 break;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000360 }
361 llvm_unreachable("target not configured for iOS or MacOSX");
362}
363
364bool MachOLinkingContext::addEntryPointLoadCommand() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000365 if ((_outputMachOType == MH_EXECUTE) && !_outputMachOTypeStatic) {
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000366 return minOS("10.8", "6.0");
367 }
368 return false;
369}
370
371bool MachOLinkingContext::addUnixThreadLoadCommand() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000372 switch (_outputMachOType) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000373 case MH_EXECUTE:
Tim Northoverd30a1f22014-06-20 15:59:00 +0000374 if (_outputMachOTypeStatic)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000375 return true;
376 else
377 return !minOS("10.8", "6.0");
378 break;
Nick Kledzike34182f2013-11-06 21:36:55 +0000379 case MH_DYLINKER:
380 case MH_PRELOAD:
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000381 return true;
382 default:
383 return false;
384 }
385}
386
Tim Northover77d82202014-07-10 11:21:06 +0000387bool MachOLinkingContext::pathExists(StringRef path) const {
Nick Kledzik94174f72014-08-15 19:53:41 +0000388 if (!_testingFileUsage)
Tim Northover77d82202014-07-10 11:21:06 +0000389 return llvm::sys::fs::exists(path.str());
390
391 // Otherwise, we're in test mode: only files explicitly provided on the
392 // command-line exist.
Rui Ueyama57a29532014-08-06 19:37:35 +0000393 std::string key = path.str();
394 std::replace(key.begin(), key.end(), '\\', '/');
395 return _existingPaths.find(key) != _existingPaths.end();
Tim Northover77d82202014-07-10 11:21:06 +0000396}
397
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000398bool MachOLinkingContext::fileExists(StringRef path) const {
399 bool found = pathExists(path);
400 // Log search misses.
401 if (!found)
402 addInputFileNotFound(path);
403
404 // When testing, file is never opened, so logging is done here.
405 if (_testingFileUsage && found)
406 addInputFileDependency(path);
407
408 return found;
409}
410
Nick Kledzik2d835da2014-08-14 22:20:41 +0000411void MachOLinkingContext::setSysLibRoots(const StringRefVector &paths) {
412 _syslibRoots = paths;
413}
414
Jean-Daniel Dupas23dd15e2014-12-18 21:33:38 +0000415void MachOLinkingContext::addRpath(StringRef rpath) {
416 _rpaths.push_back(rpath);
417}
418
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000419void MachOLinkingContext::addModifiedSearchDir(StringRef libPath,
420 bool isSystemPath) {
Tim Northover77d82202014-07-10 11:21:06 +0000421 bool addedModifiedPath = false;
422
Nick Kledzik2d835da2014-08-14 22:20:41 +0000423 // -syslibroot only applies to absolute paths.
424 if (libPath.startswith("/")) {
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000425 for (auto syslibRoot : _syslibRoots) {
Tim Northover77d82202014-07-10 11:21:06 +0000426 SmallString<256> path(syslibRoot);
427 llvm::sys::path::append(path, libPath);
428 if (pathExists(path)) {
429 _searchDirs.push_back(path.str().copy(_allocator));
430 addedModifiedPath = true;
431 }
432 }
433 }
434
435 if (addedModifiedPath)
436 return;
437
438 // Finally, if only one -syslibroot is given, system paths which aren't in it
439 // get suppressed.
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000440 if (_syslibRoots.size() != 1 || !isSystemPath) {
Tim Northover77d82202014-07-10 11:21:06 +0000441 if (pathExists(libPath)) {
442 _searchDirs.push_back(libPath);
443 }
444 }
445}
446
Nick Kledzik2d835da2014-08-14 22:20:41 +0000447void MachOLinkingContext::addFrameworkSearchDir(StringRef fwPath,
448 bool isSystemPath) {
449 bool pathAdded = false;
450
451 // -syslibroot only used with to absolute framework search paths.
452 if (fwPath.startswith("/")) {
453 for (auto syslibRoot : _syslibRoots) {
454 SmallString<256> path(syslibRoot);
455 llvm::sys::path::append(path, fwPath);
456 if (pathExists(path)) {
457 _frameworkDirs.push_back(path.str().copy(_allocator));
458 pathAdded = true;
459 }
460 }
461 }
462 // If fwPath found in any -syslibroot, then done.
463 if (pathAdded)
464 return;
465
466 // If only one -syslibroot, system paths not in that SDK are suppressed.
467 if (isSystemPath && (_syslibRoots.size() == 1))
468 return;
469
470 // Only use raw fwPath if that directory exists.
471 if (pathExists(fwPath))
472 _frameworkDirs.push_back(fwPath);
473}
474
475
Tim Northover77d82202014-07-10 11:21:06 +0000476ErrorOr<StringRef>
477MachOLinkingContext::searchDirForLibrary(StringRef path,
478 StringRef libName) const {
479 SmallString<256> fullPath;
480 if (libName.endswith(".o")) {
481 // A request ending in .o is special: just search for the file directly.
482 fullPath.assign(path);
483 llvm::sys::path::append(fullPath, libName);
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000484 if (fileExists(fullPath))
Tim Northover77d82202014-07-10 11:21:06 +0000485 return fullPath.str().copy(_allocator);
486 return make_error_code(llvm::errc::no_such_file_or_directory);
487 }
488
489 // Search for dynamic library
490 fullPath.assign(path);
491 llvm::sys::path::append(fullPath, Twine("lib") + libName + ".dylib");
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000492 if (fileExists(fullPath))
Tim Northover77d82202014-07-10 11:21:06 +0000493 return fullPath.str().copy(_allocator);
494
495 // If not, try for a static library
496 fullPath.assign(path);
497 llvm::sys::path::append(fullPath, Twine("lib") + libName + ".a");
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000498 if (fileExists(fullPath))
Tim Northover77d82202014-07-10 11:21:06 +0000499 return fullPath.str().copy(_allocator);
500
501 return make_error_code(llvm::errc::no_such_file_or_directory);
502}
503
504
505
506ErrorOr<StringRef> MachOLinkingContext::searchLibrary(StringRef libName) const {
507 SmallString<256> path;
508 for (StringRef dir : searchDirs()) {
509 ErrorOr<StringRef> ec = searchDirForLibrary(dir, libName);
510 if (ec)
511 return ec;
512 }
513
514 return make_error_code(llvm::errc::no_such_file_or_directory);
515}
516
Nick Kledzik2d835da2014-08-14 22:20:41 +0000517
518ErrorOr<StringRef> MachOLinkingContext::findPathForFramework(StringRef fwName) const{
519 SmallString<256> fullPath;
520 for (StringRef dir : frameworkDirs()) {
521 fullPath.assign(dir);
522 llvm::sys::path::append(fullPath, Twine(fwName) + ".framework", fwName);
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000523 if (fileExists(fullPath))
Nick Kledzik2d835da2014-08-14 22:20:41 +0000524 return fullPath.str().copy(_allocator);
525 }
526
527 return make_error_code(llvm::errc::no_such_file_or_directory);
528}
529
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000530bool MachOLinkingContext::validateImpl(raw_ostream &diagnostics) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000531 // TODO: if -arch not specified, look at arch of first .o file.
532
Tim Northoverd30a1f22014-06-20 15:59:00 +0000533 if (_currentVersion && _outputMachOType != MH_DYLIB) {
Nick Kledzike773e322013-09-10 23:55:14 +0000534 diagnostics << "error: -current_version can only be used with dylibs\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000535 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000536 }
537
Tim Northoverd30a1f22014-06-20 15:59:00 +0000538 if (_compatibilityVersion && _outputMachOType != MH_DYLIB) {
Nick Kledzike773e322013-09-10 23:55:14 +0000539 diagnostics
540 << "error: -compatibility_version can only be used with dylibs\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000541 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000542 }
543
Tim Northoverd30a1f22014-06-20 15:59:00 +0000544 if (_deadStrippableDylib && _outputMachOType != MH_DYLIB) {
Nick Kledzike773e322013-09-10 23:55:14 +0000545 diagnostics
546 << "error: -mark_dead_strippable_dylib can only be used with dylibs.\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000547 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000548 }
549
Tim Northoverd30a1f22014-06-20 15:59:00 +0000550 if (!_bundleLoader.empty() && outputMachOType() != MH_BUNDLE) {
Nick Kledzike773e322013-09-10 23:55:14 +0000551 diagnostics
552 << "error: -bundle_loader can only be used with Mach-O bundles\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000553 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000554 }
555
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000556 // If -exported_symbols_list used, all exported symbols must be defined.
557 if (_exportMode == ExportMode::whiteList) {
558 for (const auto &symbol : _exportedSymbols)
559 addInitialUndefinedSymbol(symbol.getKey());
560 }
561
Nick Kledzik77afc712014-08-21 20:25:50 +0000562 // If -dead_strip, set up initial live symbols.
563 if (deadStrip()) {
564 // Entry point is live.
565 if (outputTypeHasEntry())
566 addDeadStripRoot(entrySymbolName());
567 // Lazy binding helper is live.
568 if (needsStubsPass())
569 addDeadStripRoot(binderSymbolName());
570 // If using -exported_symbols_list, make all exported symbols live.
571 if (_exportMode == ExportMode::whiteList) {
Davide Italiano7b68b902015-03-09 06:05:42 +0000572 setGlobalsAreDeadStripRoots(false);
Nick Kledzik77afc712014-08-21 20:25:50 +0000573 for (const auto &symbol : _exportedSymbols)
574 addDeadStripRoot(symbol.getKey());
575 }
576 }
577
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000578 addOutputFileDependency(outputPath());
579
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000580 return true;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000581}
582
Shankar Easwaran2bc24922013-10-29 05:12:14 +0000583void MachOLinkingContext::addPasses(PassManager &pm) {
Rui Ueyama00762152015-02-05 20:05:33 +0000584 mach_o::addLayoutPass(pm, *this);
Nick Kledzik2458bec2014-07-16 19:49:02 +0000585 if (needsStubsPass())
586 mach_o::addStubsPass(pm, *this);
Tim Northovercf78d372014-09-30 21:29:54 +0000587 if (needsCompactUnwindPass())
588 mach_o::addCompactUnwindPass(pm, *this);
Nick Kledzik2458bec2014-07-16 19:49:02 +0000589 if (needsGOTPass())
590 mach_o::addGOTPass(pm, *this);
Nick Kledzik4121bce2014-10-14 01:51:42 +0000591 if (needsShimPass())
592 mach_o::addShimPass(pm, *this); // Shim pass must run after stubs pass.
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000593}
594
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000595Writer &MachOLinkingContext::writer() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000596 if (!_writer)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000597 _writer = createWriterMachO(*this);
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000598 return *_writer;
599}
600
Greg Fitzgeraldb4eb64e2015-01-23 23:26:13 +0000601ErrorOr<std::unique_ptr<MemoryBuffer>>
602MachOLinkingContext::getMemoryBuffer(StringRef path) {
603 addInputFileDependency(path);
604
Rui Ueyamadf230b22015-01-15 04:34:31 +0000605 ErrorOr<std::unique_ptr<MemoryBuffer>> mbOrErr =
Greg Fitzgeraldb4eb64e2015-01-23 23:26:13 +0000606 MemoryBuffer::getFileOrSTDIN(path);
607 if (std::error_code ec = mbOrErr.getError())
608 return ec;
609 std::unique_ptr<MemoryBuffer> mb = std::move(mbOrErr.get());
610
611 // If buffer contains a fat file, find required arch in fat buffer
612 // and switch buffer to point to just that required slice.
613 uint32_t offset;
614 uint32_t size;
Rafael Espindolaed48e532015-04-27 22:48:51 +0000615 if (sliceFromFatFile(mb->getMemBufferRef(), offset, size))
Greg Fitzgeraldb4eb64e2015-01-23 23:26:13 +0000616 return MemoryBuffer::getFileSlice(path, size, offset);
617 return std::move(mb);
618}
619
620MachODylibFile* MachOLinkingContext::loadIndirectDylib(StringRef path) {
621 ErrorOr<std::unique_ptr<MemoryBuffer>> mbOrErr = getMemoryBuffer(path);
Rui Ueyamadf230b22015-01-15 04:34:31 +0000622 if (mbOrErr.getError())
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000623 return nullptr;
624
Rafael Espindolaab5696b2015-04-24 18:51:30 +0000625 ErrorOr<std::unique_ptr<File>> fileOrErr =
626 registry().loadFile(std::move(mbOrErr.get()));
627 if (!fileOrErr)
Rui Ueyamadf230b22015-01-15 04:34:31 +0000628 return nullptr;
Rafael Espindola773a1592015-04-24 19:01:30 +0000629 std::unique_ptr<File> &file = fileOrErr.get();
630 file->parse();
631 MachODylibFile *result = reinterpret_cast<MachODylibFile *>(file.get());
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000632 // Node object now owned by _indirectDylibs vector.
Rafael Espindola773a1592015-04-24 19:01:30 +0000633 _indirectDylibs.push_back(std::move(file));
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000634 return result;
635}
636
637
Nick Kledzik22c90732014-10-01 20:24:30 +0000638MachODylibFile* MachOLinkingContext::findIndirectDylib(StringRef path) {
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000639 // See if already loaded.
640 auto pos = _pathToDylibMap.find(path);
641 if (pos != _pathToDylibMap.end())
642 return pos->second;
643
644 // Search -L paths if of the form "libXXX.dylib"
645 std::pair<StringRef, StringRef> split = path.rsplit('/');
646 StringRef leafName = split.second;
647 if (leafName.startswith("lib") && leafName.endswith(".dylib")) {
648 // FIXME: Need to enhance searchLibrary() to only look for .dylib
649 auto libPath = searchLibrary(leafName);
650 if (!libPath.getError()) {
651 return loadIndirectDylib(libPath.get());
652 }
653 }
654
655 // Try full path with sysroot.
656 for (StringRef sysPath : _syslibRoots) {
657 SmallString<256> fullPath;
658 fullPath.assign(sysPath);
659 llvm::sys::path::append(fullPath, path);
660 if (pathExists(fullPath))
661 return loadIndirectDylib(fullPath);
662 }
663
664 // Try full path.
665 if (pathExists(path)) {
666 return loadIndirectDylib(path);
667 }
668
669 return nullptr;
670}
671
Nick Kledzik5b9e48b2014-11-19 02:21:53 +0000672uint32_t MachOLinkingContext::dylibCurrentVersion(StringRef installName) const {
673 auto pos = _pathToDylibMap.find(installName);
674 if (pos != _pathToDylibMap.end())
675 return pos->second->currentVersion();
676 else
677 return 0x1000; // 1.0
678}
679
680uint32_t MachOLinkingContext::dylibCompatVersion(StringRef installName) const {
681 auto pos = _pathToDylibMap.find(installName);
682 if (pos != _pathToDylibMap.end())
683 return pos->second->compatVersion();
684 else
685 return 0x1000; // 1.0
686}
687
Simon Atanasyanc4378882015-04-06 20:43:35 +0000688void MachOLinkingContext::createImplicitFiles(
Nick Kledzik22c90732014-10-01 20:24:30 +0000689 std::vector<std::unique_ptr<File> > &result) {
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000690 // Add indirect dylibs by asking each linked dylib to add its indirects.
691 // Iterate until no more dylibs get loaded.
692 size_t dylibCount = 0;
693 while (dylibCount != _allDylibs.size()) {
694 dylibCount = _allDylibs.size();
695 for (MachODylibFile *dylib : _allDylibs) {
696 dylib->loadReExportedDylibs([this] (StringRef path) -> MachODylibFile* {
697 return findIndirectDylib(path); });
698 }
699 }
700
701 // Let writer add output type specific extras.
Simon Atanasyanc4378882015-04-06 20:43:35 +0000702 writer().createImplicitFiles(result);
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000703}
704
705
Nick Kledzik51720672014-10-16 19:31:28 +0000706void MachOLinkingContext::registerDylib(MachODylibFile *dylib,
707 bool upward) const {
Lang Hames9bbc3652015-05-13 00:17:08 +0000708 std::lock_guard<std::mutex> lock(_dylibsMutex);
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000709 _allDylibs.insert(dylib);
710 _pathToDylibMap[dylib->installName()] = dylib;
711 // If path is different than install name, register path too.
712 if (!dylib->path().equals(dylib->installName()))
713 _pathToDylibMap[dylib->path()] = dylib;
Nick Kledzik51720672014-10-16 19:31:28 +0000714 if (upward)
715 _upwardDylibs.insert(dylib);
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000716}
717
718
Nick Kledzik51720672014-10-16 19:31:28 +0000719bool MachOLinkingContext::isUpwardDylib(StringRef installName) const {
720 for (MachODylibFile *dylib : _upwardDylibs) {
721 if (dylib->installName().equals(installName))
722 return true;
723 }
724 return false;
725}
726
Nick Kledzik2458bec2014-07-16 19:49:02 +0000727ArchHandler &MachOLinkingContext::archHandler() const {
728 if (!_archHandler)
729 _archHandler = ArchHandler::create(_arch);
730 return *_archHandler;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000731}
732
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000733
Nick Kledzik2fcbe822014-07-30 00:58:06 +0000734void MachOLinkingContext::addSectionAlignment(StringRef seg, StringRef sect,
Rui Ueyamada74d572015-03-26 02:23:45 +0000735 uint16_t align) {
736 SectionAlign entry = { seg, sect, align };
Nick Kledzik2fcbe822014-07-30 00:58:06 +0000737 _sectAligns.push_back(entry);
738}
739
740bool MachOLinkingContext::sectionAligned(StringRef seg, StringRef sect,
Rui Ueyamada74d572015-03-26 02:23:45 +0000741 uint16_t &align) const {
Nick Kledzik2fcbe822014-07-30 00:58:06 +0000742 for (const SectionAlign &entry : _sectAligns) {
743 if (seg.equals(entry.segmentName) && sect.equals(entry.sectionName)) {
Rui Ueyamada74d572015-03-26 02:23:45 +0000744 align = entry.align;
Nick Kledzik2fcbe822014-07-30 00:58:06 +0000745 return true;
746 }
747 }
748 return false;
749}
750
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000751
752void MachOLinkingContext::addExportSymbol(StringRef sym) {
Nick Kledzik4183dbc2014-10-24 22:28:54 +0000753 // Support old crufty export lists with bogus entries.
754 if (sym.endswith(".eh") || sym.startswith(".objc_category_name_")) {
755 llvm::errs() << "warning: ignoring " << sym << " in export list\n";
756 return;
757 }
758 // Only i386 MacOSX uses old ABI, so don't change those.
759 if ((_os != OS::macOSX) || (_arch != arch_x86)) {
760 // ObjC has two differnent ABIs. Be nice and allow one export list work for
761 // both ABIs by renaming symbols.
762 if (sym.startswith(".objc_class_name_")) {
763 std::string abi2className("_OBJC_CLASS_$_");
764 abi2className += sym.substr(17);
765 _exportedSymbols.insert(copy(abi2className));
766 std::string abi2metaclassName("_OBJC_METACLASS_$_");
767 abi2metaclassName += sym.substr(17);
768 _exportedSymbols.insert(copy(abi2metaclassName));
769 return;
770 }
771 }
772
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000773 // FIXME: Support wildcards.
774 _exportedSymbols.insert(sym);
775}
776
777bool MachOLinkingContext::exportSymbolNamed(StringRef sym) const {
778 switch (_exportMode) {
779 case ExportMode::globals:
780 llvm_unreachable("exportSymbolNamed() should not be called in this mode");
781 break;
782 case ExportMode::whiteList:
783 return _exportedSymbols.count(sym);
784 case ExportMode::blackList:
785 return !_exportedSymbols.count(sym);
786 }
Yaron Keren9682c852014-09-21 05:07:44 +0000787 llvm_unreachable("_exportMode unknown enum value");
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000788}
789
Nick Kledzikbe43d7e2014-09-30 23:15:39 +0000790std::string MachOLinkingContext::demangle(StringRef symbolName) const {
791 // Only try to demangle symbols if -demangle on command line
Davide Italiano6d86bb22015-02-18 03:54:21 +0000792 if (!demangleSymbols())
Nick Kledzikbe43d7e2014-09-30 23:15:39 +0000793 return symbolName;
794
795 // Only try to demangle symbols that look like C++ symbols
796 if (!symbolName.startswith("__Z"))
797 return symbolName;
798
Rui Ueyamafccf7ef2014-10-27 07:44:40 +0000799#if defined(HAVE_CXXABI_H)
Nick Kledzikbe43d7e2014-09-30 23:15:39 +0000800 SmallString<256> symBuff;
801 StringRef nullTermSym = Twine(symbolName).toNullTerminatedStringRef(symBuff);
802 // Mach-O has extra leading underscore that needs to be removed.
803 const char *cstr = nullTermSym.data() + 1;
804 int status;
805 char *demangled = abi::__cxa_demangle(cstr, nullptr, nullptr, &status);
806 if (demangled != NULL) {
807 std::string result(demangled);
808 // __cxa_demangle() always uses a malloc'ed buffer to return the result.
809 free(demangled);
810 return result;
811 }
812#endif
813
814 return symbolName;
815}
816
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000817std::error_code MachOLinkingContext::createDependencyFile(StringRef path) {
818 std::error_code ec;
819 _dependencyInfo = std::unique_ptr<llvm::raw_fd_ostream>(new
820 llvm::raw_fd_ostream(path, ec, llvm::sys::fs::F_None));
821 if (ec) {
822 _dependencyInfo.reset();
823 return ec;
824 }
825
826 char linkerVersionOpcode = 0x00;
827 *_dependencyInfo << linkerVersionOpcode;
828 *_dependencyInfo << "lld"; // FIXME
829 *_dependencyInfo << '\0';
830
831 return std::error_code();
832}
833
834void MachOLinkingContext::addInputFileDependency(StringRef path) const {
835 if (!_dependencyInfo)
836 return;
837
838 char inputFileOpcode = 0x10;
839 *_dependencyInfo << inputFileOpcode;
840 *_dependencyInfo << path;
841 *_dependencyInfo << '\0';
842}
843
844void MachOLinkingContext::addInputFileNotFound(StringRef path) const {
845 if (!_dependencyInfo)
846 return;
847
848 char inputFileOpcode = 0x11;
849 *_dependencyInfo << inputFileOpcode;
850 *_dependencyInfo << path;
851 *_dependencyInfo << '\0';
852}
853
854void MachOLinkingContext::addOutputFileDependency(StringRef path) const {
855 if (!_dependencyInfo)
856 return;
857
858 char outputFileOpcode = 0x40;
859 *_dependencyInfo << outputFileOpcode;
860 *_dependencyInfo << path;
861 *_dependencyInfo << '\0';
862}
863
Nick Kledzik82d24bc2014-11-07 21:01:21 +0000864void MachOLinkingContext::appendOrderedSymbol(StringRef symbol,
865 StringRef filename) {
866 // To support sorting static functions which may have the same name in
867 // multiple .o files, _orderFiles maps the symbol name to a vector
868 // of OrderFileNode each of which can specify a file prefix.
869 OrderFileNode info;
870 if (!filename.empty())
871 info.fileFilter = copy(filename);
872 info.order = _orderFileEntries++;
873 _orderFiles[symbol].push_back(info);
874}
875
876bool
877MachOLinkingContext::findOrderOrdinal(const std::vector<OrderFileNode> &nodes,
878 const DefinedAtom *atom,
879 unsigned &ordinal) {
880 const File *objFile = &atom->file();
881 assert(objFile);
882 StringRef objName = objFile->path();
883 std::pair<StringRef, StringRef> dirAndLeaf = objName.rsplit('/');
884 if (!dirAndLeaf.second.empty())
885 objName = dirAndLeaf.second;
886 for (const OrderFileNode &info : nodes) {
887 if (info.fileFilter.empty()) {
888 // Have unprefixed symbol name in order file that matches this atom.
889 ordinal = info.order;
Nick Kledzik82d24bc2014-11-07 21:01:21 +0000890 return true;
891 }
892 if (info.fileFilter.equals(objName)) {
893 // Have prefixed symbol name in order file that matches atom's path.
894 ordinal = info.order;
Nick Kledzik82d24bc2014-11-07 21:01:21 +0000895 return true;
896 }
897 }
898 return false;
899}
900
901bool MachOLinkingContext::customAtomOrderer(const DefinedAtom *left,
902 const DefinedAtom *right,
Rui Ueyama00762152015-02-05 20:05:33 +0000903 bool &leftBeforeRight) const {
Nick Kledzik82d24bc2014-11-07 21:01:21 +0000904 // No custom sorting if no order file entries.
905 if (!_orderFileEntries)
906 return false;
907
908 // Order files can only order named atoms.
909 StringRef leftName = left->name();
910 StringRef rightName = right->name();
911 if (leftName.empty() || rightName.empty())
912 return false;
913
914 // If neither is in order file list, no custom sorter.
915 auto leftPos = _orderFiles.find(leftName);
916 auto rightPos = _orderFiles.find(rightName);
917 bool leftIsOrdered = (leftPos != _orderFiles.end());
918 bool rightIsOrdered = (rightPos != _orderFiles.end());
919 if (!leftIsOrdered && !rightIsOrdered)
920 return false;
921
922 // There could be multiple symbols with same name but different file prefixes.
923 unsigned leftOrder;
924 unsigned rightOrder;
925 bool foundLeft =
926 leftIsOrdered && findOrderOrdinal(leftPos->getValue(), left, leftOrder);
927 bool foundRight = rightIsOrdered &&
928 findOrderOrdinal(rightPos->getValue(), right, rightOrder);
929 if (!foundLeft && !foundRight)
930 return false;
931
932 // If only one is in order file list, ordered one goes first.
933 if (foundLeft != foundRight)
934 leftBeforeRight = foundLeft;
935 else
936 leftBeforeRight = (leftOrder < rightOrder);
937
938 return true;
939}
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000940
Rui Ueyama61635442015-01-15 08:31:46 +0000941static bool isLibrary(const std::unique_ptr<Node> &elem) {
Rui Ueyamaae1daae2015-01-15 08:51:23 +0000942 if (FileNode *node = dyn_cast<FileNode>(const_cast<Node *>(elem.get()))) {
943 File *file = node->getFile();
944 return isa<SharedLibraryFile>(file) || isa<ArchiveLibraryFile>(file);
945 }
946 return false;
Rui Ueyama00eb2572014-12-10 00:33:00 +0000947}
948
949// The darwin linker processes input files in two phases. The first phase
950// links in all object (.o) files in command line order. The second phase
951// links in libraries in command line order.
952// In this function we reorder the input files so that all the object files
953// comes before any library file. We also make a group for the library files
954// so that the Resolver will reiterate over the libraries as long as we find
955// new undefines from libraries.
Denis Protivenskycd617152015-03-14 10:34:43 +0000956void MachOLinkingContext::finalizeInputFiles() {
Rui Ueyama883afba2015-01-15 08:46:36 +0000957 std::vector<std::unique_ptr<Node>> &elements = getNodes();
Rui Ueyama00eb2572014-12-10 00:33:00 +0000958 std::stable_sort(elements.begin(), elements.end(),
Rui Ueyama61635442015-01-15 08:31:46 +0000959 [](const std::unique_ptr<Node> &a,
960 const std::unique_ptr<Node> &b) {
Rui Ueyama00eb2572014-12-10 00:33:00 +0000961 return !isLibrary(a) && isLibrary(b);
962 });
963 size_t numLibs = std::count_if(elements.begin(), elements.end(), isLibrary);
964 elements.push_back(llvm::make_unique<GroupEnd>(numLibs));
965}
966
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000967} // end namespace lld