1
(*******************************************************************
5
* This unit is only used by the debugger.
7
* Copyright 1996 David Turner, Robert Wilhelm and Werner Lemberg
9
* This file is part of the FreeType project, and may only be used
10
* modified and distributed under the terms of the FreeType project
11
* license, LICENSE.TXT. By continuing to use, modify or distribute
12
* this file you indicate that you have read the license and
13
* understand and accept it fully.
15
******************************************************************)
23
uses SysUtils, TTTypes, TTObjs;
27
ByteHexStr = string[2]; (* hex representation of a byte *)
28
ShortHexStr = string[4]; (* " " " short *)
29
LongHexStr = string[8]; (* " " " long *)
30
DebugStr = string[128]; (* disassembled line output *)
34
{ A simple record to hold breakpoint information }
35
{ it may be completed later with pass count, etc.. }
36
{ They must be in a sorted linked list }
38
PBreakPoint = ^TBreakPoint;
47
{ a record to store line number information and breakpoints list }
49
PRangeRec = ^TRangeRec;
55
Disassembled : PUShort;
60
{ Generate_Range : Generate Line Number information specific to }
63
procedure Generate_Range( CR : PCodeRange;
67
{ Throw_Range : Discard Line Number Information }
69
procedure Throw_Range( var RR : TRangeRec );
71
{ Toggle_Break : Toggle a breakpoint }
73
procedure Toggle_Break( var Head : PBreakPoint; Range, Adr : Int );
75
{ Set_Break : Set a breakpoint on a given address }
77
procedure Set_Break ( var Head : PBreakPoint; Range, Adr : Int );
79
{ Clear_Break : Clear one specific breakpoint }
81
procedure Clear_Break( var Head : PBreakPoint; Bp : PBreakPoint );
83
{ Clear_All_Breaks : Clear breakpoint list }
85
procedure Clear_All_Breaks( var Head : PBreakPoint );
87
{ Find_Breakpoint : find one breakpoint at a given address }
89
function Find_BreakPoint( Head : PBreakPoint; Range, IP : Int ) : PBreakPoint;
91
{ Cur_U_Line : returns the current disassembled line at Code(IP) }
93
function Cur_U_Line( Code : PByte; IP : Int ) : DebugStr;
95
{ Get_Length : returns the length of the current opcode at Code(IP) }
97
function Get_Length( Code : PByte; IP : Int ) : Int;
99
function Get_Dis_Line( var cr : TRangeRec; addr : Int ) : Int;
102
{ Hex_N : returns an hexadecimal string }
104
function Hex8 ( B : Byte ) : ByteHexStr;
105
function Hex16( W : word ) : ShortHexStr;
106
function Hex32( L : Long ) : LongHexStr;
112
TStorageLong = record (* do-it-all union record type *)
115
1 : ( S1, S2 : Integer );
116
2 : ( W1, W2 : Word );
123
OpStr : array[ 0..255 ] of String[10]
125
'SVTCA y', (* Set vectors to coordinate axis y *)
126
'SVTCA x', (* Set vectors to coordinate axis x *)
127
'SPvTCA y', (* Set Proj. vec. to coord. axis y *)
128
'SPvTCA x', (* Set Proj. vec. to coord. axis x *)
129
'SFvTCA y', (* Set Free. vec. to coord. axis y *)
130
'SFvTCA x', (* Set Free. vec. to coord. axis x *)
131
'SPvTL //', (* Set Proj. vec. parallel to segment *)
132
'SPvTL +', (* Set Proj. vec. normal to segment *)
133
'SFvTL //', (* Set Free. vec. parallel to segment *)
134
'SFvTL +', (* Set Free. vec. normal to segment *)
135
'SPvFS', (* Set Proj. vec. from stack *)
136
'SFvFS', (* Set Free. vec. from stack *)
137
'GPV', (* Get projection vector *)
138
'GFV', (* Get freedom vector *)
139
'SFvTPv', (* Set free. vec. to proj. vec. *)
140
'ISECT', (* compute intersection *)
142
'SRP0', (* Set reference point 0 *)
143
'SRP1', (* Set reference point 1 *)
144
'SRP2', (* Set reference point 2 *)
145
'SZP0', (* Set Zone Pointer 0 *)
146
'SZP1', (* Set Zone Pointer 1 *)
147
'SZP2', (* Set Zone Pointer 2 *)
148
'SZPS', (* Set all zone pointers *)
149
'SLOOP', (* Set loop counter *)
150
'RTG', (* Round to Grid *)
151
'RTHG', (* Round to Half-Grid *)
152
'SMD', (* Set Minimum Distance *)
154
'JMPR', (* Jump Relative *)
155
'SCvTCi', (* Set CVT *)
399
HexStr : string[16] = '0123456789abcdef';
401
(*******************************************************************
405
* Description : Returns the string hexadecimal representation
410
* Output : two-chars string
412
*****************************************************************)
414
function Hex8( B : Byte ) : ByteHexStr;
419
S[1] := HexStr[ 1+( B shr 4 ) ];
420
S[2] := HexStr[ 1+( B and 15 )];
424
(*******************************************************************
428
* Description : Returns the string hexadecimal representation
433
* Output : four-chars string
435
*****************************************************************)
437
function Hex16( W : word ) : ShortHexStr;
439
Hex16 := Hex8( Hi(w) )+Hex8( Lo(w) );
442
(*******************************************************************
446
* Description : Returns the string hexadecimal representation
451
* Output : eight-chars string
453
*****************************************************************)
455
function Hex32( L : Long ) : LongHexStr;
457
Result := SysUtils.IntToHex(L, 8);
458
// Hex32 := Hex16( TStorageLong(L).W2 )+Hex16( TStorageLong(L).W1 );
461
(*******************************************************************
463
* Function : Cur_U_Line
465
* Description : Returns a string of the current unassembled
468
* Input : Code base code range
469
* IP current instruction pointer
471
* Output : line string
473
*****************************************************************)
475
function Cur_U_Line( Code : PByte; IP : Int ) : DebugStr;
483
S := Hex16(IP)+': '+Hex8(Op)+' '+OpStr[Op];
489
S := S+'('+Hex8(n)+')';
491
S := S+' $'+Hex8( Code^[Ip+i+1] );
496
S := S+'('+Hex8(n)+')';
498
S := S+' $'+Hex8( Code^[Ip+i*2+1] )+Hex8( Code^[Ip+i*2+2] );
504
S := S+' $'+Hex8( Code^[Ip+i+1] );
510
S := S+' $'+Hex8( Code^[IP+i*2+1] )+Hex8( Code^[Ip+i*2+2] );
518
(*******************************************************************
520
* Function : Get_Length
522
* Description : Returns the length in bytes of the instruction at
523
* current instruction pointer.
525
* Input : Code base code range
526
* IP current instruction pointer
528
* Output : Length in bytes
530
*****************************************************************)
532
function Get_Length( Code : PByte; IP : Int ) : Int;
542
$40 : N := 2 + Code^[IP+1];
543
$41 : N := 2 + Code^[IP+1]*2;
545
$B0..$B7 : N := 2 + ( Op-$B0 );
546
$B8..$BF : N := 3 + ( Op-$B8 )*2
556
(*******************************************************************
558
* Function : Generate_Range
560
* Description : Create a list of unassembled lines for a
567
*****************************************************************)
569
procedure Generate_Range( CR : PCodeRange;
571
var RR : TRangeRec );
578
RR.Code := PByte( CR^.Base );
586
GetMem( RR.Disassembled, sizeof(Short) * N );
590
RR.Disassembled^[Line] := Adr;
592
inc( Adr, Get_Length( RR.Code, Adr ));
601
(*******************************************************************
603
* Function : Get_Dis_Line
605
* Description : Returns the line index of address 'addr'
606
* in the coderange 'cr'
608
*****************************************************************)
610
function Get_Dis_Line( var cr : TRangeRec; addr : Int ) : Int;
614
if (cr.NLines = 0) or
615
(addr > cr.Disassembled^[cr.Nlines-1] ) then
626
if cr.Disassembled^[l] = addr then
632
if cr.Disassembled^[r] = addr then
639
if cr.Disassembled^[m] = addr then
645
if cr.Disassembled^[m] < addr then
651
if cr.Disassembled^[r] = addr then
661
(*******************************************************************
663
* Function : Throw_Range
665
* Description : Destroys a list of unassembled lines for a
672
*****************************************************************)
674
procedure Throw_Range( var RR : TRangeRec );
676
B, Bnext : PBreakPoint;
680
FreeMem( RR.Disassembled, RR.Size * sizeof(Short) );
682
RR.Disassembled := nil;
698
(*******************************************************************
700
* Function : Set_Break
702
* Description : Sets a Breakpoint ON
708
*****************************************************************)
710
procedure Set_Break( var Head : PBreakPoint;
721
while (Cur <> nil) and (Cur^.Address < Adr) do
729
if (Cur^.Address = Adr) and (Cur^.Range = Range) then exit;
742
(*******************************************************************
744
* Function : Clear_Break
746
* Description : Clears a breakpoint OFF
752
*****************************************************************)
754
procedure Clear_Break( var Head : PBreakPoint; Bp : PBreakPoint );
762
while (Cur <> nil) and (Cur <> Bp) do
768
if Cur = nil then exit;
773
Old^.Next := Cur^.Next;
778
procedure Toggle_Break( var Head : PBreakPoint; Range, Adr : Int );
782
Bp := Find_BreakPoint( Head, Range, Adr );
783
if Bp <> nil then Clear_Break( Head, Bp )
784
else Set_Break( Head, Range, Adr );
787
(*******************************************************************
789
* Function : Clear_All_Breaks
791
* Description : Clears all breakpoints
797
*****************************************************************)
799
procedure Clear_All_Breaks( var Head : PBreakPoint );
815
(*******************************************************************
817
* Function : Find_BreakPoint
819
* Description : Find a breakpoint at address IP
821
* Input : Head break points sorted linked list
822
* IP address of expected breakpoint
824
* Output : pointer to breakpoint if found
827
*****************************************************************)
829
function Find_BreakPoint( Head : PBreakPoint; Range, IP : Int ) : PBreakPoint;
839
if (Cur^.Address = IP ) and
840
(Cur^.Range = Range) then Res := Cur;
842
if (Cur^.Address >= IP) then Cur := nil
843
else Cur := Cur^.Next;
846
Find_BreakPoint := Res;