LLDB  mainline
DataEncoder.cpp
Go to the documentation of this file.
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 
10 
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 }
lldb::addr_t
uint64_t addr_t
Definition: lldb-types.h:83
DataEncoder.h
uint32_t
lldb_private::endian::InlHostByteOrder
lldb::ByteOrder InlHostByteOrder()
Definition: Endian.h:25
UINT32_MAX
#define UINT32_MAX
Definition: lldb-defines.h:19
uint16_t
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::DataBufferHeap
Definition: DataBufferHeap.h:30
lldb
Definition: SBAddress.h:15
Endian.h
DataBufferHeap.h
lldb::ByteOrder
ByteOrder
Byte ordering definitions.
Definition: lldb-enumerations.h:138