diff --git a/shell/i.cpp b/shell/i.cpp index aff5642..28954de 100644 --- a/shell/i.cpp +++ b/shell/i.cpp @@ -6,6 +6,7 @@ #include #include +#include //--- // ic @@ -135,21 +136,36 @@ void _io(Session &session, std::string name) struct _isc_args { std::string vspace_name; - bool sort; + bool sort = false; + std::vector addresses; }; -static struct _isc_args parse_isc(Session &, Parser &parser) +static struct _isc_args parse_isc(Session &session, Parser &parser) { - struct _isc_args args - { - }; + _isc_args args; parser.option("sort", [&args](std::string const &value) { args.sort = (value == "true"); }); + parser.option("vspace", + [&args](std::string const &value) { args.vspace_name = value; }); parser.accept_options(); - args.vspace_name = parser.at_end() ? "" : parser.symbol("vspace_name"); - parser.accept_options(); + + 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); + } + } + + while(!parser.at_end()) + args.addresses.push_back(parser.expr(space)); parser.end(); return args; @@ -166,26 +182,54 @@ bool operator<(const SyscallInfo &left, const SyscallInfo &right) return (left.address < right.address) || (left.id < right.id); } -void _isc(Session &session, std::string vspace_name, bool sort) +void _isc(Session &session, std::string vspace_name, bool sort, + std::vector addresses) { VirtualSpace *space = session.current_space; - if(vspace_name != "") - space = session.get_space(vspace_name); - if(!space) + if(!space) { + FxOS_log(ERR, "no virtual space selected"); return; + } - // TODO: is doesn't work + if(!vspace_name.empty()) + space = session.get_space(vspace_name); + + if(!space) { + FxOS_log(ERR, "virtual space '%s' does not exist", vspace_name); + return; + } OS *os = space->os_analysis(); - if(!os) - throw CommandError("os analysis on '{}' failed", vspace_name); + if(!os) { + if(!vspace_name.empty()) + FxOS_log(ERR, "OS analysis on '%s' failed", vspace_name); + else + FxOS_log(ERR, "OS analysis failed"); + return; + } + + if(!addresses.empty()) { + if(sort) + std::sort(&addresses[0], &addresses[addresses.size()]); + + for(uint32_t address: addresses) { + int syscall = os->find_syscall(address); + if(syscall == -1) + continue; + + fmt::print(theme(3), " 0x{:08x}", address); + fmt::print(theme(10), " %{:01x}", syscall); + fmt::print("\n"); + } + + return; + } int total = os->syscall_count(); auto info = std::make_unique(total); - for(int i = 0; i < total; i++) { + for(int i = 0; i < total; i++) info[i] = (SyscallInfo) {.address = os->syscall(i), .id = i}; - } if(sort) std::sort(&info[0], &info[total]); @@ -254,10 +298,10 @@ static ShellCommand _isc_cmd( "isc", [](Session &s, Parser &p) { auto args = parse_isc(s, p); - _isc(s, args.vspace_name, args.sort); + _isc(s, args.vspace_name, args.sort, args.addresses); }, [](Session &s, Parser &p) { parse_isc(s, p); }, "Info Syscalls", R"( -isc [sort=true] [] +isc [sort=true] [vspace=] [
...] Prints the syscall table for the specified virtual space (defaults to the current one). By default, syscalls are enumerated by syscall number. If