mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-03 18:10:17 +02:00
+ parse the data section in the wasm object reader
This commit is contained in:
parent
818b6e6983
commit
bbb564437d
@ -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<low(int32)) then
|
||||
exit;
|
||||
v:=vv;
|
||||
result:=true;
|
||||
end;
|
||||
|
||||
function ReadName(out v: ansistring): boolean;
|
||||
var
|
||||
len: uint32;
|
||||
@ -2224,6 +2274,11 @@ implementation
|
||||
DataCountSectionRead: Boolean = false;
|
||||
|
||||
DataSegments: array of record
|
||||
Active: Boolean;
|
||||
MemIdx: uint32;
|
||||
Len: uint32;
|
||||
Offset: int32;
|
||||
DataPos: LongInt;
|
||||
end;
|
||||
|
||||
function ReadCustomSection: Boolean;
|
||||
@ -2731,8 +2786,35 @@ implementation
|
||||
end;
|
||||
|
||||
function ReadDataSection: Boolean;
|
||||
|
||||
function ReadExpr(out ExprV: int32): Boolean;
|
||||
var
|
||||
b: Byte;
|
||||
begin
|
||||
Result:=False;
|
||||
if not Read(b,1) then
|
||||
exit;
|
||||
if b<>$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.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user