blob: e40c3d8582c0adbbd30f71558715aa8f7cfdd0b1 [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
12#include "ArchHandler.h"
Nick Kledzik8fc67fb2014-08-13 23:55:41 +000013#include "File.h"
Nick Kledzik635f9c72014-09-04 20:08:30 +000014#include "MachONormalizedFile.h"
Nick Kledzik2458bec2014-07-16 19:49:02 +000015#include "MachOPasses.h"
Rui Ueyama0ca149f2013-08-06 22:31:59 +000016
17#include "lld/Core/PassManager.h"
Nick Kledzik8fc67fb2014-08-13 23:55:41 +000018#include "lld/Driver/DarwinInputGraph.h"
Rui Ueyama0ca149f2013-08-06 22:31:59 +000019#include "lld/ReaderWriter/Reader.h"
20#include "lld/ReaderWriter/Writer.h"
21#include "lld/Passes/LayoutPass.h"
Shankar Easwaran2bc24922013-10-29 05:12:14 +000022#include "lld/Passes/RoundTripYAMLPass.h"
Rui Ueyama0ca149f2013-08-06 22:31:59 +000023
24#include "llvm/ADT/StringExtras.h"
25#include "llvm/ADT/Triple.h"
Tim Northover77d82202014-07-10 11:21:06 +000026#include "llvm/Support/Errc.h"
Nick Kledzike34182f2013-11-06 21:36:55 +000027#include "llvm/Support/Host.h"
Nick Kledzik473933b2013-09-27 22:50:00 +000028#include "llvm/Support/MachO.h"
Tim Northover77d82202014-07-10 11:21:06 +000029#include "llvm/Support/Path.h"
Rui Ueyama0ca149f2013-08-06 22:31:59 +000030
Rui Ueyama57a29532014-08-06 19:37:35 +000031#include <algorithm>
32
Nick Kledzik2458bec2014-07-16 19:49:02 +000033using lld::mach_o::ArchHandler;
Nick Kledzik8fc67fb2014-08-13 23:55:41 +000034using lld::mach_o::MachODylibFile;
Nick Kledzike34182f2013-11-06 21:36:55 +000035using namespace llvm::MachO;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000036
37namespace lld {
38
Nick Kledzike850d9d2013-09-10 23:46:57 +000039bool MachOLinkingContext::parsePackedVersion(StringRef str, uint32_t &result) {
40 result = 0;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000041
42 if (str.empty())
43 return false;
44
45 SmallVector<StringRef, 3> parts;
46 llvm::SplitString(str, parts, ".");
47
48 unsigned long long num;
49 if (llvm::getAsUnsignedInteger(parts[0], 10, num))
50 return true;
51 if (num > 65535)
52 return true;
Nick Kledzike850d9d2013-09-10 23:46:57 +000053 result = num << 16;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000054
55 if (parts.size() > 1) {
56 if (llvm::getAsUnsignedInteger(parts[1], 10, num))
57 return true;
58 if (num > 255)
59 return true;
Nick Kledzike850d9d2013-09-10 23:46:57 +000060 result |= (num << 8);
Rui Ueyama0ca149f2013-08-06 22:31:59 +000061 }
62
63 if (parts.size() > 2) {
64 if (llvm::getAsUnsignedInteger(parts[2], 10, num))
65 return true;
66 if (num > 255)
67 return true;
Nick Kledzike850d9d2013-09-10 23:46:57 +000068 result |= num;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000069 }
70
71 return false;
72}
73
Rui Ueyama0ca149f2013-08-06 22:31:59 +000074
Nick Kledzike34182f2013-11-06 21:36:55 +000075MachOLinkingContext::ArchInfo MachOLinkingContext::_s_archInfos[] = {
76 { "x86_64", arch_x86_64, true, CPU_TYPE_X86_64, CPU_SUBTYPE_X86_64_ALL },
77 { "i386", arch_x86, true, CPU_TYPE_I386, CPU_SUBTYPE_X86_ALL },
78 { "ppc", arch_ppc, false, CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_ALL },
79 { "armv6", arch_armv6, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V6 },
80 { "armv7", arch_armv7, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7 },
81 { "armv7s", arch_armv7s, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7S },
Nick Kledzik1bebb282014-09-09 23:52:59 +000082 { "arm64", arch_arm64, true, CPU_TYPE_ARM64, CPU_SUBTYPE_ARM64_ALL },
Nick Kledzike34182f2013-11-06 21:36:55 +000083 { "", arch_unknown,false, 0, 0 }
Rui Ueyama0ca149f2013-08-06 22:31:59 +000084};
85
86MachOLinkingContext::Arch
87MachOLinkingContext::archFromCpuType(uint32_t cputype, uint32_t cpusubtype) {
Nick Kledzike34182f2013-11-06 21:36:55 +000088 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
89 if ((info->cputype == cputype) && (info->cpusubtype == cpusubtype))
Rui Ueyama0ca149f2013-08-06 22:31:59 +000090 return info->arch;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000091 }
92 return arch_unknown;
93}
94
95MachOLinkingContext::Arch
96MachOLinkingContext::archFromName(StringRef archName) {
Nick Kledzike34182f2013-11-06 21:36:55 +000097 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
98 if (info->archName.equals(archName))
Rui Ueyama0ca149f2013-08-06 22:31:59 +000099 return info->arch;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000100 }
101 return arch_unknown;
102}
103
Nick Kledzike5552772013-12-19 21:58:00 +0000104StringRef MachOLinkingContext::nameFromArch(Arch arch) {
105 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
106 if (info->arch == arch)
107 return info->archName;
108 }
109 return "<unknown>";
110}
111
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000112uint32_t MachOLinkingContext::cpuTypeFromArch(Arch arch) {
113 assert(arch != arch_unknown);
Nick Kledzike34182f2013-11-06 21:36:55 +0000114 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
115 if (info->arch == arch)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000116 return info->cputype;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000117 }
118 llvm_unreachable("Unknown arch type");
119}
120
121uint32_t MachOLinkingContext::cpuSubtypeFromArch(Arch arch) {
122 assert(arch != arch_unknown);
Nick Kledzike34182f2013-11-06 21:36:55 +0000123 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
124 if (info->arch == arch)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000125 return info->cpusubtype;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000126 }
127 llvm_unreachable("Unknown arch type");
128}
129
Nick Kledzik635f9c72014-09-04 20:08:30 +0000130bool MachOLinkingContext::isThinObjectFile(StringRef path, Arch &arch) {
131 return mach_o::normalized::isThinObjectFile(path, arch);
132}
133
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000134MachOLinkingContext::MachOLinkingContext()
Tim Northoverd30a1f22014-06-20 15:59:00 +0000135 : _outputMachOType(MH_EXECUTE), _outputMachOTypeStatic(false),
Tim Northoveraf3075b2014-09-10 10:39:57 +0000136 _doNothing(false), _pie(false), _arch(arch_unknown), _os(OS::macOSX),
137 _osMinVersion(0), _pageZeroSize(0), _pageSize(4096), _baseAddress(0),
138 _compatibilityVersion(0), _currentVersion(0), _deadStrippableDylib(false),
139 _printAtoms(false), _testingFileUsage(false), _keepPrivateExterns(false),
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000140 _archHandler(nullptr), _exportMode(ExportMode::globals) {}
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000141
142MachOLinkingContext::~MachOLinkingContext() {}
143
Nick Kledzik6960b072013-12-21 01:47:17 +0000144void MachOLinkingContext::configure(HeaderFileType type, Arch arch, OS os,
145 uint32_t minOSVersion) {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000146 _outputMachOType = type;
Nick Kledzik6960b072013-12-21 01:47:17 +0000147 _arch = arch;
148 _os = os;
149 _osMinVersion = minOSVersion;
150
Tim Northoverd30a1f22014-06-20 15:59:00 +0000151 switch (_outputMachOType) {
Nick Kledzik6960b072013-12-21 01:47:17 +0000152 case llvm::MachO::MH_EXECUTE:
153 // If targeting newer OS, use _main
154 if (minOS("10.8", "6.0")) {
155 _entrySymbolName = "_main";
156 } else {
157 // If targeting older OS, use start (in crt1.o)
158 _entrySymbolName = "start";
159 }
160
161 // __PAGEZERO defaults to 4GB on 64-bit (except for PP64 which lld does not
162 // support) and 4KB on 32-bit.
163 if (is64Bit(_arch)) {
164 _pageZeroSize = 0x100000000;
165 } else {
166 _pageZeroSize = 0x1000;
167 }
168
Nick Kledzikb7035ae2014-09-09 00:17:52 +0000169 // Make PIE by default when targetting newer OSs.
170 switch (os) {
171 case OS::macOSX:
172 if (minOSVersion >= 0x000A0700) // MacOSX 10.7
173 _pie = true;
174 break;
175 case OS::iOS:
176 if (minOSVersion >= 0x00040300) // iOS 4.3
177 _pie = true;
178 break;
179 case OS::iOS_simulator:
180 _pie = true;
181 break;
182 case OS::unknown:
183 break;
184 }
Nick Kledzik6960b072013-12-21 01:47:17 +0000185 break;
186 case llvm::MachO::MH_DYLIB:
187 _globalsAreDeadStripRoots = true;
188 break;
189 case llvm::MachO::MH_BUNDLE:
190 break;
191 case llvm::MachO::MH_OBJECT:
192 _printRemainingUndefines = false;
193 _allowRemainingUndefines = true;
194 default:
195 break;
196 }
Nick Kledzik1bebb282014-09-09 23:52:59 +0000197
198 // Set default segment page sizes based on arch.
199 if (arch == arch_arm64)
200 _pageSize = 4*4096;
Nick Kledzik6960b072013-12-21 01:47:17 +0000201}
202
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000203uint32_t MachOLinkingContext::getCPUType() const {
204 return cpuTypeFromArch(_arch);
205}
206
207uint32_t MachOLinkingContext::getCPUSubType() const {
208 return cpuSubtypeFromArch(_arch);
209}
210
Nick Kledzike34182f2013-11-06 21:36:55 +0000211bool MachOLinkingContext::is64Bit(Arch arch) {
212 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
213 if (info->arch == arch) {
214 return (info->cputype & CPU_ARCH_ABI64);
215 }
216 }
217 // unknown archs are not 64-bit.
218 return false;
219}
220
221bool MachOLinkingContext::isHostEndian(Arch arch) {
222 assert(arch != arch_unknown);
223 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
224 if (info->arch == arch) {
225 return (info->littleEndian == llvm::sys::IsLittleEndianHost);
226 }
227 }
228 llvm_unreachable("Unknown arch type");
229}
230
231bool MachOLinkingContext::isBigEndian(Arch arch) {
232 assert(arch != arch_unknown);
233 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
234 if (info->arch == arch) {
235 return ! info->littleEndian;
236 }
237 }
238 llvm_unreachable("Unknown arch type");
239}
240
241
242
243bool MachOLinkingContext::is64Bit() const {
244 return is64Bit(_arch);
245}
246
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000247bool MachOLinkingContext::outputTypeHasEntry() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000248 switch (_outputMachOType) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000249 case MH_EXECUTE:
250 case MH_DYLINKER:
251 case MH_PRELOAD:
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000252 return true;
253 default:
254 return false;
255 }
256}
257
Nick Kledzik2458bec2014-07-16 19:49:02 +0000258bool MachOLinkingContext::needsStubsPass() const {
259 switch (_outputMachOType) {
260 case MH_EXECUTE:
261 return !_outputMachOTypeStatic;
262 case MH_DYLIB:
263 case MH_BUNDLE:
264 return true;
265 default:
266 return false;
267 }
268}
269
270bool MachOLinkingContext::needsGOTPass() const {
Nick Kledzik1bebb282014-09-09 23:52:59 +0000271 // GOT pass not used in -r mode.
272 if (_outputMachOType == MH_OBJECT)
Nick Kledzik2458bec2014-07-16 19:49:02 +0000273 return false;
Nick Kledzik1bebb282014-09-09 23:52:59 +0000274 // Only some arches use GOT pass.
275 switch (_arch) {
276 case arch_x86_64:
277 case arch_arm64:
278 return true;
279 default:
280 return false;
281 }
Nick Kledzik2458bec2014-07-16 19:49:02 +0000282}
283
Tim Northovercf78d372014-09-30 21:29:54 +0000284bool MachOLinkingContext::needsCompactUnwindPass() const {
285 switch (_outputMachOType) {
286 case MH_EXECUTE:
287 case MH_DYLIB:
288 case MH_BUNDLE:
289 return archHandler().needsCompactUnwind();
290 default:
291 return false;
292 }
293}
Nick Kledzik2458bec2014-07-16 19:49:02 +0000294
295StringRef MachOLinkingContext::binderSymbolName() const {
296 return archHandler().stubInfo().binderSymbolName;
297}
298
299
300
301
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000302bool MachOLinkingContext::minOS(StringRef mac, StringRef iOS) const {
Nick Kledzik30332b12013-10-08 00:43:34 +0000303 uint32_t parsedVersion;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000304 switch (_os) {
Nick Kledzik30332b12013-10-08 00:43:34 +0000305 case OS::macOSX:
Nick Kledzike850d9d2013-09-10 23:46:57 +0000306 if (parsePackedVersion(mac, parsedVersion))
307 return false;
308 return _osMinVersion >= parsedVersion;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000309 case OS::iOS:
Nick Kledzik30332b12013-10-08 00:43:34 +0000310 case OS::iOS_simulator:
Nick Kledzike850d9d2013-09-10 23:46:57 +0000311 if (parsePackedVersion(iOS, parsedVersion))
312 return false;
313 return _osMinVersion >= parsedVersion;
Nick Kledzik30332b12013-10-08 00:43:34 +0000314 case OS::unknown:
315 break;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000316 }
317 llvm_unreachable("target not configured for iOS or MacOSX");
318}
319
320bool MachOLinkingContext::addEntryPointLoadCommand() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000321 if ((_outputMachOType == MH_EXECUTE) && !_outputMachOTypeStatic) {
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000322 return minOS("10.8", "6.0");
323 }
324 return false;
325}
326
327bool MachOLinkingContext::addUnixThreadLoadCommand() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000328 switch (_outputMachOType) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000329 case MH_EXECUTE:
Tim Northoverd30a1f22014-06-20 15:59:00 +0000330 if (_outputMachOTypeStatic)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000331 return true;
332 else
333 return !minOS("10.8", "6.0");
334 break;
Nick Kledzike34182f2013-11-06 21:36:55 +0000335 case MH_DYLINKER:
336 case MH_PRELOAD:
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000337 return true;
338 default:
339 return false;
340 }
341}
342
Tim Northover77d82202014-07-10 11:21:06 +0000343bool MachOLinkingContext::pathExists(StringRef path) const {
Nick Kledzik94174f72014-08-15 19:53:41 +0000344 if (!_testingFileUsage)
Tim Northover77d82202014-07-10 11:21:06 +0000345 return llvm::sys::fs::exists(path.str());
346
347 // Otherwise, we're in test mode: only files explicitly provided on the
348 // command-line exist.
Rui Ueyama57a29532014-08-06 19:37:35 +0000349 std::string key = path.str();
350 std::replace(key.begin(), key.end(), '\\', '/');
351 return _existingPaths.find(key) != _existingPaths.end();
Tim Northover77d82202014-07-10 11:21:06 +0000352}
353
Nick Kledzik2d835da2014-08-14 22:20:41 +0000354void MachOLinkingContext::setSysLibRoots(const StringRefVector &paths) {
355 _syslibRoots = paths;
356}
357
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000358void MachOLinkingContext::addModifiedSearchDir(StringRef libPath,
359 bool isSystemPath) {
Tim Northover77d82202014-07-10 11:21:06 +0000360 bool addedModifiedPath = false;
361
Nick Kledzik2d835da2014-08-14 22:20:41 +0000362 // -syslibroot only applies to absolute paths.
363 if (libPath.startswith("/")) {
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000364 for (auto syslibRoot : _syslibRoots) {
Tim Northover77d82202014-07-10 11:21:06 +0000365 SmallString<256> path(syslibRoot);
366 llvm::sys::path::append(path, libPath);
367 if (pathExists(path)) {
368 _searchDirs.push_back(path.str().copy(_allocator));
369 addedModifiedPath = true;
370 }
371 }
372 }
373
374 if (addedModifiedPath)
375 return;
376
377 // Finally, if only one -syslibroot is given, system paths which aren't in it
378 // get suppressed.
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000379 if (_syslibRoots.size() != 1 || !isSystemPath) {
Tim Northover77d82202014-07-10 11:21:06 +0000380 if (pathExists(libPath)) {
381 _searchDirs.push_back(libPath);
382 }
383 }
384}
385
Nick Kledzik2d835da2014-08-14 22:20:41 +0000386void MachOLinkingContext::addFrameworkSearchDir(StringRef fwPath,
387 bool isSystemPath) {
388 bool pathAdded = false;
389
390 // -syslibroot only used with to absolute framework search paths.
391 if (fwPath.startswith("/")) {
392 for (auto syslibRoot : _syslibRoots) {
393 SmallString<256> path(syslibRoot);
394 llvm::sys::path::append(path, fwPath);
395 if (pathExists(path)) {
396 _frameworkDirs.push_back(path.str().copy(_allocator));
397 pathAdded = true;
398 }
399 }
400 }
401 // If fwPath found in any -syslibroot, then done.
402 if (pathAdded)
403 return;
404
405 // If only one -syslibroot, system paths not in that SDK are suppressed.
406 if (isSystemPath && (_syslibRoots.size() == 1))
407 return;
408
409 // Only use raw fwPath if that directory exists.
410 if (pathExists(fwPath))
411 _frameworkDirs.push_back(fwPath);
412}
413
414
Tim Northover77d82202014-07-10 11:21:06 +0000415ErrorOr<StringRef>
416MachOLinkingContext::searchDirForLibrary(StringRef path,
417 StringRef libName) const {
418 SmallString<256> fullPath;
419 if (libName.endswith(".o")) {
420 // A request ending in .o is special: just search for the file directly.
421 fullPath.assign(path);
422 llvm::sys::path::append(fullPath, libName);
423 if (pathExists(fullPath))
424 return fullPath.str().copy(_allocator);
425 return make_error_code(llvm::errc::no_such_file_or_directory);
426 }
427
428 // Search for dynamic library
429 fullPath.assign(path);
430 llvm::sys::path::append(fullPath, Twine("lib") + libName + ".dylib");
431 if (pathExists(fullPath))
432 return fullPath.str().copy(_allocator);
433
434 // If not, try for a static library
435 fullPath.assign(path);
436 llvm::sys::path::append(fullPath, Twine("lib") + libName + ".a");
437 if (pathExists(fullPath))
438 return fullPath.str().copy(_allocator);
439
440 return make_error_code(llvm::errc::no_such_file_or_directory);
441}
442
443
444
445ErrorOr<StringRef> MachOLinkingContext::searchLibrary(StringRef libName) const {
446 SmallString<256> path;
447 for (StringRef dir : searchDirs()) {
448 ErrorOr<StringRef> ec = searchDirForLibrary(dir, libName);
449 if (ec)
450 return ec;
451 }
452
453 return make_error_code(llvm::errc::no_such_file_or_directory);
454}
455
Nick Kledzik2d835da2014-08-14 22:20:41 +0000456
457ErrorOr<StringRef> MachOLinkingContext::findPathForFramework(StringRef fwName) const{
458 SmallString<256> fullPath;
459 for (StringRef dir : frameworkDirs()) {
460 fullPath.assign(dir);
461 llvm::sys::path::append(fullPath, Twine(fwName) + ".framework", fwName);
462 if (pathExists(fullPath))
463 return fullPath.str().copy(_allocator);
464 }
465
466 return make_error_code(llvm::errc::no_such_file_or_directory);
467}
468
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000469bool MachOLinkingContext::validateImpl(raw_ostream &diagnostics) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000470 // TODO: if -arch not specified, look at arch of first .o file.
471
Tim Northoverd30a1f22014-06-20 15:59:00 +0000472 if (_currentVersion && _outputMachOType != MH_DYLIB) {
Nick Kledzike773e322013-09-10 23:55:14 +0000473 diagnostics << "error: -current_version can only be used with dylibs\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000474 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000475 }
476
Tim Northoverd30a1f22014-06-20 15:59:00 +0000477 if (_compatibilityVersion && _outputMachOType != MH_DYLIB) {
Nick Kledzike773e322013-09-10 23:55:14 +0000478 diagnostics
479 << "error: -compatibility_version can only be used with dylibs\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000480 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000481 }
482
Tim Northoverd30a1f22014-06-20 15:59:00 +0000483 if (_deadStrippableDylib && _outputMachOType != MH_DYLIB) {
Nick Kledzike773e322013-09-10 23:55:14 +0000484 diagnostics
485 << "error: -mark_dead_strippable_dylib can only be used with dylibs.\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000486 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000487 }
488
Tim Northoverd30a1f22014-06-20 15:59:00 +0000489 if (!_bundleLoader.empty() && outputMachOType() != MH_BUNDLE) {
Nick Kledzike773e322013-09-10 23:55:14 +0000490 diagnostics
491 << "error: -bundle_loader can only be used with Mach-O bundles\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000492 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000493 }
494
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000495 // If -exported_symbols_list used, all exported symbols must be defined.
496 if (_exportMode == ExportMode::whiteList) {
497 for (const auto &symbol : _exportedSymbols)
498 addInitialUndefinedSymbol(symbol.getKey());
499 }
500
Nick Kledzik77afc712014-08-21 20:25:50 +0000501 // If -dead_strip, set up initial live symbols.
502 if (deadStrip()) {
503 // Entry point is live.
504 if (outputTypeHasEntry())
505 addDeadStripRoot(entrySymbolName());
506 // Lazy binding helper is live.
507 if (needsStubsPass())
508 addDeadStripRoot(binderSymbolName());
509 // If using -exported_symbols_list, make all exported symbols live.
510 if (_exportMode == ExportMode::whiteList) {
511 _globalsAreDeadStripRoots = false;
512 for (const auto &symbol : _exportedSymbols)
513 addDeadStripRoot(symbol.getKey());
514 }
515 }
516
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000517 return true;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000518}
519
Shankar Easwaran2bc24922013-10-29 05:12:14 +0000520void MachOLinkingContext::addPasses(PassManager &pm) {
Nico Rieckb9d84f42014-02-24 21:14:37 +0000521 pm.add(std::unique_ptr<Pass>(new LayoutPass(registry())));
Nick Kledzik2458bec2014-07-16 19:49:02 +0000522 if (needsStubsPass())
523 mach_o::addStubsPass(pm, *this);
Tim Northovercf78d372014-09-30 21:29:54 +0000524 if (needsCompactUnwindPass())
525 mach_o::addCompactUnwindPass(pm, *this);
Nick Kledzik2458bec2014-07-16 19:49:02 +0000526 if (needsGOTPass())
527 mach_o::addGOTPass(pm, *this);
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000528}
529
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000530Writer &MachOLinkingContext::writer() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000531 if (!_writer)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000532 _writer = createWriterMachO(*this);
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000533 return *_writer;
534}
535
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000536MachODylibFile* MachOLinkingContext::loadIndirectDylib(StringRef path) const {
537 std::unique_ptr<MachOFileNode> node(new MachOFileNode(path, false));
538 std::error_code ec = node->parse(*this, llvm::errs());
539 if (ec)
540 return nullptr;
541
542 assert(node->files().size() == 1 && "expected one file in dylib");
543 // lld::File object is owned by MachOFileNode object. This method returns
544 // an unowned pointer to the lld::File object.
545 MachODylibFile* result = reinterpret_cast<MachODylibFile*>(
546 node->files().front().get());
547
548 // Node object now owned by _indirectDylibs vector.
549 _indirectDylibs.push_back(std::move(node));
550
551 return result;
552}
553
554
555MachODylibFile* MachOLinkingContext::findIndirectDylib(StringRef path) const {
556 // See if already loaded.
557 auto pos = _pathToDylibMap.find(path);
558 if (pos != _pathToDylibMap.end())
559 return pos->second;
560
561 // Search -L paths if of the form "libXXX.dylib"
562 std::pair<StringRef, StringRef> split = path.rsplit('/');
563 StringRef leafName = split.second;
564 if (leafName.startswith("lib") && leafName.endswith(".dylib")) {
565 // FIXME: Need to enhance searchLibrary() to only look for .dylib
566 auto libPath = searchLibrary(leafName);
567 if (!libPath.getError()) {
568 return loadIndirectDylib(libPath.get());
569 }
570 }
571
572 // Try full path with sysroot.
573 for (StringRef sysPath : _syslibRoots) {
574 SmallString<256> fullPath;
575 fullPath.assign(sysPath);
576 llvm::sys::path::append(fullPath, path);
577 if (pathExists(fullPath))
578 return loadIndirectDylib(fullPath);
579 }
580
581 // Try full path.
582 if (pathExists(path)) {
583 return loadIndirectDylib(path);
584 }
585
586 return nullptr;
587}
588
589bool MachOLinkingContext::createImplicitFiles(
590 std::vector<std::unique_ptr<File> > &result) const {
591 // Add indirect dylibs by asking each linked dylib to add its indirects.
592 // Iterate until no more dylibs get loaded.
593 size_t dylibCount = 0;
594 while (dylibCount != _allDylibs.size()) {
595 dylibCount = _allDylibs.size();
596 for (MachODylibFile *dylib : _allDylibs) {
597 dylib->loadReExportedDylibs([this] (StringRef path) -> MachODylibFile* {
598 return findIndirectDylib(path); });
599 }
600 }
601
602 // Let writer add output type specific extras.
603 return writer().createImplicitFiles(result);
604}
605
606
607void MachOLinkingContext::registerDylib(MachODylibFile *dylib) {
608 _allDylibs.insert(dylib);
609 _pathToDylibMap[dylib->installName()] = dylib;
610 // If path is different than install name, register path too.
611 if (!dylib->path().equals(dylib->installName()))
612 _pathToDylibMap[dylib->path()] = dylib;
613}
614
615
Nick Kledzik2458bec2014-07-16 19:49:02 +0000616ArchHandler &MachOLinkingContext::archHandler() const {
617 if (!_archHandler)
618 _archHandler = ArchHandler::create(_arch);
619 return *_archHandler;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000620}
621
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000622
Nick Kledzik2fcbe822014-07-30 00:58:06 +0000623void MachOLinkingContext::addSectionAlignment(StringRef seg, StringRef sect,
624 uint8_t align2) {
625 SectionAlign entry;
626 entry.segmentName = seg;
627 entry.sectionName = sect;
628 entry.align2 = align2;
629 _sectAligns.push_back(entry);
630}
631
632bool MachOLinkingContext::sectionAligned(StringRef seg, StringRef sect,
633 uint8_t &align2) const {
634 for (const SectionAlign &entry : _sectAligns) {
635 if (seg.equals(entry.segmentName) && sect.equals(entry.sectionName)) {
636 align2 = entry.align2;
637 return true;
638 }
639 }
640 return false;
641}
642
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000643
644void MachOLinkingContext::addExportSymbol(StringRef sym) {
645 // FIXME: Support wildcards.
646 _exportedSymbols.insert(sym);
647}
648
649bool MachOLinkingContext::exportSymbolNamed(StringRef sym) const {
650 switch (_exportMode) {
651 case ExportMode::globals:
652 llvm_unreachable("exportSymbolNamed() should not be called in this mode");
653 break;
654 case ExportMode::whiteList:
655 return _exportedSymbols.count(sym);
656 case ExportMode::blackList:
657 return !_exportedSymbols.count(sym);
658 }
Yaron Keren9682c852014-09-21 05:07:44 +0000659 llvm_unreachable("_exportMode unknown enum value");
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000660}
661
662
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000663} // end namespace lld