Merge pull request #4738 from EmptyChaos/pe-stackcheck-fix

PatchEngine: Fix potential crashing during stack probe
This commit is contained in:
Matthew Parlane 2017-01-24 11:27:44 +13:00 committed by GitHub
commit 00c993143f
3 changed files with 20 additions and 12 deletions

View File

@ -223,11 +223,7 @@ static bool IsStackSane()
return false; return false;
// Check the link register makes sense (that it points to a valid IBAT address) // Check the link register makes sense (that it points to a valid IBAT address)
auto insn = PowerPC::TryReadInstruction(PowerPC::HostRead_U32(next_SP + 4)); return PowerPC::HostIsInstructionRAMAddress(PowerPC::HostRead_U32(next_SP + 4));
if (!insn.valid || !insn.hex)
return false;
return true;
} }
bool ApplyFramePatches() bool ApplyFramePatches()

View File

@ -622,19 +622,18 @@ bool IsOptimizableRAMAddress(const u32 address)
return (bat_result & 2) != 0; return (bat_result & 2) != 0;
} }
bool HostIsRAMAddress(u32 address) template <XCheckTLBFlag flag>
static bool IsRAMAddress(u32 address, bool translate)
{ {
bool performTranslation = UReg_MSR(MSR).DR; if (translate)
int segment = address >> 28;
if (performTranslation)
{ {
auto translate_address = TranslateAddress<FLAG_NO_EXCEPTION>(address); auto translate_address = TranslateAddress<flag>(address);
if (!translate_address.Success()) if (!translate_address.Success())
return false; return false;
address = translate_address.address; address = translate_address.address;
segment = address >> 28;
} }
u32 segment = address >> 28;
if (segment == 0x0 && (address & 0x0FFFFFFF) < Memory::REALRAM_SIZE) if (segment == 0x0 && (address & 0x0FFFFFFF) < Memory::REALRAM_SIZE)
return true; return true;
else if (Memory::m_pEXRAM && segment == 0x1 && (address & 0x0FFFFFFF) < Memory::EXRAM_SIZE) else if (Memory::m_pEXRAM && segment == 0x1 && (address & 0x0FFFFFFF) < Memory::EXRAM_SIZE)
@ -646,6 +645,17 @@ bool HostIsRAMAddress(u32 address)
return false; return false;
} }
bool HostIsRAMAddress(u32 address)
{
return IsRAMAddress<FLAG_NO_EXCEPTION>(address, UReg_MSR(MSR).DR);
}
bool HostIsInstructionRAMAddress(u32 address)
{
// Instructions are always 32bit aligned.
return !(address & 3) && IsRAMAddress<FLAG_OPCODE_NO_EXCEPTION>(address, UReg_MSR(MSR).IR);
}
void DMA_LCToMemory(const u32 memAddr, const u32 cacheAddr, const u32 numBlocks) void DMA_LCToMemory(const u32 memAddr, const u32 cacheAddr, const u32 numBlocks)
{ {
// TODO: It's not completely clear this is the right spot for this code; // TODO: It's not completely clear this is the right spot for this code;
@ -1240,7 +1250,7 @@ void IBATUpdated()
template <const XCheckTLBFlag flag> template <const XCheckTLBFlag flag>
static TranslateAddressResult TranslateAddress(const u32 address) static TranslateAddressResult TranslateAddress(const u32 address)
{ {
u32 bat_result = (flag == FLAG_OPCODE ? ibat_table : dbat_table)[address >> BAT_INDEX_SHIFT]; u32 bat_result = (IsOpcodeFlag(flag) ? ibat_table : dbat_table)[address >> BAT_INDEX_SHIFT];
if (bat_result & 1) if (bat_result & 1)
{ {
u32 result_addr = (bat_result & ~3) | (address & 0x0001FFFF); u32 result_addr = (bat_result & ~3) | (address & 0x0001FFFF);

View File

@ -220,6 +220,8 @@ void HostWrite_U64(const u64 var, const u32 address);
// Returns whether a read or write to the given address will resolve to a RAM // Returns whether a read or write to the given address will resolve to a RAM
// access given the current CPU state. // access given the current CPU state.
bool HostIsRAMAddress(const u32 address); bool HostIsRAMAddress(const u32 address);
// Same as HostIsRAMAddress, but uses IBAT instead of DBAT.
bool HostIsInstructionRAMAddress(u32 address);
std::string HostGetString(u32 em_address, size_t size = 0); std::string HostGetString(u32 em_address, size_t size = 0);