Coverage Report

Created: 2018-10-20 12:32

/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
4.06k
static Flavor getFlavor(StringRef S) {
55
4.06k
  return StringSwitch<Flavor>(S)
56
4.06k
      .CasesLower("ld", "ld.lld", "gnu", Gnu)
57
4.06k
      .CasesLower("wasm", "ld-wasm", Wasm)
58
4.06k
      .CaseLower("link", WinLink)
59
4.06k
      .CasesLower("ld64", "ld64.lld", "darwin", Darwin)
60
4.06k
      .Default(Invalid);
61
4.06k
}
62
63
2.64k
static bool isPETarget(const std::vector<const char *> &V) {
64
15.7k
  for (auto It = V.begin(); It + 1 != V.end(); 
++It13.0k
) {
65
13.1k
    if (StringRef(*It) != "-m")
66
13.0k
      continue;
67
101
    StringRef S = *(It + 1);
68
101
    return S == "i386pe" || 
S == "i386pep"94
||
S == "thumb2pe"37
||
S == "arm64pe"35
;
69
101
  }
70
2.64k
  
return false2.54k
;
71
2.64k
}
72
73
3.51k
static Flavor parseProgname(StringRef Progname) {
74
3.51k
#if __APPLE__
75
3.51k
  // Use Darwin driver for "ld" on Darwin.
76
3.51k
  if (Progname == "ld")
77
1
    return Darwin;
78
3.51k
#endif
79
3.51k
80
3.51k
#if LLVM_ON_UNIX
81
3.51k
  // Use GNU driver for "ld" on other Unix-like system.
82
3.51k
  if (Progname == "ld")
83
0
    return Gnu;
84
3.51k
#endif
85
3.51k
86
3.51k
  // Progname may be something like "lld-gnu". Parse it.
87
3.51k
  SmallVector<StringRef, 3> V;
88
3.51k
  Progname.split(V, "-");
89
3.51k
  for (StringRef S : V)
90
4.06k
    if (Flavor F = getFlavor(S))
91
3.51k
      return F;
92
3.51k
  
return Invalid0
;
93
3.51k
}
94
95
3.52k
static Flavor parseFlavor(std::vector<const char *> &V) {
96
3.52k
  // Parse -flavor option.
97
3.52k
  if (V.size() > 1 && 
V[1] == StringRef("-flavor")3.51k
) {
98
2
    if (V.size() <= 2)
99
0
      die("missing arg value for '-flavor'");
100
2
    Flavor F = getFlavor(V[2]);
101
2
    if (F == Invalid)
102
0
      die("Unknown flavor: " + StringRef(V[2]));
103
2
    V.erase(V.begin() + 1, V.begin() + 3);
104
2
    return F;
105
2
  }
106
3.51k
107
3.51k
  // Deduct the flavor from argv[0].
108
3.51k
  StringRef Arg0 = path::filename(V[0]);
109
3.51k
  if (Arg0.endswith_lower(".exe"))
110
0
    Arg0 = Arg0.drop_back(4);
111
3.51k
  return parseProgname(Arg0);
112
3.51k
}
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.45k
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.52k
int main(int Argc, const char **Argv) {
125
3.52k
  InitLLVM X(Argc, Argv);
126
3.52k
127
3.52k
  std::vector<const char *> Args(Argv, Argv + Argc);
128
3.52k
  switch (parseFlavor(Args)) {
129
3.52k
  case Gnu:
130
2.64k
    if (isPETarget(Args))
131
68
      return !mingw::link(Args);
132
2.57k
    return !elf::link(Args, canExitEarly());
133
2.57k
  case WinLink:
134
545
    return !coff::link(Args, canExitEarly());
135
2.57k
  case Darwin:
136
207
    return !mach_o::link(Args, canExitEarly());
137
2.57k
  case Wasm:
138
124
    return !wasm::link(Args, canExitEarly());
139
2.57k
  default:
140
0
    die("lld is a generic driver.\n"
141
0
        "Invoke ld.lld (Unix), ld64.lld (macOS), lld-link (Windows), wasm-ld"
142
0
        " (WebAssembly) instead");
143
3.52k
  }
144
3.52k
}