File Index
Files and directories
Sign in
FILE

instructions.c

File preview with syntax highlighting.

linux-6.19.14/tools/perf/arch/arm64/annotate/instructions.c C
  1// SPDX-License-Identifier: GPL-2.0
  2#include <linux/compiler.h>
  3#include <errno.h>
  4#include <sys/types.h>
  5#include <regex.h>
  6#include <stdlib.h>
  7
  8struct arm64_annotate {
  9	regex_t call_insn,
 10		jump_insn;
 11};
 12
 13static int arm64_mov__parse(struct arch *arch __maybe_unused,
 14			    struct ins_operands *ops,
 15			    struct map_symbol *ms __maybe_unused,
 16			    struct disasm_line *dl __maybe_unused)
 17{
 18	char *s = strchr(ops->raw, ','), *target, *endptr;
 19
 20	if (s == NULL)
 21		return -1;
 22
 23	*s = '\0';
 24	ops->source.raw = strdup(ops->raw);
 25	*s = ',';
 26
 27	if (ops->source.raw == NULL)
 28		return -1;
 29
 30	target = ++s;
 31	ops->target.raw = strdup(target);
 32	if (ops->target.raw == NULL)
 33		goto out_free_source;
 34
 35	ops->target.addr = strtoull(target, &endptr, 16);
 36	if (endptr == target)
 37		goto out_free_target;
 38
 39	s = strchr(endptr, '<');
 40	if (s == NULL)
 41		goto out_free_target;
 42	endptr = strchr(s + 1, '>');
 43	if (endptr == NULL)
 44		goto out_free_target;
 45
 46	*endptr = '\0';
 47	*s = ' ';
 48	ops->target.name = strdup(s);
 49	*s = '<';
 50	*endptr = '>';
 51	if (ops->target.name == NULL)
 52		goto out_free_target;
 53
 54	return 0;
 55
 56out_free_target:
 57	zfree(&ops->target.raw);
 58out_free_source:
 59	zfree(&ops->source.raw);
 60	return -1;
 61}
 62
 63static int mov__scnprintf(struct ins *ins, char *bf, size_t size,
 64			  struct ins_operands *ops, int max_ins_name);
 65
 66static struct ins_ops arm64_mov_ops = {
 67	.parse	   = arm64_mov__parse,
 68	.scnprintf = mov__scnprintf,
 69};
 70
 71static struct ins_ops *arm64__associate_instruction_ops(struct arch *arch, const char *name)
 72{
 73	struct arm64_annotate *arm = arch->priv;
 74	struct ins_ops *ops;
 75	regmatch_t match[2];
 76
 77	if (!regexec(&arm->jump_insn, name, 2, match, 0))
 78		ops = &jump_ops;
 79	else if (!regexec(&arm->call_insn, name, 2, match, 0))
 80		ops = &call_ops;
 81	else if (!strcmp(name, "ret"))
 82		ops = &ret_ops;
 83	else
 84		ops = &arm64_mov_ops;
 85
 86	arch__associate_ins_ops(arch, name, ops);
 87	return ops;
 88}
 89
 90static int arm64__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
 91{
 92	struct arm64_annotate *arm;
 93	int err;
 94
 95	if (arch->initialized)
 96		return 0;
 97
 98	arm = zalloc(sizeof(*arm));
 99	if (!arm)
100		return ENOMEM;
101
102	/* bl, blr */
103	err = regcomp(&arm->call_insn, "^blr?$", REG_EXTENDED);
104	if (err)
105		goto out_free_arm;
106	/* b, b.cond, br, cbz/cbnz, tbz/tbnz */
107	err = regcomp(&arm->jump_insn, "^[ct]?br?\\.?(cc|cs|eq|ge|gt|hi|hs|le|lo|ls|lt|mi|ne|pl|vc|vs)?n?z?$",
108		      REG_EXTENDED);
109	if (err)
110		goto out_free_call;
111
112	arch->initialized = true;
113	arch->priv	  = arm;
114	arch->associate_instruction_ops   = arm64__associate_instruction_ops;
115	arch->objdump.comment_char	  = '/';
116	arch->objdump.skip_functions_char = '+';
117	arch->e_machine = EM_AARCH64;
118	arch->e_flags = 0;
119	return 0;
120
121out_free_call:
122	regfree(&arm->call_insn);
123out_free_arm:
124	free(arm);
125	return SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_REGEXP;
126}
~/ Read-only file preview.