/// <summary> /// allocate size bytes starting at a particular address /// </summary> public MemoryBlock(ulong start, ulong size) { if (OSTailoredCode.CurrentOS != OSTailoredCode.DistinctOS.Windows) { throw new InvalidOperationException("MemoryBlock ctor called on Unix"); } if (!WaterboxUtils.Aligned(start)) { throw new ArgumentOutOfRangeException(); } if (size == 0) { throw new ArgumentOutOfRangeException(); } size = WaterboxUtils.AlignUp(size); _handle = Kernel32.CreateFileMapping(Kernel32.INVALID_HANDLE_VALUE, IntPtr.Zero, Kernel32.FileMapProtection.PageExecuteReadWrite | Kernel32.FileMapProtection.SectionCommit, (uint)(size >> 32), (uint)size, null); if (_handle == IntPtr.Zero) { throw new InvalidOperationException($"{nameof(Kernel32.CreateFileMapping)}() returned NULL"); } Start = start; End = start + size; Size = size; _pageData = new Protection[GetPage(End - 1) + 1]; }
/// <summary>allocate <paramref name="size"/> bytes starting at a particular address <paramref name="start"/></summary> /// <exception cref="ArgumentOutOfRangeException"><paramref name="start"/> is not aligned or <paramref name="size"/> is <c>0</c></exception> protected MemoryBlockBase(ulong start, ulong size) { if (!WaterboxUtils.Aligned(start)) { throw new ArgumentOutOfRangeException(nameof(start), start, "start address must be aligned"); } if (size == 0) { throw new ArgumentOutOfRangeException(nameof(size), size, "cannot create 0-length block"); } Size = WaterboxUtils.AlignUp(size); AddressRange = start.RangeToExclusive(start + Size); _pageData = new Protection[1 + GetPage(AddressRange.EndInclusive)]; }
protected MemoryBlockBase(ulong start, ulong size) { if (!WaterboxUtils.Aligned(start)) { throw new ArgumentOutOfRangeException(); } if (size == 0) { throw new ArgumentOutOfRangeException(); } Start = start; Size = WaterboxUtils.AlignUp(size); End = Start + Size; _pageData = new Protection[GetPage(End - 1) + 1]; }
/// <summary> /// allocate size bytes starting at a particular address /// </summary> /// <param name="start"></param> /// <param name="size"></param> public MemoryBlockUnix(ulong start, ulong size) { if (!WaterboxUtils.Aligned(start)) { throw new ArgumentOutOfRangeException(); } if (size == 0) { throw new ArgumentOutOfRangeException(); } size = WaterboxUtils.AlignUp(size); _fd = memfd_create("MemoryBlockUnix", 0); if (_fd == -1) { throw new InvalidOperationException("memfd_create() returned -1"); } Start = start; End = start + size; Size = size; _pageData = new Protection[GetPage(End - 1) + 1]; }
/// <summary> /// allocate size bytes starting at a particular address /// </summary> /// <param name="start"></param> /// <param name="size"></param> public MemoryBlockWin32(ulong start, ulong size) { if (!WaterboxUtils.Aligned(start)) { throw new ArgumentOutOfRangeException(); } if (size == 0) { throw new ArgumentOutOfRangeException(); } size = WaterboxUtils.AlignUp(size); _handle = Kernel32.CreateFileMapping(Kernel32.INVALID_HANDLE_VALUE, IntPtr.Zero, Kernel32.FileMapProtection.PageExecuteReadWrite | Kernel32.FileMapProtection.SectionCommit, (uint)(size >> 32), (uint)size, null); if (_handle == IntPtr.Zero) { throw new InvalidOperationException("CreateFileMapping() returned NULL"); } Start = start; End = start + size; Size = size; _pageData = new Protection[GetPage(End - 1) + 1]; }