Opcode.cpp revision 269024
1//===-- Opcode.cpp ----------------------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include "lldb/Core/Opcode.h" 11 12// C Includes 13// C++ Includes 14// Other libraries and framework includes 15#include "llvm/ADT/Triple.h" 16// Project includes 17#include "lldb/Core/ArchSpec.h" 18#include "lldb/Core/DataBufferHeap.h" 19#include "lldb/Core/DataExtractor.h" 20#include "lldb/Core/Stream.h" 21#include "lldb/Host/Endian.h" 22 23 24using namespace lldb; 25using namespace lldb_private; 26 27 28int 29Opcode::Dump (Stream *s, uint32_t min_byte_width) 30{ 31 int bytes_written = 0; 32 switch (m_type) 33 { 34 case Opcode::eTypeInvalid: 35 bytes_written = s->PutCString ("<invalid>"); 36 break; 37 case Opcode::eType8: 38 bytes_written = s->Printf ("0x%2.2x", m_data.inst8); 39 break; 40 case Opcode::eType16: 41 bytes_written = s->Printf ("0x%4.4x", m_data.inst16); 42 break; 43 case Opcode::eType16_2: 44 case Opcode::eType32: 45 bytes_written = s->Printf ("0x%8.8x", m_data.inst32); 46 break; 47 48 case Opcode::eType64: 49 bytes_written = s->Printf ("0x%16.16" PRIx64, m_data.inst64); 50 break; 51 52 case Opcode::eTypeBytes: 53 { 54 for (uint32_t i=0; i<m_data.inst.length; ++i) 55 { 56 if (i > 0) 57 bytes_written += s->PutChar (' '); 58 bytes_written += s->Printf ("%2.2x", m_data.inst.bytes[i]); 59 } 60 } 61 break; 62 } 63 64 // Add spaces to make sure bytes dispay comes out even in case opcodes 65 // aren't all the same size 66 if (bytes_written < min_byte_width) 67 bytes_written = s->Printf ("%*s", min_byte_width - bytes_written, ""); 68 return bytes_written; 69} 70 71lldb::ByteOrder 72Opcode::GetDataByteOrder () const 73{ 74 if (m_byte_order != eByteOrderInvalid) 75 { 76 return m_byte_order; 77 } 78 switch (m_type) 79 { 80 case Opcode::eTypeInvalid: break; 81 case Opcode::eType8: 82 case Opcode::eType16: 83 case Opcode::eType16_2: 84 case Opcode::eType32: 85 case Opcode::eType64: return lldb::endian::InlHostByteOrder(); 86 case Opcode::eTypeBytes: 87 break; 88 } 89 return eByteOrderInvalid; 90} 91 92uint32_t 93Opcode::GetData (DataExtractor &data) const 94{ 95 uint32_t byte_size = GetByteSize (); 96 uint8_t swap_buf[8]; 97 const void *buf = NULL; 98 99 if (byte_size > 0) 100 { 101 if (!GetEndianSwap()) 102 { 103 if (m_type == Opcode::eType16_2) 104 { 105 // 32 bit thumb instruction, we need to sizzle this a bit 106 swap_buf[0] = m_data.inst.bytes[2]; 107 swap_buf[1] = m_data.inst.bytes[3]; 108 swap_buf[2] = m_data.inst.bytes[0]; 109 swap_buf[3] = m_data.inst.bytes[1]; 110 buf = swap_buf; 111 } 112 else 113 { 114 buf = GetOpcodeDataBytes(); 115 } 116 } 117 else 118 { 119 switch (m_type) 120 { 121 case Opcode::eTypeInvalid: 122 break; 123 case Opcode::eType8: 124 buf = GetOpcodeDataBytes(); 125 break; 126 case Opcode::eType16: 127 *(uint16_t *)swap_buf = llvm::ByteSwap_16(m_data.inst16); 128 buf = swap_buf; 129 break; 130 case Opcode::eType16_2: 131 swap_buf[0] = m_data.inst.bytes[1]; 132 swap_buf[1] = m_data.inst.bytes[0]; 133 swap_buf[2] = m_data.inst.bytes[3]; 134 swap_buf[3] = m_data.inst.bytes[2]; 135 buf = swap_buf; 136 break; 137 case Opcode::eType32: 138 *(uint32_t *)swap_buf = llvm::ByteSwap_32(m_data.inst32); 139 buf = swap_buf; 140 break; 141 case Opcode::eType64: 142 *(uint32_t *)swap_buf = llvm::ByteSwap_64(m_data.inst64); 143 buf = swap_buf; 144 break; 145 case Opcode::eTypeBytes: 146 buf = GetOpcodeDataBytes(); 147 break; 148 } 149 } 150 } 151 if (buf) 152 { 153 DataBufferSP buffer_sp; 154 155 buffer_sp.reset (new DataBufferHeap (buf, byte_size)); 156 data.SetByteOrder(GetDataByteOrder()); 157 data.SetData (buffer_sp); 158 return byte_size; 159 } 160 data.Clear(); 161 return 0; 162} 163 164 165 166