Change long -> ulong for address/size on memory related methods to avoid unnecessary casts

This commit is contained in:
gdkchan 2018-11-20 15:34:20 -03:00
parent c619596e07
commit 70e42d43d3
27 changed files with 683 additions and 655 deletions

View file

@ -7,6 +7,11 @@ namespace Ryujinx.Common
return (Value + (Size - 1)) & -Size;
}
public static ulong AlignUp(ulong Value, int Size)
{
return (ulong)AlignUp((long)Value, Size);
}
public static long AlignUp(long Value, int Size)
{
return (Value + (Size - 1)) & -(long)Size;
@ -17,11 +22,21 @@ namespace Ryujinx.Common
return Value & -Size;
}
public static ulong AlignDown(ulong Value, int Size)
{
return (ulong)AlignDown((long)Value, Size);
}
public static long AlignDown(long Value, int Size)
{
return Value & -(long)Size;
}
public static ulong DivRoundUp(ulong Value, uint Dividend)
{
return (Value + Dividend - 1) / Dividend;
}
public static long DivRoundUp(long Value, int Dividend)
{
return (Value + Dividend - 1) / Dividend;

View file

@ -25,9 +25,9 @@ namespace Ryujinx.HLE.HOS
internal const int HidSize = 0x40000;
internal const int FontSize = 0x1100000;
private const long UserSlabHeapBase = DramMemoryMap.SlabHeapBase;
private const long UserSlabHeapItemSize = KMemoryManager.PageSize;
private const long UserSlabHeapSize = 0x3de000;
private const ulong UserSlabHeapBase = DramMemoryMap.SlabHeapBase;
private const ulong UserSlabHeapItemSize = KMemoryManager.PageSize;
private const ulong UserSlabHeapSize = 0x3de000;
internal Switch Device { get; private set; }
@ -114,10 +114,10 @@ namespace Ryujinx.HLE.HOS
KMemoryRegionManager Region = MemoryRegions[(int)MemoryRegion.Service];
long HidPa = Region.Address;
long FontPa = Region.Address + HidSize;
ulong HidPa = Region.Address;
ulong FontPa = Region.Address + HidSize;
HidBaseAddress = HidPa - DramMemoryMap.DramBase;
HidBaseAddress = (long)(HidPa - DramMemoryMap.DramBase);
KPageList HidPageList = new KPageList();
KPageList FontPageList = new KPageList();
@ -132,7 +132,7 @@ namespace Ryujinx.HLE.HOS
AppletState.SetFocus(true);
Font = new SharedFontManager(Device, FontPa - DramMemoryMap.DramBase);
Font = new SharedFontManager(Device, (long)(FontPa - DramMemoryMap.DramBase));
VsyncEvent = new KEvent(this);

View file

@ -2,14 +2,14 @@ namespace Ryujinx.HLE.HOS.Kernel
{
static class DramMemoryMap
{
public const long DramBase = 0x80000000;
public const long DramSize = 0x100000000;
public const long DramEnd = DramBase + DramSize;
public const ulong DramBase = 0x80000000;
public const ulong DramSize = 0x100000000;
public const ulong DramEnd = DramBase + DramSize;
public const long KernelReserveBase = DramBase + 0x60000;
public const ulong KernelReserveBase = DramBase + 0x60000;
public const long SlabHeapBase = KernelReserveBase + 0x85000;
public const long SlapHeapSize = 0xa21000;
public const long SlabHeapEnd = SlabHeapBase + SlapHeapSize;
public const ulong SlabHeapBase = KernelReserveBase + 0x85000;
public const ulong SlapHeapSize = 0xa21000;
public const ulong SlabHeapEnd = SlabHeapBase + SlapHeapSize;
}
}

View file

@ -196,10 +196,10 @@ namespace Ryujinx.HLE.HOS.Kernel
private void ScanMemoryForTextSegments()
{
long OldAddress = 0;
long Address = 0;
ulong OldAddress = 0;
ulong Address = 0;
while ((ulong)Address >= (ulong)OldAddress)
while (Address >= OldAddress)
{
KMemoryInfo Info = Owner.MemoryManager.QueryMemory(Address);
@ -210,7 +210,7 @@ namespace Ryujinx.HLE.HOS.Kernel
if (Info.State == MemoryState.CodeStatic && Info.Permission == MemoryPermission.ReadAndExecute)
{
LoadMod0Symbols(Owner.CpuMemory, Info.Address);
LoadMod0Symbols(Owner.CpuMemory, (long)Info.Address);
}
OldAddress = Address;

View file

@ -2,12 +2,12 @@ namespace Ryujinx.HLE.HOS.Kernel
{
struct KMemoryArrangeRegion
{
public long Address { get; private set; }
public long Size { get; private set; }
public ulong Address { get; private set; }
public ulong Size { get; private set; }
public long EndAddr => Address + Size;
public ulong EndAddr => Address + Size;
public KMemoryArrangeRegion(long Address, long Size)
public KMemoryArrangeRegion(ulong Address, ulong Size)
{
this.Address = Address;
this.Size = Size;

View file

@ -2,8 +2,8 @@ namespace Ryujinx.HLE.HOS.Kernel
{
class KMemoryBlock
{
public long BaseAddress { get; set; }
public long PagesCount { get; set; }
public ulong BaseAddress { get; set; }
public ulong PagesCount { get; set; }
public MemoryState State { get; set; }
public MemoryPermission Permission { get; set; }
@ -13,8 +13,8 @@ namespace Ryujinx.HLE.HOS.Kernel
public int DeviceRefCount { get; set; }
public KMemoryBlock(
long BaseAddress,
long PagesCount,
ulong BaseAddress,
ulong PagesCount,
MemoryState State,
MemoryPermission Permission,
MemoryAttribute Attribute)
@ -28,7 +28,7 @@ namespace Ryujinx.HLE.HOS.Kernel
public KMemoryInfo GetInfo()
{
long Size = PagesCount * KMemoryManager.PageSize;
ulong Size = PagesCount * KMemoryManager.PageSize;
return new KMemoryInfo(
BaseAddress,

View file

@ -2,8 +2,8 @@ namespace Ryujinx.HLE.HOS.Kernel
{
class KMemoryInfo
{
public long Address { get; private set; }
public long Size { get; private set; }
public ulong Address { get; private set; }
public ulong Size { get; private set; }
public MemoryState State { get; private set; }
public MemoryPermission Permission { get; private set; }
@ -13,8 +13,8 @@ namespace Ryujinx.HLE.HOS.Kernel
public int DeviceRefCount { get; private set; }
public KMemoryInfo(
long Address,
long Size,
ulong Address,
ulong Size,
MemoryState State,
MemoryPermission Permission,
MemoryAttribute Attribute,

File diff suppressed because it is too large Load diff

View file

@ -4,13 +4,13 @@ namespace Ryujinx.HLE.HOS.Kernel
{
public long[][] Masks;
public long FreeCount;
public int MaxLevel;
public long StartAligned;
public long SizeInBlocksTruncated;
public long SizeInBlocksRounded;
public int Order;
public int NextOrder;
public ulong FreeCount;
public int MaxLevel;
public ulong StartAligned;
public ulong SizeInBlocksTruncated;
public ulong SizeInBlocksRounded;
public int Order;
public int NextOrder;
public bool TryCoalesce(int Index, int Size)
{
@ -35,7 +35,7 @@ namespace Ryujinx.HLE.HOS.Kernel
}
}
FreeCount -= Size;
FreeCount -= (ulong)Size;
return true;
}

View file

@ -6,15 +6,15 @@ namespace Ryujinx.HLE.HOS.Kernel
{
private static readonly int[] BlockOrders = new int[] { 12, 16, 21, 22, 25, 29, 30 };
public long Address { get; private set; }
public long EndAddr { get; private set; }
public long Size { get; private set; }
public ulong Address { get; private set; }
public ulong EndAddr { get; private set; }
public ulong Size { get; private set; }
private int BlockOrdersCount;
private KMemoryRegionBlock[] Blocks;
public KMemoryRegionManager(long Address, long Size, long EndAddr)
public KMemoryRegionManager(ulong Address, ulong Size, ulong EndAddr)
{
Blocks = new KMemoryRegionBlock[BlockOrders.Length];
@ -42,18 +42,18 @@ namespace Ryujinx.HLE.HOS.Kernel
NextBlockSize = 1 << NextOrder;
}
long StartAligned = BitUtils.AlignDown(Address, NextBlockSize);
long EndAddrAligned = BitUtils.AlignDown(EndAddr, CurrBlockSize);
ulong StartAligned = BitUtils.AlignDown(Address, NextBlockSize);
ulong EndAddrAligned = BitUtils.AlignDown(EndAddr, CurrBlockSize);
ulong SizeInBlocksTruncated = (ulong)(EndAddrAligned - StartAligned) >> BlockOrders[BlockIndex];
ulong SizeInBlocksTruncated = (EndAddrAligned - StartAligned) >> BlockOrders[BlockIndex];
long EndAddrRounded = BitUtils.AlignUp(Address + Size, NextBlockSize);
ulong EndAddrRounded = BitUtils.AlignUp(Address + Size, NextBlockSize);
ulong SizeInBlocksRounded = (ulong)(EndAddrRounded - StartAligned) >> BlockOrders[BlockIndex];
ulong SizeInBlocksRounded = (EndAddrRounded - StartAligned) >> BlockOrders[BlockIndex];
Blocks[BlockIndex].StartAligned = StartAligned;
Blocks[BlockIndex].SizeInBlocksTruncated = (long)SizeInBlocksTruncated;
Blocks[BlockIndex].SizeInBlocksRounded = (long)SizeInBlocksRounded;
Blocks[BlockIndex].SizeInBlocksTruncated = SizeInBlocksTruncated;
Blocks[BlockIndex].SizeInBlocksRounded = SizeInBlocksRounded;
ulong CurrSizeInBlocks = SizeInBlocksRounded;
@ -85,7 +85,7 @@ namespace Ryujinx.HLE.HOS.Kernel
}
}
public KernelResult AllocatePages(long PagesCount, bool Backwards, out KPageList PageList)
public KernelResult AllocatePages(ulong PagesCount, bool Backwards, out KPageList PageList)
{
lock (Blocks)
{
@ -93,7 +93,7 @@ namespace Ryujinx.HLE.HOS.Kernel
}
}
private KernelResult AllocatePagesImpl(long PagesCount, bool Backwards, out KPageList PageList)
private KernelResult AllocatePagesImpl(ulong PagesCount, bool Backwards, out KPageList PageList)
{
Backwards = false;
@ -109,10 +109,10 @@ namespace Ryujinx.HLE.HOS.Kernel
ulong BlockPagesCount = (1UL << Block.Order) / KMemoryManager.PageSize;
AvailablePages += BlockPagesCount * (ulong)Block.FreeCount;
AvailablePages += BlockPagesCount * Block.FreeCount;
}
if (AvailablePages < (ulong)PagesCount)
if (AvailablePages < PagesCount)
{
return KernelResult.OutOfMemory;
}
@ -126,15 +126,15 @@ namespace Ryujinx.HLE.HOS.Kernel
{
KMemoryRegionBlock Block = Blocks[BlockIndex];
int BestFitBlockSize = 1 << Block.Order;
ulong BestFitBlockSize = 1UL << Block.Order;
int BlockPagesCount = BestFitBlockSize / KMemoryManager.PageSize;
ulong BlockPagesCount = BestFitBlockSize / KMemoryManager.PageSize;
//Check if this is the best fit for this page size.
//If so, try allocating as much requested pages as possible.
while ((ulong)BlockPagesCount <= (ulong)PagesCount)
while (BlockPagesCount <= PagesCount)
{
long Address = 0;
ulong Address = 0;
for (int CurrBlockIndex = BlockIndex;
CurrBlockIndex < BlockOrdersCount && Address == 0;
@ -167,7 +167,7 @@ namespace Ryujinx.HLE.HOS.Kernel
}
}
if ((ulong)Block.SizeInBlocksTruncated <= (ulong)Index || ZeroMask)
if (Block.SizeInBlocksTruncated <= (ulong)Index || ZeroMask)
{
continue;
}
@ -186,7 +186,7 @@ namespace Ryujinx.HLE.HOS.Kernel
}
}
Address = Block.StartAligned + ((long)Index << Block.Order);
Address = Block.StartAligned + ((ulong)Index << Block.Order);
}
for (int CurrBlockIndex = BlockIndex;
@ -220,7 +220,7 @@ namespace Ryujinx.HLE.HOS.Kernel
}
}
if ((ulong)Block.SizeInBlocksTruncated <= (ulong)Index || ZeroMask)
if (Block.SizeInBlocksTruncated <= (ulong)Index || ZeroMask)
{
continue;
}
@ -239,7 +239,7 @@ namespace Ryujinx.HLE.HOS.Kernel
}
}
Address = Block.StartAligned + ((long)Index << Block.Order);
Address = Block.StartAligned + ((ulong)Index << Block.Order);
}
//The address being zero means that no free space was found on that order,
@ -251,7 +251,7 @@ namespace Ryujinx.HLE.HOS.Kernel
//If we are using a larger order than best fit, then we should
//split it into smaller blocks.
int FirstFreeBlockSize = 1 << Block.Order;
ulong FirstFreeBlockSize = 1UL << Block.Order;
if (FirstFreeBlockSize > BestFitBlockSize)
{
@ -304,32 +304,31 @@ namespace Ryujinx.HLE.HOS.Kernel
}
}
private void FreePages(long Address, long PagesCount)
private void FreePages(ulong Address, ulong PagesCount)
{
long EndAddr = Address + PagesCount * KMemoryManager.PageSize;
ulong EndAddr = Address + PagesCount * KMemoryManager.PageSize;
int BlockIndex = BlockOrdersCount - 1;
long AddressRounded = 0;
long EndAddrTruncated = 0;
ulong AddressRounded = 0;
ulong EndAddrTruncated = 0;
for (; BlockIndex >= 0; BlockIndex--)
{
KMemoryRegionBlock AllocInfo = Blocks[BlockIndex];
long BlockSize = 1L << AllocInfo.Order;
int BlockSize = 1 << AllocInfo.Order;
AddressRounded = (Address + BlockSize - 1) & -BlockSize;
AddressRounded = BitUtils.AlignUp (Address, BlockSize);
EndAddrTruncated = BitUtils.AlignDown(EndAddr, BlockSize);
EndAddrTruncated = EndAddr & -BlockSize;
if ((ulong)AddressRounded < (ulong)EndAddrTruncated)
if (AddressRounded < EndAddrTruncated)
{
break;
}
}
void FreeRegion(long CurrAddress)
void FreeRegion(ulong CurrAddress)
{
for (int CurrBlockIndex = BlockIndex;
CurrBlockIndex < BlockOrdersCount && CurrAddress != 0;
@ -339,7 +338,7 @@ namespace Ryujinx.HLE.HOS.Kernel
Block.FreeCount++;
ulong FreedBlocks = (ulong)(CurrAddress - Block.StartAligned) >> Block.Order;
ulong FreedBlocks = (CurrAddress - Block.StartAligned) >> Block.Order;
int Index = (int)FreedBlocks;
@ -357,23 +356,23 @@ namespace Ryujinx.HLE.HOS.Kernel
int BlockSizeDelta = 1 << (Block.NextOrder - Block.Order);
int FreedBlocksTruncated = (int)FreedBlocks & -BlockSizeDelta;
int FreedBlocksTruncated = BitUtils.AlignDown((int)FreedBlocks, BlockSizeDelta);
if (!Block.TryCoalesce(FreedBlocksTruncated, BlockSizeDelta))
{
break;
}
CurrAddress = Block.StartAligned + ((long)FreedBlocksTruncated << Block.Order);
CurrAddress = Block.StartAligned + ((ulong)FreedBlocksTruncated << Block.Order);
}
}
//Free inside aligned region.
long BaseAddress = AddressRounded;
ulong BaseAddress = AddressRounded;
while ((ulong)BaseAddress < (ulong)EndAddrTruncated)
while (BaseAddress < EndAddrTruncated)
{
long BlockSize = 1L << Blocks[BlockIndex].Order;
ulong BlockSize = 1UL << Blocks[BlockIndex].Order;
FreeRegion(BaseAddress);
@ -387,9 +386,9 @@ namespace Ryujinx.HLE.HOS.Kernel
for (BlockIndex = NextBlockIndex; BlockIndex >= 0; BlockIndex--)
{
long BlockSize = 1L << Blocks[BlockIndex].Order;
ulong BlockSize = 1UL << Blocks[BlockIndex].Order;
while ((ulong)(BaseAddress - BlockSize) >= (ulong)Address)
while (BaseAddress - BlockSize >= Address)
{
BaseAddress -= BlockSize;
@ -402,9 +401,9 @@ namespace Ryujinx.HLE.HOS.Kernel
for (BlockIndex = NextBlockIndex; BlockIndex >= 0; BlockIndex--)
{
long BlockSize = 1L << Blocks[BlockIndex].Order;
ulong BlockSize = 1UL << Blocks[BlockIndex].Order;
while ((ulong)(BaseAddress + BlockSize) <= (ulong)EndAddr)
while (BaseAddress + BlockSize <= EndAddr)
{
FreeRegion(BaseAddress);

View file

@ -12,7 +12,7 @@ namespace Ryujinx.HLE.HOS.Kernel
Nodes = new LinkedList<KPageNode>();
}
public KernelResult AddRange(long Address, long PagesCount)
public KernelResult AddRange(ulong Address, ulong PagesCount)
{
if (PagesCount != 0)
{
@ -35,9 +35,9 @@ namespace Ryujinx.HLE.HOS.Kernel
return KernelResult.Success;
}
public long GetPagesCount()
public ulong GetPagesCount()
{
long Sum = 0;
ulong Sum = 0;
foreach (KPageNode Node in Nodes)
{

View file

@ -2,10 +2,10 @@ namespace Ryujinx.HLE.HOS.Kernel
{
struct KPageNode
{
public long Address;
public long PagesCount;
public ulong Address;
public ulong PagesCount;
public KPageNode(long Address, long PagesCount)
public KPageNode(ulong Address, ulong PagesCount)
{
this.Address = Address;
this.PagesCount = PagesCount;

View file

@ -21,10 +21,8 @@ namespace Ryujinx.HLE.HOS.Kernel
public KMemoryManager MemoryManager { get; private set; }
private long TotalMemoryUsage;
private SortedDictionary<long, KTlsPageInfo> FullTlsPages;
private SortedDictionary<long, KTlsPageInfo> FreeTlsPages;
private SortedDictionary<ulong, KTlsPageInfo> FullTlsPages;
private SortedDictionary<ulong, KTlsPageInfo> FreeTlsPages;
public int DefaultCpuCore { get; private set; }
@ -32,7 +30,7 @@ namespace Ryujinx.HLE.HOS.Kernel
public KResourceLimit ResourceLimit { get; private set; }
public long PersonalMmHeapPagesCount { get; private set; }
public ulong PersonalMmHeapPagesCount { get; private set; }
private ProcessState State;
@ -59,16 +57,16 @@ namespace Ryujinx.HLE.HOS.Kernel
public long TitleId { get; private set; }
public long Pid { get; private set; }
private long CreationTimestamp;
private long Entrypoint;
private long ImageSize;
private long MainThreadStackSize;
private long MemoryUsageCapacity;
private int Category;
private long CreationTimestamp;
private ulong Entrypoint;
private ulong ImageSize;
private ulong MainThreadStackSize;
private ulong MemoryUsageCapacity;
private int Category;
public KHandleTable HandleTable { get; private set; }
public long UserExceptionContextAddress { get; private set; }
public ulong UserExceptionContextAddress { get; private set; }
private LinkedList<KThread> Threads;
@ -93,8 +91,8 @@ namespace Ryujinx.HLE.HOS.Kernel
MemoryManager = new KMemoryManager(System, CpuMemory);
FullTlsPages = new SortedDictionary<long, KTlsPageInfo>();
FreeTlsPages = new SortedDictionary<long, KTlsPageInfo>();
FullTlsPages = new SortedDictionary<ulong, KTlsPageInfo>();
FreeTlsPages = new SortedDictionary<ulong, KTlsPageInfo>();
Capabilities = new KProcessCapabilities();
@ -122,9 +120,9 @@ namespace Ryujinx.HLE.HOS.Kernel
bool AslrEnabled = ((CreationInfo.MmuFlags >> 5) & 1) != 0;
long CodeAddress = CreationInfo.CodeAddress;
ulong CodeAddress = CreationInfo.CodeAddress;
long CodeSize = (long)(uint)CreationInfo.CodePagesCount * KMemoryManager.PageSize;
ulong CodeSize = (ulong)CreationInfo.CodePagesCount * KMemoryManager.PageSize;
KernelResult Result = MemoryManager.InitializeForProcess(
AddrSpaceType,
@ -183,11 +181,11 @@ namespace Ryujinx.HLE.HOS.Kernel
this.ResourceLimit = ResourceLimit;
this.MemRegion = MemRegion;
long PersonalMmHeapSize = GetPersonalMmHeapSize(CreationInfo.PersonalMmHeapPagesCount, MemRegion);
ulong PersonalMmHeapSize = GetPersonalMmHeapSize((ulong)CreationInfo.PersonalMmHeapPagesCount, MemRegion);
long CodePagesCount = (long)(uint)CreationInfo.CodePagesCount;
ulong CodePagesCount = (ulong)CreationInfo.CodePagesCount;
long NeededSizeForProcess = PersonalMmHeapSize + CodePagesCount * KMemoryManager.PageSize;
ulong NeededSizeForProcess = PersonalMmHeapSize + CodePagesCount * KMemoryManager.PageSize;
if (NeededSizeForProcess != 0 && ResourceLimit != null)
{
@ -205,7 +203,7 @@ namespace Ryujinx.HLE.HOS.Kernel
}
}
PersonalMmHeapPagesCount = CreationInfo.PersonalMmHeapPagesCount;
PersonalMmHeapPagesCount = (ulong)CreationInfo.PersonalMmHeapPagesCount;
if (PersonalMmHeapPagesCount != 0)
{
@ -216,9 +214,9 @@ namespace Ryujinx.HLE.HOS.Kernel
bool AslrEnabled = ((CreationInfo.MmuFlags >> 5) & 1) != 0;
long CodeAddress = CreationInfo.CodeAddress;
ulong CodeAddress = CreationInfo.CodeAddress;
long CodeSize = CodePagesCount * KMemoryManager.PageSize;
ulong CodeSize = CodePagesCount * KMemoryManager.PageSize;
KernelResult Result = MemoryManager.InitializeForProcess(
AddrSpaceType,
@ -281,10 +279,10 @@ namespace Ryujinx.HLE.HOS.Kernel
return Result;
}
private bool ValidateCodeAddressAndSize(long Address, long Size)
private bool ValidateCodeAddressAndSize(ulong Address, ulong Size)
{
long CodeRegionStart;
long CodeRegionSize;
ulong CodeRegionStart;
ulong CodeRegionSize;
switch (MemoryManager.AddrSpaceWidth)
{
@ -306,18 +304,18 @@ namespace Ryujinx.HLE.HOS.Kernel
default: throw new InvalidOperationException("Invalid address space width on memory manager.");
}
long EndAddr = Address + Size;
ulong EndAddr = Address + Size;
long CodeRegionEnd = CodeRegionStart + CodeRegionSize;
ulong CodeRegionEnd = CodeRegionStart + CodeRegionSize;
if ((ulong)EndAddr <= (ulong)Address ||
(ulong)EndAddr - 1 > (ulong)CodeRegionEnd - 1)
if (EndAddr <= Address ||
EndAddr - 1 > CodeRegionEnd - 1)
{
return false;
}
if (MemoryManager.InsideHeapRegion(Address, Size) ||
MemoryManager.InsideMapRegion (Address, Size))
MemoryManager.InsideAliasRegion (Address, Size))
{
return false;
}
@ -346,7 +344,7 @@ namespace Ryujinx.HLE.HOS.Kernel
return KernelResult.InvalidCombination;
}
KernelResult Result = AllocateThreadLocalStorage(out long UserExceptionContextAddress);
KernelResult Result = AllocateThreadLocalStorage(out ulong UserExceptionContextAddress);
if (Result != KernelResult.Success)
{
@ -355,7 +353,7 @@ namespace Ryujinx.HLE.HOS.Kernel
this.UserExceptionContextAddress = UserExceptionContextAddress;
MemoryHelper.FillWithZeros(CpuMemory, UserExceptionContextAddress, KTlsPageInfo.TlsEntrySize);
MemoryHelper.FillWithZeros(CpuMemory, (long)UserExceptionContextAddress, KTlsPageInfo.TlsEntrySize);
Name = CreationInfo.Name;
@ -367,7 +365,7 @@ namespace Ryujinx.HLE.HOS.Kernel
Category = CreationInfo.Category;
TitleId = CreationInfo.TitleId;
Entrypoint = CreationInfo.CodeAddress;
ImageSize = CreationInfo.CodePagesCount * KMemoryManager.PageSize;
ImageSize = (ulong)CreationInfo.CodePagesCount * KMemoryManager.PageSize;
UseSystemMemBlocks = ((MmuFlags >> 6) & 1) != 0;
@ -395,7 +393,7 @@ namespace Ryujinx.HLE.HOS.Kernel
return KernelResult.Success;
}
public KernelResult AllocateThreadLocalStorage(out long Address)
public KernelResult AllocateThreadLocalStorage(out ulong Address)
{
System.CriticalSection.Enter();
@ -449,15 +447,15 @@ namespace Ryujinx.HLE.HOS.Kernel
{
PageInfo = default(KTlsPageInfo);
if (!System.UserSlabHeapPages.TryGetItem(out long TlsPagePa))
if (!System.UserSlabHeapPages.TryGetItem(out ulong TlsPagePa))
{
return KernelResult.OutOfMemory;
}
long RegionStart = MemoryManager.TlsIoRegionStart;
long RegionSize = MemoryManager.TlsIoRegionEnd - RegionStart;
ulong RegionStart = MemoryManager.TlsIoRegionStart;
ulong RegionSize = MemoryManager.TlsIoRegionEnd - RegionStart;
long RegionPagesCount = (long)((ulong)RegionSize / KMemoryManager.PageSize);
ulong RegionPagesCount = RegionSize / KMemoryManager.PageSize;
KernelResult Result = MemoryManager.AllocateOrMapPa(
1,
@ -468,7 +466,7 @@ namespace Ryujinx.HLE.HOS.Kernel
RegionPagesCount,
MemoryState.ThreadLocal,
MemoryPermission.ReadAndWrite,
out long TlsPageVa);
out ulong TlsPageVa);
if (Result != KernelResult.Success)
{
@ -478,15 +476,15 @@ namespace Ryujinx.HLE.HOS.Kernel
{
PageInfo = new KTlsPageInfo(TlsPageVa);
MemoryHelper.FillWithZeros(CpuMemory, TlsPageVa, KMemoryManager.PageSize);
MemoryHelper.FillWithZeros(CpuMemory, (long)TlsPageVa, KMemoryManager.PageSize);
}
return Result;
}
public KernelResult FreeThreadLocalStorage(long TlsSlotAddr)
public KernelResult FreeThreadLocalStorage(ulong TlsSlotAddr)
{
long TlsPageAddr = BitUtils.AlignDown(TlsSlotAddr, KMemoryManager.PageSize);
ulong TlsPageAddr = BitUtils.AlignDown(TlsSlotAddr, KMemoryManager.PageSize);
System.CriticalSection.Enter();
@ -531,7 +529,7 @@ namespace Ryujinx.HLE.HOS.Kernel
private KernelResult FreeTlsPage(KTlsPageInfo PageInfo)
{
KernelResult Result = MemoryManager.ConvertVaToPa(PageInfo.PageAddr, out long TlsPagePa);
KernelResult Result = MemoryManager.ConvertVaToPa(PageInfo.PageAddr, out ulong TlsPagePa);
if (Result != KernelResult.Success)
{
@ -553,7 +551,7 @@ namespace Ryujinx.HLE.HOS.Kernel
//TODO.
}
public KernelResult Start(int MainThreadPriority, long StackSize)
public KernelResult Start(int MainThreadPriority, ulong StackSize)
{
lock (ProcessLock)
{
@ -575,15 +573,15 @@ namespace Ryujinx.HLE.HOS.Kernel
throw new InvalidOperationException("Trying to start a process with a invalid state!");
}
long StackSizeRounded = BitUtils.AlignUp(StackSize, KMemoryManager.PageSize);
ulong StackSizeRounded = BitUtils.AlignUp(StackSize, KMemoryManager.PageSize);
long NeededSize = StackSizeRounded + ImageSize;
ulong NeededSize = StackSizeRounded + ImageSize;
//Check if the needed size for the code and the stack will fit on the
//memory usage capacity of this Process. Also check for possible overflow
//on the above addition.
if ((ulong)NeededSize > (ulong)MemoryUsageCapacity ||
(ulong)NeededSize < (ulong)StackSizeRounded)
if (NeededSize > MemoryUsageCapacity ||
NeededSize < StackSizeRounded)
{
ThreadResourceLimit?.Release(LimitableResource.Thread, 1);
@ -606,7 +604,7 @@ namespace Ryujinx.HLE.HOS.Kernel
KThread MainThread = null;
long StackTop = 0;
ulong StackTop = 0;
void CleanUpForError()
{
@ -615,9 +613,9 @@ namespace Ryujinx.HLE.HOS.Kernel
if (MainThreadStackSize != 0)
{
long StackBottom = StackTop - MainThreadStackSize;
ulong StackBottom = StackTop - MainThreadStackSize;
long StackPagesCount = (long)((ulong)MainThreadStackSize / KMemoryManager.PageSize);
ulong StackPagesCount = MainThreadStackSize / KMemoryManager.PageSize;
MemoryManager.UnmapForKernel(StackBottom, StackPagesCount, MemoryState.Stack);
}
@ -628,12 +626,12 @@ namespace Ryujinx.HLE.HOS.Kernel
if (StackSizeRounded != 0)
{
long StackPagesCount = (long)((ulong)StackSizeRounded / KMemoryManager.PageSize);
ulong StackPagesCount = StackSizeRounded / KMemoryManager.PageSize;
long RegionStart = MemoryManager.StackRegionStart;
long RegionSize = MemoryManager.StackRegionEnd - RegionStart;
ulong RegionStart = MemoryManager.StackRegionStart;
ulong RegionSize = MemoryManager.StackRegionEnd - RegionStart;
long RegionPagesCount = (long)((ulong)RegionSize / KMemoryManager.PageSize);
ulong RegionPagesCount = RegionSize / KMemoryManager.PageSize;
Result = MemoryManager.AllocateOrMapPa(
StackPagesCount,
@ -644,7 +642,7 @@ namespace Ryujinx.HLE.HOS.Kernel
RegionPagesCount,
MemoryState.Stack,
MemoryPermission.ReadAndWrite,
out long StackBottom);
out ulong StackBottom);
if (Result != KernelResult.Success)
{
@ -658,7 +656,7 @@ namespace Ryujinx.HLE.HOS.Kernel
StackTop = StackBottom + StackSizeRounded;
}
long HeapCapacity = MemoryUsageCapacity - MainThreadStackSize - ImageSize;
ulong HeapCapacity = MemoryUsageCapacity - MainThreadStackSize - ImageSize;
Result = MemoryManager.SetHeapCapacity(HeapCapacity);
@ -747,9 +745,9 @@ namespace Ryujinx.HLE.HOS.Kernel
public KernelResult InitializeThread(
KThread Thread,
long Entrypoint,
long ArgsPtr,
long StackTop,
ulong Entrypoint,
ulong ArgsPtr,
ulong StackTop,
int Priority,
int CpuCore)
{
@ -783,9 +781,9 @@ namespace Ryujinx.HLE.HOS.Kernel
}
}
public long GetMemoryCapacity()
public ulong GetMemoryCapacity()
{
long TotalCapacity = ResourceLimit.GetRemainingValue(LimitableResource.Memory);
ulong TotalCapacity = (ulong)ResourceLimit.GetRemainingValue(LimitableResource.Memory);
TotalCapacity += MemoryManager.GetTotalHeapSize();
@ -793,7 +791,7 @@ namespace Ryujinx.HLE.HOS.Kernel
TotalCapacity += ImageSize + MainThreadStackSize;
if ((ulong)TotalCapacity <= (ulong)MemoryUsageCapacity)
if (TotalCapacity <= MemoryUsageCapacity)
{
return TotalCapacity;
}
@ -801,28 +799,28 @@ namespace Ryujinx.HLE.HOS.Kernel
return MemoryUsageCapacity;
}
public long GetMemoryUsage()
public ulong GetMemoryUsage()
{
//TODO: Personal Mm Heap.
return ImageSize + MainThreadStackSize + MemoryManager.GetTotalHeapSize();
}
public long GetMemoryCapacityWithoutPersonalMmHeap()
public ulong GetMemoryCapacityWithoutPersonalMmHeap()
{
return GetMemoryCapacity() - GetPersonalMmHeapSize();
}
public long GetMemoryUsageWithoutPersonalMmHeap()
public ulong GetMemoryUsageWithoutPersonalMmHeap()
{
return GetMemoryUsage() - GetPersonalMmHeapSize();
}
private long GetPersonalMmHeapSize()
private ulong GetPersonalMmHeapSize()
{
return GetPersonalMmHeapSize(PersonalMmHeapPagesCount, MemRegion);
}
private static long GetPersonalMmHeapSize(long PersonalMmHeapPagesCount, MemoryRegion MemRegion)
private static ulong GetPersonalMmHeapSize(ulong PersonalMmHeapPagesCount, MemoryRegion MemRegion)
{
if (MemRegion == MemoryRegion.Applet)
{

View file

@ -5,6 +5,8 @@ namespace Ryujinx.HLE.HOS.Kernel
{
class KResourceLimit
{
private const int Time10SecondsMs = 10000;
private long[] Current;
private long[] Limit;
private long[] Available;
@ -30,10 +32,14 @@ namespace Ryujinx.HLE.HOS.Kernel
this.System = System;
}
public bool Reserve(LimitableResource Resource, ulong Amount)
{
return Reserve(Resource, (long)Amount);
}
public bool Reserve(LimitableResource Resource, long Amount)
{
//Wait 10 seconds for the resource if no timeout is specified.
return Reserve(Resource, Amount, KTimeManager.ConvertMillisecondsToNanoseconds(10000));
return Reserve(Resource, Amount, KTimeManager.ConvertMillisecondsToNanoseconds(Time10SecondsMs));
}
public bool Reserve(LimitableResource Resource, long Amount, long Timeout)
@ -77,6 +83,11 @@ namespace Ryujinx.HLE.HOS.Kernel
return Success;
}
public void Release(LimitableResource Resource, ulong Amount)
{
Release(Resource, (long)Amount);
}
public void Release(LimitableResource Resource, long Amount)
{
Release(Resource, Amount, Amount);

View file

@ -25,12 +25,12 @@ namespace Ryujinx.HLE.HOS.Kernel
public KernelResult MapIntoProcess(
KMemoryManager MemoryManager,
long Address,
long Size,
ulong Address,
ulong Size,
KProcess Process,
MemoryPermission Permission)
{
long PagesCountRounded = BitUtils.DivRoundUp(Size, KMemoryManager.PageSize);
ulong PagesCountRounded = BitUtils.DivRoundUp(Size, KMemoryManager.PageSize);
if (PageList.GetPagesCount() != PagesCountRounded)
{
@ -51,11 +51,11 @@ namespace Ryujinx.HLE.HOS.Kernel
public KernelResult UnmapFromProcess(
KMemoryManager MemoryManager,
long Address,
long Size,
ulong Address,
ulong Size,
KProcess Process)
{
long PagesCountRounded = BitUtils.DivRoundUp(Size, KMemoryManager.PageSize);
ulong PagesCountRounded = BitUtils.DivRoundUp(Size, KMemoryManager.PageSize);
if (PageList.GetPagesCount() != PagesCountRounded)
{

View file

@ -4,11 +4,11 @@ namespace Ryujinx.HLE.HOS.Kernel
{
class KSlabHeap
{
private LinkedList<long> Items;
private LinkedList<ulong> Items;
public KSlabHeap(long Pa, long ItemSize, long Size)
public KSlabHeap(ulong Pa, ulong ItemSize, ulong Size)
{
Items = new LinkedList<long>();
Items = new LinkedList<ulong>();
int ItemsCount = (int)(Size / ItemSize);
@ -20,7 +20,7 @@ namespace Ryujinx.HLE.HOS.Kernel
}
}
public bool TryGetItem(out long Pa)
public bool TryGetItem(out ulong Pa)
{
lock (Items)
{
@ -39,7 +39,7 @@ namespace Ryujinx.HLE.HOS.Kernel
return false;
}
public void Free(long Pa)
public void Free(ulong Pa)
{
lock (Items)
{

View file

@ -22,13 +22,13 @@ namespace Ryujinx.HLE.HOS.Kernel
public long CondVarAddress { get; set; }
private long Entrypoint;
private ulong Entrypoint;
public long MutexAddress { get; set; }
public KProcess Owner { get; private set; }
private long TlsAddress;
private ulong TlsAddress;
public long LastScheduledTime { get; set; }
@ -87,9 +87,9 @@ namespace Ryujinx.HLE.HOS.Kernel
}
public KernelResult Initialize(
long Entrypoint,
long ArgsPtr,
long StackTop,
ulong Entrypoint,
ulong ArgsPtr,
ulong StackTop,
int Priority,
int DefaultCpuCore,
KProcess Owner,
@ -124,7 +124,7 @@ namespace Ryujinx.HLE.HOS.Kernel
return KernelResult.OutOfMemory;
}
MemoryHelper.FillWithZeros(Owner.CpuMemory, TlsAddress, KTlsPageInfo.TlsEntrySize);
MemoryHelper.FillWithZeros(Owner.CpuMemory, (long)TlsAddress, KTlsPageInfo.TlsEntrySize);
}
bool Is64Bits;
@ -142,13 +142,13 @@ namespace Ryujinx.HLE.HOS.Kernel
Is64Bits = true;
}
Context = new CpuThread(Owner.Translator, Owner.CpuMemory, Entrypoint);
Context = new CpuThread(Owner.Translator, Owner.CpuMemory, (long)Entrypoint);
Context.ThreadState.X0 = (ulong)ArgsPtr;
Context.ThreadState.X31 = (ulong)StackTop;
Context.ThreadState.X0 = ArgsPtr;
Context.ThreadState.X31 = StackTop;
Context.ThreadState.CntfrqEl0 = 19200000;
Context.ThreadState.Tpidr = TlsAddress;
Context.ThreadState.Tpidr = (long)TlsAddress;
Owner.SubscribeThreadEventHandlers(Context);

View file

@ -4,11 +4,11 @@ namespace Ryujinx.HLE.HOS.Kernel
{
public const int TlsEntrySize = 0x200;
public long PageAddr { get; private set; }
public ulong PageAddr { get; private set; }
private bool[] IsSlotFree;
public KTlsPageInfo(long PageAddress)
public KTlsPageInfo(ulong PageAddress)
{
this.PageAddr = PageAddress;
@ -20,7 +20,7 @@ namespace Ryujinx.HLE.HOS.Kernel
}
}
public bool TryGetFreePage(out long Address)
public bool TryGetFreePage(out ulong Address)
{
Address = PageAddr;
@ -65,7 +65,7 @@ namespace Ryujinx.HLE.HOS.Kernel
return AllFree;
}
public void FreeTlsSlot(long Address)
public void FreeTlsSlot(ulong Address)
{
IsSlotFree[(Address - PageAddr) / TlsEntrySize] = true;
}

View file

@ -2,13 +2,13 @@ namespace Ryujinx.HLE.HOS.Kernel
{
class KTransferMemory
{
public long Position { get; private set; }
public long Size { get; private set; }
public ulong Address { get; private set; }
public ulong Size { get; private set; }
public KTransferMemory(long Position, long Size)
public KTransferMemory(ulong Address, ulong Size)
{
this.Position = Position;
this.Size = Size;
this.Address = Address;
this.Size = Size;
}
}
}

View file

@ -59,23 +59,23 @@ namespace Ryujinx.HLE.HOS.Kernel
ulong RamSize = (ulong)GetRamSize(KernelMemoryCfg);
long RamPart0;
long RamPart1;
ulong RamPart0;
ulong RamPart1;
if (RamSize * 2 > EmemApertureSize)
{
RamPart0 = (long)(EmemApertureSize / 2);
RamPart1 = (long)(EmemApertureSize / 2);
RamPart0 = EmemApertureSize / 2;
RamPart1 = EmemApertureSize / 2;
}
else
{
RamPart0 = (long)EmemApertureSize;
RamPart0 = EmemApertureSize;
RamPart1 = 0;
}
int MemoryArrange = 1;
long ApplicationRgSize;
ulong ApplicationRgSize;
switch (MemoryArrange)
{
@ -85,7 +85,7 @@ namespace Ryujinx.HLE.HOS.Kernel
default: ApplicationRgSize = 0xcd500000; break;
}
long AppletRgSize;
ulong AppletRgSize;
switch (MemoryArrange)
{
@ -102,13 +102,13 @@ namespace Ryujinx.HLE.HOS.Kernel
KMemoryArrangeRegion AppletRg;
KMemoryArrangeRegion ApplicationRg;
const long NvServicesRgSize = 0x29ba000;
const ulong NvServicesRgSize = 0x29ba000;
long ApplicationRgEnd = DramMemoryMap.DramEnd; //- RamPart0;
ulong ApplicationRgEnd = DramMemoryMap.DramEnd; //- RamPart0;
ApplicationRg = new KMemoryArrangeRegion(ApplicationRgEnd - ApplicationRgSize, ApplicationRgSize);
long NvServicesRgEnd = ApplicationRg.Address - AppletRgSize;
ulong NvServicesRgEnd = ApplicationRg.Address - AppletRgSize;
NvServicesRg = new KMemoryArrangeRegion(NvServicesRgEnd - NvServicesRgSize, NvServicesRgSize);
AppletRg = new KMemoryArrangeRegion(NvServicesRgEnd, AppletRgSize);
@ -116,7 +116,7 @@ namespace Ryujinx.HLE.HOS.Kernel
//Note: There is an extra region used by the kernel, however
//since we are doing HLE we are not going to use that memory, so give all
//the remaining memory space to services.
long ServiceRgSize = NvServicesRg.Address - DramMemoryMap.SlabHeapEnd;
ulong ServiceRgSize = NvServicesRg.Address - DramMemoryMap.SlabHeapEnd;
ServiceRg = new KMemoryArrangeRegion(DramMemoryMap.SlabHeapEnd, ServiceRgSize);

View file

@ -7,8 +7,8 @@ namespace Ryujinx.HLE.HOS.Kernel
public int Category { get; private set; }
public long TitleId { get; private set; }
public long CodeAddress { get; private set; }
public int CodePagesCount { get; private set; }
public ulong CodeAddress { get; private set; }
public int CodePagesCount { get; private set; }
public int MmuFlags { get; private set; }
public int ResourceLimitHandle { get; private set; }
@ -18,7 +18,7 @@ namespace Ryujinx.HLE.HOS.Kernel
string Name,
int Category,
long TitleId,
long CodeAddress,
ulong CodeAddress,
int CodePagesCount,
int MmuFlags,
int ResourceLimitHandle,

View file

@ -20,13 +20,13 @@ namespace Ryujinx.HLE.HOS.Kernel
return;
}
KernelResult Result = Process.MemoryManager.SetHeapSize((long)Size, out long Position);
KernelResult Result = Process.MemoryManager.SetHeapSize(Size, out ulong Position);
ThreadState.X0 = (ulong)Result;
if (Result == KernelResult.Success)
{
ThreadState.X1 = (ulong)Position;
ThreadState.X1 = Position;
}
else
{
@ -36,8 +36,8 @@ namespace Ryujinx.HLE.HOS.Kernel
private void SvcSetMemoryAttribute(CpuThreadState ThreadState)
{
long Position = (long)ThreadState.X0;
long Size = (long)ThreadState.X1;
ulong Position = ThreadState.X0;
ulong Size = ThreadState.X1;
if (!PageAligned(Position))
{
@ -84,7 +84,7 @@ namespace Ryujinx.HLE.HOS.Kernel
}
else
{
Memory.StopObservingRegion(Position, Size);
Memory.StopObservingRegion((long)Position, (long)Size);
}
ThreadState.X0 = (ulong)Result;
@ -92,9 +92,9 @@ namespace Ryujinx.HLE.HOS.Kernel
private void SvcMapMemory(CpuThreadState ThreadState)
{
long Dst = (long)ThreadState.X0;
long Src = (long)ThreadState.X1;
long Size = (long)ThreadState.X2;
ulong Dst = ThreadState.X0;
ulong Src = ThreadState.X1;
ulong Size = ThreadState.X2;
if (!PageAligned(Src | Dst))
{
@ -114,7 +114,7 @@ namespace Ryujinx.HLE.HOS.Kernel
return;
}
if ((ulong)(Src + Size) <= (ulong)Src || (ulong)(Dst + Size) <= (ulong)Dst)
if (Src + Size <= Src || Dst + Size <= Dst)
{
Logger.PrintWarning(LogClass.KernelSvc, "Addresses outside of range!");
@ -123,7 +123,9 @@ namespace Ryujinx.HLE.HOS.Kernel
return;
}
if (!InsideAddrSpace(Src, Size))
KProcess CurrentProcess = System.Scheduler.GetCurrentProcess();
if (!CurrentProcess.MemoryManager.InsideAddrSpace(Src, Size))
{
Logger.PrintWarning(LogClass.KernelSvc, $"Src address 0x{Src:x16} out of range!");
@ -132,7 +134,9 @@ namespace Ryujinx.HLE.HOS.Kernel
return;
}
if (!InsideNewMapRegion(Dst, Size))
if (CurrentProcess.MemoryManager.OutsideStackRegion(Dst, Size) ||
CurrentProcess.MemoryManager.InsideHeapRegion (Dst, Size) ||
CurrentProcess.MemoryManager.InsideAliasRegion (Dst, Size))
{
Logger.PrintWarning(LogClass.KernelSvc, $"Dst address 0x{Dst:x16} out of range!");
@ -153,9 +157,9 @@ namespace Ryujinx.HLE.HOS.Kernel
private void SvcUnmapMemory(CpuThreadState ThreadState)
{
long Dst = (long)ThreadState.X0;
long Src = (long)ThreadState.X1;
long Size = (long)ThreadState.X2;
ulong Dst = ThreadState.X0;
ulong Src = ThreadState.X1;
ulong Size = ThreadState.X2;
if (!PageAligned(Src | Dst))
{
@ -175,7 +179,7 @@ namespace Ryujinx.HLE.HOS.Kernel
return;
}
if ((ulong)(Src + Size) <= (ulong)Src || (ulong)(Dst + Size) <= (ulong)Dst)
if (Src + Size <= Src || Dst + Size <= Dst)
{
Logger.PrintWarning(LogClass.KernelSvc, "Addresses outside of range!");
@ -184,7 +188,9 @@ namespace Ryujinx.HLE.HOS.Kernel
return;
}
if (!InsideAddrSpace(Src, Size))
KProcess CurrentProcess = System.Scheduler.GetCurrentProcess();
if (!CurrentProcess.MemoryManager.InsideAddrSpace(Src, Size))
{
Logger.PrintWarning(LogClass.KernelSvc, $"Src address 0x{Src:x16} out of range!");
@ -193,7 +199,9 @@ namespace Ryujinx.HLE.HOS.Kernel
return;
}
if (!InsideNewMapRegion(Dst, Size))
if (CurrentProcess.MemoryManager.OutsideStackRegion(Dst, Size) ||
CurrentProcess.MemoryManager.InsideHeapRegion (Dst, Size) ||
CurrentProcess.MemoryManager.InsideAliasRegion (Dst, Size))
{
Logger.PrintWarning(LogClass.KernelSvc, $"Dst address 0x{Dst:x16} out of range!");
@ -214,19 +222,19 @@ namespace Ryujinx.HLE.HOS.Kernel
private void SvcQueryMemory(CpuThreadState ThreadState)
{
long InfoPtr = (long)ThreadState.X0;
long Position = (long)ThreadState.X2;
long InfoPtr = (long)ThreadState.X0;
ulong Position = ThreadState.X2;
KMemoryInfo BlkInfo = Process.MemoryManager.QueryMemory(Position);
Memory.WriteInt64(InfoPtr + 0x00, BlkInfo.Address);
Memory.WriteInt64(InfoPtr + 0x08, BlkInfo.Size);
Memory.WriteInt32(InfoPtr + 0x10, (int)BlkInfo.State & 0xff);
Memory.WriteInt32(InfoPtr + 0x14, (int)BlkInfo.Attribute);
Memory.WriteInt32(InfoPtr + 0x18, (int)BlkInfo.Permission);
Memory.WriteInt32(InfoPtr + 0x1c, BlkInfo.IpcRefCount);
Memory.WriteInt32(InfoPtr + 0x20, BlkInfo.DeviceRefCount);
Memory.WriteInt32(InfoPtr + 0x24, 0);
Memory.WriteUInt64(InfoPtr + 0x00, BlkInfo.Address);
Memory.WriteUInt64(InfoPtr + 0x08, BlkInfo.Size);
Memory.WriteInt32 (InfoPtr + 0x10, (int)BlkInfo.State & 0xff);
Memory.WriteInt32 (InfoPtr + 0x14, (int)BlkInfo.Attribute);
Memory.WriteInt32 (InfoPtr + 0x18, (int)BlkInfo.Permission);
Memory.WriteInt32 (InfoPtr + 0x1c, BlkInfo.IpcRefCount);
Memory.WriteInt32 (InfoPtr + 0x20, BlkInfo.DeviceRefCount);
Memory.WriteInt32 (InfoPtr + 0x24, 0);
ThreadState.X0 = 0;
ThreadState.X1 = 0;
@ -234,9 +242,9 @@ namespace Ryujinx.HLE.HOS.Kernel
private void SvcMapSharedMemory(CpuThreadState ThreadState)
{
int Handle = (int)ThreadState.X0;
long Address = (long)ThreadState.X1;
long Size = (long)ThreadState.X2;
int Handle = (int)ThreadState.X0;
ulong Address = ThreadState.X1;
ulong Size = ThreadState.X2;
if (!PageAligned(Address))
{
@ -289,7 +297,9 @@ namespace Ryujinx.HLE.HOS.Kernel
return;
}
if (!InsideAddrSpace(Address, Size) || InsideMapRegion(Address, Size) || InsideHeapRegion(Address, Size))
if (CurrentProcess.MemoryManager.IsInvalidRegion (Address, Size) ||
CurrentProcess.MemoryManager.InsideHeapRegion (Address, Size) ||
CurrentProcess.MemoryManager.InsideAliasRegion(Address, Size))
{
Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Address:x16} out of range!");
@ -315,13 +325,13 @@ namespace Ryujinx.HLE.HOS.Kernel
private void SvcUnmapSharedMemory(CpuThreadState ThreadState)
{
int Handle = (int)ThreadState.X0;
long Position = (long)ThreadState.X1;
long Size = (long)ThreadState.X2;
int Handle = (int)ThreadState.X0;
ulong Address = ThreadState.X1;
ulong Size = ThreadState.X2;
if (!PageAligned(Position))
if (!PageAligned(Address))
{
Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Position:x16} is not page aligned!");
Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Address:x16} is not page aligned!");
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress);
@ -337,9 +347,9 @@ namespace Ryujinx.HLE.HOS.Kernel
return;
}
if ((ulong)(Position + Size) <= (ulong)Position)
if ((ulong)(Address + Size) <= (ulong)Address)
{
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid region address 0x{Position:x16} / size 0x{Size:x16}!");
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid region address 0x{Address:x16} / size 0x{Size:x16}!");
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
@ -359,9 +369,11 @@ namespace Ryujinx.HLE.HOS.Kernel
return;
}
if (!InsideAddrSpace(Position, Size) || InsideMapRegion(Position, Size) || InsideHeapRegion(Position, Size))
if (CurrentProcess.MemoryManager.IsInvalidRegion (Address, Size) ||
CurrentProcess.MemoryManager.InsideHeapRegion (Address, Size) ||
CurrentProcess.MemoryManager.InsideAliasRegion(Address, Size))
{
Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Position:x16} out of range!");
Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Address:x16} out of range!");
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
@ -370,7 +382,7 @@ namespace Ryujinx.HLE.HOS.Kernel
KernelResult Result = SharedMemory.UnmapFromProcess(
CurrentProcess.MemoryManager,
Position,
Address,
Size,
CurrentProcess);
@ -384,12 +396,12 @@ namespace Ryujinx.HLE.HOS.Kernel
private void SvcCreateTransferMemory(CpuThreadState ThreadState)
{
long Position = (long)ThreadState.X1;
long Size = (long)ThreadState.X2;
ulong Address = ThreadState.X1;
ulong Size = ThreadState.X2;
if (!PageAligned(Position))
if (!PageAligned(Address))
{
Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Position:x16} is not page aligned!");
Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Address:x16} is not page aligned!");
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress);
@ -405,9 +417,9 @@ namespace Ryujinx.HLE.HOS.Kernel
return;
}
if ((ulong)(Position + Size) <= (ulong)Position)
if ((ulong)(Address + Size) <= (ulong)Address)
{
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid region address 0x{Position:x16} / size 0x{Size:x16}!");
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid region address 0x{Address:x16} / size 0x{Size:x16}!");
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
@ -425,9 +437,9 @@ namespace Ryujinx.HLE.HOS.Kernel
return;
}
Process.MemoryManager.ReserveTransferMemory(Position, Size, Permission);
Process.MemoryManager.ReserveTransferMemory(Address, Size, Permission);
KTransferMemory TransferMemory = new KTransferMemory(Position, Size);
KTransferMemory TransferMemory = new KTransferMemory(Address, Size);
KernelResult Result = Process.HandleTable.GenerateHandle(TransferMemory, out int Handle);
@ -437,12 +449,12 @@ namespace Ryujinx.HLE.HOS.Kernel
private void SvcMapPhysicalMemory(CpuThreadState ThreadState)
{
long Position = (long)ThreadState.X0;
long Size = (long)ThreadState.X1;
ulong Address = ThreadState.X0;
ulong Size = ThreadState.X1;
if (!PageAligned(Position))
if (!PageAligned(Address))
{
Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Position:x16} is not page aligned!");
Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Address:x16} is not page aligned!");
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress);
@ -458,25 +470,37 @@ namespace Ryujinx.HLE.HOS.Kernel
return;
}
if ((ulong)(Position + Size) <= (ulong)Position)
if (Address + Size <= Address)
{
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid region address 0x{Position:x16} / size 0x{Size:x16}!");
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid region address 0x{Address:x16} / size 0x{Size:x16}!");
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
return;
}
if (!InsideAddrSpace(Position, Size))
KProcess CurrentProcess = System.Scheduler.GetCurrentProcess();
if ((CurrentProcess.PersonalMmHeapPagesCount & 0xfffffffffffff) == 0)
{
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid address {Position:x16}!");
Logger.PrintWarning(LogClass.KernelSvc, $"System resource size is zero.");
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidState);
return;
}
if (!CurrentProcess.MemoryManager.InsideAddrSpace (Address, Size) ||
CurrentProcess.MemoryManager.OutsideAliasRegion(Address, Size))
{
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid address {Address:x16}.");
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
return;
}
KernelResult Result = Process.MemoryManager.MapPhysicalMemory(Position, Size);
KernelResult Result = Process.MemoryManager.MapPhysicalMemory(Address, Size);
if (Result != KernelResult.Success)
{
@ -488,12 +512,12 @@ namespace Ryujinx.HLE.HOS.Kernel
private void SvcUnmapPhysicalMemory(CpuThreadState ThreadState)
{
long Position = (long)ThreadState.X0;
long Size = (long)ThreadState.X1;
ulong Address = ThreadState.X0;
ulong Size = ThreadState.X1;
if (!PageAligned(Position))
if (!PageAligned(Address))
{
Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Position:x16} is not page aligned!");
Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Address:x16} is not page aligned!");
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress);
@ -509,25 +533,37 @@ namespace Ryujinx.HLE.HOS.Kernel
return;
}
if ((ulong)(Position + Size) <= (ulong)Position)
if ((ulong)(Address + Size) <= (ulong)Address)
{
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid region address 0x{Position:x16} / size 0x{Size:x16}!");
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid region address 0x{Address:x16} / size 0x{Size:x16}!");
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
return;
}
if (!InsideAddrSpace(Position, Size))
KProcess CurrentProcess = System.Scheduler.GetCurrentProcess();
if ((CurrentProcess.PersonalMmHeapPagesCount & 0xfffffffffffff) == 0)
{
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid address {Position:x16}!");
Logger.PrintWarning(LogClass.KernelSvc, $"System resource size is zero.");
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidState);
return;
}
if (!CurrentProcess.MemoryManager.InsideAddrSpace (Address, Size) ||
CurrentProcess.MemoryManager.OutsideAliasRegion(Address, Size))
{
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid address {Address:x16}.");
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
return;
}
KernelResult Result = Process.MemoryManager.UnmapPhysicalMemory(Position, Size);
KernelResult Result = Process.MemoryManager.UnmapPhysicalMemory(Address, Size);
if (Result != KernelResult.Success)
{
@ -537,45 +573,9 @@ namespace Ryujinx.HLE.HOS.Kernel
ThreadState.X0 = (ulong)Result;
}
private static bool PageAligned(long Position)
private static bool PageAligned(ulong Position)
{
return (Position & (KMemoryManager.PageSize - 1)) == 0;
}
private bool InsideAddrSpace(long Position, long Size)
{
ulong Start = (ulong)Position;
ulong End = (ulong)Size + Start;
return Start >= (ulong)Process.MemoryManager.AddrSpaceStart &&
End < (ulong)Process.MemoryManager.AddrSpaceEnd;
}
private bool InsideMapRegion(long Position, long Size)
{
ulong Start = (ulong)Position;
ulong End = (ulong)Size + Start;
return Start >= (ulong)Process.MemoryManager.AliasRegionStart &&
End < (ulong)Process.MemoryManager.AliasRegionEnd;
}
private bool InsideHeapRegion(long Position, long Size)
{
ulong Start = (ulong)Position;
ulong End = (ulong)Size + Start;
return Start >= (ulong)Process.MemoryManager.HeapRegionStart &&
End < (ulong)Process.MemoryManager.HeapRegionEnd;
}
private bool InsideNewMapRegion(long Position, long Size)
{
ulong Start = (ulong)Position;
ulong End = (ulong)Size + Start;
return Start >= (ulong)Process.MemoryManager.StackRegionStart &&
End < (ulong)Process.MemoryManager.StackRegionEnd;
}
}
}

View file

@ -107,7 +107,7 @@ namespace Ryujinx.HLE.HOS.Kernel
else if (Obj is KTransferMemory TransferMemory)
{
Process.MemoryManager.ResetTransferMemory(
TransferMemory.Position,
TransferMemory.Address,
TransferMemory.Size);
}
@ -339,27 +339,27 @@ namespace Ryujinx.HLE.HOS.Kernel
case 0: Value = Process.Capabilities.AllowedCpuCoresMask; break;
case 1: Value = Process.Capabilities.AllowedThreadPriosMask; break;
case 2: Value = Process.MemoryManager.AliasRegionStart; break;
case 3: Value = Process.MemoryManager.AliasRegionEnd -
Process.MemoryManager.AliasRegionStart; break;
case 2: Value = (long)Process.MemoryManager.AliasRegionStart; break;
case 3: Value = (long)(Process.MemoryManager.AliasRegionEnd -
Process.MemoryManager.AliasRegionStart); break;
case 4: Value = Process.MemoryManager.HeapRegionStart; break;
case 5: Value = Process.MemoryManager.HeapRegionEnd -
Process.MemoryManager.HeapRegionStart; break;
case 4: Value = (long)Process.MemoryManager.HeapRegionStart; break;
case 5: Value = (long)(Process.MemoryManager.HeapRegionEnd -
Process.MemoryManager.HeapRegionStart); break;
case 6: Value = Process.GetMemoryCapacity(); break;
case 6: Value = (long)Process.GetMemoryCapacity(); break;
case 7: Value = Process.GetMemoryUsage(); break;
case 7: Value = (long)Process.GetMemoryUsage(); break;
case 12: Value = Process.MemoryManager.GetAddrSpaceBaseAddr(); break;
case 12: Value = (long)Process.MemoryManager.GetAddrSpaceBaseAddr(); break;
case 13: Value = Process.MemoryManager.GetAddrSpaceSize(); break;
case 13: Value = (long)Process.MemoryManager.GetAddrSpaceSize(); break;
case 14: Value = Process.MemoryManager.StackRegionStart; break;
case 15: Value = Process.MemoryManager.StackRegionEnd -
Process.MemoryManager.StackRegionStart; break;
case 14: Value = (long)Process.MemoryManager.StackRegionStart; break;
case 15: Value = (long)(Process.MemoryManager.StackRegionEnd -
Process.MemoryManager.StackRegionStart); break;
case 16: Value = Process.PersonalMmHeapPagesCount * KMemoryManager.PageSize; break;
case 16: Value = (long)Process.PersonalMmHeapPagesCount * KMemoryManager.PageSize; break;
case 17:
if (Process.PersonalMmHeapPagesCount != 0)
@ -371,11 +371,11 @@ namespace Ryujinx.HLE.HOS.Kernel
case 18: Value = Process.TitleId; break;
case 20: Value = Process.UserExceptionContextAddress; break;
case 20: Value = (long)Process.UserExceptionContextAddress; break;
case 21: Value = Process.GetMemoryCapacityWithoutPersonalMmHeap(); break;
case 21: Value = (long)Process.GetMemoryCapacityWithoutPersonalMmHeap(); break;
case 22: Value = Process.GetMemoryUsageWithoutPersonalMmHeap(); break;
case 22: Value = (long)Process.GetMemoryUsageWithoutPersonalMmHeap(); break;
}
break;

View file

@ -9,11 +9,11 @@ namespace Ryujinx.HLE.HOS.Kernel
{
private void CreateThread64(CpuThreadState ThreadState)
{
long Entrypoint = (long)ThreadState.X1;
long ArgsPtr = (long)ThreadState.X2;
long StackTop = (long)ThreadState.X3;
int Priority = (int)ThreadState.X4;
int CpuCore = (int)ThreadState.X5;
ulong Entrypoint = ThreadState.X1;
ulong ArgsPtr = ThreadState.X2;
ulong StackTop = ThreadState.X3;
int Priority = (int)ThreadState.X4;
int CpuCore = (int)ThreadState.X5;
KernelResult Result = CreateThread(Entrypoint, ArgsPtr, StackTop, Priority, CpuCore, out int Handle);
@ -22,9 +22,9 @@ namespace Ryujinx.HLE.HOS.Kernel
}
private KernelResult CreateThread(
long Entrypoint,
long ArgsPtr,
long StackTop,
ulong Entrypoint,
ulong ArgsPtr,
ulong StackTop,
int Priority,
int CpuCore,
out int Handle)

View file

@ -19,12 +19,12 @@ namespace Ryujinx.HLE.HOS
IExecutable[] StaticObjects,
byte[] Arguments = null)
{
long ArgsStart = 0;
int ArgsSize = 0;
long CodeStart = 0x8000000;
int CodeSize = 0;
ulong ArgsStart = 0;
int ArgsSize = 0;
ulong CodeStart = 0x8000000;
int CodeSize = 0;
long[] NsoBase = new long[StaticObjects.Length];
ulong[] NsoBase = new ulong[StaticObjects.Length];
for (int Index = 0; Index < StaticObjects.Length; Index++)
{
@ -48,13 +48,13 @@ namespace Ryujinx.HLE.HOS
NsoSize = BitUtils.AlignUp(NsoSize, KMemoryManager.PageSize);
NsoBase[Index] = CodeStart + CodeSize;
NsoBase[Index] = CodeStart + (ulong)CodeSize;
CodeSize += NsoSize;
if (Arguments != null && ArgsSize == 0)
{
ArgsStart = CodeSize;
ArgsStart = (ulong)CodeSize;
ArgsSize = BitUtils.AlignDown(Arguments.Length * 2 + ArgsTotalSize - 1, KMemoryManager.PageSize);
@ -82,7 +82,7 @@ namespace Ryujinx.HLE.HOS
KResourceLimit ResourceLimit = new KResourceLimit(System);
long ApplicationRgSize = System.MemoryRegions[(int)MemoryRegion.Application].Size;
long ApplicationRgSize = (long)System.MemoryRegions[(int)MemoryRegion.Application].Size;
Result = ResourceLimit.SetLimitValue(LimitableResource.Memory, ApplicationRgSize);
Result |= ResourceLimit.SetLimitValue(LimitableResource.Thread, 608);
@ -114,26 +114,26 @@ namespace Ryujinx.HLE.HOS
{
IExecutable StaticObject = StaticObjects[Index];
long TextStart = NsoBase[Index] + StaticObject.TextOffset;
long ROStart = NsoBase[Index] + StaticObject.ROOffset;
long DataStart = NsoBase[Index] + StaticObject.DataOffset;
ulong TextStart = NsoBase[Index] + (ulong)StaticObject.TextOffset;
ulong ROStart = NsoBase[Index] + (ulong)StaticObject.ROOffset;
ulong DataStart = NsoBase[Index] + (ulong)StaticObject.DataOffset;
long BssStart = DataStart + StaticObject.Data.Length;
ulong BssStart = DataStart + (ulong)StaticObject.Data.Length;
long BssEnd = BitUtils.AlignUp(BssStart + StaticObject.BssSize, KMemoryManager.PageSize);
ulong BssEnd = BitUtils.AlignUp(BssStart + (ulong)StaticObject.BssSize, KMemoryManager.PageSize);
Process.CpuMemory.WriteBytes(TextStart, StaticObject.Text);
Process.CpuMemory.WriteBytes(ROStart, StaticObject.RO);
Process.CpuMemory.WriteBytes(DataStart, StaticObject.Data);
Process.CpuMemory.WriteBytes((long)TextStart, StaticObject.Text);
Process.CpuMemory.WriteBytes((long)ROStart, StaticObject.RO);
Process.CpuMemory.WriteBytes((long)DataStart, StaticObject.Data);
MemoryHelper.FillWithZeros(Process.CpuMemory, BssStart, (int)(BssEnd - BssStart));
MemoryHelper.FillWithZeros(Process.CpuMemory, (long)BssStart, (int)(BssEnd - BssStart));
Process.MemoryManager.SetProcessMemoryPermission(TextStart, ROStart - TextStart, MemoryPermission.ReadAndExecute);
Process.MemoryManager.SetProcessMemoryPermission(ROStart, DataStart - ROStart, MemoryPermission.Read);
Process.MemoryManager.SetProcessMemoryPermission(DataStart, BssEnd - DataStart, MemoryPermission.ReadAndWrite);
}
Result = Process.Start(MetaData.MainThreadPriority, MetaData.MainThreadStackSize);
Result = Process.Start(MetaData.MainThreadPriority, (ulong)MetaData.MainThreadStackSize);
if (Result != KernelResult.Success)
{

View file

@ -65,15 +65,15 @@ namespace Ryujinx.HLE.HOS.Services.Ldr
{
public NxRelocatableObject Executable { get; private set; }
public byte[] Hash { get; private set; }
public long NroAddress { get; private set; }
public long TotalSize { get; private set; }
public long NroMappedAddress { get; set; }
public ulong NroAddress { get; private set; }
public ulong TotalSize { get; private set; }
public ulong NroMappedAddress { get; set; }
public NroInfo(NxRelocatableObject Executable, byte[] Hash, long TotalSize)
public NroInfo(NxRelocatableObject Executable, byte[] Hash, ulong TotalSize)
{
this.Executable = Executable;
this.Hash = Hash;
this.TotalSize = TotalSize;
this.TotalSize = TotalSize;
}
}
@ -175,7 +175,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldr
return false;
}
public long ParseNro(out NroInfo Res, ServiceCtx Context, long NroHeapAddress, long NroSize, long BssHeapAddress, long BssSize)
public long ParseNro(out NroInfo Res, ServiceCtx Context, ulong NroHeapAddress, ulong NroSize, ulong BssHeapAddress, ulong BssSize)
{
Res = null;
@ -196,15 +196,15 @@ namespace Ryujinx.HLE.HOS.Services.Ldr
return MakeError(ErrorModule.Loader, LoaderErr.UnalignedAddress);
}
uint Magic = Context.Memory.ReadUInt32(NroHeapAddress + 0x10);
uint NroFileSize = Context.Memory.ReadUInt32(NroHeapAddress + 0x18);
uint Magic = Context.Memory.ReadUInt32((long)NroHeapAddress + 0x10);
uint NroFileSize = Context.Memory.ReadUInt32((long)NroHeapAddress + 0x18);
if (Magic != NroMagic || NroSize != NroFileSize)
{
return MakeError(ErrorModule.Loader, LoaderErr.InvalidNro);
}
byte[] NroData = Context.Memory.ReadBytes(NroHeapAddress, NroSize);
byte[] NroData = Context.Memory.ReadBytes((long)NroHeapAddress, (long)NroSize);
byte[] NroHash = null;
MemoryStream Stream = new MemoryStream(NroData);
@ -244,26 +244,29 @@ namespace Ryujinx.HLE.HOS.Services.Ldr
}
// finally check the bss size match.
if (Executable.BssSize != BssSize)
if ((ulong)Executable.BssSize != BssSize)
{
return MakeError(ErrorModule.Loader, LoaderErr.InvalidNro);
}
Res = new NroInfo(Executable, NroHash, Executable.Text.Length + Executable.RO.Length + Executable.Data.Length + Executable.BssSize);
int TotalSize = Executable.Text.Length + Executable.RO.Length + Executable.Data.Length + Executable.BssSize;
Res = new NroInfo(Executable, NroHash, (ulong)TotalSize);
return 0;
}
private long MapNro(ServiceCtx Context, NroInfo Info, out long NroMappedAddress)
private long MapNro(ServiceCtx Context, NroInfo Info, out ulong NroMappedAddress)
{
NroMappedAddress = 0;
long TargetAddress = Context.Process.MemoryManager.AddrSpaceStart;
long HeapRegionStart = Context.Process.MemoryManager.HeapRegionStart;
long HeapRegionEnd = Context.Process.MemoryManager.HeapRegionEnd;
ulong TargetAddress = Context.Process.MemoryManager.AddrSpaceStart;
long MapRegionStart = Context.Process.MemoryManager.AliasRegionStart;
long MapRegionEnd = Context.Process.MemoryManager.AliasRegionEnd;
ulong HeapRegionStart = Context.Process.MemoryManager.HeapRegionStart;
ulong HeapRegionEnd = Context.Process.MemoryManager.HeapRegionEnd;
ulong MapRegionStart = Context.Process.MemoryManager.AliasRegionStart;
ulong MapRegionEnd = Context.Process.MemoryManager.AliasRegionEnd;
while (true)
{
@ -309,7 +312,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldr
return MakeError(ErrorModule.Loader, LoaderErr.BadNrrAddress);
}
private long RemoveNroInfo(ServiceCtx Context, long NroMappedAddress, long NroHeapAddress)
private long RemoveNroInfo(ServiceCtx Context, ulong NroMappedAddress, ulong NroHeapAddress)
{
foreach (NroInfo Info in NroInfos)
{
@ -319,11 +322,17 @@ namespace Ryujinx.HLE.HOS.Services.Ldr
//Context.Process.RemoveProgram(Info.NroMappedAddress);
KernelResult Result = Context.Process.MemoryManager.UnmapProcessCodeMemory(Info.NroMappedAddress, Info.Executable.SourceAddress, Info.TotalSize - Info.Executable.BssSize);
KernelResult Result = Context.Process.MemoryManager.UnmapProcessCodeMemory(
Info.NroMappedAddress,
Info.Executable.SourceAddress,
Info.TotalSize - (ulong)Info.Executable.BssSize);
if (Result == KernelResult.Success && Info.Executable.BssSize != 0)
{
Result = Context.Process.MemoryManager.UnmapProcessCodeMemory(Info.NroMappedAddress + Info.TotalSize - Info.Executable.BssSize, Info.Executable.BssAddress, Info.Executable.BssSize);
Result = Context.Process.MemoryManager.UnmapProcessCodeMemory(
Info.NroMappedAddress + Info.TotalSize - (ulong)Info.Executable.BssSize,
Info.Executable.BssAddress,
(ulong)Info.Executable.BssSize);
}
return (long)Result;
@ -341,12 +350,12 @@ namespace Ryujinx.HLE.HOS.Services.Ldr
// Zero
Context.RequestData.ReadUInt64();
long NroHeapAddress = Context.RequestData.ReadInt64();
long NroSize = Context.RequestData.ReadInt64();
long BssHeapAddress = Context.RequestData.ReadInt64();
long BssSize = Context.RequestData.ReadInt64();
ulong NroHeapAddress = Context.RequestData.ReadUInt64();
ulong NroSize = Context.RequestData.ReadUInt64();
ulong BssHeapAddress = Context.RequestData.ReadUInt64();
ulong BssSize = Context.RequestData.ReadUInt64();
long NroMappedAddress = 0;
ulong NroMappedAddress = 0;
if (IsInitialized)
{
@ -375,8 +384,8 @@ namespace Ryujinx.HLE.HOS.Services.Ldr
{
long Result = MakeError(ErrorModule.Loader, LoaderErr.BadInitialization);
long NroMappedAddress = Context.RequestData.ReadInt64();
long NroHeapAddress = Context.RequestData.ReadInt64();
ulong NroMappedAddress = Context.RequestData.ReadUInt64();
ulong NroHeapAddress = Context.RequestData.ReadUInt64();
if (IsInitialized)
{

View file

@ -14,10 +14,10 @@ namespace Ryujinx.HLE.Loaders.Executables
public int DataOffset { get; private set; }
public int BssSize { get; private set; }
public long SourceAddress { get; private set; }
public long BssAddress { get; private set; }
public ulong SourceAddress { get; private set; }
public ulong BssAddress { get; private set; }
public NxRelocatableObject(Stream Input, long SourceAddress = 0, long BssAddress = 0)
public NxRelocatableObject(Stream Input, ulong SourceAddress = 0, ulong BssAddress = 0)
{
this.SourceAddress = SourceAddress;
this.BssAddress = BssAddress;