mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-08 09:23:48 +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}
|
{$endif z80}
|
||||||
{$ifdef WASM32}
|
{$ifdef WASM32}
|
||||||
RELOC_FUNCTION_INDEX_LEB,
|
RELOC_FUNCTION_INDEX_LEB,
|
||||||
|
RELOC_MEMORY_ADDR_LEB,
|
||||||
|
RELOC_MEMORY_ADDR_SLEB,
|
||||||
{$endif WASM32}
|
{$endif WASM32}
|
||||||
{ Relative relocation }
|
{ Relative relocation }
|
||||||
RELOC_RELATIVE,
|
RELOC_RELATIVE,
|
||||||
|
@ -116,7 +116,6 @@ interface
|
|||||||
FWasmLinkingSubsections: array [low(TWasmLinkingSubsectionType)..high(TWasmLinkingSubsectionType)] 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 WriteUleb5(d: tdynamicarray; v: uint64);
|
|
||||||
procedure WriteSleb(d: tdynamicarray; v: int64);
|
procedure WriteSleb(d: tdynamicarray; v: int64);
|
||||||
procedure WriteByte(d: tdynamicarray; b: byte);
|
procedure WriteByte(d: tdynamicarray; b: byte);
|
||||||
procedure WriteName(d: tdynamicarray; const s: string);
|
procedure WriteName(d: tdynamicarray; const s: string);
|
||||||
@ -153,6 +152,120 @@ implementation
|
|||||||
uses
|
uses
|
||||||
verbose;
|
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
|
TWasmObjSymbol
|
||||||
****************************************************************************}
|
****************************************************************************}
|
||||||
@ -406,6 +519,22 @@ implementation
|
|||||||
CurrObjSec.ObjRelocations.Add(objreloc);
|
CurrObjSec.ObjRelocations.Add(objreloc);
|
||||||
writebytes(leb_zero,5);
|
writebytes(leb_zero,5);
|
||||||
end;
|
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:
|
RELOC_ABSOLUTE:
|
||||||
begin
|
begin
|
||||||
{ todo... }
|
{ todo... }
|
||||||
@ -500,21 +629,6 @@ implementation
|
|||||||
until v=0;
|
until v=0;
|
||||||
end;
|
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);
|
procedure TWasmObjOutput.WriteSleb(d: tdynamicarray; v: int64);
|
||||||
var
|
var
|
||||||
b: byte;
|
b: byte;
|
||||||
@ -738,6 +852,26 @@ implementation
|
|||||||
objsec.Data.seek(objrel.DataOffset);
|
objsec.Data.seek(objrel.DataOffset);
|
||||||
WriteUleb5(objsec.Data,TWasmObjSymbol(objrel.symbol).ImportOrFuncIndex);
|
WriteUleb5(objsec.Data,TWasmObjSymbol(objrel.symbol).ImportOrFuncIndex);
|
||||||
end;
|
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
|
else
|
||||||
internalerror(2021092510);
|
internalerror(2021092510);
|
||||||
end;
|
end;
|
||||||
@ -779,6 +913,26 @@ implementation
|
|||||||
WriteUleb(relout,objrel.DataOffset+objsec.FileSectionOfs);
|
WriteUleb(relout,objrel.DataOffset+objsec.FileSectionOfs);
|
||||||
WriteUleb(relout,TWasmObjSymbol(objrel.symbol).SymbolIndex);
|
WriteUleb(relout,TWasmObjSymbol(objrel.symbol).SymbolIndex);
|
||||||
end;
|
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
|
else
|
||||||
internalerror(2021092507);
|
internalerror(2021092507);
|
||||||
end;
|
end;
|
||||||
@ -940,7 +1094,7 @@ implementation
|
|||||||
WriteUleb(FWasmSymbolTable,objsym.FuncIndex);
|
WriteUleb(FWasmSymbolTable,objsym.FuncIndex);
|
||||||
WriteName(FWasmSymbolTable,objsym.Name);
|
WriteName(FWasmSymbolTable,objsym.Name);
|
||||||
end
|
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
|
begin
|
||||||
objsym.SymbolIndex:=FWasmSymbolTableEntriesCount;
|
objsym.SymbolIndex:=FWasmSymbolTableEntriesCount;
|
||||||
Inc(FWasmSymbolTableEntriesCount);
|
Inc(FWasmSymbolTableEntriesCount);
|
||||||
|
@ -535,6 +535,17 @@ implementation
|
|||||||
internalerror(2021092001);
|
internalerror(2021092001);
|
||||||
with oper[0]^ do
|
with oper[0]^ do
|
||||||
case typ of
|
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:
|
top_const:
|
||||||
result:=1+SlebSize(val);
|
result:=1+SlebSize(val);
|
||||||
else
|
else
|
||||||
@ -607,7 +618,11 @@ implementation
|
|||||||
top_ref:
|
top_ref:
|
||||||
begin
|
begin
|
||||||
if assigned(ref^.symbol) then
|
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
|
else
|
||||||
begin
|
begin
|
||||||
if assigned(ref^.symbol) or (ref^.base<>NR_NO) or (ref^.index<>NR_NO) then
|
if assigned(ref^.symbol) or (ref^.base<>NR_NO) or (ref^.index<>NR_NO) then
|
||||||
@ -977,6 +992,17 @@ implementation
|
|||||||
internalerror(2021092001);
|
internalerror(2021092001);
|
||||||
with oper[0]^ do
|
with oper[0]^ do
|
||||||
case typ of
|
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:
|
top_const:
|
||||||
WriteSleb(val);
|
WriteSleb(val);
|
||||||
else
|
else
|
||||||
@ -1076,7 +1102,10 @@ implementation
|
|||||||
top_ref:
|
top_ref:
|
||||||
begin
|
begin
|
||||||
if assigned(ref^.symbol) then
|
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
|
else
|
||||||
begin
|
begin
|
||||||
if assigned(ref^.symbol) or (ref^.base<>NR_NO) or (ref^.index<>NR_NO) then
|
if assigned(ref^.symbol) or (ref^.base<>NR_NO) or (ref^.index<>NR_NO) then
|
||||||
|
Loading…
Reference in New Issue
Block a user