From 69ce2026b10711b32595d58e23f92f54e6c718c2 Mon Sep 17 00:00:00 2001
From: Evgeny Karpov <[email protected]>
Date: Fri, 15 Nov 2024 13:14:18 +0100
Subject: [PATCH v1 4/4] aarch64: Add SEH, stack unwinding and C++ exceptions
This patch reuses the existing SEH, stack unwinding and C++ exceptions
from ix86 and implements the required changes for AArch64.
gcc/ChangeLog:
* common/config/aarch64/aarch64-common.cc (aarch64_except_unwind_info):
Add unwind info for AArch64.
(defined): Likewise.
(TARGET_EXCEPT_UNWIND_INFO): Likewise.
* config/aarch64/aarch64.cc (aarch64_print_reg):
Print a reg.
(defined): Enable unwind tables.
(aarch64_declare_function_name): Add unwinding.
* config/aarch64/cygming.h (SYMBOL_REF_STUBVAR_P):
Enable SEH, declare required functions and parameters.
(TARGET_SEH): Likewise.
(SEH_MAX_FRAME_SIZE): Likewise.
(TARGET_ASM_UNWIND_EMIT): Likewise.
(TARGET_ASM_UNWIND_EMIT_BEFORE_INSN): Likewise.
(TARGET_ASM_FUNCTION_END_PROLOGUE): Likewise.
(TARGET_ASM_EMIT_EXCEPT_PERSONALITY): Likewise.
(TARGET_ASM_INIT_SECTIONS): Likewise.
(SUBTARGET_ASM_UNWIND_INIT): Likewise.
(aarch64_pe_seh_unwind_emit): Likewise.
(aarch64_print_reg): Likewise.
(ASM_DECLARE_FUNCTION_SIZE): Likewise.
(ASM_DECLARE_COLD_FUNCTION_SIZE): Likewise.
(ASM_DECLARE_COLD_FUNCTION_NAME): Likewise.
* config/mingw/winnt.cc (defined):
Add AArch64 implmentation for SEH.
(CALLEE_SAVED_REG_NUMBER): Likewise.
(seh_parallel_offset): Likewise.
(seh_pattern_emit): Likewise.
(aarch64_pe_seh_unwind_emit): Likewise.
libgcc/ChangeLog:
* config.host: Support AArch64.
* unwind-seh.c (defined): Likewise.
(_Unwind_Backtrace): Likewise.
---
gcc/common/config/aarch64/aarch64-common.cc | 30 +++
gcc/config/aarch64/aarch64.cc | 15 ++
gcc/config/aarch64/cygming.h | 51 +++-
gcc/config/mingw/winnt.cc | 260 +++++++++++++++++++-
libgcc/config.host | 2 +-
libgcc/unwind-seh.c | 37 ++-
6 files changed, 382 insertions(+), 13 deletions(-)
diff --git a/gcc/common/config/aarch64/aarch64-common.cc
b/gcc/common/config/aarch64/aarch64-common.cc
index 2bfc597e333..c46c0a8547d 100644
--- a/gcc/common/config/aarch64/aarch64-common.cc
+++ b/gcc/common/config/aarch64/aarch64-common.cc
@@ -447,6 +447,36 @@ aarch64_rewrite_mcpu (int argc, const char **argv)
return aarch64_rewrite_selected_cpu (argv[argc - 1]);
}
+#if TARGET_AARCH64_MS_ABI
+
+/* Implement TARGET_EXCEPT_UNWIND_INFO. */
+
+static enum unwind_info_type
+aarch64_except_unwind_info (struct gcc_options *opts)
+{
+ /* Honor the --enable-sjlj-exceptions configure switch. */
+#ifdef CONFIG_SJLJ_EXCEPTIONS
+ if (CONFIG_SJLJ_EXCEPTIONS)
+ return UI_SJLJ;
+#endif
+
+ /* On windows 64, prefer SEH exceptions over anything else. */
+#if defined (TARGET_AARCH64_MS_ABI)
+ if (opts->x_flag_unwind_tables)
+ return UI_SEH;
+#endif
+
+ if (DWARF2_UNWIND_INFO)
+ return UI_DWARF2;
+
+ return UI_SJLJ;
+}
+
+#undef TARGET_EXCEPT_UNWIND_INFO
+#define TARGET_EXCEPT_UNWIND_INFO aarch64_except_unwind_info
+
+#endif // TARGET_AARCH64_MS_ABI
+
struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER;
#undef AARCH64_CPU_NAME_LENGTH
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index f02f9c88b6e..6dd1ba8f085 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -12773,6 +12773,12 @@ aarch64_label_mentioned_p (rtx x)
return 0;
}
+void
+aarch64_print_reg (rtx x, int code, FILE *file)
+{
+ aarch64_print_operand (file, x, code);
+}
+
/* Implement REGNO_REG_CLASS. */
enum reg_class
@@ -18468,6 +18474,12 @@ aarch64_override_options_after_change_1 (struct
gcc_options *opts)
intermediary step for the former. */
if (flag_mlow_precision_sqrt)
flag_mrecip_low_precision_sqrt = true;
+
+ /* Enable unwind tables for MS. */
+#if defined (TARGET_AARCH64_MS_ABI)
+ if (opts->x_flag_unwind_tables == 0)
+ opts->x_flag_unwind_tables = 1;
+#endif // TARGET_AARCH64_MS_ABI
}
/* 'Unpack' up the internal tuning structs and update the options
@@ -24903,6 +24915,9 @@ aarch64_declare_function_name (FILE *stream, const
char* name,
/* Don't forget the type directive for ELF. */
ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "function");
+#ifdef SUBTARGET_ASM_UNWIND_INIT
+ SUBTARGET_ASM_UNWIND_INIT (stream);
+#endif
ASM_OUTPUT_FUNCTION_LABEL (stream, name, fndecl);
cfun->machine->label_is_assembled = true;
diff --git a/gcc/config/aarch64/cygming.h b/gcc/config/aarch64/cygming.h
index 8b9038ccf88..d4f4775ddab 100644
--- a/gcc/config/aarch64/cygming.h
+++ b/gcc/config/aarch64/cygming.h
@@ -45,14 +45,39 @@ along with GCC; see the file COPYING3. If not see
#define SYMBOL_REF_STUBVAR_P(X) \
((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_STUBVAR) != 0)
-/* Disable SEH and declare the required SEH-related macros that are
+/* Declare the required SEH-related macros that are
still needed for compilation. */
#undef TARGET_SEH
-#define TARGET_SEH 0
+#define TARGET_SEH 1
#define SSE_REGNO_P(N) (gcc_unreachable (), 0)
#define GENERAL_REGNO_P(N) (gcc_unreachable (), 0)
-#define SEH_MAX_FRAME_SIZE (gcc_unreachable (), 0)
+
+/* Support hooks for SEH. */
+#undef TARGET_ASM_UNWIND_EMIT
+#define TARGET_ASM_UNWIND_EMIT aarch64_pe_seh_unwind_emit
+#undef TARGET_ASM_UNWIND_EMIT_BEFORE_INSN
+#define TARGET_ASM_UNWIND_EMIT_BEFORE_INSN false
+#undef TARGET_ASM_FUNCTION_END_PROLOGUE
+#define TARGET_ASM_FUNCTION_END_PROLOGUE mingw_pe_seh_end_prologue
+#undef TARGET_ASM_EMIT_EXCEPT_PERSONALITY
+#define TARGET_ASM_EMIT_EXCEPT_PERSONALITY mingw_pe_seh_emit_except_personality
+#undef TARGET_ASM_INIT_SECTIONS
+#define TARGET_ASM_INIT_SECTIONS mingw_pe_seh_init_sections
+#undef SUBTARGET_ASM_UNWIND_INIT
+#define SUBTARGET_ASM_UNWIND_INIT mingw_pe_seh_init
+
+/* According to Windows x64 software convention, the maximum stack allocatable
+ in the prologue is 4G - 8 bytes. Furthermore, there is a limited set of
+ instructions allowed to adjust the stack pointer in the epilog, forcing the
+ use of frame pointer for frames larger than 2 GB. This theorical limit
+ is reduced by 256, an over-estimated upper bound for the stack use by the
+ prologue.
+ We define only one threshold for both the prolog and the epilog. When the
+ frame size is larger than this threshold, we allocate the area to save SSE
+ regs, then save them, and then allocate the remaining. There is no SEH
+ unwind info for this later allocation. */
+#define SEH_MAX_FRAME_SIZE ((2U << 30) - 256)
#undef TARGET_PECOFF
#define TARGET_PECOFF 1
@@ -70,6 +95,9 @@ still needed for compilation. */
#define TARGET_ASM_UNIQUE_SECTION mingw_pe_unique_section
#define TARGET_ENCODE_SECTION_INFO mingw_pe_encode_section_info
+extern void aarch64_pe_seh_unwind_emit (FILE *, rtx_insn *);
+extern void aarch64_print_reg (rtx, int, FILE*);
+
#define TARGET_VALID_DLLIMPORT_ATTRIBUTE_P mingw_pe_valid_dllimport_attribute_p
/* Output function declarations at the end of the file. */
@@ -118,6 +146,7 @@ still needed for compilation. */
builtin_define ("__MSVCRT__"); \
builtin_define ("__MINGW32__"); \
builtin_define ("_WIN32"); \
+ builtin_define ("__SEH__"); \
builtin_define_std ("WIN32"); \
builtin_define_std ("WINNT"); \
builtin_define_with_int_value ("_INTEGRAL_MAX_BITS", \
@@ -203,6 +232,14 @@ still needed for compilation. */
flag_stack_check = STATIC_BUILTIN_STACK_CHECK; \
} while (0)
+#undef ASM_DECLARE_FUNCTION_SIZE
+#define ASM_DECLARE_FUNCTION_SIZE(FILE,NAME,DECL) \
+ mingw_pe_end_function (FILE, NAME, DECL)
+
+#undef ASM_DECLARE_COLD_FUNCTION_SIZE
+#define ASM_DECLARE_COLD_FUNCTION_SIZE(FILE,NAME,DECL) \
+ mingw_pe_end_cold_function (FILE, NAME, DECL)
+
#define SUBTARGET_ATTRIBUTE_TABLE \
{ "selectany", 0, 0, true, false, false, false, \
mingw_handle_selectany_attribute, NULL }
@@ -228,6 +265,14 @@ still needed for compilation. */
aarch64_declare_function_name (STREAM, NAME, DECL);
\
} while (0)
+#define ASM_DECLARE_COLD_FUNCTION_NAME(FILE, NAME, DECL) \
+ do \
+ { \
+ mingw_pe_declare_type (FILE, NAME, 0, 1); \
+ mingw_pe_seh_cold_init (FILE, NAME); \
+ ASM_OUTPUT_LABEL (FILE, NAME); \
+ } \
+ while (0)
/* Define this to be nonzero if static stack checking is supported. */
#define STACK_CHECK_STATIC_BUILTIN 1
diff --git a/gcc/config/mingw/winnt.cc b/gcc/config/mingw/winnt.cc
index ca5da652b8b..6b8ebcf6297 100644
--- a/gcc/config/mingw/winnt.cc
+++ b/gcc/config/mingw/winnt.cc
@@ -170,6 +170,8 @@ mingw_pe_valid_dllimport_attribute_p (const_tree decl)
return true;
}
+#if !defined (TARGET_AARCH64_MS_ABI)
+
/* Return string which is the function name, identified by ID, modified
with a suffix consisting of an atsign (@) followed by the number of
bytes of arguments. If ID is NULL use the DECL_NAME as base. If
@@ -225,8 +227,6 @@ gen_stdcall_or_fastcall_suffix (tree decl, tree id, bool
fastcall)
return get_identifier (new_str);
}
-#if !defined (TARGET_AARCH64_MS_ABI)
-
/* Maybe decorate and get a new identifier for the DECL of a stdcall or
fastcall function. The original identifier is supplied in ID. */
@@ -925,6 +925,11 @@ mingw_pe_seh_end_prologue (FILE *f)
void
mingw_pe_seh_cold_init (FILE *f, const char *name)
{
+#if defined (TARGET_AARCH64_MS_ABI)
+ mingw_pe_seh_init (f);
+ return;
+#endif
+
struct seh_frame_state *seh;
HOST_WIDE_INT alloc_offset, offset;
@@ -1048,6 +1053,15 @@ seh_emit_save (FILE *f, struct seh_frame_state *seh,
rtx reg, HOST_WIDE_INT cfa_offset)
{
const unsigned int regno = REGNO (reg);
+#if defined (TARGET_AARCH64_MS_ABI)
+ fputs ((FP_REGNUM_P (regno) ? " \t.seh_save_freg\t"
+ : GP_REGNUM_P (regno) ? " \t.seh_save_reg\t"
+ : (gcc_unreachable (), "")), f);
+ aarch64_print_reg (reg, 0, f);
+ fprintf (f, ", " HOST_WIDE_INT_PRINT_DEC " \n", abs (cfa_offset));
+ return;
+#endif
+
HOST_WIDE_INT offset;
seh->reg_offset[regno] = cfa_offset;
@@ -1072,8 +1086,12 @@ seh_emit_stackalloc (FILE *f, struct seh_frame_state
*seh,
{
/* We're only concerned with prologue stack allocations, which all
are subtractions from the stack pointer. */
+#if defined (TARGET_AARCH64_MS_ABI)
+ offset = abs (offset);
+#else
gcc_assert (offset < 0);
offset = -offset;
+#endif
if (seh->cfa_reg == stack_pointer_rtx)
seh->cfa_offset += offset;
@@ -1329,6 +1347,244 @@ i386_pe_seh_unwind_emit (FILE *out_file, rtx_insn *insn)
seh_frame_related_expr (out_file, seh, pat);
}
+#if defined (TARGET_AARCH64_MS_ABI)
+#define CALLEE_SAVED_REG_NUMBER(r) \
+ (((r) >= R19_REGNUM && (r) <= R30_REGNUM) \
+ || ((r) >= V8_REGNUM && (r) <= V15_REGNUM))
+#else
+#define CALLEE_SAVED_REG_NUMBER(r) 0
+#endif
+
+static HOST_WIDE_INT
+seh_parallel_offset (rtx pat, HOST_WIDE_INT wanted_regnum)
+{
+ rtx dest, src;
+ HOST_WIDE_INT result = 0;
+
+ if (GET_CODE (pat) == PARALLEL)
+ {
+ int i, n = XVECLEN (pat, 0);
+
+ for (i = 0; i < n; ++i)
+ {
+ rtx ele = XVECEXP (pat, 0, i);
+
+ if (GET_CODE (ele) != SET)
+ continue;
+
+ dest = SET_DEST (ele);
+ src = SET_SRC (ele);
+
+ if (GET_CODE (dest) == REG
+ && REGNO (dest) == wanted_regnum
+ && GET_CODE (src) == MEM
+ && GET_CODE (XEXP (src, 0)) == PLUS
+ && XEXP (XEXP (src, 0), 0) == stack_pointer_rtx)
+ {
+ result = INTVAL (XEXP (XEXP (src, 0), 1));
+ }
+
+ if (GET_CODE (src) == REG
+ && REGNO (src) == wanted_regnum
+ && GET_CODE (dest) == MEM
+ && GET_CODE (XEXP (dest, 0)) == PLUS
+ && XEXP (XEXP (dest, 0), 0) == stack_pointer_rtx)
+ {
+ result = INTVAL (XEXP (XEXP (dest, 0), 1));
+ }
+ }
+ }
+
+ return result;
+}
+
+static void
+seh_pattern_emit (FILE *f, struct seh_frame_state *seh, rtx pat)
+{
+ rtx dest, src;
+
+ if (GET_CODE (pat) == PARALLEL)
+ {
+ int i, n = XVECLEN (pat, 0);
+ HOST_WIDE_INT regno, min_regno = 32;
+ int reg_count = 0;
+ HOST_WIDE_INT increment = 0;
+
+ for (i = 0; i < n; ++i)
+ {
+ rtx ele = XVECEXP (pat, 0, i);
+
+ if (GET_CODE (ele) != SET)
+ continue;
+
+ dest = SET_DEST (ele);
+ src = SET_SRC (ele);
+
+ if (GET_CODE (dest) == REG
+ && GET_CODE (src) == PLUS
+ && XEXP (src, 0) == stack_pointer_rtx)
+ {
+ increment = INTVAL (XEXP (src, 1));
+ }
+
+ if (!seh->after_prologue && GET_CODE (src) == REG)
+ {
+ regno = REGNO (src);
+
+ if (CALLEE_SAVED_REG_NUMBER (regno))
+ {
+ reg_count += 1;
+ min_regno = MIN (regno, min_regno);
+ }
+ }
+
+ if (seh->after_prologue && GET_CODE (dest) == REG)
+ {
+ regno = REGNO (dest);
+
+ if (CALLEE_SAVED_REG_NUMBER (regno))
+ {
+ reg_count += 1;
+ min_regno = MIN (regno, min_regno);
+ }
+ }
+ }
+
+ if (reg_count == 2)
+ {
+ fprintf (f, "\t.seh_save_%s x%ld, %ld\n",
+ increment != 0 ? "regp_x" : "regp",
+ min_regno,
+ increment != 0 ? abs (increment) :
+ seh_parallel_offset (pat, min_regno));
+ }
+ }
+ else
+ {
+ src = SET_SRC (pat);
+
+ if (GET_CODE (pat) == SET)
+ {
+ HOST_WIDE_INT increment = 0;
+ dest = SET_DEST (pat);
+
+ switch (GET_CODE (dest))
+ {
+ case REG:
+ switch (GET_CODE (src))
+ {
+ case REG:
+ if (dest == hard_frame_pointer_rtx
+ && src == stack_pointer_rtx)
+ fputs ("\t.seh_set_fp\n", f);
+ else if (CALLEE_SAVED_REG_NUMBER (REGNO (dest))
+ && src == stack_pointer_rtx)
+ seh_emit_save (f, seh, dest, INTVAL (XEXP (src, 1)));
+ break;
+
+ case PLUS:
+ increment = INTVAL (XEXP (src, 1));
+ src = XEXP (src, 0);
+ if (dest == stack_pointer_rtx)
+ seh_emit_stackalloc (f, seh, increment);
+ break;
+
+ case MEM:
+ src = XEXP (src, 0);
+ if (GET_CODE (src) == PLUS
+ && GET_CODE (XEXP (src, 0)) == REG
+ && CALLEE_SAVED_REG_NUMBER (REGNO (dest))
+ && XEXP (src, 0) == stack_pointer_rtx)
+ seh_emit_save (f, seh, dest, INTVAL (XEXP (src, 1)));
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case MEM: // Save
+ dest = XEXP (dest, 0);
+ if (GET_CODE (dest) == PRE_DEC
+ && CALLEE_SAVED_REG_NUMBER (REGNO (src))
+ && XEXP (dest, 0) == stack_pointer_rtx)
+ seh_emit_save (f, seh, src, INTVAL (XEXP (dest, 1)));
+ else if (GET_CODE (dest) == PLUS
+ && CALLEE_SAVED_REG_NUMBER (REGNO (src))
+ && XEXP (dest, 0) == stack_pointer_rtx)
+ seh_emit_save (f, seh, src, INTVAL (XEXP (dest, 1)));
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (seh->after_prologue
+ && (GET_CODE (pat) == RETURN || GET_CODE (pat) == JUMP_INSN))
+ fputs ("\t.seh_endepilogue\n", f);
+ }
+}
+
+/* This function looks at a single insn and emits any SEH directives
+ required for unwind of this insn. */
+
+void
+aarch64_pe_seh_unwind_emit (FILE *out_file, rtx_insn *insn)
+{
+ rtx note, pat;
+ struct seh_frame_state *seh;
+
+ if (!TARGET_SEH)
+ return;
+
+ if (NOTE_P (insn))
+ return;
+
+ seh = cfun->machine->seh;
+
+ if (!seh || seh->after_prologue)
+ return;
+
+ pat = PATTERN (insn);
+
+ if (GET_CODE (pat) == SET)
+ {
+ rtx dest = SET_DEST (pat);
+ if (GET_CODE (dest) == MEM && GET_CODE (XEXP (dest, 0)) == SCRATCH)
+ return;
+ }
+
+ bool related_exp_needed = true;
+
+ for (note = REG_NOTES (insn); note ; note = XEXP (note, 1))
+ {
+ switch (REG_NOTE_KIND (note))
+ {
+ case REG_FRAME_RELATED_EXPR:
+ pat = XEXP (note, 0);
+ seh_pattern_emit (out_file, seh, pat);
+ related_exp_needed = false;
+ break;
+
+ case REG_CFA_EXPRESSION:
+ case REG_CFA_REGISTER:
+ case REG_CFA_ADJUST_CFA:
+ case REG_CFA_OFFSET:
+ related_exp_needed = false;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (related_exp_needed)
+ {
+ pat = PATTERN (insn);
+ seh_pattern_emit (out_file, seh, pat);
+ }
+}
+
void
mingw_pe_seh_emit_except_personality (rtx personality)
{
diff --git a/libgcc/config.host b/libgcc/config.host
index 35f882d94e1..112e3d7ff82 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -476,7 +476,7 @@ aarch64-*-mingw*)
tmake_thr_file="mingw/t-mingw-pthread"
;;
esac
- tmake_file="${tmake_file} ${cpu_type}/t-no-eh ${tmake_thr_file}"
+ tmake_file="${tmake_file} ${tmake_thr_file} mingw/t-seh-eh"
tmake_file="${tmake_file} t-dfprules"
tmake_file="${tmake_file} ${cpu_type}/t-aarch64"
tmake_file="${tmake_file} ${cpu_type}/t-mingw"
diff --git a/libgcc/unwind-seh.c b/libgcc/unwind-seh.c
index f1b8f5a8519..219d20ad108 100644
--- a/libgcc/unwind-seh.c
+++ b/libgcc/unwind-seh.c
@@ -32,7 +32,7 @@
/* At the moment everything is written for x64, but in theory this could
also be used for i386, arm, mips and other extant embedded Windows. */
-#ifndef __x86_64__
+#if !defined (__x86_64__) && !defined (__aarch64__)
#error "Unsupported architecture."
#endif
@@ -209,7 +209,12 @@ _GCC_specific_handler (PEXCEPTION_RECORD ms_exc, void
*this_frame,
"installed" the target_ip and RAX value via the arguments
to RtlUnwindEx. All that's left is to set the RDX value
and "continue" to have the context installed. */
+#ifdef __x86_64__
ms_disp->ContextRecord->Rdx = ms_exc->ExceptionInformation[3];
+#elif defined (__aarch64__)
+ ms_disp->ContextRecord->X1 = ms_exc->ExceptionInformation[3];
+#endif
+
return ExceptionContinueSearch;
}
@@ -229,7 +234,11 @@ _GCC_specific_handler (PEXCEPTION_RECORD ms_exc, void
*this_frame,
return ExceptionContinueSearch;
}
+#ifdef __x86_64__
gcc_context.cfa = ms_disp->ContextRecord->Rsp;
+#elif defined (__aarch64__)
+ gcc_context.cfa = ms_disp->ContextRecord->Sp;
+#endif
gcc_context.ra = ms_disp->ControlPc;
gcc_context.reg[0] = 0xdeadbeef; /* These are write-only. */
gcc_context.reg[1] = 0xdeadbeef;
@@ -438,6 +447,8 @@ _Unwind_Backtrace(_Unwind_Trace_Fn trace,
CONTEXT ms_context;
struct _Unwind_Context gcc_context;
DISPATCHER_CONTEXT disp_context;
+ ULONG64 ip;
+ ULONG64 sp;
memset (&ms_history, 0, sizeof(ms_history));
memset (&gcc_context, 0, sizeof(gcc_context));
@@ -452,31 +463,43 @@ _Unwind_Backtrace(_Unwind_Trace_Fn trace,
while (1)
{
- gcc_context.disp->ControlPc = ms_context.Rip;
+#ifdef __x86_64__
+ ip = ms_context.Rip;
+#elif defined (__aarch64__)
+ ip = ms_context.Pc;
+#endif
+ gcc_context.disp->ControlPc = ip;
gcc_context.disp->FunctionEntry
- = RtlLookupFunctionEntry (ms_context.Rip, &gcc_context.disp->ImageBase,
+ = RtlLookupFunctionEntry (ip, &gcc_context.disp->ImageBase,
&ms_history);
if (!gcc_context.disp->FunctionEntry)
return _URC_END_OF_STACK;
gcc_context.disp->LanguageHandler
- = RtlVirtualUnwind (0, gcc_context.disp->ImageBase, ms_context.Rip,
+ = RtlVirtualUnwind (0, gcc_context.disp->ImageBase, ip,
gcc_context.disp->FunctionEntry, &ms_context,
&gcc_context.disp->HandlerData,
&gcc_context.disp->EstablisherFrame, NULL);
/* Set values that the callback can inspect via _Unwind_GetIP
* and _Unwind_GetCFA. */
- gcc_context.ra = ms_context.Rip;
- gcc_context.cfa = ms_context.Rsp;
+#ifdef __x86_64__
+ ip = ms_context.Rip;
+ sp = ms_context.Rsp;
+#elif defined (__aarch64__)
+ ip = ms_context.Pc;
+ sp = ms_context.Sp;
+#endif
+ gcc_context.ra = ip;
+ gcc_context.cfa = sp;
/* Call trace function. */
if (trace (&gcc_context, trace_argument) != _URC_NO_REASON)
return _URC_FATAL_PHASE1_ERROR;
/* ??? Check for invalid stack pointer. */
- if (ms_context.Rip == 0)
+ if (ip == 0)
return _URC_END_OF_STACK;
}
}
--
2.34.1