_is: info for specific symbols and vspace option

This commit is contained in:
Dr-Carlos 2022-12-04 14:34:43 +10:30
parent e5cab0cca9
commit 31406efc13
1 changed files with 118 additions and 8 deletions

View File

@ -246,17 +246,125 @@ void _isc(Session &session, std::string vspace_name, bool sort,
// is
//---
static void parse_is(Session &, Parser &parser)
struct _is_args
{
std::string vspace_name;
FxOS::Symbol symbol;
};
static struct _is_args parse_is(Session &session, Parser &parser)
{
_is_args args;
parser.option("vspace",
[&args](std::string const &value) { args.vspace_name = value; });
parser.accept_options();
FxOS::Symbol s;
if(!parser.at_end()) {
if(parser.lookahead().type == T::SYSCALL) {
s.type = FxOS::Symbol::Syscall;
s.value = parser.expect(T::SYSCALL).value.NUM;
}
else {
s.type = FxOS::Symbol::Address;
s.value = parser.expr(session.current_space);
}
}
else {
s.type = FxOS::Symbol::Address;
s.value = 0;
}
args.symbol = s;
VirtualSpace *space = session.current_space;
if(!args.vspace_name.empty()) {
space = session.get_space(args.vspace_name);
if(!space) {
std::string msg
= format("virtual space '%s' does not exist", args.vspace_name);
if(parser.completing())
throw Parser::CompletionRequest("_error", msg);
else
FxOS_log(ERR, "%s", msg);
}
}
parser.end();
return args;
}
void _is(Session &session)
void _is(Session &session, std::string vspace_name, FxOS::Symbol symbol)
{
if(!session.current_space)
VirtualSpace *space = session.current_space;
if(!space) {
FxOS_log(ERR, "no virtual space selected");
return;
}
for(auto const &s: session.current_space->symbols.symbols) {
if(!vspace_name.empty())
space = session.get_space(vspace_name);
if(!space) {
FxOS_log(ERR, "virtual space '%s' does not exist", vspace_name);
return;
}
std::vector<FxOS::Symbol> symbols;
if(symbol.type == FxOS::Symbol::Address && symbol.value == 0)
symbols = space->symbols.symbols;
else {
std::optional<std::string> name
= space->symbols.query(symbol.type, symbol.value);
if(name.has_value())
symbol.name = name.value();
else if(symbol.type == FxOS::Symbol::Address) {
if(vspace_name.empty())
fmt::print(stderr,
"\x1b[31;1merror:\x1b[0m no symbol exists for address 0x{:08x} in current virtual space\n",
symbol.value);
else
fmt::print(stderr,
"\x1b[31;1merror:\x1b[0m no symbol exists for address 0x{:08x} in virtual space '{}'\n",
symbol.value, vspace_name);
return;
}
else if(symbol.type == FxOS::Symbol::Syscall) {
if(vspace_name.empty()) {
if(symbol.value < 0x1000)
fmt::print(stderr,
"\x1b[31;1merror:\x1b[0m no symbol exists for syscall %{:03x} in current virtual space\n",
symbol.value);
else
fmt::print(stderr,
"\x1b[31;1merror:\x1b[0m no symbol exists for syscall %{:04x} in current virtual space\n",
symbol.value);
}
else {
if(symbol.value < 0x1000)
fmt::print(stderr,
"\x1b[31;1merror:\x1b[0m no symbol exists for syscall %{:03x} in virtual space '{}'\n",
symbol.value, vspace_name);
else
fmt::print(stderr,
"\x1b[31;1merror:\x1b[0m no symbol exists for syscall %{:04x} in virtual space '{}'\n",
symbol.value, vspace_name);
}
return;
}
symbols = {symbol};
}
for(auto const &s: symbols) {
if(s.type == FxOS::Symbol::Syscall && s.value < 0x1000) {
fmt::print(theme(10), " %{:03x}", s.value);
}
@ -311,11 +419,13 @@ sort=true is specified, they are instead sorted by address.
static ShellCommand _is_cmd(
"is",
[](Session &s, Parser &p) {
parse_is(s, p);
_is(s);
auto args = parse_is(s, p);
_is(s, args.vspace_name, args.symbol);
},
[](Session &s, Parser &p) { parse_is(s, p); }, "Info Symbols", R"(
is
is [vspace=<virtual_space>] [<address|syscall>]
Lists all symbols in the current virtual space.
Lists symbols in the specified virtual space (defaults to the current
one). By default, all symbols are listed, but if an address or syscall is
provided, the symbol associated with it will be printed instead.
)");