diff --git a/include/fxos/passes/print.h b/include/fxos/passes/print.h index b4bd698..caa8896 100644 --- a/include/fxos/passes/print.h +++ b/include/fxos/passes/print.h @@ -40,6 +40,8 @@ #include #include +#include + namespace FxOS { class OS; @@ -51,8 +53,8 @@ public: bool analyzeInstruction(uint32_t pc, Instruction &inst) override; /* Allows the user to specify more options */ - bool analyzeInstructionFull(uint32_t pc, Instruction &inst, - std::optional output, bool print_syscall_names); + bool analyzeInstructionOutput( + uint32_t pc, Instruction &inst, std::ostream &out); //--- // Print pass parameters @@ -85,6 +87,9 @@ public: /* In a mova, promote "pc+" to the computed address */ int promote_pcaddr_loc; + /* Print syscall names when analyzing disassembly */ + bool print_syscall_names = true; + /* TODO: More print pass parameters */ private: diff --git a/lib/passes/print.cpp b/lib/passes/print.cpp index 54a45ce..a393916 100644 --- a/lib/passes/print.cpp +++ b/lib/passes/print.cpp @@ -28,35 +28,33 @@ PrintPass::PrintPass(Disassembly &disasm): m_symtables.push_back(disasm.vspace.symbols); } -bool PrintPass::analyzeInstructionFull(uint32_t pc, Instruction &i, - std::optional output, bool print_syscall_names) +bool PrintPass::analyzeInstructionOutput( + uint32_t pc, Instruction &i, std::ostream &out) { - std::string out; - /* Ellipsis if there is a gap since last instruction */ if(m_last_address + 1 != 0 && pc != m_last_address + 2) - out += " ...\n"; + out << " ...\n"; /* Preliminary syscall number */ int syscall_id; if(print_syscall_names && m_os && (syscall_id = m_os->find_syscall(pc)) >= 0) { - out += fmt::format("\n<%{:04x}", syscall_id); + out << fmt::format("\n<%{:04x}", syscall_id); auto maybe_str = symquery(Symbol::Syscall, syscall_id); if(maybe_str) - out += " " + *maybe_str; - out += ">\n"; + out << " " + *maybe_str; + out << ">\n"; } /* Raw data if instruction cannot be decoded */ - out += fmt::format( + out << fmt::format( " {:08x}: {:04x}", pc, (i.inst ? i.inst->opcode : i.opcode)); if(!i.inst) { - out += "\n"; + out << "\n"; m_last_address = pc; return true; } @@ -68,7 +66,7 @@ bool PrintPass::analyzeInstructionFull(uint32_t pc, Instruction &i, int spacing = i.inst->arg_count ? 8 - strlen(i.inst->mnemonic) - strlen(suffix) : 0; - out += fmt::sprintf(" %s%s%*s", i.inst->mnemonic, suffix, spacing, ""); + out << fmt::sprintf(" %s%s%*s", i.inst->mnemonic, suffix, spacing, ""); /* Arguments */ @@ -77,7 +75,7 @@ bool PrintPass::analyzeInstructionFull(uint32_t pc, Instruction &i, Argument const &a = i.args[n]; if(n) - out += ", "; + out << ", "; queue(arg.str()); if(arg.kind == AsmArgument::PcJump) @@ -87,23 +85,18 @@ bool PrintPass::analyzeInstructionFull(uint32_t pc, Instruction &i, else if(arg.kind == AsmArgument::PcAddr) pcaddrloc(a); - out += queue_flush(); + out << queue_flush(); } - out += "\n"; + out << "\n"; m_last_address = pc; - if(output) - (*output)->append(out); - else - std::cout << out; - return true; } bool PrintPass::analyzeInstruction(uint32_t pc, Instruction &i) { - return analyzeInstructionFull(pc, i, {}, true); + return analyzeInstructionOutput(pc, i, std::cout); } std::optional PrintPass::symquery( diff --git a/shell/s.cpp b/shell/s.cpp index e5fea6a..3be891a 100644 --- a/shell/s.cpp +++ b/shell/s.cpp @@ -380,27 +380,19 @@ void _ssd(Session &session, char const *pattern, bool identify_claims, p.promote_syscallname = PrintPass::Append; p.promote_symbol = PrintPass::Append; p.promote_pcaddr_loc = PrintPass::Promote; + p.print_syscall_names = false; /* Stores disassembly output */ - std::string disasm_str; + std::stringstream disasm_str; for(auto &pair: disasm.instructions) - ok &= p.analyzeInstructionFull( - pair.first, pair.second, &disasm_str, false); + ok &= p.analyzeInstructionOutput(pair.first, pair.second, disasm_str); if(!ok) { FxOS_log(ERR, "ss print pass failed"); return; } - if(disasm_str.empty()) { - FxOS_log(ERR, "no disassembly found in virtual space"); - return; - } - - /* Used for std::getline */ - std::istringstream iss(disasm_str); - /* Store number of matches */ int match_count = 0; @@ -417,7 +409,7 @@ void _ssd(Session &session, char const *pattern, bool identify_claims, std::string unknown_matches; /* Do a regex search on each line */ - for(std::string line; std::getline(iss, line);) + for(std::string line; std::getline(disasm_str, line);) if(std::regex_search( line, match, std::regex(pattern, std::regex::extended))) { if(identify_claims) { @@ -561,7 +553,8 @@ static ShellCommand _ssd_cmd( auto args = parse_ssd(s, p); _ssd(s, args.pattern.c_str(), args.identify_claims, args.vspace_name); }, - [](Session &s, Parser &p) { parse_ssd(s, p); }, "Search string in disassembly", + [](Session &s, Parser &p) { parse_ssd(s, p); }, + "Search string in disassembly", R"( ssd [claims=true] [vspace=] ""