[fpc-devel] Internal jump instructions for longer conditional jumps
Martin Frb
lazarus at mfriebe.de
Mon Apr 20 22:45:59 CEST 2020
On 20/04/2020 22:11, Florian Klämpfl wrote:
> Am 20.04.20 um 16:44 schrieb Martin:
>> FPC sometimes generates jump instructions as follows. (Not always
>> bound to "IF" but that is the example I found
>> - If such jumps are within line info, they should not be at the start
>> of a line?
>
> Do you have some example code which shows this (together with the
> needed optimizer switches)?
I have not yet tried in a small example. I got it in the Lazarus IDE
from svn (with fpc 3.0.4)
components\fpdebug\fpdbgcontroller.pas
line 795 and following
-gh -g -gw -godwarfsets -gl -dCR -Ct -Co -Cr -Ci -gt -Sa -ve -vw
-vn -vi -O- -CX -WC
See the lines marked with //////////
It may be the nested "IF"
If the inner "IF" evals false, it skips over it's "then" block. It jumps
" jmp +$61 " to after the "then begin end" block.
That might actually be the line, that is the "end" of the outer "then"
block, so that jump is skipping over the outer "else" block.
However, this jump, has the same line info as the "exit" line. Even so
the "exit" is in the "then" block, and this "jmp" line is outside of it.
I checked the line info with objdump.
So I guess, having had a 2nd look, I got a better explanation.
Technically this "jmp" would probably belong to the "end" of the outer
"then" block. But "end" for such blocks usually has no line info.
procedure TDbgControllerStepOutCmd.InternalContinue(AProcess: TDbgProcess;
AThread: TDbgThread);
var
Outside: Boolean;
begin
assert(FProcess=AProcess, 'TDbgControllerStepOutCmd.DoContinue:
FProcess=AProcess');
if (AThread = FThread) then begin
if IsSteppedOut then begin
CheckForCallAndSetBreak;
end
else
if not assigned(FHiddenBreakpoint) then begin
if GetOutsideFrame(Outside) then begin
SetReturnAdressBreakpoint(AProcess, Outside);
end
else
if FStepCount < 12 then
begin
Inc(FStepCount);
if NextInstruction.IsCallInstruction or
NextInstruction.IsLeaveStackFrame then // asm "call" // set break
before "leave" or the frame becomes unavail
begin
SetReturnAdressBreakpoint(AProcess, False);
end
else
if NextInstruction.IsReturnInstruction then /////////////////
LINE 817 ////////////////
begin
FStepCount := MaxInt; // Do one more single-step, and we're
finished.
FProcess.Continue(FProcess, FThread, True);
exit; /////////////// LINE 821 //////////////// here goes
the forwarder
end;
end
else
begin
// Enough with the single-stepping
SetReturnAdressBreakpoint(AProcess, False);
end;
end;
end;
FProcess.Continue(FProcess, FThread, FHiddenBreakpoint = nil);
///////////////// LINE 832 ////////////
end;
B:\lazarus_latest_svn_2\components\fpdebug\fpdbgcontroller.pas:817 if
NextInstruction.IsReturnInstruction then // asm "ret"
0000000100D93578 488B45E8 mov rax,[rbp-$18]
0000000100D9357C 4883782800 cmp qword ptr [rax+$28],$00
0000000100D93581 7405 jz +$05
0000000100D93583 E99E000000 jmp +$0000009E
0000000100D93588 488B45E8 mov rax,[rbp-$18]
........
0000000100D93649 E8420E27FF call -$00D8F1BE
0000000100D9364E 4889F1 mov rcx,rsi
0000000100D93651 FF97E8000000 call dword ptr [rdi+$000000E8]
0000000100D93657 84C0 test al,al
0000000100D93659 7502 jnz +$02
0000000100D9365B EB61 jmp +$61 ////
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
B:\lazarus_latest_svn_2\components\fpdebug\fpdbgcontroller.pas:819
FStepCount := MaxInt; // Do one more single-step, and we're finished.
0000000100D9365D 488B45E8 mov rax,[rbp-$18]
0000000100D93661 C78088000000FFFFFF7F mov [rax+$00000088],$7FFFFFFF
B:\lazarus_latest_svn_2\components\fpdebug\fpdbgcontroller.pas:820
FProcess.Continue(FProcess, FThread, True);
0000000100D9366B 488B45E8 mov rax,[rbp-$18]
0000000100D9366F 4C8B6810 mov r13,[rax+$10]
0000000100D93673 488B45E8 mov rax,[rbp-$18]
..............................
0000000100D936B0 4C89E2 mov rdx,r12
0000000100D936B3 4D89E8 mov rax,r13
0000000100D936B6 FF9390010000 call dword ptr [rbx+$00000190]
B:\lazarus_latest_svn_2\components\fpdebug\fpdbgcontroller.pas:821 exit;
0000000100D936BC EB70 jmp +$70 /////////// jump to
end of proc
0000000100D936BE EB13 jmp +$13 ////
XXXXXXXXXXXXXXXX This is where the jump forwards to line 832
B:\lazarus_latest_svn_2\components\fpdebug\fpdbgcontroller.pas:827
SetReturnAdressBreakpoint(AProcess, False);
0000000100D936C0 488B55F8 mov rdx,[rbp-$08]
0000000100D936C4 488B4DE8 mov rcx,[rbp-$18]
0000000100D936C8 41B800000000 mov eax,$00000000
0000000100D936CE E8CDF7FFFF call -$00000833
B:\lazarus_latest_svn_2\components\fpdebug\fpdbgcontroller.pas:832
FProcess.Continue(FProcess, FThread, FHiddenBreakpoint = nil);
0000000100D936D3 488B45E8 mov rax,[rbp-$18]
0000000100D936D7 4883784800 cmp qword ptr [rax+$48],$00
More information about the fpc-devel
mailing list