//===-- Opcode.cpp ----------------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "lldb/Core/Opcode.h" // C Includes // C++ Includes // Other libraries and framework includes #include "llvm/ADT/Triple.h" // Project includes #include "lldb/Core/ArchSpec.h" #include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/DataExtractor.h" #include "lldb/Core/Stream.h" #include "lldb/Host/Endian.h" using namespace lldb; using namespace lldb_private; int Opcode::Dump (Stream *s, uint32_t min_byte_width) { int bytes_written = 0; switch (m_type) { case Opcode::eTypeInvalid: bytes_written = s->PutCString (""); break; case Opcode::eType8: bytes_written = s->Printf ("0x%2.2x", m_data.inst8); break; case Opcode::eType16: bytes_written = s->Printf ("0x%4.4x", m_data.inst16); break; case Opcode::eType16_2: case Opcode::eType32: bytes_written = s->Printf ("0x%8.8x", m_data.inst32); break; case Opcode::eType64: bytes_written = s->Printf ("0x%16.16" PRIx64, m_data.inst64); break; case Opcode::eTypeBytes: { for (uint32_t i=0; i 0) bytes_written += s->PutChar (' '); bytes_written += s->Printf ("%2.2x", m_data.inst.bytes[i]); } } break; } // Add spaces to make sure bytes dispay comes out even in case opcodes // aren't all the same size if (bytes_written < min_byte_width) bytes_written = s->Printf ("%*s", min_byte_width - bytes_written, ""); return bytes_written; } lldb::ByteOrder Opcode::GetDataByteOrder () const { if (m_byte_order != eByteOrderInvalid) { return m_byte_order; } switch (m_type) { case Opcode::eTypeInvalid: break; case Opcode::eType8: case Opcode::eType16: case Opcode::eType16_2: case Opcode::eType32: case Opcode::eType64: return lldb::endian::InlHostByteOrder(); case Opcode::eTypeBytes: break; } return eByteOrderInvalid; } uint32_t Opcode::GetData (DataExtractor &data) const { uint32_t byte_size = GetByteSize (); uint8_t swap_buf[8]; const void *buf = NULL; if (byte_size > 0) { if (!GetEndianSwap()) { if (m_type == Opcode::eType16_2) { // 32 bit thumb instruction, we need to sizzle this a bit swap_buf[0] = m_data.inst.bytes[2]; swap_buf[1] = m_data.inst.bytes[3]; swap_buf[2] = m_data.inst.bytes[0]; swap_buf[3] = m_data.inst.bytes[1]; buf = swap_buf; } else { buf = GetOpcodeDataBytes(); } } else { switch (m_type) { case Opcode::eTypeInvalid: break; case Opcode::eType8: buf = GetOpcodeDataBytes(); break; case Opcode::eType16: *(uint16_t *)swap_buf = llvm::ByteSwap_16(m_data.inst16); buf = swap_buf; break; case Opcode::eType16_2: swap_buf[0] = m_data.inst.bytes[1]; swap_buf[1] = m_data.inst.bytes[0]; swap_buf[2] = m_data.inst.bytes[3]; swap_buf[3] = m_data.inst.bytes[2]; buf = swap_buf; break; case Opcode::eType32: *(uint32_t *)swap_buf = llvm::ByteSwap_32(m_data.inst32); buf = swap_buf; break; case Opcode::eType64: *(uint32_t *)swap_buf = llvm::ByteSwap_64(m_data.inst64); buf = swap_buf; break; case Opcode::eTypeBytes: buf = GetOpcodeDataBytes(); break; } } } if (buf) { DataBufferSP buffer_sp; buffer_sp.reset (new DataBufferHeap (buf, byte_size)); data.SetByteOrder(GetDataByteOrder()); data.SetData (buffer_sp); return byte_size; } data.Clear(); return 0; }