+ implemented leb and sleb relocations to data symbols

This commit is contained in:
Nikolay Nikolov 2021-09-26 02:23:31 +03:00
parent 67cbb7032e
commit b913133152
3 changed files with 204 additions and 19 deletions

View File

@ -114,6 +114,8 @@ interface
{$endif z80}
{$ifdef WASM32}
RELOC_FUNCTION_INDEX_LEB,
RELOC_MEMORY_ADDR_LEB,
RELOC_MEMORY_ADDR_SLEB,
{$endif WASM32}
{ Relative relocation }
RELOC_RELATIVE,

View File

@ -116,7 +116,6 @@ 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);
@ -153,6 +152,120 @@ implementation
uses
verbose;
procedure 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 WriteUleb5(d: tobjsection; 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 WriteSleb5(d: tdynamicarray; v: int64);
var
b: byte;
i: Integer;
begin
for i:=1 to 5 do
begin
b:=byte(v) and 127;
v:=SarInt64(v,7);
if i<>5 then
b:=b or 128;
d.write(b,1);
end;
end;
procedure WriteSleb5(d: tobjsection; v: int64);
var
b: byte;
i: Integer;
begin
for i:=1 to 5 do
begin
b:=byte(v) and 127;
v:=SarInt64(v,7);
if i<>5 then
b:=b or 128;
d.write(b,1);
end;
end;
function ReadUleb(d: tdynamicarray): uint64;
var
b: byte;
shift:integer;
begin
result:=0;
shift:=0;
repeat
d.read(b,1);
result:=result or (uint64(b and 127) shl shift);
inc(shift,7);
until (b and 128)=0;
end;
function ReadSleb(d: tdynamicarray): int64;
var
b: byte;
shift:integer;
begin
result:=0;
shift:=0;
repeat
d.read(b,1);
result:=result or (uint64(b and 127) shl shift);
inc(shift,7);
until (b and 128)=0;
if (b and 64)<>0 then
result:=result or (high(uint64) shl shift);
end;
procedure AddSleb5(d: tdynamicarray; v: int64);
var
q: Int64;
p: LongWord;
begin
p:=d.Pos;
q:=ReadSleb(d);
q:=q+v;
d.seek(p);
WriteSleb5(d,q);
end;
procedure AddUleb5(d: tdynamicarray; v: int64);
var
q: UInt64;
p: LongWord;
begin
p:=d.Pos;
q:=ReadUleb(d);
q:=q+v;
d.seek(p);
WriteUleb5(d,q);
end;
{****************************************************************************
TWasmObjSymbol
****************************************************************************}
@ -406,6 +519,22 @@ implementation
CurrObjSec.ObjRelocations.Add(objreloc);
writebytes(leb_zero,5);
end;
RELOC_MEMORY_ADDR_LEB,
RELOC_MEMORY_ADDR_SLEB:
begin
if (Reloctype=RELOC_MEMORY_ADDR_LEB) and (Data<0) then
internalerror(2021092602);
if len<>5 then
internalerror(2021092503);
if not assigned(p) then
internalerror(2021092504);
objreloc:=TWasmObjRelocation.CreateSymbol(CurrObjSec.Size,p,Reloctype);
CurrObjSec.ObjRelocations.Add(objreloc);
if RelocType=RELOC_MEMORY_ADDR_LEB then
WriteUleb5(CurrObjSec,Data)
else
WriteSleb5(CurrObjSec,Data);
end;
RELOC_ABSOLUTE:
begin
{ todo... }
@ -500,21 +629,6 @@ 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;
@ -738,6 +852,26 @@ implementation
objsec.Data.seek(objrel.DataOffset);
WriteUleb5(objsec.Data,TWasmObjSymbol(objrel.symbol).ImportOrFuncIndex);
end;
RELOC_MEMORY_ADDR_SLEB:
begin
if not assigned(objrel.symbol) then
internalerror(2021092605);
if objrel.symbol.bind<>AB_EXTERNAL then
begin
objsec.Data.seek(objrel.DataOffset);
AddSleb5(objsec.Data,objrel.symbol.offset+TWasmObjSection(objrel.symbol.objsection).SegOfs);
end;
end;
RELOC_MEMORY_ADDR_LEB:
begin
if not assigned(objrel.symbol) then
internalerror(2021092606);
if objrel.symbol.bind<>AB_EXTERNAL then
begin
objsec.Data.seek(objrel.DataOffset);
AddUleb5(objsec.Data,objrel.symbol.offset+TWasmObjSection(objrel.symbol.objsection).SegOfs);
end;
end;
else
internalerror(2021092510);
end;
@ -779,6 +913,26 @@ implementation
WriteUleb(relout,objrel.DataOffset+objsec.FileSectionOfs);
WriteUleb(relout,TWasmObjSymbol(objrel.symbol).SymbolIndex);
end;
RELOC_MEMORY_ADDR_LEB:
begin
if not assigned(objrel.symbol) then
internalerror(2021092603);
Inc(relcount^);
WriteByte(relout,Ord(R_WASM_MEMORY_ADDR_LEB));
WriteUleb(relout,objrel.DataOffset+objsec.FileSectionOfs);
WriteUleb(relout,TWasmObjSymbol(objrel.symbol).SymbolIndex);
WriteUleb(relout,0); { addend to add to the address }
end;
RELOC_MEMORY_ADDR_SLEB:
begin
if not assigned(objrel.symbol) then
internalerror(2021092604);
Inc(relcount^);
WriteByte(relout,Ord(R_WASM_MEMORY_ADDR_SLEB));
WriteUleb(relout,objrel.DataOffset+objsec.FileSectionOfs);
WriteUleb(relout,TWasmObjSymbol(objrel.symbol).SymbolIndex);
WriteUleb(relout,0); { addend to add to the address }
end;
else
internalerror(2021092507);
end;
@ -940,7 +1094,7 @@ implementation
WriteUleb(FWasmSymbolTable,objsym.FuncIndex);
WriteName(FWasmSymbolTable,objsym.Name);
end
else if objsym.typ=AT_DATA then
else if (objsym.typ=AT_DATA) or ((objsym.typ=AT_NONE) and (objsym.bind=AB_EXTERNAL)) then
begin
objsym.SymbolIndex:=FWasmSymbolTableEntriesCount;
Inc(FWasmSymbolTableEntriesCount);

View File

@ -535,6 +535,17 @@ implementation
internalerror(2021092001);
with oper[0]^ do
case typ of
top_ref:
begin
if assigned(ref^.symbol) then
result:=6
else
begin
if assigned(ref^.symbol) or (ref^.base<>NR_NO) or (ref^.index<>NR_NO) then
internalerror(2021092018);
result:=1+SlebSize(ref^.offset);
end;
end;
top_const:
result:=1+SlebSize(val);
else
@ -607,7 +618,11 @@ implementation
top_ref:
begin
if assigned(ref^.symbol) then
Writeln('Warning! Not implemented opcode, pass1: ', opcode, ' symbol ', ref^.symbol.Name, '+', ref^.offset)
begin
Result:=1+
UlebSize(2)+ { alignment: 1 shl 2 }
5; { relocation, fixed size = 5 bytes }
end
else
begin
if assigned(ref^.symbol) or (ref^.base<>NR_NO) or (ref^.index<>NR_NO) then
@ -977,6 +992,17 @@ implementation
internalerror(2021092001);
with oper[0]^ do
case typ of
top_ref:
begin
if assigned(ref^.symbol) then
objdata.writeReloc(ref^.offset,5,ObjData.symbolref(ref^.symbol),RELOC_MEMORY_ADDR_SLEB)
else
begin
if assigned(ref^.symbol) or (ref^.base<>NR_NO) or (ref^.index<>NR_NO) then
internalerror(2021092018);
WriteSleb(ref^.offset);
end;
end;
top_const:
WriteSleb(val);
else
@ -1076,7 +1102,10 @@ implementation
top_ref:
begin
if assigned(ref^.symbol) then
Writeln('Warning! Not implemented opcode, pass1: ', opcode, ' symbol ', ref^.symbol.Name, '+', ref^.offset)
begin
WriteUleb(2); { alignment: 1 shl 2 }
objdata.writeReloc(ref^.offset,5,ObjData.symbolref(ref^.symbol),RELOC_MEMORY_ADDR_LEB);
end
else
begin
if assigned(ref^.symbol) or (ref^.base<>NR_NO) or (ref^.index<>NR_NO) then