コード例 #1
0
            public IEnumerable <KeyValuePair <string, ulong> > FetchValues(ulong sp, IGlobalExpressionEvaluator evaluator)
            {
                var bytes = evaluator.ReadMemoryBlock($"0x{sp:x8}", _Position) ?? new byte[0];
                List <KeyValuePair <string, ulong> > result = new List <KeyValuePair <string, ulong> >();

                foreach (var rec in _AllRegisters)
                {
                    if (rec.EndOffset > bytes.Length)
                    {
                        continue;   //Unavailable
                    }
                    switch (rec.Size)
                    {
                    case 4:
                        result.Add(new KeyValuePair <string, ulong>(rec.Name, BitConverter.ToUInt32(bytes, rec.Offset)));
                        break;

                    case 8:
                        result.Add(new KeyValuePair <string, ulong>(rec.Name, BitConverter.ToUInt64(bytes, rec.Offset)));
                        break;
                    }
                }

                result.Add(new KeyValuePair <string, ulong>("sp", sp + (ulong)_Position));
                return(result);
            }
コード例 #2
0
        CPUTypes?GetCPUType(IGlobalExpressionEvaluator e)
        {
            // Reads CPUID register in SCB
            ulong CPUID = (ulong)e.EvaluateIntegralExpression("*((int*)0xE000ED00)") & 0x0000FFF0;

            // Bits 15:4 are:
            // 0xC20 if Cortex-M0
            // 0xC23 if Cortex-M3
            // 0xC24 if Cortex-M4
            if (CPUID == 0x0000C200)
            {
                return(CPUTypes.CPU_ARM_CORTEX_M0);
            }
            else if (CPUID == 0x0000C230)
            {
                return(CPUTypes.CPU_ARM_CORTEX_M3);
            }
            else if (CPUID == 0x0000C240)
            {
                return(CPUTypes.CPU_ARM_CORTEX_M4);
            }
            else
            {
                return(CPUTypes.CPU_UNIDENTIFIED);
            }
        }
コード例 #3
0
        private KnownStackLayout GetThreadLayout(IGlobalExpressionEvaluator evaluator)
        {
            if (!_StackLayout.HasValue)
            {
                var  insns = evaluator.DisassembleMemory("SVC_ContextSave", 10) ?? new SimpleInstruction[0];
                bool hasFP = false;
                //This is a basic check to distinguish between known stack layouts. It is not trying to actually reconstruct the stack layout by analyzing the disassembly.
                foreach (var insn in insns)
                {
                    if (insn.Text?.ToLower()?.Contains("vstmdbeq") == true)
                    {
                        hasFP = true;
                        break;
                    }

                    if (insn.Text?.ToLower()?.StartsWith("bl") == true)
                    {
                        break;
                    }
                }

                _StackLayout = hasFP ? KnownStackLayout.IntegralWithOptionalFP : KnownStackLayout.IntegralOnly;
            }

            return(_StackLayout.Value);
        }
コード例 #4
0
        LayoutCache BuildLayoutCache(IGlobalExpressionEvaluator evaluator, string structName, IEnumerable <string> fieldDescriptors)
        {
            int minOffset = int.MaxValue, maxOffset = int.MinValue;
            List <KeyValuePair <string, int> > offsets = new List <KeyValuePair <string, int> >();

            foreach (var field in fieldDescriptors)
            {
                int idx = field.IndexOf('=');
                if (idx == -1)
                {
                    continue;
                }

                ulong?rawOffset = evaluator.EvaluateIntegralExpression($"&(({structName} *)0)->{field.Substring(0, idx).Trim()}");
                if (rawOffset.HasValue)
                {
                    int offset = (int)rawOffset.Value;

                    minOffset = Math.Min(minOffset, offset);
                    maxOffset = Math.Max(maxOffset, offset);
                    offsets.Add(new KeyValuePair <string, int>(field.Substring(idx + 1).Trim(), offset));
                }
            }

            if (offsets.Count == 0)
            {
                return(null);
            }

            return(new LayoutCache(minOffset, maxOffset, offsets));
        }
コード例 #5
0
            public ZephyrThread(ZephyrThreadProvider provider, ulong threadObjectAddress, IGlobalExpressionEvaluator evaluator, bool isCurrentlyExecuting = false)
            {
                IsCurrentlyExecuting = isCurrentlyExecuting;
                _Provider            = provider;
                _ThreadObjectAddress = threadObjectAddress;
                _Evaluator           = evaluator;

                UniqueID = (int)threadObjectAddress;

                var name = evaluator.EvaluateStringExpression($"(char *)&(((struct k_thread *)0x{threadObjectAddress:x8})->name)");

                if (!string.IsNullOrEmpty(name))
                {
                    Name = name;
                }
                else
                {
                    var sym = evaluator.TryGetMeaningulSymbolName(threadObjectAddress);
                    if (sym.Symbol != null && sym.Offset == 0)
                    {
                        Name = sym.Symbol;
                    }
                    else
                    {
                        Name = $"0x{threadObjectAddress:x8}";
                    }
                }
            }
コード例 #6
0
        public IVirtualThread[] GetVirtualThreads(
            IGlobalExpressionEvaluator e)
        {
            // Get the total number of tasks running
            int taskCount = (int)e.EvaluateIntegralExpression("uxCurrentNumberOfTasks");

            // Get the number of different priorities (i.e. configMAX_PRIORITIES) --
            // there is a ready task list for each possible priority
            int priorityCount = (int)e.EvaluateIntegralExpression("sizeof(pxReadyTasksLists)/sizeof(pxReadyTasksLists[0])");

            List <IVirtualThread> threads = new List <IVirtualThread>();

            // Get a pointer to the current TCB -- it's used to compare to the TCB of
            // each list found below, and a match means it's the currently running task
            UInt64?pxCurrentTCB = e.EvaluateIntegralExpression("pxCurrentTCB");
            int    currentTask  = 0;

            // If the CPU type hasn't been found yet, do it -- it's necessary to find
            // out the stack layout later on
            if (!CPUType.HasValue)
            {
                CPUType = GetCPUType(e);
            }

            // Find tasks in ready lists -- one for each possible priority in FreeRTOS
            for (int i = 0; i < priorityCount; i++)
            {
                // Add all tasks found in this list
                threads.AddRange(GetThreadsFromList(e, "pxReadyTasksLists[" + i + "]", pxCurrentTCB, ref currentTask));

                // If all tasks are accounted for, return early so as not to waste time
                // querying for extra tasks
                if (currentTask == taskCount)
                {
                    return(threads.ToArray());
                }
            }

            // Find tasks in delayed task lists
            for (int i = 1; i <= 2; i++)
            {
                // Add all tasks found in this list
                threads.AddRange(GetThreadsFromList(e, "xDelayedTaskList" + i, pxCurrentTCB, ref currentTask));

                // If all tasks are accounted for, return early so as not to waste time
                // querying for extra tasks
                if (currentTask == taskCount)
                {
                    return(threads.ToArray());
                }
            }

            // Find tasks in suspended task list
            threads.AddRange(GetThreadsFromList(e, "xSuspendedTaskList", pxCurrentTCB, ref currentTask));

            return(threads.ToArray());
        }
コード例 #7
0
 public VirtualThread(CPUTypes?CPUType, string name, UInt64 savedSP, int index, bool isRunning,
                      IGlobalExpressionEvaluator evaluator)
 {
     _CPUType   = CPUType;
     _SavedSP   = savedSP;
     _Name      = name;
     _Index     = index;
     _IsRunning = isRunning;
     _Evaluator = evaluator;
 }
コード例 #8
0
 public VirtualThread(StackLayout stackLayout, string name, UInt64 savedSP, int id, bool isRunning,
                      IGlobalExpressionEvaluator evaluator)
 {
     _StackLayout = stackLayout;
     _SavedSP     = savedSP;
     _Name        = name;
     _UniqueID    = id;
     _IsRunning   = isRunning;
     _Evaluator   = evaluator;
 }
コード例 #9
0
            public RTXThread(RTXThreadProvider provider, ulong threadObjectAddress, IGlobalExpressionEvaluator evaluator, bool isCurrentlyExecuting = false)
            {
                IsCurrentlyExecuting = isCurrentlyExecuting;
                _Provider            = provider;
                _ThreadObjectAddress = threadObjectAddress;
                _Evaluator           = evaluator;

                UniqueID = (int)threadObjectAddress;    //RTX threads don't have meaningful sequential IDs

                Name = evaluator.EvaluateStringExpression(GetFieldExpression("name")) ?? "(unnamed)";
            }
コード例 #10
0
        void ReportThreadList(List <IVirtualThread> result, IGlobalExpressionEvaluator expressionEvaluator, string expression, HashSet <ulong> reportedIDs)
        {
            for (ulong?addr = expressionEvaluator.EvaluateIntegralExpression(expression); addr.HasValue && addr != 0; addr = expressionEvaluator.EvaluateIntegralExpression($"(({ThreadTypeName} *)0x{addr.Value:x8})->thread_next"))
            {
                if (reportedIDs.Contains(addr.Value))
                {
                    continue;
                }

                reportedIDs.Add(addr.Value);
                result.Add(new RTXThread(this, addr.Value, expressionEvaluator));
            }
        }
コード例 #11
0
        List <IVirtualThread> GetThreadsFromList(IGlobalExpressionEvaluator e, string listName, UInt64?pxCurrentTCB, ref int currentThread)
        {
            List <IVirtualThread> threads = new List <IVirtualThread>();

            // Find how many tasks are there in this list
            int?threadsInListCount = (int?)e.EvaluateIntegralExpression(listName + ".uxNumberOfItems");

            // If none, abort early; also, it's possible that a given list doesn't exist --
            // for instance if INCLUDE_vTaskSuspend is 0
            if (!threadsInListCount.HasValue || threadsInListCount == 0)
            {
                return(threads);
            }

            // Get the first list item in that list, and the corresponding task control block
            UInt64 currentListItem = (UInt64)e.EvaluateIntegralExpression(listName + ".xListEnd.pxNext");
            UInt64 currentTCB      = (UInt64)e.EvaluateIntegralExpression(string.Format("((ListItem_t*)0x{0:x})->pvOwner", currentListItem));

            for (int j = 0; j < threadsInListCount.Value; j++)
            {
                // Get stack pointer
                UInt64 savedSP = (UInt64)e.EvaluateIntegralExpression(string.Format("((TCB_t*)0x{0:x})->pxTopOfStack", currentTCB));

                // Get task name
                string name = e.EvaluateRawExpression(string.Format("((TCB_t*)0x{0:x})->pcTaskName", currentTCB));

                // Trim null characters (\000) and quotes from the name
                Regex rgx = new Regex("\\\"(.*)\\\"(.*)");
                name = name.Replace("\\000", "");
                name = rgx.Replace(name, "$1");

                // Add this thread to the list
                threads.Add(new VirtualThread(CPUType,                    // CPU type
                                              name,                       // task name
                                              savedSP,                    // stack pointer
                                              currentThread++,            // index
                                              pxCurrentTCB == currentTCB, // is currently running? (yes if equality holds)
                                              e));                        // evaluator

                // Iterate to next list item and TCB
                currentListItem = (UInt64)e.EvaluateIntegralExpression(string.Format("((ListItem_t*)0x{0:x})->pxNext", currentListItem));
                currentTCB      = (UInt64)e.EvaluateIntegralExpression(string.Format("((ListItem_t*)0x{0:x})->pvOwner", currentListItem));
            }

            return(threads);
        }
コード例 #12
0
        public IVirtualThread[] GetVirtualThreads(IGlobalExpressionEvaluator expressionEvaluator)
        {
            _CalleeSavedLayout ??= BuildLayoutCache(expressionEvaluator, "struct k_thread", new[] { "callee_saved.psp=sp" }.Concat(Enumerable.Range(1, 8).Select(i => $"callee_saved.v{i}=r{i + 3}")));
            _ESFLayout ??= BuildLayoutCache(expressionEvaluator, "struct __esf", new[] { "basic.ip=ip", "basic.lr=lr", "basic.pc=pc" }.Concat(Enumerable.Range(1, 4).Select(i => $"basic.a{i}=r{i - 1}")));
            _ESFSize = expressionEvaluator.EvaluateIntegralExpression("sizeof(struct __esf)") ?? 0;

            List <IVirtualThread> result = new List <IVirtualThread>();

            var pCurrentThread = expressionEvaluator.EvaluateIntegralExpression("_kernel.current");

            if (!pCurrentThread.HasValue || pCurrentThread == 0)
            {
                return(new IVirtualThread[0]);
            }

            HashSet <ulong> reportedIDs = new HashSet <ulong>();

            var allThreads = expressionEvaluator.EvaluateIntegralExpression("_kernel.threads");

            if (allThreads.HasValue && allThreads.Value != 0)
            {
                for (ulong?pThread = allThreads; (pThread ?? 0) != 0; pThread = expressionEvaluator.EvaluateIntegralExpression($"((struct k_thread *)0x{pThread.Value:x8})->next_thread"))
                {
                    if (reportedIDs.Contains(pThread.Value))
                    {
                        break;  //Avoid infinite loops
                    }
                    reportedIDs.Add(pThread.Value);
                    result.Add(new ZephyrThread(this, pThread.Value, expressionEvaluator, pThread.Value == pCurrentThread.Value));
                }
            }

            if (!reportedIDs.Contains(pCurrentThread.Value))
            {
                result.Insert(0, new ZephyrThread(this, pCurrentThread.Value, expressionEvaluator, true));
            }

            return(result.ToArray());
        }
コード例 #13
0
            public IEnumerable <KeyValuePair <string, ulong> > Load(IGlobalExpressionEvaluator evaluator, ulong address)
            {
                int blockSize = _MaxOffset - _MinOffset + WordSize;
                var data      = evaluator.ReadMemoryBlock($"0x{address + (uint)_MinOffset:x8}", blockSize);
                List <KeyValuePair <string, ulong> > result = new List <KeyValuePair <string, ulong> >();

                foreach (var kv in _Offsets)
                {
                    int offset = kv.Value - _MinOffset;

                    if (data != null && data.Length >= (offset + WordSize))
                    {
                        result.Add(new KeyValuePair <string, ulong>(kv.Key, BitConverter.ToUInt32(data, offset)));
                    }
                    else
                    {
                        //We could not fetch the data block, or it was incomplete
                    }
                }

                return(result);
            }
コード例 #14
0
        public IVirtualThread[] GetVirtualThreads(IGlobalExpressionEvaluator expressionEvaluator)
        {
            //Based on the logic from svcRtxThreadEnumerate()

            List <IVirtualThread> result = new List <IVirtualThread>();

            var thr = expressionEvaluator.EvaluateIntegralExpression("osRtxInfo.thread.run.curr");

            if (!thr.HasValue || thr == 0)
            {
                return(new IVirtualThread[0]);
            }

            HashSet <ulong> reportedIDs = new HashSet <ulong> {
                thr.Value
            };

            result.Add(new RTXThread(this, thr.Value, expressionEvaluator, true));
            ReportThreadList(result, expressionEvaluator, "osRtxInfo.thread.ready.thread_list", reportedIDs);
            ReportThreadList(result, expressionEvaluator, "osRtxInfo.thread.delay_list", reportedIDs);
            ReportThreadList(result, expressionEvaluator, "osRtxInfo.thread.wait_list", reportedIDs);
            return(result.ToArray());
        }
コード例 #15
0
        public IVirtualThread[] GetVirtualThreads(
            IGlobalExpressionEvaluator e)
        {
            // Get the total number of tasks running
            int taskCount = (int)e.EvaluateIntegralExpression("uxCurrentNumberOfTasks");

            // Get the number of different priorities (i.e. configMAX_PRIORITIES) --
            // there is a ready task list for each possible priority
            int priorityCount = (int)e.EvaluateIntegralExpression("sizeof(pxReadyTasksLists)/sizeof(pxReadyTasksLists[0])");

            List <IVirtualThread> threads = new List <IVirtualThread>();

            // Get a pointer to the current TCB -- it's used to compare to the TCB of
            // each list found below, and a match means it's the currently running task
            UInt64?pxCurrentTCB = e.EvaluateIntegralExpression("pxCurrentTCB");
            int    currentTask  = 0;

            // If the CPU type hasn't been found yet, do it -- it's necessary to find
            // out the stack layout later on

            if (!_StackLayout.HasValue)
            {
                int disassemblyLines = e.GDBSession.ExecuteCommand("disassemble PendSV_Handler").AdditionalOutput?.Count(s => rgDisassemblyLine.IsMatch(s)) ?? 0;
                if (disassemblyLines == 0)
                {
                    disassemblyLines = e.GDBSession.ExecuteCommand("disassemble xPortPendSVHandler").AdditionalOutput?.Count(s => rgDisassemblyLine.IsMatch(s)) ?? 0;
                }

                if (disassemblyLines >= 21 && disassemblyLines <= 22)
                {
                    _StackLayout = StackLayout.WithoutFPU;
                }
                else if (disassemblyLines >= 30 && disassemblyLines <= 33)
                {
                    _StackLayout = StackLayout.WithOptionalFPU;
                }
                else if (e.EvaluateIntegralExpression("sizeof(void *)") == 8)
                {
                    _StackLayout = StackLayout.CortexA53;
                }
                else
                {
                    var cpu = GetCPUType(e);
                    _StackLayout = (cpu == CPUTypes.CPU_ARM_CORTEX_M4) ? StackLayout.WithOptionalFPU : StackLayout.WithoutFPU;
                }
            }

            // Find tasks in ready lists -- one for each possible priority in FreeRTOS
            for (int i = 0; i < priorityCount; i++)
            {
                // Add all tasks found in this list
                threads.AddRange(GetThreadsFromList(e, "pxReadyTasksLists[" + i + "]", pxCurrentTCB, ref currentTask));

                // If all tasks are accounted for, return early so as not to waste time
                // querying for extra tasks
                if (currentTask == taskCount)
                {
                    return(threads.ToArray());
                }
            }

            // Find tasks in delayed task lists
            for (int i = 1; i <= 2; i++)
            {
                // Add all tasks found in this list
                threads.AddRange(GetThreadsFromList(e, "xDelayedTaskList" + i, pxCurrentTCB, ref currentTask));

                // If all tasks are accounted for, return early so as not to waste time
                // querying for extra tasks
                if (currentTask == taskCount)
                {
                    return(threads.ToArray());
                }
            }

            // Find tasks in suspended task list
            threads.AddRange(GetThreadsFromList(e, "xSuspendedTaskList", pxCurrentTCB, ref currentTask));

            return(threads.ToArray());
        }
コード例 #16
0
        public int?GetActiveVirtualThreadId(IGlobalExpressionEvaluator evaluator)
        {
            ulong?id = evaluator.EvaluateIntegralExpression("_kernel.current");

            return((int?)id);
        }
コード例 #17
0
        public int?GetActiveVirtualThreadId(IGlobalExpressionEvaluator evaluator)
        {
            ulong?id = evaluator.EvaluateIntegralExpression("osRtxInfo.thread.run.curr");

            return((int?)id);
        }
コード例 #18
0
 public int?GetActiveVirtualThreadId(IGlobalExpressionEvaluator evaluator)
 {
     return((int?)evaluator.EvaluateIntegralExpression("pxCurrentTCB->uxTCBNumber"));
 }