1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: set ts=8 sts=2 et sw=2 tw=80: 3 */ 4 // Copyright 2007-2008 the V8 project authors. All rights reserved. 5 // Use of this source code is governed by a BSD-style license that can be 6 // found in the LICENSE file. 7 8 #ifndef jit_arm_disasm_Disasm_arm_h 9 #define jit_arm_disasm_Disasm_arm_h 10 11 #ifdef JS_DISASM_ARM 12 13 # include "mozilla/Assertions.h" 14 # include "mozilla/Types.h" 15 16 # include <stdio.h> 17 18 namespace js { 19 namespace jit { 20 namespace disasm { 21 22 typedef unsigned char byte; 23 24 // A reasonable (ie, safe) buffer size for the disassembly of a single 25 // instruction. 26 const int ReasonableBufferSize = 256; 27 28 // Vector as used by the original code to allow for minimal modification. 29 // Functions exactly like a character array with helper methods. 30 template <typename T> 31 class V8Vector { 32 public: V8Vector()33 V8Vector() : start_(nullptr), length_(0) {} V8Vector(T * data,int length)34 V8Vector(T* data, int length) : start_(data), length_(length) { 35 MOZ_ASSERT(length == 0 || (length > 0 && data != nullptr)); 36 } 37 38 // Returns the length of the vector. length()39 int length() const { return length_; } 40 41 // Returns the pointer to the start of the data in the vector. start()42 T* start() const { return start_; } 43 44 // Access individual vector elements - checks bounds in debug mode. 45 T& operator[](int index) const { 46 MOZ_ASSERT(0 <= index && index < length_); 47 return start_[index]; 48 } 49 50 inline V8Vector<T> operator+(int offset) { 51 MOZ_ASSERT(offset < length_); 52 return V8Vector<T>(start_ + offset, length_ - offset); 53 } 54 55 private: 56 T* start_; 57 int length_; 58 }; 59 60 template <typename T, int kSize> 61 class EmbeddedVector : public V8Vector<T> { 62 public: EmbeddedVector()63 EmbeddedVector() : V8Vector<T>(buffer_, kSize) {} 64 EmbeddedVector(T initial_value)65 explicit EmbeddedVector(T initial_value) : V8Vector<T>(buffer_, kSize) { 66 for (int i = 0; i < kSize; ++i) { 67 buffer_[i] = initial_value; 68 } 69 } 70 71 // When copying, make underlying Vector to reference our buffer. EmbeddedVector(const EmbeddedVector & rhs)72 EmbeddedVector(const EmbeddedVector& rhs) : V8Vector<T>(rhs) { 73 MemCopy(buffer_, rhs.buffer_, sizeof(T) * kSize); 74 this->set_start(buffer_); 75 } 76 77 EmbeddedVector& operator=(const EmbeddedVector& rhs) { 78 if (this == &rhs) return *this; 79 V8Vector<T>::operator=(rhs); 80 MemCopy(buffer_, rhs.buffer_, sizeof(T) * kSize); 81 this->set_start(buffer_); 82 return *this; 83 } 84 85 private: 86 T buffer_[kSize]; 87 }; 88 89 // Interface and default implementation for converting addresses and 90 // register-numbers to text. The default implementation is machine 91 // specific. 92 class NameConverter { 93 public: ~NameConverter()94 virtual ~NameConverter() {} 95 virtual const char* NameOfCPURegister(int reg) const; 96 virtual const char* NameOfByteCPURegister(int reg) const; 97 virtual const char* NameOfXMMRegister(int reg) const; 98 virtual const char* NameOfAddress(byte* addr) const; 99 virtual const char* NameOfConstant(byte* addr) const; 100 virtual const char* NameInCode(byte* addr) const; 101 102 protected: 103 EmbeddedVector<char, 128> tmp_buffer_; 104 }; 105 106 // A generic Disassembler interface 107 class Disassembler { 108 public: 109 // Caller deallocates converter. 110 explicit Disassembler(const NameConverter& converter); 111 112 virtual ~Disassembler(); 113 114 // Writes one disassembled instruction into 'buffer' (0-terminated). 115 // Returns the length of the disassembled machine instruction in bytes. 116 int InstructionDecode(V8Vector<char> buffer, uint8_t* instruction); 117 118 // Returns -1 if instruction does not mark the beginning of a constant pool, 119 // or the number of entries in the constant pool beginning here. 120 int ConstantPoolSizeAt(byte* instruction); 121 122 // Write disassembly into specified file 'f' using specified NameConverter 123 // (see constructor). 124 static void Disassemble(FILE* f, uint8_t* begin, uint8_t* end); 125 126 private: 127 const NameConverter& converter_; 128 129 // Disallow implicit constructors. 130 Disassembler() = delete; 131 Disassembler(const Disassembler&) = delete; 132 void operator=(const Disassembler&) = delete; 133 }; 134 135 } // namespace disasm 136 } // namespace jit 137 } // namespace js 138 139 #endif // JS_DISASM_ARM 140 141 #endif // jit_arm_disasm_Disasm_arm_h 142