58 lines
1.7 KiB
C++
58 lines
1.7 KiB
C++
//---------------------------------------------------------------------------//
|
|
// 1100101 |_ mov #0, r4 __ //
|
|
// 11 |_ <0xb380 %5c4> / _|_ _____ ___ //
|
|
// 0110 |_ 3.50 -> 3.60 | _\ \ / _ (_-< //
|
|
// |_ base# + offset |_| /_\_\___/__/ //
|
|
//---------------------------------------------------------------------------//
|
|
|
|
#include <fxos/passes/syscall.h>
|
|
|
|
namespace FxOS {
|
|
|
|
SyscallPass::SyscallPass(Disassembly &disasm, OS *os):
|
|
InstructionPass(disasm), m_os {os}
|
|
{
|
|
}
|
|
|
|
bool SyscallPass::analyzeInstruction(uint32_t pc, Instruction &ci)
|
|
{
|
|
/* Nothing to do if no syscall table is provided! */
|
|
if(!m_os)
|
|
return true;
|
|
|
|
(void)pc;
|
|
|
|
AsmInstruction const *i = ci.inst;
|
|
if(!i)
|
|
return true;
|
|
|
|
for(size_t n = 0; n < i->arg_count; n++) {
|
|
AsmArgument const &arg = i->args[n];
|
|
Argument &a = ci.args[n];
|
|
|
|
bool eligible = false;
|
|
uint32_t address;
|
|
|
|
if(arg.kind == AsmArgument::PcRel && a.value
|
|
&& RelConstDomain().is_constant(a.value)) {
|
|
eligible = true;
|
|
address = RelConstDomain().constant_value(a.value);
|
|
}
|
|
if(arg.kind == AsmArgument::PcJump && a.location
|
|
&& RelConstDomain().is_constant(a.location)) {
|
|
eligible = true;
|
|
address = RelConstDomain().constant_value(a.location);
|
|
}
|
|
|
|
if(eligible) {
|
|
int sid = m_os->find_syscall(address);
|
|
if(sid >= 0)
|
|
a.syscall_id = sid;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
} /* namespace FxOS */
|