1226633Sdim//===- lib/Support/Disassembler.cpp -----------------------------*- C++ -*-===// 2218885Sdim// 3218885Sdim// The LLVM Compiler Infrastructure 4218885Sdim// 5218885Sdim// This file is distributed under the University of Illinois Open Source 6218885Sdim// License. See LICENSE.TXT for details. 7218885Sdim// 8218885Sdim//===----------------------------------------------------------------------===// 9218885Sdim// 10218885Sdim// This file implements the necessary glue to call external disassembler 11218885Sdim// libraries. 12218885Sdim// 13218885Sdim//===----------------------------------------------------------------------===// 14218885Sdim 15249423Sdim#include "llvm/Support/Disassembler.h" 16218885Sdim#include "llvm/Config/config.h" 17218885Sdim#include <cassert> 18218885Sdim#include <iomanip> 19249423Sdim#include <sstream> 20218885Sdim#include <string> 21218885Sdim 22218885Sdim#if USE_UDIS86 23218885Sdim#include <udis86.h> 24218885Sdim#endif 25218885Sdim 26218885Sdimusing namespace llvm; 27218885Sdim 28218885Sdimbool llvm::sys::hasDisassembler() 29218885Sdim{ 30218885Sdim#if defined (__i386__) || defined (__amd64__) || defined (__x86_64__) 31218885Sdim // We have option to enable udis86 library. 32218885Sdim# if USE_UDIS86 33218885Sdim return true; 34218885Sdim#else 35218885Sdim return false; 36218885Sdim#endif 37218885Sdim#else 38218885Sdim return false; 39218885Sdim#endif 40218885Sdim} 41218885Sdim 42218885Sdimstd::string llvm::sys::disassembleBuffer(uint8_t* start, size_t length, 43218885Sdim uint64_t pc) { 44263508Sdim#if (defined (__i386__) || defined (__amd64__) || defined (__x86_64__)) \ 45263508Sdim && USE_UDIS86 46218885Sdim std::stringstream res; 47218885Sdim 48218885Sdim unsigned bits; 49218885Sdim# if defined(__i386__) 50218885Sdim bits = 32; 51218885Sdim# else 52218885Sdim bits = 64; 53218885Sdim# endif 54218885Sdim 55218885Sdim ud_t ud_obj; 56218885Sdim 57218885Sdim ud_init(&ud_obj); 58218885Sdim ud_set_input_buffer(&ud_obj, start, length); 59218885Sdim ud_set_mode(&ud_obj, bits); 60218885Sdim ud_set_pc(&ud_obj, pc); 61218885Sdim ud_set_syntax(&ud_obj, UD_SYN_ATT); 62218885Sdim 63218885Sdim res << std::setbase(16) 64218885Sdim << std::setw(bits/4); 65218885Sdim 66218885Sdim while (ud_disassemble(&ud_obj)) { 67218885Sdim res << ud_insn_off(&ud_obj) << ":\t" << ud_insn_asm(&ud_obj) << "\n"; 68218885Sdim } 69263508Sdim 70263508Sdim return res.str(); 71218885Sdim#else 72263508Sdim return "No disassembler available. See configure help for options.\n"; 73218885Sdim#endif 74218885Sdim} 75