Exemple #1
0
        public string GetGuestStackTrace(ARMeilleure.State.ExecutionContext context)
        {
            EnsureLoaded();

            StringBuilder trace = new StringBuilder();

            void AppendTrace(long address)
            {
                Image image = GetImage(address, out int imageIndex);

                if (image == null || !TryGetSubName(image, address, out string subName))
                {
                    subName = $"Sub{address:x16}";
                }
                else if (subName.StartsWith("_Z"))
                {
                    subName = Demangler.Parse(subName);
                }

                if (image != null)
                {
                    long offset = address - image.BaseAddress;

                    string imageName = GetGuessedNsoNameFromIndex(imageIndex);

                    trace.AppendLine($"   {imageName}:0x{offset:x8} {subName}");
                }
                else
                {
                    trace.AppendLine($"   ??? {subName}");
                }
            }

            // TODO: ARM32.
            long framePointer = (long)context.GetX(29);

            trace.AppendLine($"Process: {_owner.Name}, PID: {_owner.Pid}");

            while (framePointer != 0)
            {
                if ((framePointer & 7) != 0 ||
                    !_owner.CpuMemory.IsMapped(framePointer) ||
                    !_owner.CpuMemory.IsMapped(framePointer + 8))
                {
                    break;
                }

                // Note: This is the return address, we need to subtract one instruction
                // worth of bytes to get the branch instruction address.
                AppendTrace(_owner.CpuMemory.ReadInt64(framePointer + 8) - 4);

                framePointer = _owner.CpuMemory.ReadInt64(framePointer);
            }

            return(trace.ToString());
        }
        public string GetGuestStackTrace(ARMeilleure.State.ExecutionContext context)
        {
            EnsureLoaded();

            StringBuilder trace = new StringBuilder();

            void AppendTrace(ulong address)
            {
                Image image = GetImage(address, out int imageIndex);

                if (image == null || !TryGetSubName(image, address, out string subName))
                {
                    subName = $"Sub{address:x16}";
                }
                else if (subName.StartsWith("_Z"))
                {
                    subName = Demangler.Parse(subName);
                }

                if (image != null)
                {
                    ulong offset = address - image.BaseAddress;

                    string imageName = GetGuessedNsoNameFromIndex(imageIndex);

                    trace.AppendLine($"   {imageName}:0x{offset:x8} {subName}");
                }
                else
                {
                    trace.AppendLine($"   ??? {subName}");
                }
            }

            trace.AppendLine($"Process: {_owner.Name}, PID: {_owner.Pid}");

            if (context.IsAarch32)
            {
                ulong framePointer = context.GetX(11);

                while (framePointer != 0)
                {
                    if ((framePointer & 3) != 0 ||
                        !_owner.CpuMemory.IsMapped(framePointer) ||
                        !_owner.CpuMemory.IsMapped(framePointer + 4))
                    {
                        break;
                    }

                    AppendTrace(_owner.CpuMemory.Read <uint>(framePointer + 4));

                    framePointer = _owner.CpuMemory.Read <uint>(framePointer);
                }
            }
            else
            {
                ulong framePointer = context.GetX(29);

                while (framePointer != 0)
                {
                    if ((framePointer & 7) != 0 ||
                        !_owner.CpuMemory.IsMapped(framePointer) ||
                        !_owner.CpuMemory.IsMapped(framePointer + 8))
                    {
                        break;
                    }

                    AppendTrace(_owner.CpuMemory.Read <ulong>(framePointer + 8));

                    framePointer = _owner.CpuMemory.Read <ulong>(framePointer);
                }
            }

            return(trace.ToString());
        }
Exemple #3
0
        public KernelResult Initialize(
            ulong entrypoint,
            ulong argsPtr,
            ulong stackTop,
            int priority,
            int defaultCpuCore,
            KProcess owner,
            ThreadType type = ThreadType.User)
        {
            if ((uint)type > 3)
            {
                throw new ArgumentException($"Invalid thread type \"{type}\".");
            }

            PreferredCore = defaultCpuCore;

            AffinityMask |= 1L << defaultCpuCore;

            SchedFlags = type == ThreadType.Dummy
                ? ThreadSchedState.Running
                : ThreadSchedState.None;

            CurrentCore = PreferredCore;

            DynamicPriority = priority;
            BasePriority    = priority;

            ObjSyncResult = KernelResult.ThreadNotStarted;

            _entrypoint = entrypoint;

            if (type == ThreadType.User)
            {
                if (owner.AllocateThreadLocalStorage(out _tlsAddress) != KernelResult.Success)
                {
                    return(KernelResult.OutOfMemory);
                }

                TlsDramAddress = owner.MemoryManager.GetDramAddressFromVa(_tlsAddress);

                MemoryHelper.FillWithZeros(owner.CpuMemory, (long)_tlsAddress, KTlsPageInfo.TlsEntrySize);
            }

            bool is64Bits;

            if (owner != null)
            {
                Owner = owner;

                owner.IncrementReferenceCount();
                owner.IncrementThreadCount();

                is64Bits = (owner.MmuFlags & 1) != 0;
            }
            else
            {
                is64Bits = true;
            }

            HostThread = new Thread(() => ThreadStart(entrypoint));

            Context = new ARMeilleure.State.ExecutionContext();

            bool isAarch32 = (Owner.MmuFlags & 1) == 0;

            Context.IsAarch32 = isAarch32;

            Context.SetX(0, argsPtr);

            if (isAarch32)
            {
                Context.SetX(13, (uint)stackTop);
            }
            else
            {
                Context.SetX(31, stackTop);
            }

            Context.CntfrqEl0 = 19200000;
            Context.Tpidr     = (long)_tlsAddress;

            owner.SubscribeThreadEventHandlers(Context);

            ThreadUid = System.GetThreadUid();

            _hasBeenInitialized = true;

            if (owner != null)
            {
                owner.AddThread(this);

                if (owner.IsPaused)
                {
                    System.CriticalSection.Enter();

                    if (ShallBeTerminated || SchedFlags == ThreadSchedState.TerminationPending)
                    {
                        System.CriticalSection.Leave();

                        return(KernelResult.Success);
                    }

                    _forcePauseFlags |= ThreadSchedState.ProcessPauseFlag;

                    CombineForcePauseFlags();

                    System.CriticalSection.Leave();
                }
            }

            return(KernelResult.Success);
        }