blob: a5bca11cb5f46a1af466ee40c892f122dec15507 [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
Rui Ueyama57a29532014-08-06 19:37:35 +000028#include <algorithm>
29
Nick Kledzik2458bec2014-07-16 19:49:02 +000030using lld::mach_o::ArchHandler;
Nick Kledzike34182f2013-11-06 21:36:55 +000031using namespace llvm::MachO;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000032
33namespace lld {
34
Nick Kledzike850d9d2013-09-10 23:46:57 +000035bool MachOLinkingContext::parsePackedVersion(StringRef str, uint32_t &result) {
36 result = 0;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000037
38 if (str.empty())
39 return false;
40
41 SmallVector<StringRef, 3> parts;
42 llvm::SplitString(str, parts, ".");
43
44 unsigned long long num;
45 if (llvm::getAsUnsignedInteger(parts[0], 10, num))
46 return true;
47 if (num > 65535)
48 return true;
Nick Kledzike850d9d2013-09-10 23:46:57 +000049 result = num << 16;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000050
51 if (parts.size() > 1) {
52 if (llvm::getAsUnsignedInteger(parts[1], 10, num))
53 return true;
54 if (num > 255)
55 return true;
Nick Kledzike850d9d2013-09-10 23:46:57 +000056 result |= (num << 8);
Rui Ueyama0ca149f2013-08-06 22:31:59 +000057 }
58
59 if (parts.size() > 2) {
60 if (llvm::getAsUnsignedInteger(parts[2], 10, num))
61 return true;
62 if (num > 255)
63 return true;
Nick Kledzike850d9d2013-09-10 23:46:57 +000064 result |= num;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000065 }
66
67 return false;
68}
69
Rui Ueyama0ca149f2013-08-06 22:31:59 +000070
Nick Kledzike34182f2013-11-06 21:36:55 +000071MachOLinkingContext::ArchInfo MachOLinkingContext::_s_archInfos[] = {
72 { "x86_64", arch_x86_64, true, CPU_TYPE_X86_64, CPU_SUBTYPE_X86_64_ALL },
73 { "i386", arch_x86, true, CPU_TYPE_I386, CPU_SUBTYPE_X86_ALL },
74 { "ppc", arch_ppc, false, CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_ALL },
75 { "armv6", arch_armv6, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V6 },
76 { "armv7", arch_armv7, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7 },
77 { "armv7s", arch_armv7s, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7S },
78 { "", arch_unknown,false, 0, 0 }
Rui Ueyama0ca149f2013-08-06 22:31:59 +000079};
80
81MachOLinkingContext::Arch
82MachOLinkingContext::archFromCpuType(uint32_t cputype, uint32_t cpusubtype) {
Nick Kledzike34182f2013-11-06 21:36:55 +000083 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
84 if ((info->cputype == cputype) && (info->cpusubtype == cpusubtype))
Rui Ueyama0ca149f2013-08-06 22:31:59 +000085 return info->arch;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000086 }
87 return arch_unknown;
88}
89
90MachOLinkingContext::Arch
91MachOLinkingContext::archFromName(StringRef archName) {
Nick Kledzike34182f2013-11-06 21:36:55 +000092 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
93 if (info->archName.equals(archName))
Rui Ueyama0ca149f2013-08-06 22:31:59 +000094 return info->arch;
Rui Ueyama0ca149f2013-08-06 22:31:59 +000095 }
96 return arch_unknown;
97}
98
Nick Kledzike5552772013-12-19 21:58:00 +000099StringRef MachOLinkingContext::nameFromArch(Arch arch) {
100 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
101 if (info->arch == arch)
102 return info->archName;
103 }
104 return "<unknown>";
105}
106
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000107uint32_t MachOLinkingContext::cpuTypeFromArch(Arch arch) {
108 assert(arch != arch_unknown);
Nick Kledzike34182f2013-11-06 21:36:55 +0000109 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
110 if (info->arch == arch)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000111 return info->cputype;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000112 }
113 llvm_unreachable("Unknown arch type");
114}
115
116uint32_t MachOLinkingContext::cpuSubtypeFromArch(Arch arch) {
117 assert(arch != arch_unknown);
Nick Kledzike34182f2013-11-06 21:36:55 +0000118 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
119 if (info->arch == arch)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000120 return info->cpusubtype;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000121 }
122 llvm_unreachable("Unknown arch type");
123}
124
125MachOLinkingContext::MachOLinkingContext()
Tim Northoverd30a1f22014-06-20 15:59:00 +0000126 : _outputMachOType(MH_EXECUTE), _outputMachOTypeStatic(false),
Nick Kledzike850d9d2013-09-10 23:46:57 +0000127 _doNothing(false), _arch(arch_unknown), _os(OS::macOSX), _osMinVersion(0),
Nick Kledzik6960b072013-12-21 01:47:17 +0000128 _pageZeroSize(0), _pageSize(4096), _compatibilityVersion(0),
Nick Kledzik0224e342014-05-14 21:32:21 +0000129 _currentVersion(0), _deadStrippableDylib(false), _printAtoms(false),
Nick Kledzik2458bec2014-07-16 19:49:02 +0000130 _testingLibResolution(false), _archHandler(nullptr) {}
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000131
132MachOLinkingContext::~MachOLinkingContext() {}
133
Nick Kledzik6960b072013-12-21 01:47:17 +0000134void MachOLinkingContext::configure(HeaderFileType type, Arch arch, OS os,
135 uint32_t minOSVersion) {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000136 _outputMachOType = type;
Nick Kledzik6960b072013-12-21 01:47:17 +0000137 _arch = arch;
138 _os = os;
139 _osMinVersion = minOSVersion;
140
Tim Northoverd30a1f22014-06-20 15:59:00 +0000141 switch (_outputMachOType) {
Nick Kledzik6960b072013-12-21 01:47:17 +0000142 case llvm::MachO::MH_EXECUTE:
143 // If targeting newer OS, use _main
144 if (minOS("10.8", "6.0")) {
145 _entrySymbolName = "_main";
146 } else {
147 // If targeting older OS, use start (in crt1.o)
148 _entrySymbolName = "start";
149 }
150
151 // __PAGEZERO defaults to 4GB on 64-bit (except for PP64 which lld does not
152 // support) and 4KB on 32-bit.
153 if (is64Bit(_arch)) {
154 _pageZeroSize = 0x100000000;
155 } else {
156 _pageZeroSize = 0x1000;
157 }
158
159 break;
160 case llvm::MachO::MH_DYLIB:
161 _globalsAreDeadStripRoots = true;
162 break;
163 case llvm::MachO::MH_BUNDLE:
164 break;
165 case llvm::MachO::MH_OBJECT:
166 _printRemainingUndefines = false;
167 _allowRemainingUndefines = true;
168 default:
169 break;
170 }
171}
172
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000173uint32_t MachOLinkingContext::getCPUType() const {
174 return cpuTypeFromArch(_arch);
175}
176
177uint32_t MachOLinkingContext::getCPUSubType() const {
178 return cpuSubtypeFromArch(_arch);
179}
180
Nick Kledzike34182f2013-11-06 21:36:55 +0000181bool MachOLinkingContext::is64Bit(Arch arch) {
182 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
183 if (info->arch == arch) {
184 return (info->cputype & CPU_ARCH_ABI64);
185 }
186 }
187 // unknown archs are not 64-bit.
188 return false;
189}
190
191bool MachOLinkingContext::isHostEndian(Arch arch) {
192 assert(arch != arch_unknown);
193 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
194 if (info->arch == arch) {
195 return (info->littleEndian == llvm::sys::IsLittleEndianHost);
196 }
197 }
198 llvm_unreachable("Unknown arch type");
199}
200
201bool MachOLinkingContext::isBigEndian(Arch arch) {
202 assert(arch != arch_unknown);
203 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
204 if (info->arch == arch) {
205 return ! info->littleEndian;
206 }
207 }
208 llvm_unreachable("Unknown arch type");
209}
210
211
212
213bool MachOLinkingContext::is64Bit() const {
214 return is64Bit(_arch);
215}
216
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000217bool MachOLinkingContext::outputTypeHasEntry() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000218 switch (_outputMachOType) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000219 case MH_EXECUTE:
220 case MH_DYLINKER:
221 case MH_PRELOAD:
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000222 return true;
223 default:
224 return false;
225 }
226}
227
Nick Kledzik2458bec2014-07-16 19:49:02 +0000228bool MachOLinkingContext::needsStubsPass() const {
229 switch (_outputMachOType) {
230 case MH_EXECUTE:
231 return !_outputMachOTypeStatic;
232 case MH_DYLIB:
233 case MH_BUNDLE:
234 return true;
235 default:
236 return false;
237 }
238}
239
240bool MachOLinkingContext::needsGOTPass() const {
241 // Only x86_64 uses GOT pass but not in -r mode.
242 if (_arch != arch_x86_64)
243 return false;
244 return (_outputMachOType != MH_OBJECT);
245}
246
247
248StringRef MachOLinkingContext::binderSymbolName() const {
249 return archHandler().stubInfo().binderSymbolName;
250}
251
252
253
254
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000255bool MachOLinkingContext::minOS(StringRef mac, StringRef iOS) const {
Nick Kledzik30332b12013-10-08 00:43:34 +0000256 uint32_t parsedVersion;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000257 switch (_os) {
Nick Kledzik30332b12013-10-08 00:43:34 +0000258 case OS::macOSX:
Nick Kledzike850d9d2013-09-10 23:46:57 +0000259 if (parsePackedVersion(mac, parsedVersion))
260 return false;
261 return _osMinVersion >= parsedVersion;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000262 case OS::iOS:
Nick Kledzik30332b12013-10-08 00:43:34 +0000263 case OS::iOS_simulator:
Nick Kledzike850d9d2013-09-10 23:46:57 +0000264 if (parsePackedVersion(iOS, parsedVersion))
265 return false;
266 return _osMinVersion >= parsedVersion;
Nick Kledzik30332b12013-10-08 00:43:34 +0000267 case OS::unknown:
268 break;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000269 }
270 llvm_unreachable("target not configured for iOS or MacOSX");
271}
272
273bool MachOLinkingContext::addEntryPointLoadCommand() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000274 if ((_outputMachOType == MH_EXECUTE) && !_outputMachOTypeStatic) {
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000275 return minOS("10.8", "6.0");
276 }
277 return false;
278}
279
280bool MachOLinkingContext::addUnixThreadLoadCommand() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000281 switch (_outputMachOType) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000282 case MH_EXECUTE:
Tim Northoverd30a1f22014-06-20 15:59:00 +0000283 if (_outputMachOTypeStatic)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000284 return true;
285 else
286 return !minOS("10.8", "6.0");
287 break;
Nick Kledzike34182f2013-11-06 21:36:55 +0000288 case MH_DYLINKER:
289 case MH_PRELOAD:
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000290 return true;
291 default:
292 return false;
293 }
294}
295
Tim Northover77d82202014-07-10 11:21:06 +0000296bool MachOLinkingContext::pathExists(StringRef path) const {
297 if (!testingLibResolution())
298 return llvm::sys::fs::exists(path.str());
299
300 // Otherwise, we're in test mode: only files explicitly provided on the
301 // command-line exist.
Rui Ueyama57a29532014-08-06 19:37:35 +0000302 std::string key = path.str();
303 std::replace(key.begin(), key.end(), '\\', '/');
304 return _existingPaths.find(key) != _existingPaths.end();
Tim Northover77d82202014-07-10 11:21:06 +0000305}
306
307void MachOLinkingContext::addModifiedSearchDir(
308 StringRef libPath, const StringRefVector &syslibRoots, bool isSystemPath) {
309 bool addedModifiedPath = false;
310
311 // Two cases to consider here:
312 // + If the last -syslibroot is "/", all of them are ignored (don't ask).
313 // + -syslibroot only applies to absolute paths.
314 if (!syslibRoots.empty() && syslibRoots.back() != "/" &&
Rui Ueyama57a29532014-08-06 19:37:35 +0000315 libPath.startswith("/")) {
Tim Northover77d82202014-07-10 11:21:06 +0000316 for (auto syslibRoot : syslibRoots) {
317 SmallString<256> path(syslibRoot);
318 llvm::sys::path::append(path, libPath);
319 if (pathExists(path)) {
320 _searchDirs.push_back(path.str().copy(_allocator));
321 addedModifiedPath = true;
322 }
323 }
324 }
325
326 if (addedModifiedPath)
327 return;
328
329 // Finally, if only one -syslibroot is given, system paths which aren't in it
330 // get suppressed.
331 if (syslibRoots.size() != 1 || !isSystemPath) {
332 if (pathExists(libPath)) {
333 _searchDirs.push_back(libPath);
334 }
335 }
336}
337
338ErrorOr<StringRef>
339MachOLinkingContext::searchDirForLibrary(StringRef path,
340 StringRef libName) const {
341 SmallString<256> fullPath;
342 if (libName.endswith(".o")) {
343 // A request ending in .o is special: just search for the file directly.
344 fullPath.assign(path);
345 llvm::sys::path::append(fullPath, libName);
346 if (pathExists(fullPath))
347 return fullPath.str().copy(_allocator);
348 return make_error_code(llvm::errc::no_such_file_or_directory);
349 }
350
351 // Search for dynamic library
352 fullPath.assign(path);
353 llvm::sys::path::append(fullPath, Twine("lib") + libName + ".dylib");
354 if (pathExists(fullPath))
355 return fullPath.str().copy(_allocator);
356
357 // If not, try for a static library
358 fullPath.assign(path);
359 llvm::sys::path::append(fullPath, Twine("lib") + libName + ".a");
360 if (pathExists(fullPath))
361 return fullPath.str().copy(_allocator);
362
363 return make_error_code(llvm::errc::no_such_file_or_directory);
364}
365
366
367
368ErrorOr<StringRef> MachOLinkingContext::searchLibrary(StringRef libName) const {
369 SmallString<256> path;
370 for (StringRef dir : searchDirs()) {
371 ErrorOr<StringRef> ec = searchDirForLibrary(dir, libName);
372 if (ec)
373 return ec;
374 }
375
376 return make_error_code(llvm::errc::no_such_file_or_directory);
377}
378
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000379bool MachOLinkingContext::validateImpl(raw_ostream &diagnostics) {
Nick Kledzike34182f2013-11-06 21:36:55 +0000380 // TODO: if -arch not specified, look at arch of first .o file.
381
Tim Northoverd30a1f22014-06-20 15:59:00 +0000382 if (_currentVersion && _outputMachOType != MH_DYLIB) {
Nick Kledzike773e322013-09-10 23:55:14 +0000383 diagnostics << "error: -current_version can only be used with dylibs\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000384 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000385 }
386
Tim Northoverd30a1f22014-06-20 15:59:00 +0000387 if (_compatibilityVersion && _outputMachOType != MH_DYLIB) {
Nick Kledzike773e322013-09-10 23:55:14 +0000388 diagnostics
389 << "error: -compatibility_version can only be used with dylibs\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000390 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000391 }
392
Tim Northoverd30a1f22014-06-20 15:59:00 +0000393 if (_deadStrippableDylib && _outputMachOType != MH_DYLIB) {
Nick Kledzike773e322013-09-10 23:55:14 +0000394 diagnostics
395 << "error: -mark_dead_strippable_dylib can only be used with dylibs.\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000396 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000397 }
398
Tim Northoverd30a1f22014-06-20 15:59:00 +0000399 if (!_bundleLoader.empty() && outputMachOType() != MH_BUNDLE) {
Nick Kledzike773e322013-09-10 23:55:14 +0000400 diagnostics
401 << "error: -bundle_loader can only be used with Mach-O bundles\n";
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000402 return false;
Nick Kledzike773e322013-09-10 23:55:14 +0000403 }
404
Rui Ueyama8db1edd2013-09-24 23:26:34 +0000405 return true;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000406}
407
Shankar Easwaran2bc24922013-10-29 05:12:14 +0000408void MachOLinkingContext::addPasses(PassManager &pm) {
Nico Rieckb9d84f42014-02-24 21:14:37 +0000409 pm.add(std::unique_ptr<Pass>(new LayoutPass(registry())));
Nick Kledzik2458bec2014-07-16 19:49:02 +0000410 if (needsStubsPass())
411 mach_o::addStubsPass(pm, *this);
412 if (needsGOTPass())
413 mach_o::addGOTPass(pm, *this);
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000414}
415
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000416Writer &MachOLinkingContext::writer() const {
Tim Northoverd30a1f22014-06-20 15:59:00 +0000417 if (!_writer)
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000418 _writer = createWriterMachO(*this);
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000419 return *_writer;
420}
421
Nick Kledzik2458bec2014-07-16 19:49:02 +0000422ArchHandler &MachOLinkingContext::archHandler() const {
423 if (!_archHandler)
424 _archHandler = ArchHandler::create(_arch);
425 return *_archHandler;
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000426}
427
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000428
Nick Kledzik2fcbe822014-07-30 00:58:06 +0000429void MachOLinkingContext::addSectionAlignment(StringRef seg, StringRef sect,
430 uint8_t align2) {
431 SectionAlign entry;
432 entry.segmentName = seg;
433 entry.sectionName = sect;
434 entry.align2 = align2;
435 _sectAligns.push_back(entry);
436}
437
438bool MachOLinkingContext::sectionAligned(StringRef seg, StringRef sect,
439 uint8_t &align2) const {
440 for (const SectionAlign &entry : _sectAligns) {
441 if (seg.equals(entry.segmentName) && sect.equals(entry.sectionName)) {
442 align2 = entry.align2;
443 return true;
444 }
445 }
446 return false;
447}
448
Rui Ueyama0ca149f2013-08-06 22:31:59 +0000449} // end namespace lld