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