Skip to content

Commit

Permalink
Handle exec addr errors better - don't let IgnoreBadMemoryAccesses sk…
Browse files Browse the repository at this point in the history
…ip dispatcher exceptions.

It would then just fall through into the compiler and die.

Should remove one of the "mystery" crashes from #14082.
  • Loading branch information
hrydgard committed Feb 9, 2021
1 parent b539ce8 commit 6b4356a
Show file tree
Hide file tree
Showing 10 changed files with 37 additions and 5 deletions.
1 change: 1 addition & 0 deletions Core/Core.cpp
Expand Up @@ -398,6 +398,7 @@ const char *MemoryExceptionTypeAsString(MemoryExceptionType type) {
case MemoryExceptionType::WRITE_WORD: return "Write Word";
case MemoryExceptionType::READ_BLOCK: return "Read Block";
case MemoryExceptionType::WRITE_BLOCK: return "Read/Write Block";
case MemoryExceptionType::EXEC_ADDR: return "Bad Exec Addr";
default:
return "N/A";
}
Expand Down
1 change: 1 addition & 0 deletions Core/Core.h
Expand Up @@ -88,6 +88,7 @@ enum class MemoryExceptionType {
WRITE_WORD,
READ_BLOCK,
WRITE_BLOCK,
EXEC_ADDR,
};
enum class ExecExceptionType {
JUMP,
Expand Down
1 change: 1 addition & 0 deletions Core/MIPS/ARM64/Arm64Asm.cpp
Expand Up @@ -250,6 +250,7 @@ void Arm64Jit::GenerateFixedCode(const JitOptions &jo) {
#ifdef MASKED_PSP_MEMORY
ANDI2R(SCRATCH1, SCRATCH1, 0x3FFFFFFF);
#endif
dispatcherFetch = GetCodePtr();
LDR(SCRATCH1, MEMBASEREG, SCRATCH1_64);
LSR(SCRATCH2, SCRATCH1, 24); // or UBFX(SCRATCH2, SCRATCH1, 24, 8)
ANDI2R(SCRATCH1, SCRATCH1, 0x00FFFFFF);
Expand Down
4 changes: 4 additions & 0 deletions Core/MIPS/ARM64/Arm64Jit.h
Expand Up @@ -185,6 +185,9 @@ class Arm64Jit : public Arm64Gen::ARM64CodeBlock, public JitInterface, public MI
const u8 *GetDispatcher() const override {
return dispatcher;
}
bool IsAtDispatchFetch(const u8 *ptr) const override {
return ptr == dispatcherFetch;
}

void LinkBlock(u8 *exitPoint, const u8 *checkedEntry) override;
void UnlinkBlock(u8 *checkedEntry, u32 originalAddress) override;
Expand Down Expand Up @@ -275,6 +278,7 @@ class Arm64Jit : public Arm64Gen::ARM64CodeBlock, public JitInterface, public MI
const u8 *dispatcherPCInSCRATCH1;
const u8 *dispatcher;
const u8 *dispatcherNoCheck;
const u8 *dispatcherFetch;

const u8 *saveStaticRegisters;
const u8 *loadStaticRegisters;
Expand Down
3 changes: 3 additions & 0 deletions Core/MIPS/JitCommon/JitCommon.h
Expand Up @@ -123,6 +123,9 @@ namespace MIPSComp {

virtual bool CodeInRange(const u8 *ptr) const = 0;
virtual bool DescribeCodePtr(const u8 *ptr, std::string &name) = 0;
virtual bool IsAtDispatchFetch(const u8 *ptr) const {
return false;
}
virtual const u8 *GetDispatcher() const = 0;
virtual const u8 *GetCrashHandler() const = 0;
virtual JitBlockCache *GetBlockCache() = 0;
Expand Down
2 changes: 1 addition & 1 deletion Core/MIPS/x86/Asm.cpp
Expand Up @@ -161,7 +161,7 @@ void Jit::GenerateFixedCode(JitOptions &jo) {
#ifdef MASKED_PSP_MEMORY
AND(32, R(EAX), Imm32(Memory::MEMVIEW32_MASK));
#endif

dispatcherFetch = GetCodePtr();
#ifdef _M_IX86
_assert_msg_( Memory::base != 0, "Memory base bogus");
MOV(32, R(EAX), MDisp(EAX, (u32)Memory::base));
Expand Down
5 changes: 5 additions & 0 deletions Core/MIPS/x86/Jit.cpp
Expand Up @@ -274,6 +274,11 @@ void Jit::Compile(u32 em_address) {
ClearCache();
}

if (!Memory::IsValidAddress(em_address)) {
Core_ExecException(em_address, em_address, ExecExceptionType::JUMP);
return;
}

BeginWrite();

int block_num = blocks.AllocateBlock(em_address);
Expand Down
6 changes: 6 additions & 0 deletions Core/MIPS/x86/Jit.h
Expand Up @@ -298,6 +298,11 @@ class Jit : public Gen::XCodeBlock, public JitInterface, public MIPSFrontendInte
}
return true;
}

bool IsAtDispatchFetch(const u8 *codePtr) const override {
return codePtr == dispatcherFetch;
}

void SaveFlags();
void LoadFlags();

Expand All @@ -321,6 +326,7 @@ class Jit : public Gen::XCodeBlock, public JitInterface, public MIPSFrontendInte
const u8 *dispatcherCheckCoreState;
const u8 *dispatcherNoCheck;
const u8 *dispatcherInEAXNoCheck;
const u8 *dispatcherFetch;

const u8 *restoreRoundingMode;
const u8 *applyRoundingMode;
Expand Down
17 changes: 14 additions & 3 deletions Core/MemFault.cpp
Expand Up @@ -41,16 +41,19 @@ namespace Memory {

static int64_t g_numReportedBadAccesses = 0;
const uint8_t *g_lastCrashAddress;
MemoryExceptionType g_lastMemoryExceptionType;

std::unordered_set<const uint8_t *> g_ignoredAddresses;

void MemFault_Init() {
g_numReportedBadAccesses = 0;
g_lastCrashAddress = nullptr;
g_lastMemoryExceptionType = MemoryExceptionType::NONE;
g_ignoredAddresses.clear();
}

bool MemFault_MayBeResumable() {
return g_lastCrashAddress != nullptr;
return g_lastCrashAddress != nullptr && g_lastMemoryExceptionType != MemoryExceptionType::EXEC_ADDR;
}

void MemFault_IgnoreLastCrash() {
Expand Down Expand Up @@ -122,11 +125,15 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) {

std::string infoString = "";

bool isAtDispatch = false;
if (MIPSComp::jit) {
std::string desc;
if (MIPSComp::jit->DescribeCodePtr(codePtr, desc)) {
infoString += desc + "\n";
}
if (MIPSComp::jit->IsAtDispatchFetch(codePtr)) {
isAtDispatch = true;
}
}

int instructionSize = 4;
Expand Down Expand Up @@ -158,7 +165,9 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) {
infoString += disassembly + "\n";
}

if (success) {
if (isAtDispatch) {
type = MemoryExceptionType::EXEC_ADDR;
} else if (success) {
if (info.isMemoryWrite) {
type = MemoryExceptionType::WRITE_WORD;
} else {
Expand All @@ -168,7 +177,9 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) {
type = MemoryExceptionType::UNKNOWN;
}

if (success && (g_Config.bIgnoreBadMemAccess || g_ignoredAddresses.find(codePtr) != g_ignoredAddresses.end())) {
g_lastMemoryExceptionType = type;

if (success && !isAtDispatch && (g_Config.bIgnoreBadMemAccess || g_ignoredAddresses.find(codePtr) != g_ignoredAddresses.end())) {
if (!info.isMemoryWrite) {
// It was a read. Fill the destination register with 0.
// TODO
Expand Down

0 comments on commit 6b4356a

Please sign in to comment.