diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-02-21 10:51:08 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-02-21 10:51:08 -0800 |
| commit | c7decec2f2d2ab0366567f9e30c0e1418cece43f (patch) | |
| tree | 50312739ad43d0655ea71c942d848db2ff123e8e /tools/perf/util/annotate-arch/annotate-arm64.c | |
| parent | 3544d5ce36f403db6e5c994f526101c870ffe9fe (diff) | |
| parent | dbf0108347bdb5d4ccef8910555b16c1f1a505f8 (diff) | |
| download | lwn-c7decec2f2d2ab0366567f9e30c0e1418cece43f.tar.gz lwn-c7decec2f2d2ab0366567f9e30c0e1418cece43f.zip | |
Merge tag 'perf-tools-for-v7.0-1-2026-02-21' of git://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools
Pull perf tools updates from Arnaldo Carvalho de Melo:
- Introduce 'perf sched stats' tool with record/report/diff workflows
using schedstat counters
- Add a faster libdw based addr2line implementation and allow selecting
it or its alternatives via 'perf config addr2line.style='
- Data-type profiling fixes and improvements including the ability to
select fields using 'perf report''s -F/-fields, e.g.:
'perf report --fields overhead,type'
- Add 'perf test' regression tests for Data-type profiling with C and
Rust workloads
- Fix srcline printing with inlines in callchains, make sure this has
coverage in 'perf test'
- Fix printing of leaf IP in LBR callchains
- Fix display of metrics without sufficient permission in 'perf stat'
- Print all machines in 'perf kvm report -vvv', not just the host
- Switch from SHA-1 to BLAKE2s for build ID generation, remove SHA-1
code
- Fix 'perf report's histogram entry collapsing with '-F' option
- Use system's cacheline size instead of a hardcoded value in 'perf
report'
- Allow filtering conversion by time range in 'perf data'
- Cover conversion to CTF using 'perf data' in 'perf test'
- Address newer glibc const-correctness (-Werror=discarded-qualifiers)
issues
- Fixes and improvements for ARM's CoreSight support, simplify ARM SPE
event config in 'perf mem', update docs for 'perf c2c' including the
ARM events it can be used with
- Build support for generating metrics from arch specific python
script, add extra AMD, Intel, ARM64 metrics using it
- Add AMD Zen 6 events and metrics
- Add JSON file with OpenHW Risc-V CVA6 hardware counters
- Add 'perf kvm' stats live testing
- Add more 'perf stat' tests to 'perf test'
- Fix segfault in `perf lock contention -b/--use-bpf`
- Fix various 'perf test' cases for s390
- Build system cleanups, bump minimum shellcheck version to 0.7.2
- Support building the capstone based annotation routines as a plugin
- Allow passing extra Clang flags via EXTRA_BPF_FLAGS
* tag 'perf-tools-for-v7.0-1-2026-02-21' of git://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools: (255 commits)
perf test script: Add python script testing support
perf test script: Add perl script testing support
perf script: Allow the generated script to be a path
perf test: perf data --to-ctf testing
perf test: Test pipe mode with data conversion --to-json
perf json: Pipe mode --to-ctf support
perf json: Pipe mode --to-json support
perf check: Add libbabeltrace to the listed features
perf build: Allow passing extra Clang flags via EXTRA_BPF_FLAGS
perf test data_type_profiling.sh: Skip just the Rust tests if code_with_type workload is missing
tools build: Fix feature test for rust compiler
perf libunwind: Fix calls to thread__e_machine()
perf stat: Add no-affinity flag
perf evlist: Reduce affinity use and move into iterator, fix no affinity
perf evlist: Missing TPEBS close in evlist__close()
perf evlist: Special map propagation for tool events that read on 1 CPU
perf stat-shadow: In prepare_metric fix guard on reading NULL perf_stat_evsel
Revert "perf tool_pmu: More accurately set the cpus for tool events"
tools build: Emit dependencies file for test-rust.bin
tools build: Make test-rust.bin be removed by the 'clean' target
...
Diffstat (limited to 'tools/perf/util/annotate-arch/annotate-arm64.c')
| -rw-r--r-- | tools/perf/util/annotate-arch/annotate-arm64.c | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/tools/perf/util/annotate-arch/annotate-arm64.c b/tools/perf/util/annotate-arch/annotate-arm64.c new file mode 100644 index 000000000000..33080fdca125 --- /dev/null +++ b/tools/perf/util/annotate-arch/annotate-arm64.c @@ -0,0 +1,127 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <linux/compiler.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <linux/zalloc.h> +#include <regex.h> +#include "../annotate.h" +#include "../disasm.h" + +struct arch_arm64 { + struct arch arch; + regex_t call_insn; + regex_t jump_insn; +}; + +static int arm64_mov__parse(const struct arch *arch __maybe_unused, + struct ins_operands *ops, + struct map_symbol *ms __maybe_unused, + struct disasm_line *dl __maybe_unused) +{ + char *s = strchr(ops->raw, ','), *target, *endptr; + + if (s == NULL) + return -1; + + *s = '\0'; + ops->source.raw = strdup(ops->raw); + *s = ','; + + if (ops->source.raw == NULL) + return -1; + + target = ++s; + ops->target.raw = strdup(target); + if (ops->target.raw == NULL) + goto out_free_source; + + ops->target.addr = strtoull(target, &endptr, 16); + if (endptr == target) + goto out_free_target; + + s = strchr(endptr, '<'); + if (s == NULL) + goto out_free_target; + endptr = strchr(s + 1, '>'); + if (endptr == NULL) + goto out_free_target; + + *endptr = '\0'; + *s = ' '; + ops->target.name = strdup(s); + *s = '<'; + *endptr = '>'; + if (ops->target.name == NULL) + goto out_free_target; + + return 0; + +out_free_target: + zfree(&ops->target.raw); +out_free_source: + zfree(&ops->source.raw); + return -1; +} + +static const struct ins_ops arm64_mov_ops = { + .parse = arm64_mov__parse, + .scnprintf = mov__scnprintf, +}; + +static const struct ins_ops *arm64__associate_instruction_ops(struct arch *arch, const char *name) +{ + struct arch_arm64 *arm = container_of(arch, struct arch_arm64, arch); + const struct ins_ops *ops; + regmatch_t match[2]; + + if (!regexec(&arm->jump_insn, name, 2, match, 0)) + ops = &jump_ops; + else if (!regexec(&arm->call_insn, name, 2, match, 0)) + ops = &call_ops; + else if (!strcmp(name, "ret")) + ops = &ret_ops; + else + ops = &arm64_mov_ops; + + arch__associate_ins_ops(arch, name, ops); + return ops; +} + +const struct arch *arch__new_arm64(const struct e_machine_and_e_flags *id, + const char *cpuid __maybe_unused) +{ + int err; + struct arch_arm64 *arm = zalloc(sizeof(*arm)); + struct arch *arch; + + if (!arm) + return NULL; + + arch = &arm->arch; + arch->name = "arm64"; + arch->id = *id; + arch->objdump.comment_char = '/'; + arch->objdump.skip_functions_char = '+'; + arch->associate_instruction_ops = arm64__associate_instruction_ops; + + /* bl, blr */ + err = regcomp(&arm->call_insn, "^blr?$", REG_EXTENDED); + if (err) + goto out_free_arm; + + /* b, b.cond, br, cbz/cbnz, tbz/tbnz */ + 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?$", + REG_EXTENDED); + if (err) + goto out_free_call; + + return arch; + +out_free_call: + regfree(&arm->call_insn); +out_free_arm: + free(arm); + errno = SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_REGEXP; + return NULL; +} |
