Small change for GetBacktrace on Windows ARM64.
function GetBacktrace(Context: TContext; StartingFrame: Pointer; out Frames: PPointer): Longint;
const
CONTEXT_UNWOUND_TO_CALL = $20000000;
var
UnwindHistory: UNWIND_HISTORY_TABLE;
RuntimeFunction: PRUNTIME_FUNCTION;
HandlerData: Pointer;
EstablisherFrame: QWord;
ImageBase: QWord;
FrameCount,FrameBufSize: Longint;
CP: KNONVOLATILE_CONTEXT_POINTERS;
begin
FillChar(UnwindHistory,sizeof(UNWIND_HISTORY_TABLE),0);
UnwindHistory.Unwind:=1;
FrameCount:=0;
FrameBufSize:=0;
Frames:=nil;
repeat
RuntimeFunction:=RtlLookupFunctionEntry(ContextGetIP(Context), ImageBase, @UnwindHistory);
if Assigned(RuntimeFunction) then
RtlVirtualUnwind(UNW_FLAG_NHANDLER, ImageBase, ContextGetIP(Context),
RuntimeFunction, Context, @HandlerData, @EstablisherFrame, @CP)
else { a leaf function }
begin
{$if defined(CPUX86_64)}
Context.Rip:=PQWord(Context.Rsp)^;
Inc(Context.Rsp, sizeof(Pointer));
{$elseif defined(CPUAARCH64)}
// For leaf function on Windows ARM64, return address is at LR(X30). Add
// CONTEXT_UNWOUND_TO_CALL flag to avoid unwind ambiguity for tailcall on
// ARM64, because padding after tailcall is not guaranteed.
// Source: https://chromium.googlesource.com/chromium/src/base/+/master/profiler/win32_stack_frame_unwinder.cc#116
Context.Pc:=Context.Lr;
Context.ContextFlags := Context.ContextFlags OR CONTEXT_UNWOUND_TO_CALL;
{$else}
Edited by Alfred Glänzer