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
26using namespace llvm;
27
28bool 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
42std::string llvm::sys::disassembleBuffer(uint8_t* start, size_t length,
43                                         uint64_t pc) {
44#if (defined (__i386__) || defined (__amd64__) || defined (__x86_64__)) \
45  && USE_UDIS86
46  std::stringstream res;
47
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
70  return res.str();
71#else
72  return "No disassembler available. See configure help for options.\n";
73#endif
74}
75