+ fully implemented the RELOC_FUNCTION_INDEX_LEB relocations

This commit is contained in:
Nikolay Nikolov 2021-09-26 00:45:52 +03:00
parent 4e4910cb84
commit 67cbb7032e

View File

@ -45,7 +45,9 @@ interface
TWasmObjSymbol = class(TObjSymbol)
ImportIndex: Integer;
FuncIndex: Integer;
SymbolIndex: Integer;
constructor create(AList:TFPHashObjectList;const AName:string);
function ImportOrFuncIndex: Integer;
end;
{ TWasmObjRelocation }
@ -70,6 +72,7 @@ interface
public
SegIdx: Integer;
SegOfs: qword;
FileSectionOfs: qword;
function IsCode: Boolean;
function IsData: Boolean;
end;
@ -113,6 +116,7 @@ interface
FWasmLinkingSubsections: array [low(TWasmLinkingSubsectionType)..high(TWasmLinkingSubsectionType)] of tdynamicarray;
procedure WriteUleb(d: tdynamicarray; v: uint64);
procedure WriteUleb(w: TObjectWriter; v: uint64);
procedure WriteUleb5(d: tdynamicarray; v: uint64);
procedure WriteSleb(d: tdynamicarray; v: int64);
procedure WriteByte(d: tdynamicarray; b: byte);
procedure WriteName(d: tdynamicarray; const s: string);
@ -129,6 +133,8 @@ interface
procedure WriteRelocationCodeTable(CodeSectionIndex: Integer);
procedure WriteRelocationDataTable(DataSectionIndex: Integer);
procedure WriteLinkingSubsection(wlst: TWasmLinkingSubsectionType);
procedure DoRelocations;
procedure WriteRelocations;
protected
function writeData(Data:TObjData):boolean;override;
public
@ -156,6 +162,17 @@ implementation
inherited create(AList,AName);
ImportIndex:=-1;
FuncIndex:=-1;
SymbolIndex:=-1;
end;
function TWasmObjSymbol.ImportOrFuncIndex: Integer;
begin
if ImportIndex<>-1 then
result:=ImportIndex
else if FuncIndex<>-1 then
result:=FuncIndex
else
internalerror(2021092601);
end;
{****************************************************************************
@ -483,6 +500,21 @@ implementation
until v=0;
end;
procedure TWasmObjOutput.WriteUleb5(d: tdynamicarray; v: uint64);
var
b: byte;
i: Integer;
begin
for i:=1 to 5 do
begin
b:=byte(v) and 127;
v:=v shr 7;
if i<>5 then
b:=b or 128;
d.write(b,1);
end;
end;
procedure TWasmObjOutput.WriteSleb(d: tdynamicarray; v: int64);
var
b: byte;
@ -632,11 +664,11 @@ implementation
encoded_locals: tdynamicarray;
ObjSymExtraData: TWasmObjSymbolExtraData;
codelen: LongWord;
ObjSection: TObjSection;
ObjSection: TWasmObjSection;
codeexprlen: QWord;
begin
ObjSymExtraData:=TWasmObjSymbolExtraData(FData.FObjSymbolsExtraDataList.Find(objsym.Name));
ObjSection:=objsym.objsection;
ObjSection:=TWasmObjSection(objsym.objsection);
ObjSection.Data.seek(objsym.address);
codeexprlen:=ObjSection.Size-objsym.address;
@ -646,6 +678,7 @@ implementation
WriteUleb(dest,codelen);
encoded_locals.seek(0);
CopyDynamicArray(encoded_locals,dest,encoded_locals.size);
ObjSection.FileSectionOfs:=dest.size-objsym.offset;
CopyDynamicArray(ObjSection.Data,dest,codeexprlen);
WriteByte(dest,$0B);
encoded_locals.Free;
@ -685,6 +718,74 @@ implementation
end;
end;
procedure TWasmObjOutput.DoRelocations;
var
si, ri: Integer;
objsec: TWasmObjSection;
objrel: TWasmObjRelocation;
begin
for si:=0 to FData.ObjSectionList.Count-1 do
begin
objsec:=TWasmObjSection(FData.ObjSectionList[si]);
for ri:=0 to objsec.ObjRelocations.Count-1 do
begin
objrel:=TWasmObjRelocation(objsec.ObjRelocations[ri]);
case objrel.typ of
RELOC_FUNCTION_INDEX_LEB:
begin
if not assigned(objrel.symbol) then
internalerror(2021092509);
objsec.Data.seek(objrel.DataOffset);
WriteUleb5(objsec.Data,TWasmObjSymbol(objrel.symbol).ImportOrFuncIndex);
end;
else
internalerror(2021092510);
end;
end;
end;
end;
procedure TWasmObjOutput.WriteRelocations;
var
si, ri: Integer;
objsec: TWasmObjSection;
objrel: TWasmObjRelocation;
relout: tdynamicarray;
relcount: PInteger;
begin
for si:=0 to FData.ObjSectionList.Count-1 do
begin
objsec:=TWasmObjSection(FData.ObjSectionList[si]);
if objsec.IsCode then
begin
relout:=FWasmRelocationCodeTable;
relcount:=@FWasmRelocationCodeTableEntriesCount;
end
else
begin
relout:=FWasmRelocationDataTable;
relcount:=@FWasmRelocationDataTableEntriesCount;
end;
for ri:=0 to objsec.ObjRelocations.Count-1 do
begin
objrel:=TWasmObjRelocation(objsec.ObjRelocations[ri]);
case objrel.typ of
RELOC_FUNCTION_INDEX_LEB:
begin
if not assigned(objrel.symbol) then
internalerror(2021092508);
Inc(relcount^);
WriteByte(relout,Ord(R_WASM_FUNCTION_INDEX_LEB));
WriteUleb(relout,objrel.DataOffset+objsec.FileSectionOfs);
WriteUleb(relout,TWasmObjSymbol(objrel.symbol).SymbolIndex);
end;
else
internalerror(2021092507);
end;
end;
end;
end;
function TWasmObjOutput.writeData(Data:TObjData):boolean;
var
i: Integer;
@ -756,6 +857,7 @@ implementation
WriteSleb(FWasmSections[wsiData],objsec.SegOfs);
WriteByte(FWasmSections[wsiData],$0b);
WriteUleb(FWasmSections[wsiData],objsec.Size);
objsec.FileSectionOfs:=FWasmSections[wsiData].size;
if oso_Data in objsec.SecOptions then
begin
objsec.Data.seek(0);
@ -806,7 +908,6 @@ implementation
WriteUleb(FWasmSections[wsiImport],1); { 1 }
WriteUleb(FWasmSections[wsiFunction],functions_count);
WriteUleb(FWasmSections[wsiCode],functions_count);
NextFunctionIndex:=NextImportFunctionIndex;
for i:=0 to Data.ObjSymbolList.Count-1 do
begin
@ -816,7 +917,6 @@ implementation
objsym.FuncIndex:=NextFunctionIndex;
Inc(NextFunctionIndex);
WriteUleb(FWasmSections[wsiFunction],TWasmObjSymbolExtraData(FData.FObjSymbolsExtraDataList.Find(objsym.Name)).TypeIdx);
WriteFunctionCode(FWasmSections[wsiCode],objsym);
end;
end;
@ -825,6 +925,7 @@ implementation
objsym:=TWasmObjSymbol(Data.ObjSymbolList[i]);
if IsExternalFunction(objsym) then
begin
objsym.SymbolIndex:=FWasmSymbolTableEntriesCount;
Inc(FWasmSymbolTableEntriesCount);
WriteByte(FWasmSymbolTable,Ord(SYMTAB_FUNCTION));
WriteUleb(FWasmSymbolTable,WASM_SYM_UNDEFINED);
@ -832,6 +933,7 @@ implementation
end
else if objsym.typ=AT_FUNCTION then
begin
objsym.SymbolIndex:=FWasmSymbolTableEntriesCount;
Inc(FWasmSymbolTableEntriesCount);
WriteByte(FWasmSymbolTable,Ord(SYMTAB_FUNCTION));
WriteUleb(FWasmSymbolTable,0);
@ -840,6 +942,7 @@ implementation
end
else if objsym.typ=AT_DATA then
begin
objsym.SymbolIndex:=FWasmSymbolTableEntriesCount;
Inc(FWasmSymbolTableEntriesCount);
WriteByte(FWasmSymbolTable,Ord(SYMTAB_DATA));
if objsym.bind=AB_GLOBAL then
@ -860,6 +963,18 @@ implementation
end;
end;
DoRelocations;
WriteUleb(FWasmSections[wsiCode],functions_count);
for i:=0 to Data.ObjSymbolList.Count-1 do
begin
objsym:=TWasmObjSymbol(Data.ObjSymbolList[i]);
if objsym.typ=AT_FUNCTION then
WriteFunctionCode(FWasmSections[wsiCode],objsym);
end;
WriteRelocations;
WriteSymbolTable;
WriteLinkingSubsection(WASM_SYMBOL_TABLE);
WriteLinkingSubsection(WASM_SEGMENT_INFO);