1 //===-- SBData.cpp --------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "lldb/API/SBData.h"
10 #include "lldb/API/SBError.h"
11 #include "lldb/API/SBStream.h"
12 #include "lldb/Utility/Instrumentation.h"
14 #include "lldb/Core/DumpDataExtractor.h"
15 #include "lldb/Utility/DataBufferHeap.h"
16 #include "lldb/Utility/DataExtractor.h"
17 #include "lldb/Utility/Stream.h"
23 using namespace lldb_private
;
25 SBData::SBData() : m_opaque_sp(new DataExtractor()) {
26 LLDB_INSTRUMENT_VA(this);
29 SBData::SBData(const lldb::DataExtractorSP
&data_sp
) : m_opaque_sp(data_sp
) {}
31 SBData::SBData(const SBData
&rhs
) : m_opaque_sp(rhs
.m_opaque_sp
) {
32 LLDB_INSTRUMENT_VA(this, rhs
);
35 const SBData
&SBData::operator=(const SBData
&rhs
) {
36 LLDB_INSTRUMENT_VA(this, rhs
);
39 m_opaque_sp
= rhs
.m_opaque_sp
;
43 SBData::~SBData() = default;
45 void SBData::SetOpaque(const lldb::DataExtractorSP
&data_sp
) {
46 m_opaque_sp
= data_sp
;
49 lldb_private::DataExtractor
*SBData::get() const { return m_opaque_sp
.get(); }
51 lldb_private::DataExtractor
*SBData::operator->() const {
52 return m_opaque_sp
.operator->();
55 lldb::DataExtractorSP
&SBData::operator*() { return m_opaque_sp
; }
57 const lldb::DataExtractorSP
&SBData::operator*() const { return m_opaque_sp
; }
59 bool SBData::IsValid() {
60 LLDB_INSTRUMENT_VA(this);
61 return this->operator bool();
63 SBData::operator bool() const {
64 LLDB_INSTRUMENT_VA(this);
66 return m_opaque_sp
.get() != nullptr;
69 uint8_t SBData::GetAddressByteSize() {
70 LLDB_INSTRUMENT_VA(this);
73 if (m_opaque_sp
.get())
74 value
= m_opaque_sp
->GetAddressByteSize();
78 void SBData::SetAddressByteSize(uint8_t addr_byte_size
) {
79 LLDB_INSTRUMENT_VA(this, addr_byte_size
);
81 if (m_opaque_sp
.get())
82 m_opaque_sp
->SetAddressByteSize(addr_byte_size
);
85 void SBData::Clear() {
86 LLDB_INSTRUMENT_VA(this);
88 if (m_opaque_sp
.get())
92 size_t SBData::GetByteSize() {
93 LLDB_INSTRUMENT_VA(this);
96 if (m_opaque_sp
.get())
97 value
= m_opaque_sp
->GetByteSize();
101 lldb::ByteOrder
SBData::GetByteOrder() {
102 LLDB_INSTRUMENT_VA(this);
104 lldb::ByteOrder value
= eByteOrderInvalid
;
105 if (m_opaque_sp
.get())
106 value
= m_opaque_sp
->GetByteOrder();
110 void SBData::SetByteOrder(lldb::ByteOrder endian
) {
111 LLDB_INSTRUMENT_VA(this, endian
);
113 if (m_opaque_sp
.get())
114 m_opaque_sp
->SetByteOrder(endian
);
117 float SBData::GetFloat(lldb::SBError
&error
, lldb::offset_t offset
) {
118 LLDB_INSTRUMENT_VA(this, error
, offset
);
121 if (!m_opaque_sp
.get()) {
122 error
.SetErrorString("no value to read from");
124 uint32_t old_offset
= offset
;
125 value
= m_opaque_sp
->GetFloat(&offset
);
126 if (offset
== old_offset
)
127 error
.SetErrorString("unable to read data");
132 double SBData::GetDouble(lldb::SBError
&error
, lldb::offset_t offset
) {
133 LLDB_INSTRUMENT_VA(this, error
, offset
);
136 if (!m_opaque_sp
.get()) {
137 error
.SetErrorString("no value to read from");
139 uint32_t old_offset
= offset
;
140 value
= m_opaque_sp
->GetDouble(&offset
);
141 if (offset
== old_offset
)
142 error
.SetErrorString("unable to read data");
147 long double SBData::GetLongDouble(lldb::SBError
&error
, lldb::offset_t offset
) {
148 LLDB_INSTRUMENT_VA(this, error
, offset
);
150 long double value
= 0;
151 if (!m_opaque_sp
.get()) {
152 error
.SetErrorString("no value to read from");
154 uint32_t old_offset
= offset
;
155 value
= m_opaque_sp
->GetLongDouble(&offset
);
156 if (offset
== old_offset
)
157 error
.SetErrorString("unable to read data");
162 lldb::addr_t
SBData::GetAddress(lldb::SBError
&error
, lldb::offset_t offset
) {
163 LLDB_INSTRUMENT_VA(this, error
, offset
);
165 lldb::addr_t value
= 0;
166 if (!m_opaque_sp
.get()) {
167 error
.SetErrorString("no value to read from");
169 uint32_t old_offset
= offset
;
170 value
= m_opaque_sp
->GetAddress(&offset
);
171 if (offset
== old_offset
)
172 error
.SetErrorString("unable to read data");
177 uint8_t SBData::GetUnsignedInt8(lldb::SBError
&error
, lldb::offset_t offset
) {
178 LLDB_INSTRUMENT_VA(this, error
, offset
);
181 if (!m_opaque_sp
.get()) {
182 error
.SetErrorString("no value to read from");
184 uint32_t old_offset
= offset
;
185 value
= m_opaque_sp
->GetU8(&offset
);
186 if (offset
== old_offset
)
187 error
.SetErrorString("unable to read data");
192 uint16_t SBData::GetUnsignedInt16(lldb::SBError
&error
, lldb::offset_t offset
) {
193 LLDB_INSTRUMENT_VA(this, error
, offset
);
196 if (!m_opaque_sp
.get()) {
197 error
.SetErrorString("no value to read from");
199 uint32_t old_offset
= offset
;
200 value
= m_opaque_sp
->GetU16(&offset
);
201 if (offset
== old_offset
)
202 error
.SetErrorString("unable to read data");
207 uint32_t SBData::GetUnsignedInt32(lldb::SBError
&error
, lldb::offset_t offset
) {
208 LLDB_INSTRUMENT_VA(this, error
, offset
);
211 if (!m_opaque_sp
.get()) {
212 error
.SetErrorString("no value to read from");
214 uint32_t old_offset
= offset
;
215 value
= m_opaque_sp
->GetU32(&offset
);
216 if (offset
== old_offset
)
217 error
.SetErrorString("unable to read data");
222 uint64_t SBData::GetUnsignedInt64(lldb::SBError
&error
, lldb::offset_t offset
) {
223 LLDB_INSTRUMENT_VA(this, error
, offset
);
226 if (!m_opaque_sp
.get()) {
227 error
.SetErrorString("no value to read from");
229 uint32_t old_offset
= offset
;
230 value
= m_opaque_sp
->GetU64(&offset
);
231 if (offset
== old_offset
)
232 error
.SetErrorString("unable to read data");
237 int8_t SBData::GetSignedInt8(lldb::SBError
&error
, lldb::offset_t offset
) {
238 LLDB_INSTRUMENT_VA(this, error
, offset
);
241 if (!m_opaque_sp
.get()) {
242 error
.SetErrorString("no value to read from");
244 uint32_t old_offset
= offset
;
245 value
= (int8_t)m_opaque_sp
->GetMaxS64(&offset
, 1);
246 if (offset
== old_offset
)
247 error
.SetErrorString("unable to read data");
252 int16_t SBData::GetSignedInt16(lldb::SBError
&error
, lldb::offset_t offset
) {
253 LLDB_INSTRUMENT_VA(this, error
, offset
);
256 if (!m_opaque_sp
.get()) {
257 error
.SetErrorString("no value to read from");
259 uint32_t old_offset
= offset
;
260 value
= (int16_t)m_opaque_sp
->GetMaxS64(&offset
, 2);
261 if (offset
== old_offset
)
262 error
.SetErrorString("unable to read data");
267 int32_t SBData::GetSignedInt32(lldb::SBError
&error
, lldb::offset_t offset
) {
268 LLDB_INSTRUMENT_VA(this, error
, offset
);
271 if (!m_opaque_sp
.get()) {
272 error
.SetErrorString("no value to read from");
274 uint32_t old_offset
= offset
;
275 value
= (int32_t)m_opaque_sp
->GetMaxS64(&offset
, 4);
276 if (offset
== old_offset
)
277 error
.SetErrorString("unable to read data");
282 int64_t SBData::GetSignedInt64(lldb::SBError
&error
, lldb::offset_t offset
) {
283 LLDB_INSTRUMENT_VA(this, error
, offset
);
286 if (!m_opaque_sp
.get()) {
287 error
.SetErrorString("no value to read from");
289 uint32_t old_offset
= offset
;
290 value
= (int64_t)m_opaque_sp
->GetMaxS64(&offset
, 8);
291 if (offset
== old_offset
)
292 error
.SetErrorString("unable to read data");
297 const char *SBData::GetString(lldb::SBError
&error
, lldb::offset_t offset
) {
298 LLDB_INSTRUMENT_VA(this, error
, offset
);
301 error
.SetErrorString("no value to read from");
305 lldb::offset_t old_offset
= offset
;
306 const char *value
= m_opaque_sp
->GetCStr(&offset
);
307 if (offset
== old_offset
|| value
== nullptr) {
308 error
.SetErrorString("unable to read data");
312 return ConstString(value
).GetCString();
315 bool SBData::GetDescription(lldb::SBStream
&description
,
316 lldb::addr_t base_addr
) {
317 LLDB_INSTRUMENT_VA(this, description
, base_addr
);
319 Stream
&strm
= description
.ref();
322 DumpDataExtractor(*m_opaque_sp
, &strm
, 0, lldb::eFormatBytesWithASCII
, 1,
323 m_opaque_sp
->GetByteSize(), 16, base_addr
, 0, 0);
325 strm
.PutCString("No value");
330 size_t SBData::ReadRawData(lldb::SBError
&error
, lldb::offset_t offset
,
331 void *buf
, size_t size
) {
332 LLDB_INSTRUMENT_VA(this, error
, offset
, buf
, size
);
335 if (!m_opaque_sp
.get()) {
336 error
.SetErrorString("no value to read from");
338 uint32_t old_offset
= offset
;
339 ok
= m_opaque_sp
->GetU8(&offset
, buf
, size
);
340 if ((offset
== old_offset
) || (ok
== nullptr))
341 error
.SetErrorString("unable to read data");
343 return ok
? size
: 0;
346 void SBData::SetData(lldb::SBError
&error
, const void *buf
, size_t size
,
347 lldb::ByteOrder endian
, uint8_t addr_size
) {
348 LLDB_INSTRUMENT_VA(this, error
, buf
, size
, endian
, addr_size
);
350 if (!m_opaque_sp
.get())
351 m_opaque_sp
= std::make_shared
<DataExtractor
>(buf
, size
, endian
, addr_size
);
354 m_opaque_sp
->SetData(buf
, size
, endian
);
355 m_opaque_sp
->SetAddressByteSize(addr_size
);
359 void SBData::SetDataWithOwnership(lldb::SBError
&error
, const void *buf
,
360 size_t size
, lldb::ByteOrder endian
,
362 LLDB_INSTRUMENT_VA(this, error
, buf
, size
, endian
, addr_size
);
364 lldb::DataBufferSP buffer_sp
= std::make_shared
<DataBufferHeap
>(buf
, size
);
366 if (!m_opaque_sp
.get())
367 m_opaque_sp
= std::make_shared
<DataExtractor
>(buf
, size
, endian
, addr_size
);
369 m_opaque_sp
->SetData(buffer_sp
);
370 m_opaque_sp
->SetByteOrder(endian
);
371 m_opaque_sp
->SetAddressByteSize(addr_size
);
375 bool SBData::Append(const SBData
&rhs
) {
376 LLDB_INSTRUMENT_VA(this, rhs
);
379 if (m_opaque_sp
.get() && rhs
.m_opaque_sp
.get())
380 value
= m_opaque_sp
.get()->Append(*rhs
.m_opaque_sp
);
384 lldb::SBData
SBData::CreateDataFromCString(lldb::ByteOrder endian
,
385 uint32_t addr_byte_size
,
387 LLDB_INSTRUMENT_VA(endian
, addr_byte_size
, data
);
389 if (!data
|| !data
[0])
392 uint32_t data_len
= strlen(data
);
394 lldb::DataBufferSP
buffer_sp(new DataBufferHeap(data
, data_len
));
395 lldb::DataExtractorSP
data_sp(
396 new DataExtractor(buffer_sp
, endian
, addr_byte_size
));
403 lldb::SBData
SBData::CreateDataFromUInt64Array(lldb::ByteOrder endian
,
404 uint32_t addr_byte_size
,
407 LLDB_INSTRUMENT_VA(endian
, addr_byte_size
, array
, array_len
);
409 if (!array
|| array_len
== 0)
412 size_t data_len
= array_len
* sizeof(uint64_t);
414 lldb::DataBufferSP
buffer_sp(new DataBufferHeap(array
, data_len
));
415 lldb::DataExtractorSP
data_sp(
416 new DataExtractor(buffer_sp
, endian
, addr_byte_size
));
423 lldb::SBData
SBData::CreateDataFromUInt32Array(lldb::ByteOrder endian
,
424 uint32_t addr_byte_size
,
427 LLDB_INSTRUMENT_VA(endian
, addr_byte_size
, array
, array_len
);
429 if (!array
|| array_len
== 0)
432 size_t data_len
= array_len
* sizeof(uint32_t);
434 lldb::DataBufferSP
buffer_sp(new DataBufferHeap(array
, data_len
));
435 lldb::DataExtractorSP
data_sp(
436 new DataExtractor(buffer_sp
, endian
, addr_byte_size
));
443 lldb::SBData
SBData::CreateDataFromSInt64Array(lldb::ByteOrder endian
,
444 uint32_t addr_byte_size
,
447 LLDB_INSTRUMENT_VA(endian
, addr_byte_size
, array
, array_len
);
449 if (!array
|| array_len
== 0)
452 size_t data_len
= array_len
* sizeof(int64_t);
454 lldb::DataBufferSP
buffer_sp(new DataBufferHeap(array
, data_len
));
455 lldb::DataExtractorSP
data_sp(
456 new DataExtractor(buffer_sp
, endian
, addr_byte_size
));
463 lldb::SBData
SBData::CreateDataFromSInt32Array(lldb::ByteOrder endian
,
464 uint32_t addr_byte_size
,
467 LLDB_INSTRUMENT_VA(endian
, addr_byte_size
, array
, array_len
);
469 if (!array
|| array_len
== 0)
472 size_t data_len
= array_len
* sizeof(int32_t);
474 lldb::DataBufferSP
buffer_sp(new DataBufferHeap(array
, data_len
));
475 lldb::DataExtractorSP
data_sp(
476 new DataExtractor(buffer_sp
, endian
, addr_byte_size
));
483 lldb::SBData
SBData::CreateDataFromDoubleArray(lldb::ByteOrder endian
,
484 uint32_t addr_byte_size
,
487 LLDB_INSTRUMENT_VA(endian
, addr_byte_size
, array
, array_len
);
489 if (!array
|| array_len
== 0)
492 size_t data_len
= array_len
* sizeof(double);
494 lldb::DataBufferSP
buffer_sp(new DataBufferHeap(array
, data_len
));
495 lldb::DataExtractorSP
data_sp(
496 new DataExtractor(buffer_sp
, endian
, addr_byte_size
));
503 bool SBData::SetDataFromCString(const char *data
) {
504 LLDB_INSTRUMENT_VA(this, data
);
510 size_t data_len
= strlen(data
);
512 lldb::DataBufferSP
buffer_sp(new DataBufferHeap(data
, data_len
));
514 if (!m_opaque_sp
.get())
515 m_opaque_sp
= std::make_shared
<DataExtractor
>(buffer_sp
, GetByteOrder(),
516 GetAddressByteSize());
518 m_opaque_sp
->SetData(buffer_sp
);
524 bool SBData::SetDataFromUInt64Array(uint64_t *array
, size_t array_len
) {
525 LLDB_INSTRUMENT_VA(this, array
, array_len
);
527 if (!array
|| array_len
== 0) {
531 size_t data_len
= array_len
* sizeof(uint64_t);
533 lldb::DataBufferSP
buffer_sp(new DataBufferHeap(array
, data_len
));
535 if (!m_opaque_sp
.get())
536 m_opaque_sp
= std::make_shared
<DataExtractor
>(buffer_sp
, GetByteOrder(),
537 GetAddressByteSize());
539 m_opaque_sp
->SetData(buffer_sp
);
545 bool SBData::SetDataFromUInt32Array(uint32_t *array
, size_t array_len
) {
546 LLDB_INSTRUMENT_VA(this, array
, array_len
);
548 if (!array
|| array_len
== 0) {
552 size_t data_len
= array_len
* sizeof(uint32_t);
554 lldb::DataBufferSP
buffer_sp(new DataBufferHeap(array
, data_len
));
556 if (!m_opaque_sp
.get())
557 m_opaque_sp
= std::make_shared
<DataExtractor
>(buffer_sp
, GetByteOrder(),
558 GetAddressByteSize());
560 m_opaque_sp
->SetData(buffer_sp
);
565 bool SBData::SetDataFromSInt64Array(int64_t *array
, size_t array_len
) {
566 LLDB_INSTRUMENT_VA(this, array
, array_len
);
568 if (!array
|| array_len
== 0) {
572 size_t data_len
= array_len
* sizeof(int64_t);
574 lldb::DataBufferSP
buffer_sp(new DataBufferHeap(array
, data_len
));
576 if (!m_opaque_sp
.get())
577 m_opaque_sp
= std::make_shared
<DataExtractor
>(buffer_sp
, GetByteOrder(),
578 GetAddressByteSize());
580 m_opaque_sp
->SetData(buffer_sp
);
585 bool SBData::SetDataFromSInt32Array(int32_t *array
, size_t array_len
) {
586 LLDB_INSTRUMENT_VA(this, array
, array_len
);
588 if (!array
|| array_len
== 0) {
592 size_t data_len
= array_len
* sizeof(int32_t);
594 lldb::DataBufferSP
buffer_sp(new DataBufferHeap(array
, data_len
));
596 if (!m_opaque_sp
.get())
597 m_opaque_sp
= std::make_shared
<DataExtractor
>(buffer_sp
, GetByteOrder(),
598 GetAddressByteSize());
600 m_opaque_sp
->SetData(buffer_sp
);
605 bool SBData::SetDataFromDoubleArray(double *array
, size_t array_len
) {
606 LLDB_INSTRUMENT_VA(this, array
, array_len
);
608 if (!array
|| array_len
== 0) {
612 size_t data_len
= array_len
* sizeof(double);
614 lldb::DataBufferSP
buffer_sp(new DataBufferHeap(array
, data_len
));
616 if (!m_opaque_sp
.get())
617 m_opaque_sp
= std::make_shared
<DataExtractor
>(buffer_sp
, GetByteOrder(),
618 GetAddressByteSize());
620 m_opaque_sp
->SetData(buffer_sp
);