blob: 601a86c8b1d557247a08c1a911babcb1a5e71d43 [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),
Nick Kledzikb7035ae2014-09-09 00:17:52 +0000136 _doNothing(false), _pie(false),
137 _arch(arch_unknown), _os(OS::macOSX), _osMinVersion(0),
Nick Kledzik6960b072013-12-21 01:47:17 +0000138 _pageZeroSize(0), _pageSize(4096), _compatibilityVersion(0),
Nick Kledzik0224e342014-05-14 21:32:21 +0000139 _currentVersion(0), _deadStrippableDylib(false), _printAtoms(false),
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000140 _testingFileUsage(false), _keepPrivateExterns(false),
141 _archHandler(nullptr), _exportMode(ExportMode::globals) {}
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000142
143MachOLinkingContext::~MachOLinkingContext() {}
144
Nick Kledzik6960b072013-12-21 01:47:17 +0000145void MachOLinkingContext::configure(HeaderFileType type, Arch arch, OS os,
146 uint32_t minOSVersion) {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000147 _outputMachOType = type;
Nick Kledzik6960b072013-12-21 01:47:17 +0000148 _arch = arch;
149 _os = os;
150 _osMinVersion = minOSVersion;
151
Tim Northoverd30a1f22014-06-20 15:59:00 +0000152 switch (_outputMachOType) {
Nick Kledzik6960b072013-12-21 01:47:17 +0000153 case llvm::MachO::MH_EXECUTE:
154 // If targeting newer OS, use _main
155 if (minOS("10.8", "6.0")) {
156 _entrySymbolName = "_main";
157 } else {
158 // If targeting older OS, use start (in crt1.o)
159 _entrySymbolName = "start";
160 }
161
162 // __PAGEZERO defaults to 4GB on 64-bit (except for PP64 which lld does not
163 // support) and 4KB on 32-bit.
164 if (is64Bit(_arch)) {
165 _pageZeroSize = 0x100000000;
166 } else {
167 _pageZeroSize = 0x1000;
168 }
169
Nick Kledzikb7035ae2014-09-09 00:17:52 +0000170 // Make PIE by default when targetting newer OSs.
171 switch (os) {
172 case OS::macOSX:
173 if (minOSVersion >= 0x000A0700) // MacOSX 10.7
174 _pie = true;
175 break;
176 case OS::iOS:
177 if (minOSVersion >= 0x00040300) // iOS 4.3
178 _pie = true;
179 break;
180 case OS::iOS_simulator:
181 _pie = true;
182 break;
183 case OS::unknown:
184 break;
185 }
Nick Kledzik6960b072013-12-21 01:47:17 +0000186 break;
187 case llvm::MachO::MH_DYLIB:
188 _globalsAreDeadStripRoots = true;
189 break;
190 case llvm::MachO::MH_BUNDLE:
191 break;
192 case llvm::MachO::MH_OBJECT:
193 _printRemainingUndefines = false;
194 _allowRemainingUndefines = true;
195 default:
196 break;
197 }
Nick Kledzik1bebb282014-09-09 23:52:59 +0000198
199 // Set default segment page sizes based on arch.
200 if (arch == arch_arm64)
201 _pageSize = 4*4096;
Nick Kledzik6960b072013-12-21 01:47:17 +0000202}
203
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000204uint32_t MachOLinkingContext::getCPUType() const {
205 return cpuTypeFromArch(_arch);
206}
207
208uint32_t MachOLinkingContext::getCPUSubType() const {
209 return cpuSubtypeFromArch(_arch);
210}
211
Nick Kledzike34182f2013-11-06 21:36:55 +0000212bool MachOLinkingContext::is64Bit(Arch arch) {
213 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
214 if (info->arch == arch) {
215 return (info->cputype & CPU_ARCH_ABI64);
216 }
217 }
218 // unknown archs are not 64-bit.
219 return false;
220}
221
222bool MachOLinkingContext::isHostEndian(Arch arch) {
223 assert(arch != arch_unknown);
224 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
225 if (info->arch == arch) {
226 return (info->littleEndian == llvm::sys::IsLittleEndianHost);
227 }
228 }
229 llvm_unreachable("Unknown arch type");
230}
231
232bool MachOLinkingContext::isBigEndian(Arch arch) {
233 assert(arch != arch_unknown);
234 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
235 if (info->arch == arch) {
236 return ! info->littleEndian;
237 }
238 }
239 llvm_unreachable("Unknown arch type");
240}
241
242
243
244bool MachOLinkingContext::is64Bit() const {
245 return is64Bit(_arch);
246}
247
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000248bool MachOLinkingContext::outputTypeHasEntry() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000249 switch (_outputMachOType) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000250 case MH_EXECUTE:
251 case MH_DYLINKER:
252 case MH_PRELOAD:
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000253 return true;
254 default:
255 return false;
256 }
257}
258
Nick Kledzik2458bec2014-07-16 19:49:02 +0000259bool MachOLinkingContext::needsStubsPass() const {
260 switch (_outputMachOType) {
261 case MH_EXECUTE:
262 return !_outputMachOTypeStatic;
263 case MH_DYLIB:
264 case MH_BUNDLE:
265 return true;
266 default:
267 return false;
268 }
269}
270
271bool MachOLinkingContext::needsGOTPass() const {
Nick Kledzik1bebb282014-09-09 23:52:59 +0000272 // GOT pass not used in -r mode.
273 if (_outputMachOType == MH_OBJECT)
Nick Kledzik2458bec2014-07-16 19:49:02 +0000274 return false;
Nick Kledzik1bebb282014-09-09 23:52:59 +0000275 // Only some arches use GOT pass.
276 switch (_arch) {
277 case arch_x86_64:
278 case arch_arm64:
279 return true;
280 default:
281 return false;
282 }
Nick Kledzik2458bec2014-07-16 19:49:02 +0000283}
284
285
286StringRef MachOLinkingContext::binderSymbolName() const {
287 return archHandler().stubInfo().binderSymbolName;
288}
289
290
291
292
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000293bool MachOLinkingContext::minOS(StringRef mac, StringRef iOS) const {
Nick Kledzik30332b12013-10-08 00:43:34 +0000294 uint32_t parsedVersion;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000295 switch (_os) {
Nick Kledzik30332b12013-10-08 00:43:34 +0000296 case OS::macOSX:
Nick Kledzike850d9d2013-09-10 23:46:57 +0000297 if (parsePackedVersion(mac, parsedVersion))
298 return false;
299 return _osMinVersion >= parsedVersion;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000300 case OS::iOS:
Nick Kledzik30332b12013-10-08 00:43:34 +0000301 case OS::iOS_simulator:
Nick Kledzike850d9d2013-09-10 23:46:57 +0000302 if (parsePackedVersion(iOS, parsedVersion))
303 return false;
304 return _osMinVersion >= parsedVersion;
Nick Kledzik30332b12013-10-08 00:43:34 +0000305 case OS::unknown:
306 break;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000307 }
308 llvm_unreachable("target not configured for iOS or MacOSX");
309}
310
311bool MachOLinkingContext::addEntryPointLoadCommand() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000312 if ((_outputMachOType == MH_EXECUTE) && !_outputMachOTypeStatic) {
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000313 return minOS("10.8", "6.0");
314 }
315 return false;
316}
317
318bool MachOLinkingContext::addUnixThreadLoadCommand() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000319 switch (_outputMachOType) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000320 case MH_EXECUTE:
Tim Northoverd30a1f22014-06-20 15:59:00 +0000321 if (_outputMachOTypeStatic)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000322 return true;
323 else
324 return !minOS("10.8", "6.0");
325 break;
Nick Kledzike34182f2013-11-06 21:36:55 +0000326 case MH_DYLINKER:
327 case MH_PRELOAD:
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000328 return true;
329 default:
330 return false;
331 }
332}
333
Tim Northover77d82202014-07-10 11:21:06 +0000334bool MachOLinkingContext::pathExists(StringRef path) const {
Nick Kledzik94174f72014-08-15 19:53:41 +0000335 if (!_testingFileUsage)
Tim Northover77d82202014-07-10 11:21:06 +0000336 return llvm::sys::fs::exists(path.str());
337
338 // Otherwise, we're in test mode: only files explicitly provided on the
339 // command-line exist.
Rui Ueyama57a29532014-08-06 19:37:35 +0000340 std::string key = path.str();
341 std::replace(key.begin(), key.end(), '\\', '/');
342 return _existingPaths.find(key) != _existingPaths.end();
Tim Northover77d82202014-07-10 11:21:06 +0000343}
344
Nick Kledzik2d835da2014-08-14 22:20:41 +0000345void MachOLinkingContext::setSysLibRoots(const StringRefVector &paths) {
346 _syslibRoots = paths;
347}
348
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000349void MachOLinkingContext::addModifiedSearchDir(StringRef libPath,
350 bool isSystemPath) {
Tim Northover77d82202014-07-10 11:21:06 +0000351 bool addedModifiedPath = false;
352
Nick Kledzik2d835da2014-08-14 22:20:41 +0000353 // -syslibroot only applies to absolute paths.
354 if (libPath.startswith("/")) {
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000355 for (auto syslibRoot : _syslibRoots) {
Tim Northover77d82202014-07-10 11:21:06 +0000356 SmallString<256> path(syslibRoot);
357 llvm::sys::path::append(path, libPath);
358 if (pathExists(path)) {
359 _searchDirs.push_back(path.str().copy(_allocator));
360 addedModifiedPath = true;
361 }
362 }
363 }
364
365 if (addedModifiedPath)
366 return;
367
368 // Finally, if only one -syslibroot is given, system paths which aren't in it
369 // get suppressed.
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000370 if (_syslibRoots.size() != 1 || !isSystemPath) {
Tim Northover77d82202014-07-10 11:21:06 +0000371 if (pathExists(libPath)) {
372 _searchDirs.push_back(libPath);
373 }
374 }
375}
376
Nick Kledzik2d835da2014-08-14 22:20:41 +0000377void MachOLinkingContext::addFrameworkSearchDir(StringRef fwPath,
378 bool isSystemPath) {
379 bool pathAdded = false;
380
381 // -syslibroot only used with to absolute framework search paths.
382 if (fwPath.startswith("/")) {
383 for (auto syslibRoot : _syslibRoots) {
384 SmallString<256> path(syslibRoot);
385 llvm::sys::path::append(path, fwPath);
386 if (pathExists(path)) {
387 _frameworkDirs.push_back(path.str().copy(_allocator));
388 pathAdded = true;
389 }
390 }
391 }
392 // If fwPath found in any -syslibroot, then done.
393 if (pathAdded)
394 return;
395
396 // If only one -syslibroot, system paths not in that SDK are suppressed.
397 if (isSystemPath && (_syslibRoots.size() == 1))
398 return;
399
400 // Only use raw fwPath if that directory exists.
401 if (pathExists(fwPath))
402 _frameworkDirs.push_back(fwPath);
403}
404
405
Tim Northover77d82202014-07-10 11:21:06 +0000406ErrorOr<StringRef>
407MachOLinkingContext::searchDirForLibrary(StringRef path,
408 StringRef libName) const {
409 SmallString<256> fullPath;
410 if (libName.endswith(".o")) {
411 // A request ending in .o is special: just search for the file directly.
412 fullPath.assign(path);
413 llvm::sys::path::append(fullPath, libName);
414 if (pathExists(fullPath))
415 return fullPath.str().copy(_allocator);
416 return make_error_code(llvm::errc::no_such_file_or_directory);
417 }
418
419 // Search for dynamic library
420 fullPath.assign(path);
421 llvm::sys::path::append(fullPath, Twine("lib") + libName + ".dylib");
422 if (pathExists(fullPath))
423 return fullPath.str().copy(_allocator);
424
425 // If not, try for a static library
426 fullPath.assign(path);
427 llvm::sys::path::append(fullPath, Twine("lib") + libName + ".a");
428 if (pathExists(fullPath))
429 return fullPath.str().copy(_allocator);
430
431 return make_error_code(llvm::errc::no_such_file_or_directory);
432}
433
434
435
436ErrorOr<StringRef> MachOLinkingContext::searchLibrary(StringRef libName) const {
437 SmallString<256> path;
438 for (StringRef dir : searchDirs()) {
439 ErrorOr<StringRef> ec = searchDirForLibrary(dir, libName);
440 if (ec)
441 return ec;
442 }
443
444 return make_error_code(llvm::errc::no_such_file_or_directory);
445}
446
Nick Kledzik2d835da2014-08-14 22:20:41 +0000447
448ErrorOr<StringRef> MachOLinkingContext::findPathForFramework(StringRef fwName) const{
449 SmallString<256> fullPath;
450 for (StringRef dir : frameworkDirs()) {
451 fullPath.assign(dir);
452 llvm::sys::path::append(fullPath, Twine(fwName) + ".framework", fwName);
453 if (pathExists(fullPath))
454 return fullPath.str().copy(_allocator);
455 }
456
457 return make_error_code(llvm::errc::no_such_file_or_directory);
458}
459
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000460bool MachOLinkingContext::validateImpl(raw_ostream &diagnostics) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000461 // TODO: if -arch not specified, look at arch of first .o file.
462
Tim Northoverd30a1f22014-06-20 15:59:00 +0000463 if (_currentVersion && _outputMachOType != MH_DYLIB) {
Nick Kledzike773e322013-09-10 23:55:14 +0000464 diagnostics << "error: -current_version can only be used with dylibs\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000465 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000466 }
467
Tim Northoverd30a1f22014-06-20 15:59:00 +0000468 if (_compatibilityVersion && _outputMachOType != MH_DYLIB) {
Nick Kledzike773e322013-09-10 23:55:14 +0000469 diagnostics
470 << "error: -compatibility_version can only be used with dylibs\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000471 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000472 }
473
Tim Northoverd30a1f22014-06-20 15:59:00 +0000474 if (_deadStrippableDylib && _outputMachOType != MH_DYLIB) {
Nick Kledzike773e322013-09-10 23:55:14 +0000475 diagnostics
476 << "error: -mark_dead_strippable_dylib can only be used with dylibs.\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000477 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000478 }
479
Tim Northoverd30a1f22014-06-20 15:59:00 +0000480 if (!_bundleLoader.empty() && outputMachOType() != MH_BUNDLE) {
Nick Kledzike773e322013-09-10 23:55:14 +0000481 diagnostics
482 << "error: -bundle_loader can only be used with Mach-O bundles\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000483 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000484 }
485
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000486 // If -exported_symbols_list used, all exported symbols must be defined.
487 if (_exportMode == ExportMode::whiteList) {
488 for (const auto &symbol : _exportedSymbols)
489 addInitialUndefinedSymbol(symbol.getKey());
490 }
491
Nick Kledzik77afc712014-08-21 20:25:50 +0000492 // If -dead_strip, set up initial live symbols.
493 if (deadStrip()) {
494 // Entry point is live.
495 if (outputTypeHasEntry())
496 addDeadStripRoot(entrySymbolName());
497 // Lazy binding helper is live.
498 if (needsStubsPass())
499 addDeadStripRoot(binderSymbolName());
500 // If using -exported_symbols_list, make all exported symbols live.
501 if (_exportMode == ExportMode::whiteList) {
502 _globalsAreDeadStripRoots = false;
503 for (const auto &symbol : _exportedSymbols)
504 addDeadStripRoot(symbol.getKey());
505 }
506 }
507
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000508 return true;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000509}
510
Shankar Easwaran2bc24922013-10-29 05:12:14 +0000511void MachOLinkingContext::addPasses(PassManager &pm) {
Nico Rieckb9d84f42014-02-24 21:14:37 +0000512 pm.add(std::unique_ptr<Pass>(new LayoutPass(registry())));
Nick Kledzik2458bec2014-07-16 19:49:02 +0000513 if (needsStubsPass())
514 mach_o::addStubsPass(pm, *this);
515 if (needsGOTPass())
516 mach_o::addGOTPass(pm, *this);
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000517}
518
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000519Writer &MachOLinkingContext::writer() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000520 if (!_writer)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000521 _writer = createWriterMachO(*this);
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000522 return *_writer;
523}
524
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000525MachODylibFile* MachOLinkingContext::loadIndirectDylib(StringRef path) const {
526 std::unique_ptr<MachOFileNode> node(new MachOFileNode(path, false));
527 std::error_code ec = node->parse(*this, llvm::errs());
528 if (ec)
529 return nullptr;
530
531 assert(node->files().size() == 1 && "expected one file in dylib");
532 // lld::File object is owned by MachOFileNode object. This method returns
533 // an unowned pointer to the lld::File object.
534 MachODylibFile* result = reinterpret_cast<MachODylibFile*>(
535 node->files().front().get());
536
537 // Node object now owned by _indirectDylibs vector.
538 _indirectDylibs.push_back(std::move(node));
539
540 return result;
541}
542
543
544MachODylibFile* MachOLinkingContext::findIndirectDylib(StringRef path) const {
545 // See if already loaded.
546 auto pos = _pathToDylibMap.find(path);
547 if (pos != _pathToDylibMap.end())
548 return pos->second;
549
550 // Search -L paths if of the form "libXXX.dylib"
551 std::pair<StringRef, StringRef> split = path.rsplit('/');
552 StringRef leafName = split.second;
553 if (leafName.startswith("lib") && leafName.endswith(".dylib")) {
554 // FIXME: Need to enhance searchLibrary() to only look for .dylib
555 auto libPath = searchLibrary(leafName);
556 if (!libPath.getError()) {
557 return loadIndirectDylib(libPath.get());
558 }
559 }
560
561 // Try full path with sysroot.
562 for (StringRef sysPath : _syslibRoots) {
563 SmallString<256> fullPath;
564 fullPath.assign(sysPath);
565 llvm::sys::path::append(fullPath, path);
566 if (pathExists(fullPath))
567 return loadIndirectDylib(fullPath);
568 }
569
570 // Try full path.
571 if (pathExists(path)) {
572 return loadIndirectDylib(path);
573 }
574
575 return nullptr;
576}
577
578bool MachOLinkingContext::createImplicitFiles(
579 std::vector<std::unique_ptr<File> > &result) const {
580 // Add indirect dylibs by asking each linked dylib to add its indirects.
581 // Iterate until no more dylibs get loaded.
582 size_t dylibCount = 0;
583 while (dylibCount != _allDylibs.size()) {
584 dylibCount = _allDylibs.size();
585 for (MachODylibFile *dylib : _allDylibs) {
586 dylib->loadReExportedDylibs([this] (StringRef path) -> MachODylibFile* {
587 return findIndirectDylib(path); });
588 }
589 }
590
591 // Let writer add output type specific extras.
592 return writer().createImplicitFiles(result);
593}
594
595
596void MachOLinkingContext::registerDylib(MachODylibFile *dylib) {
597 _allDylibs.insert(dylib);
598 _pathToDylibMap[dylib->installName()] = dylib;
599 // If path is different than install name, register path too.
600 if (!dylib->path().equals(dylib->installName()))
601 _pathToDylibMap[dylib->path()] = dylib;
602}
603
604
Nick Kledzik2458bec2014-07-16 19:49:02 +0000605ArchHandler &MachOLinkingContext::archHandler() const {
606 if (!_archHandler)
607 _archHandler = ArchHandler::create(_arch);
608 return *_archHandler;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000609}
610
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000611
Nick Kledzik2fcbe822014-07-30 00:58:06 +0000612void MachOLinkingContext::addSectionAlignment(StringRef seg, StringRef sect,
613 uint8_t align2) {
614 SectionAlign entry;
615 entry.segmentName = seg;
616 entry.sectionName = sect;
617 entry.align2 = align2;
618 _sectAligns.push_back(entry);
619}
620
621bool MachOLinkingContext::sectionAligned(StringRef seg, StringRef sect,
622 uint8_t &align2) const {
623 for (const SectionAlign &entry : _sectAligns) {
624 if (seg.equals(entry.segmentName) && sect.equals(entry.sectionName)) {
625 align2 = entry.align2;
626 return true;
627 }
628 }
629 return false;
630}
631
Nick Kledzik8c0bf752014-08-21 01:59:11 +0000632
633void MachOLinkingContext::addExportSymbol(StringRef sym) {
634 // FIXME: Support wildcards.
635 _exportedSymbols.insert(sym);
636}
637
638bool MachOLinkingContext::exportSymbolNamed(StringRef sym) const {
639 switch (_exportMode) {
640 case ExportMode::globals:
641 llvm_unreachable("exportSymbolNamed() should not be called in this mode");
642 break;
643 case ExportMode::whiteList:
644 return _exportedSymbols.count(sym);
645 case ExportMode::blackList:
646 return !_exportedSymbols.count(sym);
647 }
648}
649
650
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000651} // end namespace lld