corrected stack protection bug that caused false positives

This commit is contained in:
JetSetIlly 2023-07-22 14:48:37 +01:00
parent fbee41d0fc
commit 5cfb04aa97
4 changed files with 34 additions and 29 deletions

View file

@ -865,6 +865,13 @@ func (dbg *Debugger) CartYield(yield mapper.CoProcYieldType) mapper.YieldHookRes
return mapper.YieldHookEnd
}
// resolve deferred yield
if dbg.halting.deferredCartridgeYield {
dbg.halting.deferredCartridgeYield = false
dbg.halting.cartridgeYield = true
return mapper.YieldHookEnd
}
switch yield {
case mapper.YieldProgramEnded:
// expected reason for CDF and DPC+ cartridges
@ -875,10 +882,17 @@ func (dbg *Debugger) CartYield(yield mapper.CoProcYieldType) mapper.YieldHookRes
return mapper.YieldHookContinue
}
// if emulation is in the initialisation state then we return true to
// indicate that the yield is not safe and execution should halt immediately
// if emulation is in itialisation state then we cause coprocessor execution
// to end unless it's a memory or access erorr
//
// this is an area that's likely to change. it's of particular interest to
// ACE and ELF ROMs in which the coprocessor is run very early in order to
// retrive the 6507 reset address
//
// a deferred YeildHookEnd might be a better option
if dbg.State() == govern.Initialising {
return mapper.YieldHookEnd
dbg.halting.deferredCartridgeYield = true
return mapper.YieldHookContinue
}
dbg.halting.cartridgeYield = true

View file

@ -35,6 +35,10 @@ type haltCoordination struct {
// the cartridge has issued a yield signal that we should stop the debugger for
cartridgeYield bool
// the emulation must yield to the cartridge but it must be delayed until it
// is in a better state
deferredCartridgeYield bool
// halt conditions
breakpoints *breakpoints
traps *traps

View file

@ -24,6 +24,10 @@ import (
)
func (arm *ARM) illegalAccess(event string, addr uint32) {
if arm.state.stackHasCollided {
return
}
arm.state.yield.Type = mapper.YieldMemoryAccessError
arm.state.yield.Error = fmt.Errorf("%s: unrecognised address %08x (PC: %08x)", event, addr, arm.state.instructionPC)
@ -84,10 +88,7 @@ func (arm *ARM) read8bit(addr uint32) uint8 {
}
}
if !arm.state.stackHasCollided {
arm.illegalAccess("Read 8bit", addr)
}
arm.illegalAccess("Read 8bit", addr)
return uint8(arm.mmap.IllegalAccessValue)
}
@ -129,10 +130,7 @@ func (arm *ARM) write8bit(addr uint32, val uint8) {
}
}
if !arm.state.stackHasCollided {
arm.illegalAccess("Write 8bit", addr)
}
arm.illegalAccess("Write 8bit", addr)
return
}
@ -180,10 +178,7 @@ func (arm *ARM) read16bit(addr uint32, requiresAlignment bool) uint16 {
}
}
if !arm.state.stackHasCollided {
arm.illegalAccess("Read 16bit", addr)
}
arm.illegalAccess("Read 16bit", addr)
return uint16(arm.mmap.IllegalAccessValue)
}
@ -238,10 +233,7 @@ func (arm *ARM) write16bit(addr uint32, val uint16, requiresAlignment bool) {
}
}
if !arm.state.stackHasCollided {
arm.illegalAccess("Write 16bit", addr)
}
arm.illegalAccess("Write 16bit", addr)
return
}
@ -296,10 +288,7 @@ func (arm *ARM) read32bit(addr uint32, requiresAlignment bool) uint32 {
}
}
if !arm.state.stackHasCollided {
arm.illegalAccess("Read 32bit", addr)
}
arm.illegalAccess("Read 32bit", addr)
return arm.mmap.IllegalAccessValue
}
@ -354,10 +343,7 @@ func (arm *ARM) write32bit(addr uint32, val uint32, requiresAlignment bool) {
}
}
if !arm.state.stackHasCollided {
arm.illegalAccess("Write 32bit", addr)
}
arm.illegalAccess("Write 32bit", addr)
return
}

View file

@ -79,10 +79,11 @@ func (arm *ARM) stackProtectCheckProgramMemory() {
if stackMemory == arm.state.programMemory {
arm.state.yield.Type = mapper.YieldStackError
arm.state.yield.Error = fmt.Errorf("SP is pointing to program memory")
arm.state.stackHasCollided = true
} else {
return
}
arm.state.stackHasCollided = true
// add developer details if possible
if arm.dev != nil {
detail := arm.dev.StackCollision(arm.state.executingPC, arm.state.registers[rSP])