Beispiel #1
0
        void LineComplete(ParserElementBase aElement)
        {
            ParserLine       line      = (ParserLine)aElement;
            TUserContextType tableType = (TUserContextType)line.Tag;
            UserContextTable table     = CrashDebugger.UserContextTableManager[tableType];

            // Each line should have a known number of entries stored within it's field collection.
            int expectedCount = UserContextTable.EntryCount * 2; // 2 fields per table entry
            int actualCount   = line.Count;

            if (expectedCount == actualCount)
            {
                for (int i = 0; i < expectedCount; i += 2)
                {
                    ParserField fieldType  = line[i + 0];
                    ParserField fieldValue = line[i + 1];
                    //
                    if (fieldType.IsUint && fieldValue.IsUint)
                    {
                        UserContextTable.TArmRegisterIndex reg = (UserContextTable.TArmRegisterIndex)(i / 2);
                        UserContextTableEntry entry            = table[reg];
                        //
                        UserContextTableEntry.TType type = (UserContextTableEntry.TType)fieldType.AsUint;
                        byte value = (byte)fieldValue.AsUint;
                        //
                        entry.Type   = type;
                        entry.Offset = value;
                    }
                }
            }
            else
            {
                throw new Exception("User Context Table Corruption");
            }
        }
Beispiel #2
0
        private RegisterCollection GetUserContextRegisters()
        {
            bool isCurrent         = IsCurrent;
            RegisterCollection ret = new RegisterCollection(Registers, RegisterCollection.TType.ETypeUser, iParentThread.OwningProcess);

            // User-land CPSR is stored in SPSR_SVC
            RegisterEntry spsr = Registers[TArmRegisterType.EArmReg_SPSR];

            ret[TArmRegisterType.EArmReg_CPSR].Value = spsr.Value;

            // Get the context table that we'll need to work out the reg positions
            UserContextTable.UserContextTable table = CrashDebugger.UserContextTableManager[UserContextType];

            // Get SP and stack data for supervisor thread
            uint            sp     = SavedSP;
            ThreadStackData spData = iParentThread.StackInfoSupervisor.Data;

            if (spData.Info.Data.Size > 0)
            {
                // This is the user side address that will be branched back to once we exit SVC mode...
                uint retAddr = UserReturnAddress;
                ret[TArmRegisterType.EArmReg_PC].Value = retAddr;

                // Now try to get the register values off of the supervisor stack
                DataBuffer superStackData = spData.Data;
                foreach (ArmRegister reg in ret)
                {
                    if (UserContextTable.UserContextTable.IsSupported(reg.RegType))
                    {
                        UserContextTableEntry uctEntry = table[reg.RegType];
                        if (uctEntry.IsAvailable(isCurrent))
                        {
                            ArmRegister savedSp  = new ArmRegister(TArmRegisterType.EArmReg_SP, sp);
                            uint        newValue = uctEntry.Process(savedSp, superStackData);
                            reg.Value = newValue;
                        }
                    }
                }
            }

            // Getting context of current thread? Some values can be fetched directly
            // from the registers if they are not available from the stack.
            if (isCurrent && table[TArmRegisterType.EArmReg_SP].Type == UserContextTableEntry.TType.EOffsetFromSp)
            {
                RegisterCollection userRegs = CrashDebugger.InfoCpu[RegisterCollection.TType.ETypeUser];
                //
                ret[TArmRegisterType.EArmReg_SP].Value = userRegs[TArmRegisterType.EArmReg_SP];
                ret[TArmRegisterType.EArmReg_LR].Value = userRegs[TArmRegisterType.EArmReg_LR];
            }

            return(ret);
        }