mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-19 13:09:17 +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;
|
||||
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.
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user