[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