From 00579927e43bf55ee06ae02933c1e755fb4120eb Mon Sep 17 00:00:00 2001 From: gdkchan Date: Wed, 28 Nov 2018 20:18:09 -0200 Subject: Better process implementation (#491) * Initial implementation of KProcess * Some improvements to the memory manager, implement back guest stack trace printing * Better GetInfo implementation, improve checking in some places with information from process capabilities * Allow the cpu to read/write from the correct memory locations for accesses crossing a page boundary * Change long -> ulong for address/size on memory related methods to avoid unnecessary casts * Attempt at implementing ldr:ro with new KProcess * Allow BSS with size 0 on ldr:ro * Add checking for memory block slab heap usage, return errors if full, exit gracefully * Use KMemoryBlockSize const from KMemoryManager * Allow all methods to read from non-contiguous locations * Fix for TransactParcelAuto * Address PR feedback, additionally fix some small issues related to the KIP loader and implement SVCs GetProcessId, GetProcessList, GetSystemInfo, CreatePort and ManageNamedPort * Fix wrong check for source pages count from page list on MapPhysicalMemory * Fix some issues with UnloadNro on ldr:ro --- Ryujinx.HLE/Loaders/Compression/BackwardsLz.cs | 105 +++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 Ryujinx.HLE/Loaders/Compression/BackwardsLz.cs (limited to 'Ryujinx.HLE/Loaders/Compression') diff --git a/Ryujinx.HLE/Loaders/Compression/BackwardsLz.cs b/Ryujinx.HLE/Loaders/Compression/BackwardsLz.cs new file mode 100644 index 00000000..43cc601f --- /dev/null +++ b/Ryujinx.HLE/Loaders/Compression/BackwardsLz.cs @@ -0,0 +1,105 @@ +using System; +using System.IO; + +namespace Ryujinx.HLE.Loaders.Compression +{ + static class BackwardsLz + { + private class BackwardsReader + { + private Stream BaseStream; + + public BackwardsReader(Stream BaseStream) + { + this.BaseStream = BaseStream; + } + + public byte ReadByte() + { + BaseStream.Seek(-1, SeekOrigin.Current); + + byte Value = (byte)BaseStream.ReadByte(); + + BaseStream.Seek(-1, SeekOrigin.Current); + + return Value; + } + + public short ReadInt16() + { + return (short)((ReadByte() << 8) | (ReadByte() << 0)); + } + + public int ReadInt32() + { + return ((ReadByte() << 24) | + (ReadByte() << 16) | + (ReadByte() << 8) | + (ReadByte() << 0)); + } + } + + public static byte[] Decompress(Stream Input, int DecompressedLength) + { + long End = Input.Position; + + BackwardsReader Reader = new BackwardsReader(Input); + + int AdditionalDecLength = Reader.ReadInt32(); + int StartOffset = Reader.ReadInt32(); + int CompressedLength = Reader.ReadInt32(); + + Input.Seek(12 - StartOffset, SeekOrigin.Current); + + byte[] Dec = new byte[DecompressedLength]; + + int DecompressedLengthUnpadded = CompressedLength + AdditionalDecLength; + + int DecompressionStart = DecompressedLength - DecompressedLengthUnpadded; + + int DecPos = Dec.Length; + + byte Mask = 0; + byte Header = 0; + + while (DecPos > DecompressionStart) + { + if ((Mask >>= 1) == 0) + { + Header = Reader.ReadByte(); + Mask = 0x80; + } + + if ((Header & Mask) == 0) + { + Dec[--DecPos] = Reader.ReadByte(); + } + else + { + ushort Pair = (ushort)Reader.ReadInt16(); + + int Length = (Pair >> 12) + 3; + int Position = (Pair & 0xfff) + 3; + + DecPos -= Length; + + if (Length <= Position) + { + int SrcPos = DecPos + Position; + + Buffer.BlockCopy(Dec, SrcPos, Dec, DecPos, Length); + } + else + { + for (int Offset = 0; Offset < Length; Offset++) + { + Dec[DecPos + Offset] = Dec[DecPos + Position + Offset]; + } + } + } + } + + return Dec; + } + } +} \ No newline at end of file -- cgit v1.2.3