From b913133152b08d8c823dee93425285955d5d34bf Mon Sep 17 00:00:00 2001 From: Nikolay Nikolov Date: Sun, 26 Sep 2021 02:23:31 +0300 Subject: [PATCH] + implemented leb and sleb relocations to data symbols --- compiler/ogbase.pas | 2 + compiler/ogwasm.pas | 188 ++++++++++++++++++++++++++++++++---- compiler/wasm32/aasmcpu.pas | 33 ++++++- 3 files changed, 204 insertions(+), 19 deletions(-) diff --git a/compiler/ogbase.pas b/compiler/ogbase.pas index 887dc58e8f..547b7b8063 100644 --- a/compiler/ogbase.pas +++ b/compiler/ogbase.pas @@ -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, diff --git a/compiler/ogwasm.pas b/compiler/ogwasm.pas index a9c2139011..068c8b3e4d 100644 --- a/compiler/ogwasm.pas +++ b/compiler/ogwasm.pas @@ -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); diff --git a/compiler/wasm32/aasmcpu.pas b/compiler/wasm32/aasmcpu.pas index 51b7efb0db..ddb878b710 100644 --- a/compiler/wasm32/aasmcpu.pas +++ b/compiler/wasm32/aasmcpu.pas @@ -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