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"); } }
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); }