forked from Lephenixnoir/fxos
lib: use ostream in analyzeInstructionOutput out; add
print_syscall_names PrintPass attribute
This commit is contained in:
parent
aad5708df1
commit
f58ab802d0
|
@ -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:
|
||||
|
|
|
@ -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(
|
||||
|
|
19
shell/s.cpp
19
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=<virtual_space>] "<pattern>"
|
||||
|
||||
|
|
Loading…
Reference in New Issue