lp_bld_debug.cpp revision 9228bfb37519e4a03183ec89e82a80f39addeeeb
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 28e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#include <llvm-c/Core.h> 29e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#include <llvm/Target/TargetMachine.h> 30e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#include <llvm/Target/TargetRegistry.h> 31e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#include <llvm/Target/TargetSelect.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 36eb0dd370945b9e3f5eb548a1a4a8184bb0e604fcVinson Lee#if HAVE_LLVM >= 0x0209 37eb0dd370945b9e3f5eb548a1a4a8184bb0e604fcVinson Lee#include <llvm/Support/Host.h> 38eb0dd370945b9e3f5eb548a1a4a8184bb0e604fcVinson Lee#else 39e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#include <llvm/System/Host.h> 40eb0dd370945b9e3f5eb548a1a4a8184bb0e604fcVinson Lee#endif 41e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 42e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#if HAVE_LLVM >= 0x0207 43e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#include <llvm/MC/MCDisassembler.h> 44e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#include <llvm/MC/MCAsmInfo.h> 45e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#include <llvm/MC/MCInst.h> 46e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#include <llvm/MC/MCInstPrinter.h> 47e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#endif /* HAVE_LLVM >= 0x0207 */ 48e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 49e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#include "util/u_math.h" 50e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#include "util/u_debug.h" 51e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 52e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#include "lp_bld_debug.h" 53e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 54e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 55e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 56e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca/** 57e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * Check alignment. 58e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * 59e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * It is important that this check is not implemented as a macro or inlined 60e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * function, as the compiler assumptions in respect to alignment of global 61e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * and stack variables would often make the check a no op, defeating the 62e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * whole purpose of the exercise. 63e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 64e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonsecaextern "C" boolean 65e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonsecalp_check_alignment(const void *ptr, unsigned alignment) 66e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca{ 67e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca assert(util_is_power_of_two(alignment)); 68e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca return ((uintptr_t)ptr & (alignment - 1)) == 0; 69e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca} 70e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 71e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 72e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonsecaclass raw_debug_ostream : 73e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca public llvm::raw_ostream 74e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca{ 75e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca uint64_t pos; 76e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 77e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca void write_impl(const char *Ptr, size_t Size); 78e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca uint64_t current_pos() { return pos; } 79e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca uint64_t current_pos() const { return pos; } 80e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 81e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#if HAVE_LLVM >= 0x207 82e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca uint64_t preferred_buffer_size() { return 512; } 83e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#else 84e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca size_t preferred_buffer_size() { return 512; } 85e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#endif 86e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca}; 87e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 88e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 89e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonsecavoid 90e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonsecaraw_debug_ostream::write_impl(const char *Ptr, size_t Size) 91e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca{ 92e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca if (Size > 0) { 93e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca char *lastPtr = (char *)&Ptr[Size]; 94e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca char last = *lastPtr; 95e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca *lastPtr = 0; 96e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca _debug_printf("%*s", Size, Ptr); 97e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca *lastPtr = last; 98e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca pos += Size; 99e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 100e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca} 101e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 102e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 103e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca/** 104e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * Same as LLVMDumpValue, but through our debugging channels. 105e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 106e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonsecaextern "C" void 107e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonsecalp_debug_dump_value(LLVMValueRef value) 108e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca{ 109e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#if (defined(PIPE_OS_WINDOWS) && !defined(PIPE_CC_MSVC)) || defined(PIPE_OS_EMBDDED) 110e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca raw_debug_ostream os; 111e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca llvm::unwrap(value)->print(os); 112e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca os.flush(); 113e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#else 114e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca LLVMDumpValue(value); 115e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#endif 116e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca} 117e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 118e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 119c27e58c10940a6442705a4399c5100c82c122a6eJosé Fonseca#if HAVE_LLVM >= 0x0207 120e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca/* 121e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * MemoryObject wrapper around a buffer of memory, to be used by MC 122e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * disassembler. 123e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 124e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonsecaclass BufferMemoryObject: 125e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca public llvm::MemoryObject 126e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca{ 127e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonsecaprivate: 128e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca const uint8_t *Bytes; 129e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca uint64_t Length; 130e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonsecapublic: 131e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca BufferMemoryObject(const uint8_t *bytes, uint64_t length) : 132e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca Bytes(bytes), Length(length) 133e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca { 134e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 135e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 136e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca uint64_t getBase() const 137e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca { 138e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca return 0; 139e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 140e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 141e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca uint64_t getExtent() const 142e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca { 143e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca return Length; 144e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 145e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 146e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca int readByte(uint64_t addr, uint8_t *byte) const 147e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca { 148e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca if (addr > getExtent()) 149e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca return -1; 150e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca *byte = Bytes[addr]; 151e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca return 0; 152e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 153e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca}; 154c27e58c10940a6442705a4399c5100c82c122a6eJosé Fonseca#endif /* HAVE_LLVM >= 0x0207 */ 155e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 156e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 157e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca/* 158e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * Disassemble a function, using the LLVM MC disassembler. 159e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * 160e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * See also: 161e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * - http://blog.llvm.org/2010/01/x86-disassembler.html 162e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * - http://blog.llvm.org/2010/04/intro-to-llvm-mc-project.html 163e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 164e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonsecaextern "C" void 165e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonsecalp_disassemble(const void* func) 166e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca{ 167e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#if HAVE_LLVM >= 0x0207 168e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca using namespace llvm; 169e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 170e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca const uint8_t *bytes = (const uint8_t *)func; 171e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 172e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca /* 173e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * Limit disassembly to this extent 174e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 175e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca const uint64_t extent = 0x10000; 176e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 177e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca uint64_t max_pc = 0; 178e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 179e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca /* 180e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * Initialize all used objects. 181e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 182e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 183e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca std::string Triple = sys::getHostTriple(); 184e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 185e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca std::string Error; 186e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca const Target *T = TargetRegistry::lookupTarget(Triple, Error); 187e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 188e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#if HAVE_LLVM >= 0x0208 189e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca InitializeNativeTargetAsmPrinter(); 190e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#else 191e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca InitializeAllAsmPrinters(); 192e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#endif 193e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 194e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca InitializeAllDisassemblers(); 195e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 1969228bfb37519e4a03183ec89e82a80f39addeeebVinson Lee#if HAVE_LLVM >= 0x0300 1979228bfb37519e4a03183ec89e82a80f39addeeebVinson Lee OwningPtr<const MCAsmInfo> AsmInfo(T->createMCAsmInfo(Triple)); 1989228bfb37519e4a03183ec89e82a80f39addeeebVinson Lee#else 199e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca OwningPtr<const MCAsmInfo> AsmInfo(T->createAsmInfo(Triple)); 2009228bfb37519e4a03183ec89e82a80f39addeeebVinson Lee#endif 201e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 202e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca if (!AsmInfo) { 203e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca debug_printf("error: no assembly info for target %s\n", Triple.c_str()); 204e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca return; 205e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 206e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 207e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca OwningPtr<const MCDisassembler> DisAsm(T->createMCDisassembler()); 208e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca if (!DisAsm) { 209e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca debug_printf("error: no disassembler for target %s\n", Triple.c_str()); 210e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca return; 211e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 212e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 213e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca raw_debug_ostream Out; 214e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 21592e29dc5b0474c073b0f05d60629fc6c3decfca4Vinson Lee#if HAVE_LLVM >= 0x0300 21640ae214067673edbda79371969d1730b6194d83eTobias Droste unsigned int AsmPrinterVariant = AsmInfo->getAssemblerDialect(); 21740ae214067673edbda79371969d1730b6194d83eTobias Droste#else 218e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca int AsmPrinterVariant = AsmInfo->getAssemblerDialect(); 21940ae214067673edbda79371969d1730b6194d83eTobias Droste#endif 220fc98444bd58960e6cab28423365923bc7e7af3e1Gustaw Smolarczyk#if HAVE_LLVM >= 0x0208 221e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca OwningPtr<MCInstPrinter> Printer( 222e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca T->createMCInstPrinter(AsmPrinterVariant, *AsmInfo)); 223e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#else 224e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca OwningPtr<MCInstPrinter> Printer( 225e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca T->createMCInstPrinter(AsmPrinterVariant, *AsmInfo, Out)); 226e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#endif 227e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca if (!Printer) { 228e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca debug_printf("error: no instruction printer for target %s\n", Triple.c_str()); 229e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca return; 230e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 231e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 232fc98444bd58960e6cab28423365923bc7e7af3e1Gustaw Smolarczyk#if HAVE_LLVM >= 0x0300 233fc98444bd58960e6cab28423365923bc7e7af3e1Gustaw Smolarczyk TargetMachine *TM = T->createTargetMachine(Triple, sys::getHostCPUName(), ""); 234fc98444bd58960e6cab28423365923bc7e7af3e1Gustaw Smolarczyk#else 235fc98444bd58960e6cab28423365923bc7e7af3e1Gustaw Smolarczyk TargetMachine *TM = T->createTargetMachine(Triple, ""); 236fc98444bd58960e6cab28423365923bc7e7af3e1Gustaw Smolarczyk#endif 237fc98444bd58960e6cab28423365923bc7e7af3e1Gustaw Smolarczyk 238e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca const TargetInstrInfo *TII = TM->getInstrInfo(); 239e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 240e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca /* 241e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * Wrap the data in a MemoryObject 242e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 243e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca BufferMemoryObject memoryObject((const uint8_t *)bytes, extent); 244e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 245e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca uint64_t pc; 246e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca pc = 0; 247e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca while (true) { 248e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca MCInst Inst; 249e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca uint64_t Size; 250e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 251e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca /* 252e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * Print address. We use addresses relative to the start of the function, 253e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * so that between runs. 254e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 255e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 256e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca debug_printf("%6lu:\t", (unsigned long)pc); 257e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 258e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca if (!DisAsm->getInstruction(Inst, Size, memoryObject, 259e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca pc, 260e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca nulls())) { 261e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca debug_printf("invalid\n"); 262e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca pc += 1; 263e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 264e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 265e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca /* 266e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * Output the bytes in hexidecimal format. 267e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 268e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 269e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca if (0) { 270e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca unsigned i; 271e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca for (i = 0; i < Size; ++i) { 272e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca debug_printf("%02x ", ((const uint8_t*)bytes)[pc + i]); 273e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 274e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca for (; i < 16; ++i) { 275e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca debug_printf(" "); 276e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 277e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 278e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 279e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca /* 280e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * Print the instruction. 281e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 282e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 283e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#if HAVE_LLVM >= 0x208 284e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca Printer->printInst(&Inst, Out); 285e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#else 286e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca Printer->printInst(&Inst); 287e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca#endif 288e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca Out.flush(); 289e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 290e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca /* 291e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * Advance. 292e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 293e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 294e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca pc += Size; 295e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 296b61e56756c2d61a94a8dd90abb4dc83e0c0349aeVinson Lee#if HAVE_LLVM >= 0x0300 297b61e56756c2d61a94a8dd90abb4dc83e0c0349aeVinson Lee const MCInstrDesc &TID = TII->get(Inst.getOpcode()); 298b61e56756c2d61a94a8dd90abb4dc83e0c0349aeVinson Lee#else 299e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca const TargetInstrDesc &TID = TII->get(Inst.getOpcode()); 300b61e56756c2d61a94a8dd90abb4dc83e0c0349aeVinson Lee#endif 301e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 302e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca /* 303e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * Keep track of forward jumps to a nearby address. 304e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 305e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 306e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca if (TID.isBranch()) { 307e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca for (unsigned i = 0; i < Inst.getNumOperands(); ++i) { 308e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca const MCOperand &operand = Inst.getOperand(i); 309e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca if (operand.isImm()) { 310e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca uint64_t jump; 311e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 312e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca /* 313e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * FIXME: Handle both relative and absolute addresses correctly. 314e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * EDInstInfo actually has this info, but operandTypes and 315e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * operandFlags enums are not exposed in the public interface. 316e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 317e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 318e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca if (1) { 319e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca /* 320e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * PC relative addr. 321e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 322e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 323e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca jump = pc + operand.getImm(); 324e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } else { 325e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca /* 326e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * Absolute addr. 327e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 328e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 329e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca jump = (uint64_t)operand.getImm(); 330e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 331e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 332e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca /* 333e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * Output the address relative to the function start, given 334e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * that MC will print the addresses relative the current pc. 335e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 336e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca debug_printf("\t\t; %lu", (unsigned long)jump); 337e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 338e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca /* 339e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * Ignore far jumps given it could be actually a tail return to 340e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * a random address. 341e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 342e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 343e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca if (jump > max_pc && 344e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca jump < extent) { 345e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca max_pc = jump; 346e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 347e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 348e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 349e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 350e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 351e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca debug_printf("\n"); 352e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 353e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca /* 354e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * Stop disassembling on return statements, if there is no record of a 355e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * jump to a successive address. 356e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 357e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 358e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca if (TID.isReturn()) { 359e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca if (pc > max_pc) { 360e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca break; 361e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 362e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 363e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 364e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 365e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca /* 366e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca * Print GDB command, useful to verify output. 367e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca */ 368e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 369e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca if (0) { 370e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca debug_printf("disassemble %p %p\n", bytes, bytes + pc); 371e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca } 372e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 373e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca debug_printf("\n"); 374c27e58c10940a6442705a4399c5100c82c122a6eJosé Fonseca#else /* HAVE_LLVM < 0x0207 */ 375e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca (void)func; 376c27e58c10940a6442705a4399c5100c82c122a6eJosé Fonseca#endif /* HAVE_LLVM < 0x0207 */ 377e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca} 378e6314db0ac537695a20feb5fab8d77a30836eccfJosé Fonseca 379