Coverage Report

Created: 2018-08-19 21:11

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/lld/tools/lld/lld.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- tools/lld/lld.cpp - Linker Driver Dispatcher -----------------------===//
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
// This file contains the main function of the lld executable. The main
11
// function is a thin wrapper which dispatches to the platform specific
12
// driver.
13
//
14
// lld is a single executable that contains four different linkers for ELF,
15
// COFF, WebAssembly and Mach-O. The main function dispatches according to
16
// argv[0] (i.e. command name). The most common name for each target is shown
17
// below:
18
//
19
//  - ld.lld:    ELF (Unix)
20
//  - ld64:      Mach-O (macOS)
21
//  - lld-link:  COFF (Windows)
22
//  - ld-wasm:   WebAssembly
23
//
24
// lld can be invoked as "lld" along with "-flavor" option. This is for
25
// backward compatibility and not recommended.
26
//
27
//===----------------------------------------------------------------------===//
28
29
#include "lld/Common/Driver.h"
30
#include "llvm/ADT/STLExtras.h"
31
#include "llvm/ADT/StringSwitch.h"
32
#include "llvm/ADT/Twine.h"
33
#include "llvm/Support/InitLLVM.h"
34
#include "llvm/Support/Path.h"
35
#include <cstdlib>
36
37
using namespace lld;
38
using namespace llvm;
39
using namespace llvm::sys;
40
41
enum Flavor {
42
  Invalid,
43
  Gnu,     // -flavor gnu
44
  WinLink, // -flavor link
45
  Darwin,  // -flavor darwin
46
  Wasm,    // -flavor wasm
47
};
48
49
0
LLVM_ATTRIBUTE_NORETURN static void die(const Twine &S) {
50
0
  errs() << S << "\n";
51
0
  exit(1);
52
0
}
53
54
3.65k
static Flavor getFlavor(StringRef S) {
55
3.65k
  return StringSwitch<Flavor>(S)
56
3.65k
      .CasesLower("ld", "ld.lld", "gnu", Gnu)
57
3.65k
      .CasesLower("wasm", "ld-wasm", Wasm)
58
3.65k
      .CaseLower("link", WinLink)
59
3.65k
      .CasesLower("ld64", "ld64.lld", "darwin", Darwin)
60
3.65k
      .Default(Invalid);
61
3.65k
}
62
63
2.54k
static bool isPETarget(const std::vector<const char *> &V) {
64
15.0k
  for (auto It = V.begin(); It + 1 != V.end(); 
++It12.5k
) {
65
12.6k
    if (StringRef(*It) != "-m")
66
12.5k
      continue;
67
98
    StringRef S = *(It + 1);
68
98
    return S == "i386pe" || 
S == "i386pep"92
||
S == "thumb2pe"36
||
S == "arm64pe"34
;
69
98
  }
70
2.54k
  
return false2.45k
;
71
2.54k
}
72
73
3.20k
static Flavor parseProgname(StringRef Progname) {
74
3.20k
#if __APPLE__
75
3.20k
  // Use Darwin driver for "ld" on Darwin.
76
3.20k
  if (Progname == "ld")
77
1
    return Darwin;
78
3.20k
#endif
79
3.20k
80
3.20k
#if LLVM_ON_UNIX
81
3.20k
  // Use GNU driver for "ld" on other Unix-like system.
82
3.20k
  if (Progname == "ld")
83
0
    return Gnu;
84
3.20k
#endif
85
3.20k
86
3.20k
  // Progname may be something like "lld-gnu". Parse it.
87
3.20k
  SmallVector<StringRef, 3> V;
88
3.20k
  Progname.split(V, "-");
89
3.20k
  for (StringRef S : V)
90
3.65k
    if (Flavor F = getFlavor(S))
91
3.20k
      return F;
92
3.20k
  
return Invalid0
;
93
3.20k
}
94
95
3.20k
static Flavor parseFlavor(std::vector<const char *> &V) {
96
3.20k
  // Parse -flavor option.
97
3.20k
  if (V.size() > 1 && 
V[1] == StringRef("-flavor")3.20k
) {
98
0
    if (V.size() <= 2)
99
0
      die("missing arg value for '-flavor'");
100
0
    Flavor F = getFlavor(V[2]);
101
0
    if (F == Invalid)
102
0
      die("Unknown flavor: " + StringRef(V[2]));
103
0
    V.erase(V.begin() + 1, V.begin() + 3);
104
0
    return F;
105
0
  }
106
3.20k
107
3.20k
  // Deduct the flavor from argv[0].
108
3.20k
  StringRef Arg0 = path::filename(V[0]);
109
3.20k
  if (Arg0.endswith_lower(".exe"))
110
0
    Arg0 = Arg0.drop_back(4);
111
3.20k
  return parseProgname(Arg0);
112
3.20k
}
113
114
// If this function returns true, lld calls _exit() so that it quickly
115
// exits without invoking destructors of globally allocated objects.
116
//
117
// We don't want to do that if we are running tests though, because
118
// doing that breaks leak sanitizer. So, lit sets this environment variable,
119
// and we use it to detect whether we are running tests or not.
120
3.14k
static bool canExitEarly() { return StringRef(getenv("LLD_IN_TEST")) != "1"; }
121
122
/// Universal linker main(). This linker emulates the gnu, darwin, or
123
/// windows linker based on the argv[0] or -flavor option.
124
3.20k
int main(int Argc, const char **Argv) {
125
3.20k
  InitLLVM X(Argc, Argv);
126
3.20k
127
3.20k
  std::vector<const char *> Args(Argv, Argv + Argc);
128
3.20k
  switch (parseFlavor(Args)) {
129
3.20k
  case Gnu:
130
2.54k
    if (isPETarget(Args))
131
66
      return !mingw::link(Args);
132
2.48k
    return !elf::link(Args, canExitEarly());
133
2.48k
  case WinLink:
134
450
    return !coff::link(Args, canExitEarly());
135
2.48k
  case Darwin:
136
207
    return !mach_o::link(Args, canExitEarly());
137
2.48k
  case Wasm:
138
0
    return !wasm::link(Args, canExitEarly());
139
2.48k
  default:
140
0
    die("lld is a generic driver.\n"
141
0
        "Invoke ld.lld (Unix), ld64.lld (macOS), lld-link (Windows), wasm-lld"
142
0
        " (WebAssembly) instead");
143
3.20k
  }
144
3.20k
}