_ic: new command to show claims on addresses

This commit is contained in:
Lephenixnoir 2022-04-06 18:41:41 +01:00
parent ee1c36db4e
commit 3a9a622ee3
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
4 changed files with 64 additions and 20 deletions

View File

@ -68,11 +68,11 @@ bool Claim::intersects(Claim const &other) const
std::string Claim::str() const
{
std::string details = format(" (claim %08x:%d)", address, size);
std::string details = format(" (claim 0x%08x:%d)", address, size);
switch(type) {
case Claim::Function:
return format("function %08x", owner) + details;
return format("function at 0x%08x", owner) + details;
case Claim::FunctionAuxiliary:
return std::string("auxiliary data") + details;
case Claim::Data:
@ -80,7 +80,7 @@ std::string Claim::str() const
case Claim::Zero:
return std::string("zero region") + details;
case Claim::Special:
return format("special region %08x", address) + details;
return format("special region at 0x%08x", address) + details;
default:
return format("<type %d>", type) + details;
}
@ -103,7 +103,7 @@ bool Disassembly::hasInstructionAt(uint32_t pc)
Instruction *Disassembly::getInstructionAt(uint32_t pc, bool allowDiscovery)
{
if(pc & 1) {
FxOS_log(ERR, "reading instruction for disassembly at %08x", pc);
FxOS_log(ERR, "reading instruction for disassembly at 0x%08x", pc);
pc &= -2;
}
@ -121,7 +121,7 @@ Instruction *Disassembly::getInstructionAt(uint32_t pc, bool allowDiscovery)
return &this->instructions.at(pc);
}
else {
FxOS_log(ERR, "reading non-existing instruction at %08x", pc);
FxOS_log(ERR, "reading non-existing instruction at 0x%08x", pc);
return nullptr;
}
}
@ -222,7 +222,7 @@ bool FunctionPass::analyzeFunction(uint32_t pc)
{
Function *func = m_disasm.getFunctionAt(pc);
if(!func) {
FxOS_log(ERR, "no function at %08x", pc);
FxOS_log(ERR, "no function at 0x%08x", pc);
return false;
}
return this->analyzeFunction(*func);

View File

@ -23,7 +23,7 @@ bool CfgPass::analyzeInstruction(uint32_t pc, Instruction &i)
/* Don't explore successors if the instruction cannot be decoded, not
even pc+2. This will prevent wild overshoot. */
if(!i.inst) {
FxOS_log(ERR, "invalid instruction as %08x: %04x", pc, i.opcode);
FxOS_log(ERR, "invalid instruction at 0x%08x: 0x%04x", pc, i.opcode);
return false;
}
@ -38,7 +38,7 @@ bool CfgPass::analyzeInstruction(uint32_t pc, Instruction &i)
auto &args = i.inst->args;
if(i.inst->arg_count != 1 || args[0].kind != AsmArgument::PcJump) {
FxOS_log(ERR, "invalid jump instruction at %08x", pc);
FxOS_log(ERR, "invalid jump instruction at 0x%08x", pc);
return false;
}
@ -50,8 +50,8 @@ bool CfgPass::analyzeInstruction(uint32_t pc, Instruction &i)
/* Check that it's not in a delay slot */
if(target.delayslot)
throw std::logic_error(format("%08x jumps into %08x, which is a "
"delay slot - this is unsupported by fxos and will produce "
throw std::logic_error(format("0x%08x jumps into 0x%08x, which is "
"a delay slot - this is unsupported by fxos and will produce "
"garbage analysis! (x_x)", pc, jmptarget));
}
@ -60,7 +60,7 @@ bool CfgPass::analyzeInstruction(uint32_t pc, Instruction &i)
set in the properties. */
if(i.delayslot) {
if(!i.inst->isvaliddelayslot()) {
FxOS_log(ERR, "invalid delay slot at %08x", pc);
FxOS_log(ERR, "invalid delay slot at 0x%08x", pc);
return false;
}
}
@ -68,11 +68,11 @@ bool CfgPass::analyzeInstruction(uint32_t pc, Instruction &i)
else if(i.inst->isdelayed()) {
Instruction &slot = *m_disasm.getInstructionAt(pc+2, true);
if(slot.leader)
throw std::logic_error(format("%08x is a leader and also a delay "
"slot - this is unsupported by fxos and will produce garbage "
throw std::logic_error(format("0x%08x is a leader and also a delay"
" slot - this is unsupported by fxos and will produce garbage "
"analysis! (x_x)", pc+2));
if(!slot.inst->isvaliddelayslot()) {
FxOS_log(ERR, "invalid delay slot at %08x", pc+2);
FxOS_log(ERR, "invalid delay slot at 0x%08x", pc+2);
return false;
}

View File

@ -239,10 +239,10 @@ static void ad_disassemble_all(VirtualSpace &space,
/* We collect subfunction addresses while running the pass */
for(int i = 0; i < (int)addresses.size(); i++) {
uint32_t entry = addresses[i];
printr("[cfg %d/%zu] Disassembling %08x...",
printr("[cfg %d/%zu] Disassembling 0x%08x...",
i+1, addresses.size(), entry);
if(!cfg_pass.exploreFunction(entry)) {
FxOS_log(ERR, "while processing %08x", entry);
FxOS_log(ERR, "while processing 0x%08x", entry);
errors++;
if(!force) return;
}
@ -355,7 +355,7 @@ static ShellCommand _af4_cmd("af4",
auto args = parse_af4(s, p);
_af4(s, args.value, args.regions); },
[](Session &s, Parser &p){ parse_af4(s, p); },
"Analysis Find 4-aligned value", R"(
"Analysis: Find 4-aligned value", R"(
af4 <value> [<regions>...]
Searches mapped memory for a 4-aligned 32-bit value. If regions are specified
@ -376,7 +376,7 @@ static ShellCommand _afh_cmd("afh",
_afh(s, args.reference.c_str(), args.pattern.c_str(), args.size,
args.align, args.distance, args.regions); },
[](Session &s, Parser &p){ parse_afh(s, p); },
"Analysis Find Hexadecimal pattern", R"(
"Analysis: Find Hexadecimal pattern", R"(
afh [align=<value>] "<pattern>" [<regions>...]
Searches mapped memory for a hexadecimal pattern with hole bytes. The pattern
@ -404,7 +404,7 @@ static ShellCommand _ad_cmd("ad",
auto addresses = parse_ad(s, p);
_ad(s, addresses); },
[](Session &s, Parser &p) { parse_ad(s, p); },
"Analysis Disassemble", R"(
"Analysis: Disassemble", R"(
ad [<addresses>...]
Disassemble the given set of addresses into the current virtual space's main
@ -417,7 +417,7 @@ static ShellCommand _ads_cmd("ads",
parse_ads(s, p);
_ads(s); },
[](Session &s, Parser &p) { parse_ads(s, p); },
"Analysis Disassemble all Syscalls", R"(
"Analysis: Disassemble all Syscalls", R"(
ads
Disassembles all syscalls entries using ad, which stores the results in the

View File

@ -7,6 +7,39 @@
#include <algorithm>
#include <fmt/core.h>
//---
// ic
//---
struct _ic_args {
std::vector<uint32_t> addresses;
};
static struct _ic_args parse_ic(Session &session, Parser &parser)
{
_ic_args args;
while(!parser.at_end())
args.addresses.push_back(parser.expr(session.current_space));
parser.end();
return args;
}
void _ic(Session &session, struct _ic_args const &args)
{
if(!session.current_space)
return;
for(uint32_t address: args.addresses) {
Claim const *claim = session.current_space->disasm.getClaimAt(address);
if(claim)
fmt::print("0x{:08x} is claimed by {}\n", address, claim->str());
else
fmt::print("0x{:08x} is not claimed\n", address);
}
}
//---
// io
//---
@ -164,6 +197,17 @@ void _is(Session &session, std::string vspace_name, bool sort)
// Command registration
//---
static ShellCommand _ic_cmd("ic",
[](Session &s, Parser &p){ _ic(s, parse_ic(s, p)); },
[](Session &s, Parser &p){ parse_ic(s, p); },
"Info Claims", R"(
ic <address>...
Prints information about claims over the specified addresses. Claims are
usually generated by analysis commands and allow sections of the OS to be
marked as part of functions, data, interrupt handlers, etc.
)");
static ShellCommand _io_cmd("io",
[](Session &s, Parser &p){ _io(s, parse_io(s, p)); },
[](Session &s, Parser &p){ parse_io(s, p); },