forked from Lephenixnoir/fxos
Remove _dr and add token options to atom and expr
This commit is contained in:
parent
a277a4ffad
commit
1082c451d2
122
shell/d.cpp
122
shell/d.cpp
|
@ -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.
|
||||
)");
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue