Skip to content

Commit ad4487d

Browse files
author
Andrew Fasano
committed
CallstackInstr: switch to SBE/EBE callbacks (now with correct types)
The old logic would miss many calls if tb_chaining was enabled (which is is by default). Since this plugin did not disable tb_chaining, many calls would be missed if a user didn't disable chaining or load another plugin that disabled chaining. This commit updates the plugin to use start_block_exec and end_block_exec which work even with tb_chaining enabled.
1 parent e29f574 commit ad4487d

File tree

1 file changed

+20
-38
lines changed

1 file changed

+20
-38
lines changed

panda/plugins/callstack_instr/callstack_instr.cpp

Lines changed: 20 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,8 @@ extern "C" {
5555
#include "panda/plog.h"
5656
#include "callstack_instr_int_fns.h"
5757

58-
bool translate_callback(CPUState* cpu, target_ulong pc);
59-
int exec_callback(CPUState* cpu, target_ulong pc);
60-
void before_block_exec(CPUState* cpu, TranslationBlock *tb);
61-
void after_block_exec(CPUState* cpu, TranslationBlock *tb, uint8_t exitCode);
58+
void start_block_exec(CPUState* cpu, TranslationBlock *tb);
59+
void end_block_exec(CPUState* cpu, TranslationBlock *tb);
6260
void after_block_translate(CPUState* cpu, TranslationBlock *tb);
6361

6462
bool init_plugin(void *);
@@ -322,7 +320,7 @@ void after_block_translate(CPUState *cpu, TranslationBlock *tb) {
322320
return;
323321
}
324322

325-
void before_block_exec(CPUState *cpu, TranslationBlock *tb) {
323+
void start_block_exec(CPUState *cpu, TranslationBlock *tb) {
326324
// if the block a call returns to was interrupted before it completed, this
327325
// function will be called twice - only want to remove the return value from
328326
// the stack once
@@ -366,7 +364,7 @@ void before_block_exec(CPUState *cpu, TranslationBlock *tb) {
366364
}
367365
}
368366

369-
void after_block_exec(CPUState* cpu, TranslationBlock *tb, uint8_t exitCode) {
367+
void end_block_exec(CPUState* cpu, TranslationBlock *tb) {
370368
target_ulong pc = 0x0;
371369
target_ulong cs_base = 0x0;
372370
uint32_t flags = 0x0;
@@ -377,35 +375,19 @@ void after_block_exec(CPUState* cpu, TranslationBlock *tb, uint8_t exitCode) {
377375

378376
// sometimes an attempt to run a block is interrupted, but this callback is
379377
// still made - only update the callstack if the block has run to completion
380-
if (exitCode <= TB_EXIT_IDX1) {
381-
if (tb_type == INSTR_CALL) {
382-
stack_entry se = {tb->pc + tb->size, tb_type};
383-
callstacks[curStackid].push_back(se);
384-
385-
// Also track the function that gets called
386-
// This retrieves the pc in an architecture-neutral way
387-
cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags);
388-
function_stacks[curStackid].push_back(pc);
389-
390-
PPP_RUN_CB(on_call, cpu, pc);
391-
} else if (tb_type == INSTR_RET) {
392-
//printf("Just executed a RET in TB " TARGET_FMT_lx "\n", tb->pc);
393-
//if (next) printf("Next TB: " TARGET_FMT_lx "\n", next->pc);
394-
}
395-
}
396-
// in case this block is one that a call returns to, need to node that its
397-
// execution was interrupted, so don't try to remove it from the callstack
398-
// when try (as already removed before this attempt)
399-
else {
400-
// verbose output is helpful in regression testing
401-
if (tb_type == INSTR_CALL) {
402-
verbose_log("callstack_instr not adding Stopped caller to stack",
403-
tb, curStackid, true);
404-
}
378+
if (tb_type == INSTR_CALL) {
379+
stack_entry se = {tb->pc + tb->size, tb_type};
380+
callstacks[curStackid].push_back(se);
381+
382+
// Also track the function that gets called
383+
// This retrieves the pc in an architecture-neutral way
405384
cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags);
406-
// erase nicely does nothing if key DNE
407-
stoppedInfo.erase(curStackid);
408-
stoppedInfo[curStackid] = pc;
385+
function_stacks[curStackid].push_back(pc);
386+
387+
PPP_RUN_CB(on_call, cpu, pc);
388+
} else if (tb_type == INSTR_RET) {
389+
//printf("Just executed a RET in TB " TARGET_FMT_lx "\n", tb->pc);
390+
//if (next) printf("Next TB: " TARGET_FMT_lx "\n", next->pc);
409391
}
410392
}
411393

@@ -611,10 +593,10 @@ bool init_plugin(void *self) {
611593

612594
pcb.after_block_translate = after_block_translate;
613595
panda_register_callback(self, PANDA_CB_AFTER_BLOCK_TRANSLATE, pcb);
614-
pcb.after_block_exec = after_block_exec;
615-
panda_register_callback(self, PANDA_CB_AFTER_BLOCK_EXEC, pcb);
616-
pcb.before_block_exec = before_block_exec;
617-
panda_register_callback(self, PANDA_CB_BEFORE_BLOCK_EXEC, pcb);
596+
pcb.end_block_exec = end_block_exec;
597+
panda_register_callback(self, PANDA_CB_END_BLOCK_EXEC, pcb);
598+
pcb.start_block_exec = start_block_exec;
599+
panda_register_callback(self, PANDA_CB_START_BLOCK_EXEC, pcb);
618600

619601
bool setup_ok = true;
620602

0 commit comments

Comments
 (0)