mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-18 20:09:18 +02:00
* get_addr function renamed to get_pc_addr
+ get_caller_stackinfo procedure added. git-svn-id: trunk@21707 -
This commit is contained in:
parent
117c083003
commit
f340ef87e3
@ -1061,8 +1061,8 @@ end;
|
|||||||
{$ENDIF not INTERNAL_BACKTRACE}
|
{$ENDIF not INTERNAL_BACKTRACE}
|
||||||
|
|
||||||
|
|
||||||
{$define FPC_SYSTEM_HAS_GET_ADDR}
|
{$define FPC_SYSTEM_HAS_GET_PC_ADDR}
|
||||||
Function Get_addr : Pointer;assembler;nostackframe;
|
Function Get_pc_addr : Pointer;assembler;nostackframe;
|
||||||
asm
|
asm
|
||||||
movl (%esp),%eax
|
movl (%esp),%eax
|
||||||
end;
|
end;
|
||||||
|
@ -331,14 +331,21 @@ end;
|
|||||||
|
|
||||||
|
|
||||||
procedure dump_already_free(p : pheap_mem_info;var ptext : text);
|
procedure dump_already_free(p : pheap_mem_info;var ptext : text);
|
||||||
|
var
|
||||||
|
bp, pcaddr : pointer;
|
||||||
begin
|
begin
|
||||||
Writeln(ptext,'Marked memory at $',HexStr(pointer(p)+sizeof(theap_mem_info)),' released');
|
Writeln(ptext,'Marked memory at $',HexStr(pointer(p)+sizeof(theap_mem_info)),' released');
|
||||||
call_free_stack(p,ptext);
|
call_free_stack(p,ptext);
|
||||||
Writeln(ptext,'freed again at');
|
Writeln(ptext,'freed again at');
|
||||||
dump_stack(ptext,get_caller_frame(get_frame));
|
bp:=get_frame;
|
||||||
|
pcaddr:=get_pc_addr;
|
||||||
|
get_caller_stackinfo(bp,pcaddr);
|
||||||
|
dump_stack(ptext,bp,pcaddr);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure dump_error(p : pheap_mem_info;var ptext : text);
|
procedure dump_error(p : pheap_mem_info;var ptext : text);
|
||||||
|
var
|
||||||
|
bp, pcaddr : pointer;
|
||||||
begin
|
begin
|
||||||
Writeln(ptext,'Marked memory at $',HexStr(pointer(p)+sizeof(theap_mem_info)),' invalid');
|
Writeln(ptext,'Marked memory at $',HexStr(pointer(p)+sizeof(theap_mem_info)),' invalid');
|
||||||
Writeln(ptext,'Wrong signature $',hexstr(p^.sig,8),' instead of ',hexstr(calculate_sig(p),8));
|
Writeln(ptext,'Wrong signature $',hexstr(p^.sig,8),' instead of ',hexstr(calculate_sig(p),8));
|
||||||
@ -347,7 +354,10 @@ begin
|
|||||||
write(ptext, 'Block content: ');
|
write(ptext, 'Block content: ');
|
||||||
printhex(pointer(p) + sizeof(theap_mem_info), p^.size, ptext);
|
printhex(pointer(p) + sizeof(theap_mem_info), p^.size, ptext);
|
||||||
end;
|
end;
|
||||||
dump_stack(ptext,get_caller_frame(get_frame));
|
bp:=get_frame;
|
||||||
|
pcaddr:=get_pc_addr;
|
||||||
|
get_caller_stackinfo(bp,pcaddr);
|
||||||
|
dump_stack(ptext,bp,pcaddr);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{$ifdef EXTRA}
|
{$ifdef EXTRA}
|
||||||
@ -367,10 +377,15 @@ end;
|
|||||||
{$endif EXTRA}
|
{$endif EXTRA}
|
||||||
|
|
||||||
procedure dump_wrong_size(p : pheap_mem_info;size : ptruint;var ptext : text);
|
procedure dump_wrong_size(p : pheap_mem_info;size : ptruint;var ptext : text);
|
||||||
|
var
|
||||||
|
bp, pcaddr : pointer;
|
||||||
begin
|
begin
|
||||||
Writeln(ptext,'Marked memory at $',HexStr(pointer(p)+sizeof(theap_mem_info)),' invalid');
|
Writeln(ptext,'Marked memory at $',HexStr(pointer(p)+sizeof(theap_mem_info)),' invalid');
|
||||||
Writeln(ptext,'Wrong size : ',p^.size,' allocated ',size,' freed');
|
Writeln(ptext,'Wrong size : ',p^.size,' allocated ',size,' freed');
|
||||||
dump_stack(ptext,get_caller_frame(get_frame));
|
bp:=get_frame;
|
||||||
|
pcaddr:=get_pc_addr;
|
||||||
|
get_caller_stackinfo(bp,pcaddr);
|
||||||
|
dump_stack(ptext,bp,pcaddr);
|
||||||
{ the check is done to be sure that the procvar is not overwritten }
|
{ the check is done to be sure that the procvar is not overwritten }
|
||||||
if assigned(p^.extra_info) and
|
if assigned(p^.extra_info) and
|
||||||
(p^.extra_info^.check=$12345678) and
|
(p^.extra_info^.check=$12345678) and
|
||||||
@ -445,7 +460,7 @@ Function TraceGetMem(size:ptruint):pointer;
|
|||||||
var
|
var
|
||||||
allocsize,i : ptruint;
|
allocsize,i : ptruint;
|
||||||
oldbp,
|
oldbp,
|
||||||
bp : pointer;
|
bp,pcaddr : pointer;
|
||||||
pl : pdword;
|
pl : pdword;
|
||||||
p : pointer;
|
p : pointer;
|
||||||
pp : pheap_mem_info;
|
pp : pheap_mem_info;
|
||||||
@ -509,15 +524,16 @@ begin
|
|||||||
{ clear the memory }
|
{ clear the memory }
|
||||||
fillchar(p^,size,#255);
|
fillchar(p^,size,#255);
|
||||||
{ retrieve backtrace info }
|
{ retrieve backtrace info }
|
||||||
bp:=get_caller_frame(get_frame);
|
bp:=get_frame;
|
||||||
|
pcaddr:=get_pc_addr;
|
||||||
|
get_caller_stackinfo(bp,pcaddr);
|
||||||
{ valid bp? }
|
{ valid bp? }
|
||||||
if (bp>=StackBottom) and (bp<(StackBottom + StackLength)) then
|
if (bp>=StackBottom) and (bp<(StackBottom + StackLength)) then
|
||||||
for i:=1 to tracesize do
|
for i:=1 to tracesize do
|
||||||
begin
|
begin
|
||||||
pp^.calls[i]:=get_caller_addr(bp);
|
|
||||||
oldbp:=bp;
|
oldbp:=bp;
|
||||||
bp:=get_caller_frame(bp);
|
get_caller_stackinfo(bp,pcaddr);
|
||||||
|
pp^.calls[i]:=pcaddr;
|
||||||
if (bp<oldbp) or (bp>(StackBottom + StackLength)) then
|
if (bp<oldbp) or (bp>(StackBottom + StackLength)) then
|
||||||
break;
|
break;
|
||||||
end;
|
end;
|
||||||
@ -553,7 +569,7 @@ function CheckFreeMemSize(loc_info: pheap_info; pp: pheap_mem_info;
|
|||||||
size, ppsize: ptruint): boolean; inline;
|
size, ppsize: ptruint): boolean; inline;
|
||||||
var
|
var
|
||||||
i: ptruint;
|
i: ptruint;
|
||||||
bp : pointer;
|
bp,pcaddr : pointer;
|
||||||
ptext : ^text;
|
ptext : ^text;
|
||||||
{$ifdef EXTRA}
|
{$ifdef EXTRA}
|
||||||
pp2 : pheap_mem_info;
|
pp2 : pheap_mem_info;
|
||||||
@ -612,12 +628,15 @@ begin
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
bp:=get_caller_frame(get_frame);
|
bp:=get_frame;
|
||||||
|
pcaddr:=get_pc_addr;
|
||||||
|
get_caller_stackinfo(bp,pcaddr);
|
||||||
|
|
||||||
if (bp>=StackBottom) and (bp<(StackBottom + StackLength)) then
|
if (bp>=StackBottom) and (bp<(StackBottom + StackLength)) then
|
||||||
for i:=(tracesize div 2)+1 to tracesize do
|
for i:=(tracesize div 2)+1 to tracesize do
|
||||||
begin
|
begin
|
||||||
pp^.calls[i]:=get_caller_addr(bp);
|
get_caller_stackinfo(bp,pcaddr);
|
||||||
bp:=get_caller_frame(bp);
|
pp^.calls[i]:=pcaddr;
|
||||||
if not((bp>=StackBottom) and (bp<(StackBottom + StackLength))) then
|
if not((bp>=StackBottom) and (bp<(StackBottom + StackLength))) then
|
||||||
break;
|
break;
|
||||||
end;
|
end;
|
||||||
@ -775,7 +794,8 @@ var
|
|||||||
movesize,
|
movesize,
|
||||||
i : ptruint;
|
i : ptruint;
|
||||||
oldbp,
|
oldbp,
|
||||||
bp : pointer;
|
bp,
|
||||||
|
pcaddr : pointer;
|
||||||
pl : pdword;
|
pl : pdword;
|
||||||
pp : pheap_mem_info;
|
pp : pheap_mem_info;
|
||||||
oldsize,
|
oldsize,
|
||||||
@ -890,13 +910,15 @@ begin
|
|||||||
inc(loc_info^.getmem_size,size);
|
inc(loc_info^.getmem_size,size);
|
||||||
inc(loc_info^.getmem8_size,(size+7) and not 7);
|
inc(loc_info^.getmem8_size,(size+7) and not 7);
|
||||||
{ generate new backtrace }
|
{ generate new backtrace }
|
||||||
bp:=get_caller_frame(get_frame);
|
bp:=get_frame;
|
||||||
|
pcaddr:=get_pc_addr;
|
||||||
|
get_caller_stackinfo(bp,pcaddr);
|
||||||
if (bp>=StackBottom) and (bp<(StackBottom + StackLength)) then
|
if (bp>=StackBottom) and (bp<(StackBottom + StackLength)) then
|
||||||
for i:=1 to tracesize do
|
for i:=1 to tracesize do
|
||||||
begin
|
begin
|
||||||
pp^.calls[i]:=get_caller_addr(bp);
|
|
||||||
oldbp:=bp;
|
oldbp:=bp;
|
||||||
bp:=get_caller_frame(bp);
|
get_caller_stackinfo(bp,pcaddr);
|
||||||
|
pp^.calls[i]:=pcaddr;
|
||||||
if (bp<oldbp) or (bp>(StackBottom + StackLength)) then
|
if (bp<oldbp) or (bp>(StackBottom + StackLength)) then
|
||||||
break;
|
break;
|
||||||
end;
|
end;
|
||||||
@ -979,6 +1001,7 @@ var
|
|||||||
{$ifdef morphos}
|
{$ifdef morphos}
|
||||||
stack_top: longword;
|
stack_top: longword;
|
||||||
{$endif morphos}
|
{$endif morphos}
|
||||||
|
bp,pcaddr : pointer;
|
||||||
ptext : ^text;
|
ptext : ^text;
|
||||||
label
|
label
|
||||||
_exit;
|
_exit;
|
||||||
@ -1136,7 +1159,10 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
writeln(ptext^,'pointer $',hexstr(p),' does not point to valid memory block');
|
writeln(ptext^,'pointer $',hexstr(p),' does not point to valid memory block');
|
||||||
dump_stack(ptext^,get_caller_frame(get_frame));
|
bp:=get_frame;
|
||||||
|
pcaddr:=get_pc_addr;
|
||||||
|
get_caller_stackinfo(bp,pcaddr);
|
||||||
|
dump_stack(ptext^,bp,pcaddr);
|
||||||
runerror(204);
|
runerror(204);
|
||||||
_exit:
|
_exit:
|
||||||
end;
|
end;
|
||||||
|
@ -669,43 +669,60 @@ End;
|
|||||||
Miscellaneous
|
Miscellaneous
|
||||||
*****************************************************************************}
|
*****************************************************************************}
|
||||||
|
|
||||||
{$ifndef FPC_SYSTEM_HAS_GET_ADDR}
|
{$ifndef FPC_SYSTEM_HAS_GET_PC_ADDR}
|
||||||
{ This provides a dummy implementation
|
{ This provides a dummy implementation
|
||||||
of get_addr function, for CPU's that don't need
|
of get_pc_addr function, for CPU's that don't need
|
||||||
the instruction address to walk the stack. }
|
the instruction address to walk the stack. }
|
||||||
function get_addr : pointer;
|
function get_pc_addr : pointer;
|
||||||
begin
|
begin
|
||||||
get_addr:=nil;
|
get_pc_addr:=nil;
|
||||||
end;
|
end;
|
||||||
{$endif ndef FPC_SYSTEM_HAS_GET_ADDR}
|
{$endif ndef FPC_SYSTEM_HAS_GET_PC_ADDR}
|
||||||
|
|
||||||
|
{$ifndef FPC_SYSTEM_HAS_GET_CALLER_STACKINFO}
|
||||||
|
{ This provides a simpel implementation
|
||||||
|
of get_caller_stackinfo procedure,
|
||||||
|
using get_caller_addr and get_caller_frame
|
||||||
|
functions. }
|
||||||
|
procedure get_caller_stackinfo(var framebp,addr : pointer);
|
||||||
|
var
|
||||||
|
nextbp,nextaddr : pointer;
|
||||||
|
begin
|
||||||
|
nextbp:=get_caller_frame(framebp,addr);
|
||||||
|
nextaddr:=get_caller_addr(framebp,addr);
|
||||||
|
framebp:=nextbp;
|
||||||
|
addr:=nextaddr;
|
||||||
|
end;
|
||||||
|
{$endif ndef FPC_SYSTEM_HAS_GET_CALLER_STACKINFO}
|
||||||
|
|
||||||
|
|
||||||
procedure fpc_rangeerror;[public,alias:'FPC_RANGEERROR']; compilerproc;
|
procedure fpc_rangeerror;[public,alias:'FPC_RANGEERROR']; compilerproc;
|
||||||
begin
|
begin
|
||||||
HandleErrorAddrFrame(201,get_addr,get_frame);
|
HandleErrorAddrFrame(201,get_pc_addr,get_frame);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure fpc_divbyzero;[public,alias:'FPC_DIVBYZERO']; compilerproc;
|
procedure fpc_divbyzero;[public,alias:'FPC_DIVBYZERO']; compilerproc;
|
||||||
begin
|
begin
|
||||||
HandleErrorAddrFrame(200,get_addr,get_frame);
|
HandleErrorAddrFrame(200,get_pc_addr,get_frame);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure fpc_overflow;[public,alias:'FPC_OVERFLOW']; compilerproc;
|
procedure fpc_overflow;[public,alias:'FPC_OVERFLOW']; compilerproc;
|
||||||
begin
|
begin
|
||||||
HandleErrorAddrFrame(215,get_addr,get_frame);
|
HandleErrorAddrFrame(215,get_pc_addr,get_frame);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure fpc_threaderror; [public,alias:'FPC_THREADERROR'];
|
procedure fpc_threaderror; [public,alias:'FPC_THREADERROR'];
|
||||||
begin
|
begin
|
||||||
HandleErrorAddrFrame(6,get_addr,get_frame);
|
HandleErrorAddrFrame(6,get_pc_addr,get_frame);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure fpc_invalidpointer; [public,alias:'FPC_INVALIDPOINTER'];
|
procedure fpc_invalidpointer; [public,alias:'FPC_INVALIDPOINTER'];
|
||||||
begin
|
begin
|
||||||
HandleErrorAddrFrame(216,get_addr,get_frame);
|
HandleErrorAddrFrame(216,get_pc_addr,get_frame);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -719,7 +736,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
l:=HInOutRes^;
|
l:=HInOutRes^;
|
||||||
HInOutRes^:=0;
|
HInOutRes^:=0;
|
||||||
HandleErrorAddrFrame(l,get_addr,get_frame);
|
HandleErrorAddrFrame(l,get_pc_addr,get_frame);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -748,7 +765,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
if assigned(SafeCallErrorProc) then
|
if assigned(SafeCallErrorProc) then
|
||||||
SafeCallErrorProc(res,get_frame);
|
SafeCallErrorProc(res,get_frame);
|
||||||
HandleErrorAddrFrame(229,get_addr,get_frame);
|
HandleErrorAddrFrame(229,get_pc_addr,get_frame);
|
||||||
end;
|
end;
|
||||||
result:=res;
|
result:=res;
|
||||||
end;
|
end;
|
||||||
@ -1035,15 +1052,20 @@ Procedure HandleError (Errno : longint);[public,alias : 'FPC_HANDLEERROR'];
|
|||||||
Internal function should ALWAYS call HandleError instead of RunError.
|
Internal function should ALWAYS call HandleError instead of RunError.
|
||||||
}
|
}
|
||||||
begin
|
begin
|
||||||
HandleErrorAddrFrame(Errno,get_frame,get_addr);
|
HandleErrorAddrFrame(Errno,get_pc_addr,get_frame);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure RunError(w : word);[alias: 'FPC_RUNERROR'];
|
procedure RunError(w : word);[alias: 'FPC_RUNERROR'];
|
||||||
|
var
|
||||||
|
bp,pcaddr : pointer;
|
||||||
begin
|
begin
|
||||||
errorcode:=w;
|
errorcode:=w;
|
||||||
erroraddr:=get_caller_addr(get_frame,get_addr);
|
pcaddr:=get_pc_addr;
|
||||||
errorbase:=get_caller_frame(get_frame,get_addr);
|
bp:=get_frame;
|
||||||
|
get_caller_stackinfo(bp,pcaddr);
|
||||||
|
erroraddr:=pcaddr;
|
||||||
|
errorbase:=bp;
|
||||||
Halt(errorcode);
|
Halt(errorcode);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1283,7 +1305,7 @@ procedure fpc_AbstractErrorIntern;compilerproc;[public,alias : 'FPC_ABSTRACTERRO
|
|||||||
begin
|
begin
|
||||||
If pointer(AbstractErrorProc)<>nil then
|
If pointer(AbstractErrorProc)<>nil then
|
||||||
AbstractErrorProc();
|
AbstractErrorProc();
|
||||||
HandleErrorAddrFrame(211,get_addr,get_frame);
|
HandleErrorAddrFrame(211,get_pc_addr,get_frame);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -1293,7 +1315,7 @@ begin
|
|||||||
if pointer(AssertErrorProc)<>nil then
|
if pointer(AssertErrorProc)<>nil then
|
||||||
AssertErrorProc(Msg,FName,LineNo,ErrorAddr)
|
AssertErrorProc(Msg,FName,LineNo,ErrorAddr)
|
||||||
else
|
else
|
||||||
HandleErrorAddrFrame(227,get_addr,get_frame);
|
HandleErrorAddrFrame(227,get_pc_addr,get_frame);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1066,10 +1066,11 @@ function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer;[INTERNPROC:
|
|||||||
function get_frame:pointer;{$ifdef SYSTEMINLINE}inline;{$endif}
|
function get_frame:pointer;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
Function Get_addr : Pointer;
|
Function Get_pc_addr : Pointer;
|
||||||
|
|
||||||
function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer;
|
function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer;
|
||||||
function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer;
|
function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer;
|
||||||
|
procedure get_caller_stackinfo(var framebp,addr : pointer);
|
||||||
|
|
||||||
Function IOResult:Word;
|
Function IOResult:Word;
|
||||||
Function Sptr:Pointer;[internconst:fpc_in_const_ptr];
|
Function Sptr:Pointer;[internconst:fpc_in_const_ptr];
|
||||||
|
@ -74,22 +74,97 @@ function get_frame:pointer;assembler;nostackframe;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
{$define FPC_SYSTEM_HAS_GET_CALLER_ADDR}
|
{ Try to find previous $fp,$ra register pair
|
||||||
function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer;assembler;nostackframe;
|
reset both to nil if failure }
|
||||||
asm
|
{$define FPC_SYSTEM_HAS_GET_CALLER_STACKINFO}
|
||||||
// lw $2,4($4) // #movl 4(%eax),%eax
|
procedure get_caller_stackinfo(var framebp,addr : pointer);
|
||||||
lui $2,0
|
const
|
||||||
|
instr_size = 4;
|
||||||
|
MAX_INSTRUCTIONS = 64000;
|
||||||
|
type
|
||||||
|
instr_p = pdword;
|
||||||
|
reg_p = ppointer;
|
||||||
|
var
|
||||||
|
instr,stackpos : dword;
|
||||||
|
i,LocalSize : longint;
|
||||||
|
ra_offset, s8_offset : longint;
|
||||||
|
current_ra : pointer;
|
||||||
|
begin
|
||||||
|
{ Here we need to use GDB approach,
|
||||||
|
starting at addr
|
||||||
|
go back to lower $ra values until we find a
|
||||||
|
position with ADDIU $sp,$sp,-LocalSize
|
||||||
|
}
|
||||||
|
Try
|
||||||
|
current_ra:=addr;
|
||||||
|
ra_offset:=-1;
|
||||||
|
s8_offset:=-1;
|
||||||
|
i:=0;
|
||||||
|
LocalSize:=0;
|
||||||
|
repeat
|
||||||
|
inc(i);
|
||||||
|
dec(current_ra,4);
|
||||||
|
instr:=instr_p(current_ra)^;
|
||||||
|
if (instr shr 16 = $27bd) then
|
||||||
|
begin
|
||||||
|
{ we found the instruction,
|
||||||
|
local size is the lo part }
|
||||||
|
LocalSize:=smallint(instr and $ffff);
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
until i> MAX_INSTRUCTIONS;
|
||||||
|
if LocalSize <> 0 then
|
||||||
|
begin
|
||||||
|
repeat
|
||||||
|
inc(current_ra,4);
|
||||||
|
instr:=instr_p(current_ra)^;
|
||||||
|
if (instr shr 16 = $afbf) then
|
||||||
|
ra_offset:=smallint(instr and $ffff)
|
||||||
|
else if (instr shr 16 = $afbe) then
|
||||||
|
s8_offset:=smallint(instr and $ffff);
|
||||||
|
until (current_ra >= addr)
|
||||||
|
or ((ra_offset<>-1) and (s8_offset<>-1));
|
||||||
|
if ra_offset<>-1 then
|
||||||
|
begin
|
||||||
|
stackpos:=dword(framebp+LocalSize+ra_offset);
|
||||||
|
addr:=reg_p(stackpos)^;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
addr:=nil;
|
||||||
|
if s8_offset<>-1 then
|
||||||
|
begin
|
||||||
|
stackpos:=dword(framebp+LocalSize+s8_offset);
|
||||||
|
framebp:=reg_p(stackpos)^;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
framebp:=nil;
|
||||||
|
end;
|
||||||
|
Except
|
||||||
|
framebp:=nil;
|
||||||
|
addr:=nil;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{$define FPC_SYSTEM_HAS_GET_PC_ADDR}
|
||||||
|
function get_pc_addr : pointer;assembler;nostackframe;
|
||||||
|
asm
|
||||||
|
move $2,$31
|
||||||
|
end;
|
||||||
|
|
||||||
|
{$define FPC_SYSTEM_HAS_GET_CALLER_ADDR}
|
||||||
|
function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer;
|
||||||
|
begin
|
||||||
|
get_caller_stackinfo(framebp,addr);
|
||||||
|
get_caller_addr:=addr;
|
||||||
|
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;
|
function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer;
|
||||||
asm
|
begin
|
||||||
// lw $2,0($4) // #movl (%eax),%eax
|
get_caller_stackinfo(framebp,addr);
|
||||||
lui $2,0
|
get_caller_frame:=framebp;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
{$define FPC_SYSTEM_HAS_SPTR}
|
{$define FPC_SYSTEM_HAS_SPTR}
|
||||||
function Sptr:Pointer;assembler;nostackframe;
|
function Sptr:Pointer;assembler;nostackframe;
|
||||||
asm
|
asm
|
||||||
|
@ -35,8 +35,8 @@ asm
|
|||||||
end;
|
end;
|
||||||
{$ENDIF not INTERNAL_BACKTRACE}
|
{$ENDIF not INTERNAL_BACKTRACE}
|
||||||
|
|
||||||
{$define FPC_SYSTEM_HAS_GET_ADDR}
|
{$define FPC_SYSTEM_HAS_GET_PC_ADDR}
|
||||||
function get_addr:pointer;assembler;
|
function get_pc_addr:pointer;assembler;
|
||||||
asm
|
asm
|
||||||
movq (%rsp),%rax
|
movq (%rsp),%rax
|
||||||
end;
|
end;
|
||||||
|
Loading…
Reference in New Issue
Block a user