diff options
Diffstat (limited to 'replay')
-rw-r--r-- | replay/replay-internal.h | 4 | ||||
-rw-r--r-- | replay/replay.c | 67 |
2 files changed, 71 insertions, 0 deletions
diff --git a/replay/replay-internal.h b/replay/replay-internal.h index ff4fabc326..5ff1c14287 100644 --- a/replay/replay-internal.h +++ b/replay/replay-internal.h @@ -17,6 +17,10 @@ enum ReplayEvents { /* for instruction event */ EVENT_INSTRUCTION, + /* for software interrupt */ + EVENT_INTERRUPT, + /* for emulated exceptions */ + EVENT_EXCEPTION, EVENT_COUNT }; diff --git a/replay/replay.c b/replay/replay.c index b2c67501a5..b4fc64acee 100644 --- a/replay/replay.c +++ b/replay/replay.c @@ -79,3 +79,70 @@ void replay_account_executed_instructions(void) replay_mutex_unlock(); } } + +bool replay_exception(void) +{ + if (replay_mode == REPLAY_MODE_RECORD) { + replay_save_instructions(); + replay_mutex_lock(); + replay_put_event(EVENT_EXCEPTION); + replay_mutex_unlock(); + return true; + } else if (replay_mode == REPLAY_MODE_PLAY) { + bool res = replay_has_exception(); + if (res) { + replay_mutex_lock(); + replay_finish_event(); + replay_mutex_unlock(); + } + return res; + } + + return true; +} + +bool replay_has_exception(void) +{ + bool res = false; + if (replay_mode == REPLAY_MODE_PLAY) { + replay_account_executed_instructions(); + replay_mutex_lock(); + res = replay_next_event_is(EVENT_EXCEPTION); + replay_mutex_unlock(); + } + + return res; +} + +bool replay_interrupt(void) +{ + if (replay_mode == REPLAY_MODE_RECORD) { + replay_save_instructions(); + replay_mutex_lock(); + replay_put_event(EVENT_INTERRUPT); + replay_mutex_unlock(); + return true; + } else if (replay_mode == REPLAY_MODE_PLAY) { + bool res = replay_has_interrupt(); + if (res) { + replay_mutex_lock(); + replay_finish_event(); + replay_mutex_unlock(); + } + return res; + } + + return true; +} + +bool replay_has_interrupt(void) +{ + bool res = false; + if (replay_mode == REPLAY_MODE_PLAY) { + replay_account_executed_instructions(); + replay_mutex_lock(); + res = replay_next_event_is(EVENT_INTERRUPT); + replay_mutex_unlock(); + } + return res; +} |