blob: a46c5c27c235bdf3d4f03f0f029c0d53888e114d [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"
Lang Hamesb1b67f42015-10-24 08:20:51 +000016#include "SectCreateFile.h"
Rui Ueyamadf230b22015-01-15 04:34:31 +000017#include "lld/Core/ArchiveLibraryFile.h"
Rui Ueyama0ca149f2013-08-06 22:31:59 +000018#include "lld/Core/PassManager.h"
Greg Fitzgerald4b6a7e32015-01-21 22:54:56 +000019#include "lld/Core/Reader.h"
20#include "lld/Core/Writer.h"
Rui Ueyamadf230b22015-01-15 04:34:31 +000021#include "lld/Driver/Driver.h"
Benjamin Kramer06a42af2015-03-02 00:48:06 +000022#include "llvm/ADT/STLExtras.h"
Rui Ueyama0ca149f2013-08-06 22:31:59 +000023#include "llvm/ADT/StringExtras.h"
24#include "llvm/ADT/Triple.h"
Nick Kledzikbe43d7e2014-09-30 23:15:39 +000025#include "llvm/Config/config.h"
Rui Ueyama00eb2572014-12-10 00:33:00 +000026#include "llvm/Support/Debug.h"
Chandler Carruth89642a72015-01-14 11:26:52 +000027#include "llvm/Support/Errc.h"
Nick Kledzike34182f2013-11-06 21:36:55 +000028#include "llvm/Support/Host.h"
Nick Kledzik473933b2013-09-27 22:50:00 +000029#include "llvm/Support/MachO.h"
Tim Northover77d82202014-07-10 11:21:06 +000030#include "llvm/Support/Path.h"
Rui Ueyama57a29532014-08-06 19:37:35 +000031#include <algorithm>
32
Rui Ueyamafccf7ef2014-10-27 07:44:40 +000033#if defined(HAVE_CXXABI_H)
Nick Kledzikbe43d7e2014-09-30 23:15:39 +000034#include <cxxabi.h>
35#endif
36
Nick Kledzik2458bec2014-07-16 19:49:02 +000037using lld::mach_o::ArchHandler;
Pete Cooper99f3b942016-01-14 23:25:06 +000038using lld::mach_o::MachOFile;
Nick Kledzik8fc67fb2014-08-13 23:55:41 +000039using lld::mach_o::MachODylibFile;
Nick Kledzike34182f2013-11-06 21:36:55 +000040using namespace llvm::MachO;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000041
42namespace lld {
43
Nick Kledzike850d9d2013-09-10 23:46:57 +000044bool MachOLinkingContext::parsePackedVersion(StringRef str, uint32_t &result) {
45 result = 0;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000046
47 if (str.empty())
48 return false;
49
50 SmallVector<StringRef, 3> parts;
51 llvm::SplitString(str, parts, ".");
52
53 unsigned long long num;
54 if (llvm::getAsUnsignedInteger(parts[0], 10, num))
55 return true;
56 if (num > 65535)
57 return true;
Nick Kledzike850d9d2013-09-10 23:46:57 +000058 result = num << 16;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000059
60 if (parts.size() > 1) {
61 if (llvm::getAsUnsignedInteger(parts[1], 10, num))
62 return true;
63 if (num > 255)
64 return true;
Nick Kledzike850d9d2013-09-10 23:46:57 +000065 result |= (num << 8);
Rui Ueyama0ca149f2013-08-06 22:31:59 +000066 }
67
68 if (parts.size() > 2) {
69 if (llvm::getAsUnsignedInteger(parts[2], 10, num))
70 return true;
71 if (num > 255)
72 return true;
Nick Kledzike850d9d2013-09-10 23:46:57 +000073 result |= num;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000074 }
75
76 return false;
77}
78
Pete Cooper40576fa2016-02-04 02:45:23 +000079bool MachOLinkingContext::parsePackedVersion(StringRef str, uint64_t &result) {
80 result = 0;
81
82 if (str.empty())
83 return false;
84
85 SmallVector<StringRef, 5> parts;
86 llvm::SplitString(str, parts, ".");
87
Pete Cooperd5c0e4d2016-02-04 02:50:47 +000088 unsigned long long num;
Pete Cooper40576fa2016-02-04 02:45:23 +000089 if (llvm::getAsUnsignedInteger(parts[0], 10, num))
90 return true;
91 if (num > 0xFFFFFF)
92 return true;
93 result = num << 40;
94
95 unsigned Shift = 30;
96 for (StringRef str : llvm::makeArrayRef(parts).slice(1)) {
97 if (llvm::getAsUnsignedInteger(str, 10, num))
98 return true;
99 if (num > 0x3FF)
100 return true;
101 result |= (num << Shift);
102 Shift -= 10;
103 }
104
105 return false;
106}
107
Nick Kledzike34182f2013-11-06 21:36:55 +0000108MachOLinkingContext::ArchInfo MachOLinkingContext::_s_archInfos[] = {
109 { "x86_64", arch_x86_64, true, CPU_TYPE_X86_64, CPU_SUBTYPE_X86_64_ALL },
110 { "i386", arch_x86, true, CPU_TYPE_I386, CPU_SUBTYPE_X86_ALL },
111 { "ppc", arch_ppc, false, CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_ALL },
112 { "armv6", arch_armv6, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V6 },
113 { "armv7", arch_armv7, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7 },
114 { "armv7s", arch_armv7s, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7S },
Nick Kledzik1bebb282014-09-09 23:52:59 +0000115 { "arm64", arch_arm64, true, CPU_TYPE_ARM64, CPU_SUBTYPE_ARM64_ALL },
Nick Kledzike34182f2013-11-06 21:36:55 +0000116 { "", arch_unknown,false, 0, 0 }
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000117};
118
119MachOLinkingContext::Arch
120MachOLinkingContext::archFromCpuType(uint32_t cputype, uint32_t cpusubtype) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000121 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
122 if ((info->cputype == cputype) && (info->cpusubtype == cpusubtype))
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000123 return info->arch;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000124 }
125 return arch_unknown;
126}
127
128MachOLinkingContext::Arch
129MachOLinkingContext::archFromName(StringRef archName) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000130 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
131 if (info->archName.equals(archName))
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000132 return info->arch;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000133 }
134 return arch_unknown;
135}
136
Nick Kledzike5552772013-12-19 21:58:00 +0000137StringRef MachOLinkingContext::nameFromArch(Arch arch) {
138 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
139 if (info->arch == arch)
140 return info->archName;
141 }
142 return "<unknown>";
143}
144
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000145uint32_t MachOLinkingContext::cpuTypeFromArch(Arch arch) {
146 assert(arch != arch_unknown);
Nick Kledzike34182f2013-11-06 21:36:55 +0000147 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
148 if (info->arch == arch)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000149 return info->cputype;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000150 }
151 llvm_unreachable("Unknown arch type");
152}
153
154uint32_t MachOLinkingContext::cpuSubtypeFromArch(Arch arch) {
155 assert(arch != arch_unknown);
Nick Kledzike34182f2013-11-06 21:36:55 +0000156 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
157 if (info->arch == arch)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000158 return info->cpusubtype;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000159 }
160 llvm_unreachable("Unknown arch type");
161}
162
Nick Kledzik635f9c72014-09-04 20:08:30 +0000163bool MachOLinkingContext::isThinObjectFile(StringRef path, Arch &arch) {
164 return mach_o::normalized::isThinObjectFile(path, arch);
165}
166
Rafael Espindolaed48e532015-04-27 22:48:51 +0000167bool MachOLinkingContext::sliceFromFatFile(MemoryBufferRef mb, uint32_t &offset,
Nick Kledzik14b5d202014-10-08 01:48:10 +0000168 uint32_t &size) {
169 return mach_o::normalized::sliceFromFatFile(mb, _arch, offset, size);
170}
171
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000172MachOLinkingContext::MachOLinkingContext()
Tim Northoverd30a1f22014-06-20 15:59:00 +0000173 : _outputMachOType(MH_EXECUTE), _outputMachOTypeStatic(false),
Tim Northoveraf3075b2014-09-10 10:39:57 +0000174 _doNothing(false), _pie(false), _arch(arch_unknown), _os(OS::macOSX),
175 _osMinVersion(0), _pageZeroSize(0), _pageSize(4096), _baseAddress(0),
Lang Hamesff4b13c2015-05-22 00:25:34 +0000176 _stackSize(0), _compatibilityVersion(0), _currentVersion(0),
Pete Cooperfeaa9672016-01-19 18:46:40 +0000177 _objcConstraint(objc_unknown), _swiftVersion(0), _flatNamespace(false),
178 _undefinedMode(UndefinedMode::error), _deadStrippableDylib(false),
179 _printAtoms(false), _testingFileUsage(false), _keepPrivateExterns(false),
180 _demangle(false), _archHandler(nullptr), _exportMode(ExportMode::globals),
Lang Hames5c692002015-09-28 20:25:14 +0000181 _debugInfoMode(DebugInfoMode::addDebugMap), _orderFileEntries(0),
182 _flatNamespaceFile(nullptr) {}
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000183
184MachOLinkingContext::~MachOLinkingContext() {}
185
Nick Kledzik6960b072013-12-21 01:47:17 +0000186void MachOLinkingContext::configure(HeaderFileType type, Arch arch, OS os,
Pete Cooper35116452016-01-22 21:13:24 +0000187 uint32_t minOSVersion,
188 bool exportDynamicSymbols) {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000189 _outputMachOType = type;
Nick Kledzik6960b072013-12-21 01:47:17 +0000190 _arch = arch;
191 _os = os;
192 _osMinVersion = minOSVersion;
193
Nick Kledzikcb2018f2014-10-09 01:01:16 +0000194 // If min OS not specified on command line, use reasonable defaults.
Pete Cooper3dd478a2016-02-04 01:57:59 +0000195 // Note that we only do sensible defaults when emitting something other than
196 // object and preload.
197 if (_outputMachOType != llvm::MachO::MH_OBJECT &&
198 _outputMachOType != llvm::MachO::MH_PRELOAD) {
199 if (minOSVersion == 0) {
200 switch (_arch) {
201 case arch_x86_64:
202 case arch_x86:
203 parsePackedVersion("10.8", _osMinVersion);
204 _os = MachOLinkingContext::OS::macOSX;
205 break;
206 case arch_armv6:
207 case arch_armv7:
208 case arch_armv7s:
209 case arch_arm64:
210 parsePackedVersion("7.0", _osMinVersion);
211 _os = MachOLinkingContext::OS::iOS;
212 break;
213 default:
214 break;
215 }
Nick Kledzikcb2018f2014-10-09 01:01:16 +0000216 }
217 }
218
Tim Northoverd30a1f22014-06-20 15:59:00 +0000219 switch (_outputMachOType) {
Nick Kledzik6960b072013-12-21 01:47:17 +0000220 case llvm::MachO::MH_EXECUTE:
221 // If targeting newer OS, use _main
222 if (minOS("10.8", "6.0")) {
223 _entrySymbolName = "_main";
224 } else {
225 // If targeting older OS, use start (in crt1.o)
226 _entrySymbolName = "start";
227 }
228
229 // __PAGEZERO defaults to 4GB on 64-bit (except for PP64 which lld does not
230 // support) and 4KB on 32-bit.
231 if (is64Bit(_arch)) {
232 _pageZeroSize = 0x100000000;
233 } else {
234 _pageZeroSize = 0x1000;
235 }
236
Lang Hamesc80344282015-09-21 22:06:02 +0000237 // Initial base address is __PAGEZERO size.
238 _baseAddress = _pageZeroSize;
239
Nick Kledzikb7035ae2014-09-09 00:17:52 +0000240 // Make PIE by default when targetting newer OSs.
241 switch (os) {
242 case OS::macOSX:
243 if (minOSVersion >= 0x000A0700) // MacOSX 10.7
244 _pie = true;
245 break;
246 case OS::iOS:
247 if (minOSVersion >= 0x00040300) // iOS 4.3
248 _pie = true;
249 break;
250 case OS::iOS_simulator:
251 _pie = true;
252 break;
253 case OS::unknown:
254 break;
255 }
Pete Cooper35116452016-01-22 21:13:24 +0000256 setGlobalsAreDeadStripRoots(exportDynamicSymbols);
Nick Kledzik6960b072013-12-21 01:47:17 +0000257 break;
258 case llvm::MachO::MH_DYLIB:
Pete Cooper35116452016-01-22 21:13:24 +0000259 setGlobalsAreDeadStripRoots(exportDynamicSymbols);
Nick Kledzik6960b072013-12-21 01:47:17 +0000260 break;
261 case llvm::MachO::MH_BUNDLE:
262 break;
263 case llvm::MachO::MH_OBJECT:
264 _printRemainingUndefines = false;
265 _allowRemainingUndefines = true;
266 default:
267 break;
268 }
Nick Kledzik1bebb282014-09-09 23:52:59 +0000269
270 // Set default segment page sizes based on arch.
271 if (arch == arch_arm64)
272 _pageSize = 4*4096;
Nick Kledzik6960b072013-12-21 01:47:17 +0000273}
274
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000275uint32_t MachOLinkingContext::getCPUType() const {
276 return cpuTypeFromArch(_arch);
277}
278
279uint32_t MachOLinkingContext::getCPUSubType() const {
280 return cpuSubtypeFromArch(_arch);
281}
282
Nick Kledzike34182f2013-11-06 21:36:55 +0000283bool MachOLinkingContext::is64Bit(Arch arch) {
284 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
285 if (info->arch == arch) {
286 return (info->cputype & CPU_ARCH_ABI64);
287 }
288 }
289 // unknown archs are not 64-bit.
290 return false;
291}
292
293bool MachOLinkingContext::isHostEndian(Arch arch) {
294 assert(arch != arch_unknown);
295 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
296 if (info->arch == arch) {
297 return (info->littleEndian == llvm::sys::IsLittleEndianHost);
298 }
299 }
300 llvm_unreachable("Unknown arch type");
301}
302
303bool MachOLinkingContext::isBigEndian(Arch arch) {
304 assert(arch != arch_unknown);
305 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
306 if (info->arch == arch) {
307 return ! info->littleEndian;
308 }
309 }
310 llvm_unreachable("Unknown arch type");
311}
312
Nick Kledzike34182f2013-11-06 21:36:55 +0000313bool MachOLinkingContext::is64Bit() const {
314 return is64Bit(_arch);
315}
316
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000317bool MachOLinkingContext::outputTypeHasEntry() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000318 switch (_outputMachOType) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000319 case MH_EXECUTE:
320 case MH_DYLINKER:
321 case MH_PRELOAD:
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000322 return true;
323 default:
324 return false;
325 }
326}
327
Nick Kledzik2458bec2014-07-16 19:49:02 +0000328bool MachOLinkingContext::needsStubsPass() const {
329 switch (_outputMachOType) {
330 case MH_EXECUTE:
331 return !_outputMachOTypeStatic;
332 case MH_DYLIB:
333 case MH_BUNDLE:
334 return true;
335 default:
336 return false;
337 }
338}
339
340bool MachOLinkingContext::needsGOTPass() const {
Nick Kledzik1bebb282014-09-09 23:52:59 +0000341 // GOT pass not used in -r mode.
342 if (_outputMachOType == MH_OBJECT)
Nick Kledzik2458bec2014-07-16 19:49:02 +0000343 return false;
Nick Kledzik1bebb282014-09-09 23:52:59 +0000344 // Only some arches use GOT pass.
345 switch (_arch) {
346 case arch_x86_64:
347 case arch_arm64:
348 return true;
349 default:
350 return false;
351 }
Nick Kledzik2458bec2014-07-16 19:49:02 +0000352}
353
Tim Northovercf78d372014-09-30 21:29:54 +0000354bool MachOLinkingContext::needsCompactUnwindPass() const {
355 switch (_outputMachOType) {
356 case MH_EXECUTE:
357 case MH_DYLIB:
358 case MH_BUNDLE:
359 return archHandler().needsCompactUnwind();
360 default:
361 return false;
362 }
363}
Nick Kledzik2458bec2014-07-16 19:49:02 +0000364
Pete Cooper90dbab02016-01-19 21:54:21 +0000365bool MachOLinkingContext::needsObjCPass() const {
366 // ObjC pass is only needed if any of the inputs were ObjC.
367 return _objcConstraint != objc_unknown;
368}
369
Nick Kledzik4121bce2014-10-14 01:51:42 +0000370bool MachOLinkingContext::needsShimPass() const {
371 // Shim pass only used in final executables.
372 if (_outputMachOType == MH_OBJECT)
373 return false;
374 // Only 32-bit arm arches use Shim pass.
375 switch (_arch) {
376 case arch_armv6:
377 case arch_armv7:
378 case arch_armv7s:
379 return true;
380 default:
381 return false;
382 }
383}
384
Lang Hames49047032015-06-23 20:35:31 +0000385bool MachOLinkingContext::needsTLVPass() const {
386 switch (_outputMachOType) {
387 case MH_BUNDLE:
388 case MH_EXECUTE:
389 case MH_DYLIB:
390 return true;
391 default:
392 return false;
393 }
394}
395
Nick Kledzik2458bec2014-07-16 19:49:02 +0000396StringRef MachOLinkingContext::binderSymbolName() const {
397 return archHandler().stubInfo().binderSymbolName;
398}
399
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000400bool MachOLinkingContext::minOS(StringRef mac, StringRef iOS) const {
Nick Kledzik30332b12013-10-08 00:43:34 +0000401 uint32_t parsedVersion;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000402 switch (_os) {
Nick Kledzik30332b12013-10-08 00:43:34 +0000403 case OS::macOSX:
Nick Kledzike850d9d2013-09-10 23:46:57 +0000404 if (parsePackedVersion(mac, parsedVersion))
405 return false;
406 return _osMinVersion >= parsedVersion;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000407 case OS::iOS:
Nick Kledzik30332b12013-10-08 00:43:34 +0000408 case OS::iOS_simulator:
Nick Kledzike850d9d2013-09-10 23:46:57 +0000409 if (parsePackedVersion(iOS, parsedVersion))
410 return false;
411 return _osMinVersion >= parsedVersion;
Nick Kledzik30332b12013-10-08 00:43:34 +0000412 case OS::unknown:
Pete Cooper3dd478a2016-02-04 01:57:59 +0000413 // If we don't know the target, then assume that we don't meet the min OS.
414 // This matches the ld64 behaviour
415 return false;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000416 }
Reid Kleckner257102e2016-02-10 19:28:13 +0000417 llvm_unreachable("invalid OS enum");
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000418}
419
420bool MachOLinkingContext::addEntryPointLoadCommand() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000421 if ((_outputMachOType == MH_EXECUTE) && !_outputMachOTypeStatic) {
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000422 return minOS("10.8", "6.0");
423 }
424 return false;
425}
426
427bool MachOLinkingContext::addUnixThreadLoadCommand() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000428 switch (_outputMachOType) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000429 case MH_EXECUTE:
Tim Northoverd30a1f22014-06-20 15:59:00 +0000430 if (_outputMachOTypeStatic)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000431 return true;
432 else
433 return !minOS("10.8", "6.0");
434 break;
Nick Kledzike34182f2013-11-06 21:36:55 +0000435 case MH_DYLINKER:
436 case MH_PRELOAD:
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000437 return true;
438 default:
439 return false;
440 }
441}
442
Tim Northover77d82202014-07-10 11:21:06 +0000443bool MachOLinkingContext::pathExists(StringRef path) const {
Nick Kledzik94174f72014-08-15 19:53:41 +0000444 if (!_testingFileUsage)
Tim Northover77d82202014-07-10 11:21:06 +0000445 return llvm::sys::fs::exists(path.str());
446
447 // Otherwise, we're in test mode: only files explicitly provided on the
448 // command-line exist.
Rui Ueyama57a29532014-08-06 19:37:35 +0000449 std::string key = path.str();
450 std::replace(key.begin(), key.end(), '\\', '/');
451 return _existingPaths.find(key) != _existingPaths.end();
Tim Northover77d82202014-07-10 11:21:06 +0000452}
453
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000454bool MachOLinkingContext::fileExists(StringRef path) const {
455 bool found = pathExists(path);
456 // Log search misses.
457 if (!found)
458 addInputFileNotFound(path);
459
460 // When testing, file is never opened, so logging is done here.
461 if (_testingFileUsage && found)
462 addInputFileDependency(path);
463
464 return found;
465}
466
Nick Kledzik2d835da2014-08-14 22:20:41 +0000467void MachOLinkingContext::setSysLibRoots(const StringRefVector &paths) {
468 _syslibRoots = paths;
469}
470
Jean-Daniel Dupas23dd15e2014-12-18 21:33:38 +0000471void MachOLinkingContext::addRpath(StringRef rpath) {
472 _rpaths.push_back(rpath);
473}
474
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000475void MachOLinkingContext::addModifiedSearchDir(StringRef libPath,
476 bool isSystemPath) {
Tim Northover77d82202014-07-10 11:21:06 +0000477 bool addedModifiedPath = false;
478
Nick Kledzik2d835da2014-08-14 22:20:41 +0000479 // -syslibroot only applies to absolute paths.
480 if (libPath.startswith("/")) {
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000481 for (auto syslibRoot : _syslibRoots) {
Tim Northover77d82202014-07-10 11:21:06 +0000482 SmallString<256> path(syslibRoot);
483 llvm::sys::path::append(path, libPath);
484 if (pathExists(path)) {
485 _searchDirs.push_back(path.str().copy(_allocator));
486 addedModifiedPath = true;
487 }
488 }
489 }
490
491 if (addedModifiedPath)
492 return;
493
494 // Finally, if only one -syslibroot is given, system paths which aren't in it
495 // get suppressed.
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000496 if (_syslibRoots.size() != 1 || !isSystemPath) {
Tim Northover77d82202014-07-10 11:21:06 +0000497 if (pathExists(libPath)) {
498 _searchDirs.push_back(libPath);
499 }
500 }
501}
502
Nick Kledzik2d835da2014-08-14 22:20:41 +0000503void MachOLinkingContext::addFrameworkSearchDir(StringRef fwPath,
504 bool isSystemPath) {
505 bool pathAdded = false;
506
507 // -syslibroot only used with to absolute framework search paths.
508 if (fwPath.startswith("/")) {
509 for (auto syslibRoot : _syslibRoots) {
510 SmallString<256> path(syslibRoot);
511 llvm::sys::path::append(path, fwPath);
512 if (pathExists(path)) {
513 _frameworkDirs.push_back(path.str().copy(_allocator));
514 pathAdded = true;
515 }
516 }
517 }
518 // If fwPath found in any -syslibroot, then done.
519 if (pathAdded)
520 return;
521
522 // If only one -syslibroot, system paths not in that SDK are suppressed.
523 if (isSystemPath && (_syslibRoots.size() == 1))
524 return;
525
526 // Only use raw fwPath if that directory exists.
527 if (pathExists(fwPath))
528 _frameworkDirs.push_back(fwPath);
529}
530
Tim Northover77d82202014-07-10 11:21:06 +0000531ErrorOr<StringRef>
532MachOLinkingContext::searchDirForLibrary(StringRef path,
533 StringRef libName) const {
534 SmallString<256> fullPath;
535 if (libName.endswith(".o")) {
536 // A request ending in .o is special: just search for the file directly.
537 fullPath.assign(path);
538 llvm::sys::path::append(fullPath, libName);
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000539 if (fileExists(fullPath))
Tim Northover77d82202014-07-10 11:21:06 +0000540 return fullPath.str().copy(_allocator);
541 return make_error_code(llvm::errc::no_such_file_or_directory);
542 }
543
544 // Search for dynamic library
545 fullPath.assign(path);
546 llvm::sys::path::append(fullPath, Twine("lib") + libName + ".dylib");
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000547 if (fileExists(fullPath))
Tim Northover77d82202014-07-10 11:21:06 +0000548 return fullPath.str().copy(_allocator);
549
550 // If not, try for a static library
551 fullPath.assign(path);
552 llvm::sys::path::append(fullPath, Twine("lib") + libName + ".a");
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000553 if (fileExists(fullPath))
Tim Northover77d82202014-07-10 11:21:06 +0000554 return fullPath.str().copy(_allocator);
555
556 return make_error_code(llvm::errc::no_such_file_or_directory);
557}
558
Tim Northover77d82202014-07-10 11:21:06 +0000559ErrorOr<StringRef> MachOLinkingContext::searchLibrary(StringRef libName) const {
560 SmallString<256> path;
561 for (StringRef dir : searchDirs()) {
562 ErrorOr<StringRef> ec = searchDirForLibrary(dir, libName);
563 if (ec)
564 return ec;
565 }
566
567 return make_error_code(llvm::errc::no_such_file_or_directory);
568}
569
Nick Kledzik2d835da2014-08-14 22:20:41 +0000570ErrorOr<StringRef> MachOLinkingContext::findPathForFramework(StringRef fwName) const{
571 SmallString<256> fullPath;
572 for (StringRef dir : frameworkDirs()) {
573 fullPath.assign(dir);
574 llvm::sys::path::append(fullPath, Twine(fwName) + ".framework", fwName);
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000575 if (fileExists(fullPath))
Nick Kledzik2d835da2014-08-14 22:20:41 +0000576 return fullPath.str().copy(_allocator);
577 }
578
579 return make_error_code(llvm::errc::no_such_file_or_directory);
580}
581
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000582bool MachOLinkingContext::validateImpl(raw_ostream &diagnostics) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000583 // TODO: if -arch not specified, look at arch of first .o file.
584
Tim Northoverd30a1f22014-06-20 15:59:00 +0000585 if (_currentVersion && _outputMachOType != MH_DYLIB) {
Nick Kledzike773e322013-09-10 23:55:14 +0000586 diagnostics << "error: -current_version can only be used with dylibs\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000587 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000588 }
589
Tim Northoverd30a1f22014-06-20 15:59:00 +0000590 if (_compatibilityVersion && _outputMachOType != MH_DYLIB) {
Nick Kledzike773e322013-09-10 23:55:14 +0000591 diagnostics
592 << "error: -compatibility_version can only be used with dylibs\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000593 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000594 }
595
Tim Northoverd30a1f22014-06-20 15:59:00 +0000596 if (_deadStrippableDylib && _outputMachOType != MH_DYLIB) {
Nick Kledzike773e322013-09-10 23:55:14 +0000597 diagnostics
598 << "error: -mark_dead_strippable_dylib can only be used with dylibs.\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000599 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000600 }
601
Tim Northoverd30a1f22014-06-20 15:59:00 +0000602 if (!_bundleLoader.empty() && outputMachOType() != MH_BUNDLE) {
Nick Kledzike773e322013-09-10 23:55:14 +0000603 diagnostics
604 << "error: -bundle_loader can only be used with Mach-O bundles\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000605 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000606 }
607
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000608 // If -exported_symbols_list used, all exported symbols must be defined.
609 if (_exportMode == ExportMode::whiteList) {
610 for (const auto &symbol : _exportedSymbols)
611 addInitialUndefinedSymbol(symbol.getKey());
612 }
613
Nick Kledzik77afc712014-08-21 20:25:50 +0000614 // If -dead_strip, set up initial live symbols.
615 if (deadStrip()) {
616 // Entry point is live.
617 if (outputTypeHasEntry())
618 addDeadStripRoot(entrySymbolName());
619 // Lazy binding helper is live.
620 if (needsStubsPass())
621 addDeadStripRoot(binderSymbolName());
622 // If using -exported_symbols_list, make all exported symbols live.
623 if (_exportMode == ExportMode::whiteList) {
Davide Italiano7b68b902015-03-09 06:05:42 +0000624 setGlobalsAreDeadStripRoots(false);
Nick Kledzik77afc712014-08-21 20:25:50 +0000625 for (const auto &symbol : _exportedSymbols)
626 addDeadStripRoot(symbol.getKey());
627 }
628 }
629
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000630 addOutputFileDependency(outputPath());
631
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000632 return true;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000633}
634
Shankar Easwaran2bc24922013-10-29 05:12:14 +0000635void MachOLinkingContext::addPasses(PassManager &pm) {
Pete Cooper90dbab02016-01-19 21:54:21 +0000636 // objc pass should be before layout pass. Otherwise test cases may contain
637 // no atoms which confuses the layout pass.
638 if (needsObjCPass())
639 mach_o::addObjCPass(pm, *this);
Rui Ueyama00762152015-02-05 20:05:33 +0000640 mach_o::addLayoutPass(pm, *this);
Nick Kledzik2458bec2014-07-16 19:49:02 +0000641 if (needsStubsPass())
642 mach_o::addStubsPass(pm, *this);
Tim Northovercf78d372014-09-30 21:29:54 +0000643 if (needsCompactUnwindPass())
644 mach_o::addCompactUnwindPass(pm, *this);
Nick Kledzik2458bec2014-07-16 19:49:02 +0000645 if (needsGOTPass())
646 mach_o::addGOTPass(pm, *this);
Lang Hames49047032015-06-23 20:35:31 +0000647 if (needsTLVPass())
648 mach_o::addTLVPass(pm, *this);
Nick Kledzik4121bce2014-10-14 01:51:42 +0000649 if (needsShimPass())
650 mach_o::addShimPass(pm, *this); // Shim pass must run after stubs pass.
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000651}
652
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000653Writer &MachOLinkingContext::writer() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000654 if (!_writer)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000655 _writer = createWriterMachO(*this);
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000656 return *_writer;
657}
658
Greg Fitzgeraldb4eb64e2015-01-23 23:26:13 +0000659ErrorOr<std::unique_ptr<MemoryBuffer>>
660MachOLinkingContext::getMemoryBuffer(StringRef path) {
661 addInputFileDependency(path);
662
Rui Ueyamadf230b22015-01-15 04:34:31 +0000663 ErrorOr<std::unique_ptr<MemoryBuffer>> mbOrErr =
Greg Fitzgeraldb4eb64e2015-01-23 23:26:13 +0000664 MemoryBuffer::getFileOrSTDIN(path);
665 if (std::error_code ec = mbOrErr.getError())
666 return ec;
667 std::unique_ptr<MemoryBuffer> mb = std::move(mbOrErr.get());
668
669 // If buffer contains a fat file, find required arch in fat buffer
670 // and switch buffer to point to just that required slice.
671 uint32_t offset;
672 uint32_t size;
Rafael Espindolaed48e532015-04-27 22:48:51 +0000673 if (sliceFromFatFile(mb->getMemBufferRef(), offset, size))
Greg Fitzgeraldb4eb64e2015-01-23 23:26:13 +0000674 return MemoryBuffer::getFileSlice(path, size, offset);
675 return std::move(mb);
676}
677
678MachODylibFile* MachOLinkingContext::loadIndirectDylib(StringRef path) {
679 ErrorOr<std::unique_ptr<MemoryBuffer>> mbOrErr = getMemoryBuffer(path);
Rui Ueyamadf230b22015-01-15 04:34:31 +0000680 if (mbOrErr.getError())
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000681 return nullptr;
682
Rafael Espindolaab5696b2015-04-24 18:51:30 +0000683 ErrorOr<std::unique_ptr<File>> fileOrErr =
684 registry().loadFile(std::move(mbOrErr.get()));
685 if (!fileOrErr)
Rui Ueyamadf230b22015-01-15 04:34:31 +0000686 return nullptr;
Rafael Espindola773a1592015-04-24 19:01:30 +0000687 std::unique_ptr<File> &file = fileOrErr.get();
688 file->parse();
689 MachODylibFile *result = reinterpret_cast<MachODylibFile *>(file.get());
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000690 // Node object now owned by _indirectDylibs vector.
Rafael Espindola773a1592015-04-24 19:01:30 +0000691 _indirectDylibs.push_back(std::move(file));
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000692 return result;
693}
694
Nick Kledzik22c90732014-10-01 20:24:30 +0000695MachODylibFile* MachOLinkingContext::findIndirectDylib(StringRef path) {
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000696 // See if already loaded.
697 auto pos = _pathToDylibMap.find(path);
698 if (pos != _pathToDylibMap.end())
699 return pos->second;
700
701 // Search -L paths if of the form "libXXX.dylib"
702 std::pair<StringRef, StringRef> split = path.rsplit('/');
703 StringRef leafName = split.second;
704 if (leafName.startswith("lib") && leafName.endswith(".dylib")) {
705 // FIXME: Need to enhance searchLibrary() to only look for .dylib
706 auto libPath = searchLibrary(leafName);
707 if (!libPath.getError()) {
708 return loadIndirectDylib(libPath.get());
709 }
710 }
711
712 // Try full path with sysroot.
713 for (StringRef sysPath : _syslibRoots) {
714 SmallString<256> fullPath;
715 fullPath.assign(sysPath);
716 llvm::sys::path::append(fullPath, path);
717 if (pathExists(fullPath))
718 return loadIndirectDylib(fullPath);
719 }
720
721 // Try full path.
722 if (pathExists(path)) {
723 return loadIndirectDylib(path);
724 }
725
726 return nullptr;
727}
728
Nick Kledzik5b9e48b2014-11-19 02:21:53 +0000729uint32_t MachOLinkingContext::dylibCurrentVersion(StringRef installName) const {
730 auto pos = _pathToDylibMap.find(installName);
731 if (pos != _pathToDylibMap.end())
732 return pos->second->currentVersion();
733 else
734 return 0x1000; // 1.0
735}
736
737uint32_t MachOLinkingContext::dylibCompatVersion(StringRef installName) const {
738 auto pos = _pathToDylibMap.find(installName);
739 if (pos != _pathToDylibMap.end())
740 return pos->second->compatVersion();
741 else
742 return 0x1000; // 1.0
743}
744
Simon Atanasyanc4378882015-04-06 20:43:35 +0000745void MachOLinkingContext::createImplicitFiles(
Nick Kledzik22c90732014-10-01 20:24:30 +0000746 std::vector<std::unique_ptr<File> > &result) {
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000747 // Add indirect dylibs by asking each linked dylib to add its indirects.
748 // Iterate until no more dylibs get loaded.
749 size_t dylibCount = 0;
750 while (dylibCount != _allDylibs.size()) {
751 dylibCount = _allDylibs.size();
752 for (MachODylibFile *dylib : _allDylibs) {
753 dylib->loadReExportedDylibs([this] (StringRef path) -> MachODylibFile* {
754 return findIndirectDylib(path); });
755 }
756 }
757
758 // Let writer add output type specific extras.
Simon Atanasyanc4378882015-04-06 20:43:35 +0000759 writer().createImplicitFiles(result);
Lang Hames5c692002015-09-28 20:25:14 +0000760
Lang Hames9a4c94e2015-09-28 20:52:21 +0000761 // If undefinedMode is != error, add a FlatNamespaceFile instance. This will
762 // provide a SharedLibraryAtom for symbols that aren't defined elsewhere.
763 if (undefinedMode() != UndefinedMode::error) {
764 result.emplace_back(new mach_o::FlatNamespaceFile(*this));
Lang Hames5c692002015-09-28 20:25:14 +0000765 _flatNamespaceFile = result.back().get();
766 }
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000767}
768
Nick Kledzik51720672014-10-16 19:31:28 +0000769void MachOLinkingContext::registerDylib(MachODylibFile *dylib,
770 bool upward) const {
Lang Hames9bbc3652015-05-13 00:17:08 +0000771 std::lock_guard<std::mutex> lock(_dylibsMutex);
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000772 _allDylibs.insert(dylib);
773 _pathToDylibMap[dylib->installName()] = dylib;
774 // If path is different than install name, register path too.
775 if (!dylib->path().equals(dylib->installName()))
776 _pathToDylibMap[dylib->path()] = dylib;
Nick Kledzik51720672014-10-16 19:31:28 +0000777 if (upward)
778 _upwardDylibs.insert(dylib);
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000779}
780
Nick Kledzik51720672014-10-16 19:31:28 +0000781bool MachOLinkingContext::isUpwardDylib(StringRef installName) const {
782 for (MachODylibFile *dylib : _upwardDylibs) {
783 if (dylib->installName().equals(installName))
784 return true;
785 }
786 return false;
787}
788
Nick Kledzik2458bec2014-07-16 19:49:02 +0000789ArchHandler &MachOLinkingContext::archHandler() const {
790 if (!_archHandler)
791 _archHandler = ArchHandler::create(_arch);
792 return *_archHandler;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000793}
794
Nick Kledzik2fcbe822014-07-30 00:58:06 +0000795void MachOLinkingContext::addSectionAlignment(StringRef seg, StringRef sect,
Rui Ueyamada74d572015-03-26 02:23:45 +0000796 uint16_t align) {
797 SectionAlign entry = { seg, sect, align };
Nick Kledzik2fcbe822014-07-30 00:58:06 +0000798 _sectAligns.push_back(entry);
799}
800
Lang Hamesb1b67f42015-10-24 08:20:51 +0000801void MachOLinkingContext::addSectCreateSection(
802 StringRef seg, StringRef sect,
803 std::unique_ptr<MemoryBuffer> content) {
804
805 if (!_sectCreateFile) {
806 auto sectCreateFile = llvm::make_unique<mach_o::SectCreateFile>();
807 _sectCreateFile = sectCreateFile.get();
808 getNodes().push_back(llvm::make_unique<FileNode>(std::move(sectCreateFile)));
809 }
810
811 assert(_sectCreateFile && "sectcreate file does not exist.");
812 _sectCreateFile->addSection(seg, sect, std::move(content));
813}
814
Nick Kledzik2fcbe822014-07-30 00:58:06 +0000815bool MachOLinkingContext::sectionAligned(StringRef seg, StringRef sect,
Rui Ueyamada74d572015-03-26 02:23:45 +0000816 uint16_t &align) const {
Nick Kledzik2fcbe822014-07-30 00:58:06 +0000817 for (const SectionAlign &entry : _sectAligns) {
818 if (seg.equals(entry.segmentName) && sect.equals(entry.sectionName)) {
Rui Ueyamada74d572015-03-26 02:23:45 +0000819 align = entry.align;
Nick Kledzik2fcbe822014-07-30 00:58:06 +0000820 return true;
821 }
822 }
823 return false;
824}
825
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000826void MachOLinkingContext::addExportSymbol(StringRef sym) {
Nick Kledzik4183dbc2014-10-24 22:28:54 +0000827 // Support old crufty export lists with bogus entries.
828 if (sym.endswith(".eh") || sym.startswith(".objc_category_name_")) {
829 llvm::errs() << "warning: ignoring " << sym << " in export list\n";
830 return;
831 }
832 // Only i386 MacOSX uses old ABI, so don't change those.
833 if ((_os != OS::macOSX) || (_arch != arch_x86)) {
834 // ObjC has two differnent ABIs. Be nice and allow one export list work for
835 // both ABIs by renaming symbols.
836 if (sym.startswith(".objc_class_name_")) {
837 std::string abi2className("_OBJC_CLASS_$_");
838 abi2className += sym.substr(17);
839 _exportedSymbols.insert(copy(abi2className));
840 std::string abi2metaclassName("_OBJC_METACLASS_$_");
841 abi2metaclassName += sym.substr(17);
842 _exportedSymbols.insert(copy(abi2metaclassName));
843 return;
844 }
845 }
846
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000847 // FIXME: Support wildcards.
848 _exportedSymbols.insert(sym);
849}
850
851bool MachOLinkingContext::exportSymbolNamed(StringRef sym) const {
852 switch (_exportMode) {
853 case ExportMode::globals:
854 llvm_unreachable("exportSymbolNamed() should not be called in this mode");
855 break;
856 case ExportMode::whiteList:
857 return _exportedSymbols.count(sym);
858 case ExportMode::blackList:
859 return !_exportedSymbols.count(sym);
860 }
Yaron Keren9682c852014-09-21 05:07:44 +0000861 llvm_unreachable("_exportMode unknown enum value");
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000862}
863
Nick Kledzikbe43d7e2014-09-30 23:15:39 +0000864std::string MachOLinkingContext::demangle(StringRef symbolName) const {
865 // Only try to demangle symbols if -demangle on command line
Davide Italiano6d86bb22015-02-18 03:54:21 +0000866 if (!demangleSymbols())
Nick Kledzikbe43d7e2014-09-30 23:15:39 +0000867 return symbolName;
868
869 // Only try to demangle symbols that look like C++ symbols
870 if (!symbolName.startswith("__Z"))
871 return symbolName;
872
Rui Ueyamafccf7ef2014-10-27 07:44:40 +0000873#if defined(HAVE_CXXABI_H)
Nick Kledzikbe43d7e2014-09-30 23:15:39 +0000874 SmallString<256> symBuff;
875 StringRef nullTermSym = Twine(symbolName).toNullTerminatedStringRef(symBuff);
876 // Mach-O has extra leading underscore that needs to be removed.
877 const char *cstr = nullTermSym.data() + 1;
878 int status;
879 char *demangled = abi::__cxa_demangle(cstr, nullptr, nullptr, &status);
Rui Ueyama43155d02015-10-02 00:36:00 +0000880 if (demangled) {
Nick Kledzikbe43d7e2014-09-30 23:15:39 +0000881 std::string result(demangled);
882 // __cxa_demangle() always uses a malloc'ed buffer to return the result.
883 free(demangled);
884 return result;
885 }
886#endif
887
888 return symbolName;
889}
890
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000891std::error_code MachOLinkingContext::createDependencyFile(StringRef path) {
892 std::error_code ec;
893 _dependencyInfo = std::unique_ptr<llvm::raw_fd_ostream>(new
894 llvm::raw_fd_ostream(path, ec, llvm::sys::fs::F_None));
895 if (ec) {
896 _dependencyInfo.reset();
897 return ec;
898 }
899
900 char linkerVersionOpcode = 0x00;
901 *_dependencyInfo << linkerVersionOpcode;
902 *_dependencyInfo << "lld"; // FIXME
903 *_dependencyInfo << '\0';
904
905 return std::error_code();
906}
907
908void MachOLinkingContext::addInputFileDependency(StringRef path) const {
909 if (!_dependencyInfo)
910 return;
911
912 char inputFileOpcode = 0x10;
913 *_dependencyInfo << inputFileOpcode;
914 *_dependencyInfo << path;
915 *_dependencyInfo << '\0';
916}
917
918void MachOLinkingContext::addInputFileNotFound(StringRef path) const {
919 if (!_dependencyInfo)
920 return;
921
922 char inputFileOpcode = 0x11;
923 *_dependencyInfo << inputFileOpcode;
924 *_dependencyInfo << path;
925 *_dependencyInfo << '\0';
926}
927
928void MachOLinkingContext::addOutputFileDependency(StringRef path) const {
929 if (!_dependencyInfo)
930 return;
931
932 char outputFileOpcode = 0x40;
933 *_dependencyInfo << outputFileOpcode;
934 *_dependencyInfo << path;
935 *_dependencyInfo << '\0';
936}
937
Nick Kledzik82d24bc2014-11-07 21:01:21 +0000938void MachOLinkingContext::appendOrderedSymbol(StringRef symbol,
939 StringRef filename) {
940 // To support sorting static functions which may have the same name in
941 // multiple .o files, _orderFiles maps the symbol name to a vector
942 // of OrderFileNode each of which can specify a file prefix.
943 OrderFileNode info;
944 if (!filename.empty())
945 info.fileFilter = copy(filename);
946 info.order = _orderFileEntries++;
947 _orderFiles[symbol].push_back(info);
948}
949
950bool
951MachOLinkingContext::findOrderOrdinal(const std::vector<OrderFileNode> &nodes,
952 const DefinedAtom *atom,
953 unsigned &ordinal) {
954 const File *objFile = &atom->file();
955 assert(objFile);
956 StringRef objName = objFile->path();
957 std::pair<StringRef, StringRef> dirAndLeaf = objName.rsplit('/');
958 if (!dirAndLeaf.second.empty())
959 objName = dirAndLeaf.second;
960 for (const OrderFileNode &info : nodes) {
961 if (info.fileFilter.empty()) {
962 // Have unprefixed symbol name in order file that matches this atom.
963 ordinal = info.order;
Nick Kledzik82d24bc2014-11-07 21:01:21 +0000964 return true;
965 }
966 if (info.fileFilter.equals(objName)) {
967 // Have prefixed symbol name in order file that matches atom's path.
968 ordinal = info.order;
Nick Kledzik82d24bc2014-11-07 21:01:21 +0000969 return true;
970 }
971 }
972 return false;
973}
974
975bool MachOLinkingContext::customAtomOrderer(const DefinedAtom *left,
976 const DefinedAtom *right,
Rui Ueyama00762152015-02-05 20:05:33 +0000977 bool &leftBeforeRight) const {
Nick Kledzik82d24bc2014-11-07 21:01:21 +0000978 // No custom sorting if no order file entries.
979 if (!_orderFileEntries)
980 return false;
981
982 // Order files can only order named atoms.
983 StringRef leftName = left->name();
984 StringRef rightName = right->name();
985 if (leftName.empty() || rightName.empty())
986 return false;
987
988 // If neither is in order file list, no custom sorter.
989 auto leftPos = _orderFiles.find(leftName);
990 auto rightPos = _orderFiles.find(rightName);
991 bool leftIsOrdered = (leftPos != _orderFiles.end());
992 bool rightIsOrdered = (rightPos != _orderFiles.end());
993 if (!leftIsOrdered && !rightIsOrdered)
994 return false;
995
996 // There could be multiple symbols with same name but different file prefixes.
997 unsigned leftOrder;
998 unsigned rightOrder;
999 bool foundLeft =
1000 leftIsOrdered && findOrderOrdinal(leftPos->getValue(), left, leftOrder);
1001 bool foundRight = rightIsOrdered &&
1002 findOrderOrdinal(rightPos->getValue(), right, rightOrder);
1003 if (!foundLeft && !foundRight)
1004 return false;
1005
1006 // If only one is in order file list, ordered one goes first.
1007 if (foundLeft != foundRight)
1008 leftBeforeRight = foundLeft;
1009 else
1010 leftBeforeRight = (leftOrder < rightOrder);
1011
1012 return true;
1013}
Nick Kledzik8c0bf752014-08-21 01:59:11 +00001014
Rui Ueyama61635442015-01-15 08:31:46 +00001015static bool isLibrary(const std::unique_ptr<Node> &elem) {
Rui Ueyamaae1daae2015-01-15 08:51:23 +00001016 if (FileNode *node = dyn_cast<FileNode>(const_cast<Node *>(elem.get()))) {
1017 File *file = node->getFile();
1018 return isa<SharedLibraryFile>(file) || isa<ArchiveLibraryFile>(file);
1019 }
1020 return false;
Rui Ueyama00eb2572014-12-10 00:33:00 +00001021}
1022
1023// The darwin linker processes input files in two phases. The first phase
1024// links in all object (.o) files in command line order. The second phase
1025// links in libraries in command line order.
1026// In this function we reorder the input files so that all the object files
1027// comes before any library file. We also make a group for the library files
1028// so that the Resolver will reiterate over the libraries as long as we find
1029// new undefines from libraries.
Denis Protivenskycd617152015-03-14 10:34:43 +00001030void MachOLinkingContext::finalizeInputFiles() {
Rui Ueyama883afba2015-01-15 08:46:36 +00001031 std::vector<std::unique_ptr<Node>> &elements = getNodes();
Rui Ueyama00eb2572014-12-10 00:33:00 +00001032 std::stable_sort(elements.begin(), elements.end(),
Rui Ueyama61635442015-01-15 08:31:46 +00001033 [](const std::unique_ptr<Node> &a,
1034 const std::unique_ptr<Node> &b) {
Rui Ueyama00eb2572014-12-10 00:33:00 +00001035 return !isLibrary(a) && isLibrary(b);
1036 });
1037 size_t numLibs = std::count_if(elements.begin(), elements.end(), isLibrary);
1038 elements.push_back(llvm::make_unique<GroupEnd>(numLibs));
1039}
1040
Pete Cooper80c09742016-01-14 21:53:13 +00001041std::error_code MachOLinkingContext::handleLoadedFile(File &file) {
Pete Cooper99f3b942016-01-14 23:25:06 +00001042 auto *machoFile = dyn_cast<MachOFile>(&file);
1043 if (!machoFile)
1044 return std::error_code();
1045
1046 // Check that the arch of the context matches that of the file.
1047 // Also set the arch of the context if it didn't have one.
1048 if (_arch == arch_unknown) {
1049 _arch = machoFile->arch();
1050 } else if (machoFile->arch() != arch_unknown && machoFile->arch() != _arch) {
1051 // Archs are different.
1052 return make_dynamic_error_code(file.path() +
1053 Twine(" cannot be linked due to incompatible architecture"));
1054 }
1055
1056 // Check that the OS of the context matches that of the file.
1057 // Also set the OS of the context if it didn't have one.
1058 if (_os == OS::unknown) {
1059 _os = machoFile->OS();
1060 } else if (machoFile->OS() != OS::unknown && machoFile->OS() != _os) {
1061 // OSes are different.
1062 return make_dynamic_error_code(file.path() +
1063 Twine(" cannot be linked due to incompatible operating systems"));
1064 }
Pete Coopera014ffe2016-01-16 00:07:22 +00001065
Pete Cooper0872e462016-01-19 19:46:41 +00001066 // Check that if the objc info exists, that it is compatible with the target
1067 // OS.
1068 switch (machoFile->objcConstraint()) {
1069 case objc_unknown:
1070 // The file is not compiled with objc, so skip the checks.
1071 break;
1072 case objc_gc_only:
1073 case objc_supports_gc:
1074 llvm_unreachable("GC support should already have thrown an error");
1075 case objc_retainReleaseForSimulator:
1076 // The file is built with simulator objc, so make sure that the context
1077 // is also building with simulator support.
1078 if (_os != OS::iOS_simulator)
1079 return make_dynamic_error_code(file.path() +
1080 Twine(" cannot be linked. It contains ObjC built for the simulator"
1081 " while we are linking a non-simulator target"));
1082 assert((_objcConstraint == objc_unknown ||
1083 _objcConstraint == objc_retainReleaseForSimulator) &&
1084 "Must be linking with retain/release for the simulator");
1085 _objcConstraint = objc_retainReleaseForSimulator;
1086 break;
1087 case objc_retainRelease:
1088 // The file is built without simulator objc, so make sure that the
1089 // context is also building without simulator support.
1090 if (_os == OS::iOS_simulator)
1091 return make_dynamic_error_code(file.path() +
1092 Twine(" cannot be linked. It contains ObjC built for a non-simulator"
1093 " target while we are linking a simulator target"));
1094 assert((_objcConstraint == objc_unknown ||
1095 _objcConstraint == objc_retainRelease) &&
1096 "Must be linking with retain/release for a non-simulator target");
1097 _objcConstraint = objc_retainRelease;
1098 break;
1099 }
1100
Pete Coopera014ffe2016-01-16 00:07:22 +00001101 // Check that the swift version of the context matches that of the file.
1102 // Also set the swift version of the context if it didn't have one.
1103 if (!_swiftVersion) {
1104 _swiftVersion = machoFile->swiftVersion();
1105 } else if (machoFile->swiftVersion() &&
1106 machoFile->swiftVersion() != _swiftVersion) {
1107 // Swift versions are different.
1108 return make_dynamic_error_code("different swift versions");
1109 }
Pete Cooper90dbab02016-01-19 21:54:21 +00001110
Pete Cooper80c09742016-01-14 21:53:13 +00001111 return std::error_code();
1112}
1113
Rui Ueyama0ca149f2013-08-06 22:31:59 +00001114} // end namespace lld