blob: 66686fc87e8552c2c5007a4c22de0a0f201a274f [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 Kledzik2458bec2014-07-16 19:49:02 +000014#include "MachOPasses.h"
Rui Ueyama0ca149f2013-08-06 22:31:59 +000015
16#include "lld/Core/PassManager.h"
Nick Kledzik8fc67fb2014-08-13 23:55:41 +000017#include "lld/Driver/DarwinInputGraph.h"
Rui Ueyama0ca149f2013-08-06 22:31:59 +000018#include "lld/ReaderWriter/Reader.h"
19#include "lld/ReaderWriter/Writer.h"
20#include "lld/Passes/LayoutPass.h"
Shankar Easwaran2bc24922013-10-29 05:12:14 +000021#include "lld/Passes/RoundTripYAMLPass.h"
Rui Ueyama0ca149f2013-08-06 22:31:59 +000022
23#include "llvm/ADT/StringExtras.h"
24#include "llvm/ADT/Triple.h"
Tim Northover77d82202014-07-10 11:21:06 +000025#include "llvm/Support/Errc.h"
Nick Kledzike34182f2013-11-06 21:36:55 +000026#include "llvm/Support/Host.h"
Nick Kledzik473933b2013-09-27 22:50:00 +000027#include "llvm/Support/MachO.h"
Tim Northover77d82202014-07-10 11:21:06 +000028#include "llvm/Support/Path.h"
Rui Ueyama0ca149f2013-08-06 22:31:59 +000029
Rui Ueyama57a29532014-08-06 19:37:35 +000030#include <algorithm>
31
Nick Kledzik2458bec2014-07-16 19:49:02 +000032using lld::mach_o::ArchHandler;
Nick Kledzik8fc67fb2014-08-13 23:55:41 +000033using lld::mach_o::MachODylibFile;
Nick Kledzike34182f2013-11-06 21:36:55 +000034using namespace llvm::MachO;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000035
36namespace lld {
37
Nick Kledzike850d9d2013-09-10 23:46:57 +000038bool MachOLinkingContext::parsePackedVersion(StringRef str, uint32_t &result) {
39 result = 0;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000040
41 if (str.empty())
42 return false;
43
44 SmallVector<StringRef, 3> parts;
45 llvm::SplitString(str, parts, ".");
46
47 unsigned long long num;
48 if (llvm::getAsUnsignedInteger(parts[0], 10, num))
49 return true;
50 if (num > 65535)
51 return true;
Nick Kledzike850d9d2013-09-10 23:46:57 +000052 result = num << 16;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000053
54 if (parts.size() > 1) {
55 if (llvm::getAsUnsignedInteger(parts[1], 10, num))
56 return true;
57 if (num > 255)
58 return true;
Nick Kledzike850d9d2013-09-10 23:46:57 +000059 result |= (num << 8);
Rui Ueyama0ca149f2013-08-06 22:31:59 +000060 }
61
62 if (parts.size() > 2) {
63 if (llvm::getAsUnsignedInteger(parts[2], 10, num))
64 return true;
65 if (num > 255)
66 return true;
Nick Kledzike850d9d2013-09-10 23:46:57 +000067 result |= num;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000068 }
69
70 return false;
71}
72
Rui Ueyama0ca149f2013-08-06 22:31:59 +000073
Nick Kledzike34182f2013-11-06 21:36:55 +000074MachOLinkingContext::ArchInfo MachOLinkingContext::_s_archInfos[] = {
75 { "x86_64", arch_x86_64, true, CPU_TYPE_X86_64, CPU_SUBTYPE_X86_64_ALL },
76 { "i386", arch_x86, true, CPU_TYPE_I386, CPU_SUBTYPE_X86_ALL },
77 { "ppc", arch_ppc, false, CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_ALL },
78 { "armv6", arch_armv6, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V6 },
79 { "armv7", arch_armv7, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7 },
80 { "armv7s", arch_armv7s, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7S },
81 { "", arch_unknown,false, 0, 0 }
Rui Ueyama0ca149f2013-08-06 22:31:59 +000082};
83
84MachOLinkingContext::Arch
85MachOLinkingContext::archFromCpuType(uint32_t cputype, uint32_t cpusubtype) {
Nick Kledzike34182f2013-11-06 21:36:55 +000086 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
87 if ((info->cputype == cputype) && (info->cpusubtype == cpusubtype))
Rui Ueyama0ca149f2013-08-06 22:31:59 +000088 return info->arch;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000089 }
90 return arch_unknown;
91}
92
93MachOLinkingContext::Arch
94MachOLinkingContext::archFromName(StringRef archName) {
Nick Kledzike34182f2013-11-06 21:36:55 +000095 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
96 if (info->archName.equals(archName))
Rui Ueyama0ca149f2013-08-06 22:31:59 +000097 return info->arch;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000098 }
99 return arch_unknown;
100}
101
Nick Kledzike5552772013-12-19 21:58:00 +0000102StringRef MachOLinkingContext::nameFromArch(Arch arch) {
103 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
104 if (info->arch == arch)
105 return info->archName;
106 }
107 return "<unknown>";
108}
109
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000110uint32_t MachOLinkingContext::cpuTypeFromArch(Arch arch) {
111 assert(arch != arch_unknown);
Nick Kledzike34182f2013-11-06 21:36:55 +0000112 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
113 if (info->arch == arch)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000114 return info->cputype;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000115 }
116 llvm_unreachable("Unknown arch type");
117}
118
119uint32_t MachOLinkingContext::cpuSubtypeFromArch(Arch arch) {
120 assert(arch != arch_unknown);
Nick Kledzike34182f2013-11-06 21:36:55 +0000121 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
122 if (info->arch == arch)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000123 return info->cpusubtype;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000124 }
125 llvm_unreachable("Unknown arch type");
126}
127
128MachOLinkingContext::MachOLinkingContext()
Tim Northoverd30a1f22014-06-20 15:59:00 +0000129 : _outputMachOType(MH_EXECUTE), _outputMachOTypeStatic(false),
Nick Kledzike850d9d2013-09-10 23:46:57 +0000130 _doNothing(false), _arch(arch_unknown), _os(OS::macOSX), _osMinVersion(0),
Nick Kledzik6960b072013-12-21 01:47:17 +0000131 _pageZeroSize(0), _pageSize(4096), _compatibilityVersion(0),
Nick Kledzik0224e342014-05-14 21:32:21 +0000132 _currentVersion(0), _deadStrippableDylib(false), _printAtoms(false),
Nick Kledzik94174f72014-08-15 19:53:41 +0000133 _testingFileUsage(false), _archHandler(nullptr) {}
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000134
135MachOLinkingContext::~MachOLinkingContext() {}
136
Nick Kledzik6960b072013-12-21 01:47:17 +0000137void MachOLinkingContext::configure(HeaderFileType type, Arch arch, OS os,
138 uint32_t minOSVersion) {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000139 _outputMachOType = type;
Nick Kledzik6960b072013-12-21 01:47:17 +0000140 _arch = arch;
141 _os = os;
142 _osMinVersion = minOSVersion;
143
Tim Northoverd30a1f22014-06-20 15:59:00 +0000144 switch (_outputMachOType) {
Nick Kledzik6960b072013-12-21 01:47:17 +0000145 case llvm::MachO::MH_EXECUTE:
146 // If targeting newer OS, use _main
147 if (minOS("10.8", "6.0")) {
148 _entrySymbolName = "_main";
149 } else {
150 // If targeting older OS, use start (in crt1.o)
151 _entrySymbolName = "start";
152 }
153
154 // __PAGEZERO defaults to 4GB on 64-bit (except for PP64 which lld does not
155 // support) and 4KB on 32-bit.
156 if (is64Bit(_arch)) {
157 _pageZeroSize = 0x100000000;
158 } else {
159 _pageZeroSize = 0x1000;
160 }
161
162 break;
163 case llvm::MachO::MH_DYLIB:
164 _globalsAreDeadStripRoots = true;
165 break;
166 case llvm::MachO::MH_BUNDLE:
167 break;
168 case llvm::MachO::MH_OBJECT:
169 _printRemainingUndefines = false;
170 _allowRemainingUndefines = true;
171 default:
172 break;
173 }
174}
175
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000176uint32_t MachOLinkingContext::getCPUType() const {
177 return cpuTypeFromArch(_arch);
178}
179
180uint32_t MachOLinkingContext::getCPUSubType() const {
181 return cpuSubtypeFromArch(_arch);
182}
183
Nick Kledzike34182f2013-11-06 21:36:55 +0000184bool MachOLinkingContext::is64Bit(Arch arch) {
185 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
186 if (info->arch == arch) {
187 return (info->cputype & CPU_ARCH_ABI64);
188 }
189 }
190 // unknown archs are not 64-bit.
191 return false;
192}
193
194bool MachOLinkingContext::isHostEndian(Arch arch) {
195 assert(arch != arch_unknown);
196 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
197 if (info->arch == arch) {
198 return (info->littleEndian == llvm::sys::IsLittleEndianHost);
199 }
200 }
201 llvm_unreachable("Unknown arch type");
202}
203
204bool MachOLinkingContext::isBigEndian(Arch arch) {
205 assert(arch != arch_unknown);
206 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
207 if (info->arch == arch) {
208 return ! info->littleEndian;
209 }
210 }
211 llvm_unreachable("Unknown arch type");
212}
213
214
215
216bool MachOLinkingContext::is64Bit() const {
217 return is64Bit(_arch);
218}
219
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000220bool MachOLinkingContext::outputTypeHasEntry() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000221 switch (_outputMachOType) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000222 case MH_EXECUTE:
223 case MH_DYLINKER:
224 case MH_PRELOAD:
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000225 return true;
226 default:
227 return false;
228 }
229}
230
Nick Kledzik2458bec2014-07-16 19:49:02 +0000231bool MachOLinkingContext::needsStubsPass() const {
232 switch (_outputMachOType) {
233 case MH_EXECUTE:
234 return !_outputMachOTypeStatic;
235 case MH_DYLIB:
236 case MH_BUNDLE:
237 return true;
238 default:
239 return false;
240 }
241}
242
243bool MachOLinkingContext::needsGOTPass() const {
244 // Only x86_64 uses GOT pass but not in -r mode.
245 if (_arch != arch_x86_64)
246 return false;
247 return (_outputMachOType != MH_OBJECT);
248}
249
250
251StringRef MachOLinkingContext::binderSymbolName() const {
252 return archHandler().stubInfo().binderSymbolName;
253}
254
255
256
257
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000258bool MachOLinkingContext::minOS(StringRef mac, StringRef iOS) const {
Nick Kledzik30332b12013-10-08 00:43:34 +0000259 uint32_t parsedVersion;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000260 switch (_os) {
Nick Kledzik30332b12013-10-08 00:43:34 +0000261 case OS::macOSX:
Nick Kledzike850d9d2013-09-10 23:46:57 +0000262 if (parsePackedVersion(mac, parsedVersion))
263 return false;
264 return _osMinVersion >= parsedVersion;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000265 case OS::iOS:
Nick Kledzik30332b12013-10-08 00:43:34 +0000266 case OS::iOS_simulator:
Nick Kledzike850d9d2013-09-10 23:46:57 +0000267 if (parsePackedVersion(iOS, parsedVersion))
268 return false;
269 return _osMinVersion >= parsedVersion;
Nick Kledzik30332b12013-10-08 00:43:34 +0000270 case OS::unknown:
271 break;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000272 }
273 llvm_unreachable("target not configured for iOS or MacOSX");
274}
275
276bool MachOLinkingContext::addEntryPointLoadCommand() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000277 if ((_outputMachOType == MH_EXECUTE) && !_outputMachOTypeStatic) {
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000278 return minOS("10.8", "6.0");
279 }
280 return false;
281}
282
283bool MachOLinkingContext::addUnixThreadLoadCommand() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000284 switch (_outputMachOType) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000285 case MH_EXECUTE:
Tim Northoverd30a1f22014-06-20 15:59:00 +0000286 if (_outputMachOTypeStatic)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000287 return true;
288 else
289 return !minOS("10.8", "6.0");
290 break;
Nick Kledzike34182f2013-11-06 21:36:55 +0000291 case MH_DYLINKER:
292 case MH_PRELOAD:
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000293 return true;
294 default:
295 return false;
296 }
297}
298
Tim Northover77d82202014-07-10 11:21:06 +0000299bool MachOLinkingContext::pathExists(StringRef path) const {
Nick Kledzik94174f72014-08-15 19:53:41 +0000300 if (!_testingFileUsage)
Tim Northover77d82202014-07-10 11:21:06 +0000301 return llvm::sys::fs::exists(path.str());
302
303 // Otherwise, we're in test mode: only files explicitly provided on the
304 // command-line exist.
Rui Ueyama57a29532014-08-06 19:37:35 +0000305 std::string key = path.str();
306 std::replace(key.begin(), key.end(), '\\', '/');
307 return _existingPaths.find(key) != _existingPaths.end();
Tim Northover77d82202014-07-10 11:21:06 +0000308}
309
Nick Kledzik2d835da2014-08-14 22:20:41 +0000310void MachOLinkingContext::setSysLibRoots(const StringRefVector &paths) {
311 _syslibRoots = paths;
312}
313
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000314void MachOLinkingContext::addModifiedSearchDir(StringRef libPath,
315 bool isSystemPath) {
Tim Northover77d82202014-07-10 11:21:06 +0000316 bool addedModifiedPath = false;
317
Nick Kledzik2d835da2014-08-14 22:20:41 +0000318 // -syslibroot only applies to absolute paths.
319 if (libPath.startswith("/")) {
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000320 for (auto syslibRoot : _syslibRoots) {
Tim Northover77d82202014-07-10 11:21:06 +0000321 SmallString<256> path(syslibRoot);
322 llvm::sys::path::append(path, libPath);
323 if (pathExists(path)) {
324 _searchDirs.push_back(path.str().copy(_allocator));
325 addedModifiedPath = true;
326 }
327 }
328 }
329
330 if (addedModifiedPath)
331 return;
332
333 // Finally, if only one -syslibroot is given, system paths which aren't in it
334 // get suppressed.
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000335 if (_syslibRoots.size() != 1 || !isSystemPath) {
Tim Northover77d82202014-07-10 11:21:06 +0000336 if (pathExists(libPath)) {
337 _searchDirs.push_back(libPath);
338 }
339 }
340}
341
Nick Kledzik2d835da2014-08-14 22:20:41 +0000342void MachOLinkingContext::addFrameworkSearchDir(StringRef fwPath,
343 bool isSystemPath) {
344 bool pathAdded = false;
345
346 // -syslibroot only used with to absolute framework search paths.
347 if (fwPath.startswith("/")) {
348 for (auto syslibRoot : _syslibRoots) {
349 SmallString<256> path(syslibRoot);
350 llvm::sys::path::append(path, fwPath);
351 if (pathExists(path)) {
352 _frameworkDirs.push_back(path.str().copy(_allocator));
353 pathAdded = true;
354 }
355 }
356 }
357 // If fwPath found in any -syslibroot, then done.
358 if (pathAdded)
359 return;
360
361 // If only one -syslibroot, system paths not in that SDK are suppressed.
362 if (isSystemPath && (_syslibRoots.size() == 1))
363 return;
364
365 // Only use raw fwPath if that directory exists.
366 if (pathExists(fwPath))
367 _frameworkDirs.push_back(fwPath);
368}
369
370
Tim Northover77d82202014-07-10 11:21:06 +0000371ErrorOr<StringRef>
372MachOLinkingContext::searchDirForLibrary(StringRef path,
373 StringRef libName) const {
374 SmallString<256> fullPath;
375 if (libName.endswith(".o")) {
376 // A request ending in .o is special: just search for the file directly.
377 fullPath.assign(path);
378 llvm::sys::path::append(fullPath, libName);
379 if (pathExists(fullPath))
380 return fullPath.str().copy(_allocator);
381 return make_error_code(llvm::errc::no_such_file_or_directory);
382 }
383
384 // Search for dynamic library
385 fullPath.assign(path);
386 llvm::sys::path::append(fullPath, Twine("lib") + libName + ".dylib");
387 if (pathExists(fullPath))
388 return fullPath.str().copy(_allocator);
389
390 // If not, try for a static library
391 fullPath.assign(path);
392 llvm::sys::path::append(fullPath, Twine("lib") + libName + ".a");
393 if (pathExists(fullPath))
394 return fullPath.str().copy(_allocator);
395
396 return make_error_code(llvm::errc::no_such_file_or_directory);
397}
398
399
400
401ErrorOr<StringRef> MachOLinkingContext::searchLibrary(StringRef libName) const {
402 SmallString<256> path;
403 for (StringRef dir : searchDirs()) {
404 ErrorOr<StringRef> ec = searchDirForLibrary(dir, libName);
405 if (ec)
406 return ec;
407 }
408
409 return make_error_code(llvm::errc::no_such_file_or_directory);
410}
411
Nick Kledzik2d835da2014-08-14 22:20:41 +0000412
413ErrorOr<StringRef> MachOLinkingContext::findPathForFramework(StringRef fwName) const{
414 SmallString<256> fullPath;
415 for (StringRef dir : frameworkDirs()) {
416 fullPath.assign(dir);
417 llvm::sys::path::append(fullPath, Twine(fwName) + ".framework", fwName);
418 if (pathExists(fullPath))
419 return fullPath.str().copy(_allocator);
420 }
421
422 return make_error_code(llvm::errc::no_such_file_or_directory);
423}
424
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000425bool MachOLinkingContext::validateImpl(raw_ostream &diagnostics) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000426 // TODO: if -arch not specified, look at arch of first .o file.
427
Tim Northoverd30a1f22014-06-20 15:59:00 +0000428 if (_currentVersion && _outputMachOType != MH_DYLIB) {
Nick Kledzike773e322013-09-10 23:55:14 +0000429 diagnostics << "error: -current_version can only be used with dylibs\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000430 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000431 }
432
Tim Northoverd30a1f22014-06-20 15:59:00 +0000433 if (_compatibilityVersion && _outputMachOType != MH_DYLIB) {
Nick Kledzike773e322013-09-10 23:55:14 +0000434 diagnostics
435 << "error: -compatibility_version can only be used with dylibs\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000436 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000437 }
438
Tim Northoverd30a1f22014-06-20 15:59:00 +0000439 if (_deadStrippableDylib && _outputMachOType != MH_DYLIB) {
Nick Kledzike773e322013-09-10 23:55:14 +0000440 diagnostics
441 << "error: -mark_dead_strippable_dylib can only be used with dylibs.\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000442 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000443 }
444
Tim Northoverd30a1f22014-06-20 15:59:00 +0000445 if (!_bundleLoader.empty() && outputMachOType() != MH_BUNDLE) {
Nick Kledzike773e322013-09-10 23:55:14 +0000446 diagnostics
447 << "error: -bundle_loader can only be used with Mach-O bundles\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000448 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000449 }
450
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000451 return true;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000452}
453
Shankar Easwaran2bc24922013-10-29 05:12:14 +0000454void MachOLinkingContext::addPasses(PassManager &pm) {
Nico Rieckb9d84f42014-02-24 21:14:37 +0000455 pm.add(std::unique_ptr<Pass>(new LayoutPass(registry())));
Nick Kledzik2458bec2014-07-16 19:49:02 +0000456 if (needsStubsPass())
457 mach_o::addStubsPass(pm, *this);
458 if (needsGOTPass())
459 mach_o::addGOTPass(pm, *this);
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000460}
461
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000462Writer &MachOLinkingContext::writer() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000463 if (!_writer)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000464 _writer = createWriterMachO(*this);
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000465 return *_writer;
466}
467
Nick Kledzik8fc67fb2014-08-13 23:55:41 +0000468MachODylibFile* MachOLinkingContext::loadIndirectDylib(StringRef path) const {
469 std::unique_ptr<MachOFileNode> node(new MachOFileNode(path, false));
470 std::error_code ec = node->parse(*this, llvm::errs());
471 if (ec)
472 return nullptr;
473
474 assert(node->files().size() == 1 && "expected one file in dylib");
475 // lld::File object is owned by MachOFileNode object. This method returns
476 // an unowned pointer to the lld::File object.
477 MachODylibFile* result = reinterpret_cast<MachODylibFile*>(
478 node->files().front().get());
479
480 // Node object now owned by _indirectDylibs vector.
481 _indirectDylibs.push_back(std::move(node));
482
483 return result;
484}
485
486
487MachODylibFile* MachOLinkingContext::findIndirectDylib(StringRef path) const {
488 // See if already loaded.
489 auto pos = _pathToDylibMap.find(path);
490 if (pos != _pathToDylibMap.end())
491 return pos->second;
492
493 // Search -L paths if of the form "libXXX.dylib"
494 std::pair<StringRef, StringRef> split = path.rsplit('/');
495 StringRef leafName = split.second;
496 if (leafName.startswith("lib") && leafName.endswith(".dylib")) {
497 // FIXME: Need to enhance searchLibrary() to only look for .dylib
498 auto libPath = searchLibrary(leafName);
499 if (!libPath.getError()) {
500 return loadIndirectDylib(libPath.get());
501 }
502 }
503
504 // Try full path with sysroot.
505 for (StringRef sysPath : _syslibRoots) {
506 SmallString<256> fullPath;
507 fullPath.assign(sysPath);
508 llvm::sys::path::append(fullPath, path);
509 if (pathExists(fullPath))
510 return loadIndirectDylib(fullPath);
511 }
512
513 // Try full path.
514 if (pathExists(path)) {
515 return loadIndirectDylib(path);
516 }
517
518 return nullptr;
519}
520
521bool MachOLinkingContext::createImplicitFiles(
522 std::vector<std::unique_ptr<File> > &result) const {
523 // Add indirect dylibs by asking each linked dylib to add its indirects.
524 // Iterate until no more dylibs get loaded.
525 size_t dylibCount = 0;
526 while (dylibCount != _allDylibs.size()) {
527 dylibCount = _allDylibs.size();
528 for (MachODylibFile *dylib : _allDylibs) {
529 dylib->loadReExportedDylibs([this] (StringRef path) -> MachODylibFile* {
530 return findIndirectDylib(path); });
531 }
532 }
533
534 // Let writer add output type specific extras.
535 return writer().createImplicitFiles(result);
536}
537
538
539void MachOLinkingContext::registerDylib(MachODylibFile *dylib) {
540 _allDylibs.insert(dylib);
541 _pathToDylibMap[dylib->installName()] = dylib;
542 // If path is different than install name, register path too.
543 if (!dylib->path().equals(dylib->installName()))
544 _pathToDylibMap[dylib->path()] = dylib;
545}
546
547
Nick Kledzik2458bec2014-07-16 19:49:02 +0000548ArchHandler &MachOLinkingContext::archHandler() const {
549 if (!_archHandler)
550 _archHandler = ArchHandler::create(_arch);
551 return *_archHandler;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000552}
553
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000554
Nick Kledzik2fcbe822014-07-30 00:58:06 +0000555void MachOLinkingContext::addSectionAlignment(StringRef seg, StringRef sect,
556 uint8_t align2) {
557 SectionAlign entry;
558 entry.segmentName = seg;
559 entry.sectionName = sect;
560 entry.align2 = align2;
561 _sectAligns.push_back(entry);
562}
563
564bool MachOLinkingContext::sectionAligned(StringRef seg, StringRef sect,
565 uint8_t &align2) const {
566 for (const SectionAlign &entry : _sectAligns) {
567 if (seg.equals(entry.segmentName) && sect.equals(entry.sectionName)) {
568 align2 = entry.align2;
569 return true;
570 }
571 }
572 return false;
573}
574
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000575} // end namespace lld