regs.c (3015B)
1 /* ARM32 (AArch32) register name table -- DWARF index <-> AAPCS name. 2 * 3 * "DWARF for the ARM Architecture" numbers the core registers r0..r15 as 4 * 0..15 and the VFP single-precision registers s0..s31 as 64..95. Canonical 5 * names are rN; sp/lr/pc/ip/fp aliases are accepted by lookup. v1 is 6 * soft-float, but the s-registers are listed for disassembly/debug. */ 7 8 #include "arch/arm32/regs.h" 9 10 #include <stdint.h> 11 12 #include "core/core.h" 13 #include "core/slice.h" 14 15 typedef struct Arm32Reg { 16 uint32_t dwarf_idx; 17 const char* name; 18 } Arm32Reg; 19 20 static const Arm32Reg ARM32_REGS[] = { 21 {0, "r0"}, {1, "r1"}, {2, "r2"}, {3, "r3"}, {4, "r4"}, 22 {5, "r5"}, {6, "r6"}, {7, "r7"}, {8, "r8"}, {9, "r9"}, 23 {10, "r10"}, {11, "r11"}, {12, "r12"}, {13, "sp"}, {14, "lr"}, 24 {15, "pc"}, 25 26 {64, "s0"}, {65, "s1"}, {66, "s2"}, {67, "s3"}, {68, "s4"}, 27 {69, "s5"}, {70, "s6"}, {71, "s7"}, {72, "s8"}, {73, "s9"}, 28 {74, "s10"}, {75, "s11"}, {76, "s12"}, {77, "s13"}, {78, "s14"}, 29 {79, "s15"}, {80, "s16"}, {81, "s17"}, {82, "s18"}, {83, "s19"}, 30 {84, "s20"}, {85, "s21"}, {86, "s22"}, {87, "s23"}, {88, "s24"}, 31 {89, "s25"}, {90, "s26"}, {91, "s27"}, {92, "s28"}, {93, "s29"}, 32 {94, "s30"}, {95, "s31"}, 33 }; 34 35 static const uint32_t ARM32_REGS_N = 36 (uint32_t)(sizeof ARM32_REGS / sizeof ARM32_REGS[0]); 37 38 static int parse_num_suffix(const char* name, char prefix, uint32_t max, 39 uint32_t* out) { 40 uint32_t v = 0; 41 const char* p; 42 if (!name || name[0] != prefix || name[1] == '\0') return 1; 43 p = name + 1; 44 while (*p) { 45 if (*p < '0' || *p > '9') return 1; 46 v = v * 10u + (uint32_t)(*p - '0'); 47 if (v > max) return 1; 48 ++p; 49 } 50 if (out) *out = v; 51 return 0; 52 } 53 54 const char* arm32_register_name(uint32_t dwarf_idx) { 55 uint32_t i; 56 for (i = 0; i < ARM32_REGS_N; ++i) { 57 if (ARM32_REGS[i].dwarf_idx == dwarf_idx) return ARM32_REGS[i].name; 58 } 59 return NULL; 60 } 61 62 int arm32_register_index(const char* name, uint32_t* idx_out) { 63 uint32_t i; 64 uint32_t n; 65 Slice q; 66 if (!name) return 1; 67 q = slice_from_cstr(name); 68 for (i = 0; i < ARM32_REGS_N; ++i) { 69 if (slice_eq_cstr(q, ARM32_REGS[i].name)) { 70 if (idx_out) *idx_out = ARM32_REGS[i].dwarf_idx; 71 return 0; 72 } 73 } 74 if (!parse_num_suffix(name, 'r', 15, &n)) { 75 if (idx_out) *idx_out = n; 76 return 0; 77 } 78 if (!parse_num_suffix(name, 's', 31, &n)) { 79 if (idx_out) *idx_out = 64u + n; 80 return 0; 81 } 82 if (slice_eq_cstr(q, "ip")) { /* r12 */ 83 if (idx_out) *idx_out = 12u; 84 return 0; 85 } 86 if (slice_eq_cstr(q, "fp")) { /* r11 (Thumb FP) */ 87 if (idx_out) *idx_out = 11u; 88 return 0; 89 } 90 return 1; 91 } 92 93 uint32_t arm32_register_iter_size(void) { return ARM32_REGS_N; } 94 95 int arm32_register_iter_get(uint32_t i, uint32_t* dwarf_out, 96 const char** name_out) { 97 if (i >= ARM32_REGS_N) return 1; 98 if (dwarf_out) *dwarf_out = ARM32_REGS[i].dwarf_idx; 99 if (name_out) *name_out = ARM32_REGS[i].name; 100 return 0; 101 }