mirror of
https://github.com/Smaug123/WoofWare.PawPrint
synced 2025-10-11 16:48:41 +00:00
Track addresses of arguments (#53)
This commit is contained in:
@@ -389,8 +389,10 @@ type UnaryConstIlOp =
|
|||||||
| Blt_un of int32
|
| Blt_un of int32
|
||||||
| Ldloc_s of uint8
|
| Ldloc_s of uint8
|
||||||
| Ldloca_s of uint8
|
| Ldloca_s of uint8
|
||||||
|
/// Load the address of an argument onto the stack.
|
||||||
| Ldarga of uint16
|
| Ldarga of uint16
|
||||||
| Ldarg_s of uint8
|
| Ldarg_s of uint8
|
||||||
|
/// Load the address of an argument onto the stack.
|
||||||
| Ldarga_s of uint8
|
| Ldarga_s of uint8
|
||||||
/// Unconditionally transfer control to this offset from the next instruction;
|
/// Unconditionally transfer control to this offset from the next instruction;
|
||||||
/// like Br but can leave a try/filter/catch block too, and ensures surrounding `finally` blocks execute.
|
/// like Br but can leave a try/filter/catch block too, and ensures surrounding `finally` blocks execute.
|
||||||
|
@@ -72,7 +72,9 @@ type CliValueType =
|
|||||||
| Float64 of float
|
| Float64 of float
|
||||||
|
|
||||||
[<RequireQualifiedAccess>]
|
[<RequireQualifiedAccess>]
|
||||||
type CliRuntimePointerSource = | LocalVariable of sourceThread : ThreadId * methodFrame : int * whichVar : uint16
|
type CliRuntimePointerSource =
|
||||||
|
| LocalVariable of sourceThread : ThreadId * methodFrame : int * whichVar : uint16
|
||||||
|
| Argument of sourceThread : ThreadId * methodFrame : int * whichVar : uint16
|
||||||
|
|
||||||
type CliRuntimePointer =
|
type CliRuntimePointer =
|
||||||
| Unmanaged of unit
|
| Unmanaged of unit
|
||||||
|
@@ -4,6 +4,7 @@ open Microsoft.FSharp.Core
|
|||||||
|
|
||||||
type ManagedPointerSource =
|
type ManagedPointerSource =
|
||||||
| LocalVariable of sourceThread : ThreadId * methodFrame : int * whichVar : uint16
|
| LocalVariable of sourceThread : ThreadId * methodFrame : int * whichVar : uint16
|
||||||
|
| Argument of sourceThread : ThreadId * methodFrame : int * whichVar : uint16
|
||||||
| Heap of ManagedHeapAddress
|
| Heap of ManagedHeapAddress
|
||||||
| Null
|
| Null
|
||||||
|
|
||||||
@@ -11,7 +12,10 @@ type ManagedPointerSource =
|
|||||||
match this with
|
match this with
|
||||||
| ManagedPointerSource.Null -> "<null pointer>"
|
| ManagedPointerSource.Null -> "<null pointer>"
|
||||||
| ManagedPointerSource.Heap addr -> $"%O{addr}"
|
| ManagedPointerSource.Heap addr -> $"%O{addr}"
|
||||||
| LocalVariable (source, method, var) -> $"<variable %i{var} in method frame %i{method} of thread %O{source}>"
|
| ManagedPointerSource.LocalVariable (source, method, var) ->
|
||||||
|
$"<variable %i{var} in method frame %i{method} of thread %O{source}>"
|
||||||
|
| ManagedPointerSource.Argument (source, method, var) ->
|
||||||
|
$"<argument %i{var} in method frame %i{method} of thread %O{source}>"
|
||||||
|
|
||||||
[<RequireQualifiedAccess>]
|
[<RequireQualifiedAccess>]
|
||||||
type NativeIntSource =
|
type NativeIntSource =
|
||||||
@@ -65,7 +69,9 @@ type EvalStackValue =
|
|||||||
| EvalStackValue.Float f -> $"Float(%f{f})"
|
| EvalStackValue.Float f -> $"Float(%f{f})"
|
||||||
| EvalStackValue.ManagedPointer managedPointerSource -> $"Pointer(%O{managedPointerSource})"
|
| EvalStackValue.ManagedPointer managedPointerSource -> $"Pointer(%O{managedPointerSource})"
|
||||||
| EvalStackValue.ObjectRef managedHeapAddress -> $"ObjectRef(%O{managedHeapAddress})"
|
| EvalStackValue.ObjectRef managedHeapAddress -> $"ObjectRef(%O{managedHeapAddress})"
|
||||||
| EvalStackValue.UserDefinedValueType evalStackValues -> failwith "todo"
|
| EvalStackValue.UserDefinedValueType evalStackValues ->
|
||||||
|
let desc = evalStackValues |> List.map string<EvalStackValue> |> String.concat " | "
|
||||||
|
$"Struct(%s{desc})"
|
||||||
|
|
||||||
[<RequireQualifiedAccess>]
|
[<RequireQualifiedAccess>]
|
||||||
module EvalStackValue =
|
module EvalStackValue =
|
||||||
@@ -168,6 +174,10 @@ module EvalStackValue =
|
|||||||
CliRuntimePointerSource.LocalVariable (sourceThread, methodFrame, whichVar)
|
CliRuntimePointerSource.LocalVariable (sourceThread, methodFrame, whichVar)
|
||||||
|> CliRuntimePointer.Managed
|
|> CliRuntimePointer.Managed
|
||||||
|> CliType.RuntimePointer
|
|> CliType.RuntimePointer
|
||||||
|
| ManagedPointerSource.Argument (sourceThread, methodFrame, whichVar) ->
|
||||||
|
CliRuntimePointerSource.Argument (sourceThread, methodFrame, whichVar)
|
||||||
|
|> CliRuntimePointer.Managed
|
||||||
|
|> CliType.RuntimePointer
|
||||||
| ManagedPointerSource.Heap managedHeapAddress -> CliType.ObjectRef (Some managedHeapAddress)
|
| ManagedPointerSource.Heap managedHeapAddress -> CliType.ObjectRef (Some managedHeapAddress)
|
||||||
| ManagedPointerSource.Null -> CliType.ObjectRef None
|
| ManagedPointerSource.Null -> CliType.ObjectRef None
|
||||||
| EvalStackValue.NativeInt nativeIntSource ->
|
| EvalStackValue.NativeInt nativeIntSource ->
|
||||||
@@ -175,7 +185,11 @@ module EvalStackValue =
|
|||||||
| NativeIntSource.Verbatim 0L -> CliType.ObjectRef None
|
| NativeIntSource.Verbatim 0L -> CliType.ObjectRef None
|
||||||
| NativeIntSource.Verbatim i -> failwith $"refusing to interpret verbatim native int {i} as a pointer"
|
| NativeIntSource.Verbatim i -> failwith $"refusing to interpret verbatim native int {i} as a pointer"
|
||||||
| NativeIntSource.FunctionPointer _ -> failwith "TODO"
|
| NativeIntSource.FunctionPointer _ -> failwith "TODO"
|
||||||
| i -> failwith $"TODO: %O{i}"
|
| EvalStackValue.UserDefinedValueType fields ->
|
||||||
|
match fields with
|
||||||
|
| [ esv ] -> toCliTypeCoerced target esv
|
||||||
|
| fields -> failwith $"TODO: don't know how to coerce struct of {fields} to a pointer"
|
||||||
|
| _ -> failwith $"TODO: {popped}"
|
||||||
| CliType.Bool _ ->
|
| CliType.Bool _ ->
|
||||||
match popped with
|
match popped with
|
||||||
| EvalStackValue.Int32 i ->
|
| EvalStackValue.Int32 i ->
|
||||||
@@ -194,6 +208,10 @@ module EvalStackValue =
|
|||||||
CliRuntimePointerSource.LocalVariable (sourceThread, methodFrame, var)
|
CliRuntimePointerSource.LocalVariable (sourceThread, methodFrame, var)
|
||||||
|> CliRuntimePointer.Managed
|
|> CliRuntimePointer.Managed
|
||||||
|> CliType.RuntimePointer
|
|> CliType.RuntimePointer
|
||||||
|
| ManagedPointerSource.Argument (sourceThread, methodFrame, var) ->
|
||||||
|
CliRuntimePointerSource.Argument (sourceThread, methodFrame, var)
|
||||||
|
|> CliRuntimePointer.Managed
|
||||||
|
|> CliType.RuntimePointer
|
||||||
| _ -> failwith $"TODO: %O{popped}"
|
| _ -> failwith $"TODO: %O{popped}"
|
||||||
| CliType.Char _ ->
|
| CliType.Char _ ->
|
||||||
match popped with
|
match popped with
|
||||||
@@ -241,6 +259,9 @@ module EvalStackValue =
|
|||||||
| CliRuntimePointerSource.LocalVariable (sourceThread, methodFrame, var) ->
|
| CliRuntimePointerSource.LocalVariable (sourceThread, methodFrame, var) ->
|
||||||
ManagedPointerSource.LocalVariable (sourceThread, methodFrame, var)
|
ManagedPointerSource.LocalVariable (sourceThread, methodFrame, var)
|
||||||
|> EvalStackValue.ManagedPointer
|
|> EvalStackValue.ManagedPointer
|
||||||
|
| CliRuntimePointerSource.Argument (sourceThread, methodFrame, var) ->
|
||||||
|
ManagedPointerSource.Argument (sourceThread, methodFrame, var)
|
||||||
|
|> EvalStackValue.ManagedPointer
|
||||||
| CliType.ValueType fields -> fields |> List.map ofCliType |> EvalStackValue.UserDefinedValueType
|
| CliType.ValueType fields -> fields |> List.map ofCliType |> EvalStackValue.UserDefinedValueType
|
||||||
|
|
||||||
type EvalStack =
|
type EvalStack =
|
||||||
|
@@ -83,6 +83,8 @@ module System_Threading_Monitor =
|
|||||||
| ManagedPointerSource.LocalVariable (sourceThread, methodFrame, whichVar) ->
|
| ManagedPointerSource.LocalVariable (sourceThread, methodFrame, whichVar) ->
|
||||||
state
|
state
|
||||||
|> IlMachineState.setLocalVariable sourceThread methodFrame whichVar (CliType.OfBool true)
|
|> IlMachineState.setLocalVariable sourceThread methodFrame whichVar (CliType.OfBool true)
|
||||||
|
| ManagedPointerSource.Argument (sourceThread, methodFrame, whichVar) ->
|
||||||
|
failwith "not really expecting to *edit* an argument..."
|
||||||
| ManagedPointerSource.Heap addr -> failwith "todo: managed heap"
|
| ManagedPointerSource.Heap addr -> failwith "todo: managed heap"
|
||||||
|
|
||||||
(state, WhatWeDid.Executed) |> ExecutionResult.Stepped
|
(state, WhatWeDid.Executed) |> ExecutionResult.Stepped
|
||||||
|
@@ -80,6 +80,8 @@ module NullaryIlOp =
|
|||||||
| EvalStackValue.ManagedPointer src ->
|
| EvalStackValue.ManagedPointer src ->
|
||||||
match src with
|
match src with
|
||||||
| ManagedPointerSource.Null -> failwith "TODO: throw NullReferenceException"
|
| ManagedPointerSource.Null -> failwith "TODO: throw NullReferenceException"
|
||||||
|
| ManagedPointerSource.Argument (sourceThread, methodFrame, whichVar) ->
|
||||||
|
failwith "unexpected - can we really write to an argument?"
|
||||||
| ManagedPointerSource.LocalVariable (sourceThread, methodFrame, whichVar) ->
|
| ManagedPointerSource.LocalVariable (sourceThread, methodFrame, whichVar) ->
|
||||||
{ state with
|
{ state with
|
||||||
ThreadState =
|
ThreadState =
|
||||||
@@ -668,6 +670,17 @@ module NullaryIlOp =
|
|||||||
| EvalStackValue.ManagedPointer src ->
|
| EvalStackValue.ManagedPointer src ->
|
||||||
match src with
|
match src with
|
||||||
| ManagedPointerSource.Null -> failwith "unexpected null pointer in Ldind_u1"
|
| ManagedPointerSource.Null -> failwith "unexpected null pointer in Ldind_u1"
|
||||||
|
| ManagedPointerSource.Argument (sourceThread, methodFrame, whichVar) ->
|
||||||
|
let methodState =
|
||||||
|
state.ThreadState.[sourceThread].MethodStates.[methodFrame].Arguments.[int<uint16> whichVar]
|
||||||
|
|
||||||
|
match methodState with
|
||||||
|
| CliType.Bool b -> b
|
||||||
|
| CliType.Numeric numeric -> failwith $"tried to load a Numeric as a u8: {numeric}"
|
||||||
|
| CliType.Char _ -> failwith "tried to load a Char as a u8"
|
||||||
|
| CliType.ObjectRef _ -> failwith "tried to load an ObjectRef as a u8"
|
||||||
|
| CliType.RuntimePointer _ -> failwith "tried to load a RuntimePointer as a u8"
|
||||||
|
| CliType.ValueType cliTypes -> failwith "todo"
|
||||||
| ManagedPointerSource.LocalVariable (sourceThread, methodFrame, whichVar) ->
|
| ManagedPointerSource.LocalVariable (sourceThread, methodFrame, whichVar) ->
|
||||||
let methodState =
|
let methodState =
|
||||||
state.ThreadState.[sourceThread].MethodStates.[methodFrame].LocalVariables
|
state.ThreadState.[sourceThread].MethodStates.[methodFrame].LocalVariables
|
||||||
|
@@ -409,9 +409,27 @@ module internal UnaryConstIlOp =
|
|||||||
|> IlMachineState.advanceProgramCounter currentThread
|
|> IlMachineState.advanceProgramCounter currentThread
|
||||||
|
|
||||||
state, WhatWeDid.Executed
|
state, WhatWeDid.Executed
|
||||||
| Ldarga s -> failwith "TODO: Ldarga unimplemented"
|
| Ldarga s ->
|
||||||
|
let executingMethod = state.ThreadState.[currentThread]
|
||||||
|
|
||||||
|
let ptr =
|
||||||
|
ManagedPointerSource.Argument (currentThread, executingMethod.ActiveMethodState, s)
|
||||||
|
|
||||||
|
state
|
||||||
|
|> IlMachineState.pushToEvalStack' (EvalStackValue.ManagedPointer ptr) currentThread
|
||||||
|
|> IlMachineState.advanceProgramCounter currentThread
|
||||||
|
|> Tuple.withRight WhatWeDid.Executed
|
||||||
|
| Ldarga_s b ->
|
||||||
|
let executingMethod = state.ThreadState.[currentThread]
|
||||||
|
|
||||||
|
let ptr =
|
||||||
|
ManagedPointerSource.Argument (currentThread, executingMethod.ActiveMethodState, uint16<byte> b)
|
||||||
|
|
||||||
|
state
|
||||||
|
|> IlMachineState.pushToEvalStack' (EvalStackValue.ManagedPointer ptr) currentThread
|
||||||
|
|> IlMachineState.advanceProgramCounter currentThread
|
||||||
|
|> Tuple.withRight WhatWeDid.Executed
|
||||||
| Ldarg_s b -> failwith "TODO: Ldarg_s unimplemented"
|
| Ldarg_s b -> failwith "TODO: Ldarg_s unimplemented"
|
||||||
| Ldarga_s b -> failwith "TODO: Ldarga_s unimplemented"
|
|
||||||
| Leave i -> leave currentThread i state
|
| Leave i -> leave currentThread i state
|
||||||
| Leave_s b -> leave currentThread (int<int8> b) state
|
| Leave_s b -> leave currentThread (int<int8> b) state
|
||||||
| Starg_s b -> failwith "TODO: Starg_s unimplemented"
|
| Starg_s b -> failwith "TODO: Starg_s unimplemented"
|
||||||
|
@@ -408,6 +408,7 @@ module internal UnaryMetadataIlOp =
|
|||||||
match source with
|
match source with
|
||||||
| ManagedPointerSource.Null -> failwith "TODO: raise NullReferenceException"
|
| ManagedPointerSource.Null -> failwith "TODO: raise NullReferenceException"
|
||||||
| ManagedPointerSource.LocalVariable (sourceThread, methodFrame, whichVar) -> failwith "todo"
|
| ManagedPointerSource.LocalVariable (sourceThread, methodFrame, whichVar) -> failwith "todo"
|
||||||
|
| ManagedPointerSource.Argument (sourceThread, methodFrame, whichVar) -> failwith "todo"
|
||||||
| ManagedPointerSource.Heap addr ->
|
| ManagedPointerSource.Heap addr ->
|
||||||
match state.ManagedHeap.NonArrayObjects.TryGetValue addr with
|
match state.ManagedHeap.NonArrayObjects.TryGetValue addr with
|
||||||
| false, _ -> failwith $"todo: array {addr}"
|
| false, _ -> failwith $"todo: array {addr}"
|
||||||
@@ -575,7 +576,12 @@ module internal UnaryMetadataIlOp =
|
|||||||
state.ThreadState.[sourceThread].MethodStates.[methodFrame].LocalVariables
|
state.ThreadState.[sourceThread].MethodStates.[methodFrame].LocalVariables
|
||||||
.[int<uint16> whichVar]
|
.[int<uint16> whichVar]
|
||||||
|
|
||||||
failwith $"todo: local variable {currentValue} {field}"
|
IlMachineState.pushToEvalStack currentValue thread state
|
||||||
|
| ManagedPointerSource.Argument (sourceThread, methodFrame, whichVar) ->
|
||||||
|
let currentValue =
|
||||||
|
state.ThreadState.[sourceThread].MethodStates.[methodFrame].Arguments.[int<uint16> whichVar]
|
||||||
|
|
||||||
|
IlMachineState.pushToEvalStack currentValue thread state
|
||||||
| ManagedPointerSource.Heap managedHeapAddress ->
|
| ManagedPointerSource.Heap managedHeapAddress ->
|
||||||
match state.ManagedHeap.NonArrayObjects.TryGetValue managedHeapAddress with
|
match state.ManagedHeap.NonArrayObjects.TryGetValue managedHeapAddress with
|
||||||
| false, _ -> failwith $"todo: array {managedHeapAddress}"
|
| false, _ -> failwith $"todo: array {managedHeapAddress}"
|
||||||
|
Reference in New Issue
Block a user