/* Ensure a Condition is met */ bool Test::checkConditions(ppc::Interpreter::State &state, std::vector<Test::Condition> &conds) { for (auto &cond : conds) { switch (cond.type) { case ConditionType::SetRegister: if (cond.target.type != ValueType::Register) { return false; } if (!setRegister(state, cond.target.name, cond.value)) { throw new TestError(state, "Could not set register %s", cond.target.name.c_str()); } break; case ConditionType::CheckRegister: if (cond.target.type != ValueType::Register) { return false; } if (!checkRegister(state, cond.target.name, cond.value)) { throw new TestError(state, "Incorrect value in register %s", cond.target.name.c_str()); } break; case ConditionType::SetMemory: if (cond.target.type != ValueType::Address) { return false; } if (!setMemory(state, cond.target.value, cond.value)) { throw new TestError(state, "Could not set memory at 0x%X", translateAddress(cond.target.value)); } break; case ConditionType::CheckMemory: if (cond.target.type != ValueType::Address) { return false; } if (!checkMemory(state, cond.target.value, cond.value)) { throw new TestError(state, "Incorrect value at memory location 0x%X", translateAddress(cond.target.value)); } break; } } return true; }
int performIRET() { if (mode == USER_MODE) { raiseException(newException(EX_ILLINSTR, "Call to Privileged Instruction IRET in USER mode", 0)); return 0; } Exception e = isSafeState2(); if (e.code != EX_NONE) { raiseException(e); return 0; } mode = USER_MODE; Address T = translateAddress(getInteger(reg[SP_REG])); if (T.page == -1 && T.word == -1) { mode = KERNEL_MODE; return 0; } char * value = getWordFromAddress(T); if (getType(value) == TYPE_STR) { mode = KERNEL_MODE; raiseException(newException(EX_ILLMEM, "Illegal return address", 0)); return 0; } int result = getInteger(value); if (result < 0 || result >= getInteger(reg[PTLR_REG]) * PAGE_SIZE) { mode = KERNEL_MODE; raiseException(newException(EX_ILLMEM, "Illegal return address", 0)); return 0; } storeInteger(reg[IP_REG], result); storeInteger(reg[SP_REG], getInteger(reg[SP_REG]) - 1); return 1; }
int performPop(int X, int flagX) { char * value; Exception e; Address T = translateAddress(getInteger(reg[SP_REG])); if (T.page == -1 && T.word == -1) return 0; switch (flagX) { case REG: e = isRegisterInaccessible(X); if (e.code != EX_NONE) { raiseException(e); return 0; } value = getWordFromAddress(T); strcpy(reg[X], value); storeInteger(reg[SP_REG], getInteger(reg[SP_REG]) - 1); return 1; break; case IP: raiseException(newException(EX_ILLOPERAND, "Illegal operand IP. Cannot alter readonly register", 0)); return 0; break; case EFR: raiseException(newException(EX_ILLOPERAND, "Illegal operand EFR. Cannot alter readonly register", 0)); return 0; break; default: raiseException(newException(EX_ILLOPERAND, "Illegal Operand", 0)); return 0; break; } }
int performPush(int X, int flagX) { Address T = translateAddress(getInteger(reg[SP_REG]) + 1); if (T.page == -1 && T.word == -1) return 0; Exception e; switch (flagX) { case REG: case SP: case BP: case IP: case PTBR: case PTLR: case EFR: e = isRegisterInaccessible(X); if (e.code != EX_NONE) { raiseException(e); return 0; } if (storeWordToAddress(T, reg[X])) { storeInteger(reg[SP_REG], getInteger(reg[SP_REG]) + 1); return 1; } else return 0; break; default: raiseException(newException(EX_ILLOPERAND, "Illegal Operand", 0)); return 0; break; } }
/* Check memory for value */ bool Test::checkMemory(ppc::Interpreter::State &state, uint64_t src, Test::Value &val) { int64_t value; auto addr = translateAddress(src); if (!addr || !getValue(val, value)) { return false; } return value == Memory::read<uint64_t>(addr); }
/* Set memory to value */ bool Test::setMemory(ppc::Interpreter::State &state, uint64_t dst, Test::Value &val) { int64_t value; auto addr = translateAddress(dst); if (!addr || !getValue(val, value)) { return false; } Memory::write(addr, value); return true; }
void* TR_RuntimeHelperTable::getFunctionEntryPointOrConst(TR_RuntimeHelper h) { if (h < TR_numRuntimeHelpers) { if (_linkage[h] == TR_Helper) return translateAddress(_helpers[h]); else return _helpers[h]; } else return reinterpret_cast<void*>(TR_RuntimeHelperTable::INVALID_FUNCTION_POINTER); }
/* Get value */ bool Test::getValue(Test::Value &in, int64_t &out) { switch (in.type) { case Test::ValueType::Immediate: out = in.value; return true; case Test::ValueType::Address: out = translateAddress(in.value); return true; } return false; }
int performCall(int X, int flagX) { Exception e = isSafeState2(); if (e.code != EX_NONE) { raiseException(e); return 0; } if (flagX != NUM) { raiseException(newException(EX_ILLOPERAND, "Illegal operand", 0)); return 0; } e = isRestrictedMemoryLocation(X); if (e.code != EX_NONE) { raiseException(e); return 0; } Address T = translateAddress(getInteger(reg[SP_REG]) + 1); if (T.page == -1 && T.word == -1) return; storeInteger(reg[SP_REG], getInteger(reg[SP_REG]) + 1); storeInteger(page[T.page].word[T.word], getInteger(reg[IP_REG]) + WORDS_PER_INSTR); storeInteger(reg[IP_REG], X); return 1; }
int performRet() { Exception e = isSafeState2(); if (e.code != EX_NONE) { raiseException(e); return 0; } Address T = translateAddress(getInteger(reg[SP_REG])); if (T.page == -1 && T.word == -1) return; char * value = getWordFromAddress(T); if (value == NULL || getType(value) == TYPE_STR) { raiseException(newException(EX_ILLMEM, "Illegal return address", 0)); return 0; } int result = getInteger(value); e = isRestrictedMemoryLocation(result); if (e.code != EX_NONE) { raiseException(e); return 0; } storeInteger(reg[IP_REG], result); storeInteger(reg[SP_REG], getInteger(reg[SP_REG]) - 1); return 1; }
int storeWordToMemoryLocation(int r, char * word) { return storeWordToAddress(translateAddress(r), word); }
char * getWordFromMemoryLocation(int r) { return getWordFromAddress(translateAddress(r)); }