Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[mono][wasm] Bundle assemblies as WebCIL #79416

Merged
merged 57 commits into from
Jan 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
c55c696
Implement WebCIL loader; on by default
lambdageek Dec 7, 2022
45bc3c9
Checkpoint works on wasm sample; add design doc
lambdageek Dec 8, 2022
c2739da
Remove unused fields
lambdageek Dec 8, 2022
c58670b
fixup markdown
lambdageek Dec 8, 2022
851ebde
remove unused var
lambdageek Dec 8, 2022
fa812be
specify FileAccess
lambdageek Dec 8, 2022
6a7b411
FileShare
lambdageek Dec 9, 2022
708368b
Push .dll->.webcil probing lower in the bundle logic
lambdageek Dec 9, 2022
509c219
Also convert satellite assemblies
lambdageek Dec 9, 2022
79d0770
satellite matching
lambdageek Dec 9, 2022
38ddc99
fixup asset entry
lambdageek Dec 9, 2022
91bbbce
[wasm] don't leak .webcil image names to the debugger
lambdageek Dec 19, 2022
c2650d2
fix one other PE file check
lambdageek Dec 20, 2022
b045d04
Add PE DebugTableDirectory to webcil
lambdageek Dec 22, 2022
7eb3231
fix windows build
lambdageek Dec 22, 2022
599500b
Implement a WebcilReader for BorwserDebugProxy like PEReader
lambdageek Dec 22, 2022
7d5aa77
REVERT ME: temporarily don't try to read codeview data for webcil
lambdageek Dec 22, 2022
68905aa
[debug] Match bundled pdbs if we're looking up .webcil files
lambdageek Dec 23, 2022
68da344
be less verbose
lambdageek Dec 23, 2022
1db11d1
Adjust debug directory entries when writing webcil files
lambdageek Dec 28, 2022
784f809
Fix bug in WebcilWriter
lambdageek Dec 29, 2022
111d398
bugfix: the debug directory is at pe_debug_rva not at the CLI header
lambdageek Dec 29, 2022
5541a3b
skip debug fixups if there's no debug directory
lambdageek Dec 29, 2022
c0bb6c6
WebcilReader: implement CodeView and Emebedded PPDB support
lambdageek Dec 29, 2022
e44841c
[WBT] Add UseWebcil option (default to true)
lambdageek Jan 3, 2023
96b6a1d
rename WebcilWriter -> WebcilConverter [NFC]
lambdageek Jan 3, 2023
2cd2c92
fixup AssemblyLoadedEventTest
lambdageek Jan 3, 2023
c3b7726
hack: no extension on assembly for breakpoint
lambdageek Jan 3, 2023
4f25760
pass normal .dll name for MainAssemblyName in config
lambdageek Jan 4, 2023
d82140f
Wasm.Debugger.Tests: give CI 10 more minutes
lambdageek Jan 6, 2023
c1d5169
Add Microsoft.NET.WebAssembly.Webcil assembly project
lambdageek Jan 6, 2023
3a07787
Move WebcilConverter to Microsoft.NET.WebAssembly.Webcil
lambdageek Jan 6, 2023
d507f64
Move WebcilReader to Microsoft.NET.WebAssembly.Webcil
lambdageek Jan 6, 2023
6c6cae5
make the webcil magic and version longer
lambdageek Jan 6, 2023
d9a4d25
fixups
lambdageek Jan 7, 2023
ac0404b
Code style improvements from review
lambdageek Jan 7, 2023
0cedacc
Improve some exception messages, when possible
lambdageek Jan 7, 2023
dadbf4a
Suggestings from code review
lambdageek Jan 9, 2023
73d57a4
Add WasmEnableWebcil msbuild property. Off by default
lambdageek Jan 11, 2023
f0f6340
Build non-wasm runtimes without .webcil support
lambdageek Jan 11, 2023
a2d4cbb
XXX HACK - Remove - turn on webcil by default on browser-wasm
lambdageek Jan 11, 2023
388dc2c
Run WBT twice: with and without webcil
lambdageek Jan 11, 2023
1abe30a
do the cartesian product correctly in msbuild
lambdageek Jan 13, 2023
29c5234
Revert "XXX HACK - Remove - turn on webcil by default on browser-wasm"
lambdageek Jan 13, 2023
3b6bef2
also add webcil to template projects
lambdageek Jan 17, 2023
4ab4f8f
environment variable has to be non-null and "true"
lambdageek Jan 17, 2023
5741cb8
Fix wasm work items
lambdageek Jan 17, 2023
61fef73
Update src/libraries/sendtohelix-wasm.targets
lambdageek Jan 18, 2023
81b8bce
FIXME: why is this crashing in MetadataLoadContext
lambdageek Jan 18, 2023
a795f9e
PInvokeTableGeneratorTests: don't try to use the net472 WasmAppBuilder
lambdageek Jan 18, 2023
0473ec1
PInvokeTableGeneratorTests: Add more diagnostic output if tasksDir is…
lambdageek Jan 18, 2023
56addec
nullability
lambdageek Jan 18, 2023
52b195a
simplify prefix comparison in bundled_assembly_match
lambdageek Jan 19, 2023
a176400
WasmAppBuilder improve logging
lambdageek Jan 19, 2023
67d64e3
Add missing using
lewing Jan 19, 2023
5983e65
XXX REVERT ME - temporarily disable dedup
lambdageek Jan 20, 2023
d7b3640
Revert "XXX REVERT ME - temporarily disable dedup"
lambdageek Jan 20, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions docs/design/mono/webcil.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# WebCIL assembly format

## Version

This is version 0.0 of the Webcil format.

## Motivation

When deploying the .NET runtime to the browser using WebAssembly, we have received some reports from
customers that certain users are unable to use their apps because firewalls and anti-virus software
may prevent browsers from downloading or caching assemblies with a .DLL extension and PE contents.

This document defines a new container format for ECMA-335 assemblies
that uses the `.webcil` extension and uses a new WebCIL container
format.


## Specification

As our starting point we take section II.25.1 "Structure of the
runtime file format" from ECMA-335 6th Edition.

| |
|--------|
| PE Headers |
| CLI Header |
| CLI Data |
| Native Image Sections |
| |



A Webcil file follows a similar structure


| |
|--------|
| Webcil Headers |
| CLI Header |
| CLI Data |
| |

## Webcil Headers

The Webcil headers consist of a Webcil header followed by a sequence of section headers.
(All multi-byte integers are in little endian format).

### Webcil Header

``` c
struct WebcilHeader {
uint8_t id[4]; // 'W' 'b' 'I' 'L'
// 4 bytes
uint16_t version_major; // 0
uint16_t version_minor; // 0
// 8 bytes
uint16_t coff_sections;
uint16_t reserved0; // 0
// 12 bytes

uint32_t pe_cli_header_rva;
uint32_t pe_cli_header_size;
// 20 bytes

uint32_t pe_debug_rva;
uint32_t pe_debug_size;
// 28 bytes
};
```

The Webcil header starts with the magic characters 'W' 'b' 'I' 'L' followed by the version in major
minor format (must be 0 and 0). Then a count of the section headers and two reserved bytes.

The next pairs of integers are a subset of the PE Header data directory specifying the RVA and size
of the CLI header, as well as the directory entry for the PE debug directory.


### Section header table

Immediately following the Webcil header is a sequence (whose length is given by `coff_sections`
above) of section headers giving their virtual address and virtual size, as well as the offset in
the Webcil file and the size in the file. This is a subset of the PE section header that includes
enough information to correctly interpret the RVAs from the webcil header and from the .NET
metadata. Other information (such as the section names) are not included.

``` c
struct SectionHeader {
uint32_t st_virtual_size;
uint32_t st_virtual_address;
uint32_t st_raw_data_size;
uint32_t st_raw_data_ptr;
};
```

### Sections

Immediately following the section table are the sections. These are copied verbatim from the PE file.

## Rationale

The intention is to include only the information necessary for the runtime to locate the metadata
root, and to resolve the RVA references in the metadata (for locating data declarations and method IL).

A goal is for the files not to be executable by .NET Framework.

Unlike PE files, mixing native and managed code is not a goal.

Lossless conversion from Webcil back to PE is not intended to be supported. The format is being
documented in order to support diagnostic tooling and utilities such as decompilers, disassemblers,
file identification utilities, dependency analyzers, etc.

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<Project>
<Import Project="..\Directory.Build.props" />
<PropertyGroup>
<IsShipping>true</IsShipping>
radical marked this conversation as resolved.
Show resolved Hide resolved
<!-- this assembly should not produce a public package, rather it's meant to be shipped by the
WasmAppBuilder task and the BrowserDebugProxy -->
<IsShippingPackage>false</IsShippingPackage>
<!-- This isn't a public API in a public package, don't ship documentation xml in the nugets that consume this assembly -->
<GenerateDocumentationFile>false</GenerateDocumentationFile>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace System.Runtime.CompilerServices
{
internal sealed class IsExternalInit { }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>$(NetCoreAppToolCurrent);$(NetFrameworkToolCurrent)</TargetFrameworks>
radical marked this conversation as resolved.
Show resolved Hide resolved
<Description>Abstractions for modifying .NET webcil binary images</Description>
<IncludeSymbols>true</IncludeSymbols>
<Serviceable>true</Serviceable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<CLSCompliant>false</CLSCompliant>
</PropertyGroup>

<ItemGroup>
<!-- we need to keep the version of System.Reflection.Metadata in sync with dotnet/msbuild and dotnet/sdk -->
<PackageReference Include="System.Reflection.Metadata" Version="$(SystemReflectionMetadataVersion)" />
<PackageReference Include="System.Collections.Immutable" Version="$(SystemCollectionsImmutableVersion)" />
</ItemGroup>

<ItemGroup>
<Compile Include="Webcil\**\*.cs" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'">
<Compile Include="Common\IsExternalInit.cs" />
</ItemGroup>
radical marked this conversation as resolved.
Show resolved Hide resolved
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace Microsoft.NET.WebAssembly.Webcil.Internal;

internal static unsafe class Constants
{
public const int WC_VERSION_MAJOR = 0;
public const int WC_VERSION_MINOR = 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Runtime.InteropServices;

namespace Microsoft.NET.WebAssembly.Webcil;

/// <summary>
/// The header of a WebCIL file.
/// </summary>
///
/// <remarks>
/// The header is a subset of the PE, COFF and CLI headers that are needed by the mono runtime to load managed assemblies.
/// </remarks>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public unsafe struct WebcilHeader
{
public fixed byte id[4]; // 'W' 'b' 'I' 'L'
// 4 bytes
public ushort version_major; // 0
public ushort version_minor; // 0
// 8 bytes

public ushort coff_sections;
public ushort reserved0; // 0
// 12 bytes
public uint pe_cli_header_rva;
public uint pe_cli_header_size;
// 20 bytes
public uint pe_debug_rva;
public uint pe_debug_size;
// 28 bytes
}
Loading