This commit is contained in:
Smaug123
2025-02-20 10:22:56 +00:00
parent f520b90483
commit 45bb35eb86
8 changed files with 216 additions and 14 deletions

98
.github/workflows/dotnet.yaml vendored Normal file
View File

@@ -0,0 +1,98 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/SchemaStore/schemastore/master/src/schemas/json/github-workflow.json
name: .NET
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
env:
DOTNET_NOLOGO: true
DOTNET_CLI_TELEMETRY_OPTOUT: true
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
NUGET_XMLDOC_MODE: ''
DOTNET_MULTILEVEL_LOOKUP: 0
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # so that NerdBank.GitVersioning has access to history
- name: Install Nix
uses: cachix/install-nix-action@v30
with:
extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
- name: Restore dependencies
run: nix develop --command dotnet restore
- name: Build
run: nix develop --command dotnet build --no-restore --configuration Release
- name: Test
run: nix develop --command dotnet test --no-build --verbosity normal --configuration Release
build-nix:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Nix
uses: cachix/install-nix-action@v30
with:
extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
- name: Build
run: nix build
- name: Reproducibility check
run: nix build --rebuild
check-dotnet-format:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Nix
uses: cachix/install-nix-action@v30
with:
extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
- name: Run Fantomas
run: nix run .#fantomas -- --check .
check-nix-format:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Nix
uses: cachix/install-nix-action@v30
with:
extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
- name: Run Alejandra
run: nix develop --command alejandra --check .
flake-check:
name: Check flake
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Install Nix
uses: cachix/install-nix-action@v30
with:
extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
- name: Flake check
run: nix flake check
all-required-checks-complete:
if: ${{ always() }}
needs: [check-dotnet-format, check-nix-format, build, build-nix, flake-check]
runs-on: ubuntu-latest
steps:
- uses: G-Research/common-actions/check-required-lite@2b7dc49cb14f3344fbe6019c14a31165e258c059
with:
needs-context: ${{ toJSON(needs) }}

19
Directory.Build.props Normal file
View File

@@ -0,0 +1,19 @@
<Project>
<PropertyGroup>
<DebugType Condition=" '$(DebugType)' == '' ">embedded</DebugType>
<Deterministic>true</Deterministic>
<NetCoreTargetingPackRoot>[UNDEFINED]</NetCoreTargetingPackRoot>
<DisableImplicitLibraryPacksFolder>true</DisableImplicitLibraryPacksFolder>
<DisableImplicitNuGetFallbackFolder>true</DisableImplicitNuGetFallbackFolder>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<DebugType>embedded</DebugType>
<WarnOn>FS3388,FS3559</WarnOn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Nerdbank.GitVersioning" Version="3.7.115" PrivateAssets="all"/>
<SourceLinkGitHubHost Include="github.com" ContentUrl="https://raw.githubusercontent.com"/>
</ItemGroup>
<PropertyGroup Condition="'$(GITHUB_ACTION)' != ''">
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
</PropertyGroup>
</Project>

View File

@@ -1,6 +1,8 @@
namespace WoofWare.PawPrint
open System
open System.Collections.Immutable
open System.Reflection.Metadata
open Microsoft.FSharp.Core
type ThreadId = | ThreadId of int
@@ -376,11 +378,49 @@ module AbstractMachine =
| Rethrow -> failwith "todo"
| Throw -> failwith "todo"
let private executeUnaryMetadata
(op : UnaryMetadataTokenIlOp)
(metadataToken : MetadataToken)
(state : IlMachineState)
(dumped : DumpedAssembly)
(thread : ThreadId)
: IlMachineState
=
match op with
| Call ->
let handle =
match metadataToken.Kind with
| HandleKind.MethodSpecification -> MethodSpecificationHandle.op_Explicit metadataToken
| k -> failwith $"Unrecognised kind: %O{k}"
let method =
dumped.Methods.[MethodDefinitionHandle.op_Explicit dumped.MethodSpecs.[handle].Method]
failwith "TODO: now do this!"
state
| Callvirt -> failwith "todo"
| Castclass -> failwith "todo"
| Newobj -> failwith "todo"
| Newarr -> failwith "todo"
| Box -> failwith "todo"
| Ldelema -> failwith "todo"
| Isinst -> failwith "todo"
| Stfld -> failwith "todo"
| Stsfld -> failwith "todo"
| Ldfld -> failwith "todo"
| Ldflda -> failwith "todo"
| Ldsfld -> failwith "todo"
| Unbox_Any -> failwith "todo"
| Stelem -> failwith "todo"
| Ldelem -> failwith "todo"
let executeOneStep (state : IlMachineState) (dumped : DumpedAssembly) (thread : ThreadId) : IlMachineState =
let instruction = state.ThreadState.[thread].MethodState
match instruction.ExecutingMethod.Locations.[instruction.IlOpIndex] with
| IlOp.Nullary op -> executeNullary state thread dumped op
| UnaryConst unaryConstIlOp -> failwith "todo"
| UnaryMetadataToken (unaryMetadataTokenIlOp, bytes) -> failwith "todo"
| UnaryMetadataToken (unaryMetadataTokenIlOp, bytes) ->
executeUnaryMetadata unaryMetadataTokenIlOp bytes state dumped thread
| Switch immutableArray -> failwith "todo"
| UnaryStringToken (unaryStringTokenIlOp, stringHandle) -> failwith "todo"

View File

@@ -14,6 +14,9 @@ type DumpedAssembly =
Types : TypeInfo list
Methods : IReadOnlyDictionary<MethodDefinitionHandle, MethodInfo>
MainMethod : MethodDefinitionHandle
/// Map of four-byte int token to metadata
MethodDefinitions : Map<int, MethodDefinition>
MethodSpecs : ImmutableDictionary<MethodSpecificationHandle, MethodSpecification>
}
[<RequireQualifiedAccess>]
@@ -38,10 +41,32 @@ module Assembly =
|> List.collect (fun ty -> ty.Methods |> List.map (fun mi -> KeyValuePair (mi.Handle, mi)))
|> ImmutableDictionary.CreateRange
let methodDefnMetadata =
metadataReader.MethodDefinitions
|> Seq.map (fun mh ->
let def = metadataReader.GetMethodDefinition mh
let eh : EntityHandle = MethodDefinitionHandle.op_Implicit mh
let token = MetadataTokens.GetToken eh
token, def
)
|> Map.ofSeq
let methodSpecs =
Seq.init
(metadataReader.GetTableRowCount TableIndex.MethodSpec)
(fun i ->
let i = i + 1
let handle = MetadataTokens.MethodSpecificationHandle i
KeyValuePair (handle, metadataReader.GetMethodSpecification handle)
)
|> ImmutableDictionary.CreateRange
{
Types = result
MainMethod = entryPointMethod
Methods = methods
MethodDefinitions = methodDefnMetadata
MethodSpecs = methodSpecs
}
let print (main : MethodDefinitionHandle) (dumped : DumpedAssembly) : unit =

View File

@@ -17,3 +17,9 @@ module internal BitTwiddling =
let inline toUint64 (bytes : ReadOnlySpan<byte>) : uint64 =
uint64 (toUint32 (bytes.Slice (0, 4)))
+ 0x10000UL * uint64 (toUint32 (bytes.Slice (4, 4)))
let inline toInt32 (bytes : ReadOnlySpan<byte>) : int32 =
int32 bytes.[0]
+ int32 bytes.[1] * 256
+ int32 bytes.[2] * 256 * 256
+ int32 bytes.[3] * 256 * 256 * 256

View File

@@ -1,6 +1,7 @@
namespace WoofWare.PawPrint
open System.Collections.Immutable
open System.Reflection.Metadata
type NullaryIlOp =
| Nop
@@ -121,18 +122,21 @@ type UnaryMetadataTokenIlOp =
| Ldfld
| Ldflda
| Ldsfld
| Ldstr
| Unbox_Any
| Stelem
| Ldelem
type UnaryStringTokenIlOp = | Ldstr
/// A four-byte metadata token.
type MetadataToken = byte[]
type MetadataToken = EntityHandle
type StringToken = StringHandle
type IlOp =
| Nullary of NullaryIlOp
| UnaryConst of UnaryConstIlOp
| UnaryMetadataToken of UnaryMetadataTokenIlOp * MetadataToken
| UnaryStringToken of UnaryStringTokenIlOp * StringToken
| Switch of int32 ImmutableArray
static member Format (opCode : IlOp) (offset : int) : string = $" IL_%04X{offset}: %-20O{opCode}"

View File

@@ -131,18 +131,16 @@ module TypeInfo =
LanguagePrimitives.EnumOfValue (uint16 op)
let private readMetadataToken (reader : byref<BlobReader>) : MetadataToken =
[|
reader.ReadByte ()
reader.ReadByte ()
reader.ReadByte ()
reader.ReadByte ()
|]
reader.ReadUInt32 () |> int |> MetadataTokens.EntityHandle
let private readStringToken (reader : byref<BlobReader>) : StringToken =
reader.ReadUInt32 () |> int |> MetadataTokens.StringHandle
let private readMethodBody (peReader : PEReader) (methodDef : MethodDefinition) : (IlOp * int) list =
if methodDef.RelativeVirtualAddress = 0 then
[]
else
let methodBody = peReader.GetMethodBody (methodDef.RelativeVirtualAddress)
let methodBody = peReader.GetMethodBody methodDef.RelativeVirtualAddress
let ilBytes = methodBody.GetILBytes ()
use bytes = fixed ilBytes
let mutable reader : BlobReader = BlobReader (bytes, ilBytes.Length)
@@ -283,8 +281,7 @@ module TypeInfo =
IlOp.UnaryMetadataToken (UnaryMetadataTokenIlOp.Callvirt, readMetadataToken &reader)
| ILOpCode.Cpobj -> failwith "todo"
| ILOpCode.Ldobj -> failwith "todo"
| ILOpCode.Ldstr ->
IlOp.UnaryMetadataToken (UnaryMetadataTokenIlOp.Ldstr, readMetadataToken &reader)
| ILOpCode.Ldstr -> IlOp.UnaryStringToken (UnaryStringTokenIlOp.Ldstr, readStringToken &reader)
| ILOpCode.Newobj ->
IlOp.UnaryMetadataToken (UnaryMetadataTokenIlOp.Newobj, readMetadataToken &reader)
| ILOpCode.Castclass ->
@@ -463,14 +460,17 @@ module TypeInfo =
(reader : MetadataReader, handle : TypeDefinitionHandle, rawTypeKind : byte)
: TypeDefn
=
let handle : EntityHandle = TypeDefinitionHandle.op_Implicit handle
let typeKind = reader.ResolveSignatureTypeKind (handle, rawTypeKind)
TypeDefn.FromDefinition typeKind
member this.GetTypeFromReference
(reader : MetadataReader, foo : TypeReferenceHandle, rawTypeKind : byte)
(reader : MetadataReader, handle : TypeReferenceHandle, rawTypeKind : byte)
: TypeDefn
=
let typeKind = reader.ResolveSignatureTypeKind (foo, rawTypeKind)
let handle : EntityHandle = TypeReferenceHandle.op_Implicit handle
let typeKind = reader.ResolveSignatureTypeKind (handle, rawTypeKind)
TypeDefn.FromReference typeKind
member this.GetPointerType (typeCode : TypeDefn) : TypeDefn = TypeDefn.Pointer typeCode

View File

@@ -14,6 +14,11 @@
"version": "5.0.2",
"hash": "sha256-YOoosLEiszPsOOaNAkWhFGU04JJKDOFVoA/ggrZMN10="
},
{
"pname": "FSharp.Core",
"version": "9.0.101",
"hash": "sha256-bR4PHanvKrzD43qFQxmOmmhhpz+ZmKZMPlgGnlRNcp4="
},
{
"pname": "FsUnit",
"version": "7.0.1",
@@ -144,6 +149,11 @@
"version": "17.13.0",
"hash": "sha256-L/CJzou7dhmShUgXq3aXL3CaLTJll17Q+JY2DBdUUpo="
},
{
"pname": "Nerdbank.GitVersioning",
"version": "3.7.115",
"hash": "sha256-sqn+i7vvBgBUtm7j82mH+SpApgI2hsmL5DYfLm1Z7gw="
},
{
"pname": "Newtonsoft.Json",
"version": "13.0.1",