feat: provide cli options for library api prefix
This commit is contained in:
parent
7db988bdee
commit
607ed58ffa
6 changed files with 53 additions and 27 deletions
|
@ -7,7 +7,10 @@
|
||||||
struct Config {
|
struct Config {
|
||||||
std::filesystem::path memory_file;
|
std::filesystem::path memory_file;
|
||||||
std::vector<std::filesystem::path> refs;
|
std::vector<std::filesystem::path> refs;
|
||||||
|
std::vector<std::string> refs_prefix;
|
||||||
std::filesystem::path dut;
|
std::filesystem::path dut;
|
||||||
|
std::string dut_prefix = "";
|
||||||
|
|
||||||
int cli_parse(int argc, char **argv);
|
int cli_parse(int argc, char **argv);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
23
src/cli.cpp
23
src/cli.cpp
|
@ -1,6 +1,8 @@
|
||||||
#include "config.hpp"
|
#include "config.hpp"
|
||||||
#include <CLI/App.hpp>
|
#include <CLI/App.hpp>
|
||||||
|
#include <CLI/Error.hpp>
|
||||||
#include <CLI/Validators.hpp>
|
#include <CLI/Validators.hpp>
|
||||||
|
#include <cerrno>
|
||||||
|
|
||||||
int Config::cli_parse(int argc, char **argv) {
|
int Config::cli_parse(int argc, char **argv) {
|
||||||
CLI::App app;
|
CLI::App app;
|
||||||
|
@ -12,13 +14,34 @@ int Config::cli_parse(int argc, char **argv) {
|
||||||
->required()
|
->required()
|
||||||
->check(CLI::ExistingFile);
|
->check(CLI::ExistingFile);
|
||||||
|
|
||||||
|
app.add_option("--ref-prefix", refs_prefix,
|
||||||
|
"Optional prefix for each reference library");
|
||||||
|
|
||||||
app.add_option("--dut", dut, "Design under test")
|
app.add_option("--dut", dut, "Design under test")
|
||||||
->required()
|
->required()
|
||||||
->check(CLI::ExistingFile);
|
->check(CLI::ExistingFile);
|
||||||
|
|
||||||
|
app.add_option("--dut-prefix", dut_prefix,
|
||||||
|
"Optional prefix for design under test");
|
||||||
|
|
||||||
app.set_config("-c,--config")
|
app.set_config("-c,--config")
|
||||||
->transform(CLI::FileOnDefaultPath("./difftest.toml"));
|
->transform(CLI::FileOnDefaultPath("./difftest.toml"));
|
||||||
|
|
||||||
|
// Default value for refs_prefix
|
||||||
|
app.callback([&]() {
|
||||||
|
if (refs_prefix.size() == 0) {
|
||||||
|
refs_prefix.insert(refs_prefix.end(), refs.size(), "");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Check if refs_prefix matches refs.
|
||||||
|
app.callback([&]() {
|
||||||
|
if (refs_prefix.size() != refs.size()) {
|
||||||
|
throw CLI::ParseError(
|
||||||
|
"Same number of --ref and --ref-prefix must be provided.", EINVAL);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
CLI11_PARSE(app, argc, argv);
|
CLI11_PARSE(app, argc, argv);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -35,7 +35,6 @@ void Difftest::setup(const std::filesystem::path &memory_file) {
|
||||||
// for(auto target : *this) {
|
// for(auto target : *this) {
|
||||||
for (auto it = this->begin(); it != this->end(); ++it) {
|
for (auto it = this->begin(); it != this->end(); ++it) {
|
||||||
auto &target = *it;
|
auto &target = *it;
|
||||||
printf("init addr: %p\n", target.ops.init);
|
|
||||||
target.ops.init(target.args.data());
|
target.ops.init(target.args.data());
|
||||||
target.ops.write_mem(target.args.data(), 0x80000000UL, membuf.size(),
|
target.ops.write_mem(target.args.data(), 0x80000000UL, membuf.size(),
|
||||||
membuf.data());
|
membuf.data());
|
||||||
|
@ -51,21 +50,23 @@ bool Difftest::check_all() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Difftest::exec(size_t n, gdb_action_t *ret) {
|
bool Difftest::exec(size_t n, gdb_action_t *ret) {
|
||||||
bool breakflag = false;
|
while (n--) {
|
||||||
Target *pbreak = &(*(this->begin()));
|
bool breakflag = false;
|
||||||
for (auto it = this->begin(); it != this->end(); ++it) {
|
Target *pbreak = &(*(this->begin()));
|
||||||
auto &target = *it;
|
for (auto it = this->begin(); it != this->end(); ++it) {
|
||||||
target.ops.stepi(target.args.data(), &target.last_res);
|
auto &target = *it;
|
||||||
if (target.is_on_breakpoint()) {
|
target.ops.stepi(target.args.data(), &target.last_res);
|
||||||
breakflag = true;
|
if (target.is_on_breakpoint()) {
|
||||||
pbreak = ⌖
|
breakflag = true;
|
||||||
|
pbreak = ⌖
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (breakflag) {
|
if (breakflag) {
|
||||||
ret->reason = pbreak->last_res.reason;
|
ret->reason = pbreak->last_res.reason;
|
||||||
ret->data = pbreak->last_res.data;
|
ret->data = pbreak->last_res.data;
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -86,7 +87,6 @@ gdb_action_t Difftest::cont() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int Difftest::read_reg(int regno, size_t *value) {
|
int Difftest::read_reg(int regno, size_t *value) {
|
||||||
std::cout << "read_reg(" << regno << ", " << value << ")" << std::endl;
|
|
||||||
return current_target->ops.read_reg(current_target->args.data(), regno,
|
return current_target->ops.read_reg(current_target->args.data(), regno,
|
||||||
value);
|
value);
|
||||||
}
|
}
|
||||||
|
@ -110,7 +110,7 @@ bool Difftest::set_bp(size_t addr, bp_type_t type) {
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
for (auto it = this->begin(); it != this->end(); ++it) {
|
for (auto it = this->begin(); it != this->end(); ++it) {
|
||||||
auto &target = *it;
|
auto &target = *it;
|
||||||
ret = ret && target.ops.set_bp(target.args.data(), addr, type);
|
ret = target.ops.set_bp(target.args.data(), addr, type) && ret;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -119,7 +119,7 @@ bool Difftest::del_bp(size_t addr, bp_type_t type) {
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
for (auto it = this->begin(); it != this->end(); ++it) {
|
for (auto it = this->begin(); it != this->end(); ++it) {
|
||||||
auto &target = *it;
|
auto &target = *it;
|
||||||
ret = ret && target.ops.del_bp(target.args.data(), addr, type);
|
ret = target.ops.del_bp(target.args.data(), addr, type) && ret;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,8 +57,8 @@ int gdbstub_loop(Difftest *diff) {
|
||||||
char socket_addr[] = "127.0.0.1:1234";
|
char socket_addr[] = "127.0.0.1:1234";
|
||||||
gdbstub_init(&gdbstub_priv, &gdbstub_ops, diff->get_arch(), socket_addr);
|
gdbstub_init(&gdbstub_priv, &gdbstub_ops, diff->get_arch(), socket_addr);
|
||||||
|
|
||||||
|
std::cout << "Waiting for gdb connection at " << socket_addr << std::endl;
|
||||||
bool success = gdbstub_run(&gdbstub_priv, diff);
|
bool success = gdbstub_run(&gdbstub_priv, diff);
|
||||||
std::cout << "Waiting for gdb connection at " << socket_addr;
|
|
||||||
gdbstub_close(&gdbstub_priv);
|
gdbstub_close(&gdbstub_priv);
|
||||||
return !success;
|
return !success;
|
||||||
}
|
}
|
|
@ -2,13 +2,11 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#include <gdbstub.h>
|
#include <gdbstub.h>
|
||||||
#include <iostream>
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
Target::Target(const std::string &name, const std::string &func_prefix,
|
Target::Target(const std::string &name, const std::string &func_prefix,
|
||||||
const std::filesystem::path &path) {
|
const std::filesystem::path &path) {
|
||||||
|
|
||||||
std::cout << path.c_str() << std::endl;
|
|
||||||
meta = {.name = name,
|
meta = {.name = name,
|
||||||
.libpath = path,
|
.libpath = path,
|
||||||
.dlhandle = dlopen(path.c_str(), RTLD_LAZY)};
|
.dlhandle = dlopen(path.c_str(), RTLD_LAZY)};
|
||||||
|
@ -60,10 +58,7 @@ load_error:
|
||||||
throw std::runtime_error(err);
|
throw std::runtime_error(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
Target::~Target() {
|
Target::~Target() { dlclose(meta.dlhandle); }
|
||||||
std::cout << "Destruct target " << meta.name << std::endl;
|
|
||||||
dlclose(meta.dlhandle);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Target::is_on_breakpoint() const { return is_on_breakpoint(last_res); }
|
bool Target::is_on_breakpoint() const { return is_on_breakpoint(last_res); }
|
||||||
|
|
||||||
|
|
11
src/main.cpp
11
src/main.cpp
|
@ -13,9 +13,14 @@ int main(int argc, char **argv) {
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
std::vector<Target> refs;
|
std::vector<Target> refs;
|
||||||
Target *dut = new Target{"dut", "nemu_", config.dut};
|
Target *dut = new Target{"dut", config.dut_prefix, config.dut};
|
||||||
for (const auto &ref_libpath : config.refs) {
|
auto ref_libpath = config.refs.begin();
|
||||||
refs.emplace_back(ref_libpath.string(), "nemu_", ref_libpath);
|
auto ref_prefix = config.refs_prefix.begin();
|
||||||
|
while (ref_libpath != config.refs.end() &&
|
||||||
|
ref_prefix != config.refs_prefix.end()) {
|
||||||
|
refs.emplace_back(ref_libpath->string(), *ref_prefix, *ref_libpath);
|
||||||
|
ref_libpath++;
|
||||||
|
ref_prefix++;
|
||||||
}
|
}
|
||||||
|
|
||||||
Difftest difftest{std::move(*dut), std::move(refs)};
|
Difftest difftest{std::move(*dut), std::move(refs)};
|
||||||
|
|
Loading…
Reference in a new issue