mirror of https://github.com/red-prig/fpPS4.git
tools added
This commit is contained in:
parent
1218138700
commit
d587f2dc78
|
@ -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>
|
|
@ -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.
|
||||
|
||||
|
||||
|
|
@ -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>
|
|
@ -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.
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
elf_sym -r *.prx -r *.sym -r *.a -e known_names.txt
|
||||
pause
|
|
@ -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.
|
||||
|
|
@ -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>
|
|
@ -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
|
@ -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
|
@ -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>
|
|
@ -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.
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue