1 /*===-- disassemble.c - tool for testing libLLVM and llvm-c API -----------===*\
2 |* *|
3 |* The LLVM Compiler Infrastructure *|
4 |* *|
5 |* This file is distributed under the University of Illinois Open Source *|
6 |* License. See LICENSE.TXT for details. *|
7 |* *|
8 |*===----------------------------------------------------------------------===*|
9 |* *|
10 |* This file implements the --disassemble command in llvm-c-test. *|
11 |* --disassemble reads lines from stdin, parses them as a triple and hex *|
12 |* machine code, and prints disassembly of the machine code. *|
13 |* *|
14 \*===----------------------------------------------------------------------===*/
15
16 #include "llvm-c-test.h"
17 #include "llvm-c/Disassembler.h"
18 #include "llvm-c/Target.h"
19 #include <stdio.h>
20 #include <stdlib.h>
21
pprint(int pos,unsigned char * buf,int len,const char * disasm)22 static void pprint(int pos, unsigned char *buf, int len, const char *disasm) {
23 int i;
24 printf("%04x: ", pos);
25 for (i = 0; i < 8; i++) {
26 if (i < len) {
27 printf("%02x ", buf[i]);
28 } else {
29 printf(" ");
30 }
31 }
32
33 printf(" %s\n", disasm);
34 }
35
do_disassemble(const char * triple,unsigned char * buf,int siz)36 static void do_disassemble(const char *triple, unsigned char *buf, int siz) {
37 LLVMDisasmContextRef D = LLVMCreateDisasm(triple, NULL, 0, NULL, NULL);
38 char outline[1024];
39 int pos;
40
41 if (!D) {
42 printf("ERROR: Couldn't create disassebler for triple %s\n", triple);
43 return;
44 }
45
46 pos = 0;
47 while (pos < siz) {
48 size_t l = LLVMDisasmInstruction(D, buf + pos, siz - pos, 0, outline,
49 sizeof(outline));
50 if (!l) {
51 pprint(pos, buf + pos, 1, "\t???");
52 pos++;
53 } else {
54 pprint(pos, buf + pos, l, outline);
55 pos += l;
56 }
57 }
58
59 LLVMDisasmDispose(D);
60 }
61
handle_line(char ** tokens,int ntokens)62 static void handle_line(char **tokens, int ntokens) {
63 unsigned char disbuf[128];
64 size_t disbuflen = 0;
65 char *triple = tokens[0];
66 int i;
67
68 printf("triple: %s\n", triple);
69
70 for (i = 1; i < ntokens; i++) {
71 disbuf[disbuflen++] = strtol(tokens[i], NULL, 16);
72 if (disbuflen >= sizeof(disbuf)) {
73 fprintf(stderr, "Warning: Too long line, truncating\n");
74 break;
75 }
76 }
77 do_disassemble(triple, disbuf, disbuflen);
78 }
79
disassemble(void)80 int disassemble(void) {
81 LLVMInitializeAllTargetInfos();
82 LLVMInitializeAllTargetMCs();
83 LLVMInitializeAllDisassemblers();
84
85 tokenize_stdin(handle_line);
86
87 return 0;
88 }
89