substrate/disasm/
arm_decoder.rs

1pub fn is_arm_pc_relative(instruction: u32) -> bool {
2    (instruction & 0x0c000000) == 0x04000000
3        && (instruction & 0xf0000000) != 0xf0000000
4        && (instruction & 0x000f0000) == 0x000f0000
5}
6
7pub fn is_thumb_32bit(instruction: u16) -> bool {
8    (instruction & 0xe000) == 0xe000 && (instruction & 0x1800) != 0x0000
9}
10
11pub fn is_thumb_pc_relative_cbz(instruction: u16) -> bool {
12    (instruction & 0xf500) == 0xb100
13}
14
15pub fn is_thumb_pc_relative_b(instruction: u16) -> bool {
16    (instruction & 0xf000) == 0xd000 && (instruction & 0x0e00) != 0x0e00
17}
18
19pub fn is_thumb2_pc_relative_b(instructions: &[u16]) -> bool {
20    if instructions.len() < 2 {
21        return false;
22    }
23    (instructions[0] & 0xf800) == 0xf000
24        && ((instructions[1] & 0xd000) == 0x9000 || (instructions[1] & 0xd000) == 0x8000)
25        && (instructions[0] & 0x0380) != 0x0380
26}
27
28pub fn is_thumb_pc_relative_bl(instructions: &[u16]) -> bool {
29    if instructions.len() < 2 {
30        return false;
31    }
32    (instructions[0] & 0xf800) == 0xf000
33        && ((instructions[1] & 0xd000) == 0xd000 || (instructions[1] & 0xd001) == 0xc000)
34}
35
36pub fn is_thumb_pc_relative_ldr(instruction: u16) -> bool {
37    (instruction & 0xf800) == 0x4800
38}
39
40pub fn is_thumb_pc_relative_add(instruction: u16) -> bool {
41    (instruction & 0xff78) == 0x4478
42}
43
44pub fn is_thumb_pc_relative_ldrw(instruction: u16) -> bool {
45    (instruction & 0xff7f) == 0xf85f
46}
47
48pub fn get_thumb_instruction_width(start: *const u8) -> usize {
49    unsafe {
50        let thumb = start as *const u16;
51        if is_thumb_32bit(*thumb) {
52            4
53        } else {
54            2
55        }
56    }
57}
58
59pub fn get_arm_instruction_width(_start: *const u8) -> usize {
60    4
61}
62
63pub fn get_instruction_width(start: *const u8) -> usize {
64    if (start as usize & 0x1) == 0 {
65        get_arm_instruction_width(start)
66    } else {
67        get_thumb_instruction_width((start as usize & !0x1) as *const u8)
68    }
69}