Home | History | Annotate | Download | only in Support
      1 //===- lib/Support/Disassembler.cpp -----------------------------*- C++ -*-===//
      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 necessary glue to call external disassembler
     11 // libraries.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #include "llvm/Support/Disassembler.h"
     16 #include "llvm/Config/config.h"
     17 #include <cassert>
     18 #include <iomanip>
     19 #include <sstream>
     20 #include <string>
     21 
     22 #if USE_UDIS86
     23 #include <udis86.h>
     24 #endif
     25 
     26 using namespace llvm;
     27 
     28 bool llvm::sys::hasDisassembler()
     29 {
     30 #if defined (__i386__) || defined (__amd64__) || defined (__x86_64__)
     31   // We have option to enable udis86 library.
     32 # if USE_UDIS86
     33   return true;
     34 #else
     35   return false;
     36 #endif
     37 #else
     38   return false;
     39 #endif
     40 }
     41 
     42 std::string llvm::sys::disassembleBuffer(uint8_t* start, size_t length,
     43                                          uint64_t pc) {
     44   std::stringstream res;
     45 
     46 #if (defined (__i386__) || defined (__amd64__) || defined (__x86_64__)) \
     47   && USE_UDIS86
     48   unsigned bits;
     49 # if defined(__i386__)
     50   bits = 32;
     51 # else
     52   bits = 64;
     53 # endif
     54 
     55   ud_t ud_obj;
     56 
     57   ud_init(&ud_obj);
     58   ud_set_input_buffer(&ud_obj, start, length);
     59   ud_set_mode(&ud_obj, bits);
     60   ud_set_pc(&ud_obj, pc);
     61   ud_set_syntax(&ud_obj, UD_SYN_ATT);
     62 
     63   res << std::setbase(16)
     64       << std::setw(bits/4);
     65 
     66   while (ud_disassemble(&ud_obj)) {
     67     res << ud_insn_off(&ud_obj) << ":\t" << ud_insn_asm(&ud_obj) << "\n";
     68   }
     69 #else
     70   res << "No disassembler available. See configure help for options.\n";
     71 #endif
     72 
     73   return res.str();
     74 }
     75