LLDB  mainline
Opcode.cpp
Go to the documentation of this file.
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "lldb/Core/Opcode.h"
10 
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 
21 using namespace lldb;
22 using namespace lldb_private;
23 
24 int Opcode::Dump(Stream *s, uint32_t min_byte_width) {
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::eType64:
42  s->Printf("0x%16.16" PRIx64, m_data.inst64);
43  break;
44 
45  case Opcode::eTypeBytes:
46  for (uint32_t i = 0; i < m_data.inst.length; ++i) {
47  if (i > 0)
48  s->PutChar(' ');
49  s->Printf("%2.2x", m_data.inst.bytes[i]);
50  }
51  break;
52  }
53 
54  uint32_t bytes_written_so_far = s->GetWrittenBytes() - previous_bytes;
55  // Add spaces to make sure bytes display comes out even in case opcodes aren't
56  // all the same size.
57  if (bytes_written_so_far < min_byte_width)
58  s->Printf("%*s", min_byte_width - bytes_written_so_far, "");
59  return s->GetWrittenBytes() - previous_bytes;
60 }
61 
62 lldb::ByteOrder Opcode::GetDataByteOrder() const {
63  if (m_byte_order != eByteOrderInvalid) {
64  return m_byte_order;
65  }
66  switch (m_type) {
67  case Opcode::eTypeInvalid:
68  break;
69  case Opcode::eType8:
70  case Opcode::eType16:
71  case Opcode::eType16_2:
72  case Opcode::eType32:
73  case Opcode::eType64:
74  return endian::InlHostByteOrder();
75  case Opcode::eTypeBytes:
76  break;
77  }
78  return eByteOrderInvalid;
79 }
80 
81 uint32_t Opcode::GetData(DataExtractor &data) const {
82  uint32_t byte_size = GetByteSize();
83  uint8_t swap_buf[8];
84  const void *buf = nullptr;
85 
86  if (byte_size > 0) {
87  if (!GetEndianSwap()) {
88  if (m_type == Opcode::eType16_2) {
89  // 32 bit thumb instruction, we need to sizzle this a bit
90  swap_buf[0] = m_data.inst.bytes[2];
91  swap_buf[1] = m_data.inst.bytes[3];
92  swap_buf[2] = m_data.inst.bytes[0];
93  swap_buf[3] = m_data.inst.bytes[1];
94  buf = swap_buf;
95  } else {
96  buf = GetOpcodeDataBytes();
97  }
98  } else {
99  switch (m_type) {
100  case Opcode::eTypeInvalid:
101  break;
102  case Opcode::eType8:
103  buf = GetOpcodeDataBytes();
104  break;
105  case Opcode::eType16:
106  *(uint16_t *)swap_buf = llvm::ByteSwap_16(m_data.inst16);
107  buf = swap_buf;
108  break;
109  case Opcode::eType16_2:
110  swap_buf[0] = m_data.inst.bytes[1];
111  swap_buf[1] = m_data.inst.bytes[0];
112  swap_buf[2] = m_data.inst.bytes[3];
113  swap_buf[3] = m_data.inst.bytes[2];
114  buf = swap_buf;
115  break;
116  case Opcode::eType32:
117  *(uint32_t *)swap_buf = llvm::ByteSwap_32(m_data.inst32);
118  buf = swap_buf;
119  break;
120  case Opcode::eType64:
121  *(uint32_t *)swap_buf = llvm::ByteSwap_64(m_data.inst64);
122  buf = swap_buf;
123  break;
124  case Opcode::eTypeBytes:
125  buf = GetOpcodeDataBytes();
126  break;
127  }
128  }
129  }
130  if (buf != nullptr) {
131  DataBufferSP buffer_sp;
132 
133  buffer_sp = std::make_shared<DataBufferHeap>(buf, byte_size);
134  data.SetByteOrder(GetDataByteOrder());
135  data.SetData(buffer_sp);
136  return byte_size;
137  }
138  data.Clear();
139  return 0;
140 }
Opcode.h
lldb_private::Stream
Definition: Stream.h:28
lldb_private::DataExtractor::SetData
lldb::offset_t SetData(const void *bytes, lldb::offset_t length, lldb::ByteOrder byte_order)
Set data with a buffer that is caller owned.
Definition: DataExtractor.cpp:225
lldb_private::DataExtractor::SetByteOrder
void SetByteOrder(lldb::ByteOrder byte_order)
Set the byte_order value.
Definition: DataExtractor.h:931
lldb_private::DataExtractor
Definition: DataExtractor.h:48
lldb_private::Stream::PutChar
size_t PutChar(char ch)
Definition: Stream.cpp:104
lldb::eByteOrderInvalid
@ eByteOrderInvalid
Definition: lldb-enumerations.h:139
uint32_t
lldb_private::endian::InlHostByteOrder
lldb::ByteOrder InlHostByteOrder()
Definition: Endian.h:25
uint16_t
DataExtractor.h
lldb_private::Stream::Printf
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:107
lldb-forward.h
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::Stream::GetWrittenBytes
size_t GetWrittenBytes() const
Definition: Stream.h:107
lldb_private::DataExtractor::Clear
void Clear()
Clears the object state.
Definition: DataExtractor.cpp:194
Stream.h
lldb_private::Stream::PutCString
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition: Stream.cpp:63
lldb
Definition: SBAddress.h:15
Endian.h
DataBufferHeap.h
lldb::ByteOrder
ByteOrder
Byte ordering definitions.
Definition: lldb-enumerations.h:138