From ca42f2369946bfb090eac8a02a929e0a2682d0d9 Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Sun, 29 Nov 2020 16:51:49 -0300 Subject: [PATCH] also record the binutils histogram patch --- lxo/532/binutils-ppc-insn-histogram.patch | 162 ++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 lxo/532/binutils-ppc-insn-histogram.patch diff --git a/lxo/532/binutils-ppc-insn-histogram.patch b/lxo/532/binutils-ppc-insn-histogram.patch new file mode 100644 index 000000000..18c523ef6 --- /dev/null +++ b/lxo/532/binutils-ppc-insn-histogram.patch @@ -0,0 +1,162 @@ +introduce -M histogram for ppc objdump -d + +From: Alexandre Oliva + +With -M histogram, the disassembler counts the occurrences of each +opcode it encounters, and prints the totals at the end. +--- + opcodes/disassemble.c | 4 ++ + opcodes/ppc-dis.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 98 insertions(+) + +diff --git a/opcodes/disassemble.c b/opcodes/disassemble.c +index 290dcdd100d19..961aeabfc1632 100644 +--- a/opcodes/disassemble.c ++++ b/opcodes/disassemble.c +@@ -763,6 +763,10 @@ disassemble_free_target (struct disassemble_info *info) + #endif + #ifdef ARCH_powerpc + case bfd_arch_powerpc: ++ { ++ extern void ppc_disassemble_free_target (struct disassemble_info *); ++ ppc_disassemble_free_target (info); ++ } + break; + #endif + #ifdef ARCH_riscv +diff --git a/opcodes/ppc-dis.c b/opcodes/ppc-dis.c +index f3c84e06452dc..f5065c40ff663 100644 +--- a/opcodes/ppc-dis.c ++++ b/opcodes/ppc-dis.c +@@ -27,6 +27,7 @@ + #include "opintl.h" + #include "opcode/ppc.h" + #include "libiberty.h" ++#include "hashtab.h" + + /* This file provides several disassembler functions, all of which use + the disassembler interface defined in dis-asm.h. Several functions +@@ -36,12 +37,61 @@ + static int print_insn_powerpc (bfd_vma, struct disassemble_info *, int, + ppc_cpu_t); + ++struct opcode_counter ++{ ++ const struct powerpc_opcode *opcode; ++ size_t count; ++}; ++ ++static hashval_t ++hash_opcode_counter (const void *opcnt) ++{ ++ const struct opcode_counter *oc = (const struct opcode_counter *)opcnt; ++ return htab_hash_pointer (oc->opcode); ++} ++ ++static int ++same_opcode_counter (const void *opcnt1, const void *opcnt2) ++{ ++ const struct opcode_counter *oc1 = (const struct opcode_counter *)opcnt1; ++ const struct opcode_counter *oc2 = (const struct opcode_counter *)opcnt2; ++ return htab_eq_pointer (oc1->opcode, oc2->opcode); ++} ++ + struct dis_private + { + /* Stash the result of parsing disassembler_options here. */ + ppc_cpu_t dialect; ++ ++ /* Counters for encountered opcodes. */ ++ htab_t histogram; + }; + ++static int ++increment_opcode_counter (struct disassemble_info *info, ++ const struct powerpc_opcode *opcode) ++{ ++ struct dis_private *priv = (struct dis_private *) (info->private_data); ++ ++ if (!priv->histogram) ++ return 0; ++ ++ struct opcode_counter oc, *ocp; ++ oc.opcode = opcode; ++ ++ void **ret = htab_find_slot (priv->histogram, &oc, INSERT); ++ ocp = *ret; ++ if (ocp == HTAB_EMPTY_ENTRY) ++ { ++ *ret = ocp = calloc (sizeof (oc), 1); ++ ocp->opcode = opcode; ++ } ++ ++ ocp->count++; ++ ++ return 1; ++} ++ + #define POWERPC_DIALECT(INFO) \ + (((struct dis_private *) ((INFO)->private_data))->dialect) + +@@ -381,6 +431,11 @@ powerpc_init_dialect (struct disassemble_info *info) + dialect |= PPC_OPCODE_64; + else if ((new_cpu = ppc_parse_cpu (dialect, &sticky, opt)) != 0) + dialect = new_cpu; ++ else if (disassembler_options_cmp (opt, "histogram") == 0) ++ priv->histogram = htab_create (17, ++ hash_opcode_counter, ++ same_opcode_counter, ++ free); + else + /* xgettext: c-format */ + opcodes_error_handler (_("warning: ignoring unknown -M%s option"), opt); +@@ -864,6 +919,8 @@ print_insn_powerpc (bfd_vma memaddr, + bfd_boolean skip_optional; + int blanks; + ++ increment_opcode_counter (info, opcode); ++ + (*info->fprintf_func) (info->stream, "%s", opcode->name); + /* gdb fprintf_func doesn't return count printed. */ + blanks = 8 - strlen (opcode->name); +@@ -1013,3 +1070,40 @@ the -M switch:\n")); + } + fprintf (stream, "\n"); + } ++ ++static int ++dump_opcode_histogram (void **ocp, void *info_) ++{ ++ struct opcode_counter *oc = *ocp; ++ struct disassemble_info *info = info_; ++ ++ (*info->fprintf_func) (info->stream, "%8lu %s (%lx)\n", ++ (unsigned long)oc->count, ++ oc->opcode->name, ++ (unsigned long)oc->opcode->opcode); ++ ++ return 1; ++} ++ ++void ppc_disassemble_free_target (struct disassemble_info *info); ++ ++void ++ppc_disassemble_free_target (struct disassemble_info *info) ++{ ++ struct dis_private *priv = (struct dis_private *) (info->private_data); ++ ++ if (priv->histogram) ++ { ++ if (htab_elements (priv->histogram)) ++ { ++ (*info->fprintf_func) (info->stream, "\n\nOpcode histogram\n"); ++ htab_traverse (priv->histogram, dump_opcode_histogram, info); ++ } ++ ++ htab_delete (priv->histogram); ++ priv->histogram = NULL; ++ } ++ ++ free (priv); ++ info->private_data = NULL; ++} -- 2.30.2