lld: Include new patches

This commit is contained in:
kamil 2019-11-03 12:11:27 +00:00
parent 81a9535290
commit 34ec844b09
4 changed files with 405 additions and 0 deletions

View file

@ -0,0 +1,135 @@
$NetBSD: patch-tools_lld_lld.cpp,v 1.1 2019/11/03 12:11:27 kamil Exp $
[LLD] Add NetBSD support as a new flavor of LLD (nb.lld)
https://reviews.llvm.org/D69755
--- tools/lld/lld.cpp.orig 2019-07-11 06:12:18.000000000 +0000
+++ tools/lld/lld.cpp
@@ -10,12 +10,13 @@
// function is a thin wrapper which dispatches to the platform specific
// driver.
//
-// lld is a single executable that contains four different linkers for ELF,
-// COFF, WebAssembly and Mach-O. The main function dispatches according to
-// argv[0] (i.e. command name). The most common name for each target is shown
+// lld is a single executable that contains five different linkers for ELF,
+// NetBSD, COFF, WebAssembly and Mach-O. The main function dispatches according
+// to argv[0] (i.e. command name). The most common name for each target is shown
// below:
//
// - ld.lld: ELF (Unix)
+// - nb.lld: ELF (NetBSD)
// - ld64: Mach-O (macOS)
// - lld-link: COFF (Windows)
// - ld-wasm: WebAssembly
@@ -35,6 +36,9 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/Program.h"
+#include "llvm/Support/WithColor.h"
+#include "llvm/Support/raw_ostream.h"
#include <cstdlib>
using namespace lld;
@@ -44,6 +48,7 @@ using namespace llvm::sys;
enum Flavor {
Invalid,
Gnu, // -flavor gnu
+ NetBSD, // -flavor netbsd
WinLink, // -flavor link
Darwin, // -flavor darwin
Wasm, // -flavor wasm
@@ -57,6 +62,7 @@ LLVM_ATTRIBUTE_NORETURN static void die(
static Flavor getFlavor(StringRef s) {
return StringSwitch<Flavor>(s)
.CasesLower("ld", "ld.lld", "gnu", Gnu)
+ .CasesLower("nb.lld", "netbsd", NetBSD)
.CasesLower("wasm", "ld-wasm", Wasm)
.CaseLower("link", WinLink)
.CasesLower("ld64", "ld64.lld", "darwin", Darwin)
@@ -99,10 +105,15 @@ static Flavor parseProgname(StringRef pr
#endif
#if LLVM_ON_UNIX
- // Use GNU driver for "ld" on other Unix-like system.
- if (progname == "ld")
+ // Use GNU or NetBSD driver for "ld" on other Unix-like system.
+ if (progname == "ld") {
+#if defined(__NetBSD__)
+ return NetBSD;
+#else
return Gnu;
#endif
+ }
+#endif
// Progname may be something like "lld-gnu". Parse it.
SmallVector<StringRef, 3> v;
@@ -132,6 +143,38 @@ static Flavor parseFlavor(std::vector<co
return parseProgname(arg0);
}
+// The NetBSD linker flavor will mutate arguments and call the GNU linker.
+static int exec_nb_lld(int argc, const char **argv) {
+ auto Program = sys::findProgramByName("nb.lld");
+ if (!Program) {
+ WithColor::error() << "unable to find `nb.lld' in PATH: "
+ << Program.getError().message() << "\n";
+ return 1;
+ }
+
+ std::vector<StringRef> Argv;
+ Argv.push_back("nb.lld");
+
+ // Trim -flavor option.
+ if (argc > 1 && argv[0] == StringRef("-flavor")) {
+ if (argc <= 2)
+ die("missing arg value for '-flavor'");
+ argc -= 2;
+ argv += 2;
+ }
+
+ for (int i = 0; i < argc; ++i)
+ Argv.push_back(argv[i]);
+
+ std::string ErrMsg;
+ int Result = sys::ExecuteAndWait(*Program, Argv, None, {}, 0, 0, &ErrMsg);
+ if (Result < 0) {
+ WithColor::error() << ErrMsg << "\n";
+ return 1;
+ }
+ return Result;
+}
+
// If this function returns true, lld calls _exit() so that it quickly
// exits without invoking destructors of globally allocated objects.
//
@@ -140,7 +183,7 @@ static Flavor parseFlavor(std::vector<co
// and we use it to detect whether we are running tests or not.
static bool canExitEarly() { return StringRef(getenv("LLD_IN_TEST")) != "1"; }
-/// Universal linker main(). This linker emulates the gnu, darwin, or
+/// Universal linker main(). This linker emulates the gnu, netbsd, darwin, or
/// windows linker based on the argv[0] or -flavor option.
int main(int argc, const char **argv) {
InitLLVM x(argc, argv);
@@ -151,6 +194,8 @@ int main(int argc, const char **argv) {
if (isPETarget(args))
return !mingw::link(args);
return !elf::link(args, canExitEarly());
+ case NetBSD:
+ return exec_nb_lld(argc - 1, argv + 1);
case WinLink:
return !coff::link(args, canExitEarly());
case Darwin:
@@ -159,7 +204,8 @@ int main(int argc, const char **argv) {
return !wasm::link(args, canExitEarly());
default:
die("lld is a generic driver.\n"
- "Invoke ld.lld (Unix), ld64.lld (macOS), lld-link (Windows), wasm-ld"
+ "Invoke ld.lld (Unix), nb.lld (NetBSD), ld64.lld (macOS), lld-link "
+ "(Windows), wasm-ld"
" (WebAssembly) instead");
}
}

View file

@ -0,0 +1,29 @@
$NetBSD: patch-tools_nb.lld_CMakeLists.txt,v 1.1 2019/11/03 12:11:27 kamil Exp $
[LLD] Add NetBSD support as a new flavor of LLD (nb.lld)
https://reviews.llvm.org/D69755
--- tools/nb.lld/CMakeLists.txt.orig 2019-11-03 11:46:29.308376407 +0000
+++ tools/nb.lld/CMakeLists.txt
@@ -0,0 +1,21 @@
+set(LLVM_TARGET_DEFINITIONS Options.td)
+tablegen(LLVM Options.inc -gen-opt-parser-defs)
+add_public_tablegen_target(SLLDOptionsTableGen)
+
+set(LLVM_LINK_COMPONENTS
+ Support
+ Option
+ Target
+ ${LLVM_TARGETS_TO_BUILD}
+ )
+
+add_lld_tool(nb.lld
+ nb.lld.cpp
+
+ DEPENDS
+ SLLDOptionsTableGen
+ )
+
+install(TARGETS nb.lld
+ RUNTIME DESTINATION bin
+ )

View file

@ -0,0 +1,15 @@
$NetBSD: patch-tools_nb.lld_Options.td,v 1.1 2019/11/03 12:11:27 kamil Exp $
[LLD] Add NetBSD support as a new flavor of LLD (nb.lld)
https://reviews.llvm.org/D69755
--- tools/nb.lld/Options.td.orig 2019-11-03 11:46:29.309947085 +0000
+++ tools/nb.lld/Options.td
@@ -0,0 +1,7 @@
+include "llvm/Option/OptParser.td"
+
+class F<string name>: Flag<["--", "-"], name>;
+
+def version: F<"version">, HelpText<"Display the version number and exit">;
+def v: Flag<["-"], "v">, HelpText<"Display the version number">;
+def: Flag<["-"], "V">, Alias<version>, HelpText<"Alias for --version">;

View file

@ -0,0 +1,226 @@
$NetBSD: patch-tools_nb.lld_nb.lld.cpp,v 1.1 2019/11/03 12:11:27 kamil Exp $
[LLD] Add NetBSD support as a new flavor of LLD (nb.lld)
https://reviews.llvm.org/D69755
--- tools/nb.lld/nb.lld.cpp.orig 2019-11-03 11:46:29.311435568 +0000
+++ tools/nb.lld/nb.lld.cpp
@@ -0,0 +1,218 @@
+//===- nb.lld.cpp - NetBSD LLD standalone linker --------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// The NetBSD flavor of LLD.
+//
+// This code wraps the default ELF/UNIX lld variation with NetBSD specific
+// customization.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/Triple.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Option/Option.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/InitLLVM.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Program.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
+#include "llvm/Support/WithColor.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+using namespace llvm::sys;
+
+#define LLD_PROGNAME "ld.lld"
+
+namespace {
+enum ID {
+ OPT_INVALID = 0, // This is not an option ID.
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
+ HELPTEXT, METAVAR, VALUES) \
+ OPT_##ID,
+#include "Options.inc"
+#undef OPTION
+};
+
+#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
+#include "Options.inc"
+#undef PREFIX
+
+const opt::OptTable::Info InfoTable[] = {
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
+ HELPTEXT, METAVAR, VALUES) \
+ { \
+ PREFIX, NAME, HELPTEXT, \
+ METAVAR, OPT_##ID, opt::Option::KIND##Class, \
+ PARAM, FLAGS, OPT_##GROUP, \
+ OPT_##ALIAS, ALIASARGS, VALUES},
+#include "Options.inc"
+#undef OPTION
+};
+
+class SLLDOptTable : public opt::OptTable {
+public:
+ SLLDOptTable() : OptTable(InfoTable) {}
+};
+} // namespace
+
+static Triple targetTriple;
+
+static void setTargetTriple(StringRef argv0, opt::InputArgList &args) {
+ std::string targetError;
+
+ // Firstly, try to get it from program name prefix
+ std::string ProgName = llvm::sys::path::stem(argv0);
+ size_t lastComponent = ProgName.rfind('-');
+ if (lastComponent != std::string::npos) {
+ std::string prefix = ProgName.substr(0, lastComponent);
+ if (llvm::TargetRegistry::lookupTarget(prefix, targetError)) {
+ targetTriple = llvm::Triple(prefix);
+ return;
+ }
+ }
+
+ // Secondly, use the default target triple
+ targetTriple = llvm::Triple(getDefaultTargetTriple());
+}
+
+static void appendSearchPath(std::vector<StringRef> &args, const char *path) {
+ args.push_back("--library-path");
+ args.push_back(path);
+}
+
+static void appendTargetCustomization(std::vector<StringRef> &args) {
+ // force-disable RO segment on NetBSD due to ld.elf_so limitations
+ args.push_back("--no-rosegment");
+
+ // disable superfluous RUNPATH on NetBSD
+ args.push_back("--disable-new-dtags");
+
+ // set default image base address
+ switch (targetTriple.getArch()) {
+ case llvm::Triple::aarch64:
+ case llvm::Triple::aarch64_be:
+ args.push_back("--image-base=0x200100000");
+ break;
+ default:
+ break;
+ }
+
+ // NetBSD driver relies on the linker knowing the default search paths.
+ // Please keep this in sync with clang/lib/Driver/ToolChains/NetBSD.cpp
+ // (NetBSD::NetBSD constructor)
+ switch (targetTriple.getArch()) {
+ case llvm::Triple::x86:
+ appendSearchPath(args, "=/usr/lib/i386");
+ break;
+ case llvm::Triple::arm:
+ case llvm::Triple::armeb:
+ case llvm::Triple::thumb:
+ case llvm::Triple::thumbeb:
+ switch (targetTriple.getEnvironment()) {
+ case llvm::Triple::EABI:
+ case llvm::Triple::GNUEABI:
+ appendSearchPath(args, "=/usr/lib/eabi");
+ break;
+ case llvm::Triple::EABIHF:
+ case llvm::Triple::GNUEABIHF:
+ appendSearchPath(args, "=/usr/lib/eabihf");
+ break;
+ default:
+ appendSearchPath(args, "=/usr/lib/oabi");
+ break;
+ }
+ break;
+#if 0 // TODO
+ case llvm::Triple::mips64:
+ case llvm::Triple::mips64el:
+ if (tools::mips::hasMipsAbiArg(Args, "o32")) {
+ appendSearchPath(args, "=/usr/lib/o32");
+ } else if (tools::mips::hasMipsAbiArg(Args, "64")) {
+ appendSearchPath(args, "=/usr/lib/64");
+ }
+ break;
+#endif
+ case llvm::Triple::ppc:
+ appendSearchPath(args, "=/usr/lib/powerpc");
+ break;
+ case llvm::Triple::sparc:
+ appendSearchPath(args, "=/usr/lib/sparc");
+ break;
+ default:
+ break;
+ }
+
+ appendSearchPath(args, "=/usr/lib");
+}
+
+int main(int argc, const char **argv) {
+ bool printTarget = false;
+
+ InitLLVM X(argc, argv);
+
+ auto Program = sys::findProgramByName(LLD_PROGNAME);
+ if (!Program) {
+ WithColor::error() << "unable to find `" << LLD_PROGNAME
+ << "' in PATH: " << Program.getError().message() << "\n";
+ return 1;
+ }
+
+ ArrayRef<const char *> argsArr = makeArrayRef(argv, argc);
+
+ SLLDOptTable parser;
+ unsigned MAI;
+ unsigned MAC;
+ opt::InputArgList args = parser.ParseArgs(argsArr.slice(1), MAI, MAC);
+
+ // Append to -v or -version the target information from slld.
+ if (args.hasArg(OPT_v) || args.hasArg(OPT_version))
+ printTarget = true;
+
+ InitializeAllTargets();
+ setTargetTriple(argsArr[0], args);
+
+ if (!targetTriple.isOSNetBSD()) {
+ WithColor::error() << "invalid NetBSD target: " << targetTriple.str()
+ << "\n";
+ }
+
+ argc--;
+ argv++;
+
+ std::vector<StringRef> Argv;
+ Argv.push_back(*Program);
+
+ // Prepend original arguments with the target options.
+ appendTargetCustomization(Argv);
+
+ // Append original options.
+ // Trim -flavor option.
+ if (argc > 1 && argv[0] == StringRef("-flavor")) {
+ if (argc <= 2)
+ WithColor::error() << "missing arg value for '-flavor'\n";
+ argc -= 2;
+ argv += 2;
+ }
+
+ for (int i = 0; i < argc; ++i)
+ Argv.push_back(argv[i]);
+
+ std::string ErrMsg;
+ int Result = sys::ExecuteAndWait(*Program, Argv, None, {}, 0, 0, &ErrMsg);
+ if (Result < 0) {
+ WithColor::error() << ErrMsg << "\n";
+ return 1;
+ }
+
+ if (printTarget)
+ WithColor::note() << "Target: " << targetTriple.str() << "\n";
+
+ return Result;
+}