Skip to content

Commit

Permalink
x86: Add verbose option to insn decoder test
Browse files Browse the repository at this point in the history
Add verbose option to insn decoder test. This dumps decoded
instruction when building kernel with V=1.

Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com>
Cc: systemtap <systemtap@sources.redhat.com>
Cc: DLE <dle-develop@lists.sourceforge.net>
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
Cc: Randy Dunlap <rdunlap@xenotime.net>
Cc: Jim Keniston <jkenisto@us.ibm.com>
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
LKML-Reference: <20091116230618.5250.18762.stgit@harusame>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
  • Loading branch information
Masami Hiramatsu authored and Ingo Molnar committed Nov 17, 2009
1 parent 444a2a3 commit d65ff75
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 12 deletions.
9 changes: 8 additions & 1 deletion arch/x86/tools/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
PHONY += posttest

ifeq ($(KBUILD_VERBOSE),1)
postest_verbose = -v
else
postest_verbose =
endif

quiet_cmd_posttest = TEST $@
cmd_posttest = $(OBJDUMP) -d -j .text $(objtree)/vmlinux | awk -f $(srctree)/arch/x86/tools/distill.awk | $(obj)/test_get_len $(CONFIG_64BIT)
cmd_posttest = $(OBJDUMP) -d -j .text $(objtree)/vmlinux | awk -f $(srctree)/arch/x86/tools/distill.awk | $(obj)/test_get_len -$(CONFIG_64BIT) $(posttest_verbose)

posttest: $(obj)/test_get_len vmlinux
$(call cmd,posttest)
Expand Down
74 changes: 63 additions & 11 deletions arch/x86/tools/test_get_len.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>

#define unlikely(cond) (cond)

Expand All @@ -36,11 +37,16 @@
*/

const char *prog;
static int verbose;
static int x86_64;

static void usage(void)
{
fprintf(stderr, "Usage: objdump -d a.out | awk -f distill.awk |"
" %s [y|n](64bit flag)\n", prog);
" %s [-y|-n] [-v] \n", prog);
fprintf(stderr, "\t-y 64bit mode\n");
fprintf(stderr, "\t-n 32bit mode\n");
fprintf(stderr, "\t-v verbose mode\n");
exit(1);
}

Expand All @@ -50,22 +56,66 @@ static void malformed_line(const char *line, int line_nr)
exit(3);
}

static void dump_field(FILE *fp, const char *name, const char *indent,
struct insn_field *field)
{
fprintf(fp, "%s.%s = {\n", indent, name);
fprintf(fp, "%s\t.value = %d, bytes[] = {%x, %x, %x, %x},\n",
indent, field->value, field->bytes[0], field->bytes[1],
field->bytes[2], field->bytes[3]);
fprintf(fp, "%s\t.got = %d, .nbytes = %d},\n", indent,
field->got, field->nbytes);
}

static void dump_insn(FILE *fp, struct insn *insn)
{
fprintf(fp, "Instruction = { \n");
dump_field(fp, "prefixes", "\t", &insn->prefixes);
dump_field(fp, "rex_prefix", "\t", &insn->rex_prefix);
dump_field(fp, "vex_prefix", "\t", &insn->vex_prefix);
dump_field(fp, "opcode", "\t", &insn->opcode);
dump_field(fp, "modrm", "\t", &insn->modrm);
dump_field(fp, "sib", "\t", &insn->sib);
dump_field(fp, "displacement", "\t", &insn->displacement);
dump_field(fp, "immediate1", "\t", &insn->immediate1);
dump_field(fp, "immediate2", "\t", &insn->immediate2);
fprintf(fp, "\t.attr = %x, .opnd_bytes = %d, .addr_bytes = %d,\n",
insn->attr, insn->opnd_bytes, insn->addr_bytes);
fprintf(fp, "\t.length = %d, .x86_64 = %d, .kaddr = %p}\n",
insn->length, insn->x86_64, insn->kaddr);
}

static void parse_args(int argc, char **argv)
{
int c;
prog = argv[0];
while ((c = getopt(argc, argv, "ynv")) != -1) {
switch (c) {
case 'y':
x86_64 = 1;
break;
case 'n':
x86_64 = 0;
break;
case 'v':
verbose = 1;
break;
default:
usage();
}
}
}

#define BUFSIZE 256

int main(int argc, char **argv)
{
char line[BUFSIZE];
unsigned char insn_buf[16];
struct insn insn;
int insns = 0;
int x86_64 = 0;

prog = argv[0];
if (argc > 2)
usage();
int insns = 0, c;

if (argc == 2 && argv[1][0] == 'y')
x86_64 = 1;
parse_args(argc, argv);

while (fgets(line, BUFSIZE, stdin)) {
char copy[BUFSIZE], *s, *tab1, *tab2;
Expand Down Expand Up @@ -97,8 +147,10 @@ int main(int argc, char **argv)
if (insn.length != nb) {
fprintf(stderr, "Error: %s", line);
fprintf(stderr, "Error: objdump says %d bytes, but "
"insn_get_length() says %d (attr:%x)\n", nb,
insn.length, insn.attr);
"insn_get_length() says %d\n", nb,
insn.length);
if (verbose)
dump_insn(stderr, &insn);
exit(2);
}
}
Expand Down

0 comments on commit d65ff75

Please sign in to comment.