Files
llvm-mingw/patches/lld-0001.patch
T
Martin Storsjö 93a77a441a Update patches for lld 3.9
The previously existing patch needed some modifications to fit
on top of lld 3.9.

Patch 2 makes sure that one still can use the lld built in this
way for linking in MSVC mode.

Patch 3 fixes linking binaries larger than 4 MB or so (previously
the binaries linked fine but didn't work).

Patch 4 makes sure to error out if the relocations are too far
away (instead of producing a broken binary), which happens after
16 MB.

Patch 5 fixes relocations that have an offset, which probably
happens in hand-written assembly (in libav).
2016-08-10 14:52:16 +03:00

177 lines
5.8 KiB
Diff

From 808dcadd650fd54174a0c033547a6668bf77e4f1 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/5] 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 bb6a60e..0821591 100644
--- a/COFF/Driver.cpp
+++ b/COFF/Driver.cpp
@@ -125,6 +125,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");
@@ -153,6 +154,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 Alloc.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) {
@@ -452,6 +478,9 @@ void LinkerDriver::link(llvm::ArrayRef<const char *> ArgsArr) {
// for /defaultlib option.
std::vector<StringRef> Paths;
std::vector<MemoryBufferRef> MBs;
+ for (auto *Arg : Args.filtered(OPT_l))
+ if (Optional<StringRef> Path = searchLibrary(Arg->getValue()))
+ Paths.push_back(*Path);
for (auto *Arg : Args.filtered(OPT_INPUT))
if (Optional<StringRef> Path = findFile(Arg->getValue()))
Paths.push_back(*Path);
@@ -573,7 +602,7 @@ void LinkerDriver::link(llvm::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 23969ee..230ec35 100644
--- a/COFF/Driver.h
+++ b/COFF/Driver.h
@@ -84,6 +84,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 5d7dc2b..e2f1f2d 100644
--- a/COFF/DriverUtils.cpp
+++ b/COFF/DriverUtils.cpp
@@ -591,7 +591,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 e5c9c5b..322b162 100644
--- a/COFF/Options.td
+++ b/COFF/Options.td
@@ -93,6 +93,26 @@ def nosymtab : F<"nosymtab">;
// Flags for debugging
def lldmap : 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 8805e02..68c8735 100644
--- a/tools/lld/lld.cpp
+++ b/tools/lld/lld.cpp
@@ -51,6 +51,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.
@@ -101,6 +119,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);
--
2.7.4