mirror of
https://github.com/Smaug123/WoofWare.PawPrint
synced 2025-10-08 15:38:41 +00:00
Progress
This commit is contained in:
98
.github/workflows/dotnet.yaml
vendored
Normal file
98
.github/workflows/dotnet.yaml
vendored
Normal 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
19
Directory.Build.props
Normal 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>
|
@@ -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"
|
||||
|
@@ -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 =
|
||||
|
@@ -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
|
||||
|
@@ -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}"
|
||||
|
@@ -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
|
||||
|
@@ -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",
|
||||
|
Reference in New Issue
Block a user