mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-27 17:20:29 +02:00
Debugger: more asm unwinding
This commit is contained in:
parent
eb6e46b08f
commit
8a343f5bc1
@ -5231,10 +5231,11 @@ function TX86AsmDecoder.UnwindFrame(var AnAddress, AStackPtr,
|
||||
end;
|
||||
|
||||
const
|
||||
MAX_SEARCH_ADDR = 1000;
|
||||
MAX_SEARCH_CNT = 80;
|
||||
MAX_SEARCH_ADDR = 8000;
|
||||
MAX_SEARCH_CNT = 400;
|
||||
var
|
||||
NewAddr, NewStack, NewFrame, MaxAddr, StartStack: TDBGPtr;
|
||||
NewAddr, NewStack, NewFrame, MaxAddr, MaxAddr2, StartAddr, StartStack, Tmp: TDBGPtr;
|
||||
ConditionalForwardAddr, BackwardJumpAddress: TDBGPtr;
|
||||
Cnt: Integer;
|
||||
instr: TX86AsmInstruction;
|
||||
RSize: Cardinal;
|
||||
@ -5242,18 +5243,33 @@ var
|
||||
CurAddr: PByte;
|
||||
begin
|
||||
Result := False;
|
||||
NewAddr := AnAddress;
|
||||
NewStack := AStackPtr;
|
||||
NewAddr := AnAddress;
|
||||
NewStack := AStackPtr;
|
||||
NewFrame := AFramePtr;
|
||||
StartAddr := AnAddress;
|
||||
StartStack := AStackPtr;
|
||||
NewFrame := AFramePtr;
|
||||
ConditionalForwardAddr := 0;
|
||||
BackwardJumpAddress := 0;
|
||||
|
||||
{$PUSH}{$R-}{$Q-}
|
||||
MaxAddr := AnAddress + MAX_SEARCH_ADDR;
|
||||
{$POP}
|
||||
MaxAddr2 := MaxAddr;
|
||||
Cnt := MAX_SEARCH_CNT;
|
||||
if AQuick then Cnt := 10;
|
||||
|
||||
while (NewAddr < MaxAddr) and (Cnt > 0) do begin
|
||||
if NewAddr > MaxAddr2 then begin
|
||||
if (ConditionalForwardAddr > 0) and (BackwardJumpAddress > 0) and
|
||||
(ConditionalForwardAddr >= BackwardJumpAddress)
|
||||
then begin
|
||||
NewAddr := ConditionalForwardAddr;
|
||||
MaxAddr2 := MaxAddr;
|
||||
end
|
||||
else
|
||||
exit;
|
||||
end;
|
||||
|
||||
dec(Cnt);
|
||||
instr := TX86AsmInstruction(GetInstructionInfo(NewAddr));
|
||||
if instr.InstructionLength <= 0 then
|
||||
@ -5303,7 +5319,16 @@ begin
|
||||
NewStack := NewStack - RegisterSize(instr.X86Instruction.Operand[1].Value);
|
||||
{$POP}
|
||||
end;
|
||||
OPpusha, OPpushf:
|
||||
OPpusha:
|
||||
begin
|
||||
if (FProcess.Mode <> dm32) or (instr.X86Instruction.OpCode.Suffix <> OPSx_d) then
|
||||
exit;
|
||||
// push 8 registers
|
||||
{$PUSH}{$R-}{$Q-}
|
||||
NewStack := NewStack - (8*4);
|
||||
{$POP}
|
||||
end;
|
||||
OPpushf:
|
||||
exit; // false
|
||||
OPpopa, OPpopad:
|
||||
exit; // false
|
||||
@ -5347,16 +5372,21 @@ begin
|
||||
if instr.X86Instruction.OperCnt <> 2 then
|
||||
exit;
|
||||
|
||||
if IsRegister(instr.X86Instruction.Operand[1].Value, 'sp')
|
||||
if IsRegister(instr.X86Instruction.Operand[1].Value, 'sp') and
|
||||
not(ofMemory in Instr.X86Instruction.Operand[2].Flags)
|
||||
then begin
|
||||
if (not IsRegister(instr.X86Instruction.Operand[2].Value, 'bp')) or
|
||||
(Instr.X86Instruction.Operand[2].ByteCount <> 0) or
|
||||
(Instr.X86Instruction.Operand[2].ByteCount2 <> 0) or
|
||||
(ofMemory in Instr.X86Instruction.Operand[2].Flags)
|
||||
then
|
||||
exit;
|
||||
exit; // TODO: check if source is known part of stack
|
||||
NewStack := NewFrame;
|
||||
end;
|
||||
if IsRegister(instr.X86Instruction.Operand[1].Value, 'bp') and
|
||||
not(ofMemory in Instr.X86Instruction.Operand[2].Flags)
|
||||
then
|
||||
exit; // TODO: check if source is SP or known part of stack
|
||||
end;
|
||||
OPlea:
|
||||
begin
|
||||
@ -5420,6 +5450,23 @@ begin
|
||||
{$POP}
|
||||
end;
|
||||
end;
|
||||
OPj__:
|
||||
if (not AQuick) and
|
||||
(instr.X86Instruction.OperCnt = 1) and
|
||||
(instr.X86Instruction.Operand[1].Value = '%s') and
|
||||
(Instr.X86Instruction.Operand[1].ByteCount > 0) and
|
||||
(Instr.X86Instruction.Operand[1].ByteCount2 = 0)
|
||||
then
|
||||
begin
|
||||
Val := ValueFromMem(CurAddr[Instr.X86Instruction.Operand[1].CodeIndex], Instr.X86Instruction.Operand[1].ByteCount, Instr.X86Instruction.Operand[1].FormatFlags);
|
||||
if Val > 0 then begin
|
||||
{$PUSH}{$R-}{$Q-}
|
||||
Tmp := NewAddr + Val;
|
||||
{$POP}
|
||||
if (Tmp > ConditionalForwardAddr) and (Tmp < MaxAddr) then
|
||||
ConditionalForwardAddr := Tmp;
|
||||
end;
|
||||
end;
|
||||
OPjmp:
|
||||
begin
|
||||
if AQuick then
|
||||
@ -5429,18 +5476,27 @@ begin
|
||||
if (instr.X86Instruction.Operand[1].Value <> '%s') then
|
||||
exit; // false
|
||||
if (Instr.X86Instruction.Operand[1].ByteCount = 0) or
|
||||
(Instr.X86Instruction.Operand[1].ByteCount > 2) or
|
||||
(Instr.X86Instruction.Operand[1].ByteCount2 <> 0)
|
||||
then
|
||||
exit;
|
||||
|
||||
Val := ValueFromMem(CurAddr[Instr.X86Instruction.Operand[1].CodeIndex], Instr.X86Instruction.Operand[1].ByteCount, Instr.X86Instruction.Operand[1].FormatFlags);
|
||||
if Val <= 0 then
|
||||
exit;
|
||||
|
||||
{$PUSH}{$R-}{$Q-}
|
||||
NewAddr := NewAddr + Val
|
||||
Tmp := NewAddr + Val;
|
||||
{$POP}
|
||||
if (Val < 0) then begin
|
||||
if ConditionalForwardAddr >= NewAddr then begin
|
||||
NewAddr := ConditionalForwardAddr;
|
||||
continue;
|
||||
end;
|
||||
|
||||
if (Tmp > StartAddr) or (Tmp < StartAddr - MAX_SEARCH_ADDR) then
|
||||
exit;
|
||||
MaxAddr2 := StartAddr;
|
||||
BackwardJumpAddress := NewAddr;
|
||||
end;
|
||||
|
||||
NewAddr := Tmp;
|
||||
end;
|
||||
OPjmpe, OPint, OPint1, OPint3:
|
||||
exit; // false
|
||||
|
Loading…
Reference in New Issue
Block a user