Coverage Report

Created: 2019-05-19 14:56

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- lib/ReaderWriter/MachO/MachOLinkingContext.cpp ---------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "lld/Common/ErrorHandler.h"
10
#include "lld/ReaderWriter/MachOLinkingContext.h"
11
#include "ArchHandler.h"
12
#include "File.h"
13
#include "FlatNamespaceFile.h"
14
#include "MachONormalizedFile.h"
15
#include "MachOPasses.h"
16
#include "SectCreateFile.h"
17
#include "lld/Common/Driver.h"
18
#include "lld/Core/ArchiveLibraryFile.h"
19
#include "lld/Core/PassManager.h"
20
#include "lld/Core/Reader.h"
21
#include "lld/Core/Writer.h"
22
#include "llvm/ADT/STLExtras.h"
23
#include "llvm/ADT/StringExtras.h"
24
#include "llvm/ADT/Triple.h"
25
#include "llvm/BinaryFormat/MachO.h"
26
#include "llvm/Demangle/Demangle.h"
27
#include "llvm/Support/Debug.h"
28
#include "llvm/Support/Errc.h"
29
#include "llvm/Support/Host.h"
30
#include "llvm/Support/Path.h"
31
#include <algorithm>
32
33
using lld::mach_o::ArchHandler;
34
using lld::mach_o::MachOFile;
35
using lld::mach_o::MachODylibFile;
36
using namespace llvm::MachO;
37
38
namespace lld {
39
40
459
bool MachOLinkingContext::parsePackedVersion(StringRef str, uint32_t &result) {
41
459
  result = 0;
42
459
43
459
  if (str.empty())
44
0
    return false;
45
459
46
459
  SmallVector<StringRef, 3> parts;
47
459
  llvm::SplitString(str, parts, ".");
48
459
49
459
  unsigned long long num;
50
459
  if (llvm::getAsUnsignedInteger(parts[0], 10, num))
51
0
    return true;
52
459
  if (num > 65535)
53
0
    return true;
54
459
  result = num << 16;
55
459
56
459
  if (parts.size() > 1) {
57
459
    if (llvm::getAsUnsignedInteger(parts[1], 10, num))
58
1
      return true;
59
458
    if (num > 255)
60
0
      return true;
61
458
    result |= (num << 8);
62
458
  }
63
459
64
459
  
if (458
parts.size() > 2458
) {
65
3
    if (llvm::getAsUnsignedInteger(parts[2], 10, num))
66
0
      return true;
67
3
    if (num > 255)
68
0
      return true;
69
3
    result |= num;
70
3
  }
71
458
72
458
  return false;
73
458
}
74
75
2
bool MachOLinkingContext::parsePackedVersion(StringRef str, uint64_t &result) {
76
2
  result = 0;
77
2
78
2
  if (str.empty())
79
0
    return false;
80
2
81
2
  SmallVector<StringRef, 5> parts;
82
2
  llvm::SplitString(str, parts, ".");
83
2
84
2
  unsigned long long num;
85
2
  if (llvm::getAsUnsignedInteger(parts[0], 10, num))
86
0
    return true;
87
2
  if (num > 0xFFFFFF)
88
0
    return true;
89
2
  result = num << 40;
90
2
91
2
  unsigned Shift = 30;
92
5
  for (StringRef str : llvm::makeArrayRef(parts).slice(1)) {
93
5
    if (llvm::getAsUnsignedInteger(str, 10, num))
94
1
      return true;
95
4
    if (num > 0x3FF)
96
0
      return true;
97
4
    result |= (num << Shift);
98
4
    Shift -= 10;
99
4
  }
100
2
101
2
  
return false1
;
102
2
}
103
104
MachOLinkingContext::ArchInfo MachOLinkingContext::_s_archInfos[] = {
105
  { "x86_64", arch_x86_64, true,  CPU_TYPE_X86_64,  CPU_SUBTYPE_X86_64_ALL },
106
  { "i386",   arch_x86,    true,  CPU_TYPE_I386,    CPU_SUBTYPE_X86_ALL },
107
  { "ppc",    arch_ppc,    false, CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_ALL },
108
  { "armv6",  arch_armv6,  true,  CPU_TYPE_ARM,     CPU_SUBTYPE_ARM_V6 },
109
  { "armv7",  arch_armv7,  true,  CPU_TYPE_ARM,     CPU_SUBTYPE_ARM_V7 },
110
  { "armv7s", arch_armv7s, true,  CPU_TYPE_ARM,     CPU_SUBTYPE_ARM_V7S },
111
  { "arm64",  arch_arm64,  true,  CPU_TYPE_ARM64,   CPU_SUBTYPE_ARM64_ALL },
112
  { "",       arch_unknown,false, 0,                0 }
113
};
114
115
MachOLinkingContext::Arch
116
46
MachOLinkingContext::archFromCpuType(uint32_t cputype, uint32_t cpusubtype) {
117
127
  for (ArchInfo *info = _s_archInfos; !info->archName.empty(); 
++info81
) {
118
127
    if ((info->cputype == cputype) && 
(info->cpusubtype == cpusubtype)54
)
119
46
      return info->arch;
120
127
  }
121
46
  
return arch_unknown0
;
122
46
}
123
124
MachOLinkingContext::Arch
125
251
MachOLinkingContext::archFromName(StringRef archName) {
126
492
  for (ArchInfo *info = _s_archInfos; !info->archName.empty(); 
++info241
) {
127
492
    if (info->archName.equals(archName))
128
251
      return info->arch;
129
492
  }
130
251
  
return arch_unknown0
;
131
251
}
132
133
5
StringRef MachOLinkingContext::nameFromArch(Arch arch) {
134
6
  for (ArchInfo *info = _s_archInfos; !info->archName.empty(); 
++info1
) {
135
6
    if (info->arch == arch)
136
5
      return info->archName;
137
6
  }
138
5
  
return "<unknown>"0
;
139
5
}
140
141
188
uint32_t MachOLinkingContext::cpuTypeFromArch(Arch arch) {
142
188
  assert(arch != arch_unknown);
143
383
  for (ArchInfo *info = _s_archInfos; !info->archName.empty(); 
++info195
) {
144
383
    if (info->arch == arch)
145
188
      return info->cputype;
146
383
  }
147
188
  
llvm_unreachable0
("Unknown arch type");
148
188
}
149
150
189
uint32_t MachOLinkingContext::cpuSubtypeFromArch(Arch arch) {
151
189
  assert(arch != arch_unknown);
152
384
  for (ArchInfo *info = _s_archInfos; !info->archName.empty(); 
++info195
) {
153
384
    if (info->arch == arch)
154
189
      return info->cpusubtype;
155
384
  }
156
189
  
llvm_unreachable0
("Unknown arch type");
157
189
}
158
159
1
bool MachOLinkingContext::isThinObjectFile(StringRef path, Arch &arch) {
160
1
  return mach_o::normalized::isThinObjectFile(path, arch);
161
1
}
162
163
bool MachOLinkingContext::sliceFromFatFile(MemoryBufferRef mb, uint32_t &offset,
164
319
                                           uint32_t &size) {
165
319
  return mach_o::normalized::sliceFromFatFile(mb, _arch, offset, size);
166
319
}
167
168
244
MachOLinkingContext::MachOLinkingContext() {}
169
170
244
MachOLinkingContext::~MachOLinkingContext() {
171
244
  // Atoms are allocated on BumpPtrAllocator's on File's.
172
244
  // As we transfer atoms from one file to another, we need to clear all of the
173
244
  // atoms before we remove any of the BumpPtrAllocator's.
174
244
  auto &nodes = getNodes();
175
1.67k
  for (unsigned i = 0, e = nodes.size(); i != e; 
++i1.42k
) {
176
1.42k
    FileNode *node = dyn_cast<FileNode>(nodes[i].get());
177
1.42k
    if (!node)
178
184
      continue;
179
1.24k
    File *file = node->getFile();
180
1.24k
    file->clearAtoms();
181
1.24k
  }
182
244
}
183
184
void MachOLinkingContext::configure(HeaderFileType type, Arch arch, OS os,
185
                                    uint32_t minOSVersion,
186
243
                                    bool exportDynamicSymbols) {
187
243
  _outputMachOType = type;
188
243
  _arch = arch;
189
243
  _os = os;
190
243
  _osMinVersion = minOSVersion;
191
243
192
243
  // If min OS not specified on command line, use reasonable defaults.
193
243
  // Note that we only do sensible defaults when emitting something other than
194
243
  // object and preload.
195
243
  if (_outputMachOType != llvm::MachO::MH_OBJECT &&
196
243
      
_outputMachOType != llvm::MachO::MH_PRELOAD153
) {
197
152
    if (minOSVersion == 0) {
198
95
      switch (_arch) {
199
95
      case arch_x86_64:
200
76
      case arch_x86:
201
76
        parsePackedVersion("10.8", _osMinVersion);
202
76
        _os = MachOLinkingContext::OS::macOSX;
203
76
        break;
204
76
      case arch_armv6:
205
14
      case arch_armv7:
206
14
      case arch_armv7s:
207
14
      case arch_arm64:
208
14
        parsePackedVersion("7.0", _osMinVersion);
209
14
        _os = MachOLinkingContext::OS::iOS;
210
14
        break;
211
14
      default:
212
5
        break;
213
243
      }
214
243
    }
215
152
  }
216
243
217
243
  switch (_outputMachOType) {
218
243
  case llvm::MachO::MH_EXECUTE:
219
92
    // If targeting newer OS, use _main
220
92
    if (minOS("10.8", "6.0")) {
221
79
      _entrySymbolName = "_main";
222
79
    } else {
223
13
      // If targeting older OS, use start (in crt1.o)
224
13
      _entrySymbolName = "start";
225
13
    }
226
92
227
92
    // __PAGEZERO defaults to 4GB on 64-bit (except for PP64 which lld does not
228
92
    // support) and 4KB on 32-bit.
229
92
    if (is64Bit(_arch)) {
230
66
      _pageZeroSize = 0x100000000;
231
66
    } else {
232
26
      _pageZeroSize = 0x1000;
233
26
    }
234
92
235
92
    // Initial base address is __PAGEZERO size.
236
92
    _baseAddress = _pageZeroSize;
237
92
238
92
    // Make PIE by default when targetting newer OSs.
239
92
    switch (os) {
240
92
      case OS::macOSX:
241
32
        if (minOSVersion >= 0x000A0700) // MacOSX 10.7
242
29
          _pie = true;
243
32
        break;
244
92
      case OS::iOS:
245
2
        if (minOSVersion >= 0x00040300) // iOS 4.3
246
2
          _pie = true;
247
2
       break;
248
92
       case OS::iOS_simulator:
249
3
        _pie = true;
250
3
       break;
251
92
       case OS::unknown:
252
55
       break;
253
92
    }
254
92
    setGlobalsAreDeadStripRoots(exportDynamicSymbols);
255
92
    break;
256
92
  case llvm::MachO::MH_DYLIB:
257
51
    setGlobalsAreDeadStripRoots(exportDynamicSymbols);
258
51
    break;
259
92
  case llvm::MachO::MH_BUNDLE:
260
9
    break;
261
92
  case llvm::MachO::MH_OBJECT:
262
90
    _printRemainingUndefines = false;
263
90
    _allowRemainingUndefines = true;
264
90
    break;
265
92
  default:
266
1
    break;
267
243
  }
268
243
269
243
  // Set default segment page sizes based on arch.
270
243
  if (arch == arch_arm64)
271
18
    _pageSize = 4*4096;
272
243
}
273
274
5
uint32_t MachOLinkingContext::getCPUType() const {
275
5
  return cpuTypeFromArch(_arch);
276
5
}
277
278
6
uint32_t MachOLinkingContext::getCPUSubType() const {
279
6
  return cpuSubtypeFromArch(_arch);
280
6
}
281
282
932
bool MachOLinkingContext::is64Bit(Arch arch) {
283
2.08k
  for (ArchInfo *info = _s_archInfos; !info->archName.empty(); 
++info1.15k
) {
284
2.08k
    if (info->arch == arch) {
285
927
      return (info->cputype & CPU_ARCH_ABI64);
286
927
    }
287
2.08k
  }
288
932
  // unknown archs are not 64-bit.
289
932
  
return false5
;
290
932
}
291
292
342
bool MachOLinkingContext::isHostEndian(Arch arch) {
293
342
  assert(arch != arch_unknown);
294
689
  for (ArchInfo *info = _s_archInfos; !info->archName.empty(); 
++info347
) {
295
689
    if (info->arch == arch) {
296
342
      return (info->littleEndian == llvm::sys::IsLittleEndianHost);
297
342
    }
298
689
  }
299
342
  
llvm_unreachable0
("Unknown arch type");
300
342
}
301
302
1.14k
bool MachOLinkingContext::isBigEndian(Arch arch) {
303
1.14k
  assert(arch != arch_unknown);
304
2.56k
  for (ArchInfo *info = _s_archInfos; !info->archName.empty(); 
++info1.41k
) {
305
2.56k
    if (info->arch == arch) {
306
1.14k
      return ! info->littleEndian;
307
1.14k
    }
308
2.56k
  }
309
1.14k
  
llvm_unreachable0
("Unknown arch type");
310
1.14k
}
311
312
160
bool MachOLinkingContext::is64Bit() const {
313
160
  return is64Bit(_arch);
314
160
}
315
316
414
bool MachOLinkingContext::outputTypeHasEntry() const {
317
414
  switch (_outputMachOType) {
318
414
  case MH_EXECUTE:
319
157
  case MH_DYLINKER:
320
157
  case MH_PRELOAD:
321
157
    return true;
322
257
  default:
323
257
    return false;
324
414
  }
325
414
}
326
327
368
bool MachOLinkingContext::needsStubsPass() const {
328
368
  switch (_outputMachOType) {
329
368
  case MH_EXECUTE:
330
111
    return !_outputMachOTypeStatic;
331
368
  case MH_DYLIB:
332
100
  case MH_BUNDLE:
333
100
    return true;
334
157
  default:
335
157
    return false;
336
368
  }
337
368
}
338
339
170
bool MachOLinkingContext::needsGOTPass() const {
340
170
  // GOT pass not used in -r mode.
341
170
  if (_outputMachOType == MH_OBJECT)
342
73
    return false;
343
97
  // Only some arches use GOT pass.
344
97
  switch (_arch) {
345
97
    case arch_x86_64:
346
87
    case arch_arm64:
347
87
      return true;
348
87
    default:
349
10
      return false;
350
97
  }
351
97
}
352
353
170
bool MachOLinkingContext::needsCompactUnwindPass() const {
354
170
  switch (_outputMachOType) {
355
170
  case MH_EXECUTE:
356
97
  case MH_DYLIB:
357
97
  case MH_BUNDLE:
358
97
    return archHandler().needsCompactUnwind();
359
97
  default:
360
73
    return false;
361
170
  }
362
170
}
363
364
170
bool MachOLinkingContext::needsObjCPass() const {
365
170
  // ObjC pass is only needed if any of the inputs were ObjC.
366
170
  return _objcConstraint != objc_unknown;
367
170
}
368
369
170
bool MachOLinkingContext::needsShimPass() const {
370
170
  // Shim pass only used in final executables.
371
170
  if (_outputMachOType == MH_OBJECT)
372
73
    return false;
373
97
  // Only 32-bit arm arches use Shim pass.
374
97
  switch (_arch) {
375
97
  case arch_armv6:
376
6
  case arch_armv7:
377
6
  case arch_armv7s:
378
6
    return true;
379
91
  default:
380
91
    return false;
381
97
  }
382
97
}
383
384
170
bool MachOLinkingContext::needsTLVPass() const {
385
170
  switch (_outputMachOType) {
386
170
  case MH_BUNDLE:
387
97
  case MH_EXECUTE:
388
97
  case MH_DYLIB:
389
97
    return true;
390
97
  default:
391
73
    return false;
392
170
  }
393
170
}
394
395
114
StringRef MachOLinkingContext::binderSymbolName() const {
396
114
  return archHandler().stubInfo().binderSymbolName;
397
114
}
398
399
202
bool MachOLinkingContext::minOS(StringRef mac, StringRef iOS) const {
400
202
  uint32_t parsedVersion;
401
202
  switch (_os) {
402
202
  case OS::macOSX:
403
164
    if (parsePackedVersion(mac, parsedVersion))
404
0
      return false;
405
164
    return _osMinVersion >= parsedVersion;
406
164
  case OS::iOS:
407
33
  case OS::iOS_simulator:
408
33
    if (parsePackedVersion(iOS, parsedVersion))
409
0
      return false;
410
33
    return _osMinVersion >= parsedVersion;
411
33
  case OS::unknown:
412
5
    // If we don't know the target, then assume that we don't meet the min OS.
413
5
    // This matches the ld64 behaviour
414
5
    return false;
415
0
  }
416
0
  llvm_unreachable("invalid OS enum");
417
0
}
418
419
0
bool MachOLinkingContext::addEntryPointLoadCommand() const {
420
0
  if ((_outputMachOType == MH_EXECUTE) && !_outputMachOTypeStatic) {
421
0
    return minOS("10.8", "6.0");
422
0
  }
423
0
  return false;
424
0
}
425
426
0
bool MachOLinkingContext::addUnixThreadLoadCommand() const {
427
0
  switch (_outputMachOType) {
428
0
  case MH_EXECUTE:
429
0
    if (_outputMachOTypeStatic)
430
0
      return true;
431
0
    else
432
0
      return !minOS("10.8", "6.0");
433
0
    break;
434
0
  case MH_DYLINKER:
435
0
  case MH_PRELOAD:
436
0
    return true;
437
0
  default:
438
0
    return false;
439
0
  }
440
0
}
441
442
1.01k
bool MachOLinkingContext::pathExists(StringRef path) const {
443
1.01k
  if (!_testingFileUsage)
444
908
    return llvm::sys::fs::exists(path.str());
445
110
446
110
  // Otherwise, we're in test mode: only files explicitly provided on the
447
110
  // command-line exist.
448
110
  std::string key = path.str();
449
110
  std::replace(key.begin(), key.end(), '\\', '/');
450
110
  return _existingPaths.find(key) != _existingPaths.end();
451
110
}
452
453
50
bool MachOLinkingContext::fileExists(StringRef path) const {
454
50
  bool found = pathExists(path);
455
50
  // Log search misses.
456
50
  if (!found)
457
28
    addInputFileNotFound(path);
458
50
459
50
  // When testing, file is never opened, so logging is done here.
460
50
  if (_testingFileUsage && 
found43
)
461
18
    addInputFileDependency(path);
462
50
463
50
  return found;
464
50
}
465
466
5
void MachOLinkingContext::setSysLibRoots(const StringRefVector &paths) {
467
5
  _syslibRoots = paths;
468
5
}
469
470
1
void MachOLinkingContext::addRpath(StringRef rpath) {
471
1
  _rpaths.push_back(rpath);
472
1
}
473
474
void MachOLinkingContext::addModifiedSearchDir(StringRef libPath,
475
478
                                               bool isSystemPath) {
476
478
  bool addedModifiedPath = false;
477
478
478
478
  // -syslibroot only applies to absolute paths.
479
478
  if (libPath.startswith("/")) {
480
475
    for (auto syslibRoot : _syslibRoots) {
481
14
      SmallString<256> path(syslibRoot);
482
14
      llvm::sys::path::append(path, libPath);
483
14
      if (pathExists(path)) {
484
6
        _searchDirs.push_back(path.str().copy(_allocator));
485
6
        addedModifiedPath = true;
486
6
      }
487
14
    }
488
475
  }
489
478
490
478
  if (addedModifiedPath)
491
5
    return;
492
473
493
473
  // Finally, if only one -syslibroot is given, system paths which aren't in it
494
473
  // get suppressed.
495
473
  if (_syslibRoots.size() != 1 || 
!isSystemPath7
) {
496
468
    if (pathExists(libPath)) {
497
460
      _searchDirs.push_back(libPath);
498
460
    }
499
468
  }
500
473
}
501
502
void MachOLinkingContext::addFrameworkSearchDir(StringRef fwPath,
503
475
                                                bool isSystemPath) {
504
475
  bool pathAdded = false;
505
475
506
475
  // -syslibroot only used with to absolute framework search paths.
507
475
  if (fwPath.startswith("/")) {
508
474
    for (auto syslibRoot : _syslibRoots) {
509
14
      SmallString<256> path(syslibRoot);
510
14
      llvm::sys::path::append(path, fwPath);
511
14
      if (pathExists(path)) {
512
2
        _frameworkDirs.push_back(path.str().copy(_allocator));
513
2
        pathAdded = true;
514
2
      }
515
14
    }
516
474
  }
517
475
  // If fwPath found in any -syslibroot, then done.
518
475
  if (pathAdded)
519
2
    return;
520
473
521
473
  // If only one -syslibroot, system paths not in that SDK are suppressed.
522
473
  if (isSystemPath && 
(_syslibRoots.size() == 1)469
)
523
7
    return;
524
466
525
466
  // Only use raw fwPath if that directory exists.
526
466
  if (pathExists(fwPath))
527
453
    _frameworkDirs.push_back(fwPath);
528
466
}
529
530
llvm::Optional<StringRef>
531
MachOLinkingContext::searchDirForLibrary(StringRef path,
532
24
                                         StringRef libName) const {
533
24
  SmallString<256> fullPath;
534
24
  if (libName.endswith(".o")) {
535
3
    // A request ending in .o is special: just search for the file directly.
536
3
    fullPath.assign(path);
537
3
    llvm::sys::path::append(fullPath, libName);
538
3
    if (fileExists(fullPath))
539
2
      return fullPath.str().copy(_allocator);
540
1
    return llvm::None;
541
1
  }
542
21
543
21
  // Search for dynamic library
544
21
  fullPath.assign(path);
545
21
  llvm::sys::path::append(fullPath, Twine("lib") + libName + ".dylib");
546
21
  if (fileExists(fullPath))
547
9
    return fullPath.str().copy(_allocator);
548
12
549
12
  // If not, try for a static library
550
12
  fullPath.assign(path);
551
12
  llvm::sys::path::append(fullPath, Twine("lib") + libName + ".a");
552
12
  if (fileExists(fullPath))
553
4
    return fullPath.str().copy(_allocator);
554
8
555
8
  return llvm::None;
556
8
}
557
558
llvm::Optional<StringRef>
559
16
MachOLinkingContext::searchLibrary(StringRef libName) const {
560
16
  SmallString<256> path;
561
24
  for (StringRef dir : searchDirs()) {
562
24
    llvm::Optional<StringRef> searchDir = searchDirForLibrary(dir, libName);
563
24
    if (searchDir)
564
15
      return searchDir;
565
24
  }
566
16
567
16
  
return llvm::None1
;
568
16
}
569
570
llvm::Optional<StringRef>
571
7
MachOLinkingContext::findPathForFramework(StringRef fwName) const{
572
7
  SmallString<256> fullPath;
573
14
  for (StringRef dir : frameworkDirs()) {
574
14
    fullPath.assign(dir);
575
14
    llvm::sys::path::append(fullPath, Twine(fwName) + ".framework", fwName);
576
14
    if (fileExists(fullPath))
577
7
      return fullPath.str().copy(_allocator);
578
14
  }
579
7
580
7
  
return llvm::None0
;
581
7
}
582
583
226
bool MachOLinkingContext::validateImpl() {
584
226
  // TODO: if -arch not specified, look at arch of first .o file.
585
226
586
226
  if (_currentVersion && 
_outputMachOType != MH_DYLIB4
) {
587
0
    error("-current_version can only be used with dylibs");
588
0
    return false;
589
0
  }
590
226
591
226
  if (_compatibilityVersion && 
_outputMachOType != MH_DYLIB4
) {
592
0
    error("-compatibility_version can only be used with dylibs");
593
0
    return false;
594
0
  }
595
226
596
226
  if (_deadStrippableDylib && 
_outputMachOType != MH_DYLIB2
) {
597
1
    error("-mark_dead_strippable_dylib can only be used with dylibs");
598
1
    return false;
599
1
  }
600
225
601
225
  if (!_bundleLoader.empty() && 
outputMachOType() != MH_BUNDLE2
) {
602
1
    error("-bundle_loader can only be used with Mach-O bundles");
603
1
    return false;
604
1
  }
605
224
606
224
  // If -exported_symbols_list used, all exported symbols must be defined.
607
224
  if (_exportMode == ExportMode::whiteList) {
608
8
    for (const auto &symbol : _exportedSymbols)
609
12
      addInitialUndefinedSymbol(symbol.getKey());
610
8
  }
611
224
612
224
  // If -dead_strip, set up initial live symbols.
613
224
  if (deadStrip()) {
614
14
    // Entry point is live.
615
14
    if (outputTypeHasEntry())
616
5
      addDeadStripRoot(entrySymbolName());
617
14
    // Lazy binding helper is live.
618
14
    if (needsStubsPass())
619
12
      addDeadStripRoot(binderSymbolName());
620
14
    // If using -exported_symbols_list, make all exported symbols live.
621
14
    if (_exportMode == ExportMode::whiteList) {
622
1
      setGlobalsAreDeadStripRoots(false);
623
1
      for (const auto &symbol : _exportedSymbols)
624
2
        addDeadStripRoot(symbol.getKey());
625
1
    }
626
14
  }
627
224
628
224
  addOutputFileDependency(outputPath());
629
224
630
224
  return true;
631
224
}
632
633
170
void MachOLinkingContext::addPasses(PassManager &pm) {
634
170
  // objc pass should be before layout pass.  Otherwise test cases may contain
635
170
  // no atoms which confuses the layout pass.
636
170
  if (needsObjCPass())
637
2
    mach_o::addObjCPass(pm, *this);
638
170
  mach_o::addLayoutPass(pm, *this);
639
170
  if (needsStubsPass())
640
97
    mach_o::addStubsPass(pm, *this);
641
170
  if (needsCompactUnwindPass())
642
87
    mach_o::addCompactUnwindPass(pm, *this);
643
170
  if (needsGOTPass())
644
87
    mach_o::addGOTPass(pm, *this);
645
170
  if (needsTLVPass())
646
97
    mach_o::addTLVPass(pm, *this);
647
170
  if (needsShimPass())
648
6
    mach_o::addShimPass(pm, *this); // Shim pass must run after stubs pass.
649
170
}
650
651
353
Writer &MachOLinkingContext::writer() const {
652
353
  if (!_writer)
653
184
    _writer = createWriterMachO(*this);
654
353
  return *_writer;
655
353
}
656
657
ErrorOr<std::unique_ptr<MemoryBuffer>>
658
376
MachOLinkingContext::getMemoryBuffer(StringRef path) {
659
376
  addInputFileDependency(path);
660
376
661
376
  ErrorOr<std::unique_ptr<MemoryBuffer>> mbOrErr =
662
376
    MemoryBuffer::getFileOrSTDIN(path);
663
376
  if (std::error_code ec = mbOrErr.getError())
664
57
    return ec;
665
319
  std::unique_ptr<MemoryBuffer> mb = std::move(mbOrErr.get());
666
319
667
319
  // If buffer contains a fat file, find required arch in fat buffer
668
319
  // and switch buffer to point to just that required slice.
669
319
  uint32_t offset;
670
319
  uint32_t size;
671
319
  if (sliceFromFatFile(mb->getMemBufferRef(), offset, size))
672
8
    return MemoryBuffer::getFileSlice(path, size, offset);
673
311
  return std::move(mb);
674
311
}
675
676
0
MachODylibFile* MachOLinkingContext::loadIndirectDylib(StringRef path) {
677
0
  ErrorOr<std::unique_ptr<MemoryBuffer>> mbOrErr = getMemoryBuffer(path);
678
0
  if (mbOrErr.getError())
679
0
    return nullptr;
680
0
681
0
  ErrorOr<std::unique_ptr<File>> fileOrErr =
682
0
      registry().loadFile(std::move(mbOrErr.get()));
683
0
  if (!fileOrErr)
684
0
    return nullptr;
685
0
  std::unique_ptr<File> &file = fileOrErr.get();
686
0
  file->parse();
687
0
  MachODylibFile *result = reinterpret_cast<MachODylibFile *>(file.get());
688
0
  // Node object now owned by _indirectDylibs vector.
689
0
  _indirectDylibs.push_back(std::move(file));
690
0
  return result;
691
0
}
692
693
1
MachODylibFile* MachOLinkingContext::findIndirectDylib(StringRef path) {
694
1
  // See if already loaded.
695
1
  auto pos = _pathToDylibMap.find(path);
696
1
  if (pos != _pathToDylibMap.end())
697
1
    return pos->second;
698
0
699
0
  // Search -L paths if of the form "libXXX.dylib"
700
0
  std::pair<StringRef, StringRef> split = path.rsplit('/');
701
0
  StringRef leafName = split.second;
702
0
  if (leafName.startswith("lib") && leafName.endswith(".dylib")) {
703
0
    // FIXME: Need to enhance searchLibrary() to only look for .dylib
704
0
    auto libPath = searchLibrary(leafName);
705
0
    if (libPath)
706
0
      return loadIndirectDylib(libPath.getValue());
707
0
  }
708
0
709
0
  // Try full path with sysroot.
710
0
  for (StringRef sysPath : _syslibRoots) {
711
0
    SmallString<256> fullPath;
712
0
    fullPath.assign(sysPath);
713
0
    llvm::sys::path::append(fullPath, path);
714
0
    if (pathExists(fullPath))
715
0
      return loadIndirectDylib(fullPath);
716
0
  }
717
0
718
0
  // Try full path.
719
0
  if (pathExists(path)) {
720
0
    return loadIndirectDylib(path);
721
0
  }
722
0
723
0
  return nullptr;
724
0
}
725
726
111
uint32_t MachOLinkingContext::dylibCurrentVersion(StringRef installName) const {
727
111
  auto pos = _pathToDylibMap.find(installName);
728
111
  if (pos != _pathToDylibMap.end())
729
111
    return pos->second->currentVersion();
730
0
  else
731
0
    return 0x10000; // 1.0
732
111
}
733
734
111
uint32_t MachOLinkingContext::dylibCompatVersion(StringRef installName) const {
735
111
  auto pos = _pathToDylibMap.find(installName);
736
111
  if (pos != _pathToDylibMap.end())
737
111
    return pos->second->compatVersion();
738
0
  else
739
0
    return 0x10000; // 1.0
740
111
}
741
742
void MachOLinkingContext::createImplicitFiles(
743
184
                            std::vector<std::unique_ptr<File> > &result) {
744
184
  // Add indirect dylibs by asking each linked dylib to add its indirects.
745
184
  // Iterate until no more dylibs get loaded.
746
184
  size_t dylibCount = 0;
747
289
  while (dylibCount != _allDylibs.size()) {
748
105
    dylibCount = _allDylibs.size();
749
117
    for (MachODylibFile *dylib : _allDylibs) {
750
117
      dylib->loadReExportedDylibs([this] (StringRef path) -> MachODylibFile* {
751
1
                                  return findIndirectDylib(path); });
752
117
    }
753
105
  }
754
184
755
184
  // Let writer add output type specific extras.
756
184
  writer().createImplicitFiles(result);
757
184
758
184
  // If undefinedMode is != error, add a FlatNamespaceFile instance. This will
759
184
  // provide a SharedLibraryAtom for symbols that aren't defined elsewhere.
760
184
  if (undefinedMode() != UndefinedMode::error) {
761
2
    result.emplace_back(new mach_o::FlatNamespaceFile(*this));
762
2
    _flatNamespaceFile = result.back().get();
763
2
  }
764
184
}
765
766
void MachOLinkingContext::registerDylib(MachODylibFile *dylib,
767
117
                                        bool upward) const {
768
117
  std::lock_guard<std::mutex> lock(_dylibsMutex);
769
117
770
117
  if (!llvm::count(_allDylibs, dylib))
771
117
    _allDylibs.push_back(dylib);
772
117
  _pathToDylibMap[dylib->installName()] = dylib;
773
117
  // If path is different than install name, register path too.
774
117
  if (!dylib->path().equals(dylib->installName()))
775
117
    _pathToDylibMap[dylib->path()] = dylib;
776
117
  if (upward)
777
1
    _upwardDylibs.insert(dylib);
778
117
}
779
780
111
bool MachOLinkingContext::isUpwardDylib(StringRef installName) const {
781
111
  for (MachODylibFile *dylib : _upwardDylibs) {
782
2
    if (dylib->installName().equals(installName))
783
1
      return true;
784
2
  }
785
111
  
return false110
;
786
111
}
787
788
1.20k
ArchHandler &MachOLinkingContext::archHandler() const {
789
1.20k
  if (!_archHandler)
790
225
    _archHandler = ArchHandler::create(_arch);
791
1.20k
  return *_archHandler;
792
1.20k
}
793
794
void MachOLinkingContext::addSectionAlignment(StringRef seg, StringRef sect,
795
3
                                              uint16_t align) {
796
3
  SectionAlign entry = { seg, sect, align };
797
3
  _sectAligns.push_back(entry);
798
3
}
799
800
void MachOLinkingContext::addSectCreateSection(
801
                                        StringRef seg, StringRef sect,
802
1
                                        std::unique_ptr<MemoryBuffer> content) {
803
1
804
1
  if (!_sectCreateFile) {
805
1
    auto sectCreateFile = llvm::make_unique<mach_o::SectCreateFile>();
806
1
    _sectCreateFile = sectCreateFile.get();
807
1
    getNodes().push_back(llvm::make_unique<FileNode>(std::move(sectCreateFile)));
808
1
  }
809
1
810
1
  assert(_sectCreateFile && "sectcreate file does not exist.");
811
1
  _sectCreateFile->addSection(seg, sect, std::move(content));
812
1
}
813
814
bool MachOLinkingContext::sectionAligned(StringRef seg, StringRef sect,
815
377
                                         uint16_t &align) const {
816
377
  for (const SectionAlign &entry : _sectAligns) {
817
6
    if (seg.equals(entry.segmentName) && 
sect.equals(entry.sectionName)4
) {
818
3
      align = entry.align;
819
3
      return true;
820
3
    }
821
6
  }
822
377
  
return false374
;
823
377
}
824
825
13
void MachOLinkingContext::addExportSymbol(StringRef sym) {
826
13
  // Support old crufty export lists with bogus entries.
827
13
  if (sym.endswith(".eh") || sym.startswith(".objc_category_name_")) {
828
0
    llvm::errs() << "warning: ignoring " << sym << " in export list\n";
829
0
    return;
830
0
  }
831
13
  // Only i386 MacOSX uses old ABI, so don't change those.
832
13
  if ((_os != OS::macOSX) || 
(_arch != arch_x86)10
) {
833
13
    // ObjC has two differnent ABIs.  Be nice and allow one export list work for
834
13
    // both ABIs by renaming symbols.
835
13
    if (sym.startswith(".objc_class_name_")) {
836
1
      std::string abi2className("_OBJC_CLASS_$_");
837
1
      abi2className += sym.substr(17);
838
1
      _exportedSymbols.insert(copy(abi2className));
839
1
      std::string abi2metaclassName("_OBJC_METACLASS_$_");
840
1
      abi2metaclassName += sym.substr(17);
841
1
      _exportedSymbols.insert(copy(abi2metaclassName));
842
1
      return;
843
1
    }
844
12
  }
845
12
846
12
  // FIXME: Support wildcards.
847
12
  _exportedSymbols.insert(sym);
848
12
}
849
850
47
bool MachOLinkingContext::exportSymbolNamed(StringRef sym) const {
851
47
  switch (_exportMode) {
852
47
  case ExportMode::globals:
853
0
    llvm_unreachable("exportSymbolNamed() should not be called in this mode");
854
47
    
break0
;
855
47
  case ExportMode::whiteList:
856
39
    return _exportedSymbols.count(sym);
857
47
  case ExportMode::blackList:
858
8
    return !_exportedSymbols.count(sym);
859
0
  }
860
0
  llvm_unreachable("_exportMode unknown enum value");
861
0
}
862
863
8
std::string MachOLinkingContext::demangle(StringRef symbolName) const {
864
8
  // Only try to demangle symbols if -demangle on command line
865
8
  if (!demangleSymbols())
866
5
    return symbolName;
867
3
868
3
  // Only try to demangle symbols that look like C++ symbols
869
3
  if (!symbolName.startswith("__Z"))
870
1
    return symbolName;
871
2
872
2
  SmallString<256> symBuff;
873
2
  StringRef nullTermSym = Twine(symbolName).toNullTerminatedStringRef(symBuff);
874
2
  // Mach-O has extra leading underscore that needs to be removed.
875
2
  const char *cstr = nullTermSym.data() + 1;
876
2
  int status;
877
2
  char *demangled = llvm::itaniumDemangle(cstr, nullptr, nullptr, &status);
878
2
  if (demangled) {
879
1
    std::string result(demangled);
880
1
    // __cxa_demangle() always uses a malloc'ed buffer to return the result.
881
1
    free(demangled);
882
1
    return result;
883
1
  }
884
1
885
1
  return symbolName;
886
1
}
887
888
static void addDependencyInfoHelper(llvm::raw_fd_ostream *DepInfo,
889
652
                                    char Opcode, StringRef Path) {
890
652
  if (!DepInfo)
891
645
    return;
892
7
893
7
  *DepInfo << Opcode;
894
7
  *DepInfo << Path;
895
7
  *DepInfo << '\0';
896
7
}
897
898
1
std::error_code MachOLinkingContext::createDependencyFile(StringRef path) {
899
1
  std::error_code ec;
900
1
  _dependencyInfo = std::unique_ptr<llvm::raw_fd_ostream>(new
901
1
                         llvm::raw_fd_ostream(path, ec, llvm::sys::fs::F_None));
902
1
  if (ec) {
903
0
    _dependencyInfo.reset();
904
0
    return ec;
905
0
  }
906
1
907
1
  addDependencyInfoHelper(_dependencyInfo.get(), 0x00, "lld" /*FIXME*/);
908
1
  return std::error_code();
909
1
}
910
911
399
void MachOLinkingContext::addInputFileDependency(StringRef path) const {
912
399
  addDependencyInfoHelper(_dependencyInfo.get(), 0x10, path);
913
399
}
914
915
28
void MachOLinkingContext::addInputFileNotFound(StringRef path) const {
916
28
  addDependencyInfoHelper(_dependencyInfo.get(), 0x11, path);
917
28
}
918
919
224
void MachOLinkingContext::addOutputFileDependency(StringRef path) const {
920
224
  addDependencyInfoHelper(_dependencyInfo.get(), 0x40, path);
921
224
}
922
923
void MachOLinkingContext::appendOrderedSymbol(StringRef symbol,
924
5
                                              StringRef filename) {
925
5
  // To support sorting static functions which may have the same name in
926
5
  // multiple .o files, _orderFiles maps the symbol name to a vector
927
5
  // of OrderFileNode each of which can specify a file prefix.
928
5
  OrderFileNode info;
929
5
  if (!filename.empty())
930
1
    info.fileFilter = copy(filename);
931
5
  info.order = _orderFileEntries++;
932
5
  _orderFiles[symbol].push_back(info);
933
5
}
934
935
bool
936
MachOLinkingContext::findOrderOrdinal(const std::vector<OrderFileNode> &nodes,
937
                                      const DefinedAtom *atom,
938
11
                                      unsigned &ordinal) {
939
11
  const File *objFile = &atom->file();
940
11
  assert(objFile);
941
11
  StringRef objName = objFile->path();
942
11
  std::pair<StringRef, StringRef> dirAndLeaf = objName.rsplit('/');
943
11
  if (!dirAndLeaf.second.empty())
944
11
    objName = dirAndLeaf.second;
945
11
  for (const OrderFileNode &info : nodes) {
946
11
    if (info.fileFilter.empty()) {
947
5
      // Have unprefixed symbol name in order file that matches this atom.
948
5
      ordinal = info.order;
949
5
      return true;
950
5
    }
951
6
    if (info.fileFilter.equals(objName)) {
952
6
      // Have prefixed symbol name in order file that matches atom's path.
953
6
      ordinal = info.order;
954
6
      return true;
955
6
    }
956
6
  }
957
11
  
return false0
;
958
11
}
959
960
bool MachOLinkingContext::customAtomOrderer(const DefinedAtom *left,
961
                                            const DefinedAtom *right,
962
298
                                            bool &leftBeforeRight) const {
963
298
  // No custom sorting if no order file entries.
964
298
  if (!_orderFileEntries)
965
286
    return false;
966
12
967
12
  // Order files can only order named atoms.
968
12
  StringRef leftName = left->name();
969
12
  StringRef rightName = right->name();
970
12
  if (leftName.empty() || 
rightName.empty()11
)
971
1
    return false;
972
11
973
11
  // If neither is in order file list, no custom sorter.
974
11
  auto leftPos = _orderFiles.find(leftName);
975
11
  auto rightPos = _orderFiles.find(rightName);
976
11
  bool leftIsOrdered = (leftPos != _orderFiles.end());
977
11
  bool rightIsOrdered = (rightPos != _orderFiles.end());
978
11
  if (!leftIsOrdered && 
!rightIsOrdered4
)
979
2
    return false;
980
9
981
9
  // There could be multiple symbols with same name but different file prefixes.
982
9
  unsigned leftOrder;
983
9
  unsigned rightOrder;
984
9
  bool foundLeft =
985
9
      leftIsOrdered && 
findOrderOrdinal(leftPos->getValue(), left, leftOrder)7
;
986
9
  bool foundRight = rightIsOrdered &&
987
9
                    
findOrderOrdinal(rightPos->getValue(), right, rightOrder)4
;
988
9
  if (!foundLeft && 
!foundRight2
)
989
0
    return false;
990
9
991
9
  // If only one is in order file list, ordered one goes first.
992
9
  if (foundLeft != foundRight)
993
7
    leftBeforeRight = foundLeft;
994
2
  else
995
2
    leftBeforeRight = (leftOrder < rightOrder);
996
9
997
9
  return true;
998
9
}
999
1000
1.76k
static bool isLibrary(const std::unique_ptr<Node> &elem) {
1001
1.76k
  if (FileNode *node = dyn_cast<FileNode>(const_cast<Node *>(elem.get()))) {
1002
1.76k
    File *file = node->getFile();
1003
1.76k
    return isa<SharedLibraryFile>(file) || 
isa<ArchiveLibraryFile>(file)1.52k
;
1004
1.76k
  }
1005
0
  return false;
1006
0
}
1007
1008
// The darwin linker processes input files in two phases.  The first phase
1009
// links in all object (.o) files in command line order. The second phase
1010
// links in libraries in command line order.
1011
// In this function we reorder the input files so that all the object files
1012
// comes before any library file. We also make a group for the library files
1013
// so that the Resolver will reiterate over the libraries as long as we find
1014
// new undefines from libraries.
1015
184
void MachOLinkingContext::finalizeInputFiles() {
1016
184
  std::vector<std::unique_ptr<Node>> &elements = getNodes();
1017
184
  llvm::stable_sort(elements, [](const std::unique_ptr<Node> &a,
1018
626
                                 const std::unique_ptr<Node> &b) {
1019
626
    return !isLibrary(a) && 
isLibrary(b)502
;
1020
626
  });
1021
184
  size_t numLibs = std::count_if(elements.begin(), elements.end(), isLibrary);
1022
184
  elements.push_back(llvm::make_unique<GroupEnd>(numLibs));
1023
184
}
1024
1025
632
llvm::Error MachOLinkingContext::handleLoadedFile(File &file) {
1026
632
  auto *machoFile = dyn_cast<MachOFile>(&file);
1027
632
  if (!machoFile)
1028
459
    return llvm::Error::success();
1029
173
1030
173
  // Check that the arch of the context matches that of the file.
1031
173
  // Also set the arch of the context if it didn't have one.
1032
173
  if (_arch == arch_unknown) {
1033
0
    _arch = machoFile->arch();
1034
173
  } else if (machoFile->arch() != arch_unknown && machoFile->arch() != _arch) {
1035
0
    // Archs are different.
1036
0
    return llvm::make_error<GenericError>(file.path() +
1037
0
                  Twine(" cannot be linked due to incompatible architecture"));
1038
0
  }
1039
173
1040
173
  // Check that the OS of the context matches that of the file.
1041
173
  // Also set the OS of the context if it didn't have one.
1042
173
  if (_os == OS::unknown) {
1043
71
    _os = machoFile->OS();
1044
102
  } else if (machoFile->OS() != OS::unknown && 
machoFile->OS() != _os2
) {
1045
1
    // OSes are different.
1046
1
    return llvm::make_error<GenericError>(file.path() +
1047
1
              Twine(" cannot be linked due to incompatible operating systems"));
1048
1
  }
1049
172
1050
172
  // Check that if the objc info exists, that it is compatible with the target
1051
172
  // OS.
1052
172
  switch (machoFile->objcConstraint()) {
1053
172
    case objc_unknown:
1054
166
      // The file is not compiled with objc, so skip the checks.
1055
166
      break;
1056
172
    case objc_gc_only:
1057
0
    case objc_supports_gc:
1058
0
      llvm_unreachable("GC support should already have thrown an error");
1059
3
    case objc_retainReleaseForSimulator:
1060
3
      // The file is built with simulator objc, so make sure that the context
1061
3
      // is also building with simulator support.
1062
3
      if (_os != OS::iOS_simulator)
1063
1
        return llvm::make_error<GenericError>(file.path() +
1064
1
          Twine(" cannot be linked.  It contains ObjC built for the simulator"
1065
1
                " while we are linking a non-simulator target"));
1066
2
      assert((_objcConstraint == objc_unknown ||
1067
2
              _objcConstraint == objc_retainReleaseForSimulator) &&
1068
2
             "Must be linking with retain/release for the simulator");
1069
2
      _objcConstraint = objc_retainReleaseForSimulator;
1070
2
      break;
1071
3
    case objc_retainRelease:
1072
3
      // The file is built without simulator objc, so make sure that the
1073
3
      // context is also building without simulator support.
1074
3
      if (_os == OS::iOS_simulator)
1075
1
        return llvm::make_error<GenericError>(file.path() +
1076
1
          Twine(" cannot be linked.  It contains ObjC built for a non-simulator"
1077
1
                " target while we are linking a simulator target"));
1078
2
      assert((_objcConstraint == objc_unknown ||
1079
2
              _objcConstraint == objc_retainRelease) &&
1080
2
             "Must be linking with retain/release for a non-simulator target");
1081
2
      _objcConstraint = objc_retainRelease;
1082
2
      break;
1083
170
  }
1084
170
1085
170
  // Check that the swift version of the context matches that of the file.
1086
170
  // Also set the swift version of the context if it didn't have one.
1087
170
  if (!_swiftVersion) {
1088
169
    _swiftVersion = machoFile->swiftVersion();
1089
169
  } else 
if (1
machoFile->swiftVersion()1
&&
1090
1
             machoFile->swiftVersion() != _swiftVersion) {
1091
1
    // Swift versions are different.
1092
1
    return llvm::make_error<GenericError>("different swift versions");
1093
1
  }
1094
169
1095
169
  return llvm::Error::success();
1096
169
}
1097
1098
} // end namespace lld