--break_on_instruction=0x... and --break_on_memory=0x...

This commit is contained in:
Ben Vanik 2013-10-20 16:54:59 -07:00
parent cddab7ffb0
commit 42a8fc0b59
3 changed files with 48 additions and 0 deletions

View File

@ -20,6 +20,9 @@ DECLARE_bool(trace_user_calls);
DECLARE_bool(trace_kernel_calls); DECLARE_bool(trace_kernel_calls);
DECLARE_uint64(trace_thread_mask); DECLARE_uint64(trace_thread_mask);
DECLARE_uint64(break_on_instruction);
DECLARE_uint64(break_on_memory);
DECLARE_string(load_module_map); DECLARE_string(load_module_map);
DECLARE_string(dump_path); DECLARE_string(dump_path);

View File

@ -25,6 +25,13 @@ DEFINE_uint64(trace_thread_mask, -1,
"Trace threads with IDs in the mask, or -1 for all."); "Trace threads with IDs in the mask, or -1 for all.");
// Breakpoints:
DEFINE_uint64(break_on_instruction, 0,
"int3 before the given guest address is executed.");
DEFINE_uint64(break_on_memory, 0,
"int3 on read/write to the given memory address.");
// Debugging: // Debugging:
DEFINE_string(load_module_map, "", DEFINE_string(load_module_map, "",
"Loads a .map for symbol names and to diff with the generated symbol " "Loads a .map for symbol names and to diff with the generated symbol "

View File

@ -652,7 +652,13 @@ void X64Emitter::GenerateBasicBlock(FunctionBlock* block) {
typedef int (*InstrEmitter)(X64Emitter& g, X86Compiler& c, InstrData& i); typedef int (*InstrEmitter)(X64Emitter& g, X86Compiler& c, InstrData& i);
InstrEmitter emit = (InstrEmitter)i.type->emit; InstrEmitter emit = (InstrEmitter)i.type->emit;
TraceInstruction(i); TraceInstruction(i);
if (i.address == FLAGS_break_on_instruction) {
c.int3();
}
if (!i.type->emit || emit(*this, compiler_, i)) { if (!i.type->emit || emit(*this, compiler_, i)) {
// This printf is handy for sort/uniquify to find instructions. // This printf is handy for sort/uniquify to find instructions.
printf("unimplinstr %s\n", i.type->name); printf("unimplinstr %s\n", i.type->name);
@ -1877,6 +1883,14 @@ GpVar X64Emitter::ReadMemory(
uint32_t cia, GpVar& addr, uint32_t size, bool acquire, bool bswap) { uint32_t cia, GpVar& addr, uint32_t size, bool acquire, bool bswap) {
X86Compiler& c = compiler_; X86Compiler& c = compiler_;
if (FLAGS_break_on_memory) {
Label l(c.newLabel());
c.cmp(addr.r32(), imm(FLAGS_break_on_memory));
c.jne(l);
c.int3();
c.bind(l);
}
// Rebase off of memory base pointer. // Rebase off of memory base pointer.
GpVar real_address = TouchMemoryAddress(cia, addr); GpVar real_address = TouchMemoryAddress(cia, addr);
@ -1931,6 +1945,14 @@ void X64Emitter::WriteMemory(
bool release, bool bswap) { bool release, bool bswap) {
X86Compiler& c = compiler_; X86Compiler& c = compiler_;
if (FLAGS_break_on_memory) {
Label l(c.newLabel());
c.cmp(addr.r32(), imm(FLAGS_break_on_memory));
c.jne(l);
c.int3();
c.bind(l);
}
// Rebase off of memory base pointer. // Rebase off of memory base pointer.
GpVar real_address = TouchMemoryAddress(cia, addr); GpVar real_address = TouchMemoryAddress(cia, addr);
@ -2011,6 +2033,14 @@ XmmVar X64Emitter::ReadMemoryXmm(
uint32_t cia, GpVar& addr, uint32_t alignment) { uint32_t cia, GpVar& addr, uint32_t alignment) {
X86Compiler& c = compiler_; X86Compiler& c = compiler_;
if (FLAGS_break_on_memory) {
Label l(c.newLabel());
c.cmp(addr.r32(), imm(FLAGS_break_on_memory));
c.jne(l);
c.int3();
c.bind(l);
}
// Align memory address. // Align memory address.
GpVar aligned_addr(c.newGpVar()); GpVar aligned_addr(c.newGpVar());
c.mov(aligned_addr, addr); c.mov(aligned_addr, addr);
@ -2045,6 +2075,14 @@ void X64Emitter::WriteMemoryXmm(
uint32_t cia, GpVar& addr, uint32_t alignment, XmmVar& value) { uint32_t cia, GpVar& addr, uint32_t alignment, XmmVar& value) {
X86Compiler& c = compiler_; X86Compiler& c = compiler_;
if (FLAGS_break_on_memory) {
Label l(c.newLabel());
c.cmp(addr.r32(), imm(FLAGS_break_on_memory));
c.jne(l);
c.int3();
c.bind(l);
}
// Align memory address. // Align memory address.
GpVar aligned_addr(c.newGpVar()); GpVar aligned_addr(c.newGpVar());
c.mov(aligned_addr, addr); c.mov(aligned_addr, addr);