177 lines
5.8 KiB
Diff
177 lines
5.8 KiB
Diff
From d2b8d30134e620ec5d36be0765e52c7bf9bc57d6 Mon Sep 17 00:00:00 2001
|
|
From: Martell Malone <martellmalone@gmail.com>
|
|
Date: Wed, 28 Oct 2015 19:32:16 +0000
|
|
Subject: [PATCH 1/2] add support for gnu arguments in lld coff
|
|
|
|
---
|
|
COFF/Driver.cpp | 31 ++++++++++++++++++++++++++++++-
|
|
COFF/Driver.h | 3 +++
|
|
COFF/DriverUtils.cpp | 2 +-
|
|
COFF/Options.td | 20 ++++++++++++++++++++
|
|
tools/lld/lld.cpp | 21 +++++++++++++++++++++
|
|
5 files changed, 75 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/COFF/Driver.cpp b/COFF/Driver.cpp
|
|
index 4dabd9e..4992296 100644
|
|
--- a/COFF/Driver.cpp
|
|
+++ b/COFF/Driver.cpp
|
|
@@ -232,6 +232,7 @@ void LinkerDriver::parseDirectives(StringRef S) {
|
|
case OPT_fastfail:
|
|
case OPT_guardsym:
|
|
case OPT_throwingnew:
|
|
+ case OPT_aligncomm:
|
|
break;
|
|
default:
|
|
fatal(Arg->getSpelling() + " is not allowed in .drectve");
|
|
@@ -260,6 +261,31 @@ StringRef LinkerDriver::doFindFile(StringRef Filename) {
|
|
return Filename;
|
|
}
|
|
|
|
+// Searches a given library from input search paths, which are filled
|
|
+// from -L command line switches. Returns a path to an existent library file.
|
|
+StringRef LinkerDriver::searchLibrary(StringRef Filename) {
|
|
+
|
|
+ std::vector<std::string> Names;
|
|
+ if (Filename[0] == ':') {
|
|
+ Names.push_back(Filename.drop_front());
|
|
+ } else {
|
|
+ //if (!Config->Static)
|
|
+ Names.push_back(("lib" + Filename + ".dll.a").str());
|
|
+ Names.push_back(("lib" + Filename + ".a").str());
|
|
+ }
|
|
+
|
|
+ for (const std::string &Name : Names) {
|
|
+ for (StringRef Dir : SearchPaths) {
|
|
+ SmallString<128> Path = Dir;
|
|
+ llvm::sys::path::append(Path, Name.c_str());
|
|
+ if (llvm::sys::fs::exists(Path.str()))
|
|
+ return Saver.save(Path.str());
|
|
+ }
|
|
+ }
|
|
+ fatal("Unable to find library -l" + Filename);
|
|
+ return "";
|
|
+}
|
|
+
|
|
// Resolves a file path. This never returns the same path
|
|
// (in that case, it returns None).
|
|
Optional<StringRef> LinkerDriver::findFile(StringRef Filename) {
|
|
@@ -667,6 +693,9 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
|
|
for (auto *Arg : Args.filtered(OPT_defaultlib))
|
|
if (Optional<StringRef> Path = findLib(Arg->getValue()))
|
|
enqueuePath(*Path);
|
|
+ for (auto *Arg : Args.filtered(OPT_l))
|
|
+ if (Optional<StringRef> Path = searchLibrary(Arg->getValue()))
|
|
+ enqueuePath(*Path);
|
|
|
|
// Windows specific -- Create a resource file containing a manifest file.
|
|
if (Config->Manifest == Configuration::Embed)
|
|
@@ -753,7 +782,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
|
|
if (Config->ImageBase == uint64_t(-1))
|
|
Config->ImageBase = getDefaultImageBase();
|
|
|
|
- Symtab.addRelative(mangle("__ImageBase"), 0);
|
|
+ Symtab.addRelative(mangle("__image_base__"), 0);
|
|
if (Config->Machine == I386) {
|
|
Config->SEHTable = Symtab.addRelative("___safe_se_handler_table", 0);
|
|
Config->SEHCount = Symtab.addAbsolute("___safe_se_handler_count", 0);
|
|
diff --git a/COFF/Driver.h b/COFF/Driver.h
|
|
index 4489426..d293014 100644
|
|
--- a/COFF/Driver.h
|
|
+++ b/COFF/Driver.h
|
|
@@ -86,6 +86,9 @@ private:
|
|
StringRef doFindFile(StringRef Filename);
|
|
StringRef doFindLib(StringRef Filename);
|
|
|
|
+ // Searches for a gnu library
|
|
+ StringRef searchLibrary(StringRef Path);
|
|
+
|
|
// Parses LIB environment which contains a list of search paths.
|
|
void addLibSearchPaths();
|
|
|
|
diff --git a/COFF/DriverUtils.cpp b/COFF/DriverUtils.cpp
|
|
index 14dd004..f5f3d6d 100644
|
|
--- a/COFF/DriverUtils.cpp
|
|
+++ b/COFF/DriverUtils.cpp
|
|
@@ -637,7 +637,7 @@ static const llvm::opt::OptTable::Info infoTable[] = {
|
|
|
|
class COFFOptTable : public llvm::opt::OptTable {
|
|
public:
|
|
- COFFOptTable() : OptTable(infoTable, true) {}
|
|
+ COFFOptTable() : OptTable(infoTable) {}
|
|
};
|
|
|
|
// Parses a given list of options.
|
|
diff --git a/COFF/Options.td b/COFF/Options.td
|
|
index 9dfbcc8..b3b30a3 100644
|
|
--- a/COFF/Options.td
|
|
+++ b/COFF/Options.td
|
|
@@ -99,6 +99,26 @@ def dumppdb : Joined<["/", "-"], "dumppdb">;
|
|
def lldmap : F<"lldmap">;
|
|
def lldmap_file : Joined<["/", "-"], "lldmap:">;
|
|
|
|
+
|
|
+def output : Separate<["-"], "o">, Alias<out>;
|
|
+def L : Joined<["-"], "L">, Alias<libpath>;
|
|
+def e : Separate<["-"], "e">, Alias<entry>;
|
|
+def subs : Separate<["--"], "subsystem">, Alias<subsystem>;
|
|
+
|
|
+def l : JoinedOrSeparate<["-"], "l">, MetaVarName<"<libName>">;
|
|
+
|
|
+// Used to silence some gnu warnings
|
|
+def aligncomm : P<"aligncomm", "Comm Alignment">;
|
|
+def Bdynamic: Flag<["-"], "Bdynamic">;
|
|
+
|
|
+// Used to override gnu pe targets
|
|
+def m : Separate<["-"], "m">, MetaVarName<"<emulation>">,
|
|
+ HelpText<"Select target emulation">;
|
|
+
|
|
+// Select an optional flavor
|
|
+def flavor: Separate<["-"], "flavor">,
|
|
+ HelpText<"Flavor for linking, options are gnu/darwin/link">;
|
|
+
|
|
//==============================================================================
|
|
// The flags below do nothing. They are defined only for link.exe compatibility.
|
|
//==============================================================================
|
|
diff --git a/tools/lld/lld.cpp b/tools/lld/lld.cpp
|
|
index 0c32ff1..5bd823a 100644
|
|
--- a/tools/lld/lld.cpp
|
|
+++ b/tools/lld/lld.cpp
|
|
@@ -49,6 +49,24 @@ static Flavor getFlavor(StringRef S) {
|
|
.Default(Invalid);
|
|
}
|
|
|
|
+static bool isPETarget(const std::vector<const char *> &V) {
|
|
+ for (auto It = V.begin(); It != V.end(); It++) {
|
|
+ if (*It == StringRef("-m")) {
|
|
+ It++;
|
|
+ if (It == V.end())
|
|
+ return false;
|
|
+ if (*It == StringRef("i386pe"))
|
|
+ return true;
|
|
+ if (*It == StringRef("i386pep"))
|
|
+ return true;
|
|
+ if (*It == StringRef("thumb2pe"))
|
|
+ return true;
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+ return false;
|
|
+}
|
|
+
|
|
static Flavor parseProgname(StringRef Progname) {
|
|
#if __APPLE__
|
|
// Use Darwin driver for "ld" on Darwin.
|
|
@@ -99,6 +117,9 @@ int main(int Argc, const char **Argv) {
|
|
llvm_shutdown_obj Shutdown;
|
|
|
|
std::vector<const char *> Args(Argv, Argv + Argc);
|
|
+ if (isPETarget(Args))
|
|
+ return !coff::link(Args);
|
|
+
|
|
switch (parseFlavor(Args)) {
|
|
case Gnu:
|
|
return !elf::link(Args, true);
|
|
--
|
|
2.7.4
|
|
|