mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-22 14:49:10 +02:00
[PATCH 017/188] update name gathering from linking section
From cc238c5c8b3b91c2811b0fe49de827d7e6be7981 Mon Sep 17 00:00:00 2001 From: Dmitry Boyarintsev <skalogryz.lists@gmail.com> Date: Thu, 26 Sep 2019 12:37:23 -0400 git-svn-id: branches/wasm@46013 -
This commit is contained in:
parent
357dfada91
commit
a6eab10ee5
@ -87,7 +87,13 @@ type
|
|||||||
entries : array of TCodeEntry;
|
entries : array of TCodeEntry;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
const
|
||||||
|
EXPDESC_FUNC = $00;
|
||||||
|
EXPDESC_TABLE = $01;
|
||||||
|
EXPDESC_MEM = $02;
|
||||||
|
EXPDESC_GLOBAL = $03;
|
||||||
|
|
||||||
|
type
|
||||||
TExportEntry = record
|
TExportEntry = record
|
||||||
name : string;
|
name : string;
|
||||||
desc : byte;
|
desc : byte;
|
||||||
@ -123,6 +129,9 @@ procedure ReadExportEntry(src: TStream; var ex: TExportEntry);
|
|||||||
procedure ReadExport(src: TStream; var ex: TExportSection);
|
procedure ReadExport(src: TStream; var ex: TExportSection);
|
||||||
procedure WriteExport(const ex: TExportSection; dst: TStream);
|
procedure WriteExport(const ex: TExportSection; dst: TStream);
|
||||||
|
|
||||||
|
function isWasmStream(st: TStream): Boolean;
|
||||||
|
function isWasmFile(const fn: string): Boolean;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
function ValTypeToStr(id: integer): string;
|
function ValTypeToStr(id: integer): string;
|
||||||
@ -246,5 +255,37 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function isWasmStream(st: TStream): Boolean;
|
||||||
|
var
|
||||||
|
pos : Int64;
|
||||||
|
begin
|
||||||
|
try
|
||||||
|
pos:=st.Position;
|
||||||
|
try
|
||||||
|
Result := st.ReadDWord = WasmId_Int;
|
||||||
|
finally
|
||||||
|
st.Position:=pos;
|
||||||
|
end;
|
||||||
|
except
|
||||||
|
Result:=false;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function isWasmFile(const fn: string): Boolean;
|
||||||
|
var
|
||||||
|
fs: TFileStream;
|
||||||
|
begin
|
||||||
|
try
|
||||||
|
fs:=TFileStream.Create(fn, fmOpenRead or fmShareDenyNone);
|
||||||
|
try
|
||||||
|
Result:=isWasmStream(fs);
|
||||||
|
finally
|
||||||
|
fs.Free;
|
||||||
|
end;
|
||||||
|
except
|
||||||
|
Result := false;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ type
|
|||||||
version : UInt32; // the version of linking metadata contained in this section. Currently: 2
|
version : UInt32; // the version of linking metadata contained in this section. Currently: 2
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TLinkinSubSection = record
|
TLinkingSubSection = record
|
||||||
sectype : UInt8; // code identifying type of subsection
|
sectype : UInt8; // code identifying type of subsection
|
||||||
length : UInt32; // size of this subsection in bytes
|
length : UInt32; // size of this subsection in bytes
|
||||||
end;
|
end;
|
||||||
@ -131,7 +131,7 @@ const
|
|||||||
WASM_SYM_NO_STRIP = $80;
|
WASM_SYM_NO_STRIP = $80;
|
||||||
|
|
||||||
function ReadMetaData(st: TStream; out m:TLinkingMetadata): Boolean;
|
function ReadMetaData(st: TStream; out m:TLinkingMetadata): Boolean;
|
||||||
function ReadLinkSubSect(st: TStream; out m: TLinkinSubSection): Boolean;
|
function ReadLinkSubSect(st: TStream; out m: TLinkingSubSection): Boolean;
|
||||||
function ReadSymInfo(st: TStream; out m: TSymInfo): Boolean;
|
function ReadSymInfo(st: TStream; out m: TSymInfo): Boolean;
|
||||||
|
|
||||||
procedure WriteSymInfo(st: TStream; const m: TSymInfo);
|
procedure WriteSymInfo(st: TStream; const m: TSymInfo);
|
||||||
@ -143,6 +143,16 @@ procedure DumpLinking(st: TStream; secsize: integer);
|
|||||||
function SubSecTypeToStr(b: Byte): string;
|
function SubSecTypeToStr(b: Byte): string;
|
||||||
function SymKindToStr(b: Byte): string;
|
function SymKindToStr(b: Byte): string;
|
||||||
|
|
||||||
|
type
|
||||||
|
TLinkingSection = record
|
||||||
|
metadata: TLinkingMetadata;
|
||||||
|
symbols : array of TSymInfo;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// the stream should be set at the beggining of the section
|
||||||
|
// after name and size values
|
||||||
|
procedure ReadLinkingSection(st: TStream; size: integer; var sc: TLinkingSection);
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
function ReadMetaData(st: TStream; out m:TLinkingMetadata): Boolean;
|
function ReadMetaData(st: TStream; out m:TLinkingMetadata): Boolean;
|
||||||
@ -152,7 +162,7 @@ begin
|
|||||||
Result:=true;
|
Result:=true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function ReadLinkSubSect(st: TStream; out m: TLinkinSubSection): Boolean;
|
function ReadLinkSubSect(st: TStream; out m: TLinkingSubSection): Boolean;
|
||||||
begin
|
begin
|
||||||
FillChar(m, sizeof(m), 0);
|
FillChar(m, sizeof(m), 0);
|
||||||
m.sectype := ReadU(st);
|
m.sectype := ReadU(st);
|
||||||
@ -213,7 +223,7 @@ procedure DumpLinking(st: TStream; secsize: integer);
|
|||||||
var
|
var
|
||||||
mt : TLinkingMetadata;
|
mt : TLinkingMetadata;
|
||||||
en : Int64;
|
en : Int64;
|
||||||
sub : TLinkinSubSection;
|
sub : TLinkingSubSection;
|
||||||
cnt : LongWord;
|
cnt : LongWord;
|
||||||
nx : Int64;
|
nx : Int64;
|
||||||
i : integer;
|
i : integer;
|
||||||
@ -268,5 +278,30 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure ReadLinkingSection(st: TStream; size: integer; var sc: TLinkingSection);
|
||||||
|
var
|
||||||
|
eofs : int64;
|
||||||
|
sub : TLinkingSubSection;
|
||||||
|
cnt : integer;
|
||||||
|
i : integer;
|
||||||
|
nx : int64;
|
||||||
|
begin
|
||||||
|
eofs := st.Position+size;
|
||||||
|
ReadMetadata(st, sc.metadata);
|
||||||
|
while st.Position < eofs do begin
|
||||||
|
ReadLinkSubSect(st, sub);
|
||||||
|
nx := st.Position+sub.length;
|
||||||
|
case sub.sectype of
|
||||||
|
//todo: others!
|
||||||
|
WASM_SYMBOL_TABLE: begin
|
||||||
|
cnt := ReadU(st);
|
||||||
|
SetLength(sc.symbols, cnt);
|
||||||
|
for i:=0 to cnt-1 do
|
||||||
|
ReadSymInfo(st, sc.symbols[i]);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
st.Position:=nx;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
@ -56,7 +56,7 @@ procedure ProcessLinkingSection(st: TStream; syms: TStrings);
|
|||||||
var
|
var
|
||||||
mt : TLinkingMetadata;
|
mt : TLinkingMetadata;
|
||||||
//en : Int64;
|
//en : Int64;
|
||||||
sub : TLinkinSubSection;
|
sub : TLinkingSubSection;
|
||||||
cnt : LongWord;
|
cnt : LongWord;
|
||||||
nx : Int64;
|
nx : Int64;
|
||||||
i : integer;
|
i : integer;
|
||||||
|
@ -12,6 +12,7 @@ procedure ChangeSymbolFlag(const fn, symfn: string);
|
|||||||
|
|
||||||
function ExportRenameSym(var x: TExportSection; syms: TStrings): Integer;
|
function ExportRenameSym(var x: TExportSection; syms: TStrings): Integer;
|
||||||
function ExportRenameProcess(st, dst: TStream; syms: TStrings; doVerbose: Boolean): Boolean;
|
function ExportRenameProcess(st, dst: TStream; syms: TStrings; doVerbose: Boolean): Boolean;
|
||||||
|
function ExportNameGather(const wasmfile: string; syms: TStrings; doVerbose: Boolean = false): Boolean;
|
||||||
procedure ExportRename(const fn, symfn: string; doVerbose: Boolean);
|
procedure ExportRename(const fn, symfn: string; doVerbose: Boolean);
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
@ -135,6 +136,85 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
// match between exported function names and symbol names
|
||||||
|
procedure MatchExportNameToSymName(const x: TExportSection; const l: TLinkingSection; dst: TStrings);
|
||||||
|
var
|
||||||
|
expname : string;
|
||||||
|
i,j : integer;
|
||||||
|
begin
|
||||||
|
for i:=0 to length(x.entries)-1 do begin
|
||||||
|
// gathering only function names for now
|
||||||
|
if x.entries[i].desc <> EXPDESC_FUNC then continue;
|
||||||
|
expname := x.entries[i].name;
|
||||||
|
for j:=0 to length(l.symbols)-1 do begin
|
||||||
|
if (l.symbols[j].kind = SYMTAB_FUNCTION)
|
||||||
|
and (l.symbols[j].symindex = x.entries[i].index)
|
||||||
|
and (l.symbols[j].hasSymName)
|
||||||
|
then
|
||||||
|
dst.Values[ l.symbols[j].symname ] := expname;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
function ExportNameGather(const wasmfile: string; syms: TStrings; doVerbose: Boolean = false): Boolean;
|
||||||
|
var
|
||||||
|
dw : LongWord;
|
||||||
|
ofs : int64;
|
||||||
|
sc : TSection;
|
||||||
|
ps : int64;
|
||||||
|
mem : TMemoryStream;
|
||||||
|
cnt : integer;
|
||||||
|
st : TFileStream;
|
||||||
|
nm : string;
|
||||||
|
x : TExportSection;
|
||||||
|
foundExport: Boolean;
|
||||||
|
l : TLinkingSection;
|
||||||
|
foundLink: Boolean;
|
||||||
|
begin
|
||||||
|
st := TFileStream.Create(wasmfile, fmOpenRead or fmShareDenyNone);
|
||||||
|
try
|
||||||
|
dw := st.ReadDWord;
|
||||||
|
Result := dw = WasmId_Int;
|
||||||
|
if not Result then begin
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
dw := st.ReadDWord;
|
||||||
|
|
||||||
|
foundExport:=false;
|
||||||
|
foundLink:=false;
|
||||||
|
while st.Position<st.Size do begin
|
||||||
|
ofs := st.Position;
|
||||||
|
sc.id := st.ReadByte;
|
||||||
|
sc.Size := ReadU(st);
|
||||||
|
|
||||||
|
ps := st.Position+sc.size;
|
||||||
|
|
||||||
|
if sc.id = SECT_EXPORT then begin
|
||||||
|
if doVerbose then writeln(' export section found');
|
||||||
|
ReadExport(st, x);
|
||||||
|
cnt := ExportRenameSym(x, syms);
|
||||||
|
foundExport:=true;
|
||||||
|
end else if sc.id = SECT_CUSTOM then begin
|
||||||
|
nm := ReadName(st);
|
||||||
|
if nm = SectionName_Linking then begin
|
||||||
|
foundLink := true;
|
||||||
|
ReadLinkingSection(st, sc.size, l);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if st.Position <> ps then
|
||||||
|
st.Position := ps;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Result := foundLink and foundExport;
|
||||||
|
if Result then
|
||||||
|
MatchExportNameToSymName(x, l, syms);
|
||||||
|
finally
|
||||||
|
st.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure ExportRename(const fn, symfn: string; doVerbose: Boolean);
|
procedure ExportRename(const fn, symfn: string; doVerbose: Boolean);
|
||||||
var
|
var
|
||||||
fs : TFileStream;
|
fs : TFileStream;
|
||||||
@ -149,7 +229,11 @@ begin
|
|||||||
if (symfn <> '') and fileExists(symfn) then
|
if (symfn <> '') and fileExists(symfn) then
|
||||||
begin
|
begin
|
||||||
if doVerbose then writeln('reading symbols: ', symfn);
|
if doVerbose then writeln('reading symbols: ', symfn);
|
||||||
syms.LoadFromFile(symfn);
|
|
||||||
|
if isWasmFile(symfn) then
|
||||||
|
ExportNameGather(symfn, syms, doVerbose)
|
||||||
|
else
|
||||||
|
syms.LoadFromFile(symfn);
|
||||||
if doVerbose then write(syms.Text);
|
if doVerbose then write(syms.Text);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user