blob: 5fa74d145643d7b439a7be2c07600423c58677a4 [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"
13#include "MachOPasses.h"
Rui Ueyama0ca149f2013-08-06 22:31:59 +000014
15#include "lld/Core/PassManager.h"
16#include "lld/ReaderWriter/Reader.h"
17#include "lld/ReaderWriter/Writer.h"
18#include "lld/Passes/LayoutPass.h"
Shankar Easwaran2bc24922013-10-29 05:12:14 +000019#include "lld/Passes/RoundTripYAMLPass.h"
Rui Ueyama0ca149f2013-08-06 22:31:59 +000020
21#include "llvm/ADT/StringExtras.h"
22#include "llvm/ADT/Triple.h"
Tim Northover77d82202014-07-10 11:21:06 +000023#include "llvm/Support/Errc.h"
Nick Kledzike34182f2013-11-06 21:36:55 +000024#include "llvm/Support/Host.h"
Nick Kledzik473933b2013-09-27 22:50:00 +000025#include "llvm/Support/MachO.h"
Tim Northover77d82202014-07-10 11:21:06 +000026#include "llvm/Support/Path.h"
Rui Ueyama0ca149f2013-08-06 22:31:59 +000027
Nick Kledzik2458bec2014-07-16 19:49:02 +000028using lld::mach_o::ArchHandler;
Nick Kledzike34182f2013-11-06 21:36:55 +000029using namespace llvm::MachO;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000030
31namespace lld {
32
Nick Kledzike850d9d2013-09-10 23:46:57 +000033bool MachOLinkingContext::parsePackedVersion(StringRef str, uint32_t &result) {
34 result = 0;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000035
36 if (str.empty())
37 return false;
38
39 SmallVector<StringRef, 3> parts;
40 llvm::SplitString(str, parts, ".");
41
42 unsigned long long num;
43 if (llvm::getAsUnsignedInteger(parts[0], 10, num))
44 return true;
45 if (num > 65535)
46 return true;
Nick Kledzike850d9d2013-09-10 23:46:57 +000047 result = num << 16;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000048
49 if (parts.size() > 1) {
50 if (llvm::getAsUnsignedInteger(parts[1], 10, num))
51 return true;
52 if (num > 255)
53 return true;
Nick Kledzike850d9d2013-09-10 23:46:57 +000054 result |= (num << 8);
Rui Ueyama0ca149f2013-08-06 22:31:59 +000055 }
56
57 if (parts.size() > 2) {
58 if (llvm::getAsUnsignedInteger(parts[2], 10, num))
59 return true;
60 if (num > 255)
61 return true;
Nick Kledzike850d9d2013-09-10 23:46:57 +000062 result |= num;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000063 }
64
65 return false;
66}
67
Rui Ueyama0ca149f2013-08-06 22:31:59 +000068
Nick Kledzike34182f2013-11-06 21:36:55 +000069MachOLinkingContext::ArchInfo MachOLinkingContext::_s_archInfos[] = {
70 { "x86_64", arch_x86_64, true, CPU_TYPE_X86_64, CPU_SUBTYPE_X86_64_ALL },
71 { "i386", arch_x86, true, CPU_TYPE_I386, CPU_SUBTYPE_X86_ALL },
72 { "ppc", arch_ppc, false, CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_ALL },
73 { "armv6", arch_armv6, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V6 },
74 { "armv7", arch_armv7, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7 },
75 { "armv7s", arch_armv7s, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7S },
76 { "", arch_unknown,false, 0, 0 }
Rui Ueyama0ca149f2013-08-06 22:31:59 +000077};
78
79MachOLinkingContext::Arch
80MachOLinkingContext::archFromCpuType(uint32_t cputype, uint32_t cpusubtype) {
Nick Kledzike34182f2013-11-06 21:36:55 +000081 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
82 if ((info->cputype == cputype) && (info->cpusubtype == cpusubtype))
Rui Ueyama0ca149f2013-08-06 22:31:59 +000083 return info->arch;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000084 }
85 return arch_unknown;
86}
87
88MachOLinkingContext::Arch
89MachOLinkingContext::archFromName(StringRef archName) {
Nick Kledzike34182f2013-11-06 21:36:55 +000090 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
91 if (info->archName.equals(archName))
Rui Ueyama0ca149f2013-08-06 22:31:59 +000092 return info->arch;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000093 }
94 return arch_unknown;
95}
96
Nick Kledzike5552772013-12-19 21:58:00 +000097StringRef MachOLinkingContext::nameFromArch(Arch arch) {
98 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
99 if (info->arch == arch)
100 return info->archName;
101 }
102 return "<unknown>";
103}
104
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000105uint32_t MachOLinkingContext::cpuTypeFromArch(Arch arch) {
106 assert(arch != arch_unknown);
Nick Kledzike34182f2013-11-06 21:36:55 +0000107 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
108 if (info->arch == arch)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000109 return info->cputype;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000110 }
111 llvm_unreachable("Unknown arch type");
112}
113
114uint32_t MachOLinkingContext::cpuSubtypeFromArch(Arch arch) {
115 assert(arch != arch_unknown);
Nick Kledzike34182f2013-11-06 21:36:55 +0000116 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
117 if (info->arch == arch)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000118 return info->cpusubtype;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000119 }
120 llvm_unreachable("Unknown arch type");
121}
122
123MachOLinkingContext::MachOLinkingContext()
Tim Northoverd30a1f22014-06-20 15:59:00 +0000124 : _outputMachOType(MH_EXECUTE), _outputMachOTypeStatic(false),
Nick Kledzike850d9d2013-09-10 23:46:57 +0000125 _doNothing(false), _arch(arch_unknown), _os(OS::macOSX), _osMinVersion(0),
Nick Kledzik6960b072013-12-21 01:47:17 +0000126 _pageZeroSize(0), _pageSize(4096), _compatibilityVersion(0),
Nick Kledzik0224e342014-05-14 21:32:21 +0000127 _currentVersion(0), _deadStrippableDylib(false), _printAtoms(false),
Nick Kledzik2458bec2014-07-16 19:49:02 +0000128 _testingLibResolution(false), _archHandler(nullptr) {}
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000129
130MachOLinkingContext::~MachOLinkingContext() {}
131
Nick Kledzik6960b072013-12-21 01:47:17 +0000132void MachOLinkingContext::configure(HeaderFileType type, Arch arch, OS os,
133 uint32_t minOSVersion) {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000134 _outputMachOType = type;
Nick Kledzik6960b072013-12-21 01:47:17 +0000135 _arch = arch;
136 _os = os;
137 _osMinVersion = minOSVersion;
138
Tim Northoverd30a1f22014-06-20 15:59:00 +0000139 switch (_outputMachOType) {
Nick Kledzik6960b072013-12-21 01:47:17 +0000140 case llvm::MachO::MH_EXECUTE:
141 // If targeting newer OS, use _main
142 if (minOS("10.8", "6.0")) {
143 _entrySymbolName = "_main";
144 } else {
145 // If targeting older OS, use start (in crt1.o)
146 _entrySymbolName = "start";
147 }
148
149 // __PAGEZERO defaults to 4GB on 64-bit (except for PP64 which lld does not
150 // support) and 4KB on 32-bit.
151 if (is64Bit(_arch)) {
152 _pageZeroSize = 0x100000000;
153 } else {
154 _pageZeroSize = 0x1000;
155 }
156
157 break;
158 case llvm::MachO::MH_DYLIB:
159 _globalsAreDeadStripRoots = true;
160 break;
161 case llvm::MachO::MH_BUNDLE:
162 break;
163 case llvm::MachO::MH_OBJECT:
164 _printRemainingUndefines = false;
165 _allowRemainingUndefines = true;
166 default:
167 break;
168 }
169}
170
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000171uint32_t MachOLinkingContext::getCPUType() const {
172 return cpuTypeFromArch(_arch);
173}
174
175uint32_t MachOLinkingContext::getCPUSubType() const {
176 return cpuSubtypeFromArch(_arch);
177}
178
Nick Kledzike34182f2013-11-06 21:36:55 +0000179bool MachOLinkingContext::is64Bit(Arch arch) {
180 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
181 if (info->arch == arch) {
182 return (info->cputype & CPU_ARCH_ABI64);
183 }
184 }
185 // unknown archs are not 64-bit.
186 return false;
187}
188
189bool MachOLinkingContext::isHostEndian(Arch arch) {
190 assert(arch != arch_unknown);
191 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
192 if (info->arch == arch) {
193 return (info->littleEndian == llvm::sys::IsLittleEndianHost);
194 }
195 }
196 llvm_unreachable("Unknown arch type");
197}
198
199bool MachOLinkingContext::isBigEndian(Arch arch) {
200 assert(arch != arch_unknown);
201 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
202 if (info->arch == arch) {
203 return ! info->littleEndian;
204 }
205 }
206 llvm_unreachable("Unknown arch type");
207}
208
209
210
211bool MachOLinkingContext::is64Bit() const {
212 return is64Bit(_arch);
213}
214
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000215bool MachOLinkingContext::outputTypeHasEntry() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000216 switch (_outputMachOType) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000217 case MH_EXECUTE:
218 case MH_DYLINKER:
219 case MH_PRELOAD:
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000220 return true;
221 default:
222 return false;
223 }
224}
225
Nick Kledzik2458bec2014-07-16 19:49:02 +0000226bool MachOLinkingContext::needsStubsPass() const {
227 switch (_outputMachOType) {
228 case MH_EXECUTE:
229 return !_outputMachOTypeStatic;
230 case MH_DYLIB:
231 case MH_BUNDLE:
232 return true;
233 default:
234 return false;
235 }
236}
237
238bool MachOLinkingContext::needsGOTPass() const {
239 // Only x86_64 uses GOT pass but not in -r mode.
240 if (_arch != arch_x86_64)
241 return false;
242 return (_outputMachOType != MH_OBJECT);
243}
244
245
246StringRef MachOLinkingContext::binderSymbolName() const {
247 return archHandler().stubInfo().binderSymbolName;
248}
249
250
251
252
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000253bool MachOLinkingContext::minOS(StringRef mac, StringRef iOS) const {
Nick Kledzik30332b12013-10-08 00:43:34 +0000254 uint32_t parsedVersion;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000255 switch (_os) {
Nick Kledzik30332b12013-10-08 00:43:34 +0000256 case OS::macOSX:
Nick Kledzike850d9d2013-09-10 23:46:57 +0000257 if (parsePackedVersion(mac, parsedVersion))
258 return false;
259 return _osMinVersion >= parsedVersion;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000260 case OS::iOS:
Nick Kledzik30332b12013-10-08 00:43:34 +0000261 case OS::iOS_simulator:
Nick Kledzike850d9d2013-09-10 23:46:57 +0000262 if (parsePackedVersion(iOS, parsedVersion))
263 return false;
264 return _osMinVersion >= parsedVersion;
Nick Kledzik30332b12013-10-08 00:43:34 +0000265 case OS::unknown:
266 break;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000267 }
268 llvm_unreachable("target not configured for iOS or MacOSX");
269}
270
271bool MachOLinkingContext::addEntryPointLoadCommand() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000272 if ((_outputMachOType == MH_EXECUTE) && !_outputMachOTypeStatic) {
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000273 return minOS("10.8", "6.0");
274 }
275 return false;
276}
277
278bool MachOLinkingContext::addUnixThreadLoadCommand() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000279 switch (_outputMachOType) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000280 case MH_EXECUTE:
Tim Northoverd30a1f22014-06-20 15:59:00 +0000281 if (_outputMachOTypeStatic)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000282 return true;
283 else
284 return !minOS("10.8", "6.0");
285 break;
Nick Kledzike34182f2013-11-06 21:36:55 +0000286 case MH_DYLINKER:
287 case MH_PRELOAD:
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000288 return true;
289 default:
290 return false;
291 }
292}
293
Tim Northover77d82202014-07-10 11:21:06 +0000294bool MachOLinkingContext::pathExists(StringRef path) const {
295 if (!testingLibResolution())
296 return llvm::sys::fs::exists(path.str());
297
298 // Otherwise, we're in test mode: only files explicitly provided on the
299 // command-line exist.
300 return _existingPaths.find(path) != _existingPaths.end();
301}
302
303void MachOLinkingContext::addModifiedSearchDir(
304 StringRef libPath, const StringRefVector &syslibRoots, bool isSystemPath) {
305 bool addedModifiedPath = false;
306
307 // Two cases to consider here:
308 // + If the last -syslibroot is "/", all of them are ignored (don't ask).
309 // + -syslibroot only applies to absolute paths.
310 if (!syslibRoots.empty() && syslibRoots.back() != "/" &&
311 llvm::sys::path::is_absolute(libPath)) {
312 for (auto syslibRoot : syslibRoots) {
313 SmallString<256> path(syslibRoot);
314 llvm::sys::path::append(path, libPath);
315 if (pathExists(path)) {
316 _searchDirs.push_back(path.str().copy(_allocator));
317 addedModifiedPath = true;
318 }
319 }
320 }
321
322 if (addedModifiedPath)
323 return;
324
325 // Finally, if only one -syslibroot is given, system paths which aren't in it
326 // get suppressed.
327 if (syslibRoots.size() != 1 || !isSystemPath) {
328 if (pathExists(libPath)) {
329 _searchDirs.push_back(libPath);
330 }
331 }
332}
333
334ErrorOr<StringRef>
335MachOLinkingContext::searchDirForLibrary(StringRef path,
336 StringRef libName) const {
337 SmallString<256> fullPath;
338 if (libName.endswith(".o")) {
339 // A request ending in .o is special: just search for the file directly.
340 fullPath.assign(path);
341 llvm::sys::path::append(fullPath, libName);
342 if (pathExists(fullPath))
343 return fullPath.str().copy(_allocator);
344 return make_error_code(llvm::errc::no_such_file_or_directory);
345 }
346
347 // Search for dynamic library
348 fullPath.assign(path);
349 llvm::sys::path::append(fullPath, Twine("lib") + libName + ".dylib");
350 if (pathExists(fullPath))
351 return fullPath.str().copy(_allocator);
352
353 // If not, try for a static library
354 fullPath.assign(path);
355 llvm::sys::path::append(fullPath, Twine("lib") + libName + ".a");
356 if (pathExists(fullPath))
357 return fullPath.str().copy(_allocator);
358
359 return make_error_code(llvm::errc::no_such_file_or_directory);
360}
361
362
363
364ErrorOr<StringRef> MachOLinkingContext::searchLibrary(StringRef libName) const {
365 SmallString<256> path;
366 for (StringRef dir : searchDirs()) {
367 ErrorOr<StringRef> ec = searchDirForLibrary(dir, libName);
368 if (ec)
369 return ec;
370 }
371
372 return make_error_code(llvm::errc::no_such_file_or_directory);
373}
374
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000375bool MachOLinkingContext::validateImpl(raw_ostream &diagnostics) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000376 // TODO: if -arch not specified, look at arch of first .o file.
377
Tim Northoverd30a1f22014-06-20 15:59:00 +0000378 if (_currentVersion && _outputMachOType != MH_DYLIB) {
Nick Kledzike773e322013-09-10 23:55:14 +0000379 diagnostics << "error: -current_version can only be used with dylibs\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000380 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000381 }
382
Tim Northoverd30a1f22014-06-20 15:59:00 +0000383 if (_compatibilityVersion && _outputMachOType != MH_DYLIB) {
Nick Kledzike773e322013-09-10 23:55:14 +0000384 diagnostics
385 << "error: -compatibility_version can only be used with dylibs\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000386 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000387 }
388
Tim Northoverd30a1f22014-06-20 15:59:00 +0000389 if (_deadStrippableDylib && _outputMachOType != MH_DYLIB) {
Nick Kledzike773e322013-09-10 23:55:14 +0000390 diagnostics
391 << "error: -mark_dead_strippable_dylib can only be used with dylibs.\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000392 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000393 }
394
Tim Northoverd30a1f22014-06-20 15:59:00 +0000395 if (!_bundleLoader.empty() && outputMachOType() != MH_BUNDLE) {
Nick Kledzike773e322013-09-10 23:55:14 +0000396 diagnostics
397 << "error: -bundle_loader can only be used with Mach-O bundles\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000398 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000399 }
400
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000401 return true;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000402}
403
Shankar Easwaran2bc24922013-10-29 05:12:14 +0000404void MachOLinkingContext::addPasses(PassManager &pm) {
Nico Rieckb9d84f42014-02-24 21:14:37 +0000405 pm.add(std::unique_ptr<Pass>(new LayoutPass(registry())));
Nick Kledzik2458bec2014-07-16 19:49:02 +0000406 if (needsStubsPass())
407 mach_o::addStubsPass(pm, *this);
408 if (needsGOTPass())
409 mach_o::addGOTPass(pm, *this);
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000410}
411
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000412Writer &MachOLinkingContext::writer() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000413 if (!_writer)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000414 _writer = createWriterMachO(*this);
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000415 return *_writer;
416}
417
Nick Kledzik2458bec2014-07-16 19:49:02 +0000418ArchHandler &MachOLinkingContext::archHandler() const {
419 if (!_archHandler)
420 _archHandler = ArchHandler::create(_arch);
421 return *_archHandler;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000422}
423
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000424
Nick Kledzik2fcbe822014-07-30 00:58:06 +0000425void MachOLinkingContext::addSectionAlignment(StringRef seg, StringRef sect,
426 uint8_t align2) {
427 SectionAlign entry;
428 entry.segmentName = seg;
429 entry.sectionName = sect;
430 entry.align2 = align2;
431 _sectAligns.push_back(entry);
432}
433
434bool MachOLinkingContext::sectionAligned(StringRef seg, StringRef sect,
435 uint8_t &align2) const {
436 for (const SectionAlign &entry : _sectAligns) {
437 if (seg.equals(entry.segmentName) && sect.equals(entry.sectionName)) {
438 align2 = entry.align2;
439 return true;
440 }
441 }
442 return false;
443}
444
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000445} // end namespace lld