- Switch Powerpc64 Big Endian to ELFv2 on OpenBSD.
- Adapt the -mfix-loongson2f-btb workaround from as(1) to LLVM/clang.
- Disable -fstrict-aliasing per default on OpenBSD.
- Enable -fwrapv by default
- Add ret protector options as no-ops.
- Add RETGUARD to clang for amd64. This security mechanism uses per-function
  random cookies to protect access to function return instructions, with the
  effect that the integrity of the return address is protected, and function
  return instructions are harder to use in ROP gadgets.

  On function entry the return address is combined with a per-function random
  cookie and stored in the stack frame. The integrity of this value is verified
  before function return, and if this check fails, the program aborts. In this way
  RETGUARD is an improved stack protector, since the cookies are per-function. The
  verification routine is constructed such that the binary space immediately
  before each ret instruction is padded with int03 instructions, which makes these
  return instructions difficult to use in ROP gadgets. In the kernel, this has the
  effect of removing approximately 50% of total ROP gadgets, and 15% of unique
  ROP gadgets compared to the 6.3 release kernel. Function epilogues are
  essentially gadget free, leaving only the polymorphic gadgets that result from
  jumping into the instruction stream partway through other instructions. Work to
  remove these gadgets will continue through other mechanisms.
- Add retguard for arm64.
- Add retguard for octeon/mips64.
- Add RETGUARD implementation for powerpc and powerpc64.
- Improve the X86FixupGadgets pass
- On OpenBSD disable the malloc/calloc/realloc/free/str*dup builtins, since
  they can perform strange transforms and optimizations.  Some of those could
  gain a slight advantage, but would avoid the variety of important runtime
  checks our malloc(3) code does.  In essence, the transforms performed are
  considered "anti-mitigation".
- Make -mbranch-protection=bti the default on OpenBSD.
- On openbsd amd64, emit IBT endbr64 instructions by default (meaning,
  -fcf-protection=branch is the default).
- On openbsd amd64, the compiler has been found to generate some nasty jump
  table variations (calculate address into %rax, jmp %rax) which is not
  compatible with IBT endbr64.  So we will have to disable jump tables by
  default.
- Turn on pointer-authentication on arm64 as well by default.  This means
  we effectively enable -mbranch-protection=standard on arm64 now.

Index: tools/clang/lib/Driver/ToolChains/Clang.cpp
--- tools/clang/lib/Driver/ToolChains/Clang.cpp.orig
+++ tools/clang/lib/Driver/ToolChains/Clang.cpp
@@ -1818,6 +1818,12 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args,
         Args.MakeArgString(Twine("-msign-return-address-key=") + Key));
     if (IndirectBranches)
       CmdArgs.push_back("-mbranch-target-enforce");
+  } else {
+    if (Triple.isOSOpenBSD()) {
+      CmdArgs.push_back("-msign-return-address=non-leaf");
+      CmdArgs.push_back("-msign-return-address-key=a_key");
+      CmdArgs.push_back("-mbranch-target-enforce");
+    }
   }
 
   // Handle -msve_vector_bits=<bits>
@@ -2489,6 +2495,11 @@ static void CollectArgsForIntegratedAssembler(Compilat
           CmdArgs.push_back("-soft-float");
           continue;
         }
+        if (Value.startswith("-mfix-loongson2f-btb")) {
+          CmdArgs.push_back("-mllvm");
+          CmdArgs.push_back("-fix-loongson2f-btb");
+          continue;
+        }
 
         MipsTargetFeature = llvm::StringSwitch<const char *>(Value)
                                 .Case("-mips1", "+mips1")
@@ -4943,9 +4954,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 = !D.IsCLMode();
+  bool StrictAliasingDefault = !D.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))
@@ -5868,7 +5882,8 @@ void Clang::ConstructJob(Compilation &C, const JobActi
                                       options::OPT_fno_strict_overflow)) {
     if (A->getOption().matches(options::OPT_fno_strict_overflow))
       CmdArgs.push_back("-fwrapv");
-  }
+  } else if (getToolChain().getTriple().isOSOpenBSD())
+    CmdArgs.push_back("-fwrapv");
 
   if (Arg *A = Args.getLastArg(options::OPT_freroll_loops,
                                options::OPT_fno_reroll_loops))
@@ -5888,7 +5903,48 @@ void Clang::ConstructJob(Compilation &C, const JobActi
                    options::OPT_mno_speculative_load_hardening, false))
     CmdArgs.push_back(Args.MakeArgString("-mspeculative-load-hardening"));
 
-  RenderSSPOptions(D, TC, Args, CmdArgs, KernelOrKext);
+  // -ret-protector
+  unsigned RetProtector = 1;
+  if (Arg *A = Args.getLastArg(options::OPT_fno_ret_protector,
+        options::OPT_fret_protector)) {
+    if (A->getOption().matches(options::OPT_fno_ret_protector))
+      RetProtector = 0;
+    else if (A->getOption().matches(options::OPT_fret_protector))
+      RetProtector = 1;
+  }
+
+  if (RetProtector &&
+      ((getToolChain().getArch() == llvm::Triple::x86_64) ||
+       (getToolChain().getArch() == llvm::Triple::mips64) ||
+       (getToolChain().getArch() == llvm::Triple::mips64el) ||
+       (getToolChain().getArch() == llvm::Triple::ppc) ||
+       (getToolChain().getArch() == llvm::Triple::ppc64) ||
+       (getToolChain().getArch() == llvm::Triple::ppc64le) ||
+       (getToolChain().getArch() == llvm::Triple::aarch64)) &&
+      !Args.hasArg(options::OPT_fno_stack_protector) &&
+      !Args.hasArg(options::OPT_pg)) {
+    CmdArgs.push_back(Args.MakeArgString("-D_RET_PROTECTOR"));
+    CmdArgs.push_back(Args.MakeArgString("-ret-protector"));
+    // Consume the stack protector arguments to prevent warning
+    Args.getLastArg(options::OPT_fstack_protector_all,
+        options::OPT_fstack_protector_strong,
+        options::OPT_fstack_protector,
+        options::OPT__param); // ssp-buffer-size
+  } else {
+    // If we're not using retguard, then do the usual stack protector
+    RenderSSPOptions(D, TC, Args, CmdArgs, KernelOrKext);
+  }
+
+  // -fixup-gadgets
+  if (Arg *A = Args.getLastArg(options::OPT_fno_fixup_gadgets,
+                               options::OPT_ffixup_gadgets)) {
+    CmdArgs.push_back(Args.MakeArgString(Twine("-mllvm")));
+    if (A->getOption().matches(options::OPT_fno_fixup_gadgets))
+      CmdArgs.push_back(Args.MakeArgString(Twine("-x86-fixup-gadgets=false")));
+    else if (A->getOption().matches(options::OPT_ffixup_gadgets))
+      CmdArgs.push_back(Args.MakeArgString(Twine("-x86-fixup-gadgets=true")));
+  }
+
   RenderSCPOptions(TC, Args, CmdArgs);
   RenderTrivialAutoVarInitOptions(D, TC, Args, CmdArgs);
 
@@ -5961,6 +6017,11 @@ void Clang::ConstructJob(Compilation &C, const JobActi
   if (Arg *A = Args.getLastArg(options::OPT_fcf_protection_EQ)) {
     CmdArgs.push_back(
         Args.MakeArgString(Twine("-fcf-protection=") + A->getValue()));
+  } else if (Triple.isOSOpenBSD() && Triple.getArch() == llvm::Triple::x86_64) {
+    // Emit IBT endbr64 instructions by default
+    CmdArgs.push_back("-fcf-protection=branch");
+    // jump-table can generate indirect jumps, which are not permitted
+    CmdArgs.push_back("-fno-jump-tables");
   }
 
   // Forward -f options with positive and negative forms; we translate these by
@@ -6445,6 +6506,18 @@ void Clang::ConstructJob(Compilation &C, const JobActi
                                      options::OPT_fno_rewrite_imports, false);
   if (RewriteImports)
     CmdArgs.push_back("-frewrite-imports");
+
+  // Disable some builtins on OpenBSD because they are just not
+  // right...
+  if (getToolChain().getTriple().isOSOpenBSD()) {
+    CmdArgs.push_back("-fno-builtin-malloc");
+    CmdArgs.push_back("-fno-builtin-calloc");
+    CmdArgs.push_back("-fno-builtin-realloc");
+    CmdArgs.push_back("-fno-builtin-valloc");
+    CmdArgs.push_back("-fno-builtin-free");
+    CmdArgs.push_back("-fno-builtin-strdup");
+    CmdArgs.push_back("-fno-builtin-strndup");
+  }
 
   // Enable rewrite includes if the user's asked for it or if we're generating
   // diagnostics.
