Browse Source

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

Nikolay Nikolov 1 year ago
parent
commit
12d7d271d6
1 changed files with 71 additions and 18 deletions
  1. 71 18
      compiler/ogwasm.pas

+ 71 - 18
compiler/ogwasm.pas

@@ -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;