Remove _dr and add token options to atom and expr

This commit is contained in:
Dr-Carlos 2022-12-05 15:43:58 +10:30
parent a277a4ffad
commit 1082c451d2
3 changed files with 71 additions and 68 deletions

View File

@ -69,72 +69,78 @@ static void disassemble(Session &session, Disassembly &disasm,
// d
//---
static uint32_t parse_d(Session &session, Parser &parser)
struct _d_args
{
std::optional<uint32_t> address;
std::optional<Range> range;
};
static _d_args parse_d(Session &session, Parser &parser)
{
if(!session.current_space)
return 0;
return {};
uint32_t address = session.current_space->cursor;
if(!parser.at_end())
address = parser.expr(session.current_space);
if(!parser.at_end()) {
Token t = parser.lookahead();
try {
Range range = parser.range(session.current_space);
parser.end();
return {{}, range};
}
catch(...) {
address = parser.expr(session.current_space, t);
}
}
parser.end();
return address;
return {address, {}};
}
void _d(Session &session, uint32_t address)
void _d(Session &session, std::optional<uint32_t> address_opt,
std::optional<Range> range_opt)
{
if(!session.current_space)
return;
FxOS::Disassembly disasm(*session.current_space);
if(address & 1) {
fmt::print("address 0x{:08x} is odd, starting at 0x{:08x}\n", address,
address + 1);
address++;
if(address_opt.has_value()) {
uint32_t address = address_opt.value();
if(address & 1) {
fmt::print("address 0x{:08x} is odd, starting at 0x{:08x}\n",
address, address + 1);
address++;
}
disassemble(session, disasm,
{"cfg", "pcrel", /*"constprop",*/ "syscall", "print"}, address);
}
else if(range_opt.has_value()) {
Range range = range_opt.value();
if(range.start & 1) {
fmt::print("address 0x{:08x} is odd, starting at 0x{:08x}\n",
range.start, range.start + 1);
range.start++;
}
if(range.end & 1) {
fmt::print("address 0x{:08x} is odd, ending at 0x{:08x}\n",
range.end, range.end - 1);
range.end--;
}
disassemble(session, disasm,
{"cfg", "pcrel", /*"constprop",*/ "syscall", "print"}, address);
}
if(range.start >= range.end)
return;
//---
// dr
//---
/* Load the block into memory */
for(uint32_t pc = range.start; pc < range.end; pc += 2)
disasm.getInstructionAt(pc, true);
static Range parse_dr(Session &session, Parser &parser)
{
Range range = parser.range(session.current_space);
parser.end();
return range;
}
void _dr(Session &session, Range range)
{
if(!session.current_space)
return;
FxOS::Disassembly disasm(*session.current_space);
if(range.start & 1) {
fmt::print("address 0x{:08x} is odd, starting at 0x{:08x}\n",
range.start, range.start + 1);
range.start++;
disassemble(session, disasm,
{"pcrel", /*"constprop",*/ "syscall", "print"}, -1);
}
if(range.end & 1) {
fmt::print("address 0x{:08x} is odd, ending at 0x{:08x}\n", range.end,
range.end - 1);
range.end--;
}
if(range.start >= range.end)
return;
/* Load the block into memory */
for(uint32_t pc = range.start; pc < range.end; pc += 2)
disasm.getInstructionAt(pc, true);
disassemble(
session, disasm, {"pcrel", /*"constprop",*/ "syscall", "print"}, -1);
}
//---
@ -142,9 +148,13 @@ void _dr(Session &session, Range range)
//---
static ShellCommand _d_cmd(
"d", [](Session &s, Parser &p) { _d(s, parse_d(s, p)); },
"d",
[](Session &s, Parser &p) {
auto args = parse_d(s, p);
_d(s, args.address, args.range);
},
[](Session &s, Parser &p) { parse_d(s, p); }, "Disassemble", R"(
d [<address>]
d [<address|range>]
Disassembles code starting at the specified address, exploring branches until
function terminators, invalid instructions, or dynamically-computed jumps. The
@ -159,15 +169,3 @@ The following disassembler passes are run:
pcrel Computes PC-relative addresses (eg mov.l, mova, bf, bra...)
syscall Annotates uses of syscall table entries with the syscall number
)");
static ShellCommand _dr_cmd(
"dr", [](Session &s, Parser &p) { _dr(s, parse_dr(s, p)); },
[](Session &s, Parser &p) { parse_dr(s, p); }, "Disassemble Range", R"(
dr [<range>]
Disassembles an explicit region of memory. This is similar to d, except that
the disassembled code is pre-loaded from the region instead of being explored
by the cfg pass. See d? for more information.
Like d, this command does not extend the virtual space's main disassembly.
)");

View File

@ -304,9 +304,14 @@ void Parser::accept_options()
// Parsing rules for expressions
//---
long Parser::atom()
long Parser::atom(std::optional<Token> token)
{
Token t = expect({'$', '(', '-', T::SYMBOL, T::NUM, T::SYSCALL});
Token t;
if(token.has_value())
t = token.value();
else
t = expect({'$', '(', '-', T::SYMBOL, T::NUM, T::SYSCALL});
if(t.type == T::SYMBOL) {
/* TODO: Specify the space that symbols are taken from */
@ -390,10 +395,10 @@ long Parser::term()
return v;
}
long Parser::expr(VirtualSpace *space)
long Parser::expr(VirtualSpace *space, std::optional<Token> token)
{
m_expr_space = space;
long val = atom();
long val = atom(token);
m_expr_space = nullptr;
return val;
}

View File

@ -141,7 +141,7 @@ public:
/* Read a numerical constant, or an expression. Expression uses the space
to access the program counter and query symbol values */
long num();
long expr(VirtualSpace *space);
long expr(VirtualSpace *space, std::optional<Token> token={});
/* Read a range; again $ and symbols are interpreted. If (before) and
(after) are both specified, a single value will also be accepted, and
the range [value+before, value.after) will be returned. */
@ -191,7 +191,7 @@ private:
/* Parsing rules for expressions */
long term();
long factor();
long atom();
long atom(std::optional<Token> token={});
/* true if we're completing a partial command, false if we're parsing a
finished one */