blob: acd919e4d411b4ffea9cee2f8acac2f3541ca9ed [file] [log] [blame]
Rui Ueyama0ca149f2013-08-06 22:31:59 +00001//===- lib/ReaderWriter/MachO/MachOLinkingContext.cpp ---------------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Rui Ueyama0ca149f2013-08-06 22:31:59 +00006//
7//===----------------------------------------------------------------------===//
8
Brian Gesiakb9f7f4b2018-06-12 02:34:04 +00009#include "lld/Common/ErrorHandler.h"
Rui Ueyama0ca149f2013-08-06 22:31:59 +000010#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 Ueyama3f851702017-10-02 21:00:41 +000017#include "lld/Common/Driver.h"
Rui Ueyamadf230b22015-01-15 04:34:31 +000018#include "lld/Core/ArchiveLibraryFile.h"
Rui Ueyama0ca149f2013-08-06 22:31:59 +000019#include "lld/Core/PassManager.h"
Greg Fitzgerald4b6a7e32015-01-21 22:54:56 +000020#include "lld/Core/Reader.h"
21#include "lld/Core/Writer.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"
Zachary Turner264b5d92017-06-07 03:48:56 +000025#include "llvm/BinaryFormat/MachO.h"
Rafael Espindolad1942132016-09-06 19:17:14 +000026#include "llvm/Demangle/Demangle.h"
Rui Ueyama00eb2572014-12-10 00:33:00 +000027#include "llvm/Support/Debug.h"
Chandler Carruth89642a72015-01-14 11:26:52 +000028#include "llvm/Support/Errc.h"
Nick Kledzike34182f2013-11-06 21:36:55 +000029#include "llvm/Support/Host.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
Nick Kledzik2458bec2014-07-16 19:49:02 +000033using lld::mach_o::ArchHandler;
Pete Cooper99f3b942016-01-14 23:25:06 +000034using lld::mach_o::MachOFile;
Nick Kledzik8fc67fb2014-08-13 23:55:41 +000035using lld::mach_o::MachODylibFile;
Nick Kledzike34182f2013-11-06 21:36:55 +000036using namespace llvm::MachO;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000037
38namespace lld {
39
Nick Kledzike850d9d2013-09-10 23:46:57 +000040bool MachOLinkingContext::parsePackedVersion(StringRef str, uint32_t &result) {
41 result = 0;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000042
43 if (str.empty())
44 return false;
45
46 SmallVector<StringRef, 3> parts;
47 llvm::SplitString(str, parts, ".");
48
49 unsigned long long num;
50 if (llvm::getAsUnsignedInteger(parts[0], 10, num))
51 return true;
52 if (num > 65535)
53 return true;
Nick Kledzike850d9d2013-09-10 23:46:57 +000054 result = num << 16;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000055
56 if (parts.size() > 1) {
57 if (llvm::getAsUnsignedInteger(parts[1], 10, num))
58 return true;
59 if (num > 255)
60 return true;
Nick Kledzike850d9d2013-09-10 23:46:57 +000061 result |= (num << 8);
Rui Ueyama0ca149f2013-08-06 22:31:59 +000062 }
63
64 if (parts.size() > 2) {
65 if (llvm::getAsUnsignedInteger(parts[2], 10, num))
66 return true;
67 if (num > 255)
68 return true;
Nick Kledzike850d9d2013-09-10 23:46:57 +000069 result |= num;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000070 }
71
72 return false;
73}
74
Pete Cooper40576fa2016-02-04 02:45:23 +000075bool MachOLinkingContext::parsePackedVersion(StringRef str, uint64_t &result) {
76 result = 0;
77
78 if (str.empty())
79 return false;
80
81 SmallVector<StringRef, 5> parts;
82 llvm::SplitString(str, parts, ".");
83
Pete Cooperd5c0e4d2016-02-04 02:50:47 +000084 unsigned long long num;
Pete Cooper40576fa2016-02-04 02:45:23 +000085 if (llvm::getAsUnsignedInteger(parts[0], 10, num))
86 return true;
87 if (num > 0xFFFFFF)
88 return true;
89 result = num << 40;
90
91 unsigned Shift = 30;
92 for (StringRef str : llvm::makeArrayRef(parts).slice(1)) {
93 if (llvm::getAsUnsignedInteger(str, 10, num))
94 return true;
95 if (num > 0x3FF)
96 return true;
97 result |= (num << Shift);
98 Shift -= 10;
99 }
100
101 return false;
102}
103
Nick Kledzike34182f2013-11-06 21:36:55 +0000104MachOLinkingContext::ArchInfo MachOLinkingContext::_s_archInfos[] = {
105 { "x86_64", arch_x86_64, true, CPU_TYPE_X86_64, CPU_SUBTYPE_X86_64_ALL },
106 { "i386", arch_x86, true, CPU_TYPE_I386, CPU_SUBTYPE_X86_ALL },
107 { "ppc", arch_ppc, false, CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_ALL },
108 { "armv6", arch_armv6, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V6 },
109 { "armv7", arch_armv7, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7 },
110 { "armv7s", arch_armv7s, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7S },
Nick Kledzik1bebb282014-09-09 23:52:59 +0000111 { "arm64", arch_arm64, true, CPU_TYPE_ARM64, CPU_SUBTYPE_ARM64_ALL },
Nick Kledzike34182f2013-11-06 21:36:55 +0000112 { "", arch_unknown,false, 0, 0 }
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000113};
114
115MachOLinkingContext::Arch
116MachOLinkingContext::archFromCpuType(uint32_t cputype, uint32_t cpusubtype) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000117 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
118 if ((info->cputype == cputype) && (info->cpusubtype == cpusubtype))
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000119 return info->arch;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000120 }
121 return arch_unknown;
122}
123
124MachOLinkingContext::Arch
125MachOLinkingContext::archFromName(StringRef archName) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000126 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
127 if (info->archName.equals(archName))
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000128 return info->arch;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000129 }
130 return arch_unknown;
131}
132
Nick Kledzike5552772013-12-19 21:58:00 +0000133StringRef MachOLinkingContext::nameFromArch(Arch arch) {
134 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
135 if (info->arch == arch)
136 return info->archName;
137 }
138 return "<unknown>";
139}
140
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000141uint32_t MachOLinkingContext::cpuTypeFromArch(Arch arch) {
142 assert(arch != arch_unknown);
Nick Kledzike34182f2013-11-06 21:36:55 +0000143 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
144 if (info->arch == arch)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000145 return info->cputype;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000146 }
147 llvm_unreachable("Unknown arch type");
148}
149
150uint32_t MachOLinkingContext::cpuSubtypeFromArch(Arch arch) {
151 assert(arch != arch_unknown);
Nick Kledzike34182f2013-11-06 21:36:55 +0000152 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
153 if (info->arch == arch)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000154 return info->cpusubtype;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000155 }
156 llvm_unreachable("Unknown arch type");
157}
158
Nick Kledzik635f9c72014-09-04 20:08:30 +0000159bool MachOLinkingContext::isThinObjectFile(StringRef path, Arch &arch) {
160 return mach_o::normalized::isThinObjectFile(path, arch);
161}
162
Rafael Espindolaed48e532015-04-27 22:48:51 +0000163bool MachOLinkingContext::sliceFromFatFile(MemoryBufferRef mb, uint32_t &offset,
Nick Kledzik14b5d202014-10-08 01:48:10 +0000164 uint32_t &size) {
165 return mach_o::normalized::sliceFromFatFile(mb, _arch, offset, size);
166}
167
Rui Ueyama51502552016-03-02 19:06:20 +0000168MachOLinkingContext::MachOLinkingContext() {}
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000169
Pete Cooper8ad55fb2016-03-22 17:15:50 +0000170MachOLinkingContext::~MachOLinkingContext() {
171 // Atoms are allocated on BumpPtrAllocator's on File's.
172 // As we transfer atoms from one file to another, we need to clear all of the
173 // atoms before we remove any of the BumpPtrAllocator's.
174 auto &nodes = getNodes();
175 for (unsigned i = 0, e = nodes.size(); i != e; ++i) {
176 FileNode *node = dyn_cast<FileNode>(nodes[i].get());
177 if (!node)
178 continue;
179 File *file = node->getFile();
180 file->clearAtoms();
181 }
182}
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000183
Nick Kledzik6960b072013-12-21 01:47:17 +0000184void MachOLinkingContext::configure(HeaderFileType type, Arch arch, OS os,
Pete Cooper35116452016-01-22 21:13:24 +0000185 uint32_t minOSVersion,
186 bool exportDynamicSymbols) {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000187 _outputMachOType = type;
Nick Kledzik6960b072013-12-21 01:47:17 +0000188 _arch = arch;
189 _os = os;
190 _osMinVersion = minOSVersion;
191
Nick Kledzikcb2018f2014-10-09 01:01:16 +0000192 // If min OS not specified on command line, use reasonable defaults.
Pete Cooper3dd478a2016-02-04 01:57:59 +0000193 // Note that we only do sensible defaults when emitting something other than
194 // object and preload.
195 if (_outputMachOType != llvm::MachO::MH_OBJECT &&
196 _outputMachOType != llvm::MachO::MH_PRELOAD) {
197 if (minOSVersion == 0) {
198 switch (_arch) {
199 case arch_x86_64:
200 case arch_x86:
201 parsePackedVersion("10.8", _osMinVersion);
202 _os = MachOLinkingContext::OS::macOSX;
203 break;
204 case arch_armv6:
205 case arch_armv7:
206 case arch_armv7s:
207 case arch_arm64:
208 parsePackedVersion("7.0", _osMinVersion);
209 _os = MachOLinkingContext::OS::iOS;
210 break;
211 default:
212 break;
213 }
Nick Kledzikcb2018f2014-10-09 01:01:16 +0000214 }
215 }
216
Tim Northoverd30a1f22014-06-20 15:59:00 +0000217 switch (_outputMachOType) {
Nick Kledzik6960b072013-12-21 01:47:17 +0000218 case llvm::MachO::MH_EXECUTE:
219 // If targeting newer OS, use _main
220 if (minOS("10.8", "6.0")) {
221 _entrySymbolName = "_main";
222 } else {
223 // If targeting older OS, use start (in crt1.o)
224 _entrySymbolName = "start";
225 }
226
227 // __PAGEZERO defaults to 4GB on 64-bit (except for PP64 which lld does not
228 // support) and 4KB on 32-bit.
229 if (is64Bit(_arch)) {
230 _pageZeroSize = 0x100000000;
231 } else {
232 _pageZeroSize = 0x1000;
233 }
234
Lang Hamesc80344282015-09-21 22:06:02 +0000235 // Initial base address is __PAGEZERO size.
236 _baseAddress = _pageZeroSize;
237
Nick Kledzikb7035ae2014-09-09 00:17:52 +0000238 // Make PIE by default when targetting newer OSs.
239 switch (os) {
240 case OS::macOSX:
241 if (minOSVersion >= 0x000A0700) // MacOSX 10.7
242 _pie = true;
243 break;
244 case OS::iOS:
245 if (minOSVersion >= 0x00040300) // iOS 4.3
246 _pie = true;
247 break;
248 case OS::iOS_simulator:
249 _pie = true;
250 break;
251 case OS::unknown:
252 break;
253 }
Pete Cooper35116452016-01-22 21:13:24 +0000254 setGlobalsAreDeadStripRoots(exportDynamicSymbols);
Nick Kledzik6960b072013-12-21 01:47:17 +0000255 break;
256 case llvm::MachO::MH_DYLIB:
Pete Cooper35116452016-01-22 21:13:24 +0000257 setGlobalsAreDeadStripRoots(exportDynamicSymbols);
Nick Kledzik6960b072013-12-21 01:47:17 +0000258 break;
259 case llvm::MachO::MH_BUNDLE:
260 break;
261 case llvm::MachO::MH_OBJECT:
262 _printRemainingUndefines = false;
263 _allowRemainingUndefines = true;
Reid Kleckner4dc0b1a2018-11-01 19:54:45 +0000264 break;
Nick Kledzik6960b072013-12-21 01:47:17 +0000265 default:
266 break;
267 }
Nick Kledzik1bebb282014-09-09 23:52:59 +0000268
269 // Set default segment page sizes based on arch.
270 if (arch == arch_arm64)
271 _pageSize = 4*4096;
Nick Kledzik6960b072013-12-21 01:47:17 +0000272}
273
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000274uint32_t MachOLinkingContext::getCPUType() const {
275 return cpuTypeFromArch(_arch);
276}
277
278uint32_t MachOLinkingContext::getCPUSubType() const {
279 return cpuSubtypeFromArch(_arch);
280}
281
Nick Kledzike34182f2013-11-06 21:36:55 +0000282bool MachOLinkingContext::is64Bit(Arch arch) {
283 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
284 if (info->arch == arch) {
285 return (info->cputype & CPU_ARCH_ABI64);
286 }
287 }
288 // unknown archs are not 64-bit.
289 return false;
290}
291
292bool MachOLinkingContext::isHostEndian(Arch arch) {
293 assert(arch != arch_unknown);
294 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
295 if (info->arch == arch) {
296 return (info->littleEndian == llvm::sys::IsLittleEndianHost);
297 }
298 }
299 llvm_unreachable("Unknown arch type");
300}
301
302bool MachOLinkingContext::isBigEndian(Arch arch) {
303 assert(arch != arch_unknown);
304 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
305 if (info->arch == arch) {
306 return ! info->littleEndian;
307 }
308 }
309 llvm_unreachable("Unknown arch type");
310}
311
Nick Kledzike34182f2013-11-06 21:36:55 +0000312bool MachOLinkingContext::is64Bit() const {
313 return is64Bit(_arch);
314}
315
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000316bool MachOLinkingContext::outputTypeHasEntry() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000317 switch (_outputMachOType) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000318 case MH_EXECUTE:
319 case MH_DYLINKER:
320 case MH_PRELOAD:
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000321 return true;
322 default:
323 return false;
324 }
325}
326
Nick Kledzik2458bec2014-07-16 19:49:02 +0000327bool MachOLinkingContext::needsStubsPass() const {
328 switch (_outputMachOType) {
329 case MH_EXECUTE:
330 return !_outputMachOTypeStatic;
331 case MH_DYLIB:
332 case MH_BUNDLE:
333 return true;
334 default:
335 return false;
336 }
337}
338
339bool MachOLinkingContext::needsGOTPass() const {
Nick Kledzik1bebb282014-09-09 23:52:59 +0000340 // GOT pass not used in -r mode.
341 if (_outputMachOType == MH_OBJECT)
Nick Kledzik2458bec2014-07-16 19:49:02 +0000342 return false;
Nick Kledzik1bebb282014-09-09 23:52:59 +0000343 // Only some arches use GOT pass.
344 switch (_arch) {
345 case arch_x86_64:
346 case arch_arm64:
347 return true;
348 default:
349 return false;
350 }
Nick Kledzik2458bec2014-07-16 19:49:02 +0000351}
352
Tim Northovercf78d372014-09-30 21:29:54 +0000353bool MachOLinkingContext::needsCompactUnwindPass() const {
354 switch (_outputMachOType) {
355 case MH_EXECUTE:
356 case MH_DYLIB:
357 case MH_BUNDLE:
358 return archHandler().needsCompactUnwind();
359 default:
360 return false;
361 }
362}
Nick Kledzik2458bec2014-07-16 19:49:02 +0000363
Pete Cooper90dbab02016-01-19 21:54:21 +0000364bool MachOLinkingContext::needsObjCPass() const {
365 // ObjC pass is only needed if any of the inputs were ObjC.
366 return _objcConstraint != objc_unknown;
367}
368
Nick Kledzik4121bce2014-10-14 01:51:42 +0000369bool MachOLinkingContext::needsShimPass() const {
370 // Shim pass only used in final executables.
371 if (_outputMachOType == MH_OBJECT)
372 return false;
373 // Only 32-bit arm arches use Shim pass.
374 switch (_arch) {
375 case arch_armv6:
376 case arch_armv7:
377 case arch_armv7s:
378 return true;
379 default:
380 return false;
381 }
382}
383
Lang Hames49047032015-06-23 20:35:31 +0000384bool MachOLinkingContext::needsTLVPass() const {
385 switch (_outputMachOType) {
386 case MH_BUNDLE:
387 case MH_EXECUTE:
388 case MH_DYLIB:
389 return true;
390 default:
391 return false;
392 }
393}
394
Nick Kledzik2458bec2014-07-16 19:49:02 +0000395StringRef MachOLinkingContext::binderSymbolName() const {
396 return archHandler().stubInfo().binderSymbolName;
397}
398
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000399bool MachOLinkingContext::minOS(StringRef mac, StringRef iOS) const {
Nick Kledzik30332b12013-10-08 00:43:34 +0000400 uint32_t parsedVersion;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000401 switch (_os) {
Nick Kledzik30332b12013-10-08 00:43:34 +0000402 case OS::macOSX:
Nick Kledzike850d9d2013-09-10 23:46:57 +0000403 if (parsePackedVersion(mac, parsedVersion))
404 return false;
405 return _osMinVersion >= parsedVersion;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000406 case OS::iOS:
Nick Kledzik30332b12013-10-08 00:43:34 +0000407 case OS::iOS_simulator:
Nick Kledzike850d9d2013-09-10 23:46:57 +0000408 if (parsePackedVersion(iOS, parsedVersion))
409 return false;
410 return _osMinVersion >= parsedVersion;
Nick Kledzik30332b12013-10-08 00:43:34 +0000411 case OS::unknown:
Pete Cooper3dd478a2016-02-04 01:57:59 +0000412 // If we don't know the target, then assume that we don't meet the min OS.
413 // This matches the ld64 behaviour
414 return false;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000415 }
Reid Kleckner257102e2016-02-10 19:28:13 +0000416 llvm_unreachable("invalid OS enum");
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000417}
418
419bool MachOLinkingContext::addEntryPointLoadCommand() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000420 if ((_outputMachOType == MH_EXECUTE) && !_outputMachOTypeStatic) {
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000421 return minOS("10.8", "6.0");
422 }
423 return false;
424}
425
426bool MachOLinkingContext::addUnixThreadLoadCommand() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000427 switch (_outputMachOType) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000428 case MH_EXECUTE:
Tim Northoverd30a1f22014-06-20 15:59:00 +0000429 if (_outputMachOTypeStatic)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000430 return true;
431 else
432 return !minOS("10.8", "6.0");
433 break;
Nick Kledzike34182f2013-11-06 21:36:55 +0000434 case MH_DYLINKER:
435 case MH_PRELOAD:
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000436 return true;
437 default:
438 return false;
439 }
440}
441
Tim Northover77d82202014-07-10 11:21:06 +0000442bool MachOLinkingContext::pathExists(StringRef path) const {
Nick Kledzik94174f72014-08-15 19:53:41 +0000443 if (!_testingFileUsage)
Tim Northover77d82202014-07-10 11:21:06 +0000444 return llvm::sys::fs::exists(path.str());
445
446 // Otherwise, we're in test mode: only files explicitly provided on the
447 // command-line exist.
Rui Ueyama57a29532014-08-06 19:37:35 +0000448 std::string key = path.str();
449 std::replace(key.begin(), key.end(), '\\', '/');
450 return _existingPaths.find(key) != _existingPaths.end();
Tim Northover77d82202014-07-10 11:21:06 +0000451}
452
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000453bool MachOLinkingContext::fileExists(StringRef path) const {
454 bool found = pathExists(path);
455 // Log search misses.
456 if (!found)
457 addInputFileNotFound(path);
458
459 // When testing, file is never opened, so logging is done here.
460 if (_testingFileUsage && found)
461 addInputFileDependency(path);
462
463 return found;
464}
465
Nick Kledzik2d835da2014-08-14 22:20:41 +0000466void MachOLinkingContext::setSysLibRoots(const StringRefVector &paths) {
467 _syslibRoots = paths;
468}
469
Jean-Daniel Dupas23dd15e2014-12-18 21:33:38 +0000470void MachOLinkingContext::addRpath(StringRef rpath) {
471 _rpaths.push_back(rpath);
472}
473
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000474void MachOLinkingContext::addModifiedSearchDir(StringRef libPath,
475 bool isSystemPath) {
Tim Northover77d82202014-07-10 11:21:06 +0000476 bool addedModifiedPath = false;
477
Nick Kledzik2d835da2014-08-14 22:20:41 +0000478 // -syslibroot only applies to absolute paths.
479 if (libPath.startswith("/")) {
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000480 for (auto syslibRoot : _syslibRoots) {
Tim Northover77d82202014-07-10 11:21:06 +0000481 SmallString<256> path(syslibRoot);
482 llvm::sys::path::append(path, libPath);
483 if (pathExists(path)) {
484 _searchDirs.push_back(path.str().copy(_allocator));
485 addedModifiedPath = true;
486 }
487 }
488 }
489
490 if (addedModifiedPath)
491 return;
492
493 // Finally, if only one -syslibroot is given, system paths which aren't in it
494 // get suppressed.
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000495 if (_syslibRoots.size() != 1 || !isSystemPath) {
Tim Northover77d82202014-07-10 11:21:06 +0000496 if (pathExists(libPath)) {
497 _searchDirs.push_back(libPath);
498 }
499 }
500}
501
Nick Kledzik2d835da2014-08-14 22:20:41 +0000502void MachOLinkingContext::addFrameworkSearchDir(StringRef fwPath,
503 bool isSystemPath) {
504 bool pathAdded = false;
505
506 // -syslibroot only used with to absolute framework search paths.
507 if (fwPath.startswith("/")) {
508 for (auto syslibRoot : _syslibRoots) {
509 SmallString<256> path(syslibRoot);
510 llvm::sys::path::append(path, fwPath);
511 if (pathExists(path)) {
512 _frameworkDirs.push_back(path.str().copy(_allocator));
513 pathAdded = true;
514 }
515 }
516 }
517 // If fwPath found in any -syslibroot, then done.
518 if (pathAdded)
519 return;
520
521 // If only one -syslibroot, system paths not in that SDK are suppressed.
522 if (isSystemPath && (_syslibRoots.size() == 1))
523 return;
524
525 // Only use raw fwPath if that directory exists.
526 if (pathExists(fwPath))
527 _frameworkDirs.push_back(fwPath);
528}
529
Pete Cooperd0a643e2016-03-31 01:09:35 +0000530llvm::Optional<StringRef>
Tim Northover77d82202014-07-10 11:21:06 +0000531MachOLinkingContext::searchDirForLibrary(StringRef path,
532 StringRef libName) const {
533 SmallString<256> fullPath;
534 if (libName.endswith(".o")) {
535 // A request ending in .o is special: just search for the file directly.
536 fullPath.assign(path);
537 llvm::sys::path::append(fullPath, libName);
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000538 if (fileExists(fullPath))
Tim Northover77d82202014-07-10 11:21:06 +0000539 return fullPath.str().copy(_allocator);
Pete Cooperd0a643e2016-03-31 01:09:35 +0000540 return llvm::None;
Tim Northover77d82202014-07-10 11:21:06 +0000541 }
542
Nico Weberba5087f2020-07-02 00:02:09 -0400543 // Search for stub library
544 fullPath.assign(path);
545 llvm::sys::path::append(fullPath, Twine("lib") + libName + ".tbd");
546 if (fileExists(fullPath))
547 return fullPath.str().copy(_allocator);
548
Tim Northover77d82202014-07-10 11:21:06 +0000549 // Search for dynamic library
550 fullPath.assign(path);
551 llvm::sys::path::append(fullPath, Twine("lib") + libName + ".dylib");
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000552 if (fileExists(fullPath))
Tim Northover77d82202014-07-10 11:21:06 +0000553 return fullPath.str().copy(_allocator);
554
555 // If not, try for a static library
556 fullPath.assign(path);
557 llvm::sys::path::append(fullPath, Twine("lib") + libName + ".a");
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000558 if (fileExists(fullPath))
Tim Northover77d82202014-07-10 11:21:06 +0000559 return fullPath.str().copy(_allocator);
560
Pete Cooperd0a643e2016-03-31 01:09:35 +0000561 return llvm::None;
Tim Northover77d82202014-07-10 11:21:06 +0000562}
563
Pete Cooperd0a643e2016-03-31 01:09:35 +0000564llvm::Optional<StringRef>
565MachOLinkingContext::searchLibrary(StringRef libName) const {
Tim Northover77d82202014-07-10 11:21:06 +0000566 SmallString<256> path;
567 for (StringRef dir : searchDirs()) {
Pete Cooperd0a643e2016-03-31 01:09:35 +0000568 llvm::Optional<StringRef> searchDir = searchDirForLibrary(dir, libName);
569 if (searchDir)
570 return searchDir;
Tim Northover77d82202014-07-10 11:21:06 +0000571 }
572
Pete Cooperd0a643e2016-03-31 01:09:35 +0000573 return llvm::None;
Tim Northover77d82202014-07-10 11:21:06 +0000574}
575
Pete Cooperd0a643e2016-03-31 01:09:35 +0000576llvm::Optional<StringRef>
577MachOLinkingContext::findPathForFramework(StringRef fwName) const{
Nick Kledzik2d835da2014-08-14 22:20:41 +0000578 SmallString<256> fullPath;
579 for (StringRef dir : frameworkDirs()) {
580 fullPath.assign(dir);
581 llvm::sys::path::append(fullPath, Twine(fwName) + ".framework", fwName);
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000582 if (fileExists(fullPath))
Nick Kledzik2d835da2014-08-14 22:20:41 +0000583 return fullPath.str().copy(_allocator);
584 }
585
Pete Cooperd0a643e2016-03-31 01:09:35 +0000586 return llvm::None;
Nick Kledzik2d835da2014-08-14 22:20:41 +0000587}
588
Brian Gesiakb9f7f4b2018-06-12 02:34:04 +0000589bool MachOLinkingContext::validateImpl() {
Nick Kledzike34182f2013-11-06 21:36:55 +0000590 // TODO: if -arch not specified, look at arch of first .o file.
591
Tim Northoverd30a1f22014-06-20 15:59:00 +0000592 if (_currentVersion && _outputMachOType != MH_DYLIB) {
Brian Gesiakb9f7f4b2018-06-12 02:34:04 +0000593 error("-current_version can only be used with dylibs");
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000594 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000595 }
596
Tim Northoverd30a1f22014-06-20 15:59:00 +0000597 if (_compatibilityVersion && _outputMachOType != MH_DYLIB) {
Brian Gesiakb9f7f4b2018-06-12 02:34:04 +0000598 error("-compatibility_version can only be used with dylibs");
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 (_deadStrippableDylib && _outputMachOType != MH_DYLIB) {
Brian Gesiakb9f7f4b2018-06-12 02:34:04 +0000603 error("-mark_dead_strippable_dylib can only be used with dylibs");
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000604 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000605 }
606
Tim Northoverd30a1f22014-06-20 15:59:00 +0000607 if (!_bundleLoader.empty() && outputMachOType() != MH_BUNDLE) {
Brian Gesiakb9f7f4b2018-06-12 02:34:04 +0000608 error("-bundle_loader can only be used with Mach-O bundles");
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000609 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000610 }
611
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000612 // If -exported_symbols_list used, all exported symbols must be defined.
Eric Christopher058ec202020-06-19 21:50:14 -0700613 if (_exportMode == ExportMode::exported) {
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000614 for (const auto &symbol : _exportedSymbols)
615 addInitialUndefinedSymbol(symbol.getKey());
616 }
617
Nick Kledzik77afc712014-08-21 20:25:50 +0000618 // If -dead_strip, set up initial live symbols.
619 if (deadStrip()) {
620 // Entry point is live.
621 if (outputTypeHasEntry())
622 addDeadStripRoot(entrySymbolName());
623 // Lazy binding helper is live.
624 if (needsStubsPass())
625 addDeadStripRoot(binderSymbolName());
626 // If using -exported_symbols_list, make all exported symbols live.
Eric Christopher058ec202020-06-19 21:50:14 -0700627 if (_exportMode == ExportMode::exported) {
Davide Italiano7b68b902015-03-09 06:05:42 +0000628 setGlobalsAreDeadStripRoots(false);
Nick Kledzik77afc712014-08-21 20:25:50 +0000629 for (const auto &symbol : _exportedSymbols)
630 addDeadStripRoot(symbol.getKey());
631 }
632 }
633
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000634 addOutputFileDependency(outputPath());
635
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000636 return true;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000637}
638
Shankar Easwaran2bc24922013-10-29 05:12:14 +0000639void MachOLinkingContext::addPasses(PassManager &pm) {
Pete Cooper90dbab02016-01-19 21:54:21 +0000640 // objc pass should be before layout pass. Otherwise test cases may contain
641 // no atoms which confuses the layout pass.
642 if (needsObjCPass())
643 mach_o::addObjCPass(pm, *this);
Rui Ueyama00762152015-02-05 20:05:33 +0000644 mach_o::addLayoutPass(pm, *this);
Nick Kledzik2458bec2014-07-16 19:49:02 +0000645 if (needsStubsPass())
646 mach_o::addStubsPass(pm, *this);
Tim Northovercf78d372014-09-30 21:29:54 +0000647 if (needsCompactUnwindPass())
648 mach_o::addCompactUnwindPass(pm, *this);
Nick Kledzik2458bec2014-07-16 19:49:02 +0000649 if (needsGOTPass())
650 mach_o::addGOTPass(pm, *this);
Lang Hames49047032015-06-23 20:35:31 +0000651 if (needsTLVPass())
652 mach_o::addTLVPass(pm, *this);
Nick Kledzik4121bce2014-10-14 01:51:42 +0000653 if (needsShimPass())
654 mach_o::addShimPass(pm, *this); // Shim pass must run after stubs pass.
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000655}
656
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000657Writer &MachOLinkingContext::writer() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000658 if (!_writer)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000659 _writer = createWriterMachO(*this);
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000660 return *_writer;
661}
662
Greg Fitzgeraldb4eb64e2015-01-23 23:26:13 +0000663ErrorOr<std::unique_ptr<MemoryBuffer>>
664MachOLinkingContext::getMemoryBuffer(StringRef path) {
665 addInputFileDependency(path);
666
Rui Ueyamadf230b22015-01-15 04:34:31 +0000667 ErrorOr<std::unique_ptr<MemoryBuffer>> mbOrErr =
Greg Fitzgeraldb4eb64e2015-01-23 23:26:13 +0000668 MemoryBuffer::getFileOrSTDIN(path);
669 if (std::error_code ec = mbOrErr.getError())
670 return ec;
671 std::unique_ptr<MemoryBuffer> mb = std::move(mbOrErr.get());
672
673 // If buffer contains a fat file, find required arch in fat buffer
674 // and switch buffer to point to just that required slice.
675 uint32_t offset;
676 uint32_t size;
Rafael Espindolaed48e532015-04-27 22:48:51 +0000677 if (sliceFromFatFile(mb->getMemBufferRef(), offset, size))
Greg Fitzgeraldb4eb64e2015-01-23 23:26:13 +0000678 return MemoryBuffer::getFileSlice(path, size, offset);
679 return std::move(mb);
680}
681
682MachODylibFile* MachOLinkingContext::loadIndirectDylib(StringRef path) {
683 ErrorOr<std::unique_ptr<MemoryBuffer>> mbOrErr = getMemoryBuffer(path);
Rui Ueyamadf230b22015-01-15 04:34:31 +0000684 if (mbOrErr.getError())
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000685 return nullptr;
686
Rafael Espindolaab5696b2015-04-24 18:51:30 +0000687 ErrorOr<std::unique_ptr<File>> fileOrErr =
688 registry().loadFile(std::move(mbOrErr.get()));
689 if (!fileOrErr)
Rui Ueyamadf230b22015-01-15 04:34:31 +0000690 return nullptr;
Rafael Espindola773a1592015-04-24 19:01:30 +0000691 std::unique_ptr<File> &file = fileOrErr.get();
692 file->parse();
693 MachODylibFile *result = reinterpret_cast<MachODylibFile *>(file.get());
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000694 // Node object now owned by _indirectDylibs vector.
Rafael Espindola773a1592015-04-24 19:01:30 +0000695 _indirectDylibs.push_back(std::move(file));
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000696 return result;
697}
698
Nick Kledzik22c90732014-10-01 20:24:30 +0000699MachODylibFile* MachOLinkingContext::findIndirectDylib(StringRef path) {
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000700 // See if already loaded.
701 auto pos = _pathToDylibMap.find(path);
702 if (pos != _pathToDylibMap.end())
703 return pos->second;
704
705 // Search -L paths if of the form "libXXX.dylib"
706 std::pair<StringRef, StringRef> split = path.rsplit('/');
707 StringRef leafName = split.second;
708 if (leafName.startswith("lib") && leafName.endswith(".dylib")) {
709 // FIXME: Need to enhance searchLibrary() to only look for .dylib
710 auto libPath = searchLibrary(leafName);
Pete Cooperd0a643e2016-03-31 01:09:35 +0000711 if (libPath)
712 return loadIndirectDylib(libPath.getValue());
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000713 }
714
715 // Try full path with sysroot.
716 for (StringRef sysPath : _syslibRoots) {
717 SmallString<256> fullPath;
718 fullPath.assign(sysPath);
719 llvm::sys::path::append(fullPath, path);
720 if (pathExists(fullPath))
721 return loadIndirectDylib(fullPath);
722 }
723
724 // Try full path.
725 if (pathExists(path)) {
726 return loadIndirectDylib(path);
727 }
728
729 return nullptr;
730}
731
Nick Kledzik5b9e48b2014-11-19 02:21:53 +0000732uint32_t MachOLinkingContext::dylibCurrentVersion(StringRef installName) const {
733 auto pos = _pathToDylibMap.find(installName);
734 if (pos != _pathToDylibMap.end())
735 return pos->second->currentVersion();
736 else
Pete Cooper932bce62016-08-11 18:41:14 +0000737 return 0x10000; // 1.0
Nick Kledzik5b9e48b2014-11-19 02:21:53 +0000738}
739
740uint32_t MachOLinkingContext::dylibCompatVersion(StringRef installName) const {
741 auto pos = _pathToDylibMap.find(installName);
742 if (pos != _pathToDylibMap.end())
743 return pos->second->compatVersion();
744 else
Pete Cooper932bce62016-08-11 18:41:14 +0000745 return 0x10000; // 1.0
Nick Kledzik5b9e48b2014-11-19 02:21:53 +0000746}
747
Simon Atanasyanc4378882015-04-06 20:43:35 +0000748void MachOLinkingContext::createImplicitFiles(
Nick Kledzik22c90732014-10-01 20:24:30 +0000749 std::vector<std::unique_ptr<File> > &result) {
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000750 // Add indirect dylibs by asking each linked dylib to add its indirects.
751 // Iterate until no more dylibs get loaded.
752 size_t dylibCount = 0;
753 while (dylibCount != _allDylibs.size()) {
754 dylibCount = _allDylibs.size();
755 for (MachODylibFile *dylib : _allDylibs) {
756 dylib->loadReExportedDylibs([this] (StringRef path) -> MachODylibFile* {
757 return findIndirectDylib(path); });
758 }
759 }
760
761 // Let writer add output type specific extras.
Simon Atanasyanc4378882015-04-06 20:43:35 +0000762 writer().createImplicitFiles(result);
Lang Hames5c692002015-09-28 20:25:14 +0000763
Lang Hames9a4c94e2015-09-28 20:52:21 +0000764 // If undefinedMode is != error, add a FlatNamespaceFile instance. This will
765 // provide a SharedLibraryAtom for symbols that aren't defined elsewhere.
766 if (undefinedMode() != UndefinedMode::error) {
767 result.emplace_back(new mach_o::FlatNamespaceFile(*this));
Lang Hames5c692002015-09-28 20:25:14 +0000768 _flatNamespaceFile = result.back().get();
769 }
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000770}
771
Nick Kledzik51720672014-10-16 19:31:28 +0000772void MachOLinkingContext::registerDylib(MachODylibFile *dylib,
773 bool upward) const {
Lang Hames9bbc3652015-05-13 00:17:08 +0000774 std::lock_guard<std::mutex> lock(_dylibsMutex);
Pete Cooper46cd1132016-08-11 20:10:14 +0000775
Fangrui Song8048fe22019-03-29 16:21:16 +0000776 if (!llvm::count(_allDylibs, dylib))
Pete Cooper46cd1132016-08-11 20:10:14 +0000777 _allDylibs.push_back(dylib);
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000778 _pathToDylibMap[dylib->installName()] = dylib;
779 // If path is different than install name, register path too.
780 if (!dylib->path().equals(dylib->installName()))
781 _pathToDylibMap[dylib->path()] = dylib;
Nick Kledzik51720672014-10-16 19:31:28 +0000782 if (upward)
783 _upwardDylibs.insert(dylib);
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000784}
785
Nick Kledzik51720672014-10-16 19:31:28 +0000786bool MachOLinkingContext::isUpwardDylib(StringRef installName) const {
787 for (MachODylibFile *dylib : _upwardDylibs) {
788 if (dylib->installName().equals(installName))
789 return true;
790 }
791 return false;
792}
793
Nick Kledzik2458bec2014-07-16 19:49:02 +0000794ArchHandler &MachOLinkingContext::archHandler() const {
795 if (!_archHandler)
796 _archHandler = ArchHandler::create(_arch);
797 return *_archHandler;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000798}
799
Nick Kledzik2fcbe822014-07-30 00:58:06 +0000800void MachOLinkingContext::addSectionAlignment(StringRef seg, StringRef sect,
Rui Ueyamada74d572015-03-26 02:23:45 +0000801 uint16_t align) {
802 SectionAlign entry = { seg, sect, align };
Nick Kledzik2fcbe822014-07-30 00:58:06 +0000803 _sectAligns.push_back(entry);
804}
805
Lang Hamesb1b67f42015-10-24 08:20:51 +0000806void MachOLinkingContext::addSectCreateSection(
807 StringRef seg, StringRef sect,
808 std::unique_ptr<MemoryBuffer> content) {
809
810 if (!_sectCreateFile) {
Jonas Devlieghere6ba79922019-08-14 22:28:17 +0000811 auto sectCreateFile = std::make_unique<mach_o::SectCreateFile>();
Lang Hamesb1b67f42015-10-24 08:20:51 +0000812 _sectCreateFile = sectCreateFile.get();
Jonas Devlieghere6ba79922019-08-14 22:28:17 +0000813 getNodes().push_back(std::make_unique<FileNode>(std::move(sectCreateFile)));
Lang Hamesb1b67f42015-10-24 08:20:51 +0000814 }
815
816 assert(_sectCreateFile && "sectcreate file does not exist.");
817 _sectCreateFile->addSection(seg, sect, std::move(content));
818}
819
Nick Kledzik2fcbe822014-07-30 00:58:06 +0000820bool MachOLinkingContext::sectionAligned(StringRef seg, StringRef sect,
Rui Ueyamada74d572015-03-26 02:23:45 +0000821 uint16_t &align) const {
Nick Kledzik2fcbe822014-07-30 00:58:06 +0000822 for (const SectionAlign &entry : _sectAligns) {
823 if (seg.equals(entry.segmentName) && sect.equals(entry.sectionName)) {
Rui Ueyamada74d572015-03-26 02:23:45 +0000824 align = entry.align;
Nick Kledzik2fcbe822014-07-30 00:58:06 +0000825 return true;
826 }
827 }
828 return false;
829}
830
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000831void MachOLinkingContext::addExportSymbol(StringRef sym) {
Nick Kledzik4183dbc2014-10-24 22:28:54 +0000832 // Support old crufty export lists with bogus entries.
833 if (sym.endswith(".eh") || sym.startswith(".objc_category_name_")) {
Rui Ueyamad0371f42019-11-19 11:16:59 +0900834 llvm::errs() << "warning: ignoring " << sym << " in export list\n";
Nick Kledzik4183dbc2014-10-24 22:28:54 +0000835 return;
836 }
837 // Only i386 MacOSX uses old ABI, so don't change those.
838 if ((_os != OS::macOSX) || (_arch != arch_x86)) {
Kazuaki Ishizaki7ae3d332020-01-06 10:21:05 -0800839 // ObjC has two different ABIs. Be nice and allow one export list work for
Nick Kledzik4183dbc2014-10-24 22:28:54 +0000840 // both ABIs by renaming symbols.
841 if (sym.startswith(".objc_class_name_")) {
842 std::string abi2className("_OBJC_CLASS_$_");
843 abi2className += sym.substr(17);
844 _exportedSymbols.insert(copy(abi2className));
845 std::string abi2metaclassName("_OBJC_METACLASS_$_");
846 abi2metaclassName += sym.substr(17);
847 _exportedSymbols.insert(copy(abi2metaclassName));
848 return;
849 }
850 }
851
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000852 // FIXME: Support wildcards.
853 _exportedSymbols.insert(sym);
854}
855
856bool MachOLinkingContext::exportSymbolNamed(StringRef sym) const {
857 switch (_exportMode) {
858 case ExportMode::globals:
859 llvm_unreachable("exportSymbolNamed() should not be called in this mode");
860 break;
Eric Christopher058ec202020-06-19 21:50:14 -0700861 case ExportMode::exported:
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000862 return _exportedSymbols.count(sym);
Eric Christopher058ec202020-06-19 21:50:14 -0700863 case ExportMode::unexported:
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000864 return !_exportedSymbols.count(sym);
865 }
Yaron Keren9682c852014-09-21 05:07:44 +0000866 llvm_unreachable("_exportMode unknown enum value");
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000867}
868
Nick Kledzikbe43d7e2014-09-30 23:15:39 +0000869std::string MachOLinkingContext::demangle(StringRef symbolName) const {
870 // Only try to demangle symbols if -demangle on command line
Davide Italiano6d86bb22015-02-18 03:54:21 +0000871 if (!demangleSymbols())
Benjamin Krameradcd0262020-01-28 20:23:46 +0100872 return std::string(symbolName);
Nick Kledzikbe43d7e2014-09-30 23:15:39 +0000873
874 // Only try to demangle symbols that look like C++ symbols
875 if (!symbolName.startswith("__Z"))
Benjamin Krameradcd0262020-01-28 20:23:46 +0100876 return std::string(symbolName);
Nick Kledzikbe43d7e2014-09-30 23:15:39 +0000877
Nick Kledzikbe43d7e2014-09-30 23:15:39 +0000878 SmallString<256> symBuff;
879 StringRef nullTermSym = Twine(symbolName).toNullTerminatedStringRef(symBuff);
880 // Mach-O has extra leading underscore that needs to be removed.
881 const char *cstr = nullTermSym.data() + 1;
882 int status;
Rafael Espindolad1942132016-09-06 19:17:14 +0000883 char *demangled = llvm::itaniumDemangle(cstr, nullptr, nullptr, &status);
Rui Ueyama43155d02015-10-02 00:36:00 +0000884 if (demangled) {
Nick Kledzikbe43d7e2014-09-30 23:15:39 +0000885 std::string result(demangled);
886 // __cxa_demangle() always uses a malloc'ed buffer to return the result.
887 free(demangled);
888 return result;
889 }
Nick Kledzikbe43d7e2014-09-30 23:15:39 +0000890
Benjamin Krameradcd0262020-01-28 20:23:46 +0100891 return std::string(symbolName);
Nick Kledzikbe43d7e2014-09-30 23:15:39 +0000892}
893
Davide Italianof6c1d2c2016-09-12 21:07:26 +0000894static void addDependencyInfoHelper(llvm::raw_fd_ostream *DepInfo,
895 char Opcode, StringRef Path) {
896 if (!DepInfo)
897 return;
898
899 *DepInfo << Opcode;
900 *DepInfo << Path;
901 *DepInfo << '\0';
902}
903
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000904std::error_code MachOLinkingContext::createDependencyFile(StringRef path) {
905 std::error_code ec;
Fangrui Songd9b948b2019-08-05 05:43:48 +0000906 _dependencyInfo = std::unique_ptr<llvm::raw_fd_ostream>(
907 new llvm::raw_fd_ostream(path, ec, llvm::sys::fs::OF_None));
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000908 if (ec) {
909 _dependencyInfo.reset();
910 return ec;
911 }
912
Davide Italianof6c1d2c2016-09-12 21:07:26 +0000913 addDependencyInfoHelper(_dependencyInfo.get(), 0x00, "lld" /*FIXME*/);
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000914 return std::error_code();
915}
916
917void MachOLinkingContext::addInputFileDependency(StringRef path) const {
Davide Italianof6c1d2c2016-09-12 21:07:26 +0000918 addDependencyInfoHelper(_dependencyInfo.get(), 0x10, path);
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000919}
920
921void MachOLinkingContext::addInputFileNotFound(StringRef path) const {
Davide Italianof6c1d2c2016-09-12 21:07:26 +0000922 addDependencyInfoHelper(_dependencyInfo.get(), 0x11, path);
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000923}
924
925void MachOLinkingContext::addOutputFileDependency(StringRef path) const {
Davide Italianof6c1d2c2016-09-12 21:07:26 +0000926 addDependencyInfoHelper(_dependencyInfo.get(), 0x40, path);
Nick Kledzik09d00bb2014-10-04 00:16:13 +0000927}
928
Nick Kledzik82d24bc2014-11-07 21:01:21 +0000929void MachOLinkingContext::appendOrderedSymbol(StringRef symbol,
930 StringRef filename) {
931 // To support sorting static functions which may have the same name in
932 // multiple .o files, _orderFiles maps the symbol name to a vector
933 // of OrderFileNode each of which can specify a file prefix.
934 OrderFileNode info;
935 if (!filename.empty())
936 info.fileFilter = copy(filename);
937 info.order = _orderFileEntries++;
938 _orderFiles[symbol].push_back(info);
939}
940
941bool
942MachOLinkingContext::findOrderOrdinal(const std::vector<OrderFileNode> &nodes,
943 const DefinedAtom *atom,
944 unsigned &ordinal) {
945 const File *objFile = &atom->file();
946 assert(objFile);
947 StringRef objName = objFile->path();
948 std::pair<StringRef, StringRef> dirAndLeaf = objName.rsplit('/');
949 if (!dirAndLeaf.second.empty())
950 objName = dirAndLeaf.second;
951 for (const OrderFileNode &info : nodes) {
952 if (info.fileFilter.empty()) {
953 // Have unprefixed symbol name in order file that matches this atom.
954 ordinal = info.order;
Nick Kledzik82d24bc2014-11-07 21:01:21 +0000955 return true;
956 }
957 if (info.fileFilter.equals(objName)) {
958 // Have prefixed symbol name in order file that matches atom's path.
959 ordinal = info.order;
Nick Kledzik82d24bc2014-11-07 21:01:21 +0000960 return true;
961 }
962 }
963 return false;
964}
965
966bool MachOLinkingContext::customAtomOrderer(const DefinedAtom *left,
967 const DefinedAtom *right,
Rui Ueyama00762152015-02-05 20:05:33 +0000968 bool &leftBeforeRight) const {
Nick Kledzik82d24bc2014-11-07 21:01:21 +0000969 // No custom sorting if no order file entries.
970 if (!_orderFileEntries)
971 return false;
972
973 // Order files can only order named atoms.
974 StringRef leftName = left->name();
975 StringRef rightName = right->name();
976 if (leftName.empty() || rightName.empty())
977 return false;
978
979 // If neither is in order file list, no custom sorter.
980 auto leftPos = _orderFiles.find(leftName);
981 auto rightPos = _orderFiles.find(rightName);
982 bool leftIsOrdered = (leftPos != _orderFiles.end());
983 bool rightIsOrdered = (rightPos != _orderFiles.end());
984 if (!leftIsOrdered && !rightIsOrdered)
985 return false;
986
987 // There could be multiple symbols with same name but different file prefixes.
988 unsigned leftOrder;
989 unsigned rightOrder;
990 bool foundLeft =
991 leftIsOrdered && findOrderOrdinal(leftPos->getValue(), left, leftOrder);
992 bool foundRight = rightIsOrdered &&
993 findOrderOrdinal(rightPos->getValue(), right, rightOrder);
994 if (!foundLeft && !foundRight)
995 return false;
996
997 // If only one is in order file list, ordered one goes first.
998 if (foundLeft != foundRight)
999 leftBeforeRight = foundLeft;
1000 else
1001 leftBeforeRight = (leftOrder < rightOrder);
1002
1003 return true;
1004}
Nick Kledzik8c0bf752014-08-21 01:59:11 +00001005
Rui Ueyama61635442015-01-15 08:31:46 +00001006static bool isLibrary(const std::unique_ptr<Node> &elem) {
Rui Ueyamaae1daae2015-01-15 08:51:23 +00001007 if (FileNode *node = dyn_cast<FileNode>(const_cast<Node *>(elem.get()))) {
1008 File *file = node->getFile();
1009 return isa<SharedLibraryFile>(file) || isa<ArchiveLibraryFile>(file);
1010 }
1011 return false;
Rui Ueyama00eb2572014-12-10 00:33:00 +00001012}
1013
1014// The darwin linker processes input files in two phases. The first phase
1015// links in all object (.o) files in command line order. The second phase
1016// links in libraries in command line order.
1017// In this function we reorder the input files so that all the object files
1018// comes before any library file. We also make a group for the library files
1019// so that the Resolver will reiterate over the libraries as long as we find
1020// new undefines from libraries.
Denis Protivenskycd617152015-03-14 10:34:43 +00001021void MachOLinkingContext::finalizeInputFiles() {
Rui Ueyama883afba2015-01-15 08:46:36 +00001022 std::vector<std::unique_ptr<Node>> &elements = getNodes();
Fangrui Song32c0ebe2019-04-23 02:42:06 +00001023 llvm::stable_sort(elements, [](const std::unique_ptr<Node> &a,
1024 const std::unique_ptr<Node> &b) {
1025 return !isLibrary(a) && isLibrary(b);
1026 });
Rui Ueyama00eb2572014-12-10 00:33:00 +00001027 size_t numLibs = std::count_if(elements.begin(), elements.end(), isLibrary);
Jonas Devlieghere6ba79922019-08-14 22:28:17 +00001028 elements.push_back(std::make_unique<GroupEnd>(numLibs));
Rui Ueyama00eb2572014-12-10 00:33:00 +00001029}
1030
Pete Cooper3c40b5b2016-03-30 20:56:54 +00001031llvm::Error MachOLinkingContext::handleLoadedFile(File &file) {
Pete Cooper99f3b942016-01-14 23:25:06 +00001032 auto *machoFile = dyn_cast<MachOFile>(&file);
1033 if (!machoFile)
Mehdi Aminic1edf562016-11-11 04:29:25 +00001034 return llvm::Error::success();
Pete Cooper99f3b942016-01-14 23:25:06 +00001035
1036 // Check that the arch of the context matches that of the file.
1037 // Also set the arch of the context if it didn't have one.
1038 if (_arch == arch_unknown) {
1039 _arch = machoFile->arch();
1040 } else if (machoFile->arch() != arch_unknown && machoFile->arch() != _arch) {
1041 // Archs are different.
Pete Cooper3c40b5b2016-03-30 20:56:54 +00001042 return llvm::make_error<GenericError>(file.path() +
Pete Cooper99f3b942016-01-14 23:25:06 +00001043 Twine(" cannot be linked due to incompatible architecture"));
1044 }
1045
1046 // Check that the OS of the context matches that of the file.
1047 // Also set the OS of the context if it didn't have one.
1048 if (_os == OS::unknown) {
1049 _os = machoFile->OS();
1050 } else if (machoFile->OS() != OS::unknown && machoFile->OS() != _os) {
1051 // OSes are different.
Pete Cooper3c40b5b2016-03-30 20:56:54 +00001052 return llvm::make_error<GenericError>(file.path() +
Pete Cooper99f3b942016-01-14 23:25:06 +00001053 Twine(" cannot be linked due to incompatible operating systems"));
1054 }
Pete Coopera014ffe2016-01-16 00:07:22 +00001055
Pete Cooper0872e462016-01-19 19:46:41 +00001056 // Check that if the objc info exists, that it is compatible with the target
1057 // OS.
1058 switch (machoFile->objcConstraint()) {
1059 case objc_unknown:
1060 // The file is not compiled with objc, so skip the checks.
1061 break;
1062 case objc_gc_only:
1063 case objc_supports_gc:
1064 llvm_unreachable("GC support should already have thrown an error");
1065 case objc_retainReleaseForSimulator:
1066 // The file is built with simulator objc, so make sure that the context
1067 // is also building with simulator support.
1068 if (_os != OS::iOS_simulator)
Pete Cooper3c40b5b2016-03-30 20:56:54 +00001069 return llvm::make_error<GenericError>(file.path() +
Pete Cooper0872e462016-01-19 19:46:41 +00001070 Twine(" cannot be linked. It contains ObjC built for the simulator"
1071 " while we are linking a non-simulator target"));
1072 assert((_objcConstraint == objc_unknown ||
1073 _objcConstraint == objc_retainReleaseForSimulator) &&
1074 "Must be linking with retain/release for the simulator");
1075 _objcConstraint = objc_retainReleaseForSimulator;
1076 break;
1077 case objc_retainRelease:
1078 // The file is built without simulator objc, so make sure that the
1079 // context is also building without simulator support.
1080 if (_os == OS::iOS_simulator)
Pete Cooper3c40b5b2016-03-30 20:56:54 +00001081 return llvm::make_error<GenericError>(file.path() +
Pete Cooper0872e462016-01-19 19:46:41 +00001082 Twine(" cannot be linked. It contains ObjC built for a non-simulator"
1083 " target while we are linking a simulator target"));
1084 assert((_objcConstraint == objc_unknown ||
1085 _objcConstraint == objc_retainRelease) &&
1086 "Must be linking with retain/release for a non-simulator target");
1087 _objcConstraint = objc_retainRelease;
1088 break;
1089 }
1090
Pete Coopera014ffe2016-01-16 00:07:22 +00001091 // Check that the swift version of the context matches that of the file.
1092 // Also set the swift version of the context if it didn't have one.
1093 if (!_swiftVersion) {
1094 _swiftVersion = machoFile->swiftVersion();
1095 } else if (machoFile->swiftVersion() &&
1096 machoFile->swiftVersion() != _swiftVersion) {
1097 // Swift versions are different.
Pete Cooper3c40b5b2016-03-30 20:56:54 +00001098 return llvm::make_error<GenericError>("different swift versions");
Pete Coopera014ffe2016-01-16 00:07:22 +00001099 }
Pete Cooper90dbab02016-01-19 21:54:21 +00001100
Mehdi Aminic1edf562016-11-11 04:29:25 +00001101 return llvm::Error::success();
Pete Cooper80c09742016-01-14 21:53:13 +00001102}
1103
Rui Ueyama0ca149f2013-08-06 22:31:59 +00001104} // end namespace lld