diff --git a/Architecture/CustomArchitectureInstructionCallbacks.cs b/Architecture/CustomArchitectureInstructionCallbacks.cs index 31e411c..07ae8f7 100644 --- a/Architecture/CustomArchitectureInstructionCallbacks.cs +++ b/Architecture/CustomArchitectureInstructionCallbacks.cs @@ -25,6 +25,17 @@ private delegate bool GetInstructionTextCallback( out IntPtr tokens, out ulong count); + [UnmanagedFunctionPointer(System.Runtime.InteropServices.CallingConvention.Cdecl)] + [return: MarshalAs(UnmanagedType.I1)] + private delegate bool GetInstructionTextWithContextCallback( + IntPtr context, + IntPtr data, + ulong address, + ref ulong length, + IntPtr functionContext, + out IntPtr tokens, + out ulong count); + [UnmanagedFunctionPointer(System.Runtime.InteropServices.CallingConvention.Cdecl)] private delegate void FreeInstructionTextCallback(IntPtr tokens, ulong count); @@ -43,6 +54,9 @@ private void AddInstructionCallbacks(ref BNCustomArchitecture callbacks) this.GetInstructionInfoAdapter); callbacks.getInstructionText = UnsafeUtils.PinCallback( this.GetInstructionTextAdapter); + callbacks.getInstructionTextWithContext = + UnsafeUtils.PinCallback( + this.GetInstructionTextWithContextAdapter); callbacks.freeInstructionText = UnsafeUtils.PinCallback( this.FreeInstructionTextAdapter); callbacks.getInstructionLowLevelIL = @@ -57,6 +71,44 @@ private bool GetInstructionTextAdapter( ref ulong length, out IntPtr tokens, out ulong count) + { + return this.GetInstructionTextCore( + data, + address, + ref length, + IntPtr.Zero, + false, + out tokens, + out count); + } + + private bool GetInstructionTextWithContextAdapter( + IntPtr context, + IntPtr data, + ulong address, + ref ulong length, + IntPtr functionContext, + out IntPtr tokens, + out ulong count) + { + return this.GetInstructionTextCore( + data, + address, + ref length, + functionContext, + true, + out tokens, + out count); + } + + private bool GetInstructionTextCore( + IntPtr data, + ulong address, + ref ulong length, + IntPtr functionContext, + bool useFunctionContext, + out IntPtr tokens, + out ulong count) { tokens = IntPtr.Zero; count = 0; @@ -70,9 +122,25 @@ private bool GetInstructionTextAdapter( Marshal.Copy(data, bytes, 0, bytes.Length); } - InstructionTextToken[] managedTokens = - this.GetInstructionText(bytes, address, out ulong decodedLength) - ?? Array.Empty(); + InstructionTextToken[] managedTokens; + ulong decodedLength; + if (useFunctionContext) + { + managedTokens = this.GetInstructionTextWithContext( + bytes, + address, + functionContext, + out decodedLength); + } + else + { + managedTokens = this.GetInstructionText( + bytes, + address, + out decodedLength); + } + + managedTokens = managedTokens ?? Array.Empty(); if (0 == decodedLength || maximumLength < decodedLength) { return false; @@ -87,7 +155,7 @@ private bool GetInstructionTextAdapter( catch (Exception exception) { Core.LogError( - "Unhandled exception in CustomArchitecture.GetInstructionText: {0}", + "Unhandled exception in CustomArchitecture instruction text callback: {0}", exception); tokens = IntPtr.Zero; count = 0; diff --git a/Struct/BNCustomArchitecture.cs b/Struct/BNCustomArchitecture.cs index f20076e..e5f629a 100644 --- a/Struct/BNCustomArchitecture.cs +++ b/Struct/BNCustomArchitecture.cs @@ -640,6 +640,21 @@ out ulong length return Array.Empty(); } + /// + /// Retrieves instruction text using architecture-defined function context. + /// + /// + /// The default implementation preserves the ordinary instruction text behavior. + /// + public virtual InstructionTextToken[] GetInstructionTextWithContext( + byte[] data, + ulong address, + IntPtr context, + out ulong length) + { + return this.GetInstructionText(data, address, out length); + } + public virtual void FreeInstructionText( IntPtr tokens , ulong count