lib: use ostream in analyzeInstructionOutput out; add

print_syscall_names PrintPass attribute
This commit is contained in:
Dr-Carlos 2023-08-27 20:00:18 +09:30
parent aad5708df1
commit f58ab802d0
3 changed files with 26 additions and 35 deletions

View File

@ -40,6 +40,8 @@
#include <fxos/disassembly.h>
#include <fxos/symbols.h>
#include <ostream>
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<std::string *> 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+<disp>" 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:

View File

@ -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<std::string *> 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<std::string> PrintPass::symquery(

View File

@ -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=<virtual_space>] "<pattern>"