[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:
nickysn 2020-08-03 12:59:01 +00:00
parent 357dfada91
commit a6eab10ee5
4 changed files with 166 additions and 6 deletions

View File

@ -87,7 +87,13 @@ type
entries : array of TCodeEntry;
end;
const
EXPDESC_FUNC = $00;
EXPDESC_TABLE = $01;
EXPDESC_MEM = $02;
EXPDESC_GLOBAL = $03;
type
TExportEntry = record
name : string;
desc : byte;
@ -123,6 +129,9 @@ procedure ReadExportEntry(src: TStream; var ex: TExportEntry);
procedure ReadExport(src: TStream; var ex: TExportSection);
procedure WriteExport(const ex: TExportSection; dst: TStream);
function isWasmStream(st: TStream): Boolean;
function isWasmFile(const fn: string): Boolean;
implementation
function ValTypeToStr(id: integer): string;
@ -246,5 +255,37 @@ begin
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.

View File

@ -47,7 +47,7 @@ type
version : UInt32; // the version of linking metadata contained in this section. Currently: 2
end;
TLinkinSubSection = record
TLinkingSubSection = record
sectype : UInt8; // code identifying type of subsection
length : UInt32; // size of this subsection in bytes
end;
@ -131,7 +131,7 @@ const
WASM_SYM_NO_STRIP = $80;
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;
procedure WriteSymInfo(st: TStream; const m: TSymInfo);
@ -143,6 +143,16 @@ procedure DumpLinking(st: TStream; secsize: integer);
function SubSecTypeToStr(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
function ReadMetaData(st: TStream; out m:TLinkingMetadata): Boolean;
@ -152,7 +162,7 @@ begin
Result:=true;
end;
function ReadLinkSubSect(st: TStream; out m: TLinkinSubSection): Boolean;
function ReadLinkSubSect(st: TStream; out m: TLinkingSubSection): Boolean;
begin
FillChar(m, sizeof(m), 0);
m.sectype := ReadU(st);
@ -213,7 +223,7 @@ procedure DumpLinking(st: TStream; secsize: integer);
var
mt : TLinkingMetadata;
en : Int64;
sub : TLinkinSubSection;
sub : TLinkingSubSection;
cnt : LongWord;
nx : Int64;
i : integer;
@ -268,5 +278,30 @@ begin
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.

View File

@ -56,7 +56,7 @@ procedure ProcessLinkingSection(st: TStream; syms: TStrings);
var
mt : TLinkingMetadata;
//en : Int64;
sub : TLinkinSubSection;
sub : TLinkingSubSection;
cnt : LongWord;
nx : Int64;
i : integer;

View File

@ -12,6 +12,7 @@ procedure ChangeSymbolFlag(const fn, symfn: string);
function ExportRenameSym(var x: TExportSection; syms: TStrings): Integer;
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);
implementation
@ -135,6 +136,85 @@ begin
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);
var
fs : TFileStream;
@ -149,7 +229,11 @@ begin
if (symfn <> '') and fileExists(symfn) then
begin
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);
end;