krytarowski updated this revision to Diff 227593.
krytarowski added a comment.

- upload diff with wider context


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69755/new/

https://reviews.llvm.org/D69755

Files:
  clang/lib/Driver/ToolChain.cpp
  lld/CMakeLists.txt
  lld/tools/lld/lld.cpp
  lld/tools/nb.lld/CMakeLists.txt
  lld/tools/nb.lld/Options.td
  lld/tools/nb.lld/nb.lld.cpp

Index: lld/tools/nb.lld/nb.lld.cpp
===================================================================
--- /dev/null
+++ lld/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;
+}
Index: lld/tools/nb.lld/Options.td
===================================================================
--- /dev/null
+++ lld/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">;
Index: lld/tools/nb.lld/CMakeLists.txt
===================================================================
--- /dev/null
+++ lld/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
+  )
Index: lld/tools/lld/lld.cpp
===================================================================
--- lld/tools/lld/lld.cpp
+++ lld/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
@@ -36,6 +37,9 @@
 #include "llvm/Support/Host.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;
@@ -45,6 +49,7 @@
 enum Flavor {
   Invalid,
   Gnu,     // -flavor gnu
+  NetBSD,  // -flavor netbsd
   WinLink, // -flavor link
   Darwin,  // -flavor darwin
   Wasm,    // -flavor wasm
@@ -58,6 +63,7 @@
 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)
@@ -100,10 +106,15 @@
 #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;
@@ -133,6 +144,38 @@
   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.
 //
@@ -141,7 +184,7 @@
 // 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);
@@ -152,6 +195,8 @@
     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:
@@ -160,7 +205,8 @@
     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");
   }
 }
Index: lld/CMakeLists.txt
===================================================================
--- lld/CMakeLists.txt
+++ lld/CMakeLists.txt
@@ -212,6 +212,7 @@
 add_subdirectory(Common)
 add_subdirectory(lib)
 add_subdirectory(tools/lld)
+add_subdirectory(tools/nb.lld)
 
 if (LLVM_INCLUDE_TESTS)
   add_subdirectory(test)
Index: clang/lib/Driver/ToolChain.cpp
===================================================================
--- clang/lib/Driver/ToolChain.cpp
+++ clang/lib/Driver/ToolChain.cpp
@@ -534,6 +534,8 @@
     llvm::SmallString<8> LinkerName;
     if (Triple.isOSDarwin())
       LinkerName.append("ld64.");
+    else if (Triple.isOSNetBSD())
+      LinkerName.append("nb.");
     else
       LinkerName.append("ld.");
     LinkerName.append(UseLinker);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to