diff --git a/shell/d.cpp b/shell/d.cpp index 79aacb6..d892089 100644 --- a/shell/d.cpp +++ b/shell/d.cpp @@ -69,72 +69,68 @@ static void disassemble(Session &session, Disassembly &disasm, // d //--- -static uint32_t parse_d(Session &session, Parser &parser) +struct _d_args { - if(!session.current_space) - return 0; - uint32_t address = session.current_space->cursor; + std::variant location; +}; - if(!parser.at_end()) - address = parser.expr(session.current_space); +static _d_args parse_d(Session &session, Parser &parser) +{ + _d_args args; + + if(!session.current_space) + return {}; + + args.location = parser.at_end() + ? session.current_space->cursor + : parser.expr_or_range(session.current_space); parser.end(); - return address; + return args; } -void _d(Session &session, uint32_t address) +void _d(Session &session, std::variant location) { 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(std::holds_alternative(location)) { + Range range = std::get(location); + 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--; + } + + 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); } + else { + uint32_t address = std::get(location); - disassemble(session, disasm, - {"cfg", "pcrel", /*"constprop",*/ "syscall", "print"}, address); -} + if(address & 1) { + fmt::print("address 0x{:08x} is odd, starting at 0x{:08x}\n", + address, address + 1); + address++; + } -//--- -// dr -//--- - -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, + {"cfg", "pcrel", /*"constprop",*/ "syscall", "print"}, address); } - 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 +138,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.location); + }, [](Session &s, Parser &p) { parse_d(s, p); }, "Disassemble", R"( -d [
] +d [] Disassembles code starting at the specified address, exploring branches until function terminators, invalid instructions, or dynamically-computed jumps. The @@ -159,15 +159,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 [] - -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. -)"); diff --git a/shell/parser.cpp b/shell/parser.cpp index 1fa09a2..c826ca2 100644 --- a/shell/parser.cpp +++ b/shell/parser.cpp @@ -142,24 +142,7 @@ void Parser::dump_command() { while(!at_end()) { Token t = m_la; - - if(t.type == T::NUM) - fmt::print("NUM {:#x}\n", t.value.NUM); - else if(t.type == T::SYSCALL) - fmt::print("SYSCALL %{:04x}\n", t.value.NUM); - else if(t.type == T::SYMBOL) - fmt::print("SYMBOL '{}'\n", t.value.STRING); - else if(t.type == T::OPTION) - fmt::print("OPTION '{}'\n", t.value.STRING); - else if(t.type == T::STRING) - fmt::print("STRING '{}'\n", t.value.STRING); - else if(t.type == '>') - fmt::print(">>\n"); - else if(t.type == '<') - fmt::print("<<\n"); - else - fmt::print("{}\n", (char)t.type); - + fmt::print("{}\n", t.str()); feed(); } } @@ -246,7 +229,7 @@ Range Parser::range(VirtualSpace *space, long before, long after) { long start = expr(space); - /* Accept non-rangs if (before) and (after) are provided */ + /* Accept non-ranges if (before) and (after) are provided */ if(m_la.type != ':' && m_la.type != '.' && before >= 0 && after >= 0) return {start - before, start + after}; @@ -259,6 +242,25 @@ Range Parser::range(VirtualSpace *space, long before, long after) return r; } +std::variant Parser::expr_or_range(VirtualSpace *space) +{ + long start = expr(space); + + if(m_la.type == ':') { + expect(':'); + long length = expr(space); + return (Range){start, start + length}; + } + else if(m_la.type == '.') { + expect('.'); + long end = expr(space); + return (Range){start, end}; + } + else { + return (long)start; + } +} + FxOS::MemoryRegion Parser::region(VirtualSpace *space, long before, long after) { if(m_la.type == '$' || m_la.type == '(' || m_la.type == '-' diff --git a/shell/parser.h b/shell/parser.h index 9de9771..693df9f 100644 --- a/shell/parser.h +++ b/shell/parser.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -144,8 +145,10 @@ public: long expr(VirtualSpace *space); /* 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. */ + the range [value-before, value+after) will be returned. */ Range range(VirtualSpace *space, long before=-1, long after=-1); + /* Read an expression or a range */ + std::variant expr_or_range(VirtualSpace *space); /* Read a memory region (allows both ranges and symbolic names) */ FxOS::MemoryRegion region(VirtualSpace *space, long before=-1, long after=-1);