@ -175,9 +175,10 @@ struct Breakpoint {
u64 len ;
} ;
std : : map < u64 , Breakpoint > breakpoints_execute ;
std : : map < u64 , Breakpoint > breakpoints_read ;
std : : map < u64 , Breakpoint > breakpoints_write ;
using BreakpointMap = std : : map < VAddr , Breakpoint > ;
BreakpointMap breakpoints_execute ;
BreakpointMap breakpoints_read ;
BreakpointMap breakpoints_write ;
struct Module {
std : : string name ;
@ -419,11 +420,11 @@ static u8 CalculateChecksum(const u8* buffer, size_t length) {
}
/**
* Get the list of breakpoints for a given breakpoint type .
* Get the map of breakpoints for a given breakpoint type .
*
* @ param type Type of breakpoint list .
* @ param type Type of breakpoint map .
*/
static std: : map < u64 , Breakpoint > & GetBreakpointList ( BreakpointType type ) {
static BreakpointMap& GetBreakpointMap ( BreakpointType type ) {
switch ( type ) {
case BreakpointType : : Execute :
return breakpoints_execute ;
@ -443,19 +444,21 @@ static std::map<u64, Breakpoint>& GetBreakpointList(BreakpointType type) {
* @ param addr Address of breakpoint .
*/
static void RemoveBreakpoint ( BreakpointType type , VAddr addr ) {
std: : map < u64 , Breakpoint > & p = GetBreakpointList ( type ) ;
BreakpointMap& p = GetBreakpointMap ( type ) ;
auto bp = p . find ( static_cast < u64 > ( addr ) ) ;
if ( bp ! = p . end ( ) ) {
LOG_DEBUG ( Debug_GDBStub , " gdb: removed a breakpoint: {:016X} bytes at {:016X} of type {} " ,
bp - > second . len , bp - > second . addr , static_cast < int > ( type ) ) ;
p . erase ( static_cast < u64 > ( addr ) ) ;
const auto bp = p . find ( addr ) ;
if ( bp = = p . end ( ) ) {
return ;
}
LOG_DEBUG ( Debug_GDBStub , " gdb: removed a breakpoint: {:016X} bytes at {:016X} of type {} " ,
bp - > second . len , bp - > second . addr , static_cast < int > ( type ) ) ;
p . erase ( addr ) ;
}
BreakpointAddress GetNextBreakpointFromAddress ( VAddr addr , BreakpointType type ) {
std : : map < u64 , Breakpoint > & p = GetBreakpointList ( type ) ;
auto next_breakpoint = p . lower_bound ( static_cast < u64 > ( addr ) ) ;
const BreakpointMap & p = GetBreakpointMap ( type ) ;
const auto next_breakpoint = p . lower_bound ( addr ) ;
BreakpointAddress breakpoint ;
if ( next_breakpoint ! = p . end ( ) ) {
@ -474,31 +477,33 @@ bool CheckBreakpoint(VAddr addr, BreakpointType type) {
return false ;
}
std : : map < u64 , Breakpoint > & p = GetBreakpointList ( type ) ;
const BreakpointMap & p = GetBreakpointMap ( type ) ;
const auto bp = p . find ( addr ) ;
auto bp = p . find ( static_cast < u64 > ( addr ) ) ;
if ( bp ! = p . end ( ) ) {
u64 len = bp - > second . len ;
if ( bp = = p . end ( ) ) {
return false ;
}
// IDA Pro defaults to 4-byte breakpoints for all non-hardware breakpoints
// no matter if it's a 4-byte or 2-byte instruction. When you execute a
// Thumb instruction with a 4-byte breakpoint set, it will set a breakpoint on
// two instructions instead of the single instruction you placed the breakpoint
// on. So, as a way to make sure that execution breakpoints are only breaking
// on the instruction that was specified, set the length of an execution
// breakpoint to 1. This should be fine since the CPU should never begin executing
// an instruction anywhere except the beginning of the instruction.
if ( type = = BreakpointType : : Execute ) {
len = 1 ;
}
u64 len = bp - > second . len ;
if ( bp - > second . active & & ( addr > = bp - > second . addr & & addr < bp - > second . addr + len ) ) {
LOG_DEBUG ( Debug_GDBStub ,
" Found breakpoint type {} @ {:016X}, range: {:016X} "
" - {:016X} ({:X} bytes) " ,
static_cast < int > ( type ) , addr , bp - > second . addr , bp - > second . addr + len , len ) ;
return true ;
}
// IDA Pro defaults to 4-byte breakpoints for all non-hardware breakpoints
// no matter if it's a 4-byte or 2-byte instruction. When you execute a
// Thumb instruction with a 4-byte breakpoint set, it will set a breakpoint on
// two instructions instead of the single instruction you placed the breakpoint
// on. So, as a way to make sure that execution breakpoints are only breaking
// on the instruction that was specified, set the length of an execution
// breakpoint to 1. This should be fine since the CPU should never begin executing
// an instruction anywhere except the beginning of the instruction.
if ( type = = BreakpointType : : Execute ) {
len = 1 ;
}
if ( bp - > second . active & & ( addr > = bp - > second . addr & & addr < bp - > second . addr + len ) ) {
LOG_DEBUG ( Debug_GDBStub ,
" Found breakpoint type {} @ {:016X}, range: {:016X} "
" - {:016X} ({:X} bytes) " ,
static_cast < int > ( type ) , addr , bp - > second . addr , bp - > second . addr + len , len ) ;
return true ;
}
return false ;
@ -977,7 +982,7 @@ static void Continue() {
* @ param len Length of breakpoint .
*/
static bool CommitBreakpoint ( BreakpointType type , VAddr addr , u64 len ) {
std: : map < u64 , Breakpoint > & p = GetBreakpointList ( type ) ;
BreakpointMap& p = GetBreakpointMap ( type ) ;
Breakpoint breakpoint ;
breakpoint . active = true ;