1e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca/************************************************************************** 2e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * 3e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * Copyright 2009-2011 VMware, Inc. 4e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * All Rights Reserved. 5e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * 6e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * Permission is hereby granted, free of charge, to any person obtaining a 7e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * copy of this software and associated documentation files (the 8e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * "Software"), to deal in the Software without restriction, including 9e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * without limitation the rights to use, copy, modify, merge, publish, 10e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * distribute, sub license, and/or sell copies of the Software, and to 11e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * permit persons to whom the Software is furnished to do so, subject to 12e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * the following conditions: 13e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * 14e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * The above copyright notice and this permission notice (including the 15e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * next paragraph) shall be included in all copies or substantial portions 16e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * of the Software. 17e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * 18e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * 26e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca **************************************************************************/ 27e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 2834930facfe11ef6e322c276295ddf884d36de11cJosé Fonseca#include <stddef.h> 2934930facfe11ef6e322c276295ddf884d36de11cJosé Fonseca 30e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#include <llvm-c/Core.h> 31e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#include <llvm/Target/TargetMachine.h> 32e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#include <llvm/Target/TargetInstrInfo.h> 33e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#include <llvm/Support/raw_ostream.h> 34e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#include <llvm/Support/MemoryObject.h> 35eb0dd370945b9e3f5eb548a1a4a8184bb0e604fcVinson Lee 364a468de2d78fc5a9e6de40a9dae09669ec556fc5Tobias Droste#if HAVE_LLVM >= 0x0300 374a468de2d78fc5a9e6de40a9dae09669ec556fc5Tobias Droste#include <llvm/Support/TargetRegistry.h> 384a468de2d78fc5a9e6de40a9dae09669ec556fc5Tobias Droste#else /* HAVE_LLVM < 0x0300 */ 394a468de2d78fc5a9e6de40a9dae09669ec556fc5Tobias Droste#include <llvm/Target/TargetRegistry.h> 404a468de2d78fc5a9e6de40a9dae09669ec556fc5Tobias Droste#endif /* HAVE_LLVM < 0x0300 */ 414a468de2d78fc5a9e6de40a9dae09669ec556fc5Tobias Droste 42eb0dd370945b9e3f5eb548a1a4a8184bb0e604fcVinson Lee#if HAVE_LLVM >= 0x0209 43eb0dd370945b9e3f5eb548a1a4a8184bb0e604fcVinson Lee#include <llvm/Support/Host.h> 444a468de2d78fc5a9e6de40a9dae09669ec556fc5Tobias Droste#else /* HAVE_LLVM < 0x0209 */ 45e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#include <llvm/System/Host.h> 464a468de2d78fc5a9e6de40a9dae09669ec556fc5Tobias Droste#endif /* HAVE_LLVM < 0x0209 */ 47e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 48e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#if HAVE_LLVM >= 0x0207 49e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#include <llvm/MC/MCDisassembler.h> 50e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#include <llvm/MC/MCAsmInfo.h> 51e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#include <llvm/MC/MCInst.h> 52e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#include <llvm/MC/MCInstPrinter.h> 53e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#endif /* HAVE_LLVM >= 0x0207 */ 54563489e5c922481a9a506fc5405a3dacacd6082eJosé Fonseca#if HAVE_LLVM >= 0x0301 55563489e5c922481a9a506fc5405a3dacacd6082eJosé Fonseca#include <llvm/MC/MCRegisterInfo.h> 56563489e5c922481a9a506fc5405a3dacacd6082eJosé Fonseca#endif /* HAVE_LLVM >= 0x0301 */ 57e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 58e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#include "util/u_math.h" 59e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#include "util/u_debug.h" 60e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 61e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#include "lp_bld_debug.h" 62e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 63e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 64e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 65e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca/** 66e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * Check alignment. 67e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * 68e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * It is important that this check is not implemented as a macro or inlined 69e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * function, as the compiler assumptions in respect to alignment of global 70e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * and stack variables would often make the check a no op, defeating the 71e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * whole purpose of the exercise. 72e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 73e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonsecaextern "C" boolean 74e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonsecalp_check_alignment(const void *ptr, unsigned alignment) 75e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca{ 76e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca assert(util_is_power_of_two(alignment)); 77e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca return ((uintptr_t)ptr & (alignment - 1)) == 0; 78e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca} 79e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 80e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 81e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonsecaclass raw_debug_ostream : 82e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca public llvm::raw_ostream 83e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca{ 84c3894bc2d5d5eabdc913d88d1fedc552fef074a5Vinson Leeprivate: 85e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca uint64_t pos; 86e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 87c3894bc2d5d5eabdc913d88d1fedc552fef074a5Vinson Leepublic: 88c3894bc2d5d5eabdc913d88d1fedc552fef074a5Vinson Lee raw_debug_ostream() : pos(0) { } 89c3894bc2d5d5eabdc913d88d1fedc552fef074a5Vinson Lee 90e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca void write_impl(const char *Ptr, size_t Size); 91e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 92e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#if HAVE_LLVM >= 0x207 93a7b8e16dc6fb3e076f0bce9b8c68fdce31837848Vinson Lee uint64_t current_pos() const { return pos; } 94a7b8e16dc6fb3e076f0bce9b8c68fdce31837848Vinson Lee size_t preferred_buffer_size() const { return 512; } 95e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#else 96a7b8e16dc6fb3e076f0bce9b8c68fdce31837848Vinson Lee uint64_t current_pos() { return pos; } 97e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca size_t preferred_buffer_size() { return 512; } 98e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#endif 99e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca}; 100e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 101e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 102e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonsecavoid 103e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonsecaraw_debug_ostream::write_impl(const char *Ptr, size_t Size) 104e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca{ 105e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca if (Size > 0) { 106e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca char *lastPtr = (char *)&Ptr[Size]; 107e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca char last = *lastPtr; 108e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca *lastPtr = 0; 109e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca _debug_printf("%*s", Size, Ptr); 110e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca *lastPtr = last; 111e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca pos += Size; 112e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 113e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca} 114e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 115e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 116e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca/** 117e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * Same as LLVMDumpValue, but through our debugging channels. 118e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 119e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonsecaextern "C" void 120e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonsecalp_debug_dump_value(LLVMValueRef value) 121e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca{ 122e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#if (defined(PIPE_OS_WINDOWS) && !defined(PIPE_CC_MSVC)) || defined(PIPE_OS_EMBDDED) 123e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca raw_debug_ostream os; 124e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca llvm::unwrap(value)->print(os); 125e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca os.flush(); 126e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#else 127e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca LLVMDumpValue(value); 128e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#endif 129e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca} 130e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 131e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 132c27e58c10940a6442705a4399c5100c82c122a6eJosé Fonseca#if HAVE_LLVM >= 0x0207 133e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca/* 134e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * MemoryObject wrapper around a buffer of memory, to be used by MC 135e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * disassembler. 136e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 137e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonsecaclass BufferMemoryObject: 138e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca public llvm::MemoryObject 139e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca{ 140e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonsecaprivate: 141e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca const uint8_t *Bytes; 142e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca uint64_t Length; 143e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonsecapublic: 144e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca BufferMemoryObject(const uint8_t *bytes, uint64_t length) : 145e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca Bytes(bytes), Length(length) 146e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca { 147e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 148e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 149e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca uint64_t getBase() const 150e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca { 151e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca return 0; 152e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 153e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 154e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca uint64_t getExtent() const 155e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca { 156e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca return Length; 157e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 158e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 159e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca int readByte(uint64_t addr, uint8_t *byte) const 160e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca { 161e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca if (addr > getExtent()) 162e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca return -1; 163e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca *byte = Bytes[addr]; 164e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca return 0; 165e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 166e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca}; 167c27e58c10940a6442705a4399c5100c82c122a6eJosé Fonseca#endif /* HAVE_LLVM >= 0x0207 */ 168e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 169e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 170e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca/* 171e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * Disassemble a function, using the LLVM MC disassembler. 172e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * 173e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * See also: 174e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * - http://blog.llvm.org/2010/01/x86-disassembler.html 175e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * - http://blog.llvm.org/2010/04/intro-to-llvm-mc-project.html 176e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 177e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonsecaextern "C" void 178e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonsecalp_disassemble(const void* func) 179e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca{ 180e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#if HAVE_LLVM >= 0x0207 181e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca using namespace llvm; 182e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 183e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca const uint8_t *bytes = (const uint8_t *)func; 184e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 185e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca /* 186e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * Limit disassembly to this extent 187e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 1883469715a8a171512cf9b528702e70393f01c6041José Fonseca const uint64_t extent = 96 * 1024; 189e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 190e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca uint64_t max_pc = 0; 191e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 192e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca /* 193e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * Initialize all used objects. 194e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 195e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 1963031708e648a39d1bb4c0b2b4f8fa80be7619267Christian Inci#if HAVE_LLVM >= 0x0301 1973031708e648a39d1bb4c0b2b4f8fa80be7619267Christian Inci std::string Triple = sys::getDefaultTargetTriple(); 1983031708e648a39d1bb4c0b2b4f8fa80be7619267Christian Inci#else 199e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca std::string Triple = sys::getHostTriple(); 2003031708e648a39d1bb4c0b2b4f8fa80be7619267Christian Inci#endif 201e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 202e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca std::string Error; 203e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca const Target *T = TargetRegistry::lookupTarget(Triple, Error); 204e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 2059228bfb37519e4a03183ec89e82a80f39addeeebVinson Lee#if HAVE_LLVM >= 0x0300 2069228bfb37519e4a03183ec89e82a80f39addeeebVinson Lee OwningPtr<const MCAsmInfo> AsmInfo(T->createMCAsmInfo(Triple)); 2079228bfb37519e4a03183ec89e82a80f39addeeebVinson Lee#else 208e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca OwningPtr<const MCAsmInfo> AsmInfo(T->createAsmInfo(Triple)); 2099228bfb37519e4a03183ec89e82a80f39addeeebVinson Lee#endif 210e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 211e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca if (!AsmInfo) { 212e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca debug_printf("error: no assembly info for target %s\n", Triple.c_str()); 213e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca return; 214e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 215e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 2161795372feec77e62cbe150f5853e063b9e53acd2Tobias Droste#if HAVE_LLVM >= 0x0300 2171795372feec77e62cbe150f5853e063b9e53acd2Tobias Droste const MCSubtargetInfo *STI = T->createMCSubtargetInfo(Triple, sys::getHostCPUName(), ""); 2181795372feec77e62cbe150f5853e063b9e53acd2Tobias Droste OwningPtr<const MCDisassembler> DisAsm(T->createMCDisassembler(*STI)); 2191795372feec77e62cbe150f5853e063b9e53acd2Tobias Droste#else 220e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca OwningPtr<const MCDisassembler> DisAsm(T->createMCDisassembler()); 2211795372feec77e62cbe150f5853e063b9e53acd2Tobias Droste#endif 222e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca if (!DisAsm) { 223e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca debug_printf("error: no disassembler for target %s\n", Triple.c_str()); 224e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca return; 225e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 226e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 227e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca raw_debug_ostream Out; 228e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 22992e29dc5b0474c073b0f05d60629fc6c3decfca4Vinson Lee#if HAVE_LLVM >= 0x0300 23040ae214067673edbda79371969d1730b6194d83eTobias Droste unsigned int AsmPrinterVariant = AsmInfo->getAssemblerDialect(); 23140ae214067673edbda79371969d1730b6194d83eTobias Droste#else 232e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca int AsmPrinterVariant = AsmInfo->getAssemblerDialect(); 23340ae214067673edbda79371969d1730b6194d83eTobias Droste#endif 2341795372feec77e62cbe150f5853e063b9e53acd2Tobias Droste 2351633dcd890d97bd5e4d125d57f2f529f04d14477Vinson Lee#if HAVE_LLVM >= 0x0301 2361633dcd890d97bd5e4d125d57f2f529f04d14477Vinson Lee OwningPtr<const MCRegisterInfo> MRI(T->createMCRegInfo(Triple)); 2371633dcd890d97bd5e4d125d57f2f529f04d14477Vinson Lee if (!MRI) { 2381633dcd890d97bd5e4d125d57f2f529f04d14477Vinson Lee debug_printf("error: no register info for target %s\n", Triple.c_str()); 2391633dcd890d97bd5e4d125d57f2f529f04d14477Vinson Lee return; 2401633dcd890d97bd5e4d125d57f2f529f04d14477Vinson Lee } 2414f513002f65c629576252b34efedf3c8c4531dfdVinson Lee 2424f513002f65c629576252b34efedf3c8c4531dfdVinson Lee OwningPtr<const MCInstrInfo> MII(T->createMCInstrInfo()); 2434f513002f65c629576252b34efedf3c8c4531dfdVinson Lee if (!MII) { 2444f513002f65c629576252b34efedf3c8c4531dfdVinson Lee debug_printf("error: no instruction info for target %s\n", Triple.c_str()); 2454f513002f65c629576252b34efedf3c8c4531dfdVinson Lee return; 2464f513002f65c629576252b34efedf3c8c4531dfdVinson Lee } 2471633dcd890d97bd5e4d125d57f2f529f04d14477Vinson Lee#endif 2481633dcd890d97bd5e4d125d57f2f529f04d14477Vinson Lee 2491633dcd890d97bd5e4d125d57f2f529f04d14477Vinson Lee#if HAVE_LLVM >= 0x0301 2501633dcd890d97bd5e4d125d57f2f529f04d14477Vinson Lee OwningPtr<MCInstPrinter> Printer( 2514f513002f65c629576252b34efedf3c8c4531dfdVinson Lee T->createMCInstPrinter(AsmPrinterVariant, *AsmInfo, *MII, *MRI, *STI)); 2521633dcd890d97bd5e4d125d57f2f529f04d14477Vinson Lee#elif HAVE_LLVM == 0x0300 2531795372feec77e62cbe150f5853e063b9e53acd2Tobias Droste OwningPtr<MCInstPrinter> Printer( 2541795372feec77e62cbe150f5853e063b9e53acd2Tobias Droste T->createMCInstPrinter(AsmPrinterVariant, *AsmInfo, *STI)); 2551795372feec77e62cbe150f5853e063b9e53acd2Tobias Droste#elif HAVE_LLVM >= 0x0208 256e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca OwningPtr<MCInstPrinter> Printer( 257e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca T->createMCInstPrinter(AsmPrinterVariant, *AsmInfo)); 258e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#else 259e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca OwningPtr<MCInstPrinter> Printer( 260e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca T->createMCInstPrinter(AsmPrinterVariant, *AsmInfo, Out)); 261e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#endif 262e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca if (!Printer) { 263e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca debug_printf("error: no instruction printer for target %s\n", Triple.c_str()); 264e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca return; 265e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 266e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 26795aa0e5d84a4f46f2f0809b26f5899b8e39f5afcVinson Lee#if HAVE_LLVM >= 0x0301 26895aa0e5d84a4f46f2f0809b26f5899b8e39f5afcVinson Lee TargetOptions options; 26995aa0e5d84a4f46f2f0809b26f5899b8e39f5afcVinson Lee#if defined(DEBUG) 27095aa0e5d84a4f46f2f0809b26f5899b8e39f5afcVinson Lee options.JITEmitDebugInfo = true; 27195aa0e5d84a4f46f2f0809b26f5899b8e39f5afcVinson Lee#endif 27295aa0e5d84a4f46f2f0809b26f5899b8e39f5afcVinson Lee#if defined(PIPE_ARCH_X86) 27395aa0e5d84a4f46f2f0809b26f5899b8e39f5afcVinson Lee options.StackAlignmentOverride = 4; 27495aa0e5d84a4f46f2f0809b26f5899b8e39f5afcVinson Lee#endif 27595aa0e5d84a4f46f2f0809b26f5899b8e39f5afcVinson Lee#if defined(DEBUG) || defined(PROFILE) 27695aa0e5d84a4f46f2f0809b26f5899b8e39f5afcVinson Lee options.NoFramePointerElim = true; 27795aa0e5d84a4f46f2f0809b26f5899b8e39f5afcVinson Lee#endif 27895aa0e5d84a4f46f2f0809b26f5899b8e39f5afcVinson Lee TargetMachine *TM = T->createTargetMachine(Triple, sys::getHostCPUName(), "", options); 27995aa0e5d84a4f46f2f0809b26f5899b8e39f5afcVinson Lee#elif HAVE_LLVM == 0x0300 280fc98444bd58960e6cab28423365923bc7e7af3e1Gustaw Smolarczyk TargetMachine *TM = T->createTargetMachine(Triple, sys::getHostCPUName(), ""); 281fc98444bd58960e6cab28423365923bc7e7af3e1Gustaw Smolarczyk#else 282fc98444bd58960e6cab28423365923bc7e7af3e1Gustaw Smolarczyk TargetMachine *TM = T->createTargetMachine(Triple, ""); 283fc98444bd58960e6cab28423365923bc7e7af3e1Gustaw Smolarczyk#endif 284fc98444bd58960e6cab28423365923bc7e7af3e1Gustaw Smolarczyk 285e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca const TargetInstrInfo *TII = TM->getInstrInfo(); 286e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 287e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca /* 288e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * Wrap the data in a MemoryObject 289e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 290e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca BufferMemoryObject memoryObject((const uint8_t *)bytes, extent); 291e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 292e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca uint64_t pc; 293e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca pc = 0; 294e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca while (true) { 295e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca MCInst Inst; 296e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca uint64_t Size; 297e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 298e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca /* 299e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * Print address. We use addresses relative to the start of the function, 300e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * so that between runs. 301e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 302e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 303e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca debug_printf("%6lu:\t", (unsigned long)pc); 304e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 305e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca if (!DisAsm->getInstruction(Inst, Size, memoryObject, 306e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca pc, 30751002968c97758c30511eefab1bd1358b8380e15Brian Paul#if HAVE_LLVM >= 0x0300 30851002968c97758c30511eefab1bd1358b8380e15Brian Paul nulls(), nulls())) { 30951002968c97758c30511eefab1bd1358b8380e15Brian Paul#else 31051002968c97758c30511eefab1bd1358b8380e15Brian Paul nulls())) { 31151002968c97758c30511eefab1bd1358b8380e15Brian Paul#endif 312e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca debug_printf("invalid\n"); 313e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca pc += 1; 314e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 315e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 316e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca /* 317e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * Output the bytes in hexidecimal format. 318e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 319e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 320e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca if (0) { 321e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca unsigned i; 322e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca for (i = 0; i < Size; ++i) { 323e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca debug_printf("%02x ", ((const uint8_t*)bytes)[pc + i]); 324e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 325e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca for (; i < 16; ++i) { 326e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca debug_printf(" "); 327e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 328e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 329e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 330e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca /* 331e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * Print the instruction. 332e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 333e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 33451002968c97758c30511eefab1bd1358b8380e15Brian Paul#if HAVE_LLVM >= 0x0300 33551002968c97758c30511eefab1bd1358b8380e15Brian Paul Printer->printInst(&Inst, Out, ""); 33651002968c97758c30511eefab1bd1358b8380e15Brian Paul#elif HAVE_LLVM >= 0x208 337e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca Printer->printInst(&Inst, Out); 338e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#else 339e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca Printer->printInst(&Inst); 340e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#endif 341e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca Out.flush(); 342e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 343e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca /* 344e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * Advance. 345e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 346e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 347e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca pc += Size; 348e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 349b61e56756c2d61a94a8dd90abb4dc83e0c0349aeVinson Lee#if HAVE_LLVM >= 0x0300 350b61e56756c2d61a94a8dd90abb4dc83e0c0349aeVinson Lee const MCInstrDesc &TID = TII->get(Inst.getOpcode()); 351b61e56756c2d61a94a8dd90abb4dc83e0c0349aeVinson Lee#else 352e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca const TargetInstrDesc &TID = TII->get(Inst.getOpcode()); 353b61e56756c2d61a94a8dd90abb4dc83e0c0349aeVinson Lee#endif 354e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 355e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca /* 356e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * Keep track of forward jumps to a nearby address. 357e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 358e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 359e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca if (TID.isBranch()) { 360e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca for (unsigned i = 0; i < Inst.getNumOperands(); ++i) { 361e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca const MCOperand &operand = Inst.getOperand(i); 362e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca if (operand.isImm()) { 363e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca uint64_t jump; 364e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 365e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca /* 366e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * FIXME: Handle both relative and absolute addresses correctly. 367e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * EDInstInfo actually has this info, but operandTypes and 368e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * operandFlags enums are not exposed in the public interface. 369e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 370e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 371e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca if (1) { 372e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca /* 373e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * PC relative addr. 374e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 375e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 376e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca jump = pc + operand.getImm(); 377e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } else { 378e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca /* 379e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * Absolute addr. 380e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 381e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 382e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca jump = (uint64_t)operand.getImm(); 383e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 384e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 385e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca /* 386e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * Output the address relative to the function start, given 387e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * that MC will print the addresses relative the current pc. 388e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 389e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca debug_printf("\t\t; %lu", (unsigned long)jump); 390e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 391e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca /* 392e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * Ignore far jumps given it could be actually a tail return to 393e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * a random address. 394e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 395e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 396e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca if (jump > max_pc && 397e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca jump < extent) { 398e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca max_pc = jump; 399e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 400e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 401e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 402e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 403e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 404e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca debug_printf("\n"); 405e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 406e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca /* 407e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * Stop disassembling on return statements, if there is no record of a 408e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * jump to a successive address. 409e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 410e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 411e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca if (TID.isReturn()) { 412e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca if (pc > max_pc) { 413e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca break; 414e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 415e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 416e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 417e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 418e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca /* 419e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * Print GDB command, useful to verify output. 420e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 421e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 422e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca if (0) { 423e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca debug_printf("disassemble %p %p\n", bytes, bytes + pc); 424e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 425e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 426e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca debug_printf("\n"); 427c27e58c10940a6442705a4399c5100c82c122a6eJosé Fonseca#else /* HAVE_LLVM < 0x0207 */ 428e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca (void)func; 429c27e58c10940a6442705a4399c5100c82c122a6eJosé Fonseca#endif /* HAVE_LLVM < 0x0207 */ 430e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca} 431e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 432