-
Notifications
You must be signed in to change notification settings - Fork 12.6k
Files
/
Copy pathDriverUtils.cpp
Ignoring revisions in .git-blame-ignore-revs.
1000 lines (893 loc) · 33.5 KB
1
2
//===- DriverUtils.cpp ----------------------------------------------------===//
//
3
4
5
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
7
8
9
10
11
12
13
14
//
//===----------------------------------------------------------------------===//
//
// This file contains utility functions for the driver. Because there
// are so many small functions, we created this separate file to make
// Driver.cpp less cluttered.
//
//===----------------------------------------------------------------------===//
15
#include "COFFLinkerContext.h"
16
#include "Driver.h"
17
#include "Symbols.h"
18
#include "lld/Common/ErrorHandler.h"
19
#include "lld/Common/Memory.h"
20
#include "llvm/ADT/STLExtras.h"
21
#include "llvm/ADT/StringExtras.h"
22
#include "llvm/ADT/StringSwitch.h"
23
#include "llvm/BinaryFormat/COFF.h"
24
#include "llvm/Object/COFF.h"
25
#include "llvm/Object/WindowsResource.h"
26
27
28
29
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/CommandLine.h"
30
#include "llvm/Support/FileUtilities.h"
31
#include "llvm/Support/MathExtras.h"
32
#include "llvm/Support/Process.h"
33
#include "llvm/Support/Program.h"
34
#include "llvm/Support/TimeProfiler.h"
35
#include "llvm/Support/raw_ostream.h"
36
#include "llvm/WindowsManifest/WindowsManifestMerger.h"
37
#include <limits>
38
#include <memory>
39
#include <optional>
40
41
using namespace llvm::COFF;
42
using namespace llvm::opt;
43
44
45
46
47
using namespace llvm;
using llvm::sys::Process;
namespace lld {
namespace coff {
48
49
namespace {
50
51
52
const uint16_t SUBLANG_ENGLISH_US = 0x0409;
const uint16_t RT_MANIFEST = 24;
53
54
class Executor {
public:
55
56
57
58
59
explicit Executor(StringRef s) : prog(saver().save(s)) {}
void add(StringRef s) { args.push_back(saver().save(s)); }
void add(std::string &s) { args.push_back(saver().save(s)); }
void add(Twine s) { args.push_back(saver().save(s)); }
void add(const char *s) { args.push_back(saver().save(s)); }
60
61
void run() {
62
ErrorOr<std::string> exeOrErr = sys::findProgramByName(prog);
63
if (auto ec = exeOrErr.getError())
64
fatal("unable to find " + prog + " in PATH: " + ec.message());
65
StringRef exe = saver().save(*exeOrErr);
66
args.insert(args.begin(), exe);
67
68
if (sys::ExecuteAndWait(args[0], args) != 0)
69
70
fatal("ExecuteAndWait failed: " +
llvm::join(args.begin(), args.end(), " "));
71
72
73
74
}
private:
StringRef prog;
75
std::vector<StringRef> args;
76
77
78
};
} // anonymous namespace
79
80
// Parses a string in the form of "<integer>[,<integer>]".
81
void LinkerDriver::parseNumbers(StringRef arg, uint64_t *addr, uint64_t *size) {
82
auto [s1, s2] = arg.split(',');
83
if (s1.getAsInteger(0, *addr))
84
fatal("invalid number: " + s1);
85
if (size && !s2.empty() && s2.getAsInteger(0, *size))
86
fatal("invalid number: " + s2);
87
88
}
89
90
// Parses a string in the form of "<integer>[.<integer>]".
// If second number is not present, Minor is set to 0.
91
92
void LinkerDriver::parseVersion(StringRef arg, uint32_t *major,
uint32_t *minor) {
93
auto [s1, s2] = arg.split('.');
94
if (s1.getAsInteger(10, *major))
95
fatal("invalid number: " + s1);
96
*minor = 0;
97
if (!s2.empty() && s2.getAsInteger(10, *minor))
98
fatal("invalid number: " + s2);
99
}
100
101
void LinkerDriver::parseGuard(StringRef fullArg) {