From bbb564437d88a8843f1769ce773c79c6ae0ed3c3 Mon Sep 17 00:00:00 2001 From: Nikolay Nikolov Date: Tue, 26 Dec 2023 17:42:01 +0200 Subject: [PATCH] + parse the data section in the wasm object reader --- compiler/ogwasm.pas | 151 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 149 insertions(+), 2 deletions(-) diff --git a/compiler/ogwasm.pas b/compiler/ogwasm.pas index ff0e9a4b80..fce2daa0c0 100644 --- a/compiler/ogwasm.pas +++ b/compiler/ogwasm.pas @@ -2201,6 +2201,56 @@ implementation result:=true; end; + function ReadSleb(out v: int64): boolean; + var + b: byte; + shift:integer; + begin + result:=false; + b:=0; + v:=0; + shift:=0; + repeat + if not read(b,1) then + exit; + v:=v or (uint64(b and 127) shl shift); + inc(shift,7); + until (b and 128)=0; +{$ifopt Q+} +{$define overflowon} +{$Q-} +{$endif} +{$ifopt R+} +{$define rangeon} +{$R-} +{$endif} + if (b and 64)<>0 then + v:=v or (high(uint64) shl shift); + result:=true; + end; +{$ifdef overflowon} +{$Q+} +{$undef overflowon} +{$endif} +{$ifdef rangeon} +{$R+} +{$undef rangeon} +{$endif} + + function ReadSleb32(out v: int32): boolean; + var + vv: int64; + begin + result:=false; + v:=default(int32); + if not ReadSleb(vv) then + exit; + if (vv>high(int32)) or (vv$41 then + begin + InputError('Only i32.const expressions supported'); + exit; + end; + if not ReadSleb32(ExprV) then + exit; + if not Read(b,1) then + exit; + if b<>$0B then + begin + InputError('Only single const expressions supported'); + exit; + end; + Result:=True; + end; + var DataCount: uint32; + DataType: Byte; + i: Integer; begin Result:=False; if DataSectionRead then @@ -2751,11 +2833,71 @@ implementation if Length(DataSegments)<>DataCount then begin InputError('Data entries count in the data section do not match the number, specified in the data count section'); - exit + exit; end; end else SetLength(DataSegments,DataCount); + for i:=0 to DataCount-1 do + with DataSegments[i] do + begin + if not read(DataType, 1) then + begin + InputError('Error reading data type of segment from the data section'); + exit; + end; + case DataType of + 0: + begin + Active:=True; + MemIdx:=0; + if not ReadExpr(Offset) then + begin + InputError('Error reading memory offset of segment from the data section'); + exit; + end; + end; + 1: + Active:=False; + 2: + begin + Active:=True; + if not ReadUleb32(MemIdx) then + begin + InputError('Error reading MemIdx of segment from the data section'); + exit; + end; + if not ReadExpr(Offset) then + begin + InputError('Error reading memory offset of segment from the data section'); + exit; + end; + end; + else + begin + InputError('Unsupported data type of segment in the data section: ' + tostr(DataType)); + exit; + end; + end; + if not ReadUleb32(Len) then + begin + InputError('Error reading data segment length'); + exit; + end; + if (AReader.Pos+Len)>(SectionStart+SectionSize) then + begin + InputError('Data segment exceeds the bounds of the data section'); + exit; + end; + DataPos:=AReader.Pos; + AReader.Seek(AReader.Pos+Len); + end; + if AReader.Pos<>(SectionStart+SectionSize) then + begin + InputError('Unexpected data section size'); + exit; + end; + Result:=true; end; function ReadDataCountSection: Boolean; @@ -2840,7 +2982,11 @@ implementation Byte(wsiCode): Result := ReadCodeSection; Byte(wsiData): - Result := ReadDataSection; + if not ReadDataSection then + begin + InputError('Error reading the data section'); + exit; + end; Byte(wsiDataCount): begin if not ReadDataCountSection then @@ -2948,3 +3094,4 @@ initialization RegisterAssembler(as_wasm32_wasm_info,TWasmAssembler); {$endif wasm32} end. +