The diff below syncs the devel/llvm port with the numerous changes
that have been applied to base llvm since the import of LLVM 13.0.

I have been unable to add this one commit, because the files it
modifies don't exist in the LLVM source tree:

| commit 5e1c9963cb8a2244fbe31d5e8594b757051ef3eb
| from: gnezdo <[email protected]>
| date: Wed Feb 16 03:48:55 2022 UTC
|  
|  Add ifdefs to build ubsan_minimal on OpenBSD
|  
|  ok jca@
|  
|  M  gnu/llvm/compiler-rt/lib/interception/interception.h
|  M  gnu/llvm/compiler-rt/lib/interception/interception_linux.h
|  M  gnu/llvm/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
|  M  gnu/llvm/compiler-rt/lib/sanitizer_common/sanitizer_linux.h
|  M  gnu/llvm/compiler-rt/lib/sanitizer_common/sanitizer_platform.h
|  M  gnu/llvm/compiler-rt/lib/ubsan/ubsan_platform.h

Here's the diff that syncs the other 39 src commits.
Comments?  Anybody want to double check (hahaha)?
OK?

-----------------------------------------------
commit 43b651f79bd9c05efac60f8f453f01ba2377a626 (ibt)
from: Christian Weisgerber <[email protected]>
date: Mon Jun 12 19:47:35 2023 UTC
 
 devel/llvm: sync with base
 
 Catch up with the changes to base LLVM since the import of 13.0:
 * lld: do not report undefined weak references in shared libraries
 * lld: restore upstream default for --[no-]allow-shlib-undefined
 * add a dummy -t flag to llvm-ranlib to match binutils' ranlib's -t flag
 * Enable unwind tables on all clang architectures.
 * Report versioned lib.so in cc --print-file-name given short name
 * Arm is not ready for unwinding yet. Disable unwind info generation for now.
 * Downgrade RISCV ABI mismatch error to a warning
 * Our malloc(3) guarantees 16-byte alignment.
 * support more than one input file in llvm-ranlib
 * In the linkers, collect objects in section "openbsd.mutable"
 * Recognize PT_OPENBSD_MUTABLE with LLVM's readobj / objdump.
 * add .gnu.warning.SYMBOL support to ld.lld(1)
 * correct alignment
 * Downgrade riscv64-specific LTO error to a warning
 * accept --executable-only on aarch64, riscv64, and mips64
 * arm64 and riscv64 can now do --execute-only by default
 * Allow people to try --execute-only on amd64 and sparc64.
 * Update the list of architectures where clang will accept the --execute-only 
option
 * enable --exec-only as default on AMD64
 * permit -execute-only on ppc64 (not default)
 * Change the emitted .glink stub on powerpc64 to use an instruction sequence
 * Make --execute-only the default on powerpc64.
 * Permit the --exec-only option on i386 also.
 * 32-bit powerpc should also allow the --exec-only flag.
 * sync --execute-only archs described in the manual with current code
 * make --execute-only the default on powerpc
 * default sparc64 ld.lld to --execute-only
 * switch mips64 ld.lld to execute-only
 * allow out-of-class defaulting of comparison operators
 * Make -mbranch-protection=bti the default on OpenBSD.
 * Implement support for PT_OPENBSD_NOBTCFI in lld(1).
 * Don't create IBT .plt if there are no PLT entries.
 * On openbsd amd64, emit IBT endbr64 instructions by default
 * On openbsd amd64, the compiler has been found to generate some nasty jump 
table
 * Enable kernel-address sanitizer for clang openbsd target
 * Turn on pointer-authentication on arm64 as well by default.
 * Enable BTI PLT entries by default.
 * Add IBT support to the retpoline PLTs.
 * Add IBT support to the retpoline+znow PLTs
 
 M  devel/llvm/Makefile
 A  devel/llvm/patches/patch-docs_CommandGuide_llvm-ranlib_rst
 A  devel/llvm/patches/patch-include_llvm_BinaryFormat_ELF_h
 M  
devel/llvm/patches/patch-tools_clang_include_clang_Basic_DiagnosticSemaKinds_td
 A  devel/llvm/patches/patch-tools_clang_lib_Basic_TargetInfo_cpp
 M  devel/llvm/patches/patch-tools_clang_lib_Driver_ToolChains_Clang_cpp
 A  devel/llvm/patches/patch-tools_clang_lib_CodeGen_CodeGenModule_cpp
 M  devel/llvm/patches/patch-tools_clang_lib_Driver_ToolChains_OpenBSD_cpp
 A  devel/llvm/patches/patch-tools_clang_lib_Driver_Driver_cpp
 M  devel/llvm/patches/patch-tools_clang_lib_Driver_ToolChains_OpenBSD_h
 M  devel/llvm/patches/patch-tools_lld_ELF_Config_h
 M  devel/llvm/patches/patch-tools_lld_ELF_DriverUtils_cpp
 M  devel/llvm/patches/patch-tools_lld_ELF_Driver_cpp
 A  devel/llvm/patches/patch-tools_clang_lib_Sema_SemaDeclCXX_cpp
 M  devel/llvm/patches/patch-tools_lld_ELF_Symbols_h
 A  devel/llvm/patches/patch-tools_lld_ELF_Arch_AArch64_cpp
 M  devel/llvm/patches/patch-tools_lld_ELF_Writer_cpp
 A  devel/llvm/patches/patch-tools_lld_ELF_Arch_PPC64_cpp
 A  devel/llvm/patches/patch-tools_lld_ELF_Arch_RISCV_cpp
 A  devel/llvm/patches/patch-tools_lld_ELF_Arch_X86_64_cpp
 A  devel/llvm/patches/patch-tools_lld_ELF_InputFiles_cpp
 A  devel/llvm/patches/patch-tools_lld_ELF_InputFiles_h
 A  devel/llvm/patches/patch-tools_lld_ELF_Relocations_cpp
 A  devel/llvm/patches/patch-tools_lld_ELF_ScriptParser_cpp
 A  devel/llvm/patches/patch-tools_lld_ELF_SymbolTable_cpp
 A  devel/llvm/patches/patch-tools_lld_ELF_SyntheticSections_cpp
 A  devel/llvm/patches/patch-tools_lld_ELF_SyntheticSections_h
 A  devel/llvm/patches/patch-tools_lld_docs_ld_lld_1
 A  devel/llvm/patches/patch-tools_llvm-ar_llvm-ar_cpp
 A  devel/llvm/patches/patch-tools_llvm-objdump_ELFDump_cpp
 A  devel/llvm/patches/patch-tools_llvm-readobj_ELFDumper_cpp

diff 39f5d67808d92409f719d5468dfebacadfb0376d 
43b651f79bd9c05efac60f8f453f01ba2377a626
commit - 39f5d67808d92409f719d5468dfebacadfb0376d
commit + 43b651f79bd9c05efac60f8f453f01ba2377a626
blob - c2dbce1980c80a8787eee7e69b3552d48f8dead4
blob + 8f76f56849eb1b9e680935cd1194d8bdb59bdc54
--- devel/llvm/Makefile
+++ devel/llvm/Makefile
@@ -15,7 +15,7 @@ REVISION-main =       5
 PKGSPEC-main = llvm-=${LLVM_V}
 PKGNAME-python =       py3-llvm-${LLVM_V}
 PKGNAME-lldb = lldb-${LLVM_V}
-REVISION-main =        5
+REVISION-main =        6
 REVISION-lldb =        1
 REVISION-python = 0
 
blob - /dev/null
blob + 2db158b6933509e5719b11281b7dc1355abd29df (mode 644)
--- /dev/null
+++ devel/llvm/patches/patch-docs_CommandGuide_llvm-ranlib_rst
@@ -0,0 +1,21 @@
+- support more than one input file in llvm-ranlib
+
+Index: docs/CommandGuide/llvm-ranlib.rst
+--- docs/CommandGuide/llvm-ranlib.rst.orig
++++ docs/CommandGuide/llvm-ranlib.rst
+@@ -6,13 +6,13 @@ llvm-ranlib - generates an archive index
+ SYNOPSIS
+ --------
+ 
+-:program:`llvm-ranlib` [*options*]
++:program:`llvm-ranlib` [*options*] *archive ...*
+ 
+ DESCRIPTION
+ -----------
+ 
+ :program:`llvm-ranlib` is an alias for the :doc:`llvm-ar <llvm-ar>` tool that
+-generates an index for an archive. It can be used as a replacement for GNU's
++generates an index for one or more archives. It can be used as a replacement 
for GNU's
+ :program:`ranlib` tool.
+ 
+ Running :program:`llvm-ranlib` is equivalent to running ``llvm-ar s``.
blob - /dev/null
blob + 40cfe8c92183743ce653efd25c046460c4323d9b (mode 644)
--- /dev/null
+++ devel/llvm/patches/patch-include_llvm_BinaryFormat_ELF_h
@@ -0,0 +1,20 @@
+- In the linkers, collect objects in section "openbsd.mutable" and place
+  them into a page-aligned region in the bss, with the right markers for
+  kernel/ld.so to identify the region and skip making it immutable.
+- Implement support for PT_OPENBSD_NOBTCFI in lld(1).  This can be set using
+  the -z nobtcfi option.
+
+Index: include/llvm/BinaryFormat/ELF.h
+--- include/llvm/BinaryFormat/ELF.h.orig
++++ include/llvm/BinaryFormat/ELF.h
+@@ -1303,8 +1303,10 @@ enum {
+   PT_GNU_RELRO = 0x6474e552,    // Read-only after relocation.
+   PT_GNU_PROPERTY = 0x6474e553, // .note.gnu.property notes sections.
+ 
++  PT_OPENBSD_MUTABLE = 0x65a3dbe5, // Like bss, but not immutable.
+   PT_OPENBSD_RANDOMIZE = 0x65a3dbe6, // Fill with random data.
+   PT_OPENBSD_WXNEEDED = 0x65a3dbe7,  // Program does W^X violations.
++  PT_OPENBSD_NOBTCFI = 0x65a3dbe8,   // Do not enforce branch target CFI
+   PT_OPENBSD_BOOTDATA = 0x65a41be6,  // Section for boot arguments.
+ 
+   // ARM program header types.
blob - 20179a5326226a8bcd09992e427b94e98c049d91
blob + effb07ea0b6851dd191f532f28c46a724b909598
--- 
devel/llvm/patches/patch-tools_clang_include_clang_Basic_DiagnosticSemaKinds_td
+++ 
devel/llvm/patches/patch-tools_clang_include_clang_Basic_DiagnosticSemaKinds_td
@@ -9,6 +9,10 @@ Index: tools/clang/include/clang/Basic/DiagnosticSemaK
 
 - Add a new warning for %n format specifier usage in printf(3) family functions
 
+- allow out-of-class defaulting of comparison operators
+  this is backport of the following upstream commit:
+  commit 5fbe21a7748f91adbd1b16c95bbfe180642320a3
+
 Index: tools/clang/include/clang/Basic/DiagnosticSemaKinds.td
 --- tools/clang/include/clang/Basic/DiagnosticSemaKinds.td.orig
 +++ tools/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -30,7 +34,33 @@ Index: tools/clang/include/clang/Basic/DiagnosticSemaK
  def err_typecheck_convert_incompatible_pointer_sign :
    Error<ext_typecheck_convert_incompatible_pointer_sign.Text>;
  def ext_typecheck_convert_incompatible_pointer : ExtWarn<
-@@ -9512,6 +9512,9 @@ def err_os_log_argument_too_big : Error<
+@@ -9100,15 +9100,22 @@ def warn_cxx17_compat_defaulted_comparison : Warning<
+   "before C++20">, InGroup<CXXPre20Compat>, DefaultIgnore;
+ def err_defaulted_comparison_template : Error<
+   "comparison operator template cannot be defaulted">;
+-def err_defaulted_comparison_out_of_class : Error<
+-  "%sub{select_defaulted_comparison_kind}0 can only be defaulted in a class "
+-  "definition">;
++def err_defaulted_comparison_num_args : Error<
++  "%select{non-member|member}0 %sub{select_defaulted_comparison_kind}1"
++  " comparison operator must have %select{2|1}0 parameters">;
+ def err_defaulted_comparison_param : Error<
+   "invalid parameter type for defaulted 
%sub{select_defaulted_comparison_kind}0"
+   "; found %1, expected %2%select{| or %4}3">;
++def err_defaulted_comparison_param_unknown : Error<
++  "invalid parameter type for non-member defaulted"
++  " %sub{select_defaulted_comparison_kind}0"
++  "; found %1, expected class or reference to a constant class">;
+ def err_defaulted_comparison_param_mismatch : Error<
+   "parameters for defaulted %sub{select_defaulted_comparison_kind}0 "
+   "must have the same type%diff{ (found $ vs $)|}1,2">;
++def err_defaulted_comparison_not_friend : Error<
++  "%sub{select_defaulted_comparison_kind}0 is not a friend of"
++  " %select{|incomplete class }1%2">;
+ def err_defaulted_comparison_non_const : Error<
+   "defaulted member %sub{select_defaulted_comparison_kind}0 must be "
+   "const-qualified">;
+@@ -9512,6 +9519,9 @@ def err_os_log_argument_too_big : Error<
    "os_log() argument %0 is too big (%1 bytes, max %2)">;
  def warn_os_log_format_narg : Error<
   "os_log() '%%n' format specifier is not allowed">, DefaultError;
blob - /dev/null
blob + 17dcb42ea75eda7d06441295c601087de08fb85f (mode 644)
--- /dev/null
+++ devel/llvm/patches/patch-tools_clang_lib_Basic_TargetInfo_cpp
@@ -0,0 +1,14 @@
+- Our malloc(3) guarantees 16-byte alignment.
+
+Index: tools/clang/lib/Basic/TargetInfo.cpp
+--- tools/clang/lib/Basic/TargetInfo.cpp.orig
++++ tools/clang/lib/Basic/TargetInfo.cpp
+@@ -70,7 +70,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : Target
+   // the alignment is 16 bytes on both 64-bit and 32-bit systems.
+   if (T.isGNUEnvironment() || T.isWindowsMSVCEnvironment() || T.isAndroid())
+     NewAlign = Triple.isArch64Bit() ? 128 : Triple.isArch32Bit() ? 64 : 0;
+-  else if (T.isOSDarwin())
++  else if (T.isOSDarwin() || T.isOSOpenBSD())
+     NewAlign = 128;
+   else
+     NewAlign = 0; // Infer from basic type alignment.
blob - f5ab7385cf446241e0cd3a8c4473d383ff57ed70
blob + a968ab35c1403aef9a883c58541871a77fa60f45
--- devel/llvm/patches/patch-tools_clang_lib_Driver_ToolChains_Clang_cpp
+++ devel/llvm/patches/patch-tools_clang_lib_Driver_ToolChains_Clang_cpp
@@ -29,11 +29,33 @@
   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
-@@ -2489,6 +2489,11 @@ static void CollectArgsForIntegratedAssembler(Compilat
+@@ -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;
          }
@@ -45,7 +67,7 @@ Index: tools/clang/lib/Driver/ToolChains/Clang.cpp
  
          MipsTargetFeature = llvm::StringSwitch<const char *>(Value)
                                  .Case("-mips1", "+mips1")
-@@ -4943,9 +4948,12 @@ void Clang::ConstructJob(Compilation &C, const JobActi
+@@ -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.
@@ -60,7 +82,7 @@ Index: tools/clang/lib/Driver/ToolChains/Clang.cpp
      CmdArgs.push_back("-relaxed-aliasing");
    if (!Args.hasFlag(options::OPT_fstruct_path_tbaa,
                      options::OPT_fno_struct_path_tbaa))
-@@ -5868,7 +5876,8 @@ void Clang::ConstructJob(Compilation &C, const JobActi
+@@ -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");
@@ -70,7 +92,7 @@ Index: tools/clang/lib/Driver/ToolChains/Clang.cpp
  
    if (Arg *A = Args.getLastArg(options::OPT_freroll_loops,
                                 options::OPT_fno_reroll_loops))
-@@ -5888,7 +5897,48 @@ void Clang::ConstructJob(Compilation &C, const JobActi
+@@ -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"));
  
@@ -120,7 +142,19 @@ Index: tools/clang/lib/Driver/ToolChains/Clang.cpp
    RenderSCPOptions(TC, Args, CmdArgs);
    RenderTrivialAutoVarInitOptions(D, TC, Args, CmdArgs);
  
-@@ -6445,6 +6495,18 @@ void Clang::ConstructJob(Compilation &C, const JobActi
+@@ -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");
blob - /dev/null
blob + 321f7c568ec6d810ace5609614b4530feedaede7 (mode 644)
--- /dev/null
+++ devel/llvm/patches/patch-tools_clang_lib_CodeGen_CodeGenModule_cpp
@@ -0,0 +1,14 @@
+- Downgrade riscv64-specific LTO error to a warning
+
+Index: tools/clang/lib/CodeGen/CodeGenModule.cpp
+--- tools/clang/lib/CodeGen/CodeGenModule.cpp.orig
++++ tools/clang/lib/CodeGen/CodeGenModule.cpp
+@@ -846,7 +846,7 @@ void CodeGenModule::EmitBackendOptionsMetadata(
+     break;
+   case llvm::Triple::riscv32:
+   case llvm::Triple::riscv64:
+-    getModule().addModuleFlag(llvm::Module::Error, "SmallDataLimit",
++    getModule().addModuleFlag(llvm::Module::Warning, "SmallDataLimit",
+                               CodeGenOpts.SmallDataLimit);
+     break;
+   }
blob - 379f36e54cb1a550ebf6962ced901f0fd278e9a2
blob + fd5cccc6503608734703f04d0621fa349cd92b75
--- devel/llvm/patches/patch-tools_clang_lib_Driver_ToolChains_OpenBSD_cpp
+++ devel/llvm/patches/patch-tools_clang_lib_Driver_ToolChains_OpenBSD_cpp
@@ -1,6 +1,7 @@
 - Add support for building against libestdc++ from ports-gcc.
 - Allow the compiler driver to link the libclang_rt.profile library.
 - Use Component in OpenBSD::getCompilerRT to find libraries.
+- Enable kernel-address sanitizer for clang openbsd target
 
 Index: tools/clang/lib/Driver/ToolChains/OpenBSD.cpp
 --- tools/clang/lib/Driver/ToolChains/OpenBSD.cpp.orig
@@ -46,7 +47,18 @@ Index: tools/clang/lib/Driver/ToolChains/OpenBSD.cpp
    }
  
    if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
-@@ -301,17 +313,34 @@ void OpenBSD::AddCXXStdlibLibArgs(const ArgList &Args,
+@@ -247,6 +259,10 @@ SanitizerMask OpenBSD::getSupportedSanitizers() const 
+     Res |= SanitizerKind::FuzzerNoLink;
+   }
+ 
++  if (IsX86_64) {
++    Res |= SanitizerKind::KernelAddress;
++  }
++
+   return Res;
+ }
+ 
+@@ -301,17 +317,34 @@ void OpenBSD::AddCXXStdlibLibArgs(const ArgList &Args,
                                    ArgStringList &CmdArgs) const {
    bool Profiling = Args.hasArg(options::OPT_pg);
  
@@ -87,7 +99,7 @@ Index: tools/clang/lib/Driver/ToolChains/OpenBSD.cpp
  }
  
  Tool *OpenBSD::buildAssembler() const {
-@@ -321,3 +350,54 @@ Tool *OpenBSD::buildAssembler() const {
+@@ -321,3 +354,54 @@ Tool *OpenBSD::buildAssembler() const {
  Tool *OpenBSD::buildLinker() const { return new 
tools::openbsd::Linker(*this); }
  
  bool OpenBSD::HasNativeLLVMSupport() const { return true; }
blob - /dev/null
blob + 82f63c7cb278056de229d5defdc66fdcee55b63e (mode 644)
--- /dev/null
+++ devel/llvm/patches/patch-tools_clang_lib_Driver_Driver_cpp
@@ -0,0 +1,74 @@
+- Report versioned lib.so in cc --print-file-name given short name
+
+Index: tools/clang/lib/Driver/Driver.cpp
+--- tools/clang/lib/Driver/Driver.cpp.orig
++++ tools/clang/lib/Driver/Driver.cpp
+@@ -5089,7 +5089,50 @@ const char *Driver::GetNamedOutputPath(Compilation &C,
+   }
+ }
+ 
++
++namespace {
++static Optional<std::string> findFile(StringRef path1, const Twine &path2) {
++  SmallString<128> s;
++  llvm::sys::path::append(s, path1, path2);
++
++  if (llvm::sys::fs::exists(s))
++    return std::string(s);
++  return None;
++}
++
++// Must be in sync with findMajMinShlib in lld/ELF/DriverUtils.cpp.
++llvm::Optional<std::string> findMajMinShlib(StringRef dir, const Twine& 
libNameSo) {
++  // Handle OpenBSD-style maj/min shlib scheme
++  llvm::SmallString<128> Scratch;
++  const StringRef LibName = (libNameSo + ".").toStringRef(Scratch);
++  int MaxMaj = -1, MaxMin = -1;
++  std::error_code EC;
++  for (llvm::sys::fs::directory_iterator LI(dir, EC), LE;
++       LI != LE; LI = LI.increment(EC)) {
++    StringRef FilePath = LI->path();
++    StringRef FileName = llvm::sys::path::filename(FilePath);
++    if (!(FileName.startswith(LibName)))
++      continue;
++    std::pair<StringRef, StringRef> MajMin =
++      FileName.substr(LibName.size()).split('.');
++    int Maj, Min;
++    if (MajMin.first.getAsInteger(10, Maj) || Maj < 0)
++      continue;
++    if (MajMin.second.getAsInteger(10, Min) || Min < 0)
++      continue;
++    if (Maj > MaxMaj)
++      MaxMaj = Maj, MaxMin = Min;
++    if (MaxMaj == Maj && Min > MaxMin)
++      MaxMin = Min;
++  }
++  if (MaxMaj >= 0)
++    return findFile(dir, LibName + Twine(MaxMaj) + "." + Twine(MaxMin));
++  return None;
++}
++}  // namespace
++
+ std::string Driver::GetFilePath(StringRef Name, const ToolChain &TC) const {
++  const bool lookForLibDotSo = Name.startswith("lib") && Name.endswith(".so");
+   // Search for Name in a list of paths.
+   auto SearchPaths = [&](const llvm::SmallVectorImpl<std::string> &P)
+       -> llvm::Optional<std::string> {
+@@ -5099,9 +5142,14 @@ std::string Driver::GetFilePath(StringRef Name, const 
+       if (Dir.empty())
+         continue;
+       SmallString<128> P(Dir[0] == '=' ? SysRoot + Dir.substr(1) : Dir);
+-      llvm::sys::path::append(P, Name);
+-      if (llvm::sys::fs::exists(Twine(P)))
+-        return std::string(P);
++      if (!lookForLibDotSo) {
++      llvm::sys::path::append(P, Name);
++      if (llvm::sys::fs::exists(Twine(P)))
++        return std::string(P);
++      } else {
++      if (auto s = findMajMinShlib(P, Name))
++        return std::string(*s);
++      }
+     }
+     return None;
+   };
blob - d0b4fbdb1f8ba0e9069cc5be5dcf15d4af2ed491
blob + 413963e6a9c2d022e7c5a7f512328425f56dcd6c
--- devel/llvm/patches/patch-tools_clang_lib_Driver_ToolChains_OpenBSD_h
+++ devel/llvm/patches/patch-tools_clang_lib_Driver_ToolChains_OpenBSD_h
@@ -1,10 +1,11 @@
 - Add support for building against libestdc++ from ports-gcc.
-- Make clang emit the proper path to our libcompiler_rt.a when asked to.
+- Enable unwind tables on all clang architectures.
+- Arm is not ready for unwinding yet. Disable unwind info generation for now.
 
 Index: tools/clang/lib/Driver/ToolChains/OpenBSD.h
 --- tools/clang/lib/Driver/ToolChains/OpenBSD.h.orig
 +++ tools/clang/lib/Driver/ToolChains/OpenBSD.h
-@@ -77,6 +77,11 @@ class LLVM_LIBRARY_VISIBILITY OpenBSD : public Generic
+@@ -77,8 +77,22 @@ class LLVM_LIBRARY_VISIBILITY OpenBSD : public Generic
    void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
                             llvm::opt::ArgStringList &CmdArgs) const override;
  
@@ -15,4 +16,15 @@ Index: tools/clang/lib/Driver/ToolChains/OpenBSD.h
 +
    std::string getCompilerRT(const llvm::opt::ArgList &Args, StringRef 
Component,
                              FileType Type = ToolChain::FT_Static) const 
override;
++
++  bool IsUnwindTablesDefault(const llvm::opt::ArgList &Args) const override {
++    switch (getArch()) {
++      case llvm::Triple::arm:
++        return false;
++      default:
++        return true;
++    }
++  }
  
+   LangOptions::StackProtectorMode
+   GetDefaultStackProtectorLevel(bool KernelOrKext) const override {
blob - db7ffd44cff1d09bcae16ad134afa5e2deaeb117
blob + 81df6650aa21862d78d344a5c645f700f666b276
--- devel/llvm/patches/patch-tools_lld_ELF_Config_h
+++ devel/llvm/patches/patch-tools_lld_ELF_Config_h
@@ -1,9 +1,19 @@
 - XXX no comment
+- Implement support for PT_OPENBSD_NOBTCFI in lld(1).  This can be set using
+  the -z nobtcfi option.
 
 Index: tools/lld/ELF/Config.h
 --- tools/lld/ELF/Config.h.orig
 +++ tools/lld/ELF/Config.h
-@@ -266,8 +266,13 @@ struct Configuration {
+@@ -236,6 +236,7 @@ struct Configuration {
+   bool zInitfirst;
+   bool zInterpose;
+   bool zKeepTextSectionPrefix;
++  bool zNoBtCfi;
+   bool zNodefaultlib;
+   bool zNodelete;
+   bool zNodlopen;
+@@ -266,8 +267,13 @@ struct Configuration {
    ELFKind ekind = ELFNoneKind;
    uint16_t emachine = llvm::ELF::EM_NONE;
    llvm::Optional<uint64_t> imageBase;
blob - 0a8f886ae5c779b4dd980d9846f92911147c8a09
blob + 7795edac2a243a00812b899c8ab057e57ded9028
--- devel/llvm/patches/patch-tools_lld_ELF_DriverUtils_cpp
+++ devel/llvm/patches/patch-tools_lld_ELF_DriverUtils_cpp
@@ -1,9 +1,46 @@
-Handle the OpenBSD-style major/minor shared library version scheme.
+- Handle the OpenBSD-style major/minor shared library version scheme.
+- Report versioned lib.so in cc --print-file-name given short name
 
 Index: tools/lld/ELF/DriverUtils.cpp
 --- tools/lld/ELF/DriverUtils.cpp.orig
 +++ tools/lld/ELF/DriverUtils.cpp
-@@ -234,9 +234,36 @@ Optional<std::string> elf::findFromSearchPaths(StringR
+@@ -230,13 +230,48 @@ Optional<std::string> elf::findFromSearchPaths(StringR
+   return None;
+ }
+ 
++namespace {
++// Must be in sync with findMajMinShlib in clang/lib/Driver/Driver.cpp.
++llvm::Optional<std::string> findMajMinShlib(StringRef dir, const Twine& 
libNameSo) {
++  // Handle OpenBSD-style maj/min shlib scheme
++  llvm::SmallString<128> Scratch;
++  const StringRef LibName = (libNameSo + ".").toStringRef(Scratch);
++  int MaxMaj = -1, MaxMin = -1;
++  std::error_code EC;
++  for (llvm::sys::fs::directory_iterator LI(dir, EC), LE;
++       LI != LE; LI = LI.increment(EC)) {
++    StringRef FilePath = LI->path();
++    StringRef FileName = llvm::sys::path::filename(FilePath);
++    if (!(FileName.startswith(LibName)))
++      continue;
++    std::pair<StringRef, StringRef> MajMin =
++      FileName.substr(LibName.size()).split('.');
++    int Maj, Min;
++    if (MajMin.first.getAsInteger(10, Maj) || Maj < 0)
++      continue;
++    if (MajMin.second.getAsInteger(10, Min) || Min < 0)
++      continue;
++    if (Maj > MaxMaj)
++      MaxMaj = Maj, MaxMin = Min;
++    if (MaxMaj == Maj && Min > MaxMin)
++      MaxMin = Min;
++  }
++  if (MaxMaj >= 0)
++    return findFile(dir, LibName + Twine(MaxMaj) + "." + Twine(MaxMin));
++  return None;
++}
++}  // namespace
++
+ // This is for -l<basename>. We'll look for lib<basename>.so or 
lib<basename>.a from
  // search paths.
  Optional<std::string> elf::searchLibraryBaseName(StringRef name) {
    for (StringRef dir : config->searchPaths) {
@@ -11,32 +48,8 @@ Index: tools/lld/ELF/DriverUtils.cpp
 +    if (!config->isStatic) {
        if (Optional<std::string> s = findFile(dir, "lib" + name + ".so"))
          return s;
-+
-+      // Handle OpenBSD-style maj/min shlib scheme
-+      llvm::SmallString<128> Scratch;
-+      const StringRef LibName = ("lib" + name + ".so.").toStringRef(Scratch);
-+      int MaxMaj = -1, MaxMin = -1;
-+      std::error_code EC;
-+      for (fs::directory_iterator LI(dir, EC), LE;
-+          LI != LE; LI = LI.increment(EC)) {
-+        StringRef FilePath = LI->path();
-+        StringRef FileName = path::filename(FilePath);
-+        if (!(FileName.startswith(LibName)))
-+          continue;
-+        std::pair<StringRef, StringRef> MajMin =
-+          FileName.substr(LibName.size()).split('.');
-+        int Maj, Min;
-+        if (MajMin.first.getAsInteger(10, Maj) || Maj < 0)
-+          continue;
-+        if (MajMin.second.getAsInteger(10, Min) || Min < 0)
-+          continue;
-+        if (Maj > MaxMaj)
-+          MaxMaj = Maj, MaxMin = Min;
-+        if (MaxMaj == Maj && Min > MaxMin)
-+          MaxMin = Min;
-+      }
-+      if (MaxMaj >= 0)
-+        return findFile(dir, LibName + Twine(MaxMaj) + "." + Twine(MaxMin));
++      if (Optional<std::string> s = findMajMinShlib(dir, "lib" + name + 
".so"))
++        return s;
 +    }
      if (Optional<std::string> s = findFile(dir, "lib" + name + ".a"))
        return s;
blob - 8eb56cfd7c258a1f2abcc422c2ef54ada21c44e3
blob + a4000fc8f7038c7c7a6d69cdfddc29da86abbc90
--- devel/llvm/patches/patch-tools_lld_ELF_Driver_cpp
+++ devel/llvm/patches/patch-tools_lld_ELF_Driver_cpp
@@ -1,12 +1,47 @@
 - enable retpoline by default
-- allow-shlib-undefined by default
-- anable PIE by default.
+- enable PIE by default.
+- arm64 and riscv64 can now do --execute-only by default
+- enable --exec-only as default on AMD64
+- Make --execute-only the default on powerpc64.
+- Permit the --exec-only option on i386 also.
+- make --execute-only the default on powerpc
+- default sparc64 ld.lld to --execute-only
+- switch mips64 ld.lld to execute-only
+- Implement support for PT_OPENBSD_NOBTCFI in lld(1).  This can be set using
+  the -z nobtcfi option.
 
-
 Index: tools/lld/ELF/Driver.cpp
 --- tools/lld/ELF/Driver.cpp.orig
 +++ tools/lld/ELF/Driver.cpp
-@@ -455,6 +455,7 @@ static bool isKnownZFlag(StringRef s) {
+@@ -358,8 +358,19 @@ static void checkOptions() {
+   }
+ 
+   if (config->executeOnly) {
+-    if (config->emachine != EM_AARCH64)
+-      error("-execute-only is only supported on AArch64 targets");
++    switch (config->emachine) {
++    case EM_386:
++    case EM_AARCH64:
++    case EM_MIPS:
++    case EM_PPC:
++    case EM_PPC64:
++    case EM_RISCV:
++    case EM_SPARCV9:
++    case EM_X86_64:
++      break;
++    default:
++      error("-execute-only is not supported on this target");
++    }
+ 
+     if (config->singleRoRx && !script->hasSectionsCommand)
+       error("-execute-only and -no-rosegment cannot be used together");
+@@ -451,10 +462,12 @@ static bool isKnownZFlag(StringRef s) {
+          s == "initfirst" || s == "interpose" ||
+          s == "keep-text-section-prefix" || s == "lazy" || s == "muldefs" ||
+          s == "separate-code" || s == "separate-loadable-segments" ||
+-         s == "start-stop-gc" || s == "nocombreloc" || s == "nocopyreloc" ||
++         s == "start-stop-gc" || s == "nobtcfi" ||
++         s == "nocombreloc" || s == "nocopyreloc" ||
           s == "nodefaultlib" || s == "nodelete" || s == "nodlopen" ||
           s == "noexecstack" || s == "nognustack" ||
           s == "nokeep-text-section-prefix" || s == "norelro" ||
@@ -14,16 +49,16 @@ Index: tools/lld/ELF/Driver.cpp
           s == "noseparate-code" || s == "nostart-stop-gc" || s == "notext" ||
           s == "now" || s == "origin" || s == "pac-plt" || s == "rel" ||
           s == "rela" || s == "relro" || s == "retpolineplt" ||
-@@ -598,7 +599,7 @@ static void setUnresolvedSymbolPolicy(opt::InputArgLis
-                                      : UnresolvedPolicy::Warn;
-   // -shared implies -unresolved-symbols=ignore-all because missing
-   // symbols are likely to be resolved at runtime.
--  bool diagRegular = !config->shared, diagShlib = !config->shared;
-+  bool diagRegular = !config->shared, diagShlib = false;
+@@ -1045,8 +1058,6 @@ static void readConfigs(opt::InputArgList &args) {
+   errorHandler().errorHandlingScript =
+       args.getLastArgValue(OPT_error_handling_script);
  
-   for (const opt::Arg *arg : args) {
-     switch (arg->getOption().getID()) {
-@@ -1064,7 +1065,8 @@ static void readConfigs(opt::InputArgList &args) {
+-  config->executeOnly =
+-      args.hasFlag(OPT_execute_only, OPT_no_execute_only, false);
+   config->exportDynamic =
+       args.hasFlag(OPT_export_dynamic, OPT_no_export_dynamic, false);
+   config->filterList = args::getStrings(args, OPT_filter);
+@@ -1064,7 +1075,8 @@ static void readConfigs(opt::InputArgList &args) {
    config->ignoreDataAddressEquality =
        args.hasArg(OPT_ignore_data_address_equality);
    config->ignoreFunctionAddressEquality =
@@ -33,7 +68,7 @@ Index: tools/lld/ELF/Driver.cpp
    config->init = args.getLastArgValue(OPT_init, "_init");
    config->ltoAAPipeline = args.getLastArgValue(OPT_lto_aa_pipeline);
    config->ltoCSProfileGenerate = args.hasArg(OPT_lto_cs_profile_generate);
-@@ -1118,7 +1120,12 @@ static void readConfigs(opt::InputArgList &args) {
+@@ -1118,7 +1130,12 @@ static void readConfigs(opt::InputArgList &args) {
    config->optimize = args::getInteger(args, OPT_O, 1);
    config->orphanHandling = getOrphanHandling(args);
    config->outputFile = args.getLastArgValue(OPT_o);
@@ -46,7 +81,15 @@ Index: tools/lld/ELF/Driver.cpp
    config->printIcfSections =
        args.hasFlag(OPT_print_icf_sections, OPT_no_print_icf_sections, false);
    config->printGcSections =
-@@ -1188,7 +1195,11 @@ static void readConfigs(opt::InputArgList &args) {
+@@ -1181,6 +1198,7 @@ static void readConfigs(opt::InputArgList &args) {
+   config->zInterpose = hasZOption(args, "interpose");
+   config->zKeepTextSectionPrefix = getZFlag(
+       args, "keep-text-section-prefix", "nokeep-text-section-prefix", false);
++  config->zNoBtCfi = hasZOption(args, "nobtcfi");
+   config->zNodefaultlib = hasZOption(args, "nodefaultlib");
+   config->zNodelete = hasZOption(args, "nodelete");
+   config->zNodlopen = hasZOption(args, "nodlopen");
+@@ -1188,7 +1206,11 @@ static void readConfigs(opt::InputArgList &args) {
    config->zOrigin = hasZOption(args, "origin");
    config->zPacPlt = hasZOption(args, "pac-plt");
    config->zRelro = getZFlag(args, "relro", "norelro", true);
@@ -59,16 +102,40 @@ Index: tools/lld/ELF/Driver.cpp
    config->zRodynamic = hasZOption(args, "rodynamic");
    config->zSeparate = getZSeparate(args);
    config->zShstk = hasZOption(args, "shstk");
-@@ -1596,7 +1607,7 @@ void LinkerDriver::inferMachineType() {
+@@ -1459,6 +1481,23 @@ static void setConfigs(opt::InputArgList &args) {
+       args.hasFlag(OPT_toc_optimize, OPT_no_toc_optimize, m == EM_PPC64);
+   config->pcRelOptimize =
+       args.hasFlag(OPT_pcrel_optimize, OPT_no_pcrel_optimize, m == EM_PPC64);
++
++  config->executeOnly = false;
++#ifdef __OpenBSD__
++  switch (m) {
++  case EM_AARCH64:
++  case EM_MIPS:
++  case EM_PPC:
++  case EM_PPC64:
++  case EM_RISCV:
++  case EM_SPARCV9:
++  case EM_X86_64:
++    config->executeOnly = true;
++    break;
++  }
++#endif
++  config->executeOnly =
++      args.hasFlag(OPT_execute_only, OPT_no_execute_only, 
config->executeOnly);
  }
  
+ // Returns a value of "-format" option.
+@@ -1596,7 +1635,7 @@ void LinkerDriver::inferMachineType() {
+ }
+ 
  // Parse -z max-page-size=<value>. The default value is defined by
 -// each target.
 +// each target. Is set to 1 if given nmagic or omagic.
  static uint64_t getMaxPageSize(opt::InputArgList &args) {
    uint64_t val = args::getZOptionValue(args, OPT_z, "max-page-size",
                                         target->defaultMaxPageSize);
-@@ -1611,7 +1622,7 @@ static uint64_t getMaxPageSize(opt::InputArgList &args
+@@ -1611,7 +1650,7 @@ static uint64_t getMaxPageSize(opt::InputArgList &args
  }
  
  // Parse -z common-page-size=<value>. The default value is defined by
@@ -77,7 +144,7 @@ Index: tools/lld/ELF/Driver.cpp
  static uint64_t getCommonPageSize(opt::InputArgList &args) {
    uint64_t val = args::getZOptionValue(args, OPT_z, "common-page-size",
                                         target->defaultCommonPageSize);
-@@ -1628,6 +1639,16 @@ static uint64_t getCommonPageSize(opt::InputArgList &a
+@@ -1628,6 +1667,16 @@ static uint64_t getCommonPageSize(opt::InputArgList &a
    return val;
  }
  
@@ -94,7 +161,7 @@ Index: tools/lld/ELF/Driver.cpp
  // Parses -image-base option.
  static Optional<uint64_t> getImageBase(opt::InputArgList &args) {
    // Because we are using "Config->maxPageSize" here, this function has to be
-@@ -2414,6 +2435,11 @@ template <class ELFT> void LinkerDriver::link(opt::Inp
+@@ -2414,6 +2463,11 @@ template <class ELFT> void LinkerDriver::link(opt::Inp
    // optimizations such as DATA_SEGMENT_ALIGN in linker scripts. LLD's use of 
it
    // is limited to writing trap instructions on the last executable segment.
    config->commonPageSize = getCommonPageSize(args);
blob - /dev/null
blob + 102fc42f4e6003301ffd3e798096b8c73bfae145 (mode 644)
--- /dev/null
+++ devel/llvm/patches/patch-tools_clang_lib_Sema_SemaDeclCXX_cpp
@@ -0,0 +1,266 @@
+- allow out-of-class defaulting of comparison operators
+  this is backport of the following upstream commit:
+  commit 5fbe21a7748f91adbd1b16c95bbfe180642320a3
+
+Index: tools/clang/lib/Sema/SemaDeclCXX.cpp
+--- tools/clang/lib/Sema/SemaDeclCXX.cpp.orig
++++ tools/clang/lib/Sema/SemaDeclCXX.cpp
+@@ -8371,9 +8371,6 @@ bool Sema::CheckExplicitlyDefaultedComparison(Scope *S
+                                               DefaultedComparisonKind DCK) {
+   assert(DCK != DefaultedComparisonKind::None && "not a defaulted 
comparison");
+ 
+-  CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(FD->getLexicalDeclContext());
+-  assert(RD && "defaulted comparison is not defaulted in a class");
+-
+   // Perform any unqualified lookups we're going to need to default this
+   // function.
+   if (S) {
+@@ -8391,43 +8388,17 @@ bool Sema::CheckExplicitlyDefaultedComparison(Scope *S
+   //       const C&, or
+   //    -- a friend of C having two parameters of type const C& or two
+   //       parameters of type C.
+-  QualType ExpectedParmType1 = Context.getRecordType(RD);
+-  QualType ExpectedParmType2 =
+-      Context.getLValueReferenceType(ExpectedParmType1.withConst());
+-  if (isa<CXXMethodDecl>(FD))
+-    ExpectedParmType1 = ExpectedParmType2;
+-  for (const ParmVarDecl *Param : FD->parameters()) {
+-    if (!Param->getType()->isDependentType() &&
+-        !Context.hasSameType(Param->getType(), ExpectedParmType1) &&
+-        !Context.hasSameType(Param->getType(), ExpectedParmType2)) {
+-      // Don't diagnose an implicit 'operator=='; we will have diagnosed the
+-      // corresponding defaulted 'operator<=>' already.
+-      if (!FD->isImplicit()) {
+-        Diag(FD->getLocation(), diag::err_defaulted_comparison_param)
+-            << (int)DCK << Param->getType() << ExpectedParmType1
+-            << !isa<CXXMethodDecl>(FD)
+-            << ExpectedParmType2 << Param->getSourceRange();
+-      }
+-      return true;
+-    }
+-  }
+-  if (FD->getNumParams() == 2 &&
+-      !Context.hasSameType(FD->getParamDecl(0)->getType(),
+-                           FD->getParamDecl(1)->getType())) {
+-    if (!FD->isImplicit()) {
+-      Diag(FD->getLocation(), diag::err_defaulted_comparison_param_mismatch)
+-          << (int)DCK
+-          << FD->getParamDecl(0)->getType()
+-          << FD->getParamDecl(0)->getSourceRange()
+-          << FD->getParamDecl(1)->getType()
+-          << FD->getParamDecl(1)->getSourceRange();
+-    }
+-    return true;
+-  }
+ 
+-  // ... non-static const member ...
+-  if (auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
++  CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(FD->getLexicalDeclContext());
++  bool IsMethod = isa<CXXMethodDecl>(FD);
++  if (IsMethod) {
++    auto *MD = cast<CXXMethodDecl>(FD);
+     assert(!MD->isStatic() && "comparison function cannot be a static 
member");
++
++    // If we're out-of-class, this is the class we're comparing.
++    if (!RD)
++      RD = MD->getParent();
++
+     if (!MD->isConst()) {
+       SourceLocation InsertLoc;
+       if (FunctionTypeLoc Loc = MD->getFunctionTypeLoc())
+@@ -8436,7 +8407,7 @@ bool Sema::CheckExplicitlyDefaultedComparison(Scope *S
+       // corresponding defaulted 'operator<=>' already.
+       if (!MD->isImplicit()) {
+         Diag(MD->getLocation(), diag::err_defaulted_comparison_non_const)
+-          << (int)DCK << FixItHint::CreateInsertion(InsertLoc, " const");
++            << (int)DCK << FixItHint::CreateInsertion(InsertLoc, " const");
+       }
+ 
+       // Add the 'const' to the type to recover.
+@@ -8446,9 +8417,100 @@ bool Sema::CheckExplicitlyDefaultedComparison(Scope *S
+       MD->setType(Context.getFunctionType(FPT->getReturnType(),
+                                           FPT->getParamTypes(), EPI));
+     }
+-  } else {
+-    // A non-member function declared in a class must be a friend.
++  }
++
++  if (FD->getNumParams() != (IsMethod ? 1 : 2)) {
++    // Let's not worry about using a variadic template pack here -- who would 
do
++    // such a thing?
++    Diag(FD->getLocation(), diag::err_defaulted_comparison_num_args)
++        << int(IsMethod) << int(DCK);
++    return true;
++  }
++
++  const ParmVarDecl *KnownParm = nullptr;
++  for (const ParmVarDecl *Param : FD->parameters()) {
++    QualType ParmTy = Param->getType();
++    if (ParmTy->isDependentType())
++      continue;
++    if (!KnownParm) {
++      auto CTy = ParmTy;
++      // Is it `T const &`?
++      bool Ok = !IsMethod;
++      QualType ExpectedTy;
++      if (RD)
++        ExpectedTy = Context.getRecordType(RD);
++      if (auto *Ref = CTy->getAs<ReferenceType>()) {
++        CTy = Ref->getPointeeType();
++        if (RD)
++          ExpectedTy.addConst();
++        Ok = true;
++      }
++
++      // Is T a class?
++      if (!Ok) {
++      } else if (RD) {
++        if (!RD->isDependentType() && !Context.hasSameType(CTy, ExpectedTy))
++          Ok = false;
++      } else if (auto *CRD = CTy->getAsRecordDecl()) {
++        RD = cast<CXXRecordDecl>(CRD);
++      } else {
++        Ok = false;
++      }
++
++      if (Ok) {
++        KnownParm = Param;
++      } else {
++        // Don't diagnose an implicit 'operator=='; we will have diagnosed the
++        // corresponding defaulted 'operator<=>' already.
++        if (!FD->isImplicit()) {
++          if (RD) {
++            QualType PlainTy = Context.getRecordType(RD);
++            QualType RefTy =
++                Context.getLValueReferenceType(PlainTy.withConst());
++            if (IsMethod)
++              PlainTy = QualType();
++            Diag(FD->getLocation(), diag::err_defaulted_comparison_param)
++                << int(DCK) << ParmTy << RefTy << int(!IsMethod) << PlainTy
++                << Param->getSourceRange();
++          } else {
++            assert(!IsMethod && "should know expected type for method");
++            Diag(FD->getLocation(),
++                 diag::err_defaulted_comparison_param_unknown)
++                << int(DCK) << ParmTy << Param->getSourceRange();
++          }
++        }
++        return true;
++      }
++    } else if (!Context.hasSameType(KnownParm->getType(), ParmTy)) {
++      Diag(FD->getLocation(), diag::err_defaulted_comparison_param_mismatch)
++          << int(DCK) << KnownParm->getType() << KnownParm->getSourceRange()
++          << ParmTy << Param->getSourceRange();
++      return true;
++    }
++  }
++
++  assert(RD && "must have determined class");
++  if (IsMethod) {
++  } else if (isa<CXXRecordDecl>(FD->getLexicalDeclContext())) {
++    // In-class, must be a friend decl.
+     assert(FD->getFriendObjectKind() && "expected a friend declaration");
++  } else {
++    // Out of class, require the defaulted comparison to be a friend (of a
++    // complete type).
++    if (RequireCompleteType(FD->getLocation(), Context.getRecordType(RD),
++                            diag::err_defaulted_comparison_not_friend, 
int(DCK),
++                            int(1)))
++      return true;
++
++    if (llvm::find_if(RD->friends(), [&](const FriendDecl *F) {
++          return FD->getCanonicalDecl() ==
++                 F->getFriendDecl()->getCanonicalDecl();
++        }) == RD->friends().end()) {
++      Diag(FD->getLocation(), diag::err_defaulted_comparison_not_friend)
++          << int(DCK) << int(0) << RD;
++      Diag(RD->getCanonicalDecl()->getLocation(), diag::note_declared_at);
++      return true;
++    }
+   }
+ 
+   // C++2a [class.eq]p1, [class.rel]p1:
+@@ -8606,7 +8668,10 @@ void Sema::DefineDefaultedComparison(SourceLocation Us
+ 
+   {
+     // Build and set up the function body.
+-    CXXRecordDecl *RD = cast<CXXRecordDecl>(FD->getLexicalParent());
++    // The first parameter has type maybe-ref-to maybe-const T, use that to 
get
++    // the type of the class being compared.
++    auto PT = FD->getParamDecl(0)->getType();
++    CXXRecordDecl *RD = PT.getNonReferenceType()->getAsCXXRecordDecl();
+     SourceLocation BodyLoc =
+         FD->getEndLoc().isValid() ? FD->getEndLoc() : FD->getLocation();
+     StmtResult Body =
+@@ -17088,13 +17153,6 @@ void Sema::SetDeclDefaulted(Decl *Dcl, SourceLocation 
+     return;
+   }
+ 
+-  if (DefKind.isComparison() &&
+-      !isa<CXXRecordDecl>(FD->getLexicalDeclContext())) {
+-    Diag(FD->getLocation(), diag::err_defaulted_comparison_out_of_class)
+-        << (int)DefKind.asComparison();
+-    return;
+-  }
+-
+   // Issue compatibility warning. We already warned if the operator is
+   // 'operator<=>' when parsing the '<=>' token.
+   if (DefKind.isComparison() &&
+@@ -17116,31 +17174,37 @@ void Sema::SetDeclDefaulted(Decl *Dcl, 
SourceLocation 
+   // that we've marked it as defaulted.
+   FD->setWillHaveBody(false);
+ 
+-  // If this definition appears within the record, do the checking when
+-  // the record is complete. This is always the case for a defaulted
+-  // comparison.
+-  if (DefKind.isComparison())
++  // If this is a comparison's defaulted definition within the record, do
++  // the checking when the record is complete.
++  if (DefKind.isComparison() && 
isa<CXXRecordDecl>(FD->getLexicalDeclContext()))
+     return;
+-  auto *MD = cast<CXXMethodDecl>(FD);
+ 
+-  const FunctionDecl *Primary = FD;
+-  if (const FunctionDecl *Pattern = FD->getTemplateInstantiationPattern())
+-    // Ask the template instantiation pattern that actually had the
+-    // '= default' on it.
+-    Primary = Pattern;
+-
+-  // If the method was defaulted on its first declaration, we will have
++  // If this member fn was defaulted on its first declaration, we will have
+   // already performed the checking in CheckCompletedCXXClass. Such a
+   // declaration doesn't trigger an implicit definition.
+-  if (Primary->getCanonicalDecl()->isDefaulted())
+-    return;
++  if (isa<CXXMethodDecl>(FD)) {
++    const FunctionDecl *Primary = FD;
++    if (const FunctionDecl *Pattern = FD->getTemplateInstantiationPattern())
++      // Ask the template instantiation pattern that actually had the
++      // '= default' on it.
++      Primary = Pattern;
++    if (Primary->getCanonicalDecl()->isDefaulted())
++      return;
++  }
+ 
+-  // FIXME: Once we support defining comparisons out of class, check for a
+-  // defaulted comparison here.
+-  if (CheckExplicitlyDefaultedSpecialMember(MD, DefKind.asSpecialMember()))
+-    MD->setInvalidDecl();
+-  else
+-    DefineDefaultedFunction(*this, MD, DefaultLoc);
++  if (DefKind.isComparison()) {
++    if (CheckExplicitlyDefaultedComparison(nullptr, FD, 
DefKind.asComparison()))
++      FD->setInvalidDecl();
++    else
++      DefineDefaultedComparison(DefaultLoc, FD, DefKind.asComparison());
++  } else {
++    auto *MD = cast<CXXMethodDecl>(FD);
++
++    if (CheckExplicitlyDefaultedSpecialMember(MD, DefKind.asSpecialMember()))
++      MD->setInvalidDecl();
++    else
++      DefineDefaultedFunction(*this, MD, DefaultLoc);
++  }
+ }
+ 
+ static void SearchForReturnInStmt(Sema &Self, Stmt *S) {
blob - 6dedd0a41206299b7d4301a14878aa270e85b5cf
blob + b46162dda0014a1d6e0389f60a1883da6f9e9063
--- devel/llvm/patches/patch-tools_lld_ELF_Symbols_h
+++ devel/llvm/patches/patch-tools_lld_ELF_Symbols_h
@@ -1,10 +1,30 @@
-Generate __data_start symbol that marks the start of .data when __data_start
-is referenced from code being linked.
+- Generate __data_start symbol that marks the start of .data when __data_start
+  is referenced from code being linked.
+- add .gnu.warning.SYMBOL support to ld.lld(1)
 
 Index: tools/lld/ELF/Symbols.h
 --- tools/lld/ELF/Symbols.h.orig
 +++ tools/lld/ELF/Symbols.h
-@@ -436,6 +436,9 @@ struct ElfSym {
+@@ -142,6 +142,9 @@ class Symbol { (public)
+   // True if this symbol is specified by --trace-symbol option.
+   uint8_t traced : 1;
+ 
++  // True if the .gnu.warning.SYMBOL is set for the symbol
++  uint8_t gwarn : 1;
++
+   inline void replace(const Symbol &newSym);
+ 
+   bool includeInDynsym() const;
+@@ -247,7 +250,7 @@ class Symbol { (public)
+         type(type), stOther(stOther), symbolKind(k), visibility(stOther & 3),
+         isUsedInRegularObj(!file || file->kind() == InputFile::ObjKind),
+         exportDynamic(isExportDynamic(k, visibility)), inDynamicList(false),
+-        canInline(false), referenced(false), traced(false), 
needsPltAddr(false),
++        canInline(false), referenced(false), traced(false), gwarn(false), 
needsPltAddr(false),
+         isInIplt(false), gotInIgot(false), isPreemptible(false),
+         used(!config->gcSections), needsTocRestore(false),
+         scriptDefined(false) {}
+@@ -436,6 +439,9 @@ struct ElfSym {
    // __bss_start
    static Defined *bss;
  
@@ -14,3 +34,20 @@ Index: tools/lld/ELF/Symbols.h
    // etext and _etext
    static Defined *etext1;
    static Defined *etext2;
+@@ -557,6 +563,7 @@ void Symbol::replace(const Symbol &newSym) {
+   canInline = old.canInline;
+   referenced = old.referenced;
+   traced = old.traced;
++  gwarn = old.gwarn;
+   isPreemptible = old.isPreemptible;
+   scriptDefined = old.scriptDefined;
+   partition = old.partition;
+@@ -575,6 +582,8 @@ void Symbol::replace(const Symbol &newSym) {
+ void maybeWarnUnorderableSymbol(const Symbol *sym);
+ bool computeIsPreemptible(const Symbol &sym);
+ void reportBackrefs();
++
++extern llvm::DenseMap<StringRef, StringRef> gnuWarnings;
+ 
+ // A mapping from a symbol to an InputFile referencing it backward. Used by
+ // --warn-backrefs.
blob - /dev/null
blob + da041dcdf835f5b1b069bac9efc5e6c4f5d2042a (mode 644)
--- /dev/null
+++ devel/llvm/patches/patch-tools_lld_ELF_Arch_AArch64_cpp
@@ -0,0 +1,36 @@
+- Enable BTI PLT entries by default.
+
+Index: tools/lld/ELF/Arch/AArch64.cpp
+--- tools/lld/ELF/Arch/AArch64.cpp.orig
++++ tools/lld/ELF/Arch/AArch64.cpp
+@@ -621,7 +621,11 @@ class AArch64BtiPac final : public AArch64 { (private)
+ } // namespace
+ 
+ AArch64BtiPac::AArch64BtiPac() {
++#ifdef __OpenBSD__
++  btiHeader = true;
++#else
+   btiHeader = (config->andFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_BTI);
++#endif
+   // A BTI (Branch Target Indicator) Plt Entry is only required if the
+   // address of the PLT entry can be taken by the program, which permits an
+   // indirect jump to the PLT entry. This can happen when the address
+@@ -717,6 +721,10 @@ void AArch64BtiPac::writePlt(uint8_t *buf, const Symbo
+ }
+ 
+ static TargetInfo *getTargetInfo() {
++#ifdef __OpenBSD__
++  static AArch64BtiPac t;
++  return &t;
++#else
+   if (config->andFeatures & (GNU_PROPERTY_AARCH64_FEATURE_1_BTI |
+                              GNU_PROPERTY_AARCH64_FEATURE_1_PAC)) {
+     static AArch64BtiPac t;
+@@ -724,6 +732,7 @@ static TargetInfo *getTargetInfo() {
+   }
+   static AArch64 t;
+   return &t;
++#endif
+ }
+ 
+ TargetInfo *elf::getAArch64TargetInfo() { return getTargetInfo(); }
blob - 1e4982eb100ff36a086bf2e8af1db77c1079843e
blob + 2bdedcb23daa10e1ccec593a81b3ff60fbdfc085
--- devel/llvm/patches/patch-tools_lld_ELF_Writer_cpp
+++ devel/llvm/patches/patch-tools_lld_ELF_Writer_cpp
@@ -4,6 +4,11 @@
   is referenced from code being linked.
 - Put .got.plt in RELRO.
 - On i386, produce binaries that are compatible with our W^X implementation.
+- In the linkers, collect objects in section "openbsd.mutable" and place
+  them into a page-aligned region in the bss, with the right markers for
+  kernel/ld.so to identify the region and skip making it immutable.
+- Implement support for PT_OPENBSD_NOBTCFI in lld(1).  This can be set using
+  the -z nobtcfi option.
 
 Index: tools/lld/ELF/Writer.cpp
 --- tools/lld/ELF/Writer.cpp.orig
@@ -14,7 +19,7 @@ Index: tools/lld/ELF/Writer.cpp
          ".bss.", ".init_array.", ".fini_array.", ".ctors.", ".dtors.", 
".tbss.",
 -        ".gcc_except_table.", ".tdata.", ".ARM.exidx.", ".ARM.extab."})
 +        ".gcc_except_table.", ".tdata.", ".ARM.exidx.", ".ARM.extab.",
-+        ".openbsd.randomdata."})
++        ".openbsd.randomdata.", ".openbsd.mutable." })
      if (isSectionPrefix(v, s->name))
        return v.drop_back();
  
@@ -48,7 +53,32 @@ Index: tools/lld/ELF/Writer.cpp
    // Setup MIPS _gp_disp/__gnu_local_gp symbols which should
    // be equal to the _gp symbol's value.
    if (ElfSym::mipsGp) {
-@@ -2576,6 +2585,31 @@ template <class ELFT> void Writer<ELFT>::fixSectionAli
+@@ -2461,6 +2470,12 @@ std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs(Par
+     addHdr(PT_GNU_EH_FRAME, part.ehFrameHdr->getParent()->getPhdrFlags())
+         ->add(part.ehFrameHdr->getParent());
+ 
++  // PT_OPENBSD_MUTABLE is an OpenBSD-specific feature. That makes
++  // the dynamic linker fill the segment with zero data, like bss, but
++  // it can be treated differently.
++  if (OutputSection *cmd = findSection(".openbsd.mutable", partNo))
++    addHdr(PT_OPENBSD_MUTABLE, cmd->getPhdrFlags())->add(cmd);
++
+   // PT_OPENBSD_RANDOMIZE is an OpenBSD-specific feature. That makes
+   // the dynamic linker fill the segment with random data.
+   if (OutputSection *cmd = findSection(".openbsd.randomdata", partNo))
+@@ -2484,6 +2499,11 @@ std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs(Par
+   if (config->zWxneeded)
+     addHdr(PT_OPENBSD_WXNEEDED, PF_X);
+ 
++  // PT_OPENBSD_NOBTCFI is an OpenBSD-specific header to mark that the
++  // executable is expected to violate branch-target CFI checks.
++  if (config->zNoBtCfi)
++    addHdr(PT_OPENBSD_NOBTCFI, PF_X);
++
+   if (OutputSection *cmd = findSection(".note.gnu.property", partNo))
+     addHdr(PT_GNU_PROPERTY, PF_R)->add(cmd);
+ 
+@@ -2576,6 +2596,31 @@ template <class ELFT> void Writer<ELFT>::fixSectionAli
          };
      }
    };
blob - /dev/null
blob + 3be40082420c4cb90b07e97311c0dbc2b1e41b76 (mode 644)
--- /dev/null
+++ devel/llvm/patches/patch-tools_lld_ELF_Arch_PPC64_cpp
@@ -0,0 +1,59 @@
+- Change the emitted .glink stub on powerpc64 to use an instruction sequence
+  to compose the offset to the PLT instead of having a constant pool in .text.
+  Make --execute-only work on powerpc64.
+
+Index: tools/lld/ELF/Arch/PPC64.cpp
+--- tools/lld/ELF/Arch/PPC64.cpp.orig
++++ tools/lld/ELF/Arch/PPC64.cpp
+@@ -573,7 +573,11 @@ PPC64::PPC64() {
+   relativeRel = R_PPC64_RELATIVE;
+   iRelativeRel = R_PPC64_IRELATIVE;
+   symbolicRel = R_PPC64_ADDR64;
++#ifdef __OpenBSD__
++  pltHeaderSize = 52;
++#else
+   pltHeaderSize = 60;
++#endif
+   pltEntrySize = 4;
+   ipltEntrySize = 16; // PPC64PltCallStub::size
+   gotBaseSymInGotPlt = false;
+@@ -1072,26 +1076,38 @@ void PPC64::writeGotHeader(uint8_t *buf) const {
+ }
+ 
+ void PPC64::writePltHeader(uint8_t *buf) const {
++  int64_t gotPltOffset = in.gotPlt->getVA() - (in.plt->getVA() + 8);
++
+   // The generic resolver stub goes first.
+   write32(buf +  0, 0x7c0802a6); // mflr r0
+   write32(buf +  4, 0x429f0005); // bcl  20,4*cr7+so,8 <_glink+0x8>
+   write32(buf +  8, 0x7d6802a6); // mflr r11
+   write32(buf + 12, 0x7c0803a6); // mtlr r0
+   write32(buf + 16, 0x7d8b6050); // subf r12, r11, r12
++#ifdef __OpenBSD__
++  write32(buf + 20, 0x380cffd4); // subi r0,r12,44
++#else
+   write32(buf + 20, 0x380cffcc); // subi r0,r12,52
++#endif
+   write32(buf + 24, 0x7800f082); // srdi r0,r0,62,2
++#ifdef __OpenBSD__
++  write32(buf + 28, 0x3d6b0000 | ha(gotPltOffset)); // addis r11,r11,offset@ha
++  write32(buf + 32, 0x396b0000 | lo(gotPltOffset)); // addi  r11,r11,offset@l
++#else
+   write32(buf + 28, 0xe98b002c); // ld   r12,44(r11)
+   write32(buf + 32, 0x7d6c5a14); // add  r11,r12,r11
++#endif
+   write32(buf + 36, 0xe98b0000); // ld   r12,0(r11)
+   write32(buf + 40, 0xe96b0008); // ld   r11,8(r11)
+   write32(buf + 44, 0x7d8903a6); // mtctr   r12
+   write32(buf + 48, 0x4e800420); // bctr
+ 
++#ifndef __OpenBSD__
+   // The 'bcl' instruction will set the link register to the address of the
+   // following instruction ('mflr r11'). Here we store the offset from that
+   // instruction  to the first entry in the GotPlt section.
+-  int64_t gotPltOffset = in.gotPlt->getVA() - (in.plt->getVA() + 8);
+   write64(buf + 52, gotPltOffset);
++#endif
+ }
+ 
+ void PPC64::writePlt(uint8_t *buf, const Symbol &sym,
blob - /dev/null
blob + f6afd3a194ee657e535bc05d940f035ae02f349a (mode 644)
--- /dev/null
+++ devel/llvm/patches/patch-tools_lld_ELF_Arch_RISCV_cpp
@@ -0,0 +1,16 @@
+- Downgrade RISCV ABI mismatch error to a warning
+
+Index: tools/lld/ELF/Arch/RISCV.cpp
+--- tools/lld/ELF/Arch/RISCV.cpp.orig
++++ tools/lld/ELF/Arch/RISCV.cpp
+@@ -124,8 +124,8 @@ uint32_t RISCV::calcEFlags() const {
+       target |= EF_RISCV_RVC;
+ 
+     if ((eflags & EF_RISCV_FLOAT_ABI) != (target & EF_RISCV_FLOAT_ABI))
+-      error(toString(f) +
+-            ": cannot link object files with different floating-point ABI");
++      warn(toString(f) +
++            ": linking object files with different floating-point ABI");
+ 
+     if ((eflags & EF_RISCV_RVE) != (target & EF_RISCV_RVE))
+       error(toString(f) +
blob - /dev/null
blob + e0f5e48dec9cb2fd4a3cdeddfc3cd6a2024ee358 (mode 644)
--- /dev/null
+++ devel/llvm/patches/patch-tools_lld_ELF_Arch_X86_64_cpp
@@ -0,0 +1,72 @@
+- Add IBT support to the retpoline PLTs.  Since we use retpoline PLTs by
+  default on OpenBSD this will give us IBT support by default.  Fixes
+  indirect function calls for functions in shared libraries.
+- Add IBT support to the retpoline+znow PLTs
+
+Index: tools/lld/ELF/Arch/X86_64.cpp
+--- tools/lld/ELF/Arch/X86_64.cpp.orig
++++ tools/lld/ELF/Arch/X86_64.cpp
+@@ -1050,7 +1050,7 @@ Retpoline::Retpoline() {
+ }
+ 
+ void Retpoline::writeGotPlt(uint8_t *buf, const Symbol &s) const {
+-  write64le(buf, s.getPltVA() + 17);
++  write64le(buf, s.getPltVA() + 21);
+ }
+ 
+ void Retpoline::writePltHeader(uint8_t *buf) const {
+@@ -1078,22 +1078,23 @@ void Retpoline::writePltHeader(uint8_t *buf) const {
+ void Retpoline::writePlt(uint8_t *buf, const Symbol &sym,
+                          uint64_t pltEntryAddr) const {
+   const uint8_t insn[] = {
+-      0x4c, 0x8b, 0x1d, 0, 0, 0, 0, // 0:  mov foo@GOTPLT(%rip), %r11
+-      0xe8, 0,    0,    0,    0,    // 7:  callq plt+0x20
+-      0xe9, 0,    0,    0,    0,    // c:  jmp plt+0x12
+-      0x68, 0,    0,    0,    0,    // 11: pushq <relocation index>
+-      0xe9, 0,    0,    0,    0,    // 16: jmp plt+0
+-      0xcc, 0xcc, 0xcc, 0xcc, 0xcc, // 1b: int3; padding
++      0xf3, 0x0f, 0x1e, 0xfa,       // 0:  endbr64
++      0x4c, 0x8b, 0x1d, 0, 0, 0, 0, // 4:  mov foo@GOTPLT(%rip), %r11
++      0xe8, 0,    0,    0,    0,    // b:  callq plt+0x20
++      0xe9, 0,    0,    0,    0,    // 10:  jmp plt+0x12
++      0x68, 0,    0,    0,    0,    // 15: pushq <relocation index>
++      0xe9, 0,    0,    0,    0,    // 1a: jmp plt+0
++      0xcc,                         // 1f: int3; padding
+   };
+   memcpy(buf, insn, sizeof(insn));
+ 
+   uint64_t off = pltEntryAddr - in.plt->getVA();
+ 
+-  write32le(buf + 3, sym.getGotPltVA() - pltEntryAddr - 7);
+-  write32le(buf + 8, -off - 12 + 32);
+-  write32le(buf + 13, -off - 17 + 18);
+-  write32le(buf + 18, sym.pltIndex);
+-  write32le(buf + 23, -off - 27);
++  write32le(buf + 7, sym.getGotPltVA() - pltEntryAddr - 11);
++  write32le(buf + 12, -off - 16 + 32);
++  write32le(buf + 17, -off - 21 + 18);
++  write32le(buf + 22, sym.pltIndex);
++  write32le(buf + 27, -off - 31);
+ }
+ 
+ RetpolineZNow::RetpolineZNow() {
+@@ -1121,14 +1122,14 @@ void RetpolineZNow::writePltHeader(uint8_t *buf) const
+ void RetpolineZNow::writePlt(uint8_t *buf, const Symbol &sym,
+                              uint64_t pltEntryAddr) const {
+   const uint8_t insn[] = {
+-      0x4c, 0x8b, 0x1d, 0,    0, 0, 0, // mov foo@GOTPLT(%rip), %r11
+-      0xe9, 0,    0,    0,    0,       // jmp plt+0
+-      0xcc, 0xcc, 0xcc, 0xcc,          // int3; padding
++      0xf3, 0x0f, 0x1e, 0xfa,          // 0: endbr64
++      0x4c, 0x8b, 0x1d, 0,    0, 0, 0, // 4: mov foo@GOTPLT(%rip), %r11
++      0xe9, 0,    0,    0,    0,       // b: jmp plt+0
+   };
+   memcpy(buf, insn, sizeof(insn));
+ 
+-  write32le(buf + 3, sym.getGotPltVA() - pltEntryAddr - 7);
+-  write32le(buf + 8, in.plt->getVA() - pltEntryAddr - 12);
++  write32le(buf + 7, sym.getGotPltVA() - pltEntryAddr - 11);
++  write32le(buf + 12, in.plt->getVA() - pltEntryAddr - 16);
+ }
+ 
+ static TargetInfo *getTargetInfo() {
blob - /dev/null
blob + cc6362a730c91a8a0c2675e8b7b2bfd2cf1c6c0b (mode 644)
--- /dev/null
+++ devel/llvm/patches/patch-tools_lld_ELF_InputFiles_cpp
@@ -0,0 +1,83 @@
+- lld: do not report undefined weak references in shared libraries
+  
https://github.com/llvm/llvm-project/commit/52bfd2c1ccd86ff813ee6df5a6700690acdd
+- add .gnu.warning.SYMBOL support to ld.lld(1)
+
+Index: tools/lld/ELF/InputFiles.cpp
+--- tools/lld/ELF/InputFiles.cpp.orig
++++ tools/lld/ELF/InputFiles.cpp
+@@ -52,6 +52,8 @@ std::vector<SharedFile *> elf::sharedFiles;
+ 
+ std::unique_ptr<TarWriter> elf::tar;
+ 
++DenseMap<StringRef, StringRef> elf::gnuWarnings;
++
+ // Returns "<internal>", "foo.a(bar.o)" or "baz.o".
+ std::string lld::toString(const InputFile *f) {
+   if (!f)
+@@ -66,6 +68,17 @@ std::string lld::toString(const InputFile *f) {
+   return f->toStringCache;
+ }
+ 
++// .gnu.warning.SYMBOL are treated as warning symbols for the given symbol
++void lld::parseGNUWarning(StringRef name, ArrayRef<char> data, size_t size) {
++  if (!name.empty() && name.startswith(".gnu.warning.")) {
++    StringRef wsym = name.substr(13);
++    StringRef s(data.begin());
++    StringRef wng(s.substr(0, size));
++    symtab->insert(wsym)->gwarn = true;
++    gnuWarnings.insert({wsym, wng});
++  }
++}
++
+ static ELFKind getELFKind(MemoryBufferRef mb, StringRef archiveName) {
+   unsigned char size;
+   unsigned char endian;
+@@ -647,6 +660,14 @@ void ObjFile<ELFT>::initializeSections(bool ignoreComd
+     case SHT_RELA:
+     case SHT_NULL:
+       break;
++    case SHT_PROGBITS: {
++      this->sections[i] = createInputSection(sec);
++      StringRef name = CHECK(obj.getSectionName(sec, 
this->sectionStringTable), this);
++      ArrayRef<char> data =
++          CHECK(obj.template getSectionContentsAsArray<char>(sec), this);
++      parseGNUWarning(name, data, sec.sh_size);
++      }
++      break;
+     default:
+       this->sections[i] = createInputSection(sec);
+     }
+@@ -1450,6 +1471,9 @@ template <class ELFT> void SharedFile::parse() {
+   const ELFFile<ELFT> obj = this->getObj<ELFT>();
+   ArrayRef<Elf_Shdr> sections = CHECK(obj.sections(), this);
+ 
++  StringRef sectionStringTable =
++      CHECK(obj.getSectionStringTable(sections), this);
++
+   const Elf_Shdr *versymSec = nullptr;
+   const Elf_Shdr *verdefSec = nullptr;
+   const Elf_Shdr *verneedSec = nullptr;
+@@ -1472,7 +1496,14 @@ template <class ELFT> void SharedFile::parse() {
+     case SHT_GNU_verneed:
+       verneedSec = &sec;
+       break;
++    case SHT_PROGBITS: {
++      StringRef name = CHECK(obj.getSectionName(sec, sectionStringTable), 
this);
++      ArrayRef<char> data =
++          CHECK(obj.template getSectionContentsAsArray<char>(sec), this);
++      parseGNUWarning(name, data, sec.sh_size);
++      break;
+     }
++    }
+   }
+ 
+   if (versymSec && numELFSyms == 0) {
+@@ -1567,7 +1598,7 @@ template <class ELFT> void SharedFile::parse() {
+       Symbol *s = symtab->addSymbol(
+           Undefined{this, name, sym.getBinding(), sym.st_other, 
sym.getType()});
+       s->exportDynamic = true;
+-      if (s->isUndefined() && !s->isWeak() &&
++      if (s->isUndefined() && sym.getBinding() != STB_WEAK &&
+           config->unresolvedSymbolsInShlib != UnresolvedPolicy::Ignore)
+         requiredSymbols.push_back(s);
+       continue;
blob - /dev/null
blob + 744dcfbbaf4db0ab61e0dc05bff6b55a2db35643 (mode 644)
--- /dev/null
+++ devel/llvm/patches/patch-tools_lld_ELF_InputFiles_h
@@ -0,0 +1,14 @@
+- add .gnu.warning.SYMBOL support to ld.lld(1)
+
+Index: tools/lld/ELF/InputFiles.h
+--- tools/lld/ELF/InputFiles.h.orig
++++ tools/lld/ELF/InputFiles.h
+@@ -37,6 +37,8 @@ class DWARFCache;
+ // Returns "<internal>", "foo.a(bar.o)" or "baz.o".
+ std::string toString(const elf::InputFile *f);
+ 
++void parseGNUWarning(StringRef name, ArrayRef<char> data, size_t size);
++
+ namespace elf {
+ 
+ using llvm::object::Archive;
blob - /dev/null
blob + c2dd12eb2fa1a45d116a281b05e40c25f9cc8441 (mode 644)
--- /dev/null
+++ devel/llvm/patches/patch-tools_lld_ELF_Relocations_cpp
@@ -0,0 +1,33 @@
+- add .gnu.warning.SYMBOL support to ld.lld(1)
+
+Index: tools/lld/ELF/Relocations.cpp
+--- tools/lld/ELF/Relocations.cpp.orig
++++ tools/lld/ELF/Relocations.cpp
+@@ -954,6 +954,18 @@ template <class ELFT> void elf::reportUndefinedSymbols
+   undefs.clear();
+ }
+ 
++static void reportGNUWarning(Symbol &sym, InputSectionBase &sec,
++                                 uint64_t offset) {
++  if (sym.gwarn) {
++    StringRef gnuWarning = gnuWarnings.lookup(sym.getName());
++    // report first occurance only
++    sym.gwarn = false;
++    if (!gnuWarning.empty())
++      message(sec.getSrcMsg(sym, offset) + "(" + sec.getObjMsg(offset) +
++              "): warning: " + gnuWarning);
++  }
++}
++
+ // Report an undefined symbol if necessary.
+ // Returns true if the undefined symbol will produce an error message.
+ static bool maybeReportUndefined(Symbol &sym, InputSectionBase &sec,
+@@ -1326,6 +1338,8 @@ static void scanReloc(InputSectionBase &sec, OffsetGet
+   // marker relocations, e.g. R_*_NONE and R_ARM_V4BX. Don't error on them.
+   if (symIndex != 0 && maybeReportUndefined(sym, sec, rel.r_offset))
+     return;
++
++  reportGNUWarning(sym, sec, rel.r_offset);
+ 
+   const uint8_t *relocatedAddr = sec.data().begin() + rel.r_offset;
+   RelExpr expr = target->getRelExpr(type, sym, relocatedAddr);
blob - /dev/null
blob + 7457267fce43a6d5d8bc7e45ab703b773becad74 (mode 644)
--- /dev/null
+++ devel/llvm/patches/patch-tools_lld_ELF_ScriptParser_cpp
@@ -0,0 +1,15 @@
+- In the linkers, collect objects in section "openbsd.mutable" and place
+  them into a page-aligned region in the bss, with the right markers for
+  kernel/ld.so to identify the region and skip making it immutable.
+
+Index: tools/lld/ELF/ScriptParser.cpp
+--- tools/lld/ELF/ScriptParser.cpp.orig
++++ tools/lld/ELF/ScriptParser.cpp
+@@ -1478,6 +1478,7 @@ unsigned ScriptParser::readPhdrType() {
+                      .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME)
+                      .Case("PT_GNU_STACK", PT_GNU_STACK)
+                      .Case("PT_GNU_RELRO", PT_GNU_RELRO)
++                     .Case("PT_OPENBSD_MUTABLE", PT_OPENBSD_MUTABLE)
+                      .Case("PT_OPENBSD_RANDOMIZE", PT_OPENBSD_RANDOMIZE)
+                      .Case("PT_OPENBSD_WXNEEDED", PT_OPENBSD_WXNEEDED)
+                      .Case("PT_OPENBSD_BOOTDATA", PT_OPENBSD_BOOTDATA)
blob - /dev/null
blob + c95f3c77d16aef2c01387a54e5f5348c4fe3da49 (mode 644)
--- /dev/null
+++ devel/llvm/patches/patch-tools_lld_ELF_SymbolTable_cpp
@@ -0,0 +1,13 @@
+- add .gnu.warning.SYMBOL support to ld.lld(1)
+
+Index: tools/lld/ELF/SymbolTable.cpp
+--- tools/lld/ELF/SymbolTable.cpp.orig
++++ tools/lld/ELF/SymbolTable.cpp
+@@ -90,6 +90,7 @@ Symbol *SymbolTable::insert(StringRef name) {
+   sym->canInline = true;
+   sym->referenced = false;
+   sym->traced = false;
++  sym->gwarn = false;
+   sym->scriptDefined = false;
+   sym->partition = 1;
+   return sym;
blob - /dev/null
blob + e82e925b038ff7e73c0137d3ea524b12e626298c (mode 644)
--- /dev/null
+++ devel/llvm/patches/patch-tools_lld_ELF_SyntheticSections_cpp
@@ -0,0 +1,15 @@
+- Don't create IBT .plt if there are no PLT entries.  Cherry picked from
+  upstream.
+
+Index: tools/lld/ELF/SyntheticSections.cpp
+--- tools/lld/ELF/SyntheticSections.cpp.orig
++++ tools/lld/ELF/SyntheticSections.cpp
+@@ -2729,6 +2729,8 @@ size_t IBTPltSection::getSize() const {
+   return 16 + in.plt->getNumEntries() * target->pltEntrySize;
+ }
+ 
++bool IBTPltSection::isNeeded() const { return in.plt->getNumEntries() > 0; }
++
+ // The string hash function for .gdb_index.
+ static uint32_t computeGdbHash(StringRef s) {
+   uint32_t h = 0;
blob - /dev/null
blob + 9901ccfdefa05f7c2c140e413de6d0a963a4d023 (mode 644)
--- /dev/null
+++ devel/llvm/patches/patch-tools_lld_ELF_SyntheticSections_h
@@ -0,0 +1,14 @@
+- Don't create IBT .plt if there are no PLT entries.  Cherry picked from
+  upstream.
+
+Index: tools/lld/ELF/SyntheticSections.h
+--- tools/lld/ELF/SyntheticSections.h.orig
++++ tools/lld/ELF/SyntheticSections.h
+@@ -769,6 +769,7 @@ class IBTPltSection : public SyntheticSection {
+ public:
+   IBTPltSection();
+   void writeTo(uint8_t *Buf) override;
++  bool isNeeded() const override;
+   size_t getSize() const override;
+ };
+ 
blob - /dev/null
blob + 8e5b0380572499a51ea1e500d0bdd903ca3b5a1f (mode 644)
--- /dev/null
+++ devel/llvm/patches/patch-tools_lld_docs_ld_lld_1
@@ -0,0 +1,16 @@
+- sync --execute-only archs described in the manual with current code
+
+Index: tools/lld/docs/ld.lld.1
+--- tools/lld/docs/ld.lld.1.orig
++++ tools/lld/docs/ld.lld.1
+@@ -212,7 +212,9 @@ followed by the name of the missing library.
+ followed by the name of the undefined symbol.
+ .It Fl -execute-only
+ Mark executable sections unreadable.
+-This option is currently only supported on AArch64.
++This option is currently supported on x86-32, x86-64 (default),
++AArch64 (default), MIPS64, PowerPC32 (default), PowerPC64 (default),
++RISC-V (default), and SPARC64 (default).
+ .It Fl -exclude-libs Ns = Ns Ar value
+ Exclude static libraries from automatic export.
+ .It Fl -export-dynamic , Fl E
blob - /dev/null
blob + 96280047558abc895aabf65cf246a1023796d73f (mode 644)
--- /dev/null
+++ devel/llvm/patches/patch-tools_llvm-ar_llvm-ar_cpp
@@ -0,0 +1,64 @@
+- add a dummy -t flag to llvm-ranlib to match binutils' ranlib's -t flag which
+  is a no-op
+- support more than one input file in llvm-ranlib
+
+Index: tools/llvm-ar/llvm-ar.cpp
+--- tools/llvm-ar/llvm-ar.cpp.orig
++++ tools/llvm-ar/llvm-ar.cpp
+@@ -63,9 +63,9 @@ static StringRef Stem;
+ 
+ const char RanlibHelp[] = R"(OVERVIEW: LLVM Ranlib (llvm-ranlib)
+ 
+-  This program generates an index to speed access to archives
++  Generate an index for archives
+ 
+-USAGE: llvm-ranlib <archive-file>
++USAGE: llvm-ranlib archive...
+ 
+ OPTIONS:
+   -h --help             - Display available options
+@@ -1224,7 +1224,7 @@ static int ar_main(int argc, char **argv) {
+ }
+ 
+ static int ranlib_main(int argc, char **argv) {
+-  bool ArchiveSpecified = false;
++  std::vector<StringRef> Archives;
+   for (int i = 1; i < argc; ++i) {
+     StringRef arg(argv[i]);
+     if (handleGenericOption(arg)) {
+@@ -1242,23 +1242,27 @@ static int ranlib_main(int argc, char **argv) {
+         } else if (arg.front() == 'v') {
+           cl::PrintVersionMessage();
+           return 0;
++        } else if (arg.front() == 't') {
++          // GNU ranlib also supports a -t flag, but does nothing
++          // because it just returns true without touching the
++          // timestamp, so simulate the same behaviour.
++          return 0;
+         } else {
+-          // TODO: GNU ranlib also supports a -t flag
+           fail("Invalid option: '-" + arg + "'");
+         }
+         arg = arg.drop_front(1);
+       }
+     } else {
+-      if (ArchiveSpecified)
+-        fail("exactly one archive should be specified");
+-      ArchiveSpecified = true;
+-      ArchiveName = arg.str();
++      Archives.push_back(arg);
+     }
+   }
+-  if (!ArchiveSpecified) {
+-    badUsage("an archive name must be specified");
++  for (StringRef Archive : Archives) {
++    ArchiveName = Archive.str();
++    performOperation(CreateSymTab, nullptr);
+   }
+-  return performOperation(CreateSymTab, nullptr);
++  if (Archives.empty())
++    badUsage("an archive name must be specified");
++  return 0;
+ }
+ 
+ int main(int argc, char **argv) {
blob - /dev/null
blob + 28dd2e4890eec490f94295177d9392d96a8685f3 (mode 644)
--- /dev/null
+++ devel/llvm/patches/patch-tools_llvm-objdump_ELFDump_cpp
@@ -0,0 +1,31 @@
+- Recognize PT_OPENBSD_MUTABLE with LLVM's readobj / objdump.
+- correct alignment
+- Implement support for PT_OPENBSD_NOBTCFI in lld(1).  This can be set using
+  the -z nobtcfi option.
+
+Index: tools/llvm-objdump/ELFDump.cpp
+--- tools/llvm-objdump/ELFDump.cpp.orig
++++ tools/llvm-objdump/ELFDump.cpp
+@@ -244,13 +244,19 @@ static void printProgramHeaders(const ELFFile<ELFT> &O
+       outs() << "    NOTE ";
+       break;
+     case ELF::PT_OPENBSD_BOOTDATA:
+-      outs() << "    OPENBSD_BOOTDATA ";
++      outs() << "OPENBSD_BOOTDATA ";
+       break;
++    case ELF::PT_OPENBSD_MUTABLE:
++      outs() << "OPENBSD_MUTABLE ";
++      break;
++    case ELF::PT_OPENBSD_NOBTCFI:
++      outs() << "OPENBSD_NOBTCFI ";
++      break;
+     case ELF::PT_OPENBSD_RANDOMIZE:
+-      outs() << "    OPENBSD_RANDOMIZE ";
++      outs() << "OPENBSD_RANDOMIZE ";
+       break;
+     case ELF::PT_OPENBSD_WXNEEDED:
+-      outs() << "    OPENBSD_WXNEEDED ";
++      outs() << "OPENBSD_WXNEEDED ";
+       break;
+     case ELF::PT_PHDR:
+       outs() << "    PHDR ";
blob - /dev/null
blob + 29c1bafe575bbc88eedded9ffc25e082159d38ba (mode 644)
--- /dev/null
+++ devel/llvm/patches/patch-tools_llvm-readobj_ELFDumper_cpp
@@ -0,0 +1,18 @@
+- Recognize PT_OPENBSD_MUTABLE with LLVM's readobj / objdump.
+- Implement support for PT_OPENBSD_NOBTCFI in lld(1).  This can be set using
+  the -z nobtcfi option.
+
+Index: tools/llvm-readobj/ELFDumper.cpp
+--- tools/llvm-readobj/ELFDumper.cpp.orig
++++ tools/llvm-readobj/ELFDumper.cpp
+@@ -1369,8 +1369,10 @@ static StringRef segmentTypeToString(unsigned Arch, un
+     LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_RELRO);
+     LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_PROPERTY);
+ 
++    LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_MUTABLE);
+     LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_RANDOMIZE);
+     LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_WXNEEDED);
++    LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_NOBTCFI);
+     LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_BOOTDATA);
+   default:
+     return "";

-- 
Christian "naddy" Weisgerber                          [email protected]

Reply via email to