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
--- /dev/null
+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
// 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;
}
// 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,
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;
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:
// 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,
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,
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;
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:
// 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)
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;
}
*
* 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;
return 0;
}
-static const struct ins_ops loongarch_call_ops = {
+const struct ins_ops loongarch_call_ops = {
.parse = loongarch_call__parse,
.scnprintf = call__scnprintf,
};
return 0;
}
-static const struct ins_ops loongarch_jump_ops = {
+const struct ins_ops loongarch_jump_ops = {
.parse = loongarch_jump__parse,
.scnprintf = jump__scnprintf,
};
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;
// 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)
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;
// 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)
{
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;
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);
}
#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;
// 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)
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;
// 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,
return 0;
}
-static const struct ins_ops s390_call_ops = {
+const struct ins_ops s390_call_ops = {
.parse = s390_call__parse,
.scnprintf = call__scnprintf,
};
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;
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;
// 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)
{
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;
// 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
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,
/* 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;
+}
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);
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;
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,
},
};
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);
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);
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,
};
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;
*/
}
-static const struct ins_ops jump_ops = {
+const struct ins_ops jump_ops = {
.free = jump__delete,
.parse = jump__parse,
.scnprintf = jump__scnprintf,
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,
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)
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,
};
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,
};
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);
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);