home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2002 November
/
Chip_2002-11_cd1.bin
/
zkuste
/
delphi
/
kompon
/
d456
/
CAJSCRPT.ZIP
/
ifps3
/
demo_kylix
/
ifps3disasm.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
2002-07-12
|
12KB
|
408 lines
unit ifps3disasm;
{$I ifps3_def.inc}
interface
uses
ifps3, ifps3utl, ifps3common, sysutils;
function IFPS3DataToText(const Input: string; var Output: string): Boolean;
implementation
type
TMyIFPSExec = class(TIFPSExec)
function ImportProc(const Name: ShortString; var proc: TIFProcRec): Boolean; override;
end;
function Debug2Str(const s: string): string;
var
i: Integer;
begin
result := '';
for i := 1 to length(s) do
begin
if (s[i] < #32) or (s[i] > #128) then
result := result + '\'+inttohex(ord(s[i]), 2)
else if s[i] = '\' then
result := result + '\\'
else
result := result + s[i];
end;
end;
function SpecImportProc(Sender: TObject; p: PIFProcRec): Boolean; forward;
function IFPS3DataToText(const Input: string; var Output: string): Boolean;
var
I: TMyIFPSExec;
procedure Writeln(const s: string);
begin
Output := Output + s + #13#10;
end;
function BT2S(const S: TIFPSBaseType): string;
begin
case s of
btU8: Result := 'U8';
btS8: Result := 'S8';
btU16: Result := 'U16';
btS16: Result := 'S16';
btU32: Result := 'U32';
btS32: Result := 'S32';
btSingle: Result := 'Single';
btDouble: Result := 'Double';
btExtended: Result := 'Extended';
btString: Result := 'String';
btRecord: Result := 'Record';
btArray: Result := 'Array';
btResourcePointer: Result := 'ResourcePointer';
btPointer: Result := 'Pointer';
btVariant: Result := 'Variant';
else
Result := 'Unknown';
end;
end;
procedure WriteTypes;
var
T: Longint;
begin
Writeln('[TYPES]');
for T := 0 to i.FTypes.Count -1 do
begin
if PIFTypeRec(i.FTypes.getItem(t))^.ExportName <> '' then
Writeln('Type ['+inttostr(t)+']: '+bt2s(PIFTypeRec(i.FTypes.getItem(t))^.BaseType)+' Export: '+PIFTypeRec(i.FTypes.getItem(t))^.ExportName)
else
Writeln('Type ['+inttostr(t)+']: '+bt2s(PIFTypeRec(i.FTypes.getItem(t))^.BaseType));
end;
end;
procedure WriteVars;
var
T: Longint;
function FindType(p: Pointer): Cardinal;
var
T: Longint;
begin
Result := Cardinal(-1);
for T := 0 to i.FTypes.Count -1 do
begin
if p = i.FTypes.GetItem(t) then begin
result := t;
exit;
end;
end;
end;
begin
Writeln('[VARS]');
for t := 0 to i.FGlobalVars.count -1 do
begin
Writeln('Var ['+inttostr(t)+']: '+ IntToStr(FindType(PIFVariant(i.FGlobalVars.GetItem(t))^.FType)) + ' '+ bt2s(PIFVariant(i.FGlobalVars.GetItem(t))^.Ftype^.BaseType) + ' '+ PIFVariant(i.FGlobalVars.GetItem(t))^.Ftype^.ExportName);
end;
end;
procedure WriteProcs;
var
t: Longint;
procedure WriteProc(proc: PIFProcRec);
var
CP: Cardinal;
function ReadData(var Data; Len: Cardinal): Boolean;
begin
if CP + Len <= PROC .Length then begin
Move(Proc.Data^[CP], Data, Len);
CP := CP + Len;
Result := True;
end else Result := False;
end;
function ReadByte(var B: Byte): Boolean;
begin
if CP < Proc.Length then begin
b := Proc.Data^[cp];
Inc(CP);
Result := True;
end else Result := False;
end;
function ReadLong(var B: Cardinal): Boolean;
begin
if CP + 3 < Proc.Length then begin
b := Cardinal((@Proc.Data^[CP])^);
Inc(CP, 4);
Result := True;
end else Result := False;
end;
function ReadWriteVariable: string;
var
VarType: byte;
L1, L2: Cardinal;
function ReadVar(FType: Cardinal): string;
var
F: PIFTypeRec;
b: byte;
w: word;
l: Cardinal;
e: extended;
ss: single;
d: double;
s: string;
function strtostr(const S: string): string;
var
i : Longint;
begin
result := '''';
for i := 1 to length(s) do
begin
if s[i] = '''' then result := result + '''''' else
if s[i] in [#32..#127] then result := result + s[i] else
result := result + '''#'+inttostr(ord(s[i]))+'''';
end;
result := result + '''';
end;
begin
result := '';
F:= i.FTypes.GetItem(Ftype);
if f = nil then exit;
case f^.BaseType of
btU8: begin if not ReadData(b, 1) then exit; Result := IntToStr(tbtu8(B)); end;
btS8: begin if not ReadData(b, 1) then exit; Result := IntToStr(tbts8(B)); end;
btU16: begin if not ReadData(w, 2) then exit; Result := IntToStr(tbtu16(w)); end;
btS16: begin if not ReadData(w, 2) then exit; Result := IntToStr(tbts16(w)); end;
btU32: begin if not ReadData(l, 4) then exit; Result := IntToStr(tbtu32(l)); end;
btS32: begin if not ReadData(l, 4) then exit; Result := IntToStr(tbts32(l)); end;
btSingle: begin if not ReadData(ss, Sizeof(tbtsingle)) then exit; Result := FloatToStr(ss); end;
btDouble: begin if not ReadData(d, Sizeof(tbtdouble)) then exit; Result := FloatToStr(d); end;
btExtended: begin if not ReadData(e, Sizeof(tbtextended)) then exit; Result := FloatToStr(e); end;
btPChar, btString: begin if not ReadData(l, 4) then exit; SetLength(s, l); if not readData(s[1], l) then exit; Result := strtostr(s); end;
end;
end;
function AddressToStr(a: Cardinal): string;
begin
if a < IFPSAddrNegativeStackStart then
Result := 'GlobalVar['+inttostr(a)+']'
else
Result := 'Base['+inttostr(Longint(A-IFPSAddrStackStart))+']';
end;
begin
Result := '';
if not ReadByte(VarType) then Exit;
case VarType of
0:
begin
if not ReadLong(L1) then Exit;
Result := AddressToStr(L1);
end;
1:
begin
if not ReadLong(L1) then Exit;
Result := '['+ReadVar(l1)+']';
end;
2:
begin
if not ReadLong(L1) then Exit;
if not ReadLong(L2) then Exit;
Result := AddressToStr(L1)+'.['+inttostr(l2)+']';
end;
3:
begin
if not ReadLong(l1) then Exit;
if not ReadLong(l2) then Exit;
Result := AddressToStr(L1)+'.'+AddressToStr(l2);
end;
end;
end;
var
b: Byte;
s: string;
DP, D1, D2: Cardinal;
begin
CP := 0;
while true do
begin
DP := cp;
if not ReadByte(b) then Exit;
case b of
CM_A:
begin
Writeln(' ['+inttostr(dp)+'] ASSIGN '+ReadWriteVariable+ ', ' + ReadWriteVariable);
end;
CM_CA:
begin
if not ReadByte(b) then exit;
case b of
0: s:= '+';
1: s := '-';
2: s := '*';
3: s:= '/';
4: s:= 'MOD';
5: s:= 'SHL';
6: s:= 'SHR';
7: s:= 'AND';
8: s:= 'OR';
9: s:= 'XOR';
else
exit;
end;
Writeln(' ['+inttostr(dp)+'] CALC '+ReadWriteVariable+ ' '+s+' ' + ReadWriteVariable);
end;
CM_P:
begin
Writeln(' ['+inttostr(dp)+'] PUSH '+ReadWriteVariable);
end;
CM_PV:
begin
Writeln(' ['+inttostr(dp)+'] PUSHVAR '+ReadWriteVariable);
end;
CM_PO:
begin
Writeln(' ['+inttostr(dp)+'] POP');
end;
Cm_C:
begin
if not ReadLong(D1) then exit;
Writeln(' ['+inttostr(dp)+'] CALL '+inttostr(d1));
end;
Cm_G:
begin
if not ReadLong(D1) then exit;
Writeln(' ['+inttostr(dp)+'] GOTO currpos + '+IntToStr(d1)+' ['+IntToStr(CP+d1)+']');
end;
Cm_CG:
begin
if not ReadLong(D1) then exit;
Writeln(' ['+inttostr(dp)+'] COND_GOTO currpos + '+IntToStr(d1)+' '+ReadWriteVariable+' ['+IntToStr(CP+d1)+']');
end;
Cm_CNG:
begin
if not ReadLong(D1) then exit;
Writeln(' ['+inttostr(dp)+'] COND_NOT_GOTO currpos + '+IntToStr(d1)+' '+ReadWriteVariable+' ['+IntToStr(CP+d1)+']');
end;
Cm_R: Writeln(' ['+inttostr(dp)+'] RET');
Cm_ST:
begin
if not ReadLong(d1) or not readLong(d2) then exit;
Writeln(' ['+inttostr(dp)+'] SETSTACKTYPE Base['+inttostr(d1)+'] '+inttostr(d2));
end;
Cm_Pt:
begin
if not ReadLong(D1) then exit;
Writeln(' ['+inttostr(dp)+'] PUSHTYPE '+inttostr(d1));
end;
CM_CO:
begin
if not readByte(b) then exit;
case b of
0: s := '>=';
1: s := '<=';
2: s := '>';
3: s := '<';
4: s := '<>';
5: s := '=';
else exit;
end;
Writeln(' ['+inttostr(dp)+'] COMPARE into '+ReadWriteVariable+': '+ReadWriteVariable+' '+s+' '+ReadWriteVariable);
end;
Cm_cv:
begin
Writeln(' ['+inttostr(dp)+'] CALLVAR '+ReadWriteVariable);
end;
cm_sp:
begin
Writeln(' ['+inttostr(dp)+'] SETPOINTER '+ReadWriteVariable+': '+ReadWriteVariable);
end;
cm_bn:
begin
Writeln(' ['+inttostr(dp)+'] NOT '+ReadWriteVariable);
end;
cm_vm:
begin
Writeln(' ['+inttostr(dp)+'] MINUS '+ReadWriteVariable);
end;
cm_sf:
begin
s := ReadWriteVariable;
if not ReadByte(b) then exit;
if b = 0 then
Writeln(' ['+inttostr(dp)+'] SETFLAG '+s)
else
Writeln(' ['+inttostr(dp)+'] SETFLAG NOT '+s);
end;
cm_fg:
begin
if not ReadLong(D1) then exit;
Writeln(' ['+inttostr(dp)+'] FLAGGOTO currpos + '+IntToStr(d1)+' ['+IntToStr(CP+d1)+']');
end;
else
begin
Writeln(' Disasm Error');
Break;
end;
end;
end;
end;
begin
Writeln('[PROCS]');
for t := 0 to i.FProcs.Count -1 do
begin
if PIFProcRec(i.FProcs.GetItem(t))^.ExternalProc then
begin
if PIFProcRec(i.FProcs.GetItem(t))^.ExportDecl = '' then
Writeln('Proc ['+inttostr(t)+']: External: '+PIFProcRec(i.FProcs.GetItem(t))^.Name)
else
Writeln('Proc ['+inttostr(t)+']: External Decl: '+Debug2Str(PIFProcRec(i.FProcs.GetItem(t))^.ExportDecl));
end else begin
if PIFProcRec(i.FProcs.GetItem(t))^.ExportName <> '' then
begin
Writeln('Proc ['+inttostr(t)+'] Export: '+PIFProcRec(i.FProcs.GetItem(t))^.ExportName+' '+PIFProcRec(i.FProcs.GetItem(t))^.ExportDecl);
end else
Writeln('Proc ['+inttostr(t)+']');
Writeproc(i.FProcs.GetItem(t));
end;
end;
end;
begin
Result := False;
I := TMyIFPSExec.Create;
I.AddSpecialProcImport('', @SpecImportProc, nil);
if not I.LoadData(Input) then begin
I.Free;
Exit;
end;
Output := '';
WriteTypes;
WriteVars;
WriteProcs;
I.Free;
end;
{ TMyIFPSExec }
function MyDummyProc(Caller: TIFPSExec; p: PIFProcRec; Global, Stack: TIfList): Boolean;
begin
Result := False;
end;
function TMyIFPSExec.ImportProc(const Name: ShortString;
var proc: TIFProcRec): Boolean;
begin
Proc.ProcPtr := MyDummyProc;
result := true;
end;
function SpecImportProc(Sender: TObject; p: PIFProcRec): Boolean;
begin
p.ProcPtr := MyDummyProc;
Result := True;
end;
end.