2020-02-15 18:42:14 +01:00
|
|
|
//---
|
|
|
|
// fxos.passes.syscall: Detection and substitution of syscall addresses
|
|
|
|
//---
|
|
|
|
|
|
|
|
#include <fxos/disasm-passes/syscall.h>
|
|
|
|
|
|
|
|
namespace FxOS {
|
|
|
|
|
|
|
|
SyscallPass::SyscallPass(Disassembly &disasm, OS *os):
|
2020-02-29 11:22:26 +01:00
|
|
|
InstructionDisassemblyPass(disasm, "syscall"), m_os(os)
|
2020-02-15 18:42:14 +01:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-02-28 16:19:50 +01:00
|
|
|
void SyscallPass::analyze([[maybe_unused]] uint32_t pc,ConcreteInstruction &ci)
|
2020-02-15 18:42:14 +01:00
|
|
|
{
|
|
|
|
/* Nothing to do if no syscall table is provided! */
|
|
|
|
if(!m_os) return;
|
|
|
|
|
2020-02-29 16:32:25 +01:00
|
|
|
Instruction const *i = ci.inst;
|
|
|
|
if(!i) return;
|
2020-02-15 18:42:14 +01:00
|
|
|
|
2020-02-29 16:32:25 +01:00
|
|
|
for(size_t n = 0; n < i->args.size(); n++)
|
2020-02-15 18:42:14 +01:00
|
|
|
{
|
2020-02-29 16:32:25 +01:00
|
|
|
Argument const &a = i->args[n];
|
2020-02-15 18:42:14 +01:00
|
|
|
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 */
|