$OpenBSD: patch-tools_clang_lib_Driver_Tools_cpp,v 1.41 2017/03/23 08:26:07 ajacoutot Exp $

- Select proper SPARCv9 variant for the external assembler
- Set ABIs correctly for OpenBSD/arm; soft float and aapcs-linux
- Make LLVM create strict aligned code for OpenBSD/arm64
- Disable -fstrict-aliasing per default on OpenBSD
- Always use --eh-frame-hdr on OpenBSD, even for -static

--- tools/clang/lib/Driver/Tools.cpp.orig	Tue Feb 21 14:11:22 2017
+++ tools/clang/lib/Driver/Tools.cpp	Sat Mar 18 17:32:52 2017
@@ -79,7 +79,7 @@ static const char *getSparcAsmModeForCPU(StringRef Nam
           .Case("niagara2", "-Av9b")
           .Case("niagara3", "-Av9d")
           .Case("niagara4", "-Av9d")
-          .Default("-Av9");
+          .Default("-Av9a");
   } else {
     return llvm::StringSwitch<const char *>(Name)
           .Case("v8", "-Av8")
@@ -962,6 +962,10 @@ arm::FloatABI arm::getARMFloatABI(const ToolChain &TC,
       }
       break;
 
+    case llvm::Triple::OpenBSD:
+      ABI = FloatABI::Soft;
+      break;
+
     default:
       switch (Triple.getEnvironment()) {
       case llvm::Triple::GNUEABIHF:
@@ -1251,6 +1255,8 @@ void Clang::AddARMTargetArgs(const llvm::Triple &Tripl
     default:
       if (Triple.getOS() == llvm::Triple::NetBSD)
         ABIName = "apcs-gnu";
+      else if (Triple.getOS() == llvm::Triple::OpenBSD)
+        ABIName = "aapcs-linux";
       else
         ABIName = "aapcs";
       break;
@@ -2635,7 +2641,9 @@ getAArch64MicroArchFeaturesFromMcpu(const Driver &D, S
   return getAArch64MicroArchFeaturesFromMtune(D, CPU, Args, Features);
 }
 
-static void getAArch64TargetFeatures(const Driver &D, const ArgList &Args,
+static void getAArch64TargetFeatures(const Driver &D,
+                                     const llvm::Triple &Triple,
+                                     const ArgList &Args,
                                      std::vector<StringRef> &Features) {
   Arg *A;
   bool success = true;
@@ -2677,9 +2685,11 @@ static void getAArch64TargetFeatures(const Driver &D, 
   }
 
   if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access,
-                               options::OPT_munaligned_access))
+                               options::OPT_munaligned_access)) {
     if (A->getOption().matches(options::OPT_mno_unaligned_access))
       Features.push_back("+strict-align");
+  } else if (Triple.isOSOpenBSD())
+    Features.push_back("+strict-align");
 
   if (Args.hasArg(options::OPT_ffixed_x18))
     Features.push_back("+reserve-x18");
@@ -2754,7 +2764,7 @@ static void getTargetFeatures(const ToolChain &TC, con
     break;
   case llvm::Triple::aarch64:
   case llvm::Triple::aarch64_be:
-    getAArch64TargetFeatures(D, Args, Features);
+    getAArch64TargetFeatures(D, Triple, Args, Features);
     break;
   case llvm::Triple::x86:
   case llvm::Triple::x86_64:
@@ -3845,9 +3855,10 @@ ParsePICArgs(const ToolChain &ToolChain, const ArgList
   // OpenBSD-specific defaults for PIE
   if (Triple.getOS() == llvm::Triple::OpenBSD) {
     switch (ToolChain.getArch()) {
+    case llvm::Triple::arm:
+    case llvm::Triple::aarch64:
     case llvm::Triple::mips64:
     case llvm::Triple::mips64el:
-    case llvm::Triple::sparcel:
     case llvm::Triple::x86:
     case llvm::Triple::x86_64:
       IsPICLevelTwo = false; // "-fpie"
@@ -3855,6 +3866,7 @@ ParsePICArgs(const ToolChain &ToolChain, const ArgList
 
     case llvm::Triple::ppc:
     case llvm::Triple::sparc:
+    case llvm::Triple::sparcel:
     case llvm::Triple::sparcv9:
       IsPICLevelTwo = true; // "-fPIE"
       break;
@@ -4466,9 +4478,12 @@ void Clang::ConstructJob(Compilation &C, const JobActi
       OFastEnabled ? options::OPT_Ofast : options::OPT_fstrict_aliasing;
   // We turn strict aliasing off by default if we're in CL mode, since MSVC
   // doesn't do any TBAA.
-  bool TBAAOnByDefault = !getToolChain().getDriver().IsCLMode();
+  bool StrictAliasingDefault = !getToolChain().getDriver().IsCLMode();
+  // We also turn off strict aliasing on OpenBSD.
+  if (getToolChain().getTriple().isOSOpenBSD())
+    StrictAliasingDefault = false;
   if (!Args.hasFlag(options::OPT_fstrict_aliasing, StrictAliasingAliasOption,
-                    options::OPT_fno_strict_aliasing, TBAAOnByDefault))
+                    options::OPT_fno_strict_aliasing, StrictAliasingDefault))
     CmdArgs.push_back("-relaxed-aliasing");
   if (!Args.hasFlag(options::OPT_fstruct_path_tbaa,
                     options::OPT_fno_struct_path_tbaa))
@@ -8907,12 +8922,12 @@ void openbsd::Linker::ConstructJob(Compilation &C, con
     CmdArgs.push_back("__start");
   }
 
+  CmdArgs.push_back("--eh-frame-hdr");
   if (Args.hasArg(options::OPT_static)) {
     CmdArgs.push_back("-Bstatic");
   } else {
     if (Args.hasArg(options::OPT_rdynamic))
       CmdArgs.push_back("-export-dynamic");
-    CmdArgs.push_back("--eh-frame-hdr");
     CmdArgs.push_back("-Bdynamic");
     if (Args.hasArg(options::OPT_shared)) {
       CmdArgs.push_back("-shared");
@@ -8952,15 +8967,17 @@ void openbsd::Linker::ConstructJob(Compilation &C, con
     }
   }
 
-  std::string Triple = getToolChain().getTripleString();
-  if (Triple.substr(0, 6) == "x86_64")
-    Triple.replace(0, 6, "amd64");
-  CmdArgs.push_back(
-      Args.MakeArgString("-L/usr/lib/gcc-lib/" + Triple + "/4.2.1"));
-
   Args.AddAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group,
                             options::OPT_e, options::OPT_s, options::OPT_t,
                             options::OPT_Z_Flag, options::OPT_r});
+
+  std::string Triple = getToolChain().getTripleString();
+  if (Triple.substr(0, 5) == "amd64")
+    Triple.replace(0, 5, "x86_64");
+  CmdArgs.push_back(
+      Args.MakeArgString("-L${LOCALBASE}/lib/gcc/" + Triple + "/${GCC_VER}"));
+  CmdArgs.push_back(
+      Args.MakeArgString("-L${LOCALBASE}/lib"));
 
   AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
 
