MCPcopy Create free account
hub / github.com/MultiFuzz/MultiFuzz / add_arm_extras

Function add_arm_extras

icicle-cortexm/src/arm.rs:53–278  ·  view source on GitHub ↗

Most of this should probably be implemented as part of the SLEIGH specification instead.

(vm: &mut Vm, nvic_changed_hook: pcode::HookId)

Source from the content-addressed store, hash-verified

51
52/// Most of this should probably be implemented as part of the SLEIGH specification instead.
53pub(crate) fn add_arm_extras(vm: &mut Vm, nvic_changed_hook: pcode::HookId) {
54 const CPSR_IRQ_MASK_BIT: u32 = 1 << 7;
55 const CPSR_FIQ_MASK_BIT: u32 = 1 << 6;
56
57 let xpsr_reg = vm.cpu.arch.sleigh.add_custom_reg("xpsr", 4).unwrap();
58 let xpsr_handler = XpsrHandler::new(&mut vm.cpu);
59 vm.cpu.add_reg_handler(xpsr_reg.id, Box::new(xpsr_handler));
60
61 let basepri_reg = vm.cpu.arch.sleigh.add_custom_reg("basepri", 4).unwrap();
62 let primask_reg = vm.cpu.arch.sleigh.add_custom_reg("primask", 4).unwrap();
63
64 vm.add_op_injector(
65 "getCurrentExceptionNumber",
66 move |_: &Arch, _, _, output: pcode::VarNode, b: &mut BlockState| {
67 b.pcode.push((output, Op::IntAnd, (xpsr_reg, 0x1ff_u32)));
68 false
69 },
70 );
71
72 vm.add_op_injector("enableIRQinterrupts", move |_: &Arch, _, _, _, b: &mut BlockState| {
73 b.pcode.push((primask_reg, Op::IntAnd, (primask_reg, !CPSR_IRQ_MASK_BIT)));
74 b.pcode.push(pcode::Op::Hook(nvic_changed_hook));
75 // Changing this variable could cause an interrupt to be triggered, so terminate the
76 // block here.
77 true
78 });
79
80 vm.add_op_injector("disableIRQinterrupts", move |_: &Arch, _, _, _, b: &mut BlockState| {
81 b.pcode.push((primask_reg, Op::IntOr, (primask_reg, CPSR_IRQ_MASK_BIT)));
82 b.pcode.push(pcode::Op::Hook(nvic_changed_hook));
83 false
84 });
85
86 vm.add_op_injector("enableFIQinterrupts", move |_: &Arch, _, _, _, b: &mut BlockState| {
87 b.pcode.push((primask_reg, Op::IntAnd, (primask_reg, !CPSR_FIQ_MASK_BIT)));
88 b.pcode.push(pcode::Op::Hook(nvic_changed_hook));
89 // Changing this variable could cause an interrupt to be triggered, so terminate the
90 // block here.
91 true
92 });
93
94 vm.add_op_injector("disableFIQinterrupts", move |_: &Arch, _, _, _, b: &mut BlockState| {
95 b.pcode.push((primask_reg, Op::IntOr, (primask_reg, CPSR_FIQ_MASK_BIT)));
96 b.pcode.push(pcode::Op::Hook(nvic_changed_hook));
97 false
98 });
99
100 vm.add_op_injector(
101 "isIRQinterruptsEnabled",
102 move |_: &Arch, _, _, output, b: &mut BlockState| {
103 let shift = 31 - CPSR_IRQ_MASK_BIT.leading_zeros();
104 b.pcode.push((output, Op::IntRight, (primask_reg, shift)));
105 // Even though the p-code operation is called "isIRQinterruptsEnabled" it is intended to
106 // returns the value of `PRIMASK` directly (which is 0 when interrupts are enabled, and
107 // 1 when they are enabled).
108 // b.pcode.push((output, Op::IntNot, output));
109 b.pcode.push((output, Op::IntAnd, (output, 1)));
110 false

Callers 1

fuzzware_initMethod · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected