| 1 | |
| 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 | }
|