blob: 27df3a9e2cb7b0d5c45cba03d62143fcccfd9067 [file] [log] [blame]
Daniel Dunbar2c607b62011-10-11 20:02:52 +00001//===- lib/Support/Disassembler.cpp -----------------------------*- C++ -*-===//
Anton Korobeynikovfd58e6e2007-01-23 10:26:08 +00002//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner4ee451d2007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Anton Korobeynikovfd58e6e2007-01-23 10:26:08 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the necessary glue to call external disassembler
11// libraries.
12//
13//===----------------------------------------------------------------------===//
14
Michael J. Spencer1f6efa32010-11-29 18:16:10 +000015#include "llvm/Support/Disassembler.h"
Chandler Carruthd04a8d42012-12-03 16:50:05 +000016#include "llvm/Config/config.h"
Anton Korobeynikovfd58e6e2007-01-23 10:26:08 +000017#include <cassert>
18#include <iomanip>
Anton Korobeynikovfd58e6e2007-01-23 10:26:08 +000019#include <sstream>
Chandler Carruthd04a8d42012-12-03 16:50:05 +000020#include <string>
Anton Korobeynikovfd58e6e2007-01-23 10:26:08 +000021
22#if USE_UDIS86
23#include <udis86.h>
24#endif
25
26using namespace llvm;
27
Dan Gohmana9ad0412009-08-12 22:10:57 +000028bool llvm::sys::hasDisassembler()
Anton Korobeynikovc6551ff2007-03-06 05:32:48 +000029{
30#if defined (__i386__) || defined (__amd64__) || defined (__x86_64__)
31 // We have option to enable udis86 library.
Evan Chengafc0e0a2008-11-04 06:09:38 +000032# if USE_UDIS86
Anton Korobeynikovc6551ff2007-03-06 05:32:48 +000033 return true;
34#else
35 return false;
36#endif
Evan Chengafc0e0a2008-11-04 06:09:38 +000037#else
38 return false;
39#endif
Anton Korobeynikovc6551ff2007-03-06 05:32:48 +000040}
41
Anton Korobeynikovfd58e6e2007-01-23 10:26:08 +000042std::string llvm::sys::disassembleBuffer(uint8_t* start, size_t length,
43 uint64_t pc) {
Duncan Sandsfc6afa92010-06-10 16:23:15 +000044#if (defined (__i386__) || defined (__amd64__) || defined (__x86_64__)) \
45 && USE_UDIS86
Reid Kleckner47cfec02013-08-06 22:51:21 +000046 std::stringstream res;
47
Anton Korobeynikovfd58e6e2007-01-23 10:26:08 +000048 unsigned bits;
49# if defined(__i386__)
50 bits = 32;
51# else
52 bits = 64;
53# endif
Duncan Sandsfc6afa92010-06-10 16:23:15 +000054
Anton Korobeynikovfd58e6e2007-01-23 10:26:08 +000055 ud_t ud_obj;
Duncan Sandsfc6afa92010-06-10 16:23:15 +000056
Anton Korobeynikovfd58e6e2007-01-23 10:26:08 +000057 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);
Duncan Sandsfc6afa92010-06-10 16:23:15 +000062
Anton Korobeynikovfd58e6e2007-01-23 10:26:08 +000063 res << std::setbase(16)
64 << std::setw(bits/4);
Duncan Sandsfc6afa92010-06-10 16:23:15 +000065
Anton Korobeynikovfd58e6e2007-01-23 10:26:08 +000066 while (ud_disassemble(&ud_obj)) {
67 res << ud_insn_off(&ud_obj) << ":\t" << ud_insn_asm(&ud_obj) << "\n";
68 }
Anton Korobeynikovfd58e6e2007-01-23 10:26:08 +000069
70 return res.str();
Reid Kleckner47cfec02013-08-06 22:51:21 +000071#else
72 return "No disassembler available. See configure help for options.\n";
73#endif
Anton Korobeynikovfd58e6e2007-01-23 10:26:08 +000074}