summaryrefslogtreecommitdiff
path: root/lld/COFF/DriverUtils.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-07-26 19:36:28 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-07-26 19:36:28 +0000
commitcfca06d7963fa0909f90483b42a6d7d194d01e08 (patch)
tree209fb2a2d68f8f277793fc8df46c753d31bc853b /lld/COFF/DriverUtils.cpp
parent706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff)
Notes
Diffstat (limited to 'lld/COFF/DriverUtils.cpp')
-rw-r--r--lld/COFF/DriverUtils.cpp67
1 files changed, 39 insertions, 28 deletions
diff --git a/lld/COFF/DriverUtils.cpp b/lld/COFF/DriverUtils.cpp
index 301a5c5efa8a..6cb761abea4e 100644
--- a/lld/COFF/DriverUtils.cpp
+++ b/lld/COFF/DriverUtils.cpp
@@ -220,7 +220,8 @@ void parseAligncomm(StringRef s) {
error("/aligncomm: invalid argument: " + s);
return;
}
- config->alignComm[name] = std::max(config->alignComm[name], 1 << v);
+ config->alignComm[std::string(name)] =
+ std::max(config->alignComm[std::string(name)], 1 << v);
}
// Parses /functionpadmin option argument.
@@ -318,7 +319,7 @@ public:
SmallString<128> s;
if (auto ec = sys::fs::createTemporaryFile("lld-" + prefix, extn, s))
fatal("cannot create a temporary file: " + ec.message());
- path = s.str();
+ path = std::string(s.str());
if (!contents.empty()) {
std::error_code ec;
@@ -403,7 +404,7 @@ static std::string createManifestXmlWithInternalMt(StringRef defaultXml) {
toString(std::move(e)));
}
- return merger.getMergedManifest().get()->getBuffer();
+ return std::string(merger.getMergedManifest().get()->getBuffer());
}
static std::string createManifestXmlWithExternalMt(StringRef defaultXml) {
@@ -431,9 +432,10 @@ static std::string createManifestXmlWithExternalMt(StringRef defaultXml) {
e.add("/out:" + StringRef(user.path));
e.run();
- return CHECK(MemoryBuffer::getFile(user.path), "could not open " + user.path)
- .get()
- ->getBuffer();
+ return std::string(
+ CHECK(MemoryBuffer::getFile(user.path), "could not open " + user.path)
+ .get()
+ ->getBuffer());
}
static std::string createManifestXml() {
@@ -507,7 +509,7 @@ std::unique_ptr<MemoryBuffer> createManifestRes() {
}
void createSideBySideManifest() {
- std::string path = config->manifestFile;
+ std::string path = std::string(config->manifestFile);
if (path == "")
path = config->outputFile + ".manifest";
std::error_code ec;
@@ -765,6 +767,8 @@ static const llvm::opt::OptTable::Info infoTable[] = {
COFFOptTable::COFFOptTable() : OptTable(infoTable, true) {}
+COFFOptTable optTable;
+
// Set color diagnostics according to --color-diagnostics={auto,always,never}
// or --no-color-diagnostics flags.
static void handleColorDiagnostics(opt::InputArgList &args) {
@@ -810,8 +814,7 @@ opt::InputArgList ArgParser::parse(ArrayRef<const char *> argv) {
// options so we parse here before and ignore all the options but
// --rsp-quoting and /lldignoreenv.
// (This means --rsp-quoting can't be added through %LINK%.)
- opt::InputArgList args = table.ParseArgs(argv, missingIndex, missingCount);
-
+ opt::InputArgList args = optTable.ParseArgs(argv, missingIndex, missingCount);
// Expand response files (arguments in the form of @<filename>) and insert
// flags from %LINK% and %_LINK_%, and then parse the argument again.
@@ -820,8 +823,8 @@ opt::InputArgList ArgParser::parse(ArrayRef<const char *> argv) {
if (!args.hasArg(OPT_lldignoreenv))
addLINK(expandedArgv);
cl::ExpandResponseFiles(saver, getQuotingStyle(args), expandedArgv);
- args = table.ParseArgs(makeArrayRef(expandedArgv).drop_front(), missingIndex,
- missingCount);
+ args = optTable.ParseArgs(makeArrayRef(expandedArgv).drop_front(),
+ missingIndex, missingCount);
// Print the real command line if response files are expanded.
if (args.hasArg(OPT_verbose) && argv.size() != expandedArgv.size()) {
@@ -845,7 +848,7 @@ opt::InputArgList ArgParser::parse(ArrayRef<const char *> argv) {
for (auto *arg : args.filtered(OPT_UNKNOWN)) {
std::string nearest;
- if (table.findNearest(arg->getAsString(args), nearest) > 1)
+ if (optTable.findNearest(arg->getAsString(args), nearest) > 1)
warn("ignoring unknown argument '" + arg->getAsString(args) + "'");
else
warn("ignoring unknown argument '" + arg->getAsString(args) +
@@ -859,30 +862,38 @@ opt::InputArgList ArgParser::parse(ArrayRef<const char *> argv) {
}
// Tokenizes and parses a given string as command line in .drective section.
-// /EXPORT options are processed in fastpath.
-std::pair<opt::InputArgList, std::vector<StringRef>>
-ArgParser::parseDirectives(StringRef s) {
- std::vector<StringRef> exports;
+ParsedDirectives ArgParser::parseDirectives(StringRef s) {
+ ParsedDirectives result;
SmallVector<const char *, 16> rest;
- for (StringRef tok : tokenize(s)) {
+ // Handle /EXPORT and /INCLUDE in a fast path. These directives can appear for
+ // potentially every symbol in the object, so they must be handled quickly.
+ SmallVector<StringRef, 16> tokens;
+ cl::TokenizeWindowsCommandLineNoCopy(s, saver, tokens);
+ for (StringRef tok : tokens) {
if (tok.startswith_lower("/export:") || tok.startswith_lower("-export:"))
- exports.push_back(tok.substr(strlen("/export:")));
- else
- rest.push_back(tok.data());
+ result.exports.push_back(tok.substr(strlen("/export:")));
+ else if (tok.startswith_lower("/include:") ||
+ tok.startswith_lower("-include:"))
+ result.includes.push_back(tok.substr(strlen("/include:")));
+ else {
+ // Save non-null-terminated strings to make proper C strings.
+ bool HasNul = tok.data()[tok.size()] == '\0';
+ rest.push_back(HasNul ? tok.data() : saver.save(tok).data());
+ }
}
// Make InputArgList from unparsed string vectors.
unsigned missingIndex;
unsigned missingCount;
- opt::InputArgList args = table.ParseArgs(rest, missingIndex, missingCount);
+ result.args = optTable.ParseArgs(rest, missingIndex, missingCount);
if (missingCount)
- fatal(Twine(args.getArgString(missingIndex)) + ": missing argument");
- for (auto *arg : args.filtered(OPT_UNKNOWN))
- warn("ignoring unknown argument: " + arg->getAsString(args));
- return {std::move(args), std::move(exports)};
+ fatal(Twine(result.args.getArgString(missingIndex)) + ": missing argument");
+ for (auto *arg : result.args.filtered(OPT_UNKNOWN))
+ warn("ignoring unknown argument: " + arg->getAsString(result.args));
+ return result;
}
// link.exe has an interesting feature. If LINK or _LINK_ environment
@@ -907,9 +918,9 @@ std::vector<const char *> ArgParser::tokenize(StringRef s) {
}
void printHelp(const char *argv0) {
- COFFOptTable().PrintHelp(lld::outs(),
- (std::string(argv0) + " [options] file...").c_str(),
- "LLVM Linker", false);
+ optTable.PrintHelp(lld::outs(),
+ (std::string(argv0) + " [options] file...").c_str(),
+ "LLVM Linker", false);
}
} // namespace coff