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 if (GetDataByteOrder() == eByteOrderLittle) 45 bytes_written = s->Printf ("0x%4.4x%4.4x", m_data.inst32 & 0xffff, m_data.inst32 >> 16); 46 else 47 bytes_written = s->Printf ("0x%2.2x%2.2x%2.2x%2.2x", (m_data.inst32 >> 16) & 0xff, (m_data.inst32 >> 24), 48 (m_data.inst32 & 0xff), (m_data.inst32 >> 8) & 0xff); 49 break; 50 case Opcode::eType32: 51 bytes_written = s->Printf ("0x%8.8x", m_data.inst32); 52 break; 53 54 case Opcode::eType64: 55 bytes_written = s->Printf ("0x%16.16llx", m_data.inst64); 56 break; 57 58 case Opcode::eTypeBytes: 59 { 60 for (uint32_t i=0; i<m_data.inst.length; ++i) 61 { 62 if (i > 0) 63 bytes_written += s->PutChar (' '); 64 bytes_written += s->Printf ("%2.2x", m_data.inst.bytes[i]); 65 } 66 } 67 break; 68 } 69 70 // Add spaces to make sure bytes dispay comes out even in case opcodes 71 // aren't all the same size 72 if (bytes_written < min_byte_width) 73 bytes_written = s->Printf ("%*s", min_byte_width - bytes_written, ""); 74 return bytes_written; 75 } 76 77 lldb::ByteOrder 78 Opcode::GetDataByteOrder () const 79 { 80 switch (m_type) 81 { 82 case Opcode::eTypeInvalid: break; 83 case Opcode::eType8: 84 case Opcode::eType16: 85 case Opcode::eType16_2: 86 case Opcode::eType32: 87 case Opcode::eType64: return lldb::endian::InlHostByteOrder(); 88 case Opcode::eTypeBytes: 89 break; 90 } 91 return eByteOrderInvalid; 92 } 93 94 uint32_t 95 Opcode::GetData (DataExtractor &data, lldb::AddressClass address_class) const 96 { 97 uint32_t byte_size = GetByteSize (); 98 99 DataBufferSP buffer_sp; 100 if (byte_size > 0) 101 { 102 switch (m_type) 103 { 104 case Opcode::eTypeInvalid: 105 break; 106 107 case Opcode::eType8: buffer_sp.reset (new DataBufferHeap (&m_data.inst8, byte_size)); break; 108 case Opcode::eType16: buffer_sp.reset (new DataBufferHeap (&m_data.inst16, byte_size)); break; 109 case Opcode::eType16_2: // passthrough 110 case Opcode::eType32: buffer_sp.reset (new DataBufferHeap (&m_data.inst32, byte_size)); break; 111 case Opcode::eType64: buffer_sp.reset (new DataBufferHeap (&m_data.inst64, byte_size)); break; 112 case Opcode::eTypeBytes:buffer_sp.reset (new DataBufferHeap (GetOpcodeBytes(), byte_size)); break; 113 break; 114 } 115 } 116 117 if (buffer_sp) 118 { 119 data.SetByteOrder(GetDataByteOrder()); 120 data.SetData (buffer_sp); 121 return byte_size; 122 } 123 data.Clear(); 124 return 0; 125 } 126 127 128 129