Page MenuHomeFreeBSD

Update LLVM libunwind to upstream trunk r351319
AbandonedPublic

Authored by dim on Mar 10 2019, 4:30 PM.
Tags
None
Referenced Files
F86615689: D19529.diff
Sun, Jun 23, 2:11 AM
Unknown Object (File)
Tue, Jun 11, 2:21 AM
Unknown Object (File)
Sun, Jun 2, 8:58 PM
Unknown Object (File)
Mar 22 2024, 10:24 PM
Unknown Object (File)
Jan 6 2024, 5:29 AM
Unknown Object (File)
Dec 21 2023, 7:15 PM
Unknown Object (File)
Dec 20 2023, 4:27 AM
Unknown Object (File)
Aug 31 2023, 6:50 PM
Subscribers

Details

Reviewers
emaste
jhb
Summary

This is a merge of upstream LLVM libunwind to upstream trunk r351319,
which is just before the release_80 branch was created. After this
merge goes in, I will merge the latest release_80 changes, which are
pretty minor.

I have attempted to keep all the custom changes for riscv support, and
any discrepancies I found for mips support.

For mips, I specifically noticed different cursor sizes, e.g. ours has:

#  if defined(_ABIO32) && _MIPS_SIM == _ABIO32
#    define _LIBUNWIND_TARGET_MIPS_O32 1
#    if defined(__mips_hard_float)
#      define _LIBUNWIND_CONTEXT_SIZE 50
#      define _LIBUNWIND_CURSOR_SIZE 61
#    else
#      define _LIBUNWIND_CONTEXT_SIZE 18
#      define _LIBUNWIND_CURSOR_SIZE 29
#    endif
#  elif defined(_ABIN32) && _MIPS_SIM == _ABIN32
#    define _LIBUNWIND_TARGET_MIPS_NEWABI 1
#    if defined(__mips_hard_float)
#      define _LIBUNWIND_CONTEXT_SIZE 67
#      define _LIBUNWIND_CURSOR_SIZE 78
#    else
#      define _LIBUNWIND_CONTEXT_SIZE 35
#      define _LIBUNWIND_CURSOR_SIZE 46
#    endif
#  elif defined(_ABI64) && _MIPS_SIM == _ABI64
#    define _LIBUNWIND_TARGET_MIPS_NEWABI 1
#    if defined(__mips_hard_float)
#      define _LIBUNWIND_CONTEXT_SIZE 67
#      define _LIBUNWIND_CURSOR_SIZE 79
#    else
#      define _LIBUNWIND_CONTEXT_SIZE 35
#      define _LIBUNWIND_CURSOR_SIZE 47
#    endif

while upstream has:

#  if defined(_ABIO32) && _MIPS_SIM == _ABIO32
#    define _LIBUNWIND_TARGET_MIPS_O32 1
#    if defined(__mips_hard_float)
#      define _LIBUNWIND_CONTEXT_SIZE 50
#      define _LIBUNWIND_CURSOR_SIZE 57
#    else
#      define _LIBUNWIND_CONTEXT_SIZE 18
#      define _LIBUNWIND_CURSOR_SIZE 24
#    endif
#  elif defined(_ABIN32) && _MIPS_SIM == _ABIN32
#    define _LIBUNWIND_TARGET_MIPS_NEWABI 1
#    if defined(__mips_hard_float)
#      define _LIBUNWIND_CONTEXT_SIZE 67
#      define _LIBUNWIND_CURSOR_SIZE 74
#    else
#      define _LIBUNWIND_CONTEXT_SIZE 35
#      define _LIBUNWIND_CURSOR_SIZE 42
#    endif
#  elif defined(_ABI64) && _MIPS_SIM == _ABI64
#    define _LIBUNWIND_TARGET_MIPS_NEWABI 1
#    if defined(__mips_hard_float)
#      define _LIBUNWIND_CONTEXT_SIZE 67
#      define _LIBUNWIND_CURSOR_SIZE 79
#    else
#      define _LIBUNWIND_CONTEXT_SIZE 35
#      define _LIBUNWIND_CURSOR_SIZE 47
#    endif

E.g. most cursor sizes are 4 bytes smaller, and in case of _ABIO32 and
!__mips_hard_float it's even 5 bytes. Somebody with mips-fu should be
able to tell what is correct.

Test Plan

It works for a universe build, and exceptions seem to work for me with
light testing, but I have no way of checking mips, riscv and such.

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
No Lint Coverage
Unit
No Test Coverage
Build Status
Buildable 22987
Build 22065: arc lint + arc unit

Event Timeline

For reference, the full diff between stock LLVM libunwind and the merged version:

diff -upr /share/dim/src/freebsd/vendor/libunwind-dist/include/__libunwind_config.h /usr/src/contrib/llvm/projects/libunwind/include/__libunwind_config.h
--- /share/dim/src/freebsd/vendor/libunwind-dist/include/__libunwind_config.h   2019-03-08 22:49:44.000000000 +0100
+++ /usr/src/contrib/llvm/projects/libunwind/include/__libunwind_config.h       2019-03-09 19:22:57.582506000 +0100
@@ -22,6 +22,7 @@
 #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64     95
 #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM       287
 #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K      32
+#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV     95
 #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS      65
 #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC     31

@@ -82,24 +83,30 @@
 #  define _LIBUNWIND_CONTEXT_SIZE 16
 #  define _LIBUNWIND_CURSOR_SIZE 24
 #  define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K
+# elif defined(__riscv)
+#  define _LIBUNWIND_TARGET_RISCV 1
+#  define _LIBUNWIND_CONTEXT_SIZE 64
+#  define _LIBUNWIND_CURSOR_SIZE 76
+#  define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV
+#  define _LIBUNWIND_MAX_REGISTER 96
 # elif defined(__mips__)
 #  if defined(_ABIO32) && _MIPS_SIM == _ABIO32
 #    define _LIBUNWIND_TARGET_MIPS_O32 1
 #    if defined(__mips_hard_float)
 #      define _LIBUNWIND_CONTEXT_SIZE 50
-#      define _LIBUNWIND_CURSOR_SIZE 57
+#      define _LIBUNWIND_CURSOR_SIZE 61
 #    else
 #      define _LIBUNWIND_CONTEXT_SIZE 18
-#      define _LIBUNWIND_CURSOR_SIZE 24
+#      define _LIBUNWIND_CURSOR_SIZE 29
 #    endif
 #  elif defined(_ABIN32) && _MIPS_SIM == _ABIN32
 #    define _LIBUNWIND_TARGET_MIPS_NEWABI 1
 #    if defined(__mips_hard_float)
 #      define _LIBUNWIND_CONTEXT_SIZE 67
-#      define _LIBUNWIND_CURSOR_SIZE 74
+#      define _LIBUNWIND_CURSOR_SIZE 78
 #    else
 #      define _LIBUNWIND_CONTEXT_SIZE 35
-#      define _LIBUNWIND_CURSOR_SIZE 42
+#      define _LIBUNWIND_CURSOR_SIZE 46
 #    endif
 #  elif defined(_ABI64) && _MIPS_SIM == _ABI64
 #    define _LIBUNWIND_TARGET_MIPS_NEWABI 1
diff -upr /share/dim/src/freebsd/vendor/libunwind-dist/include/libunwind.h /usr/src/contrib/llvm/projects/libunwind/include/libunwind.h
--- /share/dim/src/freebsd/vendor/libunwind-dist/include/libunwind.h    2019-03-08 22:49:43.000000000 +0100
+++ /usr/src/contrib/llvm/projects/libunwind/include/libunwind.h        2019-03-09 13:15:33.858168000 +0100
@@ -167,8 +167,8 @@ enum {
   UNW_X86_ECX = 1,
   UNW_X86_EDX = 2,
   UNW_X86_EBX = 3,
-  UNW_X86_EBP = 4,
-  UNW_X86_ESP = 5,
+  UNW_X86_ESP = 4,
+  UNW_X86_EBP = 5,
   UNW_X86_ESI = 6,
   UNW_X86_EDI = 7
 };
@@ -751,6 +751,77 @@ enum {
   UNW_OR1K_R30 = 30,
   UNW_OR1K_R31 = 31,
   UNW_OR1K_EPCR = 32,
+};
+
+// 64-bit RISC-V registers
+enum {
+  UNW_RISCV_X0  = 0,
+  UNW_RISCV_X1  = 1,
+  UNW_RISCV_RA  = 1,
+  UNW_RISCV_X2  = 2,
+  UNW_RISCV_SP  = 2,
+  UNW_RISCV_X3  = 3,
+  UNW_RISCV_X4  = 4,
+  UNW_RISCV_X5  = 5,
+  UNW_RISCV_X6  = 6,
+  UNW_RISCV_X7  = 7,
+  UNW_RISCV_X8  = 8,
+  UNW_RISCV_X9  = 9,
+  UNW_RISCV_X10 = 10,
+  UNW_RISCV_X11 = 11,
+  UNW_RISCV_X12 = 12,
+  UNW_RISCV_X13 = 13,
+  UNW_RISCV_X14 = 14,
+  UNW_RISCV_X15 = 15,
+  UNW_RISCV_X16 = 16,
+  UNW_RISCV_X17 = 17,
+  UNW_RISCV_X18 = 18,
+  UNW_RISCV_X19 = 19,
+  UNW_RISCV_X20 = 20,
+  UNW_RISCV_X21 = 21,
+  UNW_RISCV_X22 = 22,
+  UNW_RISCV_X23 = 23,
+  UNW_RISCV_X24 = 24,
+  UNW_RISCV_X25 = 25,
+  UNW_RISCV_X26 = 26,
+  UNW_RISCV_X27 = 27,
+  UNW_RISCV_X28 = 28,
+  UNW_RISCV_X29 = 29,
+  UNW_RISCV_X30 = 30,
+  UNW_RISCV_X31 = 31,
+  // reserved block
+  UNW_RISCV_D0  = 64,
+  UNW_RISCV_D1  = 65,
+  UNW_RISCV_D2  = 66,
+  UNW_RISCV_D3  = 67,
+  UNW_RISCV_D4  = 68,
+  UNW_RISCV_D5  = 69,
+  UNW_RISCV_D6  = 70,
+  UNW_RISCV_D7  = 71,
+  UNW_RISCV_D8  = 72,
+  UNW_RISCV_D9  = 73,
+  UNW_RISCV_D10 = 74,
+  UNW_RISCV_D11 = 75,
+  UNW_RISCV_D12 = 76,
+  UNW_RISCV_D13 = 77,
+  UNW_RISCV_D14 = 78,
+  UNW_RISCV_D15 = 79,
+  UNW_RISCV_D16 = 80,
+  UNW_RISCV_D17 = 81,
+  UNW_RISCV_D18 = 82,
+  UNW_RISCV_D19 = 83,
+  UNW_RISCV_D20 = 84,
+  UNW_RISCV_D21 = 85,
+  UNW_RISCV_D22 = 86,
+  UNW_RISCV_D23 = 87,
+  UNW_RISCV_D24 = 88,
+  UNW_RISCV_D25 = 89,
+  UNW_RISCV_D26 = 90,
+  UNW_RISCV_D27 = 91,
+  UNW_RISCV_D28 = 92,
+  UNW_RISCV_D29 = 93,
+  UNW_RISCV_D30 = 94,
+  UNW_RISCV_D31 = 95,
 };

 // MIPS registers
diff -upr /share/dim/src/freebsd/vendor/libunwind-dist/src/Registers.hpp /usr/src/contrib/llvm/projects/libunwind/src/Registers.hpp
--- /share/dim/src/freebsd/vendor/libunwind-dist/src/Registers.hpp      2019-03-09 13:43:05.491300000 +0100
+++ /usr/src/contrib/llvm/projects/libunwind/src/Registers.hpp  2019-03-09 18:54:46.122230000 +0100
@@ -32,6 +32,7 @@ enum {
   REGISTERS_ARM64,
   REGISTERS_ARM,
   REGISTERS_OR1K,
+  REGISTERS_RISCV,
   REGISTERS_MIPS_O32,
   REGISTERS_MIPS_NEWABI,
   REGISTERS_SPARC,
@@ -2721,6 +2722,267 @@ inline const char *Registers_or1k::getRegisterName(int

 }
 #endif // _LIBUNWIND_TARGET_OR1K
+
+#if defined(_LIBUNWIND_TARGET_RISCV)
+/// Registers_riscv holds the register state of a thread in a 64-bit RISC-V
+/// process.
+class _LIBUNWIND_HIDDEN Registers_riscv {
+public:
+  Registers_riscv();
+  Registers_riscv(const void *registers);
+
+  bool        validRegister(int num) const;
+  uint64_t    getRegister(int num) const;
+  void        setRegister(int num, uint64_t value);
+  bool        validFloatRegister(int num) const;
+  double      getFloatRegister(int num) const;
+  void        setFloatRegister(int num, double value);
+  bool        validVectorRegister(int num) const;
+  v128        getVectorRegister(int num) const;
+  void        setVectorRegister(int num, v128 value);
+  static const char *getRegisterName(int num);
+  void        jumpto();
+  static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV; }
+  static int  getArch() { return REGISTERS_RISCV; }
+
+  uint64_t  getSP() const         { return _registers.__x[2]; }
+  void      setSP(uint64_t value) { _registers.__x[2] = value; }
+  uint64_t  getIP() const         { return _registers.__x[1]; }
+  void      setIP(uint64_t value) { _registers.__x[1] = value; }
+
+private:
+  struct GPRs {
+    uint64_t __x[32]; // x0-x31
+  };
+
+  GPRs    _registers;
+  double  _vectorHalfRegisters[32];
+  // Currently only the lower double in 128-bit vectore registers
+  // is perserved during unwinding.  We could define new register
+  // numbers (> 96) which mean whole vector registers, then this
+  // struct would need to change to contain whole vector registers.
+};
+
+inline Registers_riscv::Registers_riscv(const void *registers) {
+  static_assert((check_fit<Registers_riscv, unw_context_t>::does_fit),
+                "riscv registers do not fit into unw_context_t");
+  memcpy(&_registers, registers, sizeof(_registers));
+  static_assert(sizeof(GPRs) == 0x100,
+                "expected VFP registers to be at offset 256");
+  memcpy(_vectorHalfRegisters,
+         static_cast<const uint8_t *>(registers) + sizeof(GPRs),
+         sizeof(_vectorHalfRegisters));
+}
+
+inline Registers_riscv::Registers_riscv() {
+  memset(&_registers, 0, sizeof(_registers));
+  memset(&_vectorHalfRegisters, 0, sizeof(_vectorHalfRegisters));
+}
+
+inline bool Registers_riscv::validRegister(int regNum) const {
+  if (regNum == UNW_REG_IP)
+    return true;
+  if (regNum == UNW_REG_SP)
+    return true;
+  if (regNum < 0)
+    return false;
+  if (regNum > 95)
+    return false;
+  if ((regNum > 31) && (regNum < 64))
+    return false;
+  return true;
+}
+
+inline uint64_t Registers_riscv::getRegister(int regNum) const {
+  if (regNum == UNW_REG_IP)
+    return _registers.__x[1];
+  if (regNum == UNW_REG_SP)
+    return _registers.__x[2];
+  if ((regNum >= 0) && (regNum < 32))
+    return _registers.__x[regNum];
+  _LIBUNWIND_ABORT("unsupported riscv register");
+}
+
+inline void Registers_riscv::setRegister(int regNum, uint64_t value) {
+  if (regNum == UNW_REG_IP)
+    _registers.__x[1] = value;
+  else if (regNum == UNW_REG_SP)
+    _registers.__x[2] = value;
+  else if ((regNum >= 0) && (regNum < 32))
+    _registers.__x[regNum] = value;
+  else
+    _LIBUNWIND_ABORT("unsupported riscv register");
+}
+
+inline const char *Registers_riscv::getRegisterName(int regNum) {
+  switch (regNum) {
+  case UNW_REG_IP:
+    return "ra";
+  case UNW_REG_SP:
+    return "sp";
+  case UNW_RISCV_X0:
+    return "x0";
+  case UNW_RISCV_X1:
+    return "ra";
+  case UNW_RISCV_X2:
+    return "sp";
+  case UNW_RISCV_X3:
+    return "x3";
+  case UNW_RISCV_X4:
+    return "x4";
+  case UNW_RISCV_X5:
+    return "x5";
+  case UNW_RISCV_X6:
+    return "x6";
+  case UNW_RISCV_X7:
+    return "x7";
+  case UNW_RISCV_X8:
+    return "x8";
+  case UNW_RISCV_X9:
+    return "x9";
+  case UNW_RISCV_X10:
+    return "x10";
+  case UNW_RISCV_X11:
+    return "x11";
+  case UNW_RISCV_X12:
+    return "x12";
+  case UNW_RISCV_X13:
+    return "x13";
+  case UNW_RISCV_X14:
+    return "x14";
+  case UNW_RISCV_X15:
+    return "x15";
+  case UNW_RISCV_X16:
+    return "x16";
+  case UNW_RISCV_X17:
+    return "x17";
+  case UNW_RISCV_X18:
+    return "x18";
+  case UNW_RISCV_X19:
+    return "x19";
+  case UNW_RISCV_X20:
+    return "x20";
+  case UNW_RISCV_X21:
+    return "x21";
+  case UNW_RISCV_X22:
+    return "x22";
+  case UNW_RISCV_X23:
+    return "x23";
+  case UNW_RISCV_X24:
+    return "x24";
+  case UNW_RISCV_X25:
+    return "x25";
+  case UNW_RISCV_X26:
+    return "x26";
+  case UNW_RISCV_X27:
+    return "x27";
+  case UNW_RISCV_X28:
+    return "x28";
+  case UNW_RISCV_X29:
+    return "x29";
+  case UNW_RISCV_X30:
+    return "x30";
+  case UNW_RISCV_X31:
+    return "x31";
+  case UNW_RISCV_D0:
+    return "d0";
+  case UNW_RISCV_D1:
+    return "d1";
+  case UNW_RISCV_D2:
+    return "d2";
+  case UNW_RISCV_D3:
+    return "d3";
+  case UNW_RISCV_D4:
+    return "d4";
+  case UNW_RISCV_D5:
+    return "d5";
+  case UNW_RISCV_D6:
+    return "d6";
+  case UNW_RISCV_D7:
+    return "d7";
+  case UNW_RISCV_D8:
+    return "d8";
+  case UNW_RISCV_D9:
+    return "d9";
+  case UNW_RISCV_D10:
+    return "d10";
+  case UNW_RISCV_D11:
+    return "d11";
+  case UNW_RISCV_D12:
+    return "d12";
+  case UNW_RISCV_D13:
+    return "d13";
+  case UNW_RISCV_D14:
+    return "d14";
+  case UNW_RISCV_D15:
+    return "d15";
+  case UNW_RISCV_D16:
+    return "d16";
+  case UNW_RISCV_D17:
+    return "d17";
+  case UNW_RISCV_D18:
+    return "d18";
+  case UNW_RISCV_D19:
+    return "d19";
+  case UNW_RISCV_D20:
+    return "d20";
+  case UNW_RISCV_D21:
+    return "d21";
+  case UNW_RISCV_D22:
+    return "d22";
+  case UNW_RISCV_D23:
+    return "d23";
+  case UNW_RISCV_D24:
+    return "d24";
+  case UNW_RISCV_D25:
+    return "d25";
+  case UNW_RISCV_D26:
+    return "d26";
+  case UNW_RISCV_D27:
+    return "d27";
+  case UNW_RISCV_D28:
+    return "d28";
+  case UNW_RISCV_D29:
+    return "d29";
+  case UNW_RISCV_D30:
+    return "d30";
+  case UNW_RISCV_D31:
+    return "d31";
+  default:
+    return "unknown register";
+  }
+}
+
+inline bool Registers_riscv::validFloatRegister(int regNum) const {
+  if (regNum < UNW_RISCV_D0)
+    return false;
+  if (regNum > UNW_RISCV_D31)
+    return false;
+  return true;
+}
+
+inline double Registers_riscv::getFloatRegister(int regNum) const {
+  assert(validFloatRegister(regNum));
+  return _vectorHalfRegisters[regNum - UNW_RISCV_D0];
+}
+
+inline void Registers_riscv::setFloatRegister(int regNum, double value) {
+  assert(validFloatRegister(regNum));
+  _vectorHalfRegisters[regNum - UNW_RISCV_D0] = value;
+}
+
+inline bool Registers_riscv::validVectorRegister(int) const {
+  return false;
+}
+
+inline v128 Registers_riscv::getVectorRegister(int) const {
+  _LIBUNWIND_ABORT("no riscv vector register support yet");
+}
+
+inline void Registers_riscv::setVectorRegister(int, v128) {
+  _LIBUNWIND_ABORT("no riscv vector register support yet");
+}
+#endif // _LIBUNWIND_TARGET_RISCV

 #if defined(_LIBUNWIND_TARGET_MIPS_O32)
 /// Registers_mips_o32 holds the register state of a thread in a 32-bit MIPS
diff -upr /share/dim/src/freebsd/vendor/libunwind-dist/src/UnwindCursor.hpp /usr/src/contrib/llvm/projects/libunwind/src/UnwindCursor.hpp
--- /share/dim/src/freebsd/vendor/libunwind-dist/src/UnwindCursor.hpp   2019-03-08 22:49:44.000000000 +0100
+++ /usr/src/contrib/llvm/projects/libunwind/src/UnwindCursor.hpp       2019-03-09 13:48:08.457325000 +0100
@@ -1101,6 +1101,12 @@ class UnwindCursor : public AbstractUnwindCursor{ (pri
   }
 #endif

+#if defined (_LIBUNWIND_TARGET_RISCV)
+  compact_unwind_encoding_t dwarfEncoding(Registers_riscv &) const {
+    return 0;
+  }
+#endif
+
 #if defined (_LIBUNWIND_TARGET_MIPS_O32)
   compact_unwind_encoding_t dwarfEncoding(Registers_mips_o32 &) const {
     return 0;
diff -upr /share/dim/src/freebsd/vendor/libunwind-dist/src/UnwindLevel1-gcc-ext.c /usr/src/contrib/llvm/projects/libunwind/src/UnwindLevel1-gcc-ext.c
--- /share/dim/src/freebsd/vendor/libunwind-dist/src/UnwindLevel1-gcc-ext.c     2019-03-08 22:49:44.000000000 +0100
+++ /usr/src/contrib/llvm/projects/libunwind/src/UnwindLevel1-gcc-ext.c 2019-03-09 13:49:04.619733000 +0100
@@ -228,6 +228,47 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetIPInfo(struct _

 #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)

+#ifdef __FreeBSD__
+
+// Based on LLVM's lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp
+// and XXX should be fixed to be alignment-safe.
+static void processFDE(const char *addr, bool isDeregister) {
+  uint64_t length;
+  while ((length = *((const uint32_t *)addr)) != 0) {
+    const char *p = addr + 4;
+    if (length == 0xffffffff) {
+      length = *((const uint64_t *)p);
+      p += 8;
+    }
+    uint32_t offset = *((const uint32_t *)p);
+    if (offset != 0) {
+      if (isDeregister)
+        _unw_remove_dynamic_fde((unw_word_t)(uintptr_t)addr);
+      else
+        _unw_add_dynamic_fde((unw_word_t)(uintptr_t)addr);
+    }
+    addr = p + length;
+  }
+}
+
+/// Called by programs with dynamic code generators that want to register
+/// dynamically generated FDEs, with a libgcc-compatible API.
+
+_LIBUNWIND_EXPORT void __register_frame(const void *addr) {
+  _LIBUNWIND_TRACE_API("__register_frame(%p)", addr);
+  processFDE(addr, false);
+}
+
+/// Called by programs with dynamic code generators that want to unregister
+/// dynamically generated FDEs, with a libgcc-compatible API.
+_LIBUNWIND_EXPORT void __deregister_frame(const void *addr) {
+  _LIBUNWIND_TRACE_API("__deregister_frame(%p)", addr);
+  processFDE(addr, true);
+}
+
+
+#else
+
 /// Called by programs with dynamic code generators that want
 /// to register a dynamically generated FDE.
 /// This function has existed on Mac OS X since 10.4, but
@@ -247,6 +288,7 @@ _LIBUNWIND_EXPORT void __deregister_frame(const void *
   _unw_remove_dynamic_fde((unw_word_t)(uintptr_t) fde);
 }

+#endif

 // The following register/deregister functions are gcc extensions.
 // They have existed on Mac OS X, but have never worked because Mac OS X
diff -upr /share/dim/src/freebsd/vendor/libunwind-dist/src/UnwindRegistersRestore.S /usr/src/contrib/llvm/projects/libunwind/src/UnwindRegistersRestore.S
--- /share/dim/src/freebsd/vendor/libunwind-dist/src/UnwindRegistersRestore.S   2019-03-08 22:49:44.000000000 +0100
+++ /usr/src/contrib/llvm/projects/libunwind/src/UnwindRegistersRestore.S       2019-03-09 16:02:12.049238000 +0100
@@ -801,6 +801,87 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind14Regis
   l.jr     r9
    l.nop

+#elif defined(__riscv)
+
+//
+// void libunwind::Registers_riscv::jumpto()
+//
+// On entry:
+//  thread_state pointer is in a0
+//
+  .p2align 2
+DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind15Registers_riscv6jumptoEv)
+#ifdef __riscv_float_abi_double
+  fld    f0, (8 * 32 + 8 * 0)(a0)
+  fld    f1, (8 * 32 + 8 * 1)(a0)
+  fld    f2, (8 * 32 + 8 * 2)(a0)
+  fld    f3, (8 * 32 + 8 * 3)(a0)
+  fld    f4, (8 * 32 + 8 * 4)(a0)
+  fld    f5, (8 * 32 + 8 * 5)(a0)
+  fld    f6, (8 * 32 + 8 * 6)(a0)
+  fld    f7, (8 * 32 + 8 * 7)(a0)
+  fld    f8, (8 * 32 + 8 * 8)(a0)
+  fld    f9, (8 * 32 + 8 * 9)(a0)
+  fld    f10, (8 * 32 + 8 * 10)(a0)
+  fld    f11, (8 * 32 + 8 * 11)(a0)
+  fld    f12, (8 * 32 + 8 * 12)(a0)
+  fld    f13, (8 * 32 + 8 * 13)(a0)
+  fld    f14, (8 * 32 + 8 * 14)(a0)
+  fld    f15, (8 * 32 + 8 * 15)(a0)
+  fld    f16, (8 * 32 + 8 * 16)(a0)
+  fld    f17, (8 * 32 + 8 * 17)(a0)
+  fld    f18, (8 * 32 + 8 * 18)(a0)
+  fld    f19, (8 * 32 + 8 * 19)(a0)
+  fld    f20, (8 * 32 + 8 * 20)(a0)
+  fld    f21, (8 * 32 + 8 * 21)(a0)
+  fld    f22, (8 * 32 + 8 * 22)(a0)
+  fld    f23, (8 * 32 + 8 * 23)(a0)
+  fld    f24, (8 * 32 + 8 * 24)(a0)
+  fld    f25, (8 * 32 + 8 * 25)(a0)
+  fld    f26, (8 * 32 + 8 * 26)(a0)
+  fld    f27, (8 * 32 + 8 * 27)(a0)
+  fld    f28, (8 * 32 + 8 * 28)(a0)
+  fld    f29, (8 * 32 + 8 * 29)(a0)
+  fld    f30, (8 * 32 + 8 * 30)(a0)
+  fld    f31, (8 * 32 + 8 * 31)(a0)
+#endif
+
+  // x0 is zero
+  ld    x1, (8 * 1)(a0)
+  ld    x2, (8 * 2)(a0)
+  ld    x3, (8 * 3)(a0)
+  ld    x4, (8 * 4)(a0)
+  ld    x5, (8 * 5)(a0)
+  ld    x6, (8 * 6)(a0)
+  ld    x7, (8 * 7)(a0)
+  ld    x8, (8 * 8)(a0)
+  ld    x9, (8 * 9)(a0)
+  // skip a0 for now
+  ld    x11, (8 * 11)(a0)
+  ld    x12, (8 * 12)(a0)
+  ld    x13, (8 * 13)(a0)
+  ld    x14, (8 * 14)(a0)
+  ld    x15, (8 * 15)(a0)
+  ld    x16, (8 * 16)(a0)
+  ld    x17, (8 * 17)(a0)
+  ld    x18, (8 * 18)(a0)
+  ld    x19, (8 * 19)(a0)
+  ld    x20, (8 * 20)(a0)
+  ld    x21, (8 * 21)(a0)
+  ld    x22, (8 * 22)(a0)
+  ld    x23, (8 * 23)(a0)
+  ld    x24, (8 * 24)(a0)
+  ld    x25, (8 * 25)(a0)
+  ld    x26, (8 * 26)(a0)
+  ld    x27, (8 * 27)(a0)
+  ld    x28, (8 * 28)(a0)
+  ld    x29, (8 * 29)(a0)
+  ld    x30, (8 * 30)(a0)
+  ld    x31, (8 * 31)(a0)
+  ld    x10, (8 * 10)(a0)   // restore a0
+
+  ret                       // jump to ra
+
 #elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32

 //
diff -upr /share/dim/src/freebsd/vendor/libunwind-dist/src/UnwindRegistersSave.S /usr/src/contrib/llvm/projects/libunwind/src/UnwindRegistersSave.S
--- /share/dim/src/freebsd/vendor/libunwind-dist/src/UnwindRegistersSave.S      2019-03-08 22:49:43.000000000 +0100
+++ /usr/src/contrib/llvm/projects/libunwind/src/UnwindRegistersSave.S  2019-03-09 16:08:54.229776000 +0100
@@ -943,6 +943,86 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
   # zero epcr
   l.sw     132(r3), r0

+#elif defined(__riscv)
+
+#
+# extern int unw_getcontext(unw_context_t* thread_state)
+#
+# On entry:
+#  thread_state pointer is in a0
+#
+DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
+  // x0 is zero
+  sd    x1, (8 * 1)(a0)
+  sd    x2, (8 * 2)(a0)
+  sd    x3, (8 * 3)(a0)
+  sd    x4, (8 * 4)(a0)
+  sd    x5, (8 * 5)(a0)
+  sd    x6, (8 * 6)(a0)
+  sd    x7, (8 * 7)(a0)
+  sd    x8, (8 * 8)(a0)
+  sd    x9, (8 * 9)(a0)
+  sd    x10, (8 * 10)(a0)
+  sd    x11, (8 * 11)(a0)
+  sd    x12, (8 * 12)(a0)
+  sd    x13, (8 * 13)(a0)
+  sd    x14, (8 * 14)(a0)
+  sd    x15, (8 * 15)(a0)
+  sd    x16, (8 * 16)(a0)
+  sd    x17, (8 * 17)(a0)
+  sd    x18, (8 * 18)(a0)
+  sd    x19, (8 * 19)(a0)
+  sd    x20, (8 * 20)(a0)
+  sd    x21, (8 * 21)(a0)
+  sd    x22, (8 * 22)(a0)
+  sd    x23, (8 * 23)(a0)
+  sd    x24, (8 * 24)(a0)
+  sd    x25, (8 * 25)(a0)
+  sd    x26, (8 * 26)(a0)
+  sd    x27, (8 * 27)(a0)
+  sd    x28, (8 * 28)(a0)
+  sd    x29, (8 * 29)(a0)
+  sd    x30, (8 * 30)(a0)
+  sd    x31, (8 * 31)(a0)
+
+#ifdef __riscv_float_abi_double
+  fsd    f0, (8 * 32 + 8 * 0)(a0)
+  fsd    f1, (8 * 32 + 8 * 1)(a0)
+  fsd    f2, (8 * 32 + 8 * 2)(a0)
+  fsd    f3, (8 * 32 + 8 * 3)(a0)
+  fsd    f4, (8 * 32 + 8 * 4)(a0)
+  fsd    f5, (8 * 32 + 8 * 5)(a0)
+  fsd    f6, (8 * 32 + 8 * 6)(a0)
+  fsd    f7, (8 * 32 + 8 * 7)(a0)
+  fsd    f8, (8 * 32 + 8 * 8)(a0)
+  fsd    f9, (8 * 32 + 8 * 9)(a0)
+  fsd    f10, (8 * 32 + 8 * 10)(a0)
+  fsd    f11, (8 * 32 + 8 * 11)(a0)
+  fsd    f12, (8 * 32 + 8 * 12)(a0)
+  fsd    f13, (8 * 32 + 8 * 13)(a0)
+  fsd    f14, (8 * 32 + 8 * 14)(a0)
+  fsd    f15, (8 * 32 + 8 * 15)(a0)
+  fsd    f16, (8 * 32 + 8 * 16)(a0)
+  fsd    f17, (8 * 32 + 8 * 17)(a0)
+  fsd    f18, (8 * 32 + 8 * 18)(a0)
+  fsd    f19, (8 * 32 + 8 * 19)(a0)
+  fsd    f20, (8 * 32 + 8 * 20)(a0)
+  fsd    f21, (8 * 32 + 8 * 21)(a0)
+  fsd    f22, (8 * 32 + 8 * 22)(a0)
+  fsd    f23, (8 * 32 + 8 * 23)(a0)
+  fsd    f24, (8 * 32 + 8 * 24)(a0)
+  fsd    f25, (8 * 32 + 8 * 25)(a0)
+  fsd    f26, (8 * 32 + 8 * 26)(a0)
+  fsd    f27, (8 * 32 + 8 * 27)(a0)
+  fsd    f28, (8 * 32 + 8 * 28)(a0)
+  fsd    f29, (8 * 32 + 8 * 29)(a0)
+  fsd    f30, (8 * 32 + 8 * 30)(a0)
+  fsd    f31, (8 * 32 + 8 * 31)(a0)
+#endif
+
+  li     a0, 0  // return UNW_ESUCCESS
+  ret           // jump to ra
+
 #elif defined(__sparc__)

 #
diff -upr /share/dim/src/freebsd/vendor/libunwind-dist/src/config.h /usr/src/contrib/llvm/projects/libunwind/src/config.h
--- /share/dim/src/freebsd/vendor/libunwind-dist/src/config.h   2019-03-08 22:49:44.000000000 +0100
+++ /usr/src/contrib/llvm/projects/libunwind/src/config.h       2019-03-09 16:32:41.461533000 +0100
@@ -75,7 +75,8 @@
     defined(__ppc__) || defined(__ppc64__) || defined(__powerpc64__) ||        \
     (!defined(__APPLE__) && defined(__arm__)) ||                               \
     (defined(__arm64__) || defined(__aarch64__)) ||                            \
-    defined(__mips__)
+    defined(__mips__) ||                                                       \
+    defined(__riscv)
 #if !defined(_LIBUNWIND_BUILD_SJLJ_APIS)
 #define _LIBUNWIND_BUILD_ZERO_COST_APIS
 #endif
diff -upr /share/dim/src/freebsd/vendor/libunwind-dist/src/libunwind.cpp /usr/src/contrib/llvm/projects/libunwind/src/libunwind.cpp
--- /share/dim/src/freebsd/vendor/libunwind-dist/src/libunwind.cpp      2019-03-08 22:49:44.000000000 +0100
+++ /usr/src/contrib/llvm/projects/libunwind/src/libunwind.cpp  2019-03-09 16:36:13.761914000 +0100
@@ -61,6 +61,8 @@ _LIBUNWIND_EXPORT int unw_init_local(unw_cursor_t *cur
 # define REGISTER_KIND Registers_arm
 #elif defined(__or1k__)
 # define REGISTER_KIND Registers_or1k
+#elif defined(__riscv)
+# define REGISTER_KIND Registers_riscv
 #elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32
 # define REGISTER_KIND Registers_mips_o32
 #elif defined(__mips64)

I think it's better to let you finish this and I can deal with moving it afterward. For MIPS, use the upstream cursor sizes. I committed the upstream sizes and they are different because of this upstream change that was before my MIPS merges but wasn't in our older libunwind: https://github.com/bsdjhb/llvm-project/commit/c18d5c05cbcc9fe7f8f741338bb835417108e17b

I'm curious about the remaining #ifdef FreeBSD hunk for processFDE and what the origin of that is though.

In regards the cursor sizes, the builds fail with static assertions if they are wrong FWIW. To test on mips, just install mips-xtoolchain-gcc and build a universe with 'MAKE_PARAMS_mips="CROSS_TOOLCHAIN=mips-gcc"'.

Committed in slightly different form, in rS345018.