mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-13 11:09:13 +02:00
[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:
parent
50df4ac869
commit
18910afe47
@ -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.
|
||||||
|
|
||||||
|
@ -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"/>
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
@ -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;
|
|
||||||
|
|
||||||
st.Position := ofs;
|
if si.hasSymName then begin
|
||||||
WriteSymInfo(st, si);
|
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;
|
||||||
|
WriteSymInfo(st, si);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
//writeln(si.symname);
|
//writeln(si.symname);
|
||||||
end;
|
end;
|
||||||
|
Loading…
Reference in New Issue
Block a user