Path: blob/main/contrib/llvm-project/lldb/source/Core/Opcode.cpp
39587 views
//===-- Opcode.cpp --------------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "lldb/Core/Opcode.h"910#include "lldb/Utility/DataBufferHeap.h"11#include "lldb/Utility/DataExtractor.h"12#include "lldb/Utility/Endian.h"13#include "lldb/Utility/Stream.h"14#include "lldb/lldb-forward.h"1516#include <memory>1718#include <cinttypes>1920using namespace lldb;21using namespace lldb_private;2223int Opcode::Dump(Stream *s, uint32_t min_byte_width) {24const uint32_t previous_bytes = s->GetWrittenBytes();25switch (m_type) {26case Opcode::eTypeInvalid:27s->PutCString("<invalid>");28break;29case Opcode::eType8:30s->Printf("0x%2.2x", m_data.inst8);31break;32case Opcode::eType16:33s->Printf("0x%4.4x", m_data.inst16);34break;35case Opcode::eType16_2:36case Opcode::eType32:37s->Printf("0x%8.8x", m_data.inst32);38break;3940case Opcode::eType64:41s->Printf("0x%16.16" PRIx64, m_data.inst64);42break;4344case Opcode::eTypeBytes:45for (uint32_t i = 0; i < m_data.inst.length; ++i) {46if (i > 0)47s->PutChar(' ');48s->Printf("%2.2x", m_data.inst.bytes[i]);49}50break;51}5253uint32_t bytes_written_so_far = s->GetWrittenBytes() - previous_bytes;54// Add spaces to make sure bytes display comes out even in case opcodes aren't55// all the same size.56if (bytes_written_so_far < min_byte_width)57s->Printf("%*s", min_byte_width - bytes_written_so_far, "");58return s->GetWrittenBytes() - previous_bytes;59}6061lldb::ByteOrder Opcode::GetDataByteOrder() const {62if (m_byte_order != eByteOrderInvalid) {63return m_byte_order;64}65switch (m_type) {66case Opcode::eTypeInvalid:67break;68case Opcode::eType8:69case Opcode::eType16:70case Opcode::eType16_2:71case Opcode::eType32:72case Opcode::eType64:73return endian::InlHostByteOrder();74case Opcode::eTypeBytes:75break;76}77return eByteOrderInvalid;78}7980uint32_t Opcode::GetData(DataExtractor &data) const {81uint32_t byte_size = GetByteSize();82uint8_t swap_buf[8];83const void *buf = nullptr;8485if (byte_size > 0) {86if (!GetEndianSwap()) {87if (m_type == Opcode::eType16_2) {88// 32 bit thumb instruction, we need to sizzle this a bit89swap_buf[0] = m_data.inst.bytes[2];90swap_buf[1] = m_data.inst.bytes[3];91swap_buf[2] = m_data.inst.bytes[0];92swap_buf[3] = m_data.inst.bytes[1];93buf = swap_buf;94} else {95buf = GetOpcodeDataBytes();96}97} else {98switch (m_type) {99case Opcode::eTypeInvalid:100break;101case Opcode::eType8:102buf = GetOpcodeDataBytes();103break;104case Opcode::eType16:105*(uint16_t *)swap_buf = llvm::byteswap<uint16_t>(m_data.inst16);106buf = swap_buf;107break;108case Opcode::eType16_2:109swap_buf[0] = m_data.inst.bytes[1];110swap_buf[1] = m_data.inst.bytes[0];111swap_buf[2] = m_data.inst.bytes[3];112swap_buf[3] = m_data.inst.bytes[2];113buf = swap_buf;114break;115case Opcode::eType32:116*(uint32_t *)swap_buf = llvm::byteswap<uint32_t>(m_data.inst32);117buf = swap_buf;118break;119case Opcode::eType64:120*(uint32_t *)swap_buf = llvm::byteswap<uint64_t>(m_data.inst64);121buf = swap_buf;122break;123case Opcode::eTypeBytes:124buf = GetOpcodeDataBytes();125break;126}127}128}129if (buf != nullptr) {130DataBufferSP buffer_sp;131132buffer_sp = std::make_shared<DataBufferHeap>(buf, byte_size);133data.SetByteOrder(GetDataByteOrder());134data.SetData(buffer_sp);135return byte_size;136}137data.Clear();138return 0;139}140141142