tools added

This commit is contained in:
red-prig 2021-12-12 22:26:59 +03:00
parent 1218138700
commit d587f2dc78
16 changed files with 205842 additions and 0 deletions

View File

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<General>
<Flags>
<SaveClosedFiles Value="False"/>
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
<MainUnitHasScaledStatement Value="False"/>
<SaveJumpHistory Value="False"/>
<SaveFoldState Value="False"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<MainUnit Value="0"/>
<Title Value="dump_sym"/>
<UseAppBundle Value="False"/>
<ResourceType Value="res"/>
</General>
<BuildModes Count="1">
<Item1 Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
<UseFileFilters Value="True"/>
</PublishOptions>
<RunParams>
<FormatVersion Value="2"/>
<Modes Count="0"/>
</RunParams>
<Units Count="1">
<Unit0>
<Filename Value="dump_sym.lpr"/>
<IsPartOfProject Value="True"/>
</Unit0>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<Target>
<Filename Value="dump_sym"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir)"/>
<OtherUnitFiles Value="..\.."/>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<CodeGeneration>
<SmartLinkUnit Value="True"/>
<RelocatableUnit Value="True"/>
<Optimizations>
<OptimizationLevel Value="3"/>
</Optimizations>
</CodeGeneration>
<Linking>
<Debugging>
<GenerateDebugInfo Value="False"/>
</Debugging>
<LinkSmart Value="True"/>
</Linking>
</CompilerOptions>
<Debugging>
<Exceptions Count="3">
<Item1>
<Name Value="EAbort"/>
</Item1>
<Item2>
<Name Value="ECodetoolError"/>
</Item2>
<Item3>
<Name Value="EFOpenError"/>
</Item3>
</Exceptions>
</Debugging>
</CONFIG>

View File

@ -0,0 +1,88 @@
uses
{$IFDEF Linux}
cmem,
cthreads,
{$ENDIF}
Classes,sysutils,
ps4_elf;
var
ifname:RawByteString='';
ofname:RawByteString='';
sfname:RawByteString='';
i,n:Integer;
elf:Telf_file;
F:THandle;
label
promo;
begin
DefaultSystemCodePage:=CP_UTF8;
DefaultUnicodeCodePage:=CP_UTF8;
DefaultFileSystemCodePage:=CP_UTF8;
DefaultRTLFileSystemCodePage:=CP_UTF8;
UTF8CompareLocale:=CP_UTF8;
if (ParamCount=0) then
begin
promo:
Writeln('Tool for dump symbols from *.prx/*.sprx files');
Writeln(' Parameters:');
Writeln(' -i <name> //file name to load prx/sprx');
Writeln(' -o <name> //file name to save txt');
Writeln(' -s <name> //file name to save prx');
Exit;
end;
n:=-1;
For i:=1 to ParamCount do
begin
case LowerCase(ParamStr(i)) of
'-i':n:=0;
'-o':n:=1;
'-s':n:=2;
else
if (n<>-1) then
begin
Case n of
0:ifname:=ParamStr(i);
1:ofname:=ParamStr(i);
2:sfname:=ParamStr(i);
end;
n:=-1;
end;
end;
end;
if not FileExists(ifname) then
begin
Writeln('File not found:',ifname);
Writeln;
Goto promo;
end;
elf:=Telf_file(LoadPs4ElfFromFile(ifname));
elf.Prepare;
if (sfname<>'') then
elf.SavePs4ElfToFile(sfname);
if (ofname='') then
begin
ofname:=ChangeFileExt(ifname,'.txt');
end;
F:=FileCreate(ofname);
elf.DympSymbol(F);
FileClose(F);
FreeAndNil(elf);
writeln;
end.

80
tools/elf_sym/elf_sym.lpi Normal file
View File

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<General>
<Flags>
<SaveClosedFiles Value="False"/>
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
<MainUnitHasScaledStatement Value="False"/>
<SaveJumpHistory Value="False"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<MainUnit Value="0"/>
<Title Value="elf_sym"/>
<UseAppBundle Value="False"/>
<ResourceType Value="res"/>
</General>
<BuildModes Count="1">
<Item1 Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
<UseFileFilters Value="True"/>
</PublishOptions>
<RunParams>
<FormatVersion Value="2"/>
<Modes Count="0"/>
</RunParams>
<Units Count="2">
<Unit0>
<Filename Value="elf_sym.lpr"/>
<IsPartOfProject Value="True"/>
</Unit0>
<Unit1>
<Filename Value="uarch.pas"/>
<IsPartOfProject Value="True"/>
</Unit1>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<Target>
<Filename Value="elf_sym"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir)"/>
<OtherUnitFiles Value="..\.."/>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<CodeGeneration>
<SmartLinkUnit Value="True"/>
<RelocatableUnit Value="True"/>
<Optimizations>
<OptimizationLevel Value="3"/>
</Optimizations>
</CodeGeneration>
<Linking>
<Debugging>
<GenerateDebugInfo Value="False"/>
</Debugging>
<LinkSmart Value="True"/>
</Linking>
</CompilerOptions>
<Debugging>
<Exceptions Count="3">
<Item1>
<Name Value="EAbort"/>
</Item1>
<Item2>
<Name Value="ECodetoolError"/>
</Item2>
<Item3>
<Name Value="EFOpenError"/>
</Item3>
</Exceptions>
</Debugging>
</CONFIG>

494
tools/elf_sym/elf_sym.lpr Normal file
View File

@ -0,0 +1,494 @@
uses
{$IFDEF Linux}
cmem,
cthreads,
{$ENDIF}
Classes,sysutils,
gset,
sha1,
ps4_types,
uarch;
type
TRawStrCompare=class
class function c(var a,b:RawByteString):boolean; static;
end;
TRawStrSet=specialize TSet<RawByteString,TRawStrCompare>;
class function TRawStrCompare.c(var a,b:RawByteString):boolean;
var
count1,count2:SizeInt;
begin
Count1:=Length(a);
Count2:=Length(b);
Result:=(Count1<Count2) or (
(Count1=Count2) and (CompareMemRange(PChar(a),PChar(b),Count1)<0)
);
end;
function ps4_nid_hash(name:PChar):QWORD;
const
salt:array[0..15] of Byte=($51,$8D,$64,$A6,$35,$DE,$D8,$C1,$E6,$B0,$39,$B1,$C3,$E5,$52,$30);
var
Context:TSHA1Context;
Digest:TSHA1Digest;
begin
SHA1Init(Context);
SHA1Update(Context,name^,StrLen(name));
SHA1Update(Context,salt,Length(salt));
SHA1Final(Context,Digest);
Result:=PQWORD(@Digest)^;
end;
function DecodeValue64(strEnc:PAnsiChar;len:SizeUint;var nVal:QWORD):Boolean;
const
nEncLenMax=11;
var
i,nIndex:Integer;
begin
Result:=False;
nVal:=0;
if (len>nEncLenMax) or (len=0) then Exit;
For i:=0 to len-1 do
begin
case strEnc[i] of
'A'..'Z':nIndex:=Byte(strEnc[i])-Byte('A')+0;
'a'..'z':nIndex:=Byte(strEnc[i])-Byte('a')+26;
'0'..'9':nIndex:=Byte(strEnc[i])-Byte('0')+52;
'+':nIndex:=62;
'-':nIndex:=63;
else Exit;
end;
if (i<(nEncLenMax-1)) then
begin
nVal:=nVal shl 6;
nVal:=nVal or nIndex;
end else
begin
nVal:=nVal shl 4;
nVal:=nVal or (nIndex shr 2);
end;
end;
Result:=True;
end;
function EncodeValue64(nVal:QWORD):RawByteString;
const
nEncLenMax=11;
var
i,nIndex:Integer;
begin
SetLength(Result,nEncLenMax);
For i:=nEncLenMax downto 1 do
begin
if (i<>nEncLenMax) then
begin
nIndex:=nVal and 63;
nVal:=nVal shr 6;
end else
begin
nIndex:=(nVal and 15) shl 2;
nVal:=nVal shr 4;
end;
case nIndex of
0..25:Result[i]:=Char(nIndex+Byte('A')-0);
26..51:Result[i]:=Char(nIndex+Byte('a')-26);
52..61:Result[i]:=Char(nIndex+Byte('0')-52);
62:Result[i]:='+';
63:Result[i]:='-';
end;
end;
end;
type
TPcharCb=procedure(pName:Pchar;data:Pointer);
procedure _LoadSym(F:THandle;offset:Int64;cb:TPcharCb;data:Pointer);
Var
i:SizeInt;
elf_hdr:elf64_hdr;
elf_shdr:elf64_shdr;
symbol:elf64_sym;
pStrTab_pAddr:QWORD;
pStrTab_nSize:QWORD;
pSymTab_pAddr:QWORD;
pSymTab_nSize:QWORD;
pStrTable:PChar;
pName:PChar;
begin
FileSeek(F,offset,0);
FileRead(F,elf_hdr,SizeOf(elf_hdr));
if (PDWORD(@elf_hdr.e_ident)^<>ELFMAG) then Exit; //is elf
if (elf_hdr.e_phnum=0) then Exit;
pStrTab_pAddr:=0;
pStrTab_nSize:=0;
pSymTab_pAddr:=0;
pSymTab_nSize:=0;
FileSeek(F,offset+Int64(elf_hdr.e_shoff),0);
For i:=0 to elf_hdr.e_shnum-1 do
begin
FileRead(F,elf_shdr,SizeOf(elf64_shdr));
case elf_shdr.sh_type of
SHT_STRTAB:
begin
pStrTab_pAddr:=elf_shdr.sh_offset;
pStrTab_nSize:=elf_shdr.sh_size;
end;
SHT_SYMTAB:
begin
pSymTab_pAddr:=elf_shdr.sh_offset;
pSymTab_nSize:=elf_shdr.sh_size div SizeOf(Elf64_Sym);
Assert(SizeOf(elf64_sym)=elf_shdr.sh_entsize);
end;
end;
end;
if (pStrTab_pAddr=0) then Exit;
if (pStrTab_nSize=0) then Exit;
if (pSymTab_pAddr=0) then Exit;
if (pSymTab_nSize=0) then Exit;
pStrTable:=AllocMem(pStrTab_nSize);
FileSeek(F,offset+Int64(pStrTab_pAddr),0);
FileRead(F,pStrTable^,pStrTab_nSize);
FileSeek(F,offset+Int64(pSymTab_pAddr),0);
For i:=0 to pSymTab_nSize-1 do
begin
FileRead(F,symbol,SizeOf(elf64_sym));
if (symbol.st_size=0) then Continue;
case ELF64_ST_BIND(symbol.st_info) of
STB_GLOBAL,
STB_WEAK:;
else
Continue;
end;
case ELF64_ST_TYPE(symbol.st_info) of
STT_OBJECT,
STT_FUN,
STT_COMMON,
STT_TLS:;
else
Continue;
end;
if ELF64_ST_VISIBILITY(symbol.st_other)<>STV_DEFAULT then
begin
Continue;
end;
pName:=@pStrTable[symbol.st_name];
case PWORD(pName)^ of
$502F: // /P
begin
Case pName[2] of
'G':pName:=@pName[3];
'L':Continue;
else
pName:=@pName[2];
end;
end;
$472F: // /G
begin
Case pName[2] of
'/':Continue;
else
pName:=@pName[2];
end;
end;
$532F: // /S
begin
Continue;
end;
end;
{if Pos('/P',pName)<>0 then
begin
Writeln(ELF64_ST_BIND(symbol.st_info));
Writeln(ELF64_ST_TYPE(symbol.st_info));
Writeln(ELF64_ST_VISIBILITY(symbol.st_other));
h:=ps4_nid_hash(pName);
Writeln('h1:',HexStr(h,16));
sh:=EncodeValue64(h);
Writeln('sh:',sh);
h:=0;
DecodeValue64(PChar(sh),Length(sh),h);
Writeln('h2:',HexStr(h,16));
writeln;
end;}
cb(pName,data);
end;
FreeMem(pStrTable);
end;
function LoadSymFromFile(Const name:RawByteString;cb:TPcharCb;data:Pointer):Boolean;
Var
F:THandle;
elf_hdr:elf64_hdr;
arch_hdr:Tarch_header;
size,offset,fsize:Int64;
begin
Result:=False;
if (name='') or (cb=nil) then Exit;
F:=FileOpen(name,fmOpenRead or fmShareDenyNone);
if (F=feInvalidHandle) then
begin
Writeln('Error open file:',name);
Exit;
end;
FileRead(F,elf_hdr,SizeOf(elf_hdr));
if (PDWORD(@elf_hdr.e_ident)^=ELFMAG) then //is elf
begin
_LoadSym(F,0,cb,data);
end else
if (Parch_sig(@elf_hdr.e_ident)^=arch_sig) then //is arch
begin
size:=FileSeek(F,0,fsFromEnd);
offset:=FileSeek(F,SizeOf(Tarch_sig),0);
While (offset>0) and (offset<size) do
begin
FileRead(F,arch_hdr,SizeOf(Tarch_header));
offset:=FileSeek(F,0,fsFromCurrent);
fsize:=StrToInt64Def(Trim(arch_hdr.FileSize),0);
if (fsize<>0) then
begin
_LoadSym(F,offset,cb,data);
end;
offset:=offset+Align(fsize,2);
offset:=FileSeek(F,offset,0);
end;
end else
begin
FileClose(F);
Writeln(name,' is unknow file type!');
Exit;
end;
FileClose(F);
end;
{
procedure FWriteStr(pName:Pchar;data:Pointer);
var
S:RawByteString;
begin
S:=pName+#13#10;
FileWrite(THandle(data),PChar(S)^,Length(S));
end;
}
procedure FInsertStr(pName:Pchar;data:Pointer);
begin
TRawStrSet(data).Insert(pName);
end;
function SaveSym(iList:TStringList;Const ofname:RawByteString;exclude:TRawStrSet):Boolean;
Var
F:THandle;
FSet:TRawStrSet;
i,c:Integer;
it:TRawStrSet.TIterator;
S:RawByteString;
begin
Result:=False;
if (iList=nil) or (ofname='') then Exit;
FSet:=TRawStrSet.Create;
c:=iList.Count;
if (c<>0) then
For i:=0 to c-1 do
begin
LoadSymFromFile(iList.Strings[i],@FInsertStr,Pointer(FSet));
end;
F:=FileCreate(ofname);
if (F=feInvalidHandle) then
begin
Writeln('Error create file:',ofname);
FreeAndNil(FSet);
Exit;
end;
it:=FSet.Min;
if (it<>nil) then
begin
repeat
S:=it.Data;
if (exclude.NFind(S)=nil) then
begin
S:=S+#13#10;
FileWrite(F,PChar(S)^,Length(S));
end;
until not it.Next;
FreeAndNil(it);
end;
FileClose(F);
FreeAndNil(FSet);
end;
var
i,n:Integer;
iList:TStringList;
ofname:RawByteString='';
exclude:TRawStrSet;
label
promo;
procedure LoadFolder(iList:TStringList;const fname:RawByteString);
Var
Info:TSearchRec;
f,n:RawByteString;
begin
If FindFirst(fname,faAnyFile,Info)=0 then
begin
f:=IncludeTrailingPathDelimiter(ExtractFileDir(fname));
Repeat
If (Info.Attr and faDirectory)=0 then
begin
n:=ExcludeLeadingPathDelimiter(f+Info.Name);
iList.Add(n);
end;
Until FindNext(info)<>0;
FindClose(Info);
end;
end;
procedure LoadRecrusive(iList:TStringList;const fname:RawByteString);
Var
Info:TSearchRec;
f,n:RawByteString;
begin
LoadFolder(iList,fname);
f:=IncludeTrailingPathDelimiter(ExtractFileDir(fname));
if (ExcludeLeadingPathDelimiter(f)='') then
begin
f:=IncludeTrailingPathDelimiter(GetCurrentDir);
end;
n:=ExtractFileName(fname);
If FindFirst(f+'*',faDirectory,Info)=0 then
begin
Repeat
Case Info.Name of
'.','..':;
else
LoadRecrusive(iList,IncludeTrailingPathDelimiter(f+Info.Name)+n);
end;
Until FindNext(info)<>0;
FindClose(Info);
end;
end;
procedure LoadExclude(exclude:TRawStrSet;const fname:RawByteString);
var
L:TStringList;
i,c:Integer;
s:RawByteString;
begin
L:=TStringList.Create;
try
L.LoadFromFile(fname);
except
Writeln('Error open file:',fname);
FreeAndNil(L);
Exit;
end;
c:=L.Count;
if (c<>0) then
For i:=0 to c-1 do
begin
s:=Trim(L.Strings[i]);
if (s<>'') then
exclude.Insert(s);
end;
FreeAndNil(L);
end;
begin
DefaultSystemCodePage:=CP_UTF8;
DefaultUnicodeCodePage:=CP_UTF8;
DefaultFileSystemCodePage:=CP_UTF8;
DefaultRTLFileSystemCodePage:=CP_UTF8;
UTF8CompareLocale:=CP_UTF8;
iList:=TStringList.Create;
exclude:=TRawStrSet.Create;
if (ParamCount=0) then
begin
promo:
Writeln('Tool for extract strings from *.prx.sym files');
Writeln(' Parameters:');
Writeln(' -i <name> //file name to load');
Writeln(' -o <name> //file name to save');
Writeln(' -f <name> //folder and file mask to load');
Writeln(' -r <name> //folder and file mask to load (Recrusive)');
Writeln(' -e <name> //text file name to exclude values');
Exit;
end;
n:=-1;
For i:=1 to ParamCount do
begin
case LowerCase(ParamStr(i)) of
'-i':n:=0;
'-o':n:=1;
'-f':n:=2;
'-r':n:=3;
'-e':n:=4;
else
if (n<>-1) then
begin
Case n of
0:iList.Add(ParamStr(i));
1:ofname:=ParamStr(i);
2:LoadFolder(iList,ParamStr(i));
3:LoadRecrusive(iList,ParamStr(i));
4:LoadExclude(exclude,ParamStr(i));
end;
n:=-1;
end;
end;
end;
if (iList.Count=0) then goto promo;
if (ofname='') then
begin
if (iList.Count=1) then
begin
ofname:=ChangeFileExt(iList.Strings[0],'.txt');
end else
begin
ofname:='list.txt';
end;
end;
SaveSym(iList,ofname,exclude);
writeln;
end.

2
tools/elf_sym/run.cmd Normal file
View File

@ -0,0 +1,2 @@
elf_sym -r *.prx -r *.sym -r *.a -e known_names.txt
pause

31
tools/elf_sym/uarch.pas Normal file
View File

@ -0,0 +1,31 @@
unit uarch;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils;
type
Parch_sig=^Tarch_sig;
Tarch_sig=array[0..7] of AnsiChar;
Parch_header=^Tarch_header;
Tarch_header=packed record
FileName :array[0..15] of AnsiChar;
timestamp:array[0..11] of AnsiChar;
OwnerID :array[0..5] of AnsiChar;
GroupID :array[0..5] of AnsiChar;
FileMode :array[0..7] of AnsiChar;
FileSize :array[0..9] of AnsiChar;
Ending :array[0..1] of AnsiChar;
end;
const
arch_sig:Tarch_sig='!<arch>'#$0A;
implementation
end.

63
tools/gfx6_chip/chip.lpi Normal file
View File

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<General>
<Flags>
<SaveClosedFiles Value="False"/>
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
<MainUnitHasScaledStatement Value="False"/>
<SaveJumpHistory Value="False"/>
<SaveFoldState Value="False"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<MainUnit Value="0"/>
<Title Value="chip"/>
<UseAppBundle Value="False"/>
<ResourceType Value="res"/>
</General>
<BuildModes Count="1">
<Item1 Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
<UseFileFilters Value="True"/>
</PublishOptions>
<RunParams>
<FormatVersion Value="2"/>
<Modes Count="0"/>
</RunParams>
<Units Count="1">
<Unit0>
<Filename Value="chip.lpr"/>
<IsPartOfProject Value="True"/>
</Unit0>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<Target>
<Filename Value="chip"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir)"/>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
</CompilerOptions>
<Debugging>
<Exceptions Count="3">
<Item1>
<Name Value="EAbort"/>
</Item1>
<Item2>
<Name Value="ECodetoolError"/>
</Item2>
<Item3>
<Name Value="EFOpenError"/>
</Item3>
</Exceptions>
</Debugging>
</CONFIG>

643
tools/gfx6_chip/chip.lpr Normal file
View File

@ -0,0 +1,643 @@
uses
gset,
gmap,
Classes,SysUtils;
type
TRawStrCompare=class
class function c(var a,b:RawByteString):boolean; static;
end;
TMapStr=specialize TMap<RawByteString,RawByteString,TRawStrCompare>;
TSetStr=specialize TSet<RawByteString,TRawStrCompare>;
function ReCompareText(const S1,S2:RawByteString):sizeint;
var
i,count1,count2: sizeint;
Chr1, Chr2: byte;
P1, P2: PChar;
begin
Count1 := Length(S1);
Count2 := Length(S2);
if (Count1<>Count2) then Exit(Count1-Count2);
if (Count1>0) then
begin
i := 0;
P1 := @S1[1];
P2 := @S2[1];
while (i<Count1) do
begin
Chr1 := byte(p1[i]);
Chr2 := byte(p2[i]);
if (Chr1<>Chr2) then
begin
Exit(Chr1-Chr2);
end;
Inc(I);
end;
end;
end;
class function TRawStrCompare.c(var a,b:RawByteString):boolean;
begin
Result:=ReCompareText(a,b)<0;
end;
type
TChars=Set of AnsiChar;
function FetchAny(var Value:RawByteString;Delimiters,Quotations:TChars):RawByteString;
Var
i:SizeUInt;
Quote:AnsiChar;
State:Byte;
begin
Result:='';
Quote:=#0;
State:=0;
if Length(Value)>0 then
begin
For i:=1 to Length(Value) do
begin
case State of
0:begin
if (Value[i] in Quotations) then
begin
State:=2;
Quote:=Value[i];
end else
if (Value[i] in Delimiters) then
begin
end else
begin
Result:=Result+Value[i];
State:=1;
end;
end;
1:begin
if (Value[i] in Quotations) then
begin
State:=2;
Quote:=Value[i];
end else
if (Value[i] in Delimiters) then
begin
System.Delete(Value,1,i);
Exit;
end else
begin
Result:=Result+Value[i];
end;
end;
2:begin
if Value[i]=Quote then
begin
State:=3;
end else
begin
Result:=Result+Value[i];
end;
end;
3:begin
if Value[i]=Quote then
begin
State:=2;
Result:=Result+Quote;
end else
if (Value[i] in Delimiters) then
begin
System.Delete(Value,1,i);
Exit;
end else
begin
State:=1;
Quote:=#0;
Result:=Result+Value[i];
end;
end;
end;
end;
Value:='';
end;
end;
Procedure CutEnd(var Value:RawByteString;const S:RawByteString);
begin
if Copy(Value,Length(Value)-Length(S)+1,Length(S))=S then
begin
Delete(Value,Length(Value)-Length(S)+1,Length(S));
end;
end;
function BeginIs(const Value,S:RawByteString):Boolean;
begin
Result:=Copy(Value,1,Length(S))=S;
end;
function EndIs(const Value,S:RawByteString):Boolean;
begin
Result:=Copy(Value,Length(Value)-Length(S)+1,Length(S))=S;
end;
Var
RMNV_offsets:TMapStr;
RMVN_offsets:TMapStr;
RMNV_default:TMapStr;
RMVN_default:TMapStr;
Excl_default:TSetStr;
Procedure load_offsets(const fname:RawByteString);
var
L:TStringList;
i:Integer;
S,Name,Value:RawByteString;
maxlen:Integer;
It:TMapStr.TIterator;
F:THandle;
begin
RMNV_offsets:=TMapStr.Create;
RMVN_offsets:=TMapStr.Create;
maxlen:=0;
L:=TStringList.Create;
L.LoadFromFile(fname);
For i:=0 to L.Count -1 do
begin
S:=L.Strings[i];
Case FetchAny(S,[' ',#9],[]) of
'constexpr':
begin
if (FetchAny(S,[' ',#9],[])='unsigned') then
if (FetchAny(S,[' ',#9],[])='int') then
begin
Name:=FetchAny(S,[' ',#9],[]);
if (not EndIs(Name,'__SI')) and
(not EndIs(Name,'__SI__CI')) and
(not BeginIs(Name,'mmDBG')) and
(
BeginIs(Name,'mmCB') or
BeginIs(Name,'mmDB') or
BeginIs(Name,'mmGB') or
BeginIs(Name,'mmGRBM') or
BeginIs(Name,'mmPA') or
BeginIs(Name,'mmSPI') or
//BeginIs(Name,'mmSX') or
//BeginIs(Name,'mmSQ') or
//BeginIs(Name,'mmTA') or
BeginIs(Name,'mmVGT') or
BeginIs(Name,'mmIA') or
BeginIs(Name,'mmCOMPUTE')) then
if (FetchAny(S,[' ',#9],[])='=') then
begin
CutEnd(Name,'__CI__VI');
CutEnd(Name,'__VI');
Value:=FetchAny(S,[' ',#9,';'],[]);
if BeginIs(Value,'0x') then
begin
System.Delete(Value,1,2);
Value:='$'+Value;
end;
it:=RMNV_offsets.Find(Name);
if Assigned(It) then
begin
if (It.Value<>Value) then
Writeln('Double:',Name,'=',Value,'<>',It.Value);
FreeAndNil(It);
end else
if StrToIntDef(Value,0)<=$FFFF then
begin
it:=RMVN_offsets.Find(Value);
if Assigned(It) then
begin
if (It.Value<>Name) then
Writeln('Double:',Name,'=',Value,'<>',It.Value);
FreeAndNil(It);
end;
if Length(Name)>maxlen then maxlen:=Length(Name);
RMNV_offsets.Insert(Name,Value);
RMVN_offsets.Insert(Value,Name);
end;
end;
end;
end;
end;
end;
L.Free;
F:=FileCreate(ChangeFileExt(fname,'.pas'));
S:='unit '+ChangeFileExt(ExtractFileName(fname),'')+';'#13#10#13#10+
'interface'#13#10#13#10+
'{$mode objfpc}{$H+}'#13#10#13#10+
'const'#13#10;
FileWrite(F,Pchar(S)^,Length(S));
It:=RMVN_offsets.Min;
if Assigned(It) then
begin
repeat
S:=' '+It.Value+Space(maxlen-Length(It.Value))+'='+It.Key+';'#13#10;
FileWrite(F,Pchar(S)^,Length(S));
until not It.Next;
FreeAndNil(It);
end;
S:=#13#10'function getRegName(i:Word):RawByteString;'#13#10#13#10+
'implementation'#13#10#13#10+
'function getRegName(i:Word):RawByteString;'#13#10+
'begin'#13#10+
' case i of'#13#10;
FileWrite(F,Pchar(S)^,Length(S));
It:=RMVN_offsets.Min;
if Assigned(It) then
begin
repeat
S:=' '+It.Value+Space(maxlen-Length(It.Value))+':Result:='#$27+It.Value+#$27';'#13#10;
FileWrite(F,Pchar(S)^,Length(S));
until not It.Next;
FreeAndNil(It);
end;
S:=' else'#13#10+
' Result:=HexStr(i,4);'#13#10+
' end;'#13#10+
'end;'#13#10+
#13#10'end.'#13#10#13#10;
FileWrite(F,Pchar(S)^,Length(S));
FileClose(F);
end;
//
type
TUnionList=class(TStringList)
public
name:RawByteString;
end;
TStructList=TUnionList;
TMapUnionList=specialize TMap<RawByteString,TUnionList,TRawStrCompare>;
var
UnionList:TMapUnionList;
Procedure load_registers(const fname:RawByteString);
var
L:TStringList;
maxlen:Integer;
i,w:Integer;
S:RawByteString;
It:TMapUnionList.TIterator;
F:THandle;
is_union,is_struct:Boolean;
reserved:Integer;
union_field:TUnionList;
struct_field:TStructList;
name,value:RawByteString;
begin
UnionList:=TMapUnionList.Create;
is_union:=false;
is_struct:=false;
L:=TStringList.Create;
L.LoadFromFile(fname);
For i:=0 to L.Count -1 do
begin
S:=L.Strings[i];
Case FetchAny(S,[' ',#9],[]) of
'union':
begin
name:=FetchAny(S,[' ',#9],[]);
if (not EndIs(Name,'__SI')) and
(not EndIs(Name,'__CI')) and
(not EndIs(Name,'__SI__CI')) and
(not BeginIs(Name,'mmDBG')) and
(
BeginIs(Name,'CB') or
BeginIs(Name,'DB') or
BeginIs(Name,'GB') or
BeginIs(Name,'GRBM') or
BeginIs(Name,'PA') or
BeginIs(Name,'SPI') or
//BeginIs(Name,'SX') or
//BeginIs(Name,'SQ') or
//BeginIs(Name,'TA') or
BeginIs(Name,'VGT') or
BeginIs(Name,'IA') or
BeginIs(Name,'COMPUTE')) then
begin
CutEnd(Name,'__CI__VI');
CutEnd(Name,'__VI');
is_union:=True;
is_struct:=false;
reserved:=0;
union_field:=TUnionList.Create;
union_field.name:=name;
end;
end;
'};':
if is_union then
begin
is_union:=false;
is_struct:=false;
It:=UnionList.Find(union_field.name);
If Assigned(It) then
begin
Writeln('Double:',union_field.name);
FreeAndNil(It);
end else
begin
UnionList.Insert(union_field.name,union_field);
end;
union_field:=nil;
end;
'struct':
if is_union then
begin
is_struct:=True;
struct_field:=TStructList.Create;
struct_field.NameValueSeparator:=':';
end;
'}':
if is_struct then
begin
is_struct:=False;
Name:=FetchAny(S,[' ',#9,',',';'],[]);
CutEnd(Name,'__CI__VI');
CutEnd(Name,'__VI');
CutEnd(Name,'__SI');
struct_field.name:=Name;
union_field.AddObject(struct_field.name,struct_field);
struct_field:=nil;
end;
'unsigned':
if is_struct then
if (FetchAny(S,[' ',#9],[])='int') then
begin
name:=FetchAny(S,[' ',#9],[]);
if (name=':') then
begin
repeat
name:='RESERVED'+IntToStr(reserved);
Inc(reserved);
until (struct_field.IndexOfName(name)=-1);
end else
if FetchAny(S,[' ',#9],[])<>':' then
begin
Writeln('wtf?:',i);
end;
CutEnd(Name,'__CI__VI');
CutEnd(Name,'__VI');
CutEnd(Name,'__SI');
Case name of
'OVERRIDE',
'TYPE':name:='_'+name;
end;
value:=FetchAny(S,[' ',#9,';'],[]);
struct_field.Add(name+':bit'+value);
end;
end;
end;
L.Free;
F:=FileCreate(ChangeFileExt(fname,'.pas'));
S:='unit '+ChangeFileExt(ExtractFileName(fname),'')+';'#13#10#13#10+
'{$mode objfpc}{$H+}'#13#10#13#10+
'interface'#13#10#13#10+
'uses'#13#10+
' bittype;'#13#10#13#10+
'type'#13#10;
FileWrite(F,Pchar(S)^,Length(S));
It:=UnionList.Min;
if Assigned(It) then
begin
repeat
union_field:=It.Value;
if (union_field.Count=1) then
begin
struct_field:=TStructList(union_field.Objects[0]);
if (struct_field.Count=1) then
begin
struct_field.GetNameValue(0,String(name),String(Value));
S:=' T'+union_field.name+'='+Value+';'+#13#10#13#10;
FileWrite(F,Pchar(S)^,Length(S));
end else
begin
S:=' T'+union_field.name+'=bitpacked record'#13#10;
FileWrite(F,Pchar(S)^,Length(S));
maxlen:=0;
For i:=0 to struct_field.Count-1 do
begin
name:=struct_field.Names[i];
if Length(name)>maxlen then maxlen:=Length(name);
end;
For i:=0 to struct_field.Count-1 do
begin
struct_field.GetNameValue(i,String(name),String(Value));
S:=' '+name+Space(maxlen-Length(name))+':'+Value+';'#13#10;
FileWrite(F,Pchar(S)^,Length(S));
end;
S:=' end;'#13#10#13#10;
FileWrite(F,Pchar(S)^,Length(S));
end;
end else
begin
S:=' T'+union_field.name+'=packed record'#13#10+
' Case Byte of'#13#10;
FileWrite(F,Pchar(S)^,Length(S));
For w:=0 to union_field.Count-1 do
begin
S:=' '+IntToStr(w)+':('#13#10;
FileWrite(F,Pchar(S)^,Length(S));
struct_field:=TStructList(union_field.Objects[w]);
if (struct_field.Count=1) then
begin
struct_field.GetNameValue(0,String(name),String(Value));
S:=' '+struct_field.name+':'+Value+');'+#13#10;
FileWrite(F,Pchar(S)^,Length(S));
end else
begin
S:=' '+struct_field.name+':bitpacked record'#13#10;
FileWrite(F,Pchar(S)^,Length(S));
maxlen:=0;
For i:=0 to struct_field.Count-1 do
begin
name:=struct_field.Names[i];
if Length(name)>maxlen then maxlen:=Length(name);
end;
For i:=0 to struct_field.Count-1 do
begin
struct_field.GetNameValue(i,String(name),String(Value));
S:=' '+name+Space(maxlen-Length(name))+':'+Value+';'#13#10;
FileWrite(F,Pchar(S)^,Length(S));
end;
S:=' end);'#13#10;
FileWrite(F,Pchar(S)^,Length(S));
end;
end;
S:=' end;'#13#10#13#10;
FileWrite(F,Pchar(S)^,Length(S));
end;
until not It.Next;
FreeAndNil(It);
end;
S:=#13#10'implementation'#13#10#13#10+
'end.'#13#10#13#10;
FileWrite(F,Pchar(S)^,Length(S));
FileClose(F);
end;
type
TEnum=TUnionList;
var
Enum_Set:TSetStr;
EnumList:TStringList;
Procedure load_enum(const fname:RawByteString);
var
L:TStringList;
maxlen:Integer;
i,e:Integer;
S,name,value:RawByteString;
Enum:TEnum;
is_enum:Boolean;
F:THandle;
begin
Enum_Set:=TSetStr.Create;
EnumList:=TStringList.Create;
is_enum:=False;
maxlen:=0;
L:=TStringList.Create;
L.LoadFromFile(fname);
For i:=0 to L.Count-1 do
begin
S:=L.Strings[i];
name:=FetchAny(S,[' ',#9],[]);
Case name of
'typedef':
begin
if FetchAny(S,[' ',#9],[])='enum' then
begin
name:=FetchAny(S,[' ',#9,'{'],[]);
is_enum:=True;
Enum:=TEnum.Create;
Enum.name:=name;
Enum.NameValueSeparator:='=';
end;
end;
'}':
if is_enum then
begin
EnumList.AddObject(Enum.name,Enum);
Enum:=nil;
is_enum:=False;
end;
else
if is_enum then
begin
if (not EndIs(Name,'__SI')) and
(not EndIs(Name,'__CI')) and
(not EndIs(Name,'__SI__CI')) then
if FetchAny(S,[' ',#9],[])='=' then
begin
CutEnd(Name,'__CI__VI');
CutEnd(Name,'__VI');
CutEnd(Name,'__SI');
value:=FetchAny(S,[' ',#9,','],[]);
if BeginIs(Value,'0x') then
begin
System.Delete(Value,1,2);
Value:='$'+Value;
end;
if Enum_Set.NFind(Name)=nil then
begin
if Length(name)>maxlen then maxlen:=Length(name);
Enum_Set.Insert(Name);
Enum.Add(Name+'='+value);
end else
begin
Writeln('Double enum:',Name);
end;
end;
end;
end;
end;
L.Free;
F:=FileCreate(ChangeFileExt(fname,'.pas'));
S:='unit '+ChangeFileExt(ExtractFileName(fname),'')+';'#13#10#13#10+
'{$mode objfpc}{$H+}'#13#10#13#10+
'interface'#13#10#13#10+
'Const'#13#10;
FileWrite(F,Pchar(S)^,Length(S));
For i:=0 to EnumList.Count-1 do
begin
Enum:=TEnum(EnumList.Objects[i]);
S:=' // '+Enum.name+#13#10;
FileWrite(F,Pchar(S)^,Length(S));
For e:=0 to Enum.Count-1 do
begin
Enum.GetNameValue(e,String(name),String(Value));
S:=' '+name+Space(maxlen-Length(name))+'='+Value+';'#13#10;
FileWrite(F,Pchar(S)^,Length(S));
end;
end;
S:=#13#10'implementation'#13#10#13#10+
'end.'#13#10#13#10;
FileWrite(F,Pchar(S)^,Length(S));
FileClose(F);
end;
begin
load_offsets('si_ci_vi_merged_offset.h');
load_registers('si_ci_vi_merged_registers.h');
load_enum('si_ci_vi_merged_enum.h');
readln;
end.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,117 @@
/*
***********************************************************************************************************************
*
* Copyright (c) 2015-2021 Advanced Micro Devices, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
**********************************************************************************************************************/
#ifndef PM4_IT_OPCODES_H
#define PM4_IT_OPCODES_H
enum IT_OpCodeType {
IT_NOP = 0x10,
IT_SET_BASE = 0x11,
IT_CLEAR_STATE = 0x12,
IT_INDEX_BUFFER_SIZE = 0x13,
IT_DISPATCH_DIRECT = 0x15,
IT_DISPATCH_INDIRECT = 0x16,
IT_ATOMIC_GDS = 0x1D,
IT_ATOMIC = 0x1E,
IT_OCCLUSION_QUERY = 0x1F,
IT_SET_PREDICATION = 0x20,
IT_REG_RMW = 0x21,
IT_COND_EXEC = 0x22,
IT_PRED_EXEC = 0x23,
IT_DRAW_INDIRECT = 0x24,
IT_DRAW_INDEX_INDIRECT = 0x25,
IT_INDEX_BASE = 0x26,
IT_DRAW_INDEX_2 = 0x27,
IT_CONTEXT_CONTROL = 0x28,
IT_INDEX_TYPE = 0x2A,
IT_DRAW_INDIRECT_MULTI = 0x2C,
IT_DRAW_INDEX_AUTO = 0x2D,
IT_NUM_INSTANCES = 0x2F,
IT_DRAW_INDEX_MULTI_AUTO = 0x30,
IT_INDIRECT_BUFFER_CNST = 0x33,
IT_STRMOUT_BUFFER_UPDATE = 0x34,
IT_DRAW_INDEX_OFFSET_2 = 0x35,
IT_WRITE_DATA = 0x37,
IT_DRAW_INDEX_INDIRECT_MULTI = 0x38,
IT_MEM_SEMAPHORE = 0x39,
IT_COPY_DW__SI__CI = 0x3B,
IT_WAIT_REG_MEM = 0x3C,
IT_INDIRECT_BUFFER = 0x3F,
IT_COND_INDIRECT_BUFFER = 0x3F,
IT_COPY_DATA = 0x40,
IT_CP_DMA = 0x41,
IT_PFP_SYNC_ME = 0x42,
IT_SURFACE_SYNC = 0x43,
IT_COND_WRITE = 0x45,
IT_EVENT_WRITE = 0x46,
IT_EVENT_WRITE_EOP = 0x47,
IT_EVENT_WRITE_EOS = 0x48,
IT_PREAMBLE_CNTL = 0x4A,
IT_CONTEXT_REG_RMW = 0x51,
IT_LOAD_SH_REG = 0x5F,
IT_LOAD_CONFIG_REG = 0x60,
IT_LOAD_CONTEXT_REG = 0x61,
IT_SET_CONFIG_REG = 0x68,
IT_SET_CONTEXT_REG = 0x69,
IT_SET_CONTEXT_REG_INDIRECT = 0x73,
IT_SET_SH_REG = 0x76,
IT_SET_SH_REG_OFFSET = 0x77,
IT_SCRATCH_RAM_WRITE = 0x7D,
IT_SCRATCH_RAM_READ = 0x7E,
IT_LOAD_CONST_RAM = 0x80,
IT_WRITE_CONST_RAM = 0x81,
IT_DUMP_CONST_RAM = 0x83,
IT_INCREMENT_CE_COUNTER = 0x84,
IT_INCREMENT_DE_COUNTER = 0x85,
IT_WAIT_ON_CE_COUNTER = 0x86,
IT_WAIT_ON_DE_COUNTER__SI = 0x87,
IT_WAIT_ON_DE_COUNTER_DIFF = 0x88,
IT_SWITCH_BUFFER = 0x8B,
IT_DRAW_PREAMBLE__CI__VI = 0x36,
IT_RELEASE_MEM__CI__VI = 0x49,
IT_DMA_DATA__CI__VI = 0x50,
IT_ACQUIRE_MEM__CI__VI = 0x58,
IT_REWIND__CI__VI = 0x59,
IT_LOAD_UCONFIG_REG__CI__VI = 0x5E,
IT_SET_QUEUE_REG__CI__VI = 0x78,
IT_SET_UCONFIG_REG__CI__VI = 0x79,
IT_INDEX_ATTRIBUTES_INDIRECT__CI__VI = 0x91,
IT_SET_SH_REG_INDEX__CI__VI = 0x9B,
IT_SET_RESOURCES__CI__VI = 0xA0,
IT_MAP_PROCESS__CI__VI = 0xA1,
IT_MAP_QUEUES__CI__VI = 0xA2,
IT_UNMAP_QUEUES__CI__VI = 0xA3,
IT_QUERY_STATUS__CI__VI = 0xA4,
IT_RUN_LIST__CI__VI = 0xA5,
IT_LOAD_SH_REG_INDEX__VI = 0x63,
IT_LOAD_CONTEXT_REG_INDEX__VI = 0x9F,
IT_DUMP_CONST_RAM_OFFSET__VI = 0x9E,
};
#define PM4_TYPE_0 0
#define PM4_TYPE_2 2
#define PM4_TYPE_3 3
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<General>
<Flags>
<SaveClosedFiles Value="False"/>
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
<MainUnitHasScaledStatement Value="False"/>
<SaveJumpHistory Value="False"/>
<SaveFoldState Value="False"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<MainUnit Value="0"/>
<Title Value="funct_helper2"/>
<UseAppBundle Value="False"/>
<ResourceType Value="res"/>
</General>
<BuildModes Count="1">
<Item1 Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
<UseFileFilters Value="True"/>
</PublishOptions>
<RunParams>
<FormatVersion Value="2"/>
<Modes Count="0"/>
</RunParams>
<Units Count="1">
<Unit0>
<Filename Value="funct_helper2.lpr"/>
<IsPartOfProject Value="True"/>
</Unit0>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<Target>
<Filename Value="funct_helper2"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir)"/>
<OtherUnitFiles Value="xpath"/>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<CodeGeneration>
<SmartLinkUnit Value="True"/>
<RelocatableUnit Value="True"/>
<Optimizations>
<OptimizationLevel Value="3"/>
</Optimizations>
</CodeGeneration>
<Linking>
<LinkSmart Value="True"/>
</Linking>
</CompilerOptions>
<Debugging>
<Exceptions Count="3">
<Item1>
<Name Value="EAbort"/>
</Item1>
<Item2>
<Name Value="ECodetoolError"/>
</Item2>
<Item3>
<Name Value="EFOpenError"/>
</Item3>
</Exceptions>
</Debugging>
</CONFIG>

View File

@ -0,0 +1,241 @@
{$mode objfpc}{$H+}
Uses
classes,
Sysutils,
sha1,
gmap;
type
TQWORDCompare=class
class function c(var a,b:QWORD):boolean; static;
end;
TMapSym=specialize TMap<QWORD,RawByteString,TQWORDCompare>;
class function TQWORDCompare.c(var a,b:QWORD):boolean;
begin
Result:=a<b;
end;
function ps4_nid_hash(name:PChar):QWORD;
const
salt:array[0..15] of Byte=($51,$8D,$64,$A6,$35,$DE,$D8,$C1,$E6,$B0,$39,$B1,$C3,$E5,$52,$30);
var
Context:TSHA1Context;
Digest:TSHA1Digest;
begin
SHA1Init(Context);
SHA1Update(Context,name^,StrLen(name));
SHA1Update(Context,salt,Length(salt));
SHA1Final(Context,Digest);
Result:=PQWORD(@Digest)^;
end;
function DecodeValue64(strEnc:PAnsiChar;len:SizeUint;var nVal:QWORD):Boolean;
const
nEncLenMax=11;
var
i,nIndex:Integer;
begin
Result:=False;
nVal:=0;
if (len>nEncLenMax) or (len=0) then Exit;
For i:=0 to len-1 do
begin
case strEnc[i] of
'A'..'Z':nIndex:=Byte(strEnc[i])-Byte('A')+0;
'a'..'z':nIndex:=Byte(strEnc[i])-Byte('a')+26;
'0'..'9':nIndex:=Byte(strEnc[i])-Byte('0')+52;
'+':nIndex:=62;
'-':nIndex:=63;
else Exit;
end;
if (i<(nEncLenMax-1)) then
begin
nVal:=nVal shl 6;
nVal:=nVal or nIndex;
end else
begin
nVal:=nVal shl 4;
nVal:=nVal or (nIndex shr 2);
end;
end;
Result:=True;
end;
procedure loadInlFile(MapSym:TMapSym;Const fname:RawByteString);
Var
List:TStringList;
i,p:SizeInt;
S,name,sid:RawByteString;
nid:QWORD;
begin
nid:=0;
List:=TStringList.Create;
List.LoadFromFile(fname);
For i:=0 to List.Count-1 do
begin
S:=List.Strings[i];
p:=Pos('(',S);
if (p<>0) then S:=copy(s,p+1,Length(s)-p);
if (s[Length(s)]=')') then SetLength(s,Length(s)-1);
p:=Pos(',',S);
if (p<>0) then
begin
name:=copy(s,1,p-1);
sid:=copy(s,p+1,Length(s)-p);
if (sid[Length(sid)]='"') then SetLength(sid,Length(sid)-1);
if (sid[1]='"') then sid:=copy(sid,2,Length(sid)-1);
if not DecodeValue64(PChar(sid),Length(sid),nid) then
begin
Writeln('Error decode with:',sid);
Continue;
end;
if (name<>'') then
begin
if ps4_nid_hash(pchar(name))<>nid then
begin
Writeln('Error: nid hash check:',nid,'<>',ps4_nid_hash(pchar(name)));
end;
if MapSym.TryGetValue(nid,s) and (s<>name) then
begin
Writeln('Error: nid hash collision:',nid,':',s,'<>',name);
end else
MapSym.Insert(nid,name);
end;
end;
end;
FreeAndNil(List);
end;
procedure loadTxtFile(MapSym:TMapSym;Const fname:RawByteString);
Var
List:TStringList;
i:SizeInt;
name,s:RawByteString;
nid:QWORD;
begin
nid:=0;
List:=TStringList.Create;
List.LoadFromFile(fname);
For i:=0 to List.Count-1 do
begin
name:=Trim(List.Strings[i]);
if (name<>'') then
begin
nid:=ps4_nid_hash(pchar(name));
if MapSym.TryGetValue(nid,s) and (s<>name) then
begin
Writeln('Error: nid hash collision:',nid,':',s,'<>',name);
end else
MapSym.Insert(nid,name);
end;
end;
FreeAndNil(List);
end;
Var
MapSym:TMapSym;
Const
prolog1='unit ps4libdoc;'#$0D#$0A#$0D#$0A+
'{$mode objfpc}{$H+}'#$0D#$0A#$0D#$0A+
'{$WARNINGS OFF}'#$0D#$0A#$0D#$0A+
'interface'#$0D#$0A#$0D#$0A+
'Function GetFunctName(N:QWORD):PChar;'#$0D#$0A#$0D#$0A+
'implementation'#$0D#$0A#$0D#$0A+
'type'#$0D#$0A+
' TFunctData=packed record'#$0D#$0A+
' i:QWORD;'#$0D#$0A+
' n:PChar;'#$0D#$0A+
' end;'#$0D#$0A#$0D#$0A+
'var'#$0D#$0A+
' FunctData:array[0..';
prolog2='] of TFunctData=('#$0D#$0A;
ep_func=' );'#$0D#$0A#$0D#$0A+
'Function GetFunctName(N:QWORD):PChar;'#$0D#$0A+
'Var'#$0D#$0A+
' l,r,m:SizeInt;'#$0D#$0A+
'begin'#$0D#$0A+
' Result:='#$27'Unknow'#$27';'#$0D#$0A+
' l:=0;'#$0D#$0A+
' r:=Length(FunctData);'#$0D#$0A+
' while (l<r) do'#$0D#$0A+
' begin'#$0D#$0A+
' m:=l+(r-l) div 2;'#$0D#$0A+
' if (FunctData[m].i=N) then Exit(FunctData[m].n);'#$0D#$0A+
' if (FunctData[m].i>N) then'#$0D#$0A+
' begin'#$0D#$0A+
' r:=m;'#$0D#$0A+
' end else'#$0D#$0A+
' begin'#$0D#$0A+
' l:=m+1;'#$0D#$0A+
' end;'#$0D#$0A+
' end;'#$0D#$0A+
'end;'#$0D#$0A#$0D#$0A+
'end.'#$0D#$0A;
Procedure SaveToPas(Const FName:RawByteString);
Var
F:Thandle;
SymIter:TMapSym.TIterator;
i,_id:QWORD;
_name:RawByteString;
begin
F:=FileCreate(FName);
FileWrite(F,PChar(prolog1)^,Length(prolog1));
_name:=IntToStr(MapSym.Size-1);
FileWrite(F,PChar(_name)^,Length(_name));
FileWrite(F,PChar(prolog2)^,Length(prolog2));
i:=0;
SymIter:=MapSym.Min;
if (SymIter<>nil) then
begin
repeat
Inc(i);
_id :=SymIter.Key;
_name:=SymIter.Value;
_name:=' (i:$'+HexStr(_id,16)+';n:'#$27+_name+#$27')';
if (i=MapSym.Size) then
_name:=_name+#$0D#$0A
else
_name:=_name+','#$0D#$0A;
FileWrite(F,PChar(_name)^,Length(_name));
until (not SymIter.Next);
FreeAndNil(SymIter);
end;
FileWrite(F,PChar(ep_func)^,Length(ep_func));
FileClose(F);
end;
begin
DefaultSystemCodePage:=CP_UTF8;
DefaultUnicodeCodePage:=CP_UTF8;
DefaultFileSystemCodePage:=CP_UTF8;
DefaultRTLFileSystemCodePage:=CP_UTF8;
UTF8CompareLocale:=CP_UTF8;
MapSym:=TMapSym.Create;
if FileExists('ps4libdoc.inl') then
loadInlFile(MapSym,'ps4libdoc.inl');
if FileExists('list.txt') then
loadTxtFile(MapSym,'list.txt');
Writeln('Load is Fin');
SaveToPas('ps4libdoc.pas');
Writeln('Save is Fin');
readln;
end.

33006
tools/ps4libdoc/ps4libdoc.inl Normal file

File diff suppressed because it is too large Load Diff