//--- // fxos.passes.syscall: Detection and substitution of syscall addresses //--- #include 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->arg_count; 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 */