Browse Source

* Xtensa: patch by Christo Crause: add support for windowed ABI stack dump, resolves #37583

git-svn-id: trunk@46463 -
florian 5 years ago
parent
commit
66e682dfdd
3 changed files with 109 additions and 10 deletions
  1. 1 1
      rtl/freertos/consoleio.pp
  2. 2 0
      rtl/freertos/system.pp
  3. 106 9
      rtl/xtensa/xtensa.inc

+ 1 - 1
rtl/freertos/consoleio.pp

@@ -169,7 +169,7 @@ finalization
      Writeln(pstdout^,'Runtime error ',Errorcode,' at $',hexstr(erroraddr));
      Writeln(pstdout^,'Runtime error ',Errorcode,' at $',hexstr(erroraddr));
      { to get a nice symify }
      { to get a nice symify }
      Writeln(pstdout^,BackTraceStrFunc(Erroraddr));
      Writeln(pstdout^,BackTraceStrFunc(Erroraddr));
-     dump_stack(pstdout^,ErrorBase);
+     dump_stack(pstdout^,ErrorBase,erroraddr);
      Writeln(pstdout^,'');
      Writeln(pstdout^,'');
    End;
    End;
   SysFlushStdIO;
   SysFlushStdIO;

+ 2 - 0
rtl/freertos/system.pp

@@ -208,6 +208,7 @@ const calculated_cmdline:Pchar=nil;
 {*****************************************************************************
 {*****************************************************************************
                        Misc. System Dependent Functions
                        Misc. System Dependent Functions
 *****************************************************************************}
 *****************************************************************************}
+{$ifndef FPC_SYSTEM_HAS_STACKTOP}
 var
 var
  _stack_top: record end; external name '_stack_top';
  _stack_top: record end; external name '_stack_top';
 
 
@@ -215,6 +216,7 @@ function StackTop: pointer;
 begin
 begin
   StackTop:=@_stack_top;
   StackTop:=@_stack_top;
 end;
 end;
+{$endif FPC_SYSTEM_HAS_STACKTOP}
 
 
 
 
 procedure haltproc;cdecl;external name '_haltproc';
 procedure haltproc;cdecl;external name '_haltproc';

+ 106 - 9
rtl/xtensa/xtensa.inc

@@ -31,27 +31,114 @@ begin
     SysInitFPU;
     SysInitFPU;
 end;
 end;
 
 
-
-{$IFNDEF INTERNAL_BACKTRACE}
-{$define FPC_SYSTEM_HAS_GET_FRAME}
-function get_frame:pointer;assembler;nostackframe;
+{$ifdef fpc_abi_windowed}
+const
+  // Minimum call8 calls to force register spilling to stack for caller of forceSpilledRegs
+  spillcount = 6;
+
+procedure forceSpilledRegs(n: uint32); assembler; public name 'forcespilledregs';
+  label
+    done, fin;
   asm
   asm
+    beqz a2, done
+    addi a10, a2, -1
+    call8 forcespilledregs
+    done:
+    bnez a2, fin
+    movi a15, 0
+    fin:
+  end;
+
+procedure fixCodeAddress(var addr: pointer);
+  begin
+    // Check if valid code address
+    if ptruint(addr) and $C0000000 >= $40000000 then
+      begin
+        // Replace windowed call prefix
+        addr:=codepointer((ptruint(addr)and$00FFFFFF) or $40000000);
+        // Rewind to call instruction address
+        dec(addr,3);
+      end
+    else
+      addr:=nil;
   end;
   end;
+{$endif fpc_abi_windowed}
+
+{$IFNDEF INTERNAL_BACKTRACE}
+  {$define FPC_SYSTEM_HAS_GET_FRAME}
+  function get_frame:pointer;assembler;
+    label
+      done;
+    asm
+      {$ifdef fpc_abi_windowed}
+        // Force registers to spill onto stack
+        movi a10, spillcount
+        call8 forcespilledregs
+        // now get frame pointer of caller
+        addi a2, a1, -12
+        l32i a2, a2, 0
+        done:
+      {$else}
+        mov a2, a1
+      {$endif}
+    end;
 {$ENDIF not INTERNAL_BACKTRACE}
 {$ENDIF not INTERNAL_BACKTRACE}
 
 
 
 
 {$define FPC_SYSTEM_HAS_GET_CALLER_ADDR}
 {$define FPC_SYSTEM_HAS_GET_CALLER_ADDR}
-function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer;assembler;nostackframe;
-  asm
+function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer;
+  begin
+    {$ifdef fpc_abi_windowed}
+      forceSpilledRegs(spillcount);
+      if (ptruint(framebp)>$3ff00000)and(ptruint(framebp)<$40000000) then
+        begin
+          get_caller_addr:=pointer((framebp-16)^);
+          fixCodeAddress(get_caller_addr);
+        end
+      else
+        get_caller_addr:=nil;
+    {$else}
+      get_caller_addr:=nil;
+    {$endif}
   end;
   end;
 
 
-
 {$define FPC_SYSTEM_HAS_GET_CALLER_FRAME}
 {$define FPC_SYSTEM_HAS_GET_CALLER_FRAME}
-function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer;assembler;nostackframe;
-  asm
+function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer;
+  begin
+    {$ifdef fpc_abi_windowed}
+      if (ptruint(framebp)>$3ff00000)and(ptruint(framebp)<$40000000) then
+        begin
+          forceSpilledRegs(spillcount);
+          get_caller_frame:=pointer((framebp-12)^);
+        end
+      else
+        get_caller_frame:=nil;
+    {$else}
+      get_caller_frame:=nil;
+    {$endif}
   end;
   end;
 
 
 
 
+{$ifdef fpc_abi_windowed}
+  {$define FPC_SYSTEM_HAS_GET_CALLER_STACKINFO}
+  procedure get_caller_stackinfo(var framebp : pointer; var addr : codepointer);
+    begin
+      if (ptruint(framebp)>$3ff00000)and(ptruint(framebp)<$40000000) then
+        begin
+          forceSpilledRegs(spillcount);
+          addr:=codepointer((framebp-16)^);
+          framebp := pointer((framebp-12)^);
+          fixCodeAddress(addr);
+        end
+      else
+        begin
+          addr:=nil;
+          framebp:=nil;
+        end;
+    end;
+{$endif fpc_abi_windowed}
+
+
 {$define FPC_SYSTEM_HAS_SPTR}
 {$define FPC_SYSTEM_HAS_SPTR}
 Function Sptr : pointer;assembler;
 Function Sptr : pointer;assembler;
   asm
   asm
@@ -59,6 +146,16 @@ Function Sptr : pointer;assembler;
   end;
   end;
 
 
 
 
+{$define FPC_SYSTEM_HAS_STACKTOP}
+// Interim fix for now, set to large address
+// TODO: provide more realistic value, possibly by inspecting stack pointer
+// when main or task is started
+function StackTop: pointer;
+  begin
+    StackTop:=pointer($3fffffff);
+  end;
+
+
 function InterLockedDecrement (var Target: longint) : longint;
 function InterLockedDecrement (var Target: longint) : longint;
   var
   var
     temp_sreg : byte;
     temp_sreg : byte;