mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-06 22:50:14 +02:00
+ implemented leb and sleb relocations to data symbols
This commit is contained in:
parent
67cbb7032e
commit
b913133152
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user