+ write the externals to the symbol table

This commit is contained in:
Nikolay Nikolov 2021-09-25 22:45:30 +03:00
parent 3e98429418
commit 2d2906205b

View File

@ -40,6 +40,13 @@ interface
type type
{ TWasmObjSymbol }
TWasmObjSymbol = class(TObjSymbol)
ImportIndex: Integer;
constructor create(AList:TFPHashObjectList;const AName:string);
end;
{ TWasmObjRelocation } { TWasmObjRelocation }
TWasmObjRelocation = class(TObjRelocation) TWasmObjRelocation = class(TObjRelocation)
@ -94,8 +101,11 @@ interface
TWasmObjOutput = class(tObjOutput) TWasmObjOutput = class(tObjOutput)
private private
FData: TWasmObjData; FData: TWasmObjData;
FWasmSymbolTable: tdynamicarray;
FWasmSymbolTableEntriesCount: Integer;
FWasmSections: array [TWasmSectionID] of tdynamicarray; FWasmSections: array [TWasmSectionID] of tdynamicarray;
FWasmCustomSections: array [TWasmCustomSectionType] of tdynamicarray; FWasmCustomSections: array [TWasmCustomSectionType] of tdynamicarray;
FWasmLinkingSubsections: array [low(TWasmLinkingSubsectionType)..high(TWasmLinkingSubsectionType)] of tdynamicarray;
procedure WriteUleb(d: tdynamicarray; v: uint64); procedure WriteUleb(d: tdynamicarray; v: uint64);
procedure WriteUleb(w: TObjectWriter; v: uint64); procedure WriteUleb(w: TObjectWriter; v: uint64);
procedure WriteSleb(d: tdynamicarray; v: int64); procedure WriteSleb(d: tdynamicarray; v: int64);
@ -110,6 +120,8 @@ interface
function IsExternalFunction(sym: TObjSymbol): Boolean; function IsExternalFunction(sym: TObjSymbol): Boolean;
procedure WriteFunctionLocals(dest: tdynamicarray; ed: TWasmObjSymbolExtraData); procedure WriteFunctionLocals(dest: tdynamicarray; ed: TWasmObjSymbolExtraData);
procedure WriteFunctionCode(dest: tdynamicarray; objsym: TObjSymbol); procedure WriteFunctionCode(dest: tdynamicarray; objsym: TObjSymbol);
procedure WriteSymbolTable;
procedure WriteLinkingSubsection(wlst: TWasmLinkingSubsectionType);
protected protected
function writeData(Data:TObjData):boolean;override; function writeData(Data:TObjData):boolean;override;
public public
@ -128,6 +140,16 @@ implementation
uses uses
verbose; verbose;
{****************************************************************************
TWasmObjSymbol
****************************************************************************}
constructor TWasmObjSymbol.create(AList: TFPHashObjectList; const AName: string);
begin
inherited create(AList,AName);
ImportIndex:=-1;
end;
{**************************************************************************** {****************************************************************************
TWasmObjSymbolExtraData TWasmObjSymbolExtraData
****************************************************************************} ****************************************************************************}
@ -309,6 +331,7 @@ implementation
begin begin
inherited; inherited;
CObjSection:=TWasmObjSection; CObjSection:=TWasmObjSection;
CObjSymbol:=TWasmObjSymbol;
FObjSymbolsExtraDataList:=TFPHashObjectList.Create; FObjSymbolsExtraDataList:=TFPHashObjectList.Create;
end; end;
@ -620,6 +643,24 @@ implementation
encoded_locals.Free; encoded_locals.Free;
end; end;
procedure TWasmObjOutput.WriteSymbolTable;
begin
WriteUleb(FWasmLinkingSubsections[WASM_SYMBOL_TABLE],FWasmSymbolTableEntriesCount);
FWasmSymbolTable.seek(0);
CopyDynamicArray(FWasmSymbolTable,FWasmLinkingSubsections[WASM_SYMBOL_TABLE],FWasmSymbolTable.size);
end;
procedure TWasmObjOutput.WriteLinkingSubsection(wlst: TWasmLinkingSubsectionType);
begin
if FWasmLinkingSubsections[wlst].size>0 then
begin
WriteByte(FWasmCustomSections[wcstLinking],Ord(wlst));
WriteUleb(FWasmCustomSections[wcstLinking],FWasmLinkingSubsections[wlst].size);
FWasmLinkingSubsections[wlst].seek(0);
CopyDynamicArray(FWasmLinkingSubsections[wlst],FWasmCustomSections[wcstLinking],FWasmLinkingSubsections[wlst].size);
end;
end;
function TWasmObjOutput.writeData(Data:TObjData):boolean; function TWasmObjOutput.writeData(Data:TObjData):boolean;
var var
i: Integer; i: Integer;
@ -627,10 +668,10 @@ implementation
segment_count: Integer = 0; segment_count: Integer = 0;
cur_seg_ofs: qword = 0; cur_seg_ofs: qword = 0;
types_count, types_count,
imports_count: Integer; imports_count, NextImportFunctionIndex: Integer;
import_functions_count: Integer = 0; import_functions_count: Integer = 0;
functions_count: Integer = 0; functions_count: Integer = 0;
objsym: TObjSymbol; objsym: TWasmObjSymbol;
cust_sec: TWasmCustomSectionType; cust_sec: TWasmCustomSectionType;
begin begin
FData:=TWasmObjData(Data); FData:=TWasmObjData(Data);
@ -643,7 +684,7 @@ implementation
for i:=0 to Data.ObjSymbolList.Count-1 do for i:=0 to Data.ObjSymbolList.Count-1 do
begin begin
objsym:=TObjSymbol(Data.ObjSymbolList[i]); objsym:=TWasmObjSymbol(Data.ObjSymbolList[i]);
if IsExternalFunction(objsym) then if IsExternalFunction(objsym) then
Inc(import_functions_count); Inc(import_functions_count);
if objsym.typ=AT_FUNCTION then if objsym.typ=AT_FUNCTION then
@ -714,11 +755,14 @@ implementation
WriteByte(FWasmSections[wsiImport],$7F); { i32 } WriteByte(FWasmSections[wsiImport],$7F); { i32 }
WriteByte(FWasmSections[wsiImport],$01); { var } WriteByte(FWasmSections[wsiImport],$01); { var }
{ import[2]..import[imports_count-2] } { import[2]..import[imports_count-2] }
NextImportFunctionIndex:=0;
for i:=0 to Data.ObjSymbolList.Count-1 do for i:=0 to Data.ObjSymbolList.Count-1 do
begin begin
objsym:=TObjSymbol(Data.ObjSymbolList[i]); objsym:=TWasmObjSymbol(Data.ObjSymbolList[i]);
if IsExternalFunction(objsym) then if IsExternalFunction(objsym) then
begin begin
objsym.ImportIndex:=NextImportFunctionIndex;
Inc(NextImportFunctionIndex);
WriteName(FWasmSections[wsiImport],'env'); WriteName(FWasmSections[wsiImport],'env');
WriteName(FWasmSections[wsiImport],objsym.Name); WriteName(FWasmSections[wsiImport],objsym.Name);
WriteByte(FWasmSections[wsiImport],$00); { func } WriteByte(FWasmSections[wsiImport],$00); { func }
@ -737,7 +781,7 @@ implementation
WriteUleb(FWasmSections[wsiCode],functions_count); WriteUleb(FWasmSections[wsiCode],functions_count);
for i:=0 to Data.ObjSymbolList.Count-1 do for i:=0 to Data.ObjSymbolList.Count-1 do
begin begin
objsym:=TObjSymbol(Data.ObjSymbolList[i]); objsym:=TWasmObjSymbol(Data.ObjSymbolList[i]);
if objsym.typ=AT_FUNCTION then if objsym.typ=AT_FUNCTION then
begin begin
WriteUleb(FWasmSections[wsiFunction],TWasmObjSymbolExtraData(FData.FObjSymbolsExtraDataList.Find(objsym.Name)).TypeIdx); WriteUleb(FWasmSections[wsiFunction],TWasmObjSymbolExtraData(FData.FObjSymbolsExtraDataList.Find(objsym.Name)).TypeIdx);
@ -745,6 +789,24 @@ implementation
end; end;
end; end;
for i:=0 to Data.ObjSymbolList.Count-1 do
begin
objsym:=TWasmObjSymbol(Data.ObjSymbolList[i]);
if IsExternalFunction(objsym) then
begin
Inc(FWasmSymbolTableEntriesCount);
WriteByte(FWasmSymbolTable,Ord(SYMTAB_FUNCTION));
WriteUleb(FWasmSymbolTable,WASM_SYM_UNDEFINED);
WriteUleb(FWasmSymbolTable,objsym.ImportIndex);
end
else if objsym.typ=AT_FUNCTION then
begin
end;
end;
WriteSymbolTable;
WriteLinkingSubsection(WASM_SYMBOL_TABLE);
Writer.write(WasmModuleMagic,SizeOf(WasmModuleMagic)); Writer.write(WasmModuleMagic,SizeOf(WasmModuleMagic));
Writer.write(WasmVersion,SizeOf(WasmVersion)); Writer.write(WasmVersion,SizeOf(WasmVersion));
@ -759,7 +821,7 @@ implementation
Writeln('ObjSymbolList:'); Writeln('ObjSymbolList:');
for i:=0 to Data.ObjSymbolList.Count-1 do for i:=0 to Data.ObjSymbolList.Count-1 do
begin begin
objsym:=TObjSymbol(Data.ObjSymbolList[i]); objsym:=TWasmObjSymbol(Data.ObjSymbolList[i]);
Write(objsym.Name, ' bind=', objsym.Bind, ' typ=', objsym.typ, ' address=', objsym.address, ' objsection='); Write(objsym.Name, ' bind=', objsym.Bind, ' typ=', objsym.typ, ' address=', objsym.address, ' objsection=');
if assigned(objsym.objsection) then if assigned(objsym.objsection) then
Write(objsym.objsection.Name) Write(objsym.objsection.Name)
@ -782,6 +844,7 @@ implementation
var var
i: TWasmSectionID; i: TWasmSectionID;
j: TWasmCustomSectionType; j: TWasmCustomSectionType;
k: TWasmLinkingSubsectionType;
begin begin
inherited; inherited;
cobjdata:=TWasmObjData; cobjdata:=TWasmObjData;
@ -789,17 +852,25 @@ implementation
FWasmSections[i] := tdynamicarray.create(SectionDataMaxGrow); FWasmSections[i] := tdynamicarray.create(SectionDataMaxGrow);
for j in TWasmCustomSectionType do for j in TWasmCustomSectionType do
FWasmCustomSections[j] := tdynamicarray.create(SectionDataMaxGrow); FWasmCustomSections[j] := tdynamicarray.create(SectionDataMaxGrow);
for k:=low(TWasmLinkingSubsectionType) to high(TWasmLinkingSubsectionType) do
FWasmLinkingSubsections[k] := tdynamicarray.create(SectionDataMaxGrow);
FWasmSymbolTable:=tdynamicarray.create(SectionDataMaxGrow);
FWasmSymbolTableEntriesCount:=0;
end; end;
destructor TWasmObjOutput.destroy; destructor TWasmObjOutput.destroy;
var var
i: TWasmSectionID; i: TWasmSectionID;
j: TWasmCustomSectionType; j: TWasmCustomSectionType;
k: TWasmLinkingSubsectionType;
begin begin
for i in TWasmSectionID do for i in TWasmSectionID do
FWasmSections[i].Free; FWasmSections[i].Free;
for j in TWasmCustomSectionType do for j in TWasmCustomSectionType do
FWasmCustomSections[j].Free; FWasmCustomSections[j].Free;
for k:=low(TWasmLinkingSubsectionType) to high(TWasmLinkingSubsectionType) do
FWasmLinkingSubsections[k].Free;
FWasmSymbolTable.Free;
inherited destroy; inherited destroy;
end; end;