]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
perf disasm: Don't include C files from the arch directory
authorIan Rogers <irogers@google.com>
Thu, 22 Jan 2026 21:35:12 +0000 (13:35 -0800)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Fri, 23 Jan 2026 19:58:38 +0000 (16:58 -0300)
Move the arch instructions.c files into appropriately named files in
annotate-arch in the util directory.

Don't #include to compile the code, switch to building the files and fix
up the #includes accordingly.

Move powerpc specific disasm code out of disasm.c and into
annotate-powerpc.c.

Declarations and static removed as appropriate for the code to compile
as separate compilation units.

The e_machine and e_flags set up is moved to the disasm.c architectures
array so that later patches can sort by them.

Reviewed-by: James Clark <james.clark@linaro.org>
Signed-off-by: Ian Rogers <irogers@google.com>
Cc: Aditya Bodkhe <aditya.b1@linux.ibm.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Albert Ou <aou@eecs.berkeley.edu>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Alexandre Ghiti <alex@ghiti.fr>
Cc: Athira Rajeev <atrajeev@linux.ibm.com>
Cc: Bill Wendling <morbo@google.com>
Cc: Dr. David Alan Gilbert <linux@treblig.org>
Cc: Guo Ren <guoren@kernel.org>
Cc: Howard Chu <howardchu95@gmail.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: John Garry <john.g.garry@oracle.com>
Cc: Julia Lawall <Julia.Lawall@inria.fr>
Cc: Justin Stitt <justinstitt@google.com>
Cc: Krzysztof Ɓopatowski <krzysztof.m.lopatowski@gmail.com>
Cc: Leo Yan <leo.yan@linux.dev>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nick Desaulniers <nick.desaulniers+lkml@gmail.com>
Cc: Palmer Dabbelt <palmer@dabbelt.com>
Cc: Paul Walmsley <pjw@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Sergei Trofimovich <slyich@gmail.com>
Cc: Shimin Guo <shimin.guo@skydio.com>
Cc: Suchit Karunakaran <suchitkarunakaran@gmail.com>
Cc: Thomas Falcon <thomas.falcon@intel.com>
Cc: Tianyou Li <tianyou.li@intel.com>
Cc: Will Deacon <will@kernel.org>
Cc: Zecheng Li <zecheng@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
15 files changed:
tools/perf/util/Build
tools/perf/util/annotate-arch/Build [new file with mode: 0644]
tools/perf/util/annotate-arch/annotate-arc.c [moved from tools/perf/arch/arc/annotate/instructions.c with 53% similarity]
tools/perf/util/annotate-arch/annotate-arm.c [moved from tools/perf/arch/arm/annotate/instructions.c with 90% similarity]
tools/perf/util/annotate-arch/annotate-arm64.c [moved from tools/perf/arch/arm64/annotate/instructions.c with 90% similarity]
tools/perf/util/annotate-arch/annotate-csky.c [moved from tools/perf/arch/csky/annotate/instructions.c with 83% similarity]
tools/perf/util/annotate-arch/annotate-loongarch.c [moved from tools/perf/arch/loongarch/annotate/instructions.c with 93% similarity]
tools/perf/util/annotate-arch/annotate-mips.c [moved from tools/perf/arch/mips/annotate/instructions.c with 94% similarity]
tools/perf/util/annotate-arch/annotate-powerpc.c [moved from tools/perf/arch/powerpc/annotate/instructions.c with 76% similarity]
tools/perf/util/annotate-arch/annotate-riscv64.c [moved from tools/perf/arch/riscv64/annotate/instructions.c with 91% similarity]
tools/perf/util/annotate-arch/annotate-s390.c [moved from tools/perf/arch/s390/annotate/instructions.c with 91% similarity]
tools/perf/util/annotate-arch/annotate-sparc.c [moved from tools/perf/arch/sparc/annotate/instructions.c with 96% similarity]
tools/perf/util/annotate-arch/annotate-x86.c [moved from tools/perf/arch/x86/annotate/instructions.c with 97% similarity]
tools/perf/util/disasm.c
tools/perf/util/disasm.h

index c30ff257f8b40e65bde076fa041ba9178666022b..b9925c6902ca3d40d3575dae2d03a57cc64cd43f 100644 (file)
@@ -1,6 +1,7 @@
 include $(srctree)/tools/scripts/Makefile.include
 include $(srctree)/tools/scripts/utilities.mak
 
+perf-util-y += annotate-arch/
 perf-util-y += arm64-frame-pointer-unwind-support.o
 perf-util-y += addr2line.o
 perf-util-y += addr_location.o
diff --git a/tools/perf/util/annotate-arch/Build b/tools/perf/util/annotate-arch/Build
new file mode 100644 (file)
index 0000000..2331674
--- /dev/null
@@ -0,0 +1,11 @@
+perf-util-y += annotate-arc.o
+perf-util-y += annotate-arm.o
+perf-util-y += annotate-arm64.o
+perf-util-y += annotate-csky.o
+perf-util-y += annotate-loongarch.o
+perf-util-y += annotate-mips.o
+perf-util-y += annotate-x86.o
+perf-util-y += annotate-powerpc.o
+perf-util-y += annotate-riscv64.o
+perf-util-y += annotate-s390.o
+perf-util-y += annotate-sparc.o
similarity index 53%
rename from tools/perf/arch/arc/annotate/instructions.c
rename to tools/perf/util/annotate-arch/annotate-arc.c
index e5619770a1af7365bffb79505c952a9d34ff4e0e..d7ca08ca5600671aadc2150b427f83dd1df4ad93 100644 (file)
@@ -1,11 +1,10 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/compiler.h>
+#include "../disasm.h"
 
-static int arc__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
+int arc__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
 {
        arch->initialized = true;
        arch->objdump.comment_char = ';';
-       arch->e_machine = EM_ARC;
-       arch->e_flags = 0;
        return 0;
 }
similarity index 90%
rename from tools/perf/arch/arm/annotate/instructions.c
rename to tools/perf/util/annotate-arch/annotate-arm.c
index b997d127fedd6ae13aba8eed12d0f5b59fab2dae..08c49067c3c90d6743ce77958a1ac6c3b12490de 100644 (file)
@@ -1,10 +1,11 @@
 // SPDX-License-Identifier: GPL-2.0
+#include <stdlib.h>
 #include <linux/compiler.h>
 #include <linux/zalloc.h>
 #include <errno.h>
-#include <sys/types.h>
 #include <regex.h>
-#include <stdlib.h>
+#include "../annotate.h"
+#include "../disasm.h"
 
 struct arm_annotate {
        regex_t call_insn,
@@ -28,7 +29,7 @@ static const struct ins_ops *arm__associate_instruction_ops(struct arch *arch, c
        return ops;
 }
 
-static int arm__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
+int arm__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
 {
        struct arm_annotate *arm;
        int err;
@@ -54,8 +55,6 @@ static int arm__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
        arch->associate_instruction_ops   = arm__associate_instruction_ops;
        arch->objdump.comment_char        = ';';
        arch->objdump.skip_functions_char = '+';
-       arch->e_machine = EM_ARM;
-       arch->e_flags = 0;
        return 0;
 
 out_free_call:
similarity index 90%
rename from tools/perf/arch/arm64/annotate/instructions.c
rename to tools/perf/util/annotate-arch/annotate-arm64.c
index 44db33854dbaca7faf8d647c9c25d326b76e69b0..d2ea32984b0db6bad46870f88789fd5153a16c9f 100644 (file)
@@ -1,9 +1,12 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/compiler.h>
 #include <errno.h>
-#include <sys/types.h>
-#include <regex.h>
 #include <stdlib.h>
+#include <string.h>
+#include <linux/zalloc.h>
+#include <regex.h>
+#include "../annotate.h"
+#include "../disasm.h"
 
 struct arm64_annotate {
        regex_t call_insn,
@@ -60,9 +63,6 @@ out_free_source:
        return -1;
 }
 
-static int mov__scnprintf(const struct ins *ins, char *bf, size_t size,
-                         struct ins_operands *ops, int max_ins_name);
-
 static const struct ins_ops arm64_mov_ops = {
        .parse     = arm64_mov__parse,
        .scnprintf = mov__scnprintf,
@@ -87,7 +87,7 @@ static const struct ins_ops *arm64__associate_instruction_ops(struct arch *arch,
        return ops;
 }
 
-static int arm64__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
+int arm64__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
 {
        struct arm64_annotate *arm;
        int err;
@@ -114,8 +114,6 @@ static int arm64__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
        arch->associate_instruction_ops   = arm64__associate_instruction_ops;
        arch->objdump.comment_char        = '/';
        arch->objdump.skip_functions_char = '+';
-       arch->e_machine = EM_AARCH64;
-       arch->e_flags = 0;
        return 0;
 
 out_free_call:
similarity index 83%
rename from tools/perf/arch/csky/annotate/instructions.c
rename to tools/perf/util/annotate-arch/annotate-csky.c
index 4a55c84a320a67650b5ac05ac79758d0327119f9..0b0b09b068ecf0ed50601a13a15f1744f8fd268b 100644 (file)
@@ -1,7 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0
 // Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd.
-
+#include <string.h>
 #include <linux/compiler.h>
+#include "../disasm.h"
 
 static const struct ins_ops *csky__associate_ins_ops(struct arch *arch,
                                                     const char *name)
@@ -38,16 +39,10 @@ static const struct ins_ops *csky__associate_ins_ops(struct arch *arch,
        return ops;
 }
 
-static int csky__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
+int csky__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
 {
        arch->initialized = true;
        arch->objdump.comment_char = '/';
        arch->associate_instruction_ops = csky__associate_ins_ops;
-       arch->e_machine = EM_CSKY;
-#if defined(__CSKYABIV2__)
-       arch->e_flags = EF_CSKY_ABIV2;
-#else
-       arch->e_flags = EF_CSKY_ABIV1;
-#endif
        return 0;
 }
similarity index 93%
rename from tools/perf/arch/loongarch/annotate/instructions.c
rename to tools/perf/util/annotate-arch/annotate-loongarch.c
index 5010d5d583758a5298c2ab9f33f76cf6e4e237a4..32df10f6fed5143269d7bbd7efadfb115b4c6658 100644 (file)
@@ -4,11 +4,17 @@
  *
  * Copyright (C) 2020-2023 Loongson Technology Corporation Limited
  */
+#include <stdlib.h>
+#include <string.h>
+#include <linux/compiler.h>
+#include "../disasm.h"
+#include "../map.h"
+#include "../maps.h"
+#include "../symbol.h"
 
 static int loongarch_call__parse(const struct arch *arch, struct ins_operands *ops,
                                 struct map_symbol *ms,
                                 struct disasm_line *dl __maybe_unused)
-
 {
        char *c, *endptr, *tok, *name;
        struct map *map = ms->map;
@@ -51,7 +57,7 @@ static int loongarch_call__parse(const struct arch *arch, struct ins_operands *o
        return 0;
 }
 
-static const struct ins_ops loongarch_call_ops = {
+const struct ins_ops loongarch_call_ops = {
        .parse     = loongarch_call__parse,
        .scnprintf = call__scnprintf,
 };
@@ -100,7 +106,7 @@ static int loongarch_jump__parse(const struct arch *arch, struct ins_operands *o
        return 0;
 }
 
-static const struct ins_ops loongarch_jump_ops = {
+const struct ins_ops loongarch_jump_ops = {
        .parse     = loongarch_jump__parse,
        .scnprintf = jump__scnprintf,
 };
@@ -130,15 +136,12 @@ const struct ins_ops *loongarch__associate_ins_ops(struct arch *arch, const char
        return ops;
 }
 
-static
 int loongarch__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
 {
        if (!arch->initialized) {
                arch->associate_instruction_ops = loongarch__associate_ins_ops;
                arch->initialized = true;
                arch->objdump.comment_char = '#';
-               arch->e_machine = EM_LOONGARCH;
-               arch->e_flags = 0;
        }
 
        return 0;
similarity index 94%
rename from tools/perf/arch/mips/annotate/instructions.c
rename to tools/perf/util/annotate-arch/annotate-mips.c
index 0fbe0a7df95a19c2276dc840af42f7641bd28d56..f14b34ed77d3b8f774038cee0a138f2731cc3240 100644 (file)
@@ -1,4 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
+#include <string.h>
+#include <linux/compiler.h>
+#include "../disasm.h"
 
 static
 const struct ins_ops *mips__associate_ins_ops(struct arch *arch, const char *name)
@@ -33,15 +36,12 @@ const struct ins_ops *mips__associate_ins_ops(struct arch *arch, const char *nam
        return ops;
 }
 
-static
 int mips__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
 {
        if (!arch->initialized) {
                arch->associate_instruction_ops = mips__associate_ins_ops;
                arch->initialized = true;
                arch->objdump.comment_char = '#';
-               arch->e_machine = EM_MIPS;
-               arch->e_flags = 0;
        }
 
        return 0;
similarity index 76%
rename from tools/perf/arch/powerpc/annotate/instructions.c
rename to tools/perf/util/annotate-arch/annotate-powerpc.c
index d1be55425e35b8a812c3f0d54836b35dc7567157..593c138c8104d764424cfe8f844e1fcc5821fb51 100644 (file)
@@ -1,5 +1,97 @@
 // SPDX-License-Identifier: GPL-2.0
+#include <string.h>
 #include <linux/compiler.h>
+#include <linux/kernel.h>
+#include "../annotate-data.h"
+#include "../debug.h"
+#include "../disasm.h"
+
+#define PPC_OP(op)     (((op) >> 26) & 0x3F)
+#define PPC_21_30(R)   (((R) >> 1) & 0x3ff)
+#define PPC_22_30(R)   (((R) >> 1) & 0x1ff)
+
+#define MINUS_EXT_XO_FORM      234
+#define SUB_EXT_XO_FORM                232
+#define        ADD_ZERO_EXT_XO_FORM    202
+#define        SUB_ZERO_EXT_XO_FORM    200
+
+static int arithmetic__scnprintf(const struct ins *ins, char *bf, size_t size,
+               struct ins_operands *ops, int max_ins_name)
+{
+       return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name,
+                       ops->raw);
+}
+
+/*
+ * Sets the fields: multi_regs and "mem_ref".
+ * "mem_ref" is set for ops->source which is later used to
+ * fill the objdump->memory_ref-char field. This ops is currently
+ * used by powerpc and since binary instruction code is used to
+ * extract opcode, regs and offset, no other parsing is needed here.
+ *
+ * Dont set multi regs for 4 cases since it has only one operand
+ * for source:
+ * - Add to Minus One Extended XO-form ( Ex: addme, addmeo )
+ * - Subtract From Minus One Extended XO-form ( Ex: subfme )
+ * - Add to Zero Extended XO-form ( Ex: addze, addzeo )
+ * - Subtract From Zero Extended XO-form ( Ex: subfze )
+ */
+static int arithmetic__parse(const struct arch *arch __maybe_unused, struct ins_operands *ops,
+               struct map_symbol *ms __maybe_unused, struct disasm_line *dl)
+{
+       int opcode = PPC_OP(dl->raw.raw_insn);
+
+       ops->source.mem_ref = false;
+       if (opcode == 31) {
+               if ((opcode != MINUS_EXT_XO_FORM) && (opcode != SUB_EXT_XO_FORM) &&
+                   (opcode != ADD_ZERO_EXT_XO_FORM) && (opcode != SUB_ZERO_EXT_XO_FORM))
+                       ops->source.multi_regs = true;
+       }
+
+       ops->target.mem_ref = false;
+       ops->target.multi_regs = false;
+
+       return 0;
+}
+
+static const struct ins_ops arithmetic_ops = {
+       .parse     = arithmetic__parse,
+       .scnprintf = arithmetic__scnprintf,
+};
+
+static int load_store__scnprintf(const struct ins *ins, char *bf, size_t size,
+               struct ins_operands *ops, int max_ins_name)
+{
+       return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name,
+                       ops->raw);
+}
+
+/*
+ * Sets the fields: multi_regs and "mem_ref".
+ * "mem_ref" is set for ops->source which is later used to
+ * fill the objdump->memory_ref-char field. This ops is currently
+ * used by powerpc and since binary instruction code is used to
+ * extract opcode, regs and offset, no other parsing is needed here
+ */
+static int load_store__parse(const struct arch *arch __maybe_unused, struct ins_operands *ops,
+               struct map_symbol *ms __maybe_unused, struct disasm_line *dl __maybe_unused)
+{
+       ops->source.mem_ref = true;
+       ops->source.multi_regs = false;
+       /* opcode 31 is of X form */
+       if (PPC_OP(dl->raw.raw_insn) == 31)
+               ops->source.multi_regs = true;
+
+       ops->target.mem_ref = false;
+       ops->target.multi_regs = false;
+
+       return 0;
+}
+
+static const struct ins_ops load_store_ops = {
+       .parse     = load_store__parse,
+       .scnprintf = load_store__scnprintf,
+};
 
 static const struct ins_ops *powerpc__associate_instruction_ops(struct arch *arch, const char *name)
 {
@@ -49,10 +141,6 @@ static const struct ins_ops *powerpc__associate_instruction_ops(struct arch *arc
        return ops;
 }
 
-#define PPC_OP(op)     (((op) >> 26) & 0x3F)
-#define PPC_21_30(R)   (((R) >> 1) & 0x3ff)
-#define PPC_22_30(R)   (((R) >> 1) & 0x1ff)
-
 struct insn_offset {
        const char      *name;
        int             value;
@@ -189,7 +277,7 @@ static int cmp_offset(const void *a, const void *b)
        return (val1->value - val2->value);
 }
 
-static const struct ins_ops *check_ppc_insn(struct disasm_line *dl)
+const struct ins_ops *check_ppc_insn(struct disasm_line *dl)
 {
        int raw_insn = dl->raw.raw_insn;
        int opcode = PPC_OP(raw_insn);
@@ -302,15 +390,16 @@ static void update_insn_state_powerpc(struct type_state *state,
 }
 #endif /* HAVE_LIBDW_SUPPORT */
 
-static int powerpc__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
+int powerpc__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
 {
        if (!arch->initialized) {
                arch->initialized = true;
                arch->associate_instruction_ops = powerpc__associate_instruction_ops;
                arch->objdump.comment_char      = '#';
                annotate_opts.show_asm_raw = true;
-               arch->e_machine = EM_PPC;
-               arch->e_flags = 0;
+#ifdef HAVE_LIBDW_SUPPORT
+               arch->update_insn_state = update_insn_state_powerpc;
+#endif
        }
 
        return 0;
similarity index 91%
rename from tools/perf/arch/riscv64/annotate/instructions.c
rename to tools/perf/util/annotate-arch/annotate-riscv64.c
index a34798864fabe5778f119443517cc92dc1b7b964..15526824037a65291e9b8fce90cc104dd908d45c 100644 (file)
@@ -1,4 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
+#include <string.h>
+#include <linux/compiler.h>
+#include "../disasm.h"
 
 static
 const struct ins_ops *riscv64__associate_ins_ops(struct arch *arch, const char *name)
@@ -21,15 +24,12 @@ const struct ins_ops *riscv64__associate_ins_ops(struct arch *arch, const char *
        return ops;
 }
 
-static
 int riscv64__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
 {
        if (!arch->initialized) {
                arch->associate_instruction_ops = riscv64__associate_ins_ops;
                arch->initialized = true;
                arch->objdump.comment_char = '#';
-               arch->e_machine = EM_RISCV;
-               arch->e_flags = 0;
        }
 
        return 0;
similarity index 91%
rename from tools/perf/arch/s390/annotate/instructions.c
rename to tools/perf/util/annotate-arch/annotate-s390.c
index 1b22e6276e7d323454a743107d0f3eb91ba9c298..81db102b3e1590e1f1c890510f09431e56e6eba0 100644 (file)
@@ -1,5 +1,13 @@
 // SPDX-License-Identifier: GPL-2.0
+#include <string.h>
 #include <linux/compiler.h>
+#include "../debug.h"
+#include "../disasm.h"
+#include "../map.h"
+#include "../maps.h"
+#include "../symbol.h"
+#include "../annotate.h"
+#include "../annotate-data.h"
 
 static int s390_call__parse(const struct arch *arch, struct ins_operands *ops,
                            struct map_symbol *ms,
@@ -49,7 +57,7 @@ static int s390_call__parse(const struct arch *arch, struct ins_operands *ops,
        return 0;
 }
 
-static const struct ins_ops s390_call_ops = {
+const struct ins_ops s390_call_ops = {
        .parse     = s390_call__parse,
        .scnprintf = call__scnprintf,
 };
@@ -159,7 +167,7 @@ static int s390__cpuid_parse(struct arch *arch, char *cpuid)
        return -1;
 }
 
-static int s390__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
+int s390__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
 {
        int err = 0;
 
@@ -170,8 +178,7 @@ static int s390__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
                        if (s390__cpuid_parse(arch, cpuid))
                                err = SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_CPUID_PARSING;
                }
-               arch->e_machine = EM_S390;
-               arch->e_flags = 0;
+               arch->objdump.comment_char = '#';
        }
 
        return err;
similarity index 96%
rename from tools/perf/arch/sparc/annotate/instructions.c
rename to tools/perf/util/annotate-arch/annotate-sparc.c
index a08d8734c883c1c07f40e253e99af8892ac08267..66a0174376dd67e93c922c85bd7be0641e7e34d4 100644 (file)
@@ -1,4 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
+#include <string.h>
+#include <linux/compiler.h>
+#include "../../util/disasm.h"
 
 static int is_branch_cond(const char *cond)
 {
@@ -157,14 +160,12 @@ static const struct ins_ops *sparc__associate_instruction_ops(struct arch *arch,
        return ops;
 }
 
-static int sparc__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
+int sparc__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
 {
        if (!arch->initialized) {
                arch->initialized = true;
                arch->associate_instruction_ops = sparc__associate_instruction_ops;
                arch->objdump.comment_char = '#';
-               arch->e_machine = EM_SPARC;
-               arch->e_flags = 0;
        }
 
        return 0;
similarity index 97%
rename from tools/perf/arch/x86/annotate/instructions.c
rename to tools/perf/util/annotate-arch/annotate-x86.c
index ffca3029388b48a7454f4ad7d7ba2844050e0e11..0c7957fe60da279c2295b74ec53f6d438dbbdca6 100644 (file)
@@ -1,4 +1,16 @@
 // SPDX-License-Identifier: GPL-2.0
+#include <string.h>
+#include <linux/compiler.h>
+#include <assert.h>
+#include <inttypes.h>
+#include "../annotate-data.h"
+#include "../debug.h"
+#include "../disasm.h"
+#include "../dso.h"
+#include "../map.h"
+#include "../string2.h" // strstarts
+#include "../symbol.h"
+
 /*
  * x86 instruction nmemonic table to parse disasm lines for annotate.
  * This table is searched twice - one for exact match and another for
@@ -191,37 +203,6 @@ static int x86__cpuid_parse(struct arch *arch, char *cpuid)
        return -1;
 }
 
-static int x86__annotate_init(struct arch *arch, char *cpuid)
-{
-       int err = 0;
-
-       if (arch->initialized)
-               return 0;
-
-       if (cpuid) {
-               if (x86__cpuid_parse(arch, cpuid))
-                       err = SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_CPUID_PARSING;
-       }
-
-#ifndef NDEBUG
-       {
-               static bool sorted_check;
-
-               if (!sorted_check) {
-                       for (size_t i = 0; i < arch->nr_instructions - 1; i++) {
-                               assert(strcmp(arch->instructions[i].name,
-                                             arch->instructions[i + 1].name) <= 0);
-                       }
-                       sorted_check = true;
-               }
-       }
-#endif
-       arch->e_machine = EM_X86_64;
-       arch->e_flags = 0;
-       arch->initialized = true;
-       return err;
-}
-
 #ifdef HAVE_LIBDW_SUPPORT
 static void update_insn_state_x86(struct type_state *state,
                                  struct data_loc_info *dloc, Dwarf_Die *cu_die,
@@ -795,3 +776,45 @@ retry:
        /* Case 4. memory to memory transfers (not handled for now) */
 }
 #endif
+
+int x86__annotate_init(struct arch *arch, char *cpuid)
+{
+       int err = 0;
+
+       if (arch->initialized)
+               return 0;
+
+       if (cpuid) {
+               if (x86__cpuid_parse(arch, cpuid))
+                       err = SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_CPUID_PARSING;
+       }
+
+       arch->instructions = x86__instructions;
+       arch->nr_instructions = ARRAY_SIZE(x86__instructions);
+#ifndef NDEBUG
+       {
+               static bool sorted_check;
+
+               if (!sorted_check) {
+                       for (size_t i = 0; i < arch->nr_instructions - 1; i++) {
+                               assert(strcmp(arch->instructions[i].name,
+                                             arch->instructions[i + 1].name) <= 0);
+                       }
+                       sorted_check = true;
+               }
+       }
+#endif
+       arch->sorted_instructions = true;
+       arch->objdump.comment_char = '#';
+       arch->objdump.register_char = '%';
+       arch->objdump.memory_ref_char = '(';
+       arch->objdump.imm_char = '$';
+       arch->insn_suffix = "bwlq";
+       arch->e_machine = EM_X86_64;
+       arch->e_flags = 0;
+       arch->initialized = true;
+#ifdef HAVE_LIBDW_SUPPORT
+       arch->update_insn_state = update_insn_state_x86;
+#endif
+       return err;
+}
index b7523256c4ad7d3b713ee7771c6410464ea8e639..845c2d0f39b12f5d07848642793e0c1c1d3fc032 100644 (file)
 static regex_t  file_lineno;
 
 /* These can be referred from the arch-dependent code */
-static const struct ins_ops call_ops;
-static const struct ins_ops dec_ops;
-static const struct ins_ops jump_ops;
-static const struct ins_ops mov_ops;
-static const struct ins_ops nop_ops;
-static const struct ins_ops lock_ops;
-static const struct ins_ops ret_ops;
-static const struct ins_ops load_store_ops;
-static const struct ins_ops arithmetic_ops;
-
-static int jump__scnprintf(const struct ins *ins, char *bf, size_t size,
-                          struct ins_operands *ops, int max_ins_name);
-static int call__scnprintf(const struct ins *ins, char *bf, size_t size,
-                          struct ins_operands *ops, int max_ins_name);
+const struct ins_ops call_ops;
+const struct ins_ops dec_ops;
+const struct ins_ops jump_ops;
+const struct ins_ops mov_ops;
+const struct ins_ops nop_ops;
+const struct ins_ops lock_ops;
+const struct ins_ops ret_ops;
+const struct ins_ops load_store_ops;
+const struct ins_ops arithmetic_ops;
 
 static void ins__sort(struct arch *arch);
 static int disasm_line__parse(char *line, const char **namep, char **rawp);
@@ -86,7 +81,7 @@ grow_from_non_allocated_table:
        goto out_update_instructions;
 }
 
-static int arch__associate_ins_ops(struct arch *arch, const char *name, const struct ins_ops *ops)
+int arch__associate_ins_ops(struct arch *arch, const char *name, const struct ins_ops *ops)
 {
        struct ins *ins;
 
@@ -106,90 +101,66 @@ static int arch__associate_ins_ops(struct arch *arch, const char *name, const st
        return 0;
 }
 
-#include "arch/arc/annotate/instructions.c"
-#include "arch/arm/annotate/instructions.c"
-#include "arch/arm64/annotate/instructions.c"
-#include "arch/csky/annotate/instructions.c"
-#include "arch/loongarch/annotate/instructions.c"
-#include "arch/mips/annotate/instructions.c"
-#include "arch/x86/annotate/instructions.c"
-#include "arch/powerpc/annotate/instructions.c"
-#include "arch/riscv64/annotate/instructions.c"
-#include "arch/s390/annotate/instructions.c"
-#include "arch/sparc/annotate/instructions.c"
-
 static struct arch architectures[] = {
        {
                .name = "arc",
                .init = arc__annotate_init,
+               .e_machine = EM_ARC,
        },
        {
                .name = "arm",
                .init = arm__annotate_init,
+               .e_machine = EM_ARM,
        },
        {
                .name = "arm64",
                .init = arm64__annotate_init,
+               .e_machine = EM_AARCH64,
        },
        {
                .name = "csky",
                .init = csky__annotate_init,
+               .e_machine = EM_CSKY,
+#if defined(__CSKYABIV2__)
+               .e_flags = EF_CSKY_ABIV2,
+#else
+               .e_flags = EF_CSKY_ABIV1,
+#endif
        },
        {
                .name = "mips",
                .init = mips__annotate_init,
-               .objdump = {
-                       .comment_char = '#',
-               },
+               .e_machine = EM_MIPS,
        },
        {
                .name = "x86",
                .init = x86__annotate_init,
-               .instructions = x86__instructions,
-               .nr_instructions = ARRAY_SIZE(x86__instructions),
-               .sorted_instructions = true,
-               .insn_suffix = "bwlq",
-               .objdump =  {
-                       .comment_char = '#',
-                       .register_char = '%',
-                       .memory_ref_char = '(',
-                       .imm_char = '$',
-               },
-#ifdef HAVE_LIBDW_SUPPORT
-               .update_insn_state = update_insn_state_x86,
-#endif
+               .e_machine = EM_X86_64, // TODO: EM_386 too.
        },
        {
                .name = "powerpc",
                .init = powerpc__annotate_init,
-#ifdef HAVE_LIBDW_SUPPORT
-               .update_insn_state = update_insn_state_powerpc,
-#endif
+               .e_machine = EM_PPC, // TODO: EM_PPC64 too.
        },
        {
                .name = "riscv64",
                .init = riscv64__annotate_init,
+               .e_machine = EM_RISCV,
        },
        {
                .name = "s390",
                .init = s390__annotate_init,
-               .objdump =  {
-                       .comment_char = '#',
-               },
+               .e_machine = EM_S390,
        },
        {
                .name = "sparc",
                .init = sparc__annotate_init,
-               .objdump = {
-                       .comment_char = '#',
-               },
+               .e_machine = EM_SPARC,
        },
        {
                .name = "loongarch",
                .init = loongarch__annotate_init,
-               .objdump = {
-                       .comment_char = '#',
-               },
+               .e_machine = EM_LOONGARCH,
        },
 };
 
@@ -248,14 +219,14 @@ static void ins_ops__delete(struct ins_operands *ops)
        zfree(&ops->target.name);
 }
 
-static int ins__raw_scnprintf(const struct ins *ins, char *bf, size_t size,
-                             struct ins_operands *ops, int max_ins_name)
+int ins__raw_scnprintf(const struct ins *ins, char *bf, size_t size,
+                          struct ins_operands *ops, int max_ins_name)
 {
        return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name, ops->raw);
 }
 
-static int ins__scnprintf(const struct ins *ins, char *bf, size_t size,
-                         struct ins_operands *ops, int max_ins_name)
+int ins__scnprintf(const struct ins *ins, char *bf, size_t size,
+                  struct ins_operands *ops, int max_ins_name)
 {
        if (ins->ops->scnprintf)
                return ins->ops->scnprintf(ins, bf, size, ops, max_ins_name);
@@ -326,8 +297,8 @@ indirect_call:
        goto find_target;
 }
 
-static int call__scnprintf(const struct ins *ins, char *bf, size_t size,
-                          struct ins_operands *ops, int max_ins_name)
+int call__scnprintf(const struct ins *ins, char *bf, size_t size,
+                     struct ins_operands *ops, int max_ins_name)
 {
        if (ops->target.sym)
                return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name, ops->target.sym->name);
@@ -341,7 +312,7 @@ static int call__scnprintf(const struct ins *ins, char *bf, size_t size,
        return scnprintf(bf, size, "%-*s *%" PRIx64, max_ins_name, ins->name, ops->target.addr);
 }
 
-static const struct ins_ops call_ops = {
+const struct ins_ops call_ops = {
        .parse     = call__parse,
        .scnprintf = call__scnprintf,
 };
@@ -453,8 +424,8 @@ static int jump__parse(const struct arch *arch, struct ins_operands *ops, struct
        return 0;
 }
 
-static int jump__scnprintf(const struct ins *ins, char *bf, size_t size,
-                          struct ins_operands *ops, int max_ins_name)
+int jump__scnprintf(const struct ins *ins, char *bf, size_t size,
+                     struct ins_operands *ops, int max_ins_name)
 {
        const char *c;
 
@@ -494,7 +465,7 @@ static void jump__delete(struct ins_operands *ops __maybe_unused)
         */
 }
 
-static const struct ins_ops jump_ops = {
+const struct ins_ops jump_ops = {
        .free      = jump__delete,
        .parse     = jump__parse,
        .scnprintf = jump__scnprintf,
@@ -586,7 +557,7 @@ static void lock__delete(struct ins_operands *ops)
        zfree(&ops->target.name);
 }
 
-static const struct ins_ops lock_ops = {
+const struct ins_ops lock_ops = {
        .free      = lock__delete,
        .parse     = lock__parse,
        .scnprintf = lock__scnprintf,
@@ -687,103 +658,19 @@ out_free_source:
        return -1;
 }
 
-static int mov__scnprintf(const struct ins *ins, char *bf, size_t size,
-                          struct ins_operands *ops, int max_ins_name)
+int mov__scnprintf(const struct ins *ins, char *bf, size_t size,
+                    struct ins_operands *ops, int max_ins_name)
 {
        return scnprintf(bf, size, "%-*s %s,%s", max_ins_name, ins->name,
                         ops->source.name ?: ops->source.raw,
                         ops->target.name ?: ops->target.raw);
 }
 
-static const struct ins_ops mov_ops = {
+const struct ins_ops mov_ops = {
        .parse     = mov__parse,
        .scnprintf = mov__scnprintf,
 };
 
-#define PPC_22_30(R)    (((R) >> 1) & 0x1ff)
-#define MINUS_EXT_XO_FORM      234
-#define SUB_EXT_XO_FORM                232
-#define        ADD_ZERO_EXT_XO_FORM    202
-#define        SUB_ZERO_EXT_XO_FORM    200
-
-static int arithmetic__scnprintf(const struct ins *ins, char *bf, size_t size,
-               struct ins_operands *ops, int max_ins_name)
-{
-       return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name,
-                       ops->raw);
-}
-
-/*
- * Sets the fields: multi_regs and "mem_ref".
- * "mem_ref" is set for ops->source which is later used to
- * fill the objdump->memory_ref-char field. This ops is currently
- * used by powerpc and since binary instruction code is used to
- * extract opcode, regs and offset, no other parsing is needed here.
- *
- * Dont set multi regs for 4 cases since it has only one operand
- * for source:
- * - Add to Minus One Extended XO-form ( Ex: addme, addmeo )
- * - Subtract From Minus One Extended XO-form ( Ex: subfme )
- * - Add to Zero Extended XO-form ( Ex: addze, addzeo )
- * - Subtract From Zero Extended XO-form ( Ex: subfze )
- */
-static int arithmetic__parse(const struct arch *arch __maybe_unused, struct ins_operands *ops,
-               struct map_symbol *ms __maybe_unused, struct disasm_line *dl)
-{
-       int opcode = PPC_OP(dl->raw.raw_insn);
-
-       ops->source.mem_ref = false;
-       if (opcode == 31) {
-               if ((opcode != MINUS_EXT_XO_FORM) && (opcode != SUB_EXT_XO_FORM) \
-                               && (opcode != ADD_ZERO_EXT_XO_FORM) && (opcode != SUB_ZERO_EXT_XO_FORM))
-                       ops->source.multi_regs = true;
-       }
-
-       ops->target.mem_ref = false;
-       ops->target.multi_regs = false;
-
-       return 0;
-}
-
-static const struct ins_ops arithmetic_ops = {
-       .parse     = arithmetic__parse,
-       .scnprintf = arithmetic__scnprintf,
-};
-
-static int load_store__scnprintf(const struct ins *ins, char *bf, size_t size,
-               struct ins_operands *ops, int max_ins_name)
-{
-       return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name,
-                       ops->raw);
-}
-
-/*
- * Sets the fields: multi_regs and "mem_ref".
- * "mem_ref" is set for ops->source which is later used to
- * fill the objdump->memory_ref-char field. This ops is currently
- * used by powerpc and since binary instruction code is used to
- * extract opcode, regs and offset, no other parsing is needed here
- */
-static int load_store__parse(const struct arch *arch __maybe_unused, struct ins_operands *ops,
-               struct map_symbol *ms __maybe_unused, struct disasm_line *dl __maybe_unused)
-{
-       ops->source.mem_ref = true;
-       ops->source.multi_regs = false;
-       /* opcode 31 is of X form */
-       if (PPC_OP(dl->raw.raw_insn) == 31)
-               ops->source.multi_regs = true;
-
-       ops->target.mem_ref = false;
-       ops->target.multi_regs = false;
-
-       return 0;
-}
-
-static const struct ins_ops load_store_ops = {
-       .parse     = load_store__parse,
-       .scnprintf = load_store__scnprintf,
-};
-
 static int dec__parse(const struct arch *arch __maybe_unused, struct ins_operands *ops,
                      struct map_symbol *ms __maybe_unused,
                      struct disasm_line *dl __maybe_unused)
@@ -820,7 +707,7 @@ static int dec__scnprintf(const struct ins *ins, char *bf, size_t size,
                         ops->target.name ?: ops->target.raw);
 }
 
-static const struct ins_ops dec_ops = {
+const struct ins_ops dec_ops = {
        .parse     = dec__parse,
        .scnprintf = dec__scnprintf,
 };
@@ -831,11 +718,11 @@ static int nop__scnprintf(const struct ins *ins __maybe_unused, char *bf, size_t
        return scnprintf(bf, size, "%-*s", max_ins_name, "nop");
 }
 
-static const struct ins_ops nop_ops = {
+const struct ins_ops nop_ops = {
        .scnprintf = nop__scnprintf,
 };
 
-static const struct ins_ops ret_ops = {
+const struct ins_ops ret_ops = {
        .scnprintf = ins__raw_scnprintf,
 };
 
index db7f1ee3d8e7d4f470a27e9faaaebfdf4a230d20..83503c5075f9ad7d477b7336c4aa78d7fe882d9c 100644 (file)
@@ -109,6 +109,28 @@ const struct arch *arch__find(const char *name);
 bool arch__is_x86(const struct arch *arch);
 bool arch__is_powerpc(const struct arch *arch);
 
+extern const struct ins_ops call_ops;
+extern const struct ins_ops dec_ops;
+extern const struct ins_ops jump_ops;
+extern const struct ins_ops mov_ops;
+extern const struct ins_ops nop_ops;
+extern const struct ins_ops lock_ops;
+extern const struct ins_ops ret_ops;
+
+int arch__associate_ins_ops(struct arch *arch, const char *name, const struct ins_ops *ops);
+
+int arc__annotate_init(struct arch *arch, char *cpuid);
+int arm__annotate_init(struct arch *arch, char *cpuid);
+int arm64__annotate_init(struct arch *arch, char *cpuid);
+int csky__annotate_init(struct arch *arch, char *cpuid);
+int loongarch__annotate_init(struct arch *arch, char *cpuid);
+int mips__annotate_init(struct arch *arch, char *cpuid);
+int powerpc__annotate_init(struct arch *arch, char *cpuid);
+int riscv64__annotate_init(struct arch *arch, char *cpuid);
+int s390__annotate_init(struct arch *arch, char *cpuid);
+int sparc__annotate_init(struct arch *arch, char *cpuid);
+int x86__annotate_init(struct arch *arch, char *cpuid);
+
 const struct ins_ops *ins__find(const struct arch *arch, const char *name, struct disasm_line *dl);
 
 bool ins__is_call(const struct ins *ins);
@@ -117,12 +139,28 @@ bool ins__is_fused(const struct arch *arch, const char *ins1, const char *ins2);
 bool ins__is_ret(const struct ins *ins);
 bool ins__is_lock(const struct ins *ins);
 
+extern const struct ins_ops s390_call_ops;
+extern const struct ins_ops loongarch_call_ops;
+extern const struct ins_ops loongarch_jump_ops;
+const struct ins_ops *check_ppc_insn(struct disasm_line *dl);
+
 struct disasm_line *disasm_line__new(struct annotate_args *args);
 void disasm_line__free(struct disasm_line *dl);
 
 int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size,
                           bool raw, int max_ins_name);
 
+int ins__raw_scnprintf(const struct ins *ins, char *bf, size_t size,
+                          struct ins_operands *ops, int max_ins_name);
+int ins__scnprintf(const struct ins *ins, char *bf, size_t size,
+                  struct ins_operands *ops, int max_ins_name);
+int call__scnprintf(const struct ins *ins, char *bf, size_t size,
+                   struct ins_operands *ops, int max_ins_name);
+int jump__scnprintf(const struct ins *ins, char *bf, size_t size,
+                   struct ins_operands *ops, int max_ins_name);
+int mov__scnprintf(const struct ins *ins, char *bf, size_t size,
+                  struct ins_operands *ops, int max_ins_name);
+
 int symbol__disassemble(struct symbol *sym, struct annotate_args *args);
 
 char *expand_tabs(char *line, char **storage, size_t *storage_len);