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