@@ -55,8 +55,10 @@ extern "C" {
5555#include " panda/plog.h"
5656#include " callstack_instr_int_fns.h"
5757
58- void start_block_exec (CPUState* cpu, TranslationBlock *tb);
59- void end_block_exec (CPUState* cpu, TranslationBlock *tb);
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);
6062void after_block_translate (CPUState* cpu, TranslationBlock *tb);
6163
6264bool init_plugin (void *);
@@ -320,7 +322,7 @@ void after_block_translate(CPUState *cpu, TranslationBlock *tb) {
320322 return ;
321323}
322324
323- void start_block_exec (CPUState *cpu, TranslationBlock *tb) {
325+ void before_block_exec (CPUState *cpu, TranslationBlock *tb) {
324326 // if the block a call returns to was interrupted before it completed, this
325327 // function will be called twice - only want to remove the return value from
326328 // the stack once
@@ -364,7 +366,7 @@ void start_block_exec(CPUState *cpu, TranslationBlock *tb) {
364366 }
365367}
366368
367- void end_block_exec (CPUState* cpu, TranslationBlock *tb) {
369+ void after_block_exec (CPUState* cpu, TranslationBlock *tb, uint8_t exitCode ) {
368370 target_ulong pc = 0x0 ;
369371 target_ulong cs_base = 0x0 ;
370372 uint32_t flags = 0x0 ;
@@ -375,19 +377,35 @@ void end_block_exec(CPUState* cpu, TranslationBlock *tb) {
375377
376378 // sometimes an attempt to run a block is interrupted, but this callback is
377379 // still made - only update the callstack if the block has run to completion
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
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+ }
384405 cpu_get_tb_cpu_state (env, &pc, &cs_base, &flags);
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);
406+ // erase nicely does nothing if key DNE
407+ stoppedInfo.erase (curStackid);
408+ stoppedInfo[curStackid] = pc;
391409 }
392410}
393411
@@ -593,9 +611,9 @@ bool init_plugin(void *self) {
593611
594612 pcb.after_block_translate = after_block_translate;
595613 panda_register_callback (self, PANDA_CB_AFTER_BLOCK_TRANSLATE, pcb);
596- pcb.end_block_exec = end_block_exec ;
614+ pcb.after_block_exec = after_block_exec ;
597615 panda_register_callback (self, PANDA_CB_AFTER_BLOCK_EXEC, pcb);
598- pcb.start_block_exec = start_block_exec ;
616+ pcb.before_block_exec = before_block_exec ;
599617 panda_register_callback (self, PANDA_CB_BEFORE_BLOCK_EXEC, pcb);
600618
601619 bool setup_ok = true ;
0 commit comments