MemoryManagerUnixHelper.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. using System;
  2. using System.Runtime.InteropServices;
  3. namespace Ryujinx.Memory
  4. {
  5. public static partial class MemoryManagerUnixHelper
  6. {
  7. [Flags]
  8. public enum MmapProts : uint
  9. {
  10. PROT_NONE = 0,
  11. PROT_READ = 1,
  12. PROT_WRITE = 2,
  13. PROT_EXEC = 4
  14. }
  15. [Flags]
  16. public enum MmapFlags : uint
  17. {
  18. MAP_SHARED = 1,
  19. MAP_PRIVATE = 2,
  20. MAP_ANONYMOUS = 4,
  21. MAP_NORESERVE = 8,
  22. MAP_FIXED = 16,
  23. MAP_UNLOCKED = 32
  24. }
  25. [Flags]
  26. public enum OpenFlags : uint
  27. {
  28. O_RDONLY = 0,
  29. O_WRONLY = 1,
  30. O_RDWR = 2,
  31. O_CREAT = 4,
  32. O_EXCL = 8,
  33. O_NOCTTY = 16,
  34. O_TRUNC = 32,
  35. O_APPEND = 64,
  36. O_NONBLOCK = 128,
  37. O_SYNC = 256,
  38. }
  39. private const int MAP_ANONYMOUS_LINUX_GENERIC = 0x20;
  40. private const int MAP_NORESERVE_LINUX_GENERIC = 0x4000;
  41. private const int MAP_UNLOCKED_LINUX_GENERIC = 0x80000;
  42. private const int MAP_NORESERVE_DARWIN = 0x40;
  43. private const int MAP_JIT_DARWIN = 0x800;
  44. private const int MAP_ANONYMOUS_DARWIN = 0x1000;
  45. public const int MADV_DONTNEED = 4;
  46. public const int MADV_REMOVE = 9;
  47. [LibraryImport("libc", EntryPoint = "mmap", SetLastError = true)]
  48. private static partial IntPtr Internal_mmap(IntPtr address, ulong length, MmapProts prot, int flags, int fd, long offset);
  49. [LibraryImport("libc", SetLastError = true)]
  50. public static partial int mprotect(IntPtr address, ulong length, MmapProts prot);
  51. [LibraryImport("libc", SetLastError = true)]
  52. public static partial int munmap(IntPtr address, ulong length);
  53. [LibraryImport("libc", SetLastError = true)]
  54. public static partial IntPtr mremap(IntPtr old_address, ulong old_size, ulong new_size, int flags, IntPtr new_address);
  55. [LibraryImport("libc", SetLastError = true)]
  56. public static partial int madvise(IntPtr address, ulong size, int advice);
  57. [LibraryImport("libc", SetLastError = true)]
  58. public static partial int mkstemp(IntPtr template);
  59. [LibraryImport("libc", SetLastError = true)]
  60. public static partial int unlink(IntPtr pathname);
  61. [LibraryImport("libc", SetLastError = true)]
  62. public static partial int ftruncate(int fildes, IntPtr length);
  63. [LibraryImport("libc", SetLastError = true)]
  64. public static partial int close(int fd);
  65. [LibraryImport("libc", SetLastError = true)]
  66. public static partial int shm_open(IntPtr name, int oflag, uint mode);
  67. [LibraryImport("libc", SetLastError = true)]
  68. public static partial int shm_unlink(IntPtr name);
  69. private static int MmapFlagsToSystemFlags(MmapFlags flags)
  70. {
  71. int result = 0;
  72. if (flags.HasFlag(MmapFlags.MAP_SHARED))
  73. {
  74. result |= (int)MmapFlags.MAP_SHARED;
  75. }
  76. if (flags.HasFlag(MmapFlags.MAP_PRIVATE))
  77. {
  78. result |= (int)MmapFlags.MAP_PRIVATE;
  79. }
  80. if (flags.HasFlag(MmapFlags.MAP_FIXED))
  81. {
  82. result |= (int)MmapFlags.MAP_FIXED;
  83. }
  84. if (flags.HasFlag(MmapFlags.MAP_ANONYMOUS))
  85. {
  86. if (OperatingSystem.IsLinux())
  87. {
  88. result |= MAP_ANONYMOUS_LINUX_GENERIC;
  89. }
  90. else if (OperatingSystem.IsMacOS())
  91. {
  92. result |= MAP_ANONYMOUS_DARWIN;
  93. }
  94. else
  95. {
  96. throw new NotImplementedException();
  97. }
  98. }
  99. if (flags.HasFlag(MmapFlags.MAP_NORESERVE))
  100. {
  101. if (OperatingSystem.IsLinux())
  102. {
  103. result |= MAP_NORESERVE_LINUX_GENERIC;
  104. }
  105. else if (OperatingSystem.IsMacOS())
  106. {
  107. result |= MAP_NORESERVE_DARWIN;
  108. }
  109. else
  110. {
  111. throw new NotImplementedException();
  112. }
  113. }
  114. if (flags.HasFlag(MmapFlags.MAP_UNLOCKED))
  115. {
  116. if (OperatingSystem.IsLinux())
  117. {
  118. result |= MAP_UNLOCKED_LINUX_GENERIC;
  119. }
  120. else if (OperatingSystem.IsMacOS())
  121. {
  122. // FIXME: Doesn't exist on Darwin
  123. }
  124. else
  125. {
  126. throw new NotImplementedException();
  127. }
  128. }
  129. if (OperatingSystem.IsMacOSVersionAtLeast(10, 14))
  130. {
  131. // Only to be used with the Hardened Runtime.
  132. // result |= MAP_JIT_DARWIN;
  133. }
  134. return result;
  135. }
  136. public static IntPtr mmap(IntPtr address, ulong length, MmapProts prot, MmapFlags flags, int fd, long offset)
  137. {
  138. return Internal_mmap(address, length, prot, MmapFlagsToSystemFlags(flags), fd, offset);
  139. }
  140. }
  141. }