Skip to content

Commit

Permalink
fixes the CTD in linux (macOS untested) when patching short virtual m…
Browse files Browse the repository at this point in the history
…ethods
  • Loading branch information
pardeike committed Sep 6, 2020
1 parent 855cf78 commit 406586a
Showing 1 changed file with 19 additions and 0 deletions.
19 changes: 19 additions & 0 deletions Harmony/Internal/Memory.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
using MonoMod.RuntimeDetour;
using MonoMod.Utils;
using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;

namespace HarmonyLib
{
/// <summary>A low level memory helper</summary>
///
public static class Memory
{
/// <summary>Mark method for no inlining (currently only works on Mono)</summary>
/// <param name="method">The method/constructor to change</param>
///
unsafe public static void MarkForNoInlining(MethodBase method)
{
// TODO for now, this only works on mono
Expand All @@ -30,6 +34,9 @@ public static string DetourMethod(MethodBase original, MethodBase replacement)
var originalCodeStart = GetMethodStart(original, out var exception);
if (originalCodeStart == 0)
return exception.Message;

FixVirtualMethodTrampoline(original);

var patchCodeStart = GetMethodStart(replacement, out exception);
if (patchCodeStart == 0)
return exception.Message;
Expand All @@ -45,6 +52,18 @@ internal static void DetourMethodAndPersist(MethodBase original, MethodBase repl
PatchTools.RememberObject(original, replacement);
}

internal static void FixVirtualMethodTrampoline(MethodBase method)
{
if (!method.IsVirtual || method.IsAbstract || method.IsFinal) return;
var bytes = method.GetMethodBody()?.GetILAsByteArray();
if (bytes == null || bytes.Length == 0) return;
if (bytes.Length == 1 && bytes[0] == 0x2A) return;

var methodDef = new DynamicMethodDefinition($"VirtualFix-{Guid.NewGuid()}", typeof(void), new Type[0]);
methodDef.GetILGenerator().Emit(OpCodes.Ret);
_ = GetMethodStart(methodDef.Generate(), out var _); // trigger allocation/generation of jitted assembler
}

/// <summary>Writes a jump to memory</summary>
/// <param name="memory">The memory address</param>
/// <param name="destination">Jump destination</param>
Expand Down

0 comments on commit 406586a

Please sign in to comment.