[PATCH 009/188] updating renaming export entries

From a15a2d961684c96837cc57b09193fdb499ae4fa8 Mon Sep 17 00:00:00 2001
From: Dmitry Boyarintsev <skalogryz.lists@gmail.com>
Date: Thu, 26 Sep 2019 01:34:58 -0400

git-svn-id: branches/wasm@46005 -
This commit is contained in:
nickysn 2020-08-03 12:58:52 +00:00
parent 50df4ac869
commit 18910afe47
4 changed files with 250 additions and 25 deletions

View File

@ -28,18 +28,18 @@ const
WasmId_Int = $6D736100; WasmId_Int = $6D736100;
const const
sect_custom = 0; // custom section SECT_CUSTOM = 0; // custom section
sect_type = 1; // type section SECT_TYPE = 1; // type section
sect_import = 2; // import section SECT_IMPORT = 2; // import section
sect_function = 3; // function section SECT_FUNCTION = 3; // function section
sect_table = 4; // table section SECT_TABLE = 4; // table section
sect_memory = 5; // memory section SECT_MEMORY = 5; // memory section
sect_global = 6; // global section SECT_GLOBAL = 6; // global section
sect_export = 7; // export section SECT_EXPORT = 7; // export section
sect_start = 8; // start section SECT_START = 8; // start section
sect_element = 9; // element section SECT_ELEMENT = 9; // element section
sect_code = 10; // code section SECT_CODE = 10; // code section
sect_data = 11; // data section SECT_DATA = 11; // data section
type type
TSection = packed record TSection = packed record
@ -87,6 +87,17 @@ type
entries : array of TCodeEntry; entries : array of TCodeEntry;
end; end;
TExportEntry = record
name : string;
desc : byte;
index : UInt32;
end;
TExportSection = record
entries : array of TExportEntry;
end;
function SectionIdToStr(id: integer): string; function SectionIdToStr(id: integer): string;
function ValTypeToStr(id: integer): string; function ValTypeToStr(id: integer): string;
@ -106,6 +117,12 @@ procedure ReadCodeEntry(src: TStream; var en: TCodeEntry);
// reads the code entry into TCodeEntry structure // reads the code entry into TCodeEntry structure
procedure ReadCodeSection(src: TStream; var sc: TCodeSection); procedure ReadCodeSection(src: TStream; var sc: TCodeSection);
procedure ReadExportEntry(src: TStream; var ex: TExportEntry);
// reads the export entry
procedure ReadExport(src: TStream; var ex: TExportSection);
procedure WriteExport(const ex: TExportSection; dst: TStream);
implementation implementation
function ValTypeToStr(id: integer): string; function ValTypeToStr(id: integer): string;
@ -199,5 +216,35 @@ begin
ReadCodeEntry(src, sc.entries[i]); ReadCodeEntry(src, sc.entries[i]);
end; end;
procedure ReadExportEntry(src: TStream; var ex: TExportEntry);
begin
ex.name := ReadName(src);
ex.desc := src.ReadByte;
ex.index := ReadU(src);
end;
procedure ReadExport(src: TStream; var ex: TExportSection);
var
cnt : integer;
i : integer;
begin
cnt := ReadU(src);
SetLength(ex.entries, cnt);
for i:=0 to cnt-1 do
ReadExportEntry(src, ex.entries[i]);
end;
procedure WriteExport(const ex: TExportSection; dst: TStream);
var
i : integer;
begin
WriteU32(dst, length(ex.entries));
for i:=0 to length(ex.entries)-1 do begin
WriteName(dst, ex.entries[i].name);
dst.WriteByte(ex.entries[i].desc);
WriteU32(dst, ex.entries[i].index);
end;
end;
end. end.

View File

@ -1,16 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<CONFIG> <CONFIG>
<ProjectOptions> <ProjectOptions>
<Version Value="11"/> <Version Value="12"/>
<PathDelim Value="\"/> <PathDelim Value="\"/>
<General> <General>
<Flags> <Flags>
<MainUnitHasCreateFormStatements Value="False"/> <MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/> <MainUnitHasTitleStatement Value="False"/>
<MainUnitHasScaledStatement Value="False"/> <MainUnitHasScaledStatement Value="False"/>
<CompatibilityMode Value="True"/>
</Flags> </Flags>
<SessionStorage Value="InProjectDir"/> <SessionStorage Value="InProjectDir"/>
<MainUnit Value="0"/>
<Title Value="wasmld"/> <Title Value="wasmld"/>
<UseAppBundle Value="False"/> <UseAppBundle Value="False"/>
<ResourceType Value="res"/> <ResourceType Value="res"/>

View File

@ -62,7 +62,7 @@ begin
end; end;
function WriteStream(st: TStream): Boolean; function WriteStream(st: TStream; syms: TStrings): Boolean;
var var
dw : LongWord; dw : LongWord;
ofs : int64; ofs : int64;
@ -92,7 +92,7 @@ begin
writeln(nm); writeln(nm);
if nm = SectionName_Linking then begin if nm = SectionName_Linking then begin
writeln('rewriting linking...'); writeln('rewriting linking...');
ProcessLinkingSection(st); ProcessLinkingSection(st, syms);
break; break;
end; end;
//DumpLinking(st, sc.size - (st.Position - ofs)); //DumpLinking(st, sc.size - (st.Position - ofs));
@ -107,27 +107,145 @@ begin
end; end;
end; end;
procedure ProcessWasmFile(const fn: string); procedure ProcessWasmFile(const fn, symfn: string);
var var
fs :TFileStream; fs :TFileStream;
syms: TStringList;
begin begin
writeln('proc: ', fn); writeln('proc: ', fn);
syms:=TStringList.Create;
fs := TFileStream.Create(fn, fmOpenReadWrite or fmShareDenyNone); fs := TFileStream.Create(fn, fmOpenReadWrite or fmShareDenyNone);
try try
if (symfn<>'') then
ReadSymbolsConf(symfn, syms);
writeln('size: ', fs.size); writeln('size: ', fs.size);
WriteStream(fs); WriteStream(fs, syms);
finally finally
fs.Free; fs.Free;
syms.Free;
end; end;
end; end;
procedure RenameExport(var x: TExportSection; syms: TStrings);
var
i : integer;
v : string;
begin
for i:=0 to length(x.entries)-1 do begin
v := syms.Values[x.entries[i].name];
if v <> '' then
x.entries[i].name := v;
end;
end;
function ProcessSections(st, dst: TStream; syms: TStrings): Boolean;
var
dw : LongWord;
ofs : int64;
sc : TSection;
ps : int64;
x : TExportSection;
i : integer;
mem : TMemoryStream;
begin
dw := st.ReadDWord;
Result := dw = WasmId_Int;
if not Result then begin
Exit;
end;
dw := st.ReadDWord;
while st.Position<st.Size do begin
ofs := st.Position;
sc.id := st.ReadByte;
sc.Size := ReadU(st);
writeln(ofs,': id=', sc.id,'(', SectionIdToStr(sc.id),') sz=', sc.size);
ps := st.Position+sc.size;
if sc.id = SECT_EXPORT then begin
ReadExport(st, x);
RenameExport(x, syms);
st.Position:=0;
dst.CopyFrom(st, ofs);
st.Position:=ps;
mem := TMemoryStream.Create;
WriteExport(x, mem);
mem.Position:=0;
dst.WriteByte(SECT_EXPORT);
WriteU32(dst, mem.Size);
dst.CopyFrom(mem, mem.Size);
writeln('entries = ', length(x.entries));
for i:=0 to length(x.entries)-1 do begin
writeln(x.entries[i].desc,' ', x.entries[i].name)
end;
dst.CopyFrom(st, st.Size-st.Position);
break; // done
end;
{if sc.id=0 then begin
nm := GetName(st);
writeln(nm);
if nm = SectionName_Linking then begin
writeln('rewriting linking...');
ProcessLinkingSection(st, syms);
break;
end;
//DumpLinking(st, sc.size - (st.Position - ofs));
end;}
//if sc.id= 1 then DumpTypes(st);
if st.Position <> ps then
begin
//writeln('adjust stream targ=',ps,' actual: ', st.position);
st.Position := ps;
end;
end;
end;
procedure ProcessWasmSection(const fn, {%H-}symfn: string);
var
fs : TFileStream;
syms : TStringList;
dst : TMemoryStream;
begin
writeln('proc: ', fn);
syms:=TStringList.Create;
fs := TFileStream.Create(fn, fmOpenReadWrite or fmShareDenyNone);
dst := TMemoryStream.Create;
try
if (symfn <> '') and fileExists(symfn) then
syms.LoadFromFile(symfn);
ProcessSections(fs, dst, syms);
fs.Position:=0;
dst.Position:=0;
fs.CopyFrom(dst, dst.Size);
fs.Size:=dst.Size;
finally
dst.Free;
fs.Free;
syms.Free;
end;
end;
var
symfn : string;
begin begin
if ParamCount=0 then begin if ParamCount=0 then begin
writeln('please specify .wasm file'); writeln('please specify .wasm file');
exit; exit;
end; end;
symfn:='';
if ParamCount>1 then symfn:=ParamStr(2);
//ReadWasmFile(ParamStr(1)); //ReadWasmFile(ParamStr(1));
ProcessWasmFile(ParamStr(1)); //ProcessWasmFile(ParamStr(1), symfn);
ProcessWasmSection(ParamStr(1), symfn);
end. end.

View File

@ -4,11 +4,55 @@ interface
uses Classes, SysUtils, wasmlink, wasmbin, lebutils; uses Classes, SysUtils, wasmlink, wasmbin, lebutils;
procedure ProcessLinkingSection(st: TStream); type
TSymbolType = (
st_Nochange, st_Hidden, st_Weak
);
TSymbolConfigure = class(TObject)
symname : string;
needtype : TSymbolType;
end;
procedure ReadSymbolsConf(const fn: string; dst: TStrings);
procedure ReadSymbolsConf(src: TStream; dst: TStrings);
procedure ProcessLinkingSection(st: TStream; syms: TStrings);
implementation implementation
procedure ProcessLinkingSection(st: TStream); procedure ReadSymbolsConf(const fn: string; dst: TStrings);
var
fs: TFileStream;
begin
fs:=TFileStream.Create(fn, fmOpenRead or fmShareDenyNone);
try
ReadSymbolsConf(fs, dst);
finally
fs.Free;
end;
end;
function StrToSymType(const s: string): TSymbolType;
begin
if length(s)=0 then
Result:=st_Nochange
else
case upCase(s[1]) of
'H','L': Result:=st_Hidden;
'W': Result:=st_Weak;
else
Result:=st_Nochange;
end;
end;
procedure ReadSymbolsConf(src: TStream; dst: TStrings);
begin
dst.LoadFromStream(src);
end;
procedure ProcessLinkingSection(st: TStream; syms: TStrings);
var var
mt : TLinkingMetadata; mt : TLinkingMetadata;
//en : Int64; //en : Int64;
@ -18,6 +62,9 @@ var
i : integer; i : integer;
si : TSymInfo; si : TSymInfo;
ofs : Int64; ofs : Int64;
v : string;
tt : TSymbolType;
fl : LongWord;
begin begin
//en := st.Position+secsize; //en := st.Position+secsize;
ReadMetadata(st, mt); ReadMetadata(st, mt);
@ -37,11 +84,24 @@ begin
//write(SymKindToStr(si.kind),' ',IntToHex(si.flags,8)); //write(SymKindToStr(si.kind),' ',IntToHex(si.flags,8));
//if si.hasSymName then write(' ',si.symname); //if si.hasSymName then write(' ',si.symname);
//writeln; //writeln;
if si.flags and WASM_SYM_UNDEFINED = 0 then
si.flags := si.flags or WASM_SYM_BINDING_LOCAL;
if si.hasSymName then begin
v := syms.Values[si.symname];
tt := StrToSymType(v);
fl := si.flags;
case tt of
st_Hidden:
si.flags := (si.flags or WASM_SYM_BINDING_LOCAL) and (not WASM_SYM_BINDING_WEAK) and (not WASM_SYM_UNDEFINED);
st_Weak:
si.flags := (si.flags or WASM_SYM_BINDING_WEAK) and (not WASM_SYM_BINDING_LOCAL)
end;
if fl <> si.flags then begin
st.Position := ofs; st.Position := ofs;
WriteSymInfo(st, si); WriteSymInfo(st, si);
end;
end;
//writeln(si.symname); //writeln(si.symname);
end; end;