blob: 4031eb8840ad1794460d97dd36aaeb3d6829a3ea [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"
Lang Hames5c692002015-09-28 20:25:14 +000013#include "FlatNamespaceFile.h"
Nick Kledzik635f9c72014-09-04 20:08:30 +000014#include "MachONormalizedFile.h"
Nick Kledzik2458bec2014-07-16 19:49:02 +000015#include "MachOPasses.h"
Rui Ueyamadf230b22015-01-15 04:34:31 +000016#include "lld/Core/ArchiveLibraryFile.h"
Rui Ueyama0ca149f2013-08-06 22:31:59 +000017#include "lld/Core/PassManager.h"
Greg Fitzgerald4b6a7e32015-01-21 22:54:56 +000018#include "lld/Core/Reader.h"
19#include "lld/Core/Writer.h"
Rui Ueyamadf230b22015-01-15 04:34:31 +000020#include "lld/Driver/Driver.h"
Benjamin Kramer06a42af2015-03-02 00:48:06 +000021#include "llvm/ADT/STLExtras.h"
Rui Ueyama0ca149f2013-08-06 22:31:59 +000022#include "llvm/ADT/StringExtras.h"
23#include "llvm/ADT/Triple.h"
Nick Kledzikbe43d7e2014-09-30 23:15:39 +000024#include "llvm/Config/config.h"
Rui Ueyama00eb2572014-12-10 00:33:00 +000025#include "llvm/Support/Debug.h"
Chandler Carruth89642a72015-01-14 11:26:52 +000026#include "llvm/Support/Errc.h"
Nick Kledzike34182f2013-11-06 21:36:55 +000027#include "llvm/Support/Host.h"
Nick Kledzik473933b2013-09-27 22:50:00 +000028#include "llvm/Support/MachO.h"
Tim Northover77d82202014-07-10 11:21:06 +000029#include "llvm/Support/Path.h"
Rui Ueyama57a29532014-08-06 19:37:35 +000030#include <algorithm>
31
Rui Ueyamafccf7ef2014-10-27 07:44:40 +000032#if defined(HAVE_CXXABI_H)
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
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 Hamesff4b13c2015-05-22 00:25:34 +0000145 _stackSize(0), _compatibilityVersion(0), _currentVersion(0),
Lang Hames5c692002015-09-28 20:25:14 +0000146 _flatNamespace(false), _undefinedMode(UndefinedMode::error),
Lang Hames65a64c92015-05-20 22:10:50 +0000147 _deadStrippableDylib(false), _printAtoms(false), _testingFileUsage(false),
148 _keepPrivateExterns(false), _demangle(false), _archHandler(nullptr),
Nick Kledzik8f75da02014-11-06 03:03:42 +0000149 _exportMode(ExportMode::globals),
Lang Hames5c692002015-09-28 20:25:14 +0000150 _debugInfoMode(DebugInfoMode::addDebugMap), _orderFileEntries(0),
151 _flatNamespaceFile(nullptr) {}
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000152
153MachOLinkingContext::~MachOLinkingContext() {}
154
Nick Kledzik6960b072013-12-21 01:47:17 +0000155void MachOLinkingContext::configure(HeaderFileType type, Arch arch, OS os,
156 uint32_t minOSVersion) {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000157 _outputMachOType = type;
Nick Kledzik6960b072013-12-21 01:47:17 +0000158 _arch = arch;
159 _os = os;
160 _osMinVersion = minOSVersion;
161
Nick Kledzikcb2018f2014-10-09 01:01:16 +0000162 // If min OS not specified on command line, use reasonable defaults.
163 if (minOSVersion == 0) {
164 switch (_arch) {
165 case arch_x86_64:
166 case arch_x86:
167 parsePackedVersion("10.8", _osMinVersion);
168 _os = MachOLinkingContext::OS::macOSX;
169 break;
170 case arch_armv6:
171 case arch_armv7:
172 case arch_armv7s:
173 case arch_arm64:
174 parsePackedVersion("7.0", _osMinVersion);
175 _os = MachOLinkingContext::OS::iOS;
176 break;
177 default:
178 break;
179 }
180 }
181
Tim Northoverd30a1f22014-06-20 15:59:00 +0000182 switch (_outputMachOType) {
Nick Kledzik6960b072013-12-21 01:47:17 +0000183 case llvm::MachO::MH_EXECUTE:
184 // If targeting newer OS, use _main
185 if (minOS("10.8", "6.0")) {
186 _entrySymbolName = "_main";
187 } else {
188 // If targeting older OS, use start (in crt1.o)
189 _entrySymbolName = "start";
190 }
191
192 // __PAGEZERO defaults to 4GB on 64-bit (except for PP64 which lld does not
193 // support) and 4KB on 32-bit.
194 if (is64Bit(_arch)) {
195 _pageZeroSize = 0x100000000;
196 } else {
197 _pageZeroSize = 0x1000;
198 }
199
Lang Hamesc80344282015-09-21 22:06:02 +0000200 // Initial base address is __PAGEZERO size.
201 _baseAddress = _pageZeroSize;
202
Nick Kledzikb7035ae2014-09-09 00:17:52 +0000203 // Make PIE by default when targetting newer OSs.
204 switch (os) {
205 case OS::macOSX:
206 if (minOSVersion >= 0x000A0700) // MacOSX 10.7
207 _pie = true;
208 break;
209 case OS::iOS:
210 if (minOSVersion >= 0x00040300) // iOS 4.3
211 _pie = true;
212 break;
213 case OS::iOS_simulator:
214 _pie = true;
215 break;
216 case OS::unknown:
217 break;
218 }
Nick Kledzik6960b072013-12-21 01:47:17 +0000219 break;
220 case llvm::MachO::MH_DYLIB:
Davide Italiano7b68b902015-03-09 06:05:42 +0000221 setGlobalsAreDeadStripRoots(true);
Nick Kledzik6960b072013-12-21 01:47:17 +0000222 break;
223 case llvm::MachO::MH_BUNDLE:
224 break;
225 case llvm::MachO::MH_OBJECT:
226 _printRemainingUndefines = false;
227 _allowRemainingUndefines = true;
228 default:
229 break;
230 }
Nick Kledzik1bebb282014-09-09 23:52:59 +0000231
232 // Set default segment page sizes based on arch.
233 if (arch == arch_arm64)
234 _pageSize = 4*4096;
Nick Kledzik6960b072013-12-21 01:47:17 +0000235}
236
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000237uint32_t MachOLinkingContext::getCPUType() const {
238 return cpuTypeFromArch(_arch);
239}
240
241uint32_t MachOLinkingContext::getCPUSubType() const {
242 return cpuSubtypeFromArch(_arch);
243}
244
Nick Kledzike34182f2013-11-06 21:36:55 +0000245bool MachOLinkingContext::is64Bit(Arch arch) {
246 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
247 if (info->arch == arch) {
248 return (info->cputype & CPU_ARCH_ABI64);
249 }
250 }
251 // unknown archs are not 64-bit.
252 return false;
253}
254
255bool MachOLinkingContext::isHostEndian(Arch arch) {
256 assert(arch != arch_unknown);
257 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
258 if (info->arch == arch) {
259 return (info->littleEndian == llvm::sys::IsLittleEndianHost);
260 }
261 }
262 llvm_unreachable("Unknown arch type");
263}
264
265bool MachOLinkingContext::isBigEndian(Arch arch) {
266 assert(arch != arch_unknown);
267 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
268 if (info->arch == arch) {
269 return ! info->littleEndian;
270 }
271 }
272 llvm_unreachable("Unknown arch type");
273}
274
Nick Kledzike34182f2013-11-06 21:36:55 +0000275bool MachOLinkingContext::is64Bit() const {
276 return is64Bit(_arch);
277}
278
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000279bool MachOLinkingContext::outputTypeHasEntry() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000280 switch (_outputMachOType) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000281 case MH_EXECUTE:
282 case MH_DYLINKER:
283 case MH_PRELOAD:
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000284 return true;
285 default:
286 return false;
287 }
288}
289
Nick Kledzik2458bec2014-07-16 19:49:02 +0000290bool MachOLinkingContext::needsStubsPass() const {
291 switch (_outputMachOType) {
292 case MH_EXECUTE:
293 return !_outputMachOTypeStatic;
294 case MH_DYLIB:
295 case MH_BUNDLE:
296 return true;
297 default:
298 return false;
299 }
300}
301
302bool MachOLinkingContext::needsGOTPass() const {
Nick Kledzik1bebb282014-09-09 23:52:59 +0000303 // GOT pass not used in -r mode.
304 if (_outputMachOType == MH_OBJECT)
Nick Kledzik2458bec2014-07-16 19:49:02 +0000305 return false;
Nick Kledzik1bebb282014-09-09 23:52:59 +0000306 // Only some arches use GOT pass.
307 switch (_arch) {
308 case arch_x86_64:
309 case arch_arm64:
310 return true;
311 default:
312 return false;
313 }
Nick Kledzik2458bec2014-07-16 19:49:02 +0000314}
315
Tim Northovercf78d372014-09-30 21:29:54 +0000316bool MachOLinkingContext::needsCompactUnwindPass() const {
317 switch (_outputMachOType) {
318 case MH_EXECUTE:
319 case MH_DYLIB:
320 case MH_BUNDLE:
321 return archHandler().needsCompactUnwind();
322 default:
323 return false;
324 }
325}
Nick Kledzik2458bec2014-07-16 19:49:02 +0000326
Nick Kledzik4121bce2014-10-14 01:51:42 +0000327bool MachOLinkingContext::needsShimPass() const {
328 // Shim pass only used in final executables.
329 if (_outputMachOType == MH_OBJECT)
330 return false;
331 // Only 32-bit arm arches use Shim pass.
332 switch (_arch) {
333 case arch_armv6:
334 case arch_armv7:
335 case arch_armv7s:
336 return true;
337 default:
338 return false;
339 }
340}
341
Lang Hames49047032015-06-23 20:35:31 +0000342bool MachOLinkingContext::needsTLVPass() const {
343 switch (_outputMachOType) {
344 case MH_BUNDLE:
345 case MH_EXECUTE:
346 case MH_DYLIB:
347 return true;
348 default:
349 return false;
350 }
351}
352
Nick Kledzik2458bec2014-07-16 19:49:02 +0000353StringRef MachOLinkingContext::binderSymbolName() const {
354 return archHandler().stubInfo().binderSymbolName;
355}
356
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000357bool MachOLinkingContext::minOS(StringRef mac, StringRef iOS) const {
Nick Kledzik30332b12013-10-08 00:43:34 +0000358 uint32_t parsedVersion;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000359 switch (_os) {
Nick Kledzik30332b12013-10-08 00:43:34 +0000360 case OS::macOSX:
Nick Kledzike850d9d2013-09-10 23:46:57 +0000361 if (parsePackedVersion(mac, parsedVersion))
362 return false;
363 return _osMinVersion >= parsedVersion;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000364 case OS::iOS:
Nick Kledzik30332b12013-10-08 00:43:34 +0000365 case OS::iOS_simulator:
Nick Kledzike850d9d2013-09-10 23:46:57 +0000366 if (parsePackedVersion(iOS, parsedVersion))
367 return false;
368 return _osMinVersion >= parsedVersion;
Nick Kledzik30332b12013-10-08 00:43:34 +0000369 case OS::unknown:
370 break;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000371 }
372 llvm_unreachable("target not configured for iOS or MacOSX");
373}
374
375bool MachOLinkingContext::addEntryPointLoadCommand() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000376 if ((_outputMachOType == MH_EXECUTE) && !_outputMachOTypeStatic) {
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000377 return minOS("10.8", "6.0");
378 }
379 return false;
380}
381
382bool MachOLinkingContext::addUnixThreadLoadCommand() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000383 switch (_outputMachOType) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000384 case MH_EXECUTE:
Tim Northoverd30a1f22014-06-20 15:59:00 +0000385 if (_outputMachOTypeStatic)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000386 return true;
387 else
388 return !minOS("10.8", "6.0");
389 break;
Nick Kledzike34182f2013-11-06 21:36:55 +0000390 case MH_DYLINKER:
391 case MH_PRELOAD:
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000392 return true;
393 default:
394 return false;
395 }
396}
397
Tim Northover77d82202014-07-10 11:21:06 +0000398bool MachOLinkingContext::pathExists(StringRef path) const {
Nick Kledzik94174f72014-08-15 19:53:41 +0000399 if (!_testingFileUsage)
Tim Northover77d82202014-07-10 11:21:06 +0000400 return llvm::sys::fs::exists(path.str());
401
402 // Otherwise, we're in test mode: only files explicitly provided on the
403 // command-line exist.
Rui Ueyama57a29532014-08-06 19:37:35 +0000404 std::string key = path.str();
405 std::replace(key.begin(), key.end(), '\\', '/');
406 return _existingPaths.find(key) != _existingPaths.end();
Tim Northover77d82202014-07-10 11:21:06 +0000407}
408
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000409bool MachOLinkingContext::fileExists(StringRef path) const {
410 bool found = pathExists(path);
411 // Log search misses.
412 if (!found)
413 addInputFileNotFound(path);
414
415 // When testing, file is never opened, so logging is done here.
416 if (_testingFileUsage && found)
417 addInputFileDependency(path);
418
419 return found;
420}
421
Nick Kledzik2d835da2014-08-14 22:20:41 +0000422void MachOLinkingContext::setSysLibRoots(const StringRefVector &paths) {
423 _syslibRoots = paths;
424}
425
Jean-Daniel Dupas23dd15e2014-12-18 21:33:38 +0000426void MachOLinkingContext::addRpath(StringRef rpath) {
427 _rpaths.push_back(rpath);
428}
429
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000430void MachOLinkingContext::addModifiedSearchDir(StringRef libPath,
431 bool isSystemPath) {
Tim Northover77d82202014-07-10 11:21:06 +0000432 bool addedModifiedPath = false;
433
Nick Kledzik2d835da2014-08-14 22:20:41 +0000434 // -syslibroot only applies to absolute paths.
435 if (libPath.startswith("/")) {
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000436 for (auto syslibRoot : _syslibRoots) {
Tim Northover77d82202014-07-10 11:21:06 +0000437 SmallString<256> path(syslibRoot);
438 llvm::sys::path::append(path, libPath);
439 if (pathExists(path)) {
440 _searchDirs.push_back(path.str().copy(_allocator));
441 addedModifiedPath = true;
442 }
443 }
444 }
445
446 if (addedModifiedPath)
447 return;
448
449 // Finally, if only one -syslibroot is given, system paths which aren't in it
450 // get suppressed.
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000451 if (_syslibRoots.size() != 1 || !isSystemPath) {
Tim Northover77d82202014-07-10 11:21:06 +0000452 if (pathExists(libPath)) {
453 _searchDirs.push_back(libPath);
454 }
455 }
456}
457
Nick Kledzik2d835da2014-08-14 22:20:41 +0000458void MachOLinkingContext::addFrameworkSearchDir(StringRef fwPath,
459 bool isSystemPath) {
460 bool pathAdded = false;
461
462 // -syslibroot only used with to absolute framework search paths.
463 if (fwPath.startswith("/")) {
464 for (auto syslibRoot : _syslibRoots) {
465 SmallString<256> path(syslibRoot);
466 llvm::sys::path::append(path, fwPath);
467 if (pathExists(path)) {
468 _frameworkDirs.push_back(path.str().copy(_allocator));
469 pathAdded = true;
470 }
471 }
472 }
473 // If fwPath found in any -syslibroot, then done.
474 if (pathAdded)
475 return;
476
477 // If only one -syslibroot, system paths not in that SDK are suppressed.
478 if (isSystemPath && (_syslibRoots.size() == 1))
479 return;
480
481 // Only use raw fwPath if that directory exists.
482 if (pathExists(fwPath))
483 _frameworkDirs.push_back(fwPath);
484}
485
Tim Northover77d82202014-07-10 11:21:06 +0000486ErrorOr<StringRef>
487MachOLinkingContext::searchDirForLibrary(StringRef path,
488 StringRef libName) const {
489 SmallString<256> fullPath;
490 if (libName.endswith(".o")) {
491 // A request ending in .o is special: just search for the file directly.
492 fullPath.assign(path);
493 llvm::sys::path::append(fullPath, libName);
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000494 if (fileExists(fullPath))
Tim Northover77d82202014-07-10 11:21:06 +0000495 return fullPath.str().copy(_allocator);
496 return make_error_code(llvm::errc::no_such_file_or_directory);
497 }
498
499 // Search for dynamic library
500 fullPath.assign(path);
501 llvm::sys::path::append(fullPath, Twine("lib") + libName + ".dylib");
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000502 if (fileExists(fullPath))
Tim Northover77d82202014-07-10 11:21:06 +0000503 return fullPath.str().copy(_allocator);
504
505 // If not, try for a static library
506 fullPath.assign(path);
507 llvm::sys::path::append(fullPath, Twine("lib") + libName + ".a");
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000508 if (fileExists(fullPath))
Tim Northover77d82202014-07-10 11:21:06 +0000509 return fullPath.str().copy(_allocator);
510
511 return make_error_code(llvm::errc::no_such_file_or_directory);
512}
513
Tim Northover77d82202014-07-10 11:21:06 +0000514ErrorOr<StringRef> MachOLinkingContext::searchLibrary(StringRef libName) const {
515 SmallString<256> path;
516 for (StringRef dir : searchDirs()) {
517 ErrorOr<StringRef> ec = searchDirForLibrary(dir, libName);
518 if (ec)
519 return ec;
520 }
521
522 return make_error_code(llvm::errc::no_such_file_or_directory);
523}
524
Nick Kledzik2d835da2014-08-14 22:20:41 +0000525ErrorOr<StringRef> MachOLinkingContext::findPathForFramework(StringRef fwName) const{
526 SmallString<256> fullPath;
527 for (StringRef dir : frameworkDirs()) {
528 fullPath.assign(dir);
529 llvm::sys::path::append(fullPath, Twine(fwName) + ".framework", fwName);
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000530 if (fileExists(fullPath))
Nick Kledzik2d835da2014-08-14 22:20:41 +0000531 return fullPath.str().copy(_allocator);
532 }
533
534 return make_error_code(llvm::errc::no_such_file_or_directory);
535}
536
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000537bool MachOLinkingContext::validateImpl(raw_ostream &diagnostics) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000538 // TODO: if -arch not specified, look at arch of first .o file.
539
Tim Northoverd30a1f22014-06-20 15:59:00 +0000540 if (_currentVersion && _outputMachOType != MH_DYLIB) {
Nick Kledzike773e322013-09-10 23:55:14 +0000541 diagnostics << "error: -current_version 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 (_compatibilityVersion && _outputMachOType != MH_DYLIB) {
Nick Kledzike773e322013-09-10 23:55:14 +0000546 diagnostics
547 << "error: -compatibility_version can only be used with dylibs\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000548 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000549 }
550
Tim Northoverd30a1f22014-06-20 15:59:00 +0000551 if (_deadStrippableDylib && _outputMachOType != MH_DYLIB) {
Nick Kledzike773e322013-09-10 23:55:14 +0000552 diagnostics
553 << "error: -mark_dead_strippable_dylib can only be used with dylibs.\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000554 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000555 }
556
Tim Northoverd30a1f22014-06-20 15:59:00 +0000557 if (!_bundleLoader.empty() && outputMachOType() != MH_BUNDLE) {
Nick Kledzike773e322013-09-10 23:55:14 +0000558 diagnostics
559 << "error: -bundle_loader can only be used with Mach-O bundles\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000560 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000561 }
562
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000563 // If -exported_symbols_list used, all exported symbols must be defined.
564 if (_exportMode == ExportMode::whiteList) {
565 for (const auto &symbol : _exportedSymbols)
566 addInitialUndefinedSymbol(symbol.getKey());
567 }
568
Nick Kledzik77afc712014-08-21 20:25:50 +0000569 // If -dead_strip, set up initial live symbols.
570 if (deadStrip()) {
571 // Entry point is live.
572 if (outputTypeHasEntry())
573 addDeadStripRoot(entrySymbolName());
574 // Lazy binding helper is live.
575 if (needsStubsPass())
576 addDeadStripRoot(binderSymbolName());
577 // If using -exported_symbols_list, make all exported symbols live.
578 if (_exportMode == ExportMode::whiteList) {
Davide Italiano7b68b902015-03-09 06:05:42 +0000579 setGlobalsAreDeadStripRoots(false);
Nick Kledzik77afc712014-08-21 20:25:50 +0000580 for (const auto &symbol : _exportedSymbols)
581 addDeadStripRoot(symbol.getKey());
582 }
583 }
584
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000585 addOutputFileDependency(outputPath());
586
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000587 return true;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000588}
589
Shankar Easwaran2bc24922013-10-29 05:12:14 +0000590void MachOLinkingContext::addPasses(PassManager &pm) {
Rui Ueyama00762152015-02-05 20:05:33 +0000591 mach_o::addLayoutPass(pm, *this);
Nick Kledzik2458bec2014-07-16 19:49:02 +0000592 if (needsStubsPass())
593 mach_o::addStubsPass(pm, *this);
Tim Northovercf78d372014-09-30 21:29:54 +0000594 if (needsCompactUnwindPass())
595 mach_o::addCompactUnwindPass(pm, *this);
Nick Kledzik2458bec2014-07-16 19:49:02 +0000596 if (needsGOTPass())
597 mach_o::addGOTPass(pm, *this);
Lang Hames49047032015-06-23 20:35:31 +0000598 if (needsTLVPass())
599 mach_o::addTLVPass(pm, *this);
Nick Kledzik4121bce2014-10-14 01:51:42 +0000600 if (needsShimPass())
601 mach_o::addShimPass(pm, *this); // Shim pass must run after stubs pass.
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000602}
603
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000604Writer &MachOLinkingContext::writer() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000605 if (!_writer)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000606 _writer = createWriterMachO(*this);
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000607 return *_writer;
608}
609
Greg Fitzgeraldb4eb64e2015-01-23 23:26:13 +0000610ErrorOr<std::unique_ptr<MemoryBuffer>>
611MachOLinkingContext::getMemoryBuffer(StringRef path) {
612 addInputFileDependency(path);
613
Rui Ueyamadf230b22015-01-15 04:34:31 +0000614 ErrorOr<std::unique_ptr<MemoryBuffer>> mbOrErr =
Greg Fitzgeraldb4eb64e2015-01-23 23:26:13 +0000615 MemoryBuffer::getFileOrSTDIN(path);
616 if (std::error_code ec = mbOrErr.getError())
617 return ec;
618 std::unique_ptr<MemoryBuffer> mb = std::move(mbOrErr.get());
619
620 // If buffer contains a fat file, find required arch in fat buffer
621 // and switch buffer to point to just that required slice.
622 uint32_t offset;
623 uint32_t size;
Rafael Espindolaed48e532015-04-27 22:48:51 +0000624 if (sliceFromFatFile(mb->getMemBufferRef(), offset, size))
Greg Fitzgeraldb4eb64e2015-01-23 23:26:13 +0000625 return MemoryBuffer::getFileSlice(path, size, offset);
626 return std::move(mb);
627}
628
629MachODylibFile* MachOLinkingContext::loadIndirectDylib(StringRef path) {
630 ErrorOr<std::unique_ptr<MemoryBuffer>> mbOrErr = getMemoryBuffer(path);
Rui Ueyamadf230b22015-01-15 04:34:31 +0000631 if (mbOrErr.getError())
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000632 return nullptr;
633
Rafael Espindolaab5696b2015-04-24 18:51:30 +0000634 ErrorOr<std::unique_ptr<File>> fileOrErr =
635 registry().loadFile(std::move(mbOrErr.get()));
636 if (!fileOrErr)
Rui Ueyamadf230b22015-01-15 04:34:31 +0000637 return nullptr;
Rafael Espindola773a1592015-04-24 19:01:30 +0000638 std::unique_ptr<File> &file = fileOrErr.get();
639 file->parse();
640 MachODylibFile *result = reinterpret_cast<MachODylibFile *>(file.get());
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000641 // Node object now owned by _indirectDylibs vector.
Rafael Espindola773a1592015-04-24 19:01:30 +0000642 _indirectDylibs.push_back(std::move(file));
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000643 return result;
644}
645
Nick Kledzik22c90732014-10-01 20:24:30 +0000646MachODylibFile* MachOLinkingContext::findIndirectDylib(StringRef path) {
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000647 // See if already loaded.
648 auto pos = _pathToDylibMap.find(path);
649 if (pos != _pathToDylibMap.end())
650 return pos->second;
651
652 // Search -L paths if of the form "libXXX.dylib"
653 std::pair<StringRef, StringRef> split = path.rsplit('/');
654 StringRef leafName = split.second;
655 if (leafName.startswith("lib") && leafName.endswith(".dylib")) {
656 // FIXME: Need to enhance searchLibrary() to only look for .dylib
657 auto libPath = searchLibrary(leafName);
658 if (!libPath.getError()) {
659 return loadIndirectDylib(libPath.get());
660 }
661 }
662
663 // Try full path with sysroot.
664 for (StringRef sysPath : _syslibRoots) {
665 SmallString<256> fullPath;
666 fullPath.assign(sysPath);
667 llvm::sys::path::append(fullPath, path);
668 if (pathExists(fullPath))
669 return loadIndirectDylib(fullPath);
670 }
671
672 // Try full path.
673 if (pathExists(path)) {
674 return loadIndirectDylib(path);
675 }
676
677 return nullptr;
678}
679
Nick Kledzik5b9e48b2014-11-19 02:21:53 +0000680uint32_t MachOLinkingContext::dylibCurrentVersion(StringRef installName) const {
681 auto pos = _pathToDylibMap.find(installName);
682 if (pos != _pathToDylibMap.end())
683 return pos->second->currentVersion();
684 else
685 return 0x1000; // 1.0
686}
687
688uint32_t MachOLinkingContext::dylibCompatVersion(StringRef installName) const {
689 auto pos = _pathToDylibMap.find(installName);
690 if (pos != _pathToDylibMap.end())
691 return pos->second->compatVersion();
692 else
693 return 0x1000; // 1.0
694}
695
Simon Atanasyanc4378882015-04-06 20:43:35 +0000696void MachOLinkingContext::createImplicitFiles(
Nick Kledzik22c90732014-10-01 20:24:30 +0000697 std::vector<std::unique_ptr<File> > &result) {
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000698 // Add indirect dylibs by asking each linked dylib to add its indirects.
699 // Iterate until no more dylibs get loaded.
700 size_t dylibCount = 0;
701 while (dylibCount != _allDylibs.size()) {
702 dylibCount = _allDylibs.size();
703 for (MachODylibFile *dylib : _allDylibs) {
704 dylib->loadReExportedDylibs([this] (StringRef path) -> MachODylibFile* {
705 return findIndirectDylib(path); });
706 }
707 }
708
709 // Let writer add output type specific extras.
Simon Atanasyanc4378882015-04-06 20:43:35 +0000710 writer().createImplicitFiles(result);
Lang Hames5c692002015-09-28 20:25:14 +0000711
Lang Hames9a4c94e2015-09-28 20:52:21 +0000712 // If undefinedMode is != error, add a FlatNamespaceFile instance. This will
713 // provide a SharedLibraryAtom for symbols that aren't defined elsewhere.
714 if (undefinedMode() != UndefinedMode::error) {
715 result.emplace_back(new mach_o::FlatNamespaceFile(*this));
Lang Hames5c692002015-09-28 20:25:14 +0000716 _flatNamespaceFile = result.back().get();
717 }
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000718}
719
Nick Kledzik51720672014-10-16 19:31:28 +0000720void MachOLinkingContext::registerDylib(MachODylibFile *dylib,
721 bool upward) const {
Lang Hames9bbc3652015-05-13 00:17:08 +0000722 std::lock_guard<std::mutex> lock(_dylibsMutex);
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000723 _allDylibs.insert(dylib);
724 _pathToDylibMap[dylib->installName()] = dylib;
725 // If path is different than install name, register path too.
726 if (!dylib->path().equals(dylib->installName()))
727 _pathToDylibMap[dylib->path()] = dylib;
Nick Kledzik51720672014-10-16 19:31:28 +0000728 if (upward)
729 _upwardDylibs.insert(dylib);
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000730}
731
Nick Kledzik51720672014-10-16 19:31:28 +0000732bool MachOLinkingContext::isUpwardDylib(StringRef installName) const {
733 for (MachODylibFile *dylib : _upwardDylibs) {
734 if (dylib->installName().equals(installName))
735 return true;
736 }
737 return false;
738}
739
Nick Kledzik2458bec2014-07-16 19:49:02 +0000740ArchHandler &MachOLinkingContext::archHandler() const {
741 if (!_archHandler)
742 _archHandler = ArchHandler::create(_arch);
743 return *_archHandler;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000744}
745
Nick Kledzik2fcbe822014-07-30 00:58:06 +0000746void MachOLinkingContext::addSectionAlignment(StringRef seg, StringRef sect,
Rui Ueyamada74d572015-03-26 02:23:45 +0000747 uint16_t align) {
748 SectionAlign entry = { seg, sect, align };
Nick Kledzik2fcbe822014-07-30 00:58:06 +0000749 _sectAligns.push_back(entry);
750}
751
752bool MachOLinkingContext::sectionAligned(StringRef seg, StringRef sect,
Rui Ueyamada74d572015-03-26 02:23:45 +0000753 uint16_t &align) const {
Nick Kledzik2fcbe822014-07-30 00:58:06 +0000754 for (const SectionAlign &entry : _sectAligns) {
755 if (seg.equals(entry.segmentName) && sect.equals(entry.sectionName)) {
Rui Ueyamada74d572015-03-26 02:23:45 +0000756 align = entry.align;
Nick Kledzik2fcbe822014-07-30 00:58:06 +0000757 return true;
758 }
759 }
760 return false;
761}
762
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000763void MachOLinkingContext::addExportSymbol(StringRef sym) {
Nick Kledzik4183dbc2014-10-24 22:28:54 +0000764 // Support old crufty export lists with bogus entries.
765 if (sym.endswith(".eh") || sym.startswith(".objc_category_name_")) {
766 llvm::errs() << "warning: ignoring " << sym << " in export list\n";
767 return;
768 }
769 // Only i386 MacOSX uses old ABI, so don't change those.
770 if ((_os != OS::macOSX) || (_arch != arch_x86)) {
771 // ObjC has two differnent ABIs. Be nice and allow one export list work for
772 // both ABIs by renaming symbols.
773 if (sym.startswith(".objc_class_name_")) {
774 std::string abi2className("_OBJC_CLASS_$_");
775 abi2className += sym.substr(17);
776 _exportedSymbols.insert(copy(abi2className));
777 std::string abi2metaclassName("_OBJC_METACLASS_$_");
778 abi2metaclassName += sym.substr(17);
779 _exportedSymbols.insert(copy(abi2metaclassName));
780 return;
781 }
782 }
783
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000784 // FIXME: Support wildcards.
785 _exportedSymbols.insert(sym);
786}
787
788bool MachOLinkingContext::exportSymbolNamed(StringRef sym) const {
789 switch (_exportMode) {
790 case ExportMode::globals:
791 llvm_unreachable("exportSymbolNamed() should not be called in this mode");
792 break;
793 case ExportMode::whiteList:
794 return _exportedSymbols.count(sym);
795 case ExportMode::blackList:
796 return !_exportedSymbols.count(sym);
797 }
Yaron Keren9682c852014-09-21 05:07:44 +0000798 llvm_unreachable("_exportMode unknown enum value");
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000799}
800
Nick Kledzikbe43d7e2014-09-30 23:15:39 +0000801std::string MachOLinkingContext::demangle(StringRef symbolName) const {
802 // Only try to demangle symbols if -demangle on command line
Davide Italiano6d86bb22015-02-18 03:54:21 +0000803 if (!demangleSymbols())
Nick Kledzikbe43d7e2014-09-30 23:15:39 +0000804 return symbolName;
805
806 // Only try to demangle symbols that look like C++ symbols
807 if (!symbolName.startswith("__Z"))
808 return symbolName;
809
Rui Ueyamafccf7ef2014-10-27 07:44:40 +0000810#if defined(HAVE_CXXABI_H)
Nick Kledzikbe43d7e2014-09-30 23:15:39 +0000811 SmallString<256> symBuff;
812 StringRef nullTermSym = Twine(symbolName).toNullTerminatedStringRef(symBuff);
813 // Mach-O has extra leading underscore that needs to be removed.
814 const char *cstr = nullTermSym.data() + 1;
815 int status;
816 char *demangled = abi::__cxa_demangle(cstr, nullptr, nullptr, &status);
Rui Ueyama43155d02015-10-02 00:36:00 +0000817 if (demangled) {
Nick Kledzikbe43d7e2014-09-30 23:15:39 +0000818 std::string result(demangled);
819 // __cxa_demangle() always uses a malloc'ed buffer to return the result.
820 free(demangled);
821 return result;
822 }
823#endif
824
825 return symbolName;
826}
827
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000828std::error_code MachOLinkingContext::createDependencyFile(StringRef path) {
829 std::error_code ec;
830 _dependencyInfo = std::unique_ptr<llvm::raw_fd_ostream>(new
831 llvm::raw_fd_ostream(path, ec, llvm::sys::fs::F_None));
832 if (ec) {
833 _dependencyInfo.reset();
834 return ec;
835 }
836
837 char linkerVersionOpcode = 0x00;
838 *_dependencyInfo << linkerVersionOpcode;
839 *_dependencyInfo << "lld"; // FIXME
840 *_dependencyInfo << '\0';
841
842 return std::error_code();
843}
844
845void MachOLinkingContext::addInputFileDependency(StringRef path) const {
846 if (!_dependencyInfo)
847 return;
848
849 char inputFileOpcode = 0x10;
850 *_dependencyInfo << inputFileOpcode;
851 *_dependencyInfo << path;
852 *_dependencyInfo << '\0';
853}
854
855void MachOLinkingContext::addInputFileNotFound(StringRef path) const {
856 if (!_dependencyInfo)
857 return;
858
859 char inputFileOpcode = 0x11;
860 *_dependencyInfo << inputFileOpcode;
861 *_dependencyInfo << path;
862 *_dependencyInfo << '\0';
863}
864
865void MachOLinkingContext::addOutputFileDependency(StringRef path) const {
866 if (!_dependencyInfo)
867 return;
868
869 char outputFileOpcode = 0x40;
870 *_dependencyInfo << outputFileOpcode;
871 *_dependencyInfo << path;
872 *_dependencyInfo << '\0';
873}
874
Nick Kledzik82d24bc2014-11-07 21:01:21 +0000875void MachOLinkingContext::appendOrderedSymbol(StringRef symbol,
876 StringRef filename) {
877 // To support sorting static functions which may have the same name in
878 // multiple .o files, _orderFiles maps the symbol name to a vector
879 // of OrderFileNode each of which can specify a file prefix.
880 OrderFileNode info;
881 if (!filename.empty())
882 info.fileFilter = copy(filename);
883 info.order = _orderFileEntries++;
884 _orderFiles[symbol].push_back(info);
885}
886
887bool
888MachOLinkingContext::findOrderOrdinal(const std::vector<OrderFileNode> &nodes,
889 const DefinedAtom *atom,
890 unsigned &ordinal) {
891 const File *objFile = &atom->file();
892 assert(objFile);
893 StringRef objName = objFile->path();
894 std::pair<StringRef, StringRef> dirAndLeaf = objName.rsplit('/');
895 if (!dirAndLeaf.second.empty())
896 objName = dirAndLeaf.second;
897 for (const OrderFileNode &info : nodes) {
898 if (info.fileFilter.empty()) {
899 // Have unprefixed symbol name in order file that matches this atom.
900 ordinal = info.order;
Nick Kledzik82d24bc2014-11-07 21:01:21 +0000901 return true;
902 }
903 if (info.fileFilter.equals(objName)) {
904 // Have prefixed symbol name in order file that matches atom's path.
905 ordinal = info.order;
Nick Kledzik82d24bc2014-11-07 21:01:21 +0000906 return true;
907 }
908 }
909 return false;
910}
911
912bool MachOLinkingContext::customAtomOrderer(const DefinedAtom *left,
913 const DefinedAtom *right,
Rui Ueyama00762152015-02-05 20:05:33 +0000914 bool &leftBeforeRight) const {
Nick Kledzik82d24bc2014-11-07 21:01:21 +0000915 // No custom sorting if no order file entries.
916 if (!_orderFileEntries)
917 return false;
918
919 // Order files can only order named atoms.
920 StringRef leftName = left->name();
921 StringRef rightName = right->name();
922 if (leftName.empty() || rightName.empty())
923 return false;
924
925 // If neither is in order file list, no custom sorter.
926 auto leftPos = _orderFiles.find(leftName);
927 auto rightPos = _orderFiles.find(rightName);
928 bool leftIsOrdered = (leftPos != _orderFiles.end());
929 bool rightIsOrdered = (rightPos != _orderFiles.end());
930 if (!leftIsOrdered && !rightIsOrdered)
931 return false;
932
933 // There could be multiple symbols with same name but different file prefixes.
934 unsigned leftOrder;
935 unsigned rightOrder;
936 bool foundLeft =
937 leftIsOrdered && findOrderOrdinal(leftPos->getValue(), left, leftOrder);
938 bool foundRight = rightIsOrdered &&
939 findOrderOrdinal(rightPos->getValue(), right, rightOrder);
940 if (!foundLeft && !foundRight)
941 return false;
942
943 // If only one is in order file list, ordered one goes first.
944 if (foundLeft != foundRight)
945 leftBeforeRight = foundLeft;
946 else
947 leftBeforeRight = (leftOrder < rightOrder);
948
949 return true;
950}
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000951
Rui Ueyama61635442015-01-15 08:31:46 +0000952static bool isLibrary(const std::unique_ptr<Node> &elem) {
Rui Ueyamaae1daae2015-01-15 08:51:23 +0000953 if (FileNode *node = dyn_cast<FileNode>(const_cast<Node *>(elem.get()))) {
954 File *file = node->getFile();
955 return isa<SharedLibraryFile>(file) || isa<ArchiveLibraryFile>(file);
956 }
957 return false;
Rui Ueyama00eb2572014-12-10 00:33:00 +0000958}
959
960// The darwin linker processes input files in two phases. The first phase
961// links in all object (.o) files in command line order. The second phase
962// links in libraries in command line order.
963// In this function we reorder the input files so that all the object files
964// comes before any library file. We also make a group for the library files
965// so that the Resolver will reiterate over the libraries as long as we find
966// new undefines from libraries.
Denis Protivenskycd617152015-03-14 10:34:43 +0000967void MachOLinkingContext::finalizeInputFiles() {
Rui Ueyama883afba2015-01-15 08:46:36 +0000968 std::vector<std::unique_ptr<Node>> &elements = getNodes();
Rui Ueyama00eb2572014-12-10 00:33:00 +0000969 std::stable_sort(elements.begin(), elements.end(),
Rui Ueyama61635442015-01-15 08:31:46 +0000970 [](const std::unique_ptr<Node> &a,
971 const std::unique_ptr<Node> &b) {
Rui Ueyama00eb2572014-12-10 00:33:00 +0000972 return !isLibrary(a) && isLibrary(b);
973 });
974 size_t numLibs = std::count_if(elements.begin(), elements.end(), isLibrary);
975 elements.push_back(llvm::make_unique<GroupEnd>(numLibs));
976}
977
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000978} // end namespace lld