+ write the data section in the wasm internal linker exe writer

This commit is contained in:
Nikolay Nikolov 2024-01-01 15:58:17 +02:00
parent 1e89579766
commit 12d7d271d6

View File

@ -191,7 +191,6 @@ interface
FWasmLinkingSubsections: array [low(TWasmLinkingSubsectionType)..high(TWasmLinkingSubsectionType)] of tdynamicarray;
procedure WriteWasmSection(wsid: TWasmSectionID);
procedure WriteWasmCustomSection(wcst: TWasmCustomSectionType);
procedure WriteZeros(dest: tdynamicarray; size: QWord);
function IsExternalFunction(sym: TObjSymbol): Boolean;
function IsExportedFunction(sym: TWasmObjSymbol): Boolean;
procedure WriteFunctionLocals(dest: tdynamicarray; ed: TWasmObjSymbolExtraData);
@ -497,6 +496,24 @@ implementation
end;
end;
procedure WriteZeros(dest: tdynamicarray; size: QWord);
var
buf : array[0..1023] of byte;
bs: Integer;
begin
fillchar(buf,sizeof(buf),0);
while size>0 do
begin
if size<SizeOf(buf) then
bs:=Integer(size)
else
bs:=SizeOf(buf);
dest.write(buf,bs);
dec(size,bs);
end;
end;
{****************************************************************************
TWasmObjSymbolLinkingData
****************************************************************************}
@ -1091,23 +1108,6 @@ implementation
Writer.writearray(FWasmCustomSections[wcst]);
end;
procedure TWasmObjOutput.WriteZeros(dest: tdynamicarray; size: QWord);
var
buf : array[0..1023] of byte;
bs: Integer;
begin
fillchar(buf,sizeof(buf),0);
while size>0 do
begin
if size<SizeOf(buf) then
bs:=Integer(size)
else
bs:=SizeOf(buf);
dest.write(buf,bs);
dec(size,bs);
end;
end;
function TWasmObjOutput.IsExternalFunction(sym: TObjSymbol): Boolean;
var
ExtraData: TWasmObjSymbolExtraData;
@ -4138,12 +4138,63 @@ implementation
end;
end;
procedure WriteDataSegments;
procedure WriteExeSection(exesec: TExeSection);
var
i: Integer;
objsec: TObjSection;
exesecdatapos: LongWord;
dpos, pad: QWord;
begin
WriteByte(FWasmSections[wsiData],0);
WriteByte(FWasmSections[wsiData],$41); { i32.const }
WriteSleb(FWasmSections[wsiData],longint(exesec.MemPos));
WriteByte(FWasmSections[wsiData],$0B); { end }
WriteUleb(FWasmSections[wsiData],exesec.Size);
exesecdatapos:=FWasmSections[wsiData].size;
for i:=0 to exesec.ObjSectionList.Count-1 do
begin
objsec:=TObjSection(exesec.ObjSectionList[i]);
if not (oso_data in objsec.secoptions) then
internalerror(2024010104);
if not assigned(objsec.data) then
internalerror(2024010105);
dpos:=objsec.MemPos-exesec.MemPos+exesecdatapos;
pad:=dpos-FWasmSections[wsiData].size;
{ objsection must be within SecAlign bytes from the previous one }
if (dpos<FWasmSections[wsiData].Size) or
(pad>=max(objsec.SecAlign,1)) then
internalerror(2024010106);
writeZeros(FWasmSections[wsiData],pad);
objsec.data.seek(0);
CopyDynamicArray(objsec.data,FWasmSections[wsiData],objsec.data.size);
end;
if (FWasmSections[wsiData].size-exesecdatapos)<>exesec.Size then
internalerror(2024010107);
end;
var
DataCount: Integer;
begin
DataCount:=2;
WriteUleb(FWasmSections[wsiDataCount],DataCount);
WriteUleb(FWasmSections[wsiData],DataCount);
WriteExeSection(FindExeSection('.rodata'));
WriteExeSection(FindExeSection('.data'));
end;
begin
result:=false;
FFuncTypes.WriteTo(FWasmSections[wsiType]);
WriteImportSection;
WriteCodeSegments;
WriteDataSegments;
WriteUleb(FWasmSections[wsiMemory],1);
WriteByte(FWasmSections[wsiMemory],0);
@ -4157,7 +4208,9 @@ implementation
WriteWasmSection(wsiImport);
WriteWasmSection(wsiFunction);
WriteWasmSection(wsiMemory);
WriteWasmSection(wsiDataCount);
WriteWasmSection(wsiCode);
WriteWasmSection(wsiData);
result := true;
end;