fxos/shell/d.cpp

162 lines
3.4 KiB
C++

#include "shell.h"
#include "parser.h"
#include "commands.h"
#include "errors.h"
#include <fmt/core.h>
#include <fxos/disassembly.h>
#include <fxos/util.h>
#include <fxos/log.h>
#include <fxos/disasm-passes/cfg.h>
#include <fxos/disasm-passes/pcrel.h>
#include <fxos/disasm-passes/syscall.h>
#include <fxos/disasm-passes/print.h>
static void disassemble(Session &session, Disassembly &disasm,
std::vector<std::string> const &passes, uint32_t address)
{
for(auto pass: passes)
{
auto start = timer_start();
log(LOG "Running pass %s...\\", pass);
if(pass == "cfg")
{
CfgPass p(disasm);
p.run(address);
}
else if(pass == "pcrel")
{
PcrelPass p(disasm);
p.run();
}
else if(pass == "syscall")
{
OS *os = session.current_space->os_analysis();
if(os) {
SyscallPass p(disasm, os);
p.run();
}
}
else if(pass == "print")
{
PrintPass p(disasm);
p.promote_pcjump_loc = PrintPass::Promote;
p.promote_pcrel_loc = PrintPass::Promote;
p.promote_pcrel_value = PrintPass::Promote;
p.promote_syscall = PrintPass::Promote;
p.promote_syscallname = PrintPass::Append;
p.promote_symbol = PrintPass::Append;
p.promote_pcaddr_loc = PrintPass::Promote;
p.run();
}
log(LOG "%s", timer_format(timer_end(start)));
}
}
//---
// d
//---
static uint32_t parse_d(Session &session, Parser &parser)
{
uint32_t address = session.current_space->cursor;
if(!parser.at_end())
address = parser.expr(session.current_space);
parser.end();
return address;
}
void _d(Session &session, uint32_t address)
{
session.require_vspace();
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++;
}
disassemble(session, disasm,
{ "cfg", "pcrel", "constprop", "syscall", "print" }, 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)
{
session.require_vspace();
FxOS::Disassembly disasm(*session.current_space);
if(range.start == range.end) return;
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--;
}
/* Load the block into memory */
for(uint32_t pc = range.start; pc < range.end; pc += 2)
disasm.readins(pc);
disassemble(session, disasm, { "pcrel", "constprop", "syscall", "print" },
-1);
}
//---
// dtl
//---
static std::string parse_dtl(Session &session, Parser &parser)
{
std::string filename = parser.str();
parser.end();
return session.file(filename);
}
void _dtl(Session &, std::string filename)
{
Buffer buf(filename);
FxOS::load_instructions(buf);
}
//---
// Command registration
//---
[[gnu::constructor]] static void _(void)
{
shell_register_command("d",
[](Session &s, Parser &p){ _d(s, parse_d(s, p)); },
[](Session &s, Parser &p){ parse_d(s, p); });
shell_register_command("dr",
[](Session &s, Parser &p){ _dr(s, parse_dr(s, p)); },
[](Session &s, Parser &p){ parse_dr(s, p); });
shell_register_command("dtl",
[](Session &s, Parser &p){ _dtl(s, parse_dtl(s, p)); },
[](Session &s, Parser &p){ parse_dtl(s, p); });
}