Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Utility/DataEncoder.cpp
39587 views
1
//===-- DataEncoder.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/Utility/DataEncoder.h"
10
11
#include "lldb/Utility/DataBufferHeap.h"
12
#include "lldb/Utility/Endian.h"
13
14
#include "llvm/Support/Endian.h"
15
#include "llvm/Support/ErrorHandling.h"
16
17
#include <cstddef>
18
19
#include <cstring>
20
21
using namespace lldb;
22
using namespace lldb_private;
23
using namespace llvm::support::endian;
24
25
DataEncoder::DataEncoder()
26
: m_data_sp(new DataBufferHeap()), m_byte_order(endian::InlHostByteOrder()),
27
m_addr_size(sizeof(void *)) {}
28
29
DataEncoder::DataEncoder(const void *data, uint32_t length, ByteOrder endian,
30
uint8_t addr_size)
31
: m_data_sp(new DataBufferHeap(data, length)), m_byte_order(endian),
32
m_addr_size(addr_size) {}
33
34
DataEncoder::DataEncoder(ByteOrder endian, uint8_t addr_size)
35
: m_data_sp(new DataBufferHeap()), m_byte_order(endian),
36
m_addr_size(addr_size) {}
37
38
DataEncoder::~DataEncoder() = default;
39
40
llvm::ArrayRef<uint8_t> DataEncoder::GetData() const {
41
return llvm::ArrayRef<uint8_t>(m_data_sp->GetBytes(), GetByteSize());
42
}
43
44
size_t DataEncoder::GetByteSize() const { return m_data_sp->GetByteSize(); }
45
46
// Extract a single unsigned char from the binary data and update the offset
47
// pointed to by "offset_ptr".
48
//
49
// RETURNS the byte that was extracted, or zero on failure.
50
uint32_t DataEncoder::PutU8(uint32_t offset, uint8_t value) {
51
if (ValidOffset(offset)) {
52
m_data_sp->GetBytes()[offset] = value;
53
return offset + 1;
54
}
55
return UINT32_MAX;
56
}
57
58
uint32_t DataEncoder::PutU16(uint32_t offset, uint16_t value) {
59
if (ValidOffsetForDataOfSize(offset, sizeof(value))) {
60
if (m_byte_order != endian::InlHostByteOrder())
61
write16be(m_data_sp->GetBytes() + offset, value);
62
else
63
write16le(m_data_sp->GetBytes() + offset, value);
64
65
return offset + sizeof(value);
66
}
67
return UINT32_MAX;
68
}
69
70
uint32_t DataEncoder::PutU32(uint32_t offset, uint32_t value) {
71
if (ValidOffsetForDataOfSize(offset, sizeof(value))) {
72
if (m_byte_order != endian::InlHostByteOrder())
73
write32be(m_data_sp->GetBytes() + offset, value);
74
else
75
write32le(m_data_sp->GetBytes() + offset, value);
76
77
return offset + sizeof(value);
78
}
79
return UINT32_MAX;
80
}
81
82
uint32_t DataEncoder::PutU64(uint32_t offset, uint64_t value) {
83
if (ValidOffsetForDataOfSize(offset, sizeof(value))) {
84
if (m_byte_order != endian::InlHostByteOrder())
85
write64be(m_data_sp->GetBytes() + offset, value);
86
else
87
write64le(m_data_sp->GetBytes() + offset, value);
88
89
return offset + sizeof(value);
90
}
91
return UINT32_MAX;
92
}
93
94
uint32_t DataEncoder::PutUnsigned(uint32_t offset, uint32_t byte_size,
95
uint64_t value) {
96
switch (byte_size) {
97
case 1:
98
return PutU8(offset, value);
99
case 2:
100
return PutU16(offset, value);
101
case 4:
102
return PutU32(offset, value);
103
case 8:
104
return PutU64(offset, value);
105
default:
106
llvm_unreachable("GetMax64 unhandled case!");
107
}
108
return UINT32_MAX;
109
}
110
111
uint32_t DataEncoder::PutData(uint32_t offset, const void *src,
112
uint32_t src_len) {
113
if (src == nullptr || src_len == 0)
114
return offset;
115
116
if (ValidOffsetForDataOfSize(offset, src_len)) {
117
memcpy(m_data_sp->GetBytes() + offset, src, src_len);
118
return offset + src_len;
119
}
120
return UINT32_MAX;
121
}
122
123
uint32_t DataEncoder::PutAddress(uint32_t offset, lldb::addr_t addr) {
124
return PutUnsigned(offset, m_addr_size, addr);
125
}
126
127
uint32_t DataEncoder::PutCString(uint32_t offset, const char *cstr) {
128
if (cstr != nullptr)
129
return PutData(offset, cstr, strlen(cstr) + 1);
130
return UINT32_MAX;
131
}
132
133
void DataEncoder::AppendU8(uint8_t value) {
134
m_data_sp->AppendData(&value, sizeof(value));
135
}
136
137
void DataEncoder::AppendU16(uint16_t value) {
138
uint32_t offset = m_data_sp->GetByteSize();
139
m_data_sp->SetByteSize(m_data_sp->GetByteSize() + sizeof(value));
140
PutU16(offset, value);
141
}
142
143
void DataEncoder::AppendU32(uint32_t value) {
144
uint32_t offset = m_data_sp->GetByteSize();
145
m_data_sp->SetByteSize(m_data_sp->GetByteSize() + sizeof(value));
146
PutU32(offset, value);
147
}
148
149
void DataEncoder::AppendU64(uint64_t value) {
150
uint32_t offset = m_data_sp->GetByteSize();
151
m_data_sp->SetByteSize(m_data_sp->GetByteSize() + sizeof(value));
152
PutU64(offset, value);
153
}
154
155
void DataEncoder::AppendAddress(lldb::addr_t addr) {
156
switch (m_addr_size) {
157
case 4:
158
AppendU32(addr);
159
break;
160
case 8:
161
AppendU64(addr);
162
break;
163
default:
164
llvm_unreachable("AppendAddress unhandled case!");
165
}
166
}
167
168
void DataEncoder::AppendData(llvm::StringRef data) {
169
const char *bytes = data.data();
170
const size_t length = data.size();
171
if (bytes && length > 0)
172
m_data_sp->AppendData(bytes, length);
173
}
174
175
void DataEncoder::AppendData(llvm::ArrayRef<uint8_t> data) {
176
const uint8_t *bytes = data.data();
177
const size_t length = data.size();
178
if (bytes && length > 0)
179
m_data_sp->AppendData(bytes, length);
180
}
181
182
void DataEncoder::AppendCString(llvm::StringRef data) {
183
const char *bytes = data.data();
184
const size_t length = data.size();
185
if (bytes) {
186
if (length > 0)
187
m_data_sp->AppendData(bytes, length);
188
if (length == 0 || bytes[length - 1] != '\0')
189
AppendU8(0);
190
}
191
}
192
193