示例#1
0
        public static AOpCode DecodeOpCode(AThreadState State, AMemory Memory, long Position)
        {
            int OpCode = Memory.ReadInt32(Position);

            AInst Inst;

            if (State.ExecutionMode == AExecutionMode.AArch64)
            {
                Inst = AOpCodeTable.GetInstA64(OpCode);
            }
            else
            {
                //TODO: Thumb support.
                Inst = AOpCodeTable.GetInstA32(OpCode);
            }

            AOpCode DecodedOpCode = new AOpCode(AInst.Undefined, Position, OpCode);

            if (Inst.Type != null)
            {
                DecodedOpCode = MakeOpCode(Inst.Type, Inst, Position, OpCode);
            }

            return(DecodedOpCode);
        }
示例#2
0
        private void UploadTexture(AMemory Memory, long BasePosition, int TexIndex, int HndIndex)
        {
            long Position = BasePosition + HndIndex * 4;

            int TextureHandle = Memory.ReadInt32(Position);

            int TicIndex = (TextureHandle >> 0) & 0xfffff;
            int TscIndex = (TextureHandle >> 20) & 0xfff;

            TryGetCpuAddr(NvGpuEngine3dReg.TexHeaderPoolOffset, out long TicPosition);
            TryGetCpuAddr(NvGpuEngine3dReg.TexSamplerPoolOffset, out long TscPosition);

            TicPosition += TicIndex * 0x20;
            TscPosition += TscIndex * 0x20;

            GalTextureSampler Sampler = TextureFactory.MakeSampler(Gpu, Memory, TscPosition);

            long TextureAddress = Memory.ReadInt64(TicPosition + 4) & 0xffffffffffff;

            if (FrameBuffers.Contains(TextureAddress))
            {
                //This texture is a frame buffer texture,
                //we shouldn't read anything from memory and bind
                //the frame buffer texture instead, since we're not
                //really writing anything to memory.
                Gpu.Renderer.BindFrameBufferTexture(TextureAddress, TexIndex, Sampler);
            }
            else
            {
                GalTexture Texture = TextureFactory.MakeTexture(Gpu, Memory, TicPosition);

                Gpu.Renderer.SetTextureAndSampler(TexIndex, Texture, Sampler);
                Gpu.Renderer.BindTexture(TexIndex);
            }
        }
示例#3
0
        public static ulong WaitForAddressIfLessThan(Process Process,
                                                     AThreadState ThreadState,
                                                     AMemory Memory,
                                                     long Address,
                                                     int Value,
                                                     ulong Timeout,
                                                     bool ShouldDecrement)
        {
            Memory.SetExclusive(ThreadState, Address);

            int CurrentValue = Memory.ReadInt32(Address);

            while (true)
            {
                if (Memory.TestExclusive(ThreadState, Address))
                {
                    if (CurrentValue < Value)
                    {
                        if (ShouldDecrement)
                        {
                            Memory.WriteInt32(Address, CurrentValue - 1);
                        }

                        Memory.ClearExclusiveForStore(ThreadState);
                    }
                    else
                    {
                        Memory.ClearExclusiveForStore(ThreadState);

                        return(MakeError(ErrorModule.Kernel, KernelErr.InvalidState));
                    }

                    break;
                }

                Memory.SetExclusive(ThreadState, Address);

                CurrentValue = Memory.ReadInt32(Address);
            }

            if (Timeout == 0)
            {
                return(MakeError(ErrorModule.Kernel, KernelErr.Timeout));
            }

            return(WaitForAddress(Process, ThreadState, Address, Timeout));
        }
示例#4
0
        public int ReadInt32()
        {
            int Value = Memory.ReadInt32(Position);

            Position += 4;

            return(Value);
        }
示例#5
0
        private int ReadCb(AMemory Memory, int Cbuf, int Offset)
        {
            long Position = ConstBuffers[Cbuf].Position;

            int Value = Memory.ReadInt32(Position + Offset);

            return(Value);
        }
示例#6
0
        private void FetchOpCode(AMemory Memory)
        {
            OpCode = PipeOp;

            PipeOp = Memory.ReadInt32(Pc);

            Pc += 4;
        }
示例#7
0
        private static int[] ReadWords(AMemory Memory, long Position, int Count)
        {
            int[] Words = new int[Count];

            for (int Index = 0; Index < Count; Index++, Position += 4)
            {
                Words[Index] = Memory.ReadInt32(Position);
            }

            return(Words);
        }
示例#8
0
        private bool UserToKernelInt32(AMemory Memory, long Address, out int Value)
        {
            if (Memory.IsMapped(Address))
            {
                Value = Memory.ReadInt32(Address);

                return(true);
            }

            Value = 0;

            return(false);
        }
示例#9
0
        public long ArbitrateLock(
            Process Process,
            AMemory Memory,
            int OwnerHandle,
            long MutexAddress,
            int RequesterHandle)
        {
            System.CriticalSectionLock.Lock();

            KThread CurrentThread = System.Scheduler.GetCurrentThread();

            CurrentThread.SignaledObj   = null;
            CurrentThread.ObjSyncResult = 0;

            int MutexValue = Memory.ReadInt32(MutexAddress);

            if (MutexValue != (OwnerHandle | HasListenersMask))
            {
                System.CriticalSectionLock.Unlock();

                return(0);
            }

            KThread MutexOwner = Process.HandleTable.GetData <KThread>(OwnerHandle);

            if (MutexOwner == null)
            {
                System.CriticalSectionLock.Unlock();

                return(MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle));
            }

            CurrentThread.MutexAddress             = MutexAddress;
            CurrentThread.ThreadHandleForUserMutex = RequesterHandle;

            MutexOwner.AddMutexWaiter(CurrentThread);

            CurrentThread.Reschedule(ThreadSchedState.Paused);

            System.CriticalSectionLock.Unlock();
            System.CriticalSectionLock.Lock();

            if (CurrentThread.MutexOwner != null)
            {
                CurrentThread.MutexOwner.TransferMutexTo(CurrentThread);
            }

            System.CriticalSectionLock.Unlock();

            return((uint)CurrentThread.ObjSyncResult);
        }
示例#10
0
        private void SendTexture(AMemory Memory)
        {
            long TicPos = (long)GetRegister(NsGpuRegister._3dTicAddressHigh) << 32 |
                          (long)GetRegister(NsGpuRegister._3dTicAddressLow) << 0;

            int CbData = GetRegister(NsGpuRegister._3dCbData0);

            int TicIndex = (CbData >> 0) & 0xfffff;
            int TscIndex = (CbData >> 20) & 0xfff; //I guess?

            TicPos = Gpu.MemoryMgr.GetCpuAddr(TicPos + TicIndex * 0x20);

            if (TicPos != -1)
            {
                int Word0 = Memory.ReadInt32(TicPos + 0x0);
                int Word1 = Memory.ReadInt32(TicPos + 0x4);
                int Word2 = Memory.ReadInt32(TicPos + 0x8);
                int Word3 = Memory.ReadInt32(TicPos + 0xc);
                int Word4 = Memory.ReadInt32(TicPos + 0x10);
                int Word5 = Memory.ReadInt32(TicPos + 0x14);
                int Word6 = Memory.ReadInt32(TicPos + 0x18);
                int Word7 = Memory.ReadInt32(TicPos + 0x1c);

                long TexAddress = Word1;

                TexAddress |= (long)(Word2 & 0xff) << 32;

                TexAddress = Gpu.MemoryMgr.GetCpuAddr(TexAddress);

                if (TexAddress != -1)
                {
                    NsGpuTextureFormat Format = (NsGpuTextureFormat)(Word0 & 0x7f);

                    int Width  = (Word4 & 0xffff) + 1;
                    int Height = (Word5 & 0xffff) + 1;

                    byte[] Buffer = GetDecodedTexture(Memory, Format, TexAddress, Width, Height);

                    if (Buffer != null)
                    {
                        Gpu.Renderer.QueueAction(delegate()
                        {
                            Gpu.Renderer.SendR8G8B8A8Texture(0, Buffer, Width, Height);
                        });
                    }
                }
            }
        }
示例#11
0
        public void WaitForLock(AThread RequestingThread, int RequestingThreadHandle)
        {
            lock (EnterWaitLock)
            {
                int CurrentThreadHandle = Memory.ReadInt32(MutexAddress) & ~MutexHasListenersMask;

                if (CurrentThreadHandle == RequestingThreadHandle ||
                    CurrentThreadHandle == 0)
                {
                    return;
                }

                if (CurrRequestingThreadHandle == 0 || RequestingThread.Priority < HighestPriority)
                {
                    CurrRequestingThreadHandle = RequestingThreadHandle;

                    HighestPriority = RequestingThread.Priority;
                }
            }

            ThreadEvent.Reset();
            ThreadEvent.WaitOne();
        }
示例#12
0
        public Executable(IExecutable Exe, AMemory Memory, long ImageBase)
        {
            this.Memory    = Memory;
            this.ImageBase = ImageBase;
            this.ImageEnd  = ImageBase;

            WriteData(ImageBase + Exe.TextOffset, Exe.Text, MemoryType.CodeStatic, AMemoryPerm.RX);
            WriteData(ImageBase + Exe.ROOffset, Exe.RO, MemoryType.Normal, AMemoryPerm.Read);
            WriteData(ImageBase + Exe.DataOffset, Exe.Data, MemoryType.Normal, AMemoryPerm.RW);

            if (Exe.Mod0Offset == 0)
            {
                MapBss(ImageBase + Exe.DataOffset + Exe.Data.Count, Exe.BssSize);

                return;
            }

            long Mod0Offset = ImageBase + Exe.Mod0Offset;

            int  Mod0Magic        = Memory.ReadInt32(Mod0Offset + 0x0);
            long DynamicOffset    = Memory.ReadInt32(Mod0Offset + 0x4) + Mod0Offset;
            long BssStartOffset   = Memory.ReadInt32(Mod0Offset + 0x8) + Mod0Offset;
            long BssEndOffset     = Memory.ReadInt32(Mod0Offset + 0xc) + Mod0Offset;
            long EhHdrStartOffset = Memory.ReadInt32(Mod0Offset + 0x10) + Mod0Offset;
            long EhHdrEndOffset   = Memory.ReadInt32(Mod0Offset + 0x14) + Mod0Offset;
            long ModObjOffset     = Memory.ReadInt32(Mod0Offset + 0x18) + Mod0Offset;

            MapBss(BssStartOffset, BssEndOffset - BssStartOffset);

            ImageEnd = BssEndOffset;

            List <ElfDyn> Dynamic = new List <ElfDyn>();

            while (true)
            {
                long TagVal = Memory.ReadInt64(DynamicOffset + 0);
                long Value  = Memory.ReadInt64(DynamicOffset + 8);

                DynamicOffset += 0x10;

                ElfDynTag Tag = (ElfDynTag)TagVal;

                if (Tag == ElfDynTag.DT_NULL)
                {
                    break;
                }

                Dynamic.Add(new ElfDyn(Tag, Value));
            }

            this.Dynamic = Dynamic.ToArray();
        }
示例#13
0
        public static AOpCode DecodeOpCode(AMemory Memory, long Position)
        {
            int OpCode = Memory.ReadInt32(Position);

            AInst Inst = AOpCodeTable.GetInst(OpCode);

            AOpCode DecodedOpCode = new AOpCode(AInst.Undefined, Position, OpCode);

            if (Inst.Type != null)
            {
                DecodedOpCode = CreateOpCode(Inst.Type, Inst, Position, OpCode);
            }

            return(DecodedOpCode);
        }
示例#14
0
        private ElfSym GetSymbol(long Position, long StrTblAddr)
        {
            int  NameIndex = Memory.ReadInt32(Position + 0);
            int  Info      = Memory.ReadByte(Position + 4);
            int  Other     = Memory.ReadByte(Position + 5);
            int  SHIdx     = Memory.ReadInt16(Position + 6);
            long Value     = Memory.ReadInt64(Position + 8);
            long Size      = Memory.ReadInt64(Position + 16);

            string Name = string.Empty;

            for (int Chr; (Chr = Memory.ReadByte(StrTblAddr + NameIndex++)) != 0;)
            {
                Name += (char)Chr;
            }

            return(new ElfSym(Name, Info, Other, SHIdx, Value, Size));
        }
示例#15
0
        private void UploadTexture(AMemory Memory, long BasePosition, int TexIndex, int HndIndex)
        {
            long Position = BasePosition + HndIndex * 4;

            int TextureHandle = Memory.ReadInt32(Position);

            int TicIndex = (TextureHandle >> 0) & 0xfffff;
            int TscIndex = (TextureHandle >> 20) & 0xfff;

            TryGetCpuAddr(NvGpuEngine3dReg.TexHeaderPoolOffset, out long TicPosition);
            TryGetCpuAddr(NvGpuEngine3dReg.TexSamplerPoolOffset, out long TscPosition);

            TicPosition += TicIndex * 0x20;
            TscPosition += TscIndex * 0x20;

            Gpu.Renderer.SetTexture(TexIndex, TextureFactory.MakeTexture(Gpu, Memory, TicPosition));
            Gpu.Renderer.SetSampler(TexIndex, TextureFactory.MakeSampler(Gpu, Memory, TscPosition));
        }
示例#16
0
        public long SignalAndIncrementIfEqual(AMemory Memory, long Address, int Value, int Count)
        {
            System.CriticalSectionLock.Lock();

            Memory.SetExclusive(0, Address);

            if (!UserToKernelInt32(Memory, Address, out int CurrentValue))
            {
                System.CriticalSectionLock.Unlock();

                return(MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm));
            }

            while (CurrentValue == Value)
            {
                if (Memory.TestExclusive(0, Address))
                {
                    Memory.WriteInt32(Address, CurrentValue + 1);

                    Memory.ClearExclusiveForStore(0);

                    break;
                }

                Memory.SetExclusive(0, Address);

                CurrentValue = Memory.ReadInt32(Address);
            }

            Memory.ClearExclusive(0);

            if (CurrentValue != Value)
            {
                System.CriticalSectionLock.Unlock();

                return(MakeError(ErrorModule.Kernel, KernelErr.InvalidState));
            }

            WakeArbiterThreads(Address, Count);

            System.CriticalSectionLock.Unlock();

            return(0);
        }
示例#17
0
        public static ulong WaitForAddressIfEqual(Process Process,
                                                  AThreadState ThreadState,
                                                  AMemory Memory,
                                                  long Address,
                                                  int Value,
                                                  ulong Timeout)
        {
            if (Memory.ReadInt32(Address) != Value)
            {
                return(MakeError(ErrorModule.Kernel, KernelErr.InvalidState));
            }

            if (Timeout == 0)
            {
                return(MakeError(ErrorModule.Kernel, KernelErr.Timeout));
            }

            return(WaitForAddress(Process, ThreadState, Address, Timeout));
        }
示例#18
0
        public void WaitForSignal(int ThreadHandle)
        {
            int Count = Memory.ReadInt32(CondVarAddress);

            if (Count <= 0)
            {
                return;
            }

            Memory.WriteInt32(CondVarAddress, Count - 1);

            ManualResetEvent Event = new ManualResetEvent(false);

            WaitingThreads.Enqueue(new WaitingThread(ThreadHandle, Event));

            if (Timeout != -1)
            {
                Event.WaitOne((int)(Timeout / 1000000));
            }
            else
            {
                Event.WaitOne();
            }
        }
示例#19
0
        public Executable(IExecutable Exe, AMemory Memory, long ImageBase)
        {
            Dynamic = new List <ElfDyn>();

            m_SymbolTable = new Dictionary <long, string>();

            Name = Exe.Name;

            this.Memory    = Memory;
            this.ImageBase = ImageBase;
            this.ImageEnd  = ImageBase;

            WriteData(ImageBase + Exe.TextOffset, Exe.Text, MemoryType.CodeStatic, AMemoryPerm.RX);
            WriteData(ImageBase + Exe.ROOffset, Exe.RO, MemoryType.CodeMutable, AMemoryPerm.Read);
            WriteData(ImageBase + Exe.DataOffset, Exe.Data, MemoryType.CodeMutable, AMemoryPerm.RW);

            if (Exe.Mod0Offset == 0)
            {
                int BssOffset = Exe.DataOffset + Exe.Data.Length;
                int BssSize   = Exe.BssSize;

                MapBss(ImageBase + BssOffset, BssSize);

                ImageEnd = ImageBase + BssOffset + BssSize;

                return;
            }

            long Mod0Offset = ImageBase + Exe.Mod0Offset;

            int  Mod0Magic        = Memory.ReadInt32(Mod0Offset + 0x0);
            long DynamicOffset    = Memory.ReadInt32(Mod0Offset + 0x4) + Mod0Offset;
            long BssStartOffset   = Memory.ReadInt32(Mod0Offset + 0x8) + Mod0Offset;
            long BssEndOffset     = Memory.ReadInt32(Mod0Offset + 0xc) + Mod0Offset;
            long EhHdrStartOffset = Memory.ReadInt32(Mod0Offset + 0x10) + Mod0Offset;
            long EhHdrEndOffset   = Memory.ReadInt32(Mod0Offset + 0x14) + Mod0Offset;
            long ModObjOffset     = Memory.ReadInt32(Mod0Offset + 0x18) + Mod0Offset;

            MapBss(BssStartOffset, BssEndOffset - BssStartOffset);

            ImageEnd = BssEndOffset;

            while (true)
            {
                long TagVal = Memory.ReadInt64(DynamicOffset + 0);
                long Value  = Memory.ReadInt64(DynamicOffset + 8);

                DynamicOffset += 0x10;

                ElfDynTag Tag = (ElfDynTag)TagVal;

                if (Tag == ElfDynTag.DT_NULL)
                {
                    break;
                }

                Dynamic.Add(new ElfDyn(Tag, Value));
            }

            long StrTblAddr = ImageBase + GetFirstValue(ElfDynTag.DT_STRTAB);
            long SymTblAddr = ImageBase + GetFirstValue(ElfDynTag.DT_SYMTAB);

            long SymEntSize = GetFirstValue(ElfDynTag.DT_SYMENT);

            while ((ulong)SymTblAddr < (ulong)StrTblAddr)
            {
                ElfSym Sym = GetSymbol(SymTblAddr, StrTblAddr);

                m_SymbolTable.TryAdd(Sym.Value, Sym.Name);

                SymTblAddr += SymEntSize;
            }
        }
示例#20
0
        public long WaitForAddressIfLessThan(
            AMemory Memory,
            long Address,
            int Value,
            bool ShouldDecrement,
            long Timeout)
        {
            KThread CurrentThread = System.Scheduler.GetCurrentThread();

            System.CriticalSectionLock.Lock();

            if (CurrentThread.ShallBeTerminated ||
                CurrentThread.SchedFlags == ThreadSchedState.TerminationPending)
            {
                System.CriticalSectionLock.Unlock();

                return(MakeError(ErrorModule.Kernel, KernelErr.ThreadTerminating));
            }

            CurrentThread.SignaledObj   = null;
            CurrentThread.ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.Timeout);

            //If ShouldDecrement is true, do atomic decrement of the value at Address.
            Memory.SetExclusive(0, Address);

            if (!UserToKernelInt32(Memory, Address, out int CurrentValue))
            {
                System.CriticalSectionLock.Unlock();

                return(MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm));
            }

            if (ShouldDecrement)
            {
                while (CurrentValue < Value)
                {
                    if (Memory.TestExclusive(0, Address))
                    {
                        Memory.WriteInt32(Address, CurrentValue - 1);

                        Memory.ClearExclusiveForStore(0);

                        break;
                    }

                    Memory.SetExclusive(0, Address);

                    CurrentValue = Memory.ReadInt32(Address);
                }
            }

            Memory.ClearExclusive(0);

            if (CurrentValue < Value)
            {
                if (Timeout == 0)
                {
                    System.CriticalSectionLock.Unlock();

                    return(MakeError(ErrorModule.Kernel, KernelErr.Timeout));
                }

                CurrentThread.MutexAddress         = Address;
                CurrentThread.WaitingInArbitration = true;

                InsertSortedByPriority(ArbiterThreads, CurrentThread);

                CurrentThread.Reschedule(ThreadSchedState.Paused);

                if (Timeout > 0)
                {
                    System.TimeManager.ScheduleFutureInvocation(CurrentThread, Timeout);
                }

                System.CriticalSectionLock.Unlock();

                if (Timeout > 0)
                {
                    System.TimeManager.UnscheduleFutureInvocation(CurrentThread);
                }

                System.CriticalSectionLock.Lock();

                if (CurrentThread.WaitingInArbitration)
                {
                    ArbiterThreads.Remove(CurrentThread);

                    CurrentThread.WaitingInArbitration = false;
                }

                System.CriticalSectionLock.Unlock();

                return(CurrentThread.ObjSyncResult);
            }

            System.CriticalSectionLock.Unlock();

            return(MakeError(ErrorModule.Kernel, KernelErr.InvalidState));
        }
示例#21
0
        public long SignalAndModifyIfEqual(AMemory Memory, long Address, int Value, int Count)
        {
            System.CriticalSectionLock.Lock();

            int Offset;

            //The value is decremented if the number of threads waiting is less
            //or equal to the Count of threads to be signaled, or Count is zero
            //or negative. It is incremented if there are no threads waiting.
            int WaitingCount = 0;

            foreach (KThread Thread in ArbiterThreads.Where(x => x.MutexAddress == Address))
            {
                if (++WaitingCount > Count)
                {
                    break;
                }
            }

            if (WaitingCount > 0)
            {
                Offset = WaitingCount <= Count || Count <= 0 ? -1 : 0;
            }
            else
            {
                Offset = 1;
            }

            Memory.SetExclusive(0, Address);

            if (!UserToKernelInt32(Memory, Address, out int CurrentValue))
            {
                System.CriticalSectionLock.Unlock();

                return(MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm));
            }

            while (CurrentValue == Value)
            {
                if (Memory.TestExclusive(0, Address))
                {
                    Memory.WriteInt32(Address, CurrentValue + Offset);

                    Memory.ClearExclusiveForStore(0);

                    break;
                }

                Memory.SetExclusive(0, Address);

                CurrentValue = Memory.ReadInt32(Address);
            }

            Memory.ClearExclusive(0);

            if (CurrentValue != Value)
            {
                System.CriticalSectionLock.Unlock();

                return(MakeError(ErrorModule.Kernel, KernelErr.InvalidState));
            }

            WakeArbiterThreads(Address, Count);

            System.CriticalSectionLock.Unlock();

            return(0);
        }
示例#22
0
        public Executable(IExecutable Exe, KMemoryManager MemoryManager, AMemory Memory, long ImageBase)
        {
            Dynamic = new List <ElfDyn>();

            FilePath = Exe.FilePath;

            if (FilePath != null)
            {
                Name = Path.GetFileNameWithoutExtension(FilePath.Replace(Homebrew.TemporaryNroSuffix, ""));
            }

            this.Memory        = Memory;
            this.MemoryManager = MemoryManager;
            this.ImageBase     = ImageBase;
            this.ImageEnd      = ImageBase;

            long TextPosition = ImageBase + (uint)Exe.TextOffset;
            long ROPosition   = ImageBase + (uint)Exe.ROOffset;
            long DataPosition = ImageBase + (uint)Exe.DataOffset;

            long TextSize = (uint)IntUtils.AlignUp(Exe.Text.Length, KMemoryManager.PageSize);
            long ROSize   = (uint)IntUtils.AlignUp(Exe.RO.Length, KMemoryManager.PageSize);
            long DataSize = (uint)IntUtils.AlignUp(Exe.Data.Length, KMemoryManager.PageSize);

            long DataAndBssSize = (uint)IntUtils.AlignUp(Exe.BssSize, KMemoryManager.PageSize) + DataSize;

            ImageEnd = DataPosition + DataAndBssSize;

            MemoryManager.HleMapProcessCode(TextPosition, TextSize + ROSize + DataAndBssSize);

            MemoryManager.SetProcessMemoryPermission(ROPosition, ROSize, MemoryPermission.Read);
            MemoryManager.SetProcessMemoryPermission(DataPosition, DataAndBssSize, MemoryPermission.ReadAndWrite);

            Memory.WriteBytes(TextPosition, Exe.Text);
            Memory.WriteBytes(ROPosition, Exe.RO);
            Memory.WriteBytes(DataPosition, Exe.Data);

            if (Exe.Mod0Offset == 0)
            {
                return;
            }

            long Mod0Offset = ImageBase + Exe.Mod0Offset;

            int  Mod0Magic        = Memory.ReadInt32(Mod0Offset + 0x0);
            long DynamicOffset    = Memory.ReadInt32(Mod0Offset + 0x4) + Mod0Offset;
            long BssStartOffset   = Memory.ReadInt32(Mod0Offset + 0x8) + Mod0Offset;
            long BssEndOffset     = Memory.ReadInt32(Mod0Offset + 0xc) + Mod0Offset;
            long EhHdrStartOffset = Memory.ReadInt32(Mod0Offset + 0x10) + Mod0Offset;
            long EhHdrEndOffset   = Memory.ReadInt32(Mod0Offset + 0x14) + Mod0Offset;
            long ModObjOffset     = Memory.ReadInt32(Mod0Offset + 0x18) + Mod0Offset;

            while (true)
            {
                long TagVal = Memory.ReadInt64(DynamicOffset + 0);
                long Value  = Memory.ReadInt64(DynamicOffset + 8);

                DynamicOffset += 0x10;

                ElfDynTag Tag = (ElfDynTag)TagVal;

                if (Tag == ElfDynTag.DT_NULL)
                {
                    break;
                }

                Dynamic.Add(new ElfDyn(Tag, Value));
            }

            long StrTblAddr = ImageBase + GetFirstValue(ElfDynTag.DT_STRTAB);
            long SymTblAddr = ImageBase + GetFirstValue(ElfDynTag.DT_SYMTAB);

            long SymEntSize = GetFirstValue(ElfDynTag.DT_SYMENT);

            List <ElfSym> Symbols = new List <ElfSym>();

            while ((ulong)SymTblAddr < (ulong)StrTblAddr)
            {
                ElfSym Sym = GetSymbol(SymTblAddr, StrTblAddr);

                Symbols.Add(Sym);

                SymTblAddr += SymEntSize;
            }

            SymbolTable = Array.AsReadOnly(Symbols.OrderBy(x => x.Value).ToArray());
        }
示例#23
0
        private KThread TryAcquireMutex(Process Process, AMemory Memory, KThread Requester)
        {
            int Core = Requester.CurrentCore;

            long Address = Requester.MutexAddress;

            Memory.SetExclusive(Core, Address);

            int MutexValue = Memory.ReadInt32(Address);

            while (MutexValue != 0)
            {
                if (Memory.TestExclusive(Core, Address))
                {
                    if (MutexValue != 0)
                    {
                        //Update value to indicate there is a mutex waiter now.
                        Memory.WriteInt32(Address, MutexValue | HasListenersMask);
                    }
                    else
                    {
                        //No thread owning the mutex, assign to requesting thread.
                        Memory.WriteInt32(Address, Requester.ThreadHandleForUserMutex);
                    }

                    Memory.ClearExclusiveForStore(Core);

                    break;
                }

                Memory.SetExclusive(Core, Address);

                MutexValue = Memory.ReadInt32(Address);
            }

            if (MutexValue == 0)
            {
                //We now own the mutex.
                Requester.SignaledObj   = null;
                Requester.ObjSyncResult = 0;

                Requester.ReleaseAndResume();

                return(null);
            }

            MutexValue &= ~HasListenersMask;

            KThread MutexOwner = Process.HandleTable.GetData <KThread>(MutexValue);

            if (MutexOwner != null)
            {
                //Mutex already belongs to another thread, wait for it.
                MutexOwner.AddMutexWaiter(Requester);
            }
            else
            {
                //Invalid mutex owner.
                Requester.SignaledObj   = null;
                Requester.ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);

                Requester.ReleaseAndResume();
            }

            return(MutexOwner);
        }