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 24 using namespace lldb; 25 using namespace lldb_private; 26 27 28 int 29 Opcode::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 71 lldb::ByteOrder 72 Opcode::GetDataByteOrder () const 73 { 74 switch (m_type) 75 { 76 case Opcode::eTypeInvalid: break; 77 case Opcode::eType8: 78 case Opcode::eType16: 79 case Opcode::eType16_2: 80 case Opcode::eType32: 81 case Opcode::eType64: return lldb::endian::InlHostByteOrder(); 82 case Opcode::eTypeBytes: 83 break; 84 } 85 return eByteOrderInvalid; 86 } 87 88 uint32_t 89 Opcode::GetData (DataExtractor &data) const 90 { 91 uint32_t byte_size = GetByteSize (); 92 93 DataBufferSP buffer_sp; 94 if (byte_size > 0) 95 { 96 switch (m_type) 97 { 98 case Opcode::eTypeInvalid: 99 break; 100 101 case Opcode::eType8: buffer_sp.reset (new DataBufferHeap (&m_data.inst8, byte_size)); break; 102 case Opcode::eType16: buffer_sp.reset (new DataBufferHeap (&m_data.inst16, byte_size)); break; 103 case Opcode::eType16_2: 104 { 105 // 32 bit thumb instruction, we need to sizzle this a bit 106 uint8_t buf[4]; 107 buf[0] = m_data.inst.bytes[2]; 108 buf[1] = m_data.inst.bytes[3]; 109 buf[2] = m_data.inst.bytes[0]; 110 buf[3] = m_data.inst.bytes[1]; 111 buffer_sp.reset (new DataBufferHeap (buf, byte_size)); 112 } 113 break; 114 case Opcode::eType32: 115 buffer_sp.reset (new DataBufferHeap (&m_data.inst32, byte_size)); 116 break; 117 case Opcode::eType64: buffer_sp.reset (new DataBufferHeap (&m_data.inst64, byte_size)); break; 118 case Opcode::eTypeBytes:buffer_sp.reset (new DataBufferHeap (GetOpcodeBytes(), byte_size)); break; 119 break; 120 } 121 } 122 123 if (buffer_sp) 124 { 125 data.SetByteOrder(GetDataByteOrder()); 126 data.SetData (buffer_sp); 127 return byte_size; 128 } 129 data.Clear(); 130 return 0; 131 } 132 133 134 135