From 808dcadd650fd54174a0c033547a6668bf77e4f1 Mon Sep 17 00:00:00 2001 From: Martell Malone 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 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 LinkerDriver::findFile(StringRef Filename) { @@ -452,6 +478,9 @@ void LinkerDriver::link(llvm::ArrayRef ArgsArr) { // for /defaultlib option. std::vector Paths; std::vector MBs; + for (auto *Arg : Args.filtered(OPT_l)) + if (Optional Path = searchLibrary(Arg->getValue())) + Paths.push_back(*Path); for (auto *Arg : Args.filtered(OPT_INPUT)) if (Optional Path = findFile(Arg->getValue())) Paths.push_back(*Path); @@ -573,7 +602,7 @@ void LinkerDriver::link(llvm::ArrayRef 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; +def L : Joined<["-"], "L">, Alias; +def e : Separate<["-"], "e">, Alias; +def subs : Separate<["--"], "subsystem">, Alias; + +def l : JoinedOrSeparate<["-"], "l">, MetaVarName<"">; + +// 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<"">, + 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 &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 Args(Argv, Argv + Argc); + if (isPETarget(Args)) + return !coff::link(Args); + switch (parseFlavor(Args)) { case Gnu: return !elf::link(Args); -- 2.7.4