Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Core/Opcode.cpp
39587 views
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
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
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<uint16_t>(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<uint32_t>(m_data.inst32);
118
buf = swap_buf;
119
break;
120
case Opcode::eType64:
121
*(uint32_t *)swap_buf = llvm::byteswap<uint64_t>(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
}
141
142