mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-16 23:59:23 +02:00
[PATCH 010/188] starting wasmtool
From 8bc85f8323cf0fc24a838a0dcc8cde90b91dabee Mon Sep 17 00:00:00 2001 From: Dmitry Boyarintsev <skalogryz.lists@gmail.com> Date: Thu, 26 Sep 2019 09:24:27 -0400 git-svn-id: branches/wasm@46006 -
This commit is contained in:
parent
18910afe47
commit
d4f8da8112
3
.gitattributes
vendored
3
.gitattributes
vendored
@ -18983,3 +18983,6 @@ utils/wasmbin/wasmld.lpi svneol=native#text/plain
|
|||||||
utils/wasmbin/wasmld.lpr svneol=native#text/plain
|
utils/wasmbin/wasmld.lpr svneol=native#text/plain
|
||||||
utils/wasmbin/wasmlink.pas svneol=native#text/plain
|
utils/wasmbin/wasmlink.pas svneol=native#text/plain
|
||||||
utils/wasmbin/wasmlinkchange.pas svneol=native#text/plain
|
utils/wasmbin/wasmlinkchange.pas svneol=native#text/plain
|
||||||
|
utils/wasmbin/wasmtool.lpi svneol=native#text/plain
|
||||||
|
utils/wasmbin/wasmtool.lpr svneol=native#text/plain
|
||||||
|
utils/wasmbin/wasmtoolutils.pas svneol=native#text/plain
|
||||||
|
68
utils/wasmbin/wasmtool.lpi
Normal file
68
utils/wasmbin/wasmtool.lpi
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<CONFIG>
|
||||||
|
<ProjectOptions>
|
||||||
|
<Version Value="11"/>
|
||||||
|
<PathDelim Value="\"/>
|
||||||
|
<General>
|
||||||
|
<Flags>
|
||||||
|
<MainUnitHasCreateFormStatements Value="False"/>
|
||||||
|
<MainUnitHasTitleStatement Value="False"/>
|
||||||
|
<MainUnitHasScaledStatement Value="False"/>
|
||||||
|
</Flags>
|
||||||
|
<SessionStorage Value="InProjectDir"/>
|
||||||
|
<MainUnit Value="0"/>
|
||||||
|
<Title Value="wasmtool"/>
|
||||||
|
<UseAppBundle Value="False"/>
|
||||||
|
<ResourceType Value="res"/>
|
||||||
|
</General>
|
||||||
|
<BuildModes Count="1">
|
||||||
|
<Item1 Name="Default" Default="True"/>
|
||||||
|
</BuildModes>
|
||||||
|
<PublishOptions>
|
||||||
|
<Version Value="2"/>
|
||||||
|
<UseFileFilters Value="True"/>
|
||||||
|
</PublishOptions>
|
||||||
|
<RunParams>
|
||||||
|
<FormatVersion Value="2"/>
|
||||||
|
<Modes Count="0"/>
|
||||||
|
</RunParams>
|
||||||
|
<Units Count="3">
|
||||||
|
<Unit0>
|
||||||
|
<Filename Value="wasmtool.lpr"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
</Unit0>
|
||||||
|
<Unit1>
|
||||||
|
<Filename Value="wasmbin.pas"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
</Unit1>
|
||||||
|
<Unit2>
|
||||||
|
<Filename Value="wasmbindebug.pas"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
</Unit2>
|
||||||
|
</Units>
|
||||||
|
</ProjectOptions>
|
||||||
|
<CompilerOptions>
|
||||||
|
<Version Value="11"/>
|
||||||
|
<PathDelim Value="\"/>
|
||||||
|
<Target>
|
||||||
|
<Filename Value="wasmtool"/>
|
||||||
|
</Target>
|
||||||
|
<SearchPaths>
|
||||||
|
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||||
|
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||||
|
</SearchPaths>
|
||||||
|
</CompilerOptions>
|
||||||
|
<Debugging>
|
||||||
|
<Exceptions Count="3">
|
||||||
|
<Item1>
|
||||||
|
<Name Value="EAbort"/>
|
||||||
|
</Item1>
|
||||||
|
<Item2>
|
||||||
|
<Name Value="ECodetoolError"/>
|
||||||
|
</Item2>
|
||||||
|
<Item3>
|
||||||
|
<Name Value="EFOpenError"/>
|
||||||
|
</Item3>
|
||||||
|
</Exceptions>
|
||||||
|
</Debugging>
|
||||||
|
</CONFIG>
|
39
utils/wasmbin/wasmtool.lpr
Normal file
39
utils/wasmbin/wasmtool.lpr
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
program wasmtool;
|
||||||
|
|
||||||
|
{$mode objfpc}{$H+}
|
||||||
|
|
||||||
|
uses
|
||||||
|
{$IFDEF UNIX}{$IFDEF UseCThreads}
|
||||||
|
cthreads,
|
||||||
|
{$ENDIF}{$ENDIF}
|
||||||
|
{ you can add units after this }
|
||||||
|
Classes, SysUtils, wasmbin, lebutils,
|
||||||
|
wasmbindebug, wasmlink, wasmlinkchange,
|
||||||
|
wasmtoolutils;
|
||||||
|
|
||||||
|
procedure PrintHelp;
|
||||||
|
begin
|
||||||
|
writeln('wasmtool [options] .wasm file...');
|
||||||
|
writeln();
|
||||||
|
writeln('options:');
|
||||||
|
writeln(' --exportrename @inputfile');
|
||||||
|
writeln(' --symbolflag @inputfile');
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
var
|
||||||
|
symfn : string;
|
||||||
|
begin
|
||||||
|
if ParamCount=0 then begin
|
||||||
|
PrintHelp;
|
||||||
|
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
symfn:='';
|
||||||
|
if ParamCount>1 then symfn:=ParamStr(2);
|
||||||
|
|
||||||
|
//ReadWasmFile(ParamStr(1));
|
||||||
|
//ProcessWasmFile(ParamStr(1), symfn);
|
||||||
|
ProcessWasmSection(ParamStr(1), symfn);
|
||||||
|
end.
|
||||||
|
|
243
utils/wasmbin/wasmtoolutils.pas
Normal file
243
utils/wasmbin/wasmtoolutils.pas
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
unit wasmtoolutils;
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes,SysUtils, wasmbin, lebutils,
|
||||||
|
//wasmbindebug,
|
||||||
|
wasmlink, wasmlinkchange;
|
||||||
|
|
||||||
|
function ReadStream(st: TStream): Boolean;
|
||||||
|
procedure ReadWasmFile(const fn: string);
|
||||||
|
function WriteStream(st: TStream; syms: TStrings): Boolean;
|
||||||
|
procedure ProcessWasmFile(const fn, symfn: string);
|
||||||
|
procedure RenameExport(var x: TExportSection; syms: TStrings);
|
||||||
|
function ProcessSections(st, dst: TStream; syms: TStrings): Boolean;
|
||||||
|
procedure ProcessWasmSection(const fn, {%H-}symfn: string);
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
function ReadStream(st: TStream): Boolean;
|
||||||
|
var
|
||||||
|
dw : LongWord;
|
||||||
|
ofs : int64;
|
||||||
|
sc : TSection;
|
||||||
|
ps : int64;
|
||||||
|
nm : string;
|
||||||
|
begin
|
||||||
|
dw := st.ReadDWord;
|
||||||
|
Result := dw = WasmId_Int;
|
||||||
|
if not Result then begin
|
||||||
|
writeln('not a wasm file');
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
dw := st.ReadDWord;
|
||||||
|
writeln('version: ', dw);
|
||||||
|
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=0 then begin
|
||||||
|
nm := GetName(st);
|
||||||
|
writeln(nm);
|
||||||
|
if nm = SectionName_Linking then
|
||||||
|
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 ReadWasmFile(const fn: string);
|
||||||
|
var
|
||||||
|
fs :TFileStream;
|
||||||
|
begin
|
||||||
|
fs := TFileStream.Create(fn, fmOpenRead or fmShareDenyNone);
|
||||||
|
try
|
||||||
|
ReadStream(fs);
|
||||||
|
finally
|
||||||
|
fs.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function WriteStream(st: TStream; syms: TStrings): Boolean;
|
||||||
|
var
|
||||||
|
dw : LongWord;
|
||||||
|
ofs : int64;
|
||||||
|
sc : TSection;
|
||||||
|
ps : int64;
|
||||||
|
nm : string;
|
||||||
|
begin
|
||||||
|
writeln('read: ');
|
||||||
|
dw := st.ReadDWord;
|
||||||
|
writeln('dw: ' ,dw);
|
||||||
|
Result := dw = WasmId_Int;
|
||||||
|
if not Result then begin
|
||||||
|
writeln('not a wasm file');
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
dw := st.ReadDWord;
|
||||||
|
writeln('version: ', dw);
|
||||||
|
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=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 ProcessWasmFile(const fn, symfn: string);
|
||||||
|
var
|
||||||
|
fs :TFileStream;
|
||||||
|
syms: TStringList;
|
||||||
|
begin
|
||||||
|
writeln('proc: ', fn);
|
||||||
|
syms:=TStringList.Create;
|
||||||
|
fs := TFileStream.Create(fn, fmOpenReadWrite or fmShareDenyNone);
|
||||||
|
try
|
||||||
|
if (symfn<>'') then
|
||||||
|
ReadSymbolsConf(symfn, syms);
|
||||||
|
writeln('size: ', fs.size);
|
||||||
|
WriteStream(fs, syms);
|
||||||
|
finally
|
||||||
|
fs.Free;
|
||||||
|
syms.Free;
|
||||||
|
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;
|
||||||
|
|
||||||
|
end.
|
Loading…
Reference in New Issue
Block a user