Home | History | Annotate | Download | only in llvm-c-test
      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 #include <string.h>
     22 
     23 static void pprint(int pos, unsigned char *buf, int len, const char *disasm) {
     24   int i;
     25   printf("%04x:  ", pos);
     26   for (i = 0; i < 8; i++) {
     27     if (i < len) {
     28       printf("%02x ", buf[i]);
     29     } else {
     30       printf("   ");
     31     }
     32   }
     33 
     34   printf("   %s\n", disasm);
     35 }
     36 
     37 static void do_disassemble(const char *triple, const char *features,
     38                            unsigned char *buf, int siz) {
     39   LLVMDisasmContextRef D = LLVMCreateDisasmCPUFeatures(triple, "", features,
     40                                                        NULL, 0, NULL, NULL);
     41   char outline[1024];
     42   int pos;
     43 
     44   if (!D) {
     45     printf("ERROR: Couldn't create disassembler for triple %s\n", triple);
     46     return;
     47   }
     48 
     49   pos = 0;
     50   while (pos < siz) {
     51     size_t l = LLVMDisasmInstruction(D, buf + pos, siz - pos, 0, outline,
     52                                      sizeof(outline));
     53     if (!l) {
     54       pprint(pos, buf + pos, 1, "\t???");
     55       pos++;
     56     } else {
     57       pprint(pos, buf + pos, l, outline);
     58       pos += l;
     59     }
     60   }
     61 
     62   LLVMDisasmDispose(D);
     63 }
     64 
     65 static void handle_line(char **tokens, int ntokens) {
     66   unsigned char disbuf[128];
     67   size_t disbuflen = 0;
     68   const char *triple = tokens[0];
     69   const char *features = tokens[1];
     70   int i;
     71 
     72   printf("triple: %s, features: %s\n", triple, features);
     73   if (!strcmp(features, "NULL"))
     74     features = "";
     75 
     76   for (i = 2; i < ntokens; i++) {
     77     disbuf[disbuflen++] = strtol(tokens[i], NULL, 16);
     78     if (disbuflen >= sizeof(disbuf)) {
     79       fprintf(stderr, "Warning: Too long line, truncating\n");
     80       break;
     81     }
     82   }
     83   do_disassemble(triple, features, disbuf, disbuflen);
     84 }
     85 
     86 int llvm_disassemble(void) {
     87   LLVMInitializeAllTargetInfos();
     88   LLVMInitializeAllTargetMCs();
     89   LLVMInitializeAllDisassemblers();
     90 
     91   llvm_tokenize_stdin(handle_line);
     92 
     93   return 0;
     94 }
     95