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