[fpc-devel] Internal jump instructions for longer conditional jumps
Florian Klämpfl
florian at freepascal.org
Mon Apr 20 23:11:19 CEST 2020
Am 20.04.20 um 22:45 schrieb Martin Frb:
> 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
Can you post also the relevant output of -al? It makes it easier to see
where every assembler instruction comes from.
>
> 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
>
> _______________________________________________
> fpc-devel maillist - fpc-devel at lists.freepascal.org
> https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
More information about the fpc-devel
mailing list