fxos/lib/passes/syscall.cpp
Lephenixnoir 2e58a8850b
support non-decoded instructions
This finally makes it possible to disassemble any interval without
worrying about potential errors. That's some progress.

By the way, now we can fully disassemble fx@3.10. Takes about 6 seconds
for the analysis passes, and ~9 seconds for printing on my machine.
2020-02-29 16:32:25 +01:00

52 lines
1.1 KiB
C++

//---
// fxos.passes.syscall: Detection and substitution of syscall addresses
//---
#include <fxos/disasm-passes/syscall.h>
namespace FxOS {
SyscallPass::SyscallPass(Disassembly &disasm, OS *os):
InstructionDisassemblyPass(disasm, "syscall"), m_os(os)
{
}
void SyscallPass::analyze([[maybe_unused]] uint32_t pc,ConcreteInstruction &ci)
{
/* Nothing to do if no syscall table is provided! */
if(!m_os) return;
Instruction const *i = ci.inst;
if(!i) return;
for(size_t n = 0; n < i->args.size(); n++)
{
Argument const &a = i->args[n];
ConcreteInstructionArg &ca = ci.args[n];
bool eligible = false;
uint32_t address;
if(a.kind == Argument::PcRel && ca.value
&& ca.value.type == IntegerType::u32)
{
eligible = true;
address = ca.value.read(0, 4);
}
if(a.kind == Argument::PcJump && ca.location
&& RelConstDomain().is_constant(ca.location))
{
eligible = true;
address = RelConstDomain().constant_value(ca.location);
}
if(eligible)
{
int sid = m_os->find_syscall(address);
if(sid >= 0) ca.syscall_id = sid;
}
}
}
} /* namespace FxOS */