Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/lld/MinGW/Driver.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- MinGW/Driver.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
/// GNU ld style linker driver for COFF currently supporting mingw-w64.
11
///
12
//===----------------------------------------------------------------------===//
13
14
#include "lld/Driver/Driver.h"
15
#include "llvm/ADT/ArrayRef.h"
16
#include "llvm/ADT/Optional.h"
17
#include "llvm/ADT/StringExtras.h"
18
#include "llvm/ADT/StringRef.h"
19
#include "llvm/Option/Arg.h"
20
#include "llvm/Option/ArgList.h"
21
#include "llvm/Option/Option.h"
22
#include "llvm/Support/CommandLine.h"
23
#include "llvm/Support/FileSystem.h"
24
#include "llvm/Support/Path.h"
25
26
#if !defined(_MSC_VER) && !defined(__MINGW32__)
27
#include <unistd.h>
28
#endif
29
30
using namespace lld;
31
using namespace llvm;
32
33
2
LLVM_ATTRIBUTE_NORETURN static void error(const Twine &Msg) {
34
2
  errs() << Msg << "\n";
35
2
  exit(1);
36
2
}
37
38
// Create OptTable
39
enum {
40
  OPT_INVALID = 0,
41
#define OPTION(_1, _2, ID, _4, _5, _6, _7, _8, _9, _10, _11, _12) OPT_##ID,
42
#include "Options.inc"
43
#undef OPTION
44
};
45
46
// Create prefix string literals used in Options.td
47
#define PREFIX(NAME, VALUE) static const char *const NAME[] = VALUE;
48
#include "Options.inc"
49
#undef PREFIX
50
51
// Create table mapping all options defined in Options.td
52
static const opt::OptTable::Info InfoTable[] = {
53
#define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12)      \
54
  {X1, X2, X10,         X11,         OPT_##ID, opt::Option::KIND##Class,       \
55
   X9, X8, OPT_##GROUP, OPT_##ALIAS, X7,       X12},
56
#include "Options.inc"
57
#undef OPTION
58
};
59
60
namespace {
61
class MinGWOptTable : public opt::OptTable {
62
public:
63
31
  MinGWOptTable() : OptTable(InfoTable, false) {}
64
  opt::InputArgList parse(ArrayRef<const char *> Argv);
65
};
66
} // namespace
67
68
31
opt::InputArgList MinGWOptTable::parse(ArrayRef<const char *> Argv) {
69
31
  unsigned MissingIndex;
70
31
  unsigned MissingCount;
71
31
72
31
  SmallVector<const char *, 256> Vec(Argv.data(), Argv.data() + Argv.size());
73
31
  opt::InputArgList Args = this->ParseArgs(Vec, MissingIndex, MissingCount);
74
31
75
31
  if (MissingCount)
76
0
    error(StringRef(Args.getArgString(MissingIndex)) + ": missing argument");
77
31
  for (auto *Arg : Args.filtered(OPT_UNKNOWN))
78
0
    error("unknown argument: " + Arg->getSpelling());
79
31
  
if (31
!Args.hasArg(OPT_INPUT) && 31
!Args.hasArg(OPT_l)5
)
80
0
    error("no input files");
81
31
  return Args;
82
31
}
83
84
// Find a file by concatenating given paths.
85
7
static Optional<std::string> findFile(StringRef Path1, const Twine &Path2) {
86
7
  SmallString<128> S;
87
7
  sys::path::append(S, Path1, Path2);
88
7
  if (sys::fs::exists(S))
89
4
    return S.str().str();
90
3
  return None;
91
3
}
92
93
// This is for -lfoo. We'll look for libfoo.dll.a or libfoo.a from search paths.
94
static std::string
95
6
searchLibrary(StringRef Name, ArrayRef<StringRef> SearchPaths, bool BStatic) {
96
6
  if (
Name.startswith(":")6
) {
97
0
    for (StringRef Dir : SearchPaths)
98
0
      
if (Optional<std::string> 0
S0
= findFile(Dir, Name.substr(1)))
99
0
        return *S;
100
0
    error("unable to find library -l" + Name);
101
0
  }
102
6
103
6
  
for (StringRef Dir : SearchPaths) 6
{
104
6
    if (!BStatic)
105
3
      
if (Optional<std::string> 3
S3
= findFile(Dir, "lib" + Name + ".dll.a"))
106
2
        return *S;
107
4
    
if (Optional<std::string> 4
S4
= findFile(Dir, "lib" + Name + ".a"))
108
2
      return *S;
109
2
  }
110
2
  error("unable to find library -l" + Name);
111
2
}
112
113
// Convert Unix-ish command line arguments to Windows-ish ones and
114
// then call coff::link.
115
31
bool mingw::link(ArrayRef<const char *> ArgsArr, raw_ostream &Diag) {
116
31
  MinGWOptTable Parser;
117
31
  opt::InputArgList Args = Parser.parse(ArgsArr.slice(1));
118
31
119
31
  std::vector<std::string> LinkArgs;
120
210
  auto Add = [&](const Twine &S) { LinkArgs.push_back(S.str()); };
121
31
122
31
  Add("lld-link");
123
31
  Add("-lldmingw");
124
31
125
31
  if (auto *
A31
= Args.getLastArg(OPT_entry)) {
126
4
    StringRef S = A->getValue();
127
4
    if (
Args.getLastArgValue(OPT_m) == "i386pe" && 4
S.startswith("_")1
)
128
1
      Add("-entry:" + S.substr(1));
129
4
    else
130
3
      Add("-entry:" + S);
131
4
  }
132
31
133
31
  if (auto *A = Args.getLastArg(OPT_subs))
134
2
    Add("-subsystem:" + StringRef(A->getValue()));
135
31
  if (auto *A = Args.getLastArg(OPT_out_implib))
136
1
    Add("-implib:" + StringRef(A->getValue()));
137
31
  if (auto *A = Args.getLastArg(OPT_stack))
138
2
    Add("-stack:" + StringRef(A->getValue()));
139
31
140
31
  if (auto *A = Args.getLastArg(OPT_o))
141
3
    Add("-out:" + StringRef(A->getValue()));
142
28
  else 
if (28
Args.hasArg(OPT_shared)28
)
143
5
    Add("-out:a.dll");
144
28
  else
145
23
    Add("-out:a.exe");
146
31
147
31
  if (Args.hasArg(OPT_shared))
148
5
    Add("-dll");
149
31
  if (Args.hasArg(OPT_verbose))
150
2
    Add("-verbose");
151
31
152
31
  if (auto *
A31
= Args.getLastArg(OPT_m)) {
153
31
    StringRef S = A->getValue();
154
31
    if (S == "i386pe")
155
2
      Add("-machine:x86");
156
29
    else 
if (29
S == "i386pep"29
)
157
27
      Add("-machine:x64");
158
2
    else 
if (2
S == "thumb2pe"2
)
159
1
      Add("-machine:arm");
160
1
    else 
if (1
S == "arm64pe"1
)
161
1
      Add("-machine:arm64");
162
1
    else
163
0
      error("unknown parameter: -m" + S);
164
31
  }
165
31
166
31
  for (auto *A : Args.filtered(OPT_mllvm))
167
2
    Add("-mllvm:" + StringRef(A->getValue()));
168
31
169
31
  if (Args.getLastArgValue(OPT_m) == "i386pe")
170
2
    Add("-alternatename:__image_base__=___ImageBase");
171
31
  else
172
29
    Add("-alternatename:__image_base__=__ImageBase");
173
31
174
31
  std::vector<StringRef> SearchPaths;
175
31
  for (auto *A : Args.filtered(OPT_L))
176
5
    SearchPaths.push_back(A->getValue());
177
31
178
31
  StringRef Prefix = "";
179
31
  bool Static = false;
180
164
  for (auto *A : Args) {
181
164
    switch (A->getOption().getUnaliasedOption().getID()) {
182
33
    case OPT_INPUT:
183
33
      if (StringRef(A->getValue()).endswith_lower(".def"))
184
2
        Add("-def:" + StringRef(A->getValue()));
185
33
      else
186
31
        Add(Prefix + StringRef(A->getValue()));
187
33
      break;
188
6
    case OPT_l:
189
6
      Add(Prefix + searchLibrary(A->getValue(), SearchPaths, Static));
190
6
      break;
191
2
    case OPT_whole_archive:
192
2
      Prefix = "-wholearchive:";
193
2
      break;
194
2
    case OPT_no_whole_archive:
195
2
      Prefix = "";
196
2
      break;
197
3
    case OPT_Bstatic:
198
3
      Static = true;
199
3
      break;
200
1
    case OPT_Bdynamic:
201
1
      Static = false;
202
1
      break;
203
29
    }
204
29
  }
205
29
206
29
  
if (29
Args.hasArg(OPT_verbose) || 29
Args.hasArg(OPT__HASH_HASH_HASH)27
)
207
29
    outs() << llvm::join(LinkArgs, " ") << "\n";
208
29
209
29
  if (Args.hasArg(OPT__HASH_HASH_HASH))
210
29
    return true;
211
0
212
0
  // Repack vector of strings to vector of const char pointers for coff::link.
213
0
  std::vector<const char *> Vec;
214
0
  for (const std::string &S : LinkArgs)
215
0
    Vec.push_back(S.c_str());
216
31
  return coff::link(Vec);
217
31
}