feat: graceful shutdown
This commit is contained in:
parent
6501c55e30
commit
7db988bdee
4 changed files with 27 additions and 33 deletions
|
@ -17,6 +17,8 @@ private:
|
||||||
// target used for read_reg, write_reg, read_mem, write_mem
|
// target used for read_reg, write_reg, read_mem, write_mem
|
||||||
Target *current_target = &dut;
|
Target *current_target = &dut;
|
||||||
|
|
||||||
|
bool exec(size_t n, gdb_action_t *ret);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Difftest(Target &&dut, std::vector<Target> &&refs);
|
Difftest(Target &&dut, std::vector<Target> &&refs);
|
||||||
|
|
||||||
|
@ -32,12 +34,13 @@ public:
|
||||||
bool set_bp(size_t addr, bp_type_t type);
|
bool set_bp(size_t addr, bp_type_t type);
|
||||||
bool del_bp(size_t addr, bp_type_t type);
|
bool del_bp(size_t addr, bp_type_t type);
|
||||||
|
|
||||||
|
bool check_all();
|
||||||
|
|
||||||
arch_info_t get_arch() const {
|
arch_info_t get_arch() const {
|
||||||
std::cout << dut.arch.reg_num << std::endl;
|
std::cout << dut.arch.reg_num << std::endl;
|
||||||
return dut.arch;
|
return dut.arch;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Other APi
|
|
||||||
static bool check(Target &dut, Target &ref) {
|
static bool check(Target &dut, Target &ref) {
|
||||||
for (int r = 0; r < dut.arch.reg_num; r++) {
|
for (int r = 0; r < dut.arch.reg_num; r++) {
|
||||||
size_t regdut = 0, regref = 0;
|
size_t regdut = 0, regref = 0;
|
||||||
|
@ -51,7 +54,6 @@ public:
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
bool check_all();
|
|
||||||
|
|
||||||
class Iterator {
|
class Iterator {
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "api.hpp"
|
#include "api.hpp"
|
||||||
#include <difftest.hpp>
|
#include <difftest.hpp>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <gdbstub.h>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
@ -49,9 +50,9 @@ bool Difftest::check_all() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
gdb_action_t Difftest::stepi() {
|
bool Difftest::exec(size_t n, gdb_action_t *ret) {
|
||||||
bool breakflag = false;
|
bool breakflag = false;
|
||||||
Target *pbreak;
|
Target *pbreak = &(*(this->begin()));
|
||||||
for (auto it = this->begin(); it != this->end(); ++it) {
|
for (auto it = this->begin(); it != this->end(); ++it) {
|
||||||
auto &target = *it;
|
auto &target = *it;
|
||||||
target.ops.stepi(target.args.data(), &target.last_res);
|
target.ops.stepi(target.args.data(), &target.last_res);
|
||||||
|
@ -62,37 +63,26 @@ gdb_action_t Difftest::stepi() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (breakflag) {
|
if (breakflag) {
|
||||||
gdb_action_t ret = {.reason = gdb_action_t::ACT_BREAKPOINT};
|
ret->reason = pbreak->last_res.reason;
|
||||||
pbreak->ops.read_reg(pbreak->args.data(), 32, &ret.data);
|
ret->data = pbreak->last_res.data;
|
||||||
return ret;
|
return false;
|
||||||
}
|
}
|
||||||
return {gdb_action_t::ACT_NONE, 0};
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
gdb_action_t Difftest::stepi() {
|
||||||
|
gdb_action_t ret = {.reason = gdb_action_t::ACT_NONE};
|
||||||
|
exec(1, &ret);
|
||||||
|
check_all();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
gdb_action_t Difftest::cont() {
|
gdb_action_t Difftest::cont() {
|
||||||
bool breakflag = false;
|
gdb_action_t ret = {.reason = gdb_action_t::ACT_NONE};
|
||||||
Target *pbreak;
|
while (exec(1, &ret)) {
|
||||||
while (true) {
|
|
||||||
// for(auto &target : *this) {
|
|
||||||
for (auto it = this->begin(); it != this->end(); ++it) {
|
|
||||||
auto &target = *it;
|
|
||||||
target.ops.stepi(target.args.data(), &target.last_res);
|
|
||||||
|
|
||||||
if (target.is_on_breakpoint()) {
|
|
||||||
breakflag = true;
|
|
||||||
pbreak = ⌖
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
check_all();
|
check_all();
|
||||||
|
};
|
||||||
if (breakflag) {
|
return ret;
|
||||||
gdb_action_t ret = {.reason = gdb_action_t::ACT_BREAKPOINT};
|
|
||||||
pbreak->ops.read_reg(pbreak->args.data(), 32, &ret.data);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {gdb_action_t::ACT_NONE, 0};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Difftest::read_reg(int regno, size_t *value) {
|
int Difftest::read_reg(int regno, size_t *value) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "api.hpp"
|
#include "api.hpp"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
#include <gdbstub.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
|
@ -70,7 +71,8 @@ bool Target::is_on_breakpoint(const gdb_action_t &res) const {
|
||||||
if (res.reason == gdb_action_t::ACT_BREAKPOINT ||
|
if (res.reason == gdb_action_t::ACT_BREAKPOINT ||
|
||||||
res.reason == gdb_action_t::ACT_RWATCH ||
|
res.reason == gdb_action_t::ACT_RWATCH ||
|
||||||
res.reason == gdb_action_t::ACT_WATCH ||
|
res.reason == gdb_action_t::ACT_WATCH ||
|
||||||
res.reason == gdb_action_t::ACT_WWATCH) {
|
res.reason == gdb_action_t::ACT_WWATCH ||
|
||||||
|
res.reason == gdb_action_t::ACT_SHUTDOWN) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -13,12 +13,12 @@ int main(int argc, char **argv) {
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
std::vector<Target> refs;
|
std::vector<Target> refs;
|
||||||
Target dut = Target{"dut", "nemu_", config.dut};
|
Target *dut = new Target{"dut", "nemu_", config.dut};
|
||||||
for (const auto &ref_libpath : config.refs) {
|
for (const auto &ref_libpath : config.refs) {
|
||||||
refs.emplace_back(ref_libpath.string(), "nemu_", ref_libpath);
|
refs.emplace_back(ref_libpath.string(), "nemu_", ref_libpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
Difftest difftest{std::move(dut), std::move(refs)};
|
Difftest difftest{std::move(*dut), std::move(refs)};
|
||||||
|
|
||||||
difftest.setup(config.memory_file);
|
difftest.setup(config.memory_file);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue