aboutsummaryrefslogtreecommitdiff
path: root/lib/libunwind/src/DwarfParser.hpp
diff options
context:
space:
mode:
authorKoakuma <koachan@protonmail.com>2022-02-13 22:16:22 +0700
committerGitHub <noreply@github.com>2022-02-13 17:16:22 +0200
commit55fa349ad946aaa4e2ff5a5dc2a3f0d6bce64282 (patch)
treefbd8365132d929851ec418d048a90aaafd1d575e /lib/libunwind/src/DwarfParser.hpp
parentb5f8fb85e64022ed1ee59ff70753577839ad41b6 (diff)
downloadzig-55fa349ad946aaa4e2ff5a5dc2a3f0d6bce64282.tar.gz
zig-55fa349ad946aaa4e2ff5a5dc2a3f0d6bce64282.zip
Import SPARCv9 libunwind
Import LLVM's D32450/D116857 patch to enable unwinding support on SPARCv9 systems.
Diffstat (limited to 'lib/libunwind/src/DwarfParser.hpp')
-rw-r--r--lib/libunwind/src/DwarfParser.hpp25
1 files changed, 24 insertions, 1 deletions
diff --git a/lib/libunwind/src/DwarfParser.hpp b/lib/libunwind/src/DwarfParser.hpp
index de0eb6de9d..f0aa4085d3 100644
--- a/lib/libunwind/src/DwarfParser.hpp
+++ b/lib/libunwind/src/DwarfParser.hpp
@@ -71,6 +71,7 @@ public:
kRegisterUnused,
kRegisterUndefined,
kRegisterInCFA,
+ kRegisterInCFADecrypt, // sparc64 specific
kRegisterOffsetFromCFA,
kRegisterInRegister,
kRegisterAtExpression,
@@ -723,7 +724,8 @@ bool CFI_Parser<A>::parseFDEInstructions(A &addressSpace,
"DW_CFA_GNU_negative_offset_extended(%" PRId64 ")\n", offset);
break;
-#if defined(_LIBUNWIND_TARGET_AARCH64) || defined(_LIBUNWIND_TARGET_SPARC)
+#if defined(_LIBUNWIND_TARGET_AARCH64) || defined(_LIBUNWIND_TARGET_SPARC) || \
+ defined(_LIBUNWIND_TARGET_SPARC64)
// The same constant is used to represent different instructions on
// AArch64 (negate_ra_state) and SPARC (window_save).
static_assert(DW_CFA_AARCH64_negate_ra_state == DW_CFA_GNU_window_save,
@@ -757,8 +759,29 @@ bool CFI_Parser<A>::parseFDEInstructions(A &addressSpace,
}
break;
#endif
+
+#if defined(_LIBUNWIND_TARGET_SPARC64)
+ // case DW_CFA_GNU_window_save:
+ case REGISTERS_SPARC64:
+ // Don't save %o0-%o7 on sparc64.
+ // https://reviews.llvm.org/D32450#736405
+
+ for (reg = UNW_SPARC_L0; reg <= UNW_SPARC_I7; reg++) {
+ if (reg == UNW_SPARC_I7)
+ results->setRegister(
+ reg, kRegisterInCFADecrypt,
+ ((int64_t)reg - UNW_SPARC_L0) * sizeof(pint_t), initialState);
+ else
+ results->setRegister(
+ reg, kRegisterInCFA,
+ ((int64_t)reg - UNW_SPARC_L0) * sizeof(pint_t), initialState);
+ }
+ _LIBUNWIND_TRACE_DWARF("DW_CFA_GNU_window_save\n");
+ break;
+#endif
}
break;
+
#else
(void)arch;
#endif