PageAllocator.cs 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. using System;
  2. using System.Runtime.CompilerServices;
  3. using MonoMod.Utils;
  4. namespace BepInEx.IL2CPP
  5. {
  6. /// <summary>
  7. /// A general purpose page allocator for patching purposes.
  8. /// Allows to allocate pages (4k memory chunks) within the 1GB radius of a given address.
  9. /// </summary>
  10. /// <remarks>Based on https://github.com/kubo/funchook</remarks>
  11. internal abstract class PageAllocator
  12. {
  13. /// <summary>
  14. /// Common page size on Unix and Windows (4k).
  15. /// </summary>
  16. public const int PAGE_SIZE = 0x1000;
  17. /// <summary>
  18. /// Allocation granularity on Windows (but can be reused in other implementations).
  19. /// </summary>
  20. protected const int ALLOCATION_UNIT = 0x100000;
  21. protected const int PAGES_PER_UNIT = ALLOCATION_UNIT / PAGE_SIZE;
  22. private static PageAllocator instance;
  23. public static PageAllocator Instance => instance ??= Init();
  24. public abstract IntPtr Allocate(IntPtr hint);
  25. public abstract void Free(IntPtr page);
  26. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  27. protected static long RoundDown(long num, long unit)
  28. {
  29. return num & ~(unit - 1);
  30. }
  31. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  32. protected static long RoundUp(long num, long unit)
  33. {
  34. return (num + unit - 1) & ~ (unit - 1);
  35. }
  36. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  37. protected static bool IsInRelJmpRange(IntPtr src, IntPtr dst)
  38. {
  39. long diff = dst.ToInt64() - src.ToInt64();
  40. return int.MinValue <= diff && diff <= int.MaxValue;
  41. }
  42. private static PageAllocator Init()
  43. {
  44. if (PlatformHelper.Is(Platform.Windows))
  45. return new WindowsPageAllocator();
  46. if (PlatformHelper.Is(Platform.Unix))
  47. return new UnixPageAllocator();
  48. throw new NotImplementedException();
  49. }
  50. }
  51. }