| .. | .. |
|---|
| 2 | 2 | #include <linux/compiler.h> |
|---|
| 3 | 3 | #include <sys/types.h> |
|---|
| 4 | 4 | #include <regex.h> |
|---|
| 5 | +#include <stdlib.h> |
|---|
| 5 | 6 | |
|---|
| 6 | 7 | struct arm64_annotate { |
|---|
| 7 | 8 | regex_t call_insn, |
|---|
| 8 | 9 | jump_insn; |
|---|
| 10 | +}; |
|---|
| 11 | + |
|---|
| 12 | +static int arm64_mov__parse(struct arch *arch __maybe_unused, |
|---|
| 13 | + struct ins_operands *ops, |
|---|
| 14 | + struct map_symbol *ms __maybe_unused) |
|---|
| 15 | +{ |
|---|
| 16 | + char *s = strchr(ops->raw, ','), *target, *endptr; |
|---|
| 17 | + |
|---|
| 18 | + if (s == NULL) |
|---|
| 19 | + return -1; |
|---|
| 20 | + |
|---|
| 21 | + *s = '\0'; |
|---|
| 22 | + ops->source.raw = strdup(ops->raw); |
|---|
| 23 | + *s = ','; |
|---|
| 24 | + |
|---|
| 25 | + if (ops->source.raw == NULL) |
|---|
| 26 | + return -1; |
|---|
| 27 | + |
|---|
| 28 | + target = ++s; |
|---|
| 29 | + ops->target.raw = strdup(target); |
|---|
| 30 | + if (ops->target.raw == NULL) |
|---|
| 31 | + goto out_free_source; |
|---|
| 32 | + |
|---|
| 33 | + ops->target.addr = strtoull(target, &endptr, 16); |
|---|
| 34 | + if (endptr == target) |
|---|
| 35 | + goto out_free_target; |
|---|
| 36 | + |
|---|
| 37 | + s = strchr(endptr, '<'); |
|---|
| 38 | + if (s == NULL) |
|---|
| 39 | + goto out_free_target; |
|---|
| 40 | + endptr = strchr(s + 1, '>'); |
|---|
| 41 | + if (endptr == NULL) |
|---|
| 42 | + goto out_free_target; |
|---|
| 43 | + |
|---|
| 44 | + *endptr = '\0'; |
|---|
| 45 | + *s = ' '; |
|---|
| 46 | + ops->target.name = strdup(s); |
|---|
| 47 | + *s = '<'; |
|---|
| 48 | + *endptr = '>'; |
|---|
| 49 | + if (ops->target.name == NULL) |
|---|
| 50 | + goto out_free_target; |
|---|
| 51 | + |
|---|
| 52 | + return 0; |
|---|
| 53 | + |
|---|
| 54 | +out_free_target: |
|---|
| 55 | + zfree(&ops->target.raw); |
|---|
| 56 | +out_free_source: |
|---|
| 57 | + zfree(&ops->source.raw); |
|---|
| 58 | + return -1; |
|---|
| 59 | +} |
|---|
| 60 | + |
|---|
| 61 | +static int mov__scnprintf(struct ins *ins, char *bf, size_t size, |
|---|
| 62 | + struct ins_operands *ops, int max_ins_name); |
|---|
| 63 | + |
|---|
| 64 | +static struct ins_ops arm64_mov_ops = { |
|---|
| 65 | + .parse = arm64_mov__parse, |
|---|
| 66 | + .scnprintf = mov__scnprintf, |
|---|
| 9 | 67 | }; |
|---|
| 10 | 68 | |
|---|
| 11 | 69 | static struct ins_ops *arm64__associate_instruction_ops(struct arch *arch, const char *name) |
|---|
| .. | .. |
|---|
| 21 | 79 | else if (!strcmp(name, "ret")) |
|---|
| 22 | 80 | ops = &ret_ops; |
|---|
| 23 | 81 | else |
|---|
| 24 | | - return NULL; |
|---|
| 82 | + ops = &arm64_mov_ops; |
|---|
| 25 | 83 | |
|---|
| 26 | 84 | arch__associate_ins_ops(arch, name, ops); |
|---|
| 27 | 85 | return ops; |
|---|
| .. | .. |
|---|
| 37 | 95 | |
|---|
| 38 | 96 | arm = zalloc(sizeof(*arm)); |
|---|
| 39 | 97 | if (!arm) |
|---|
| 40 | | - return -1; |
|---|
| 98 | + return ENOMEM; |
|---|
| 41 | 99 | |
|---|
| 42 | 100 | /* bl, blr */ |
|---|
| 43 | 101 | err = regcomp(&arm->call_insn, "^blr?$", REG_EXTENDED); |
|---|
| .. | .. |
|---|
| 60 | 118 | regfree(&arm->call_insn); |
|---|
| 61 | 119 | out_free_arm: |
|---|
| 62 | 120 | free(arm); |
|---|
| 63 | | - return -1; |
|---|
| 121 | + return SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_REGEXP; |
|---|
| 64 | 122 | } |
|---|