brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.6 KiB · 6c9ced9 Raw
166 lines · cpp
1//===-- Opcode.cpp --------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "lldb/Core/Opcode.h"10 11#include "lldb/Utility/DataBufferHeap.h"12#include "lldb/Utility/DataExtractor.h"13#include "lldb/Utility/Endian.h"14#include "lldb/Utility/Stream.h"15#include "lldb/lldb-forward.h"16 17#include <memory>18 19#include <cinttypes>20 21using namespace lldb;22using namespace lldb_private;23 24int Opcode::Dump(Stream *s, uint32_t min_byte_width) const {25  const uint32_t previous_bytes = s->GetWrittenBytes();26  switch (m_type) {27  case Opcode::eTypeInvalid:28    s->PutCString("<invalid>");29    break;30  case Opcode::eType8:31    s->Printf("0x%2.2x", m_data.inst8);32    break;33  case Opcode::eType16:34    s->Printf("0x%4.4x", m_data.inst16);35    break;36  case Opcode::eType16_2:37  case Opcode::eType32:38    s->Printf("0x%8.8x", m_data.inst32);39    break;40 41  case Opcode::eType16_32Tuples: {42    const bool format_as_words = (m_data.inst.length % 4) == 0;43    uint32_t i = 0;44    while (i < m_data.inst.length) {45      if (i > 0)46        s->PutChar(' ');47      if (format_as_words) {48        // Format as words; print 1 or more UInt32 values.49        s->Printf("%2.2x%2.2x%2.2x%2.2x", m_data.inst.bytes[i + 3],50                  m_data.inst.bytes[i + 2], m_data.inst.bytes[i + 1],51                  m_data.inst.bytes[i + 0]);52        i += 4;53      } else {54        // Format as halfwords; print 1 or more UInt16 values.55        s->Printf("%2.2x%2.2x", m_data.inst.bytes[i + 1],56                  m_data.inst.bytes[i + 0]);57        i += 2;58      }59    }60  } break;61 62  case Opcode::eType64:63    s->Printf("0x%16.16" PRIx64, m_data.inst64);64    break;65 66  case Opcode::eTypeBytes:67    for (uint32_t i = 0; i < m_data.inst.length; ++i) {68      if (i > 0)69        s->PutChar(' ');70      s->Printf("%2.2x", m_data.inst.bytes[i]);71    }72    break;73  }74 75  uint32_t bytes_written_so_far = s->GetWrittenBytes() - previous_bytes;76  // Add spaces to make sure bytes display comes out even in case opcodes aren't77  // all the same size.78  if (bytes_written_so_far < min_byte_width)79    s->Printf("%*s", min_byte_width - bytes_written_so_far, "");80  return s->GetWrittenBytes() - previous_bytes;81}82 83lldb::ByteOrder Opcode::GetDataByteOrder() const {84  if (m_byte_order != eByteOrderInvalid) {85    return m_byte_order;86  }87  switch (m_type) {88  case Opcode::eTypeInvalid:89    break;90  case Opcode::eType8:91  case Opcode::eType16:92  case Opcode::eType16_2:93  case Opcode::eType16_32Tuples:94  case Opcode::eType32:95  case Opcode::eType64:96    return endian::InlHostByteOrder();97  case Opcode::eTypeBytes:98    break;99  }100  return eByteOrderInvalid;101}102 103uint32_t Opcode::GetData(DataExtractor &data) const {104  uint32_t byte_size = GetByteSize();105  uint8_t swap_buf[8];106  const void *buf = nullptr;107 108  if (byte_size > 0) {109    if (!GetEndianSwap()) {110      if (m_type == Opcode::eType16_2) {111        // 32 bit thumb instruction, we need to sizzle this a bit112        swap_buf[0] = m_data.inst.bytes[2];113        swap_buf[1] = m_data.inst.bytes[3];114        swap_buf[2] = m_data.inst.bytes[0];115        swap_buf[3] = m_data.inst.bytes[1];116        buf = swap_buf;117      } else {118        buf = GetOpcodeDataBytes();119      }120    } else {121      switch (m_type) {122      case Opcode::eTypeInvalid:123        break;124      case Opcode::eType8:125        buf = GetOpcodeDataBytes();126        break;127      case Opcode::eType16:128        *(uint16_t *)swap_buf = llvm::byteswap<uint16_t>(m_data.inst16);129        buf = swap_buf;130        break;131      case Opcode::eType16_2:132        swap_buf[0] = m_data.inst.bytes[1];133        swap_buf[1] = m_data.inst.bytes[0];134        swap_buf[2] = m_data.inst.bytes[3];135        swap_buf[3] = m_data.inst.bytes[2];136        buf = swap_buf;137        break;138      case Opcode::eType16_32Tuples:139        buf = GetOpcodeDataBytes();140        break;141      case Opcode::eType32:142        *(uint32_t *)swap_buf = llvm::byteswap<uint32_t>(m_data.inst32);143        buf = swap_buf;144        break;145      case Opcode::eType64:146        *(uint32_t *)swap_buf = llvm::byteswap<uint64_t>(m_data.inst64);147        buf = swap_buf;148        break;149      case Opcode::eTypeBytes:150        buf = GetOpcodeDataBytes();151        break;152      }153    }154  }155  if (buf != nullptr) {156    DataBufferSP buffer_sp;157 158    buffer_sp = std::make_shared<DataBufferHeap>(buf, byte_size);159    data.SetByteOrder(GetDataByteOrder());160    data.SetData(buffer_sp);161    return byte_size;162  }163  data.Clear();164  return 0;165}166