dotnet8.0/runtime-92274-webcil-s390x....

261 lines
13 KiB
Diff

From 72f310a6c3dccbabf9edc29677b51ed78c87cc67 Mon Sep 17 00:00:00 2001
From: Sanjam Panda <sanjam.panda@ibm.com>
Date: Tue, 19 Sep 2023 15:16:02 +0200
Subject: [PATCH 1/3] [wasm] Endian fix for Webcil
'dotnet new blazorwasm' command failed on s390x and was throwing a not implemented exception
The issue was with with the WebCil writer and reader, specific endianness conversions relating to the webcil payload were not implemented for big endian machines.
We considered fixing the generic implementation, but there were only two structures in use: WebcilHeader and WebcilSectionHeader, so it was easier to handle them explicitly.
---
.../Microsoft.NET.WebAssembly.Webcil.csproj | 1 +
.../WebcilConverter.cs | 35 +++++++++++++-----
.../WebcilReader.cs | 37 +++++++++++++++----
3 files changed, 57 insertions(+), 16 deletions(-)
diff --git a/src/runtime/src/tasks/Microsoft.NET.WebAssembly.Webcil/Microsoft.NET.WebAssembly.Webcil.csproj b/src/runtime/src/tasks/Microsoft.NET.WebAssembly.Webcil/Microsoft.NET.WebAssembly.Webcil.csproj
index c35eb57e80686..d09ae4a569a59 100644
--- a/src/runtime/src/tasks/Microsoft.NET.WebAssembly.Webcil/Microsoft.NET.WebAssembly.Webcil.csproj
+++ b/src/runtime/src/tasks/Microsoft.NET.WebAssembly.Webcil/Microsoft.NET.WebAssembly.Webcil.csproj
@@ -16,6 +16,7 @@
<ItemGroup>
<!-- we need to keep the version of System.Reflection.Metadata in sync with dotnet/msbuild and dotnet/sdk -->
+ <PackageReference Include="System.Memory" Version="$(SystemMemoryVersion)" />
<PackageReference Include="System.Reflection.Metadata" Version="$(SystemReflectionMetadataVersion)" />
<PackageReference Include="System.Collections.Immutable" Version="$(SystemCollectionsImmutableVersion)" />
</ItemGroup>
diff --git a/src/runtime/src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilConverter.cs b/src/runtime/src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilConverter.cs
index a38af7270a2da..7b882c42d579e 100644
--- a/src/runtime/src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilConverter.cs
+++ b/src/runtime/src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilConverter.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System;
+using System.Buffers.Binary;
using System.IO;
using System.Collections.Immutable;
using System.Reflection.PortableExecutable;
@@ -181,9 +182,6 @@ private static void WriteHeader(Stream s, WebcilHeader header)
private static void WriteSectionHeaders(Stream s, ImmutableArray<WebcilSectionHeader> sectionsHeaders)
{
- // FIXME: fixup endianness
- if (!BitConverter.IsLittleEndian)
- throw new NotImplementedException();
foreach (var sectionHeader in sectionsHeaders)
{
WriteSectionHeader(s, sectionHeader);
@@ -192,16 +190,38 @@ private static void WriteSectionHeaders(Stream s, ImmutableArray<WebcilSectionHe
private static void WriteSectionHeader(Stream s, WebcilSectionHeader sectionHeader)
{
+ if (!BitConverter.IsLittleEndian)
+ {
+ sectionHeader = new WebcilSectionHeader
+ (
+ virtualSize: BinaryPrimitives.ReverseEndianness(sectionHeader.VirtualSize),
+ virtualAddress: BinaryPrimitives.ReverseEndianness(sectionHeader.VirtualAddress),
+ sizeOfRawData: BinaryPrimitives.ReverseEndianness(sectionHeader.SizeOfRawData),
+ pointerToRawData: BinaryPrimitives.ReverseEndianness(sectionHeader.PointerToRawData)
+ );
+ }
WriteStructure(s, sectionHeader);
}
+ private static void WriteStructure(Stream s, WebcilHeader webcilHeader)
+ {
+ if (!BitConverter.IsLittleEndian)
+ {
+ webcilHeader.version_major = BinaryPrimitives.ReverseEndianness(webcilHeader.version_major);
+ webcilHeader.version_minor = BinaryPrimitives.ReverseEndianness(webcilHeader.version_minor);
+ webcilHeader.coff_sections = BinaryPrimitives.ReverseEndianness(webcilHeader.coff_sections);
+ webcilHeader.pe_cli_header_rva = BinaryPrimitives.ReverseEndianness(webcilHeader.pe_cli_header_rva);
+ webcilHeader.pe_cli_header_size = BinaryPrimitives.ReverseEndianness(webcilHeader.pe_cli_header_size);
+ webcilHeader.pe_debug_rva = BinaryPrimitives.ReverseEndianness(webcilHeader.pe_debug_rva);
+ webcilHeader.pe_debug_size = BinaryPrimitives.ReverseEndianness(webcilHeader.pe_debug_size);
+ }
+ WriteStructure(s, webcilHeader);
+ }
+
#if NETCOREAPP2_1_OR_GREATER
private static void WriteStructure<T>(Stream s, T structure)
where T : unmanaged
{
- // FIXME: fixup endianness
- if (!BitConverter.IsLittleEndian)
- throw new NotImplementedException();
unsafe
{
byte* p = (byte*)&structure;
@@ -212,9 +232,6 @@ private static void WriteStructure<T>(Stream s, T structure)
private static void WriteStructure<T>(Stream s, T structure)
where T : unmanaged
{
- // FIXME: fixup endianness
- if (!BitConverter.IsLittleEndian)
- throw new NotImplementedException();
int size = Marshal.SizeOf<T>();
byte[] buffer = new byte[size];
IntPtr ptr = IntPtr.Zero;
diff --git a/src/runtime/src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilReader.cs b/src/runtime/src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilReader.cs
index 4f42f82798664..ac4f9d86095a9 100644
--- a/src/runtime/src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilReader.cs
+++ b/src/runtime/src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilReader.cs
@@ -6,7 +6,7 @@
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
-
+using System.Buffers.Binary;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
@@ -63,14 +63,20 @@ private unsafe bool ReadHeader()
{
return false;
}
- if (!BitConverter.IsLittleEndian)
- {
- throw new NotImplementedException("TODO: implement big endian support");
- }
fixed (byte* p = buffer)
{
header = *(WebcilHeader*)p;
}
+ if (!BitConverter.IsLittleEndian)
+ {
+ header.version_major = BinaryPrimitives.ReverseEndianness(header.version_major);
+ header.version_minor = BinaryPrimitives.ReverseEndianness(header.version_minor);
+ header.coff_sections = BinaryPrimitives.ReverseEndianness(header.coff_sections);
+ header.pe_cli_header_rva = BinaryPrimitives.ReverseEndianness(header.pe_cli_header_rva);
+ header.pe_cli_header_size = BinaryPrimitives.ReverseEndianness(header.pe_cli_header_size);
+ header.pe_debug_rva = BinaryPrimitives.ReverseEndianness(header.pe_debug_rva);
+ header.pe_debug_rva = BinaryPrimitives.ReverseEndianness(header.pe_debug_size);
+ }
if (header.id[0] != 'W' || header.id[1] != 'b'
|| header.id[2] != 'I' || header.id[3] != 'L'
|| header.version_major != Internal.Constants.WC_VERSION_MAJOR
@@ -346,6 +352,7 @@ private long TranslateRVA(uint rva)
private unsafe ImmutableArray<WebcilSectionHeader> ReadSections()
{
+ WebcilSectionHeader secheader;
var sections = ImmutableArray.CreateBuilder<WebcilSectionHeader>(_header.coff_sections);
var buffer = new byte[Marshal.SizeOf<WebcilSectionHeader>()];
_stream.Seek(SectionDirectoryOffset + _webcilInWasmOffset, SeekOrigin.Begin);
@@ -357,8 +364,24 @@ private unsafe ImmutableArray<WebcilSectionHeader> ReadSections()
}
fixed (byte* p = buffer)
{
- // FIXME endianness
- sections.Add(*(WebcilSectionHeader*)p);
+ secheader = (*(WebcilSectionHeader*)p);
+ }
+ if (!BitConverter.IsLittleEndian)
+ {
+ sections.Add
+ (
+ new WebcilSectionHeader
+ (
+ virtualSize: BinaryPrimitives.ReverseEndianness(secheader.VirtualSize),
+ virtualAddress: BinaryPrimitives.ReverseEndianness(secheader.VirtualAddress),
+ sizeOfRawData: BinaryPrimitives.ReverseEndianness(secheader.SizeOfRawData),
+ pointerToRawData: BinaryPrimitives.ReverseEndianness(secheader.PointerToRawData)
+ )
+ );
+ }
+ else
+ {
+ sections.Add(secheader);
}
}
return sections.MoveToImmutable();
From 0c78184347335db183a38cf6bd26e2fe69160931 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Aleksey=20Kliger=20=28=CE=BBgeek=29?= <alklig@microsoft.com>
Date: Thu, 21 Sep 2023 14:31:12 -0400
Subject: [PATCH 2/3] Fix infinite recursion
---
.../WebcilConverter.cs | 25 ++++++++-----------
1 file changed, 10 insertions(+), 15 deletions(-)
diff --git a/src/runtime/src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilConverter.cs b/src/runtime/src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilConverter.cs
index 7b882c42d579e..fc95eded5bc33 100644
--- a/src/runtime/src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilConverter.cs
+++ b/src/runtime/src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilConverter.cs
@@ -177,6 +177,16 @@ public unsafe void GatherInfo(PEReader peReader, out WCFileInfo wcInfo, out PEFi
private static void WriteHeader(Stream s, WebcilHeader header)
{
+ if (!BitConverter.IsLittleEndian)
+ {
+ webcilHeader.version_major = BinaryPrimitives.ReverseEndianness(webcilHeader.version_major);
+ webcilHeader.version_minor = BinaryPrimitives.ReverseEndianness(webcilHeader.version_minor);
+ webcilHeader.coff_sections = BinaryPrimitives.ReverseEndianness(webcilHeader.coff_sections);
+ webcilHeader.pe_cli_header_rva = BinaryPrimitives.ReverseEndianness(webcilHeader.pe_cli_header_rva);
+ webcilHeader.pe_cli_header_size = BinaryPrimitives.ReverseEndianness(webcilHeader.pe_cli_header_size);
+ webcilHeader.pe_debug_rva = BinaryPrimitives.ReverseEndianness(webcilHeader.pe_debug_rva);
+ webcilHeader.pe_debug_size = BinaryPrimitives.ReverseEndianness(webcilHeader.pe_debug_size);
+ }
WriteStructure(s, header);
}
@@ -203,21 +213,6 @@ private static void WriteSectionHeader(Stream s, WebcilSectionHeader sectionHead
WriteStructure(s, sectionHeader);
}
- private static void WriteStructure(Stream s, WebcilHeader webcilHeader)
- {
- if (!BitConverter.IsLittleEndian)
- {
- webcilHeader.version_major = BinaryPrimitives.ReverseEndianness(webcilHeader.version_major);
- webcilHeader.version_minor = BinaryPrimitives.ReverseEndianness(webcilHeader.version_minor);
- webcilHeader.coff_sections = BinaryPrimitives.ReverseEndianness(webcilHeader.coff_sections);
- webcilHeader.pe_cli_header_rva = BinaryPrimitives.ReverseEndianness(webcilHeader.pe_cli_header_rva);
- webcilHeader.pe_cli_header_size = BinaryPrimitives.ReverseEndianness(webcilHeader.pe_cli_header_size);
- webcilHeader.pe_debug_rva = BinaryPrimitives.ReverseEndianness(webcilHeader.pe_debug_rva);
- webcilHeader.pe_debug_size = BinaryPrimitives.ReverseEndianness(webcilHeader.pe_debug_size);
- }
- WriteStructure(s, webcilHeader);
- }
-
#if NETCOREAPP2_1_OR_GREATER
private static void WriteStructure<T>(Stream s, T structure)
where T : unmanaged
From cecf4f09f0c52340c753811098f0f2d9593049aa Mon Sep 17 00:00:00 2001
From: Aleksey Kliger <alklig@microsoft.com>
Date: Thu, 21 Sep 2023 14:36:20 -0400
Subject: [PATCH 3/3] rename var
---
src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilConverter.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/runtime/src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilConverter.cs b/src/runtime/src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilConverter.cs
index fc95eded5bc33..13c34bde4b8ea 100644
--- a/src/runtime/src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilConverter.cs
+++ b/src/runtime/src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilConverter.cs
@@ -175,7 +175,7 @@ public unsafe void GatherInfo(PEReader peReader, out WCFileInfo wcInfo, out PEFi
SectionStart: firstWCSection);
}
- private static void WriteHeader(Stream s, WebcilHeader header)
+ private static void WriteHeader(Stream s, WebcilHeader webcilHeader)
{
if (!BitConverter.IsLittleEndian)
{
@@ -187,7 +187,7 @@ private static void WriteHeader(Stream s, WebcilHeader header)
webcilHeader.pe_debug_rva = BinaryPrimitives.ReverseEndianness(webcilHeader.pe_debug_rva);
webcilHeader.pe_debug_size = BinaryPrimitives.ReverseEndianness(webcilHeader.pe_debug_size);
}
- WriteStructure(s, header);
+ WriteStructure(s, webcilHeader);
}
private static void WriteSectionHeaders(Stream s, ImmutableArray<WebcilSectionHeader> sectionsHeaders)