root/tools/perf/arch/arm64/annotate/instructions.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. arm64_mov__parse
  2. arm64__associate_instruction_ops
  3. arm64__annotate_init

   1 // SPDX-License-Identifier: GPL-2.0
   2 #include <linux/compiler.h>
   3 #include <sys/types.h>
   4 #include <regex.h>
   5 #include <stdlib.h>
   6 
   7 struct arm64_annotate {
   8         regex_t call_insn,
   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,
  67 };
  68 
  69 static struct ins_ops *arm64__associate_instruction_ops(struct arch *arch, const char *name)
  70 {
  71         struct arm64_annotate *arm = arch->priv;
  72         struct ins_ops *ops;
  73         regmatch_t match[2];
  74 
  75         if (!regexec(&arm->jump_insn, name, 2, match, 0))
  76                 ops = &jump_ops;
  77         else if (!regexec(&arm->call_insn, name, 2, match, 0))
  78                 ops = &call_ops;
  79         else if (!strcmp(name, "ret"))
  80                 ops = &ret_ops;
  81         else
  82                 ops = &arm64_mov_ops;
  83 
  84         arch__associate_ins_ops(arch, name, ops);
  85         return ops;
  86 }
  87 
  88 static int arm64__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
  89 {
  90         struct arm64_annotate *arm;
  91         int err;
  92 
  93         if (arch->initialized)
  94                 return 0;
  95 
  96         arm = zalloc(sizeof(*arm));
  97         if (!arm)
  98                 return ENOMEM;
  99 
 100         /* bl, blr */
 101         err = regcomp(&arm->call_insn, "^blr?$", REG_EXTENDED);
 102         if (err)
 103                 goto out_free_arm;
 104         /* b, b.cond, br, cbz/cbnz, tbz/tbnz */
 105         err = regcomp(&arm->jump_insn, "^[ct]?br?\\.?(cc|cs|eq|ge|gt|hi|le|ls|lt|mi|ne|pl)?n?z?$",
 106                       REG_EXTENDED);
 107         if (err)
 108                 goto out_free_call;
 109 
 110         arch->initialized = true;
 111         arch->priv        = arm;
 112         arch->associate_instruction_ops   = arm64__associate_instruction_ops;
 113         arch->objdump.comment_char        = '/';
 114         arch->objdump.skip_functions_char = '+';
 115         return 0;
 116 
 117 out_free_call:
 118         regfree(&arm->call_insn);
 119 out_free_arm:
 120         free(arm);
 121         return SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_REGEXP;
 122 }

/* [<][>][^][v][top][bottom][index][help] */