1 // SPDX-License-Identifier: GPL-2.0 2 #include <stdlib.h> 3 #include <linux/compiler.h> 4 #include <linux/zalloc.h> 5 #include <errno.h> 6 #include <regex.h> 7 #include "../annotate.h" 8 #include "../disasm.h" 9 10 struct arch_arm { 11 struct arch arch; 12 regex_t call_insn; 13 regex_t jump_insn; 14 }; 15 16 static const struct ins_ops *arm__associate_instruction_ops(struct arch *arch, const char *name) 17 { 18 struct arch_arm *arm = container_of(arch, struct arch_arm, arch); 19 const struct ins_ops *ops; 20 regmatch_t match[2]; 21 22 if (!regexec(&arm->call_insn, name, 2, match, 0)) 23 ops = &call_ops; 24 else if (!regexec(&arm->jump_insn, name, 2, match, 0)) 25 ops = &jump_ops; 26 else 27 return NULL; 28 29 arch__associate_ins_ops(arch, name, ops); 30 return ops; 31 } 32 33 const struct arch *arch__new_arm(const struct e_machine_and_e_flags *id, 34 const char *cpuid __maybe_unused) 35 { 36 int err; 37 struct arch_arm *arm = zalloc(sizeof(*arm)); 38 struct arch *arch; 39 40 if (!arm) 41 return NULL; 42 43 arch = &arm->arch; 44 arch->name = "arm"; 45 arch->id = *id; 46 arch->objdump.comment_char = ';'; 47 arch->objdump.skip_functions_char = '+'; 48 arch->associate_instruction_ops = arm__associate_instruction_ops; 49 50 #define ARM_CONDS "(cc|cs|eq|ge|gt|hi|le|ls|lt|mi|ne|pl|vc|vs)" 51 err = regcomp(&arm->call_insn, "^blx?" ARM_CONDS "?$", REG_EXTENDED); 52 if (err) 53 goto out_free_arm; 54 55 err = regcomp(&arm->jump_insn, "^bx?" ARM_CONDS "?$", REG_EXTENDED); 56 if (err) 57 goto out_free_call; 58 #undef ARM_CONDS 59 60 return arch; 61 62 out_free_call: 63 regfree(&arm->call_insn); 64 out_free_arm: 65 free(arm); 66 errno = SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_REGEXP; 67 return NULL; 68 } 69