624 lines · cpp
1//===-- SBData.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-exception6//7//===----------------------------------------------------------------------===//8 9#include "lldb/API/SBData.h"10#include "lldb/API/SBError.h"11#include "lldb/API/SBStream.h"12#include "lldb/Utility/Instrumentation.h"13 14#include "lldb/Core/DumpDataExtractor.h"15#include "lldb/Utility/DataBufferHeap.h"16#include "lldb/Utility/DataExtractor.h"17#include "lldb/Utility/Stream.h"18 19#include <cinttypes>20#include <memory>21 22using namespace lldb;23using namespace lldb_private;24 25SBData::SBData() : m_opaque_sp(new DataExtractor()) {26 LLDB_INSTRUMENT_VA(this);27}28 29SBData::SBData(const lldb::DataExtractorSP &data_sp) : m_opaque_sp(data_sp) {}30 31SBData::SBData(const SBData &rhs) : m_opaque_sp(rhs.m_opaque_sp) {32 LLDB_INSTRUMENT_VA(this, rhs);33}34 35const SBData &SBData::operator=(const SBData &rhs) {36 LLDB_INSTRUMENT_VA(this, rhs);37 38 if (this != &rhs)39 m_opaque_sp = rhs.m_opaque_sp;40 return *this;41}42 43SBData::~SBData() = default;44 45void SBData::SetOpaque(const lldb::DataExtractorSP &data_sp) {46 m_opaque_sp = data_sp;47}48 49lldb_private::DataExtractor *SBData::get() const { return m_opaque_sp.get(); }50 51lldb_private::DataExtractor *SBData::operator->() const {52 return m_opaque_sp.operator->();53}54 55lldb::DataExtractorSP &SBData::operator*() { return m_opaque_sp; }56 57const lldb::DataExtractorSP &SBData::operator*() const { return m_opaque_sp; }58 59bool SBData::IsValid() {60 LLDB_INSTRUMENT_VA(this);61 return this->operator bool();62}63SBData::operator bool() const {64 LLDB_INSTRUMENT_VA(this);65 66 return m_opaque_sp.get() != nullptr;67}68 69uint8_t SBData::GetAddressByteSize() {70 LLDB_INSTRUMENT_VA(this);71 72 uint8_t value = 0;73 if (m_opaque_sp.get())74 value = m_opaque_sp->GetAddressByteSize();75 return value;76}77 78void SBData::SetAddressByteSize(uint8_t addr_byte_size) {79 LLDB_INSTRUMENT_VA(this, addr_byte_size);80 81 if (m_opaque_sp.get())82 m_opaque_sp->SetAddressByteSize(addr_byte_size);83}84 85void SBData::Clear() {86 LLDB_INSTRUMENT_VA(this);87 88 if (m_opaque_sp.get())89 m_opaque_sp->Clear();90}91 92size_t SBData::GetByteSize() {93 LLDB_INSTRUMENT_VA(this);94 95 size_t value = 0;96 if (m_opaque_sp.get())97 value = m_opaque_sp->GetByteSize();98 return value;99}100 101lldb::ByteOrder SBData::GetByteOrder() {102 LLDB_INSTRUMENT_VA(this);103 104 lldb::ByteOrder value = eByteOrderInvalid;105 if (m_opaque_sp.get())106 value = m_opaque_sp->GetByteOrder();107 return value;108}109 110void SBData::SetByteOrder(lldb::ByteOrder endian) {111 LLDB_INSTRUMENT_VA(this, endian);112 113 if (m_opaque_sp.get())114 m_opaque_sp->SetByteOrder(endian);115}116 117float SBData::GetFloat(lldb::SBError &error, lldb::offset_t offset) {118 LLDB_INSTRUMENT_VA(this, error, offset);119 120 float value = 0;121 if (!m_opaque_sp.get()) {122 error.SetErrorString("no value to read from");123 } else {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");128 }129 return value;130}131 132double SBData::GetDouble(lldb::SBError &error, lldb::offset_t offset) {133 LLDB_INSTRUMENT_VA(this, error, offset);134 135 double value = 0;136 if (!m_opaque_sp.get()) {137 error.SetErrorString("no value to read from");138 } else {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");143 }144 return value;145}146 147long double SBData::GetLongDouble(lldb::SBError &error, lldb::offset_t offset) {148 LLDB_INSTRUMENT_VA(this, error, offset);149 150 long double value = 0;151 if (!m_opaque_sp.get()) {152 error.SetErrorString("no value to read from");153 } else {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");158 }159 return value;160}161 162lldb::addr_t SBData::GetAddress(lldb::SBError &error, lldb::offset_t offset) {163 LLDB_INSTRUMENT_VA(this, error, offset);164 165 lldb::addr_t value = 0;166 if (!m_opaque_sp.get()) {167 error.SetErrorString("no value to read from");168 } else {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");173 }174 return value;175}176 177uint8_t SBData::GetUnsignedInt8(lldb::SBError &error, lldb::offset_t offset) {178 LLDB_INSTRUMENT_VA(this, error, offset);179 180 uint8_t value = 0;181 if (!m_opaque_sp.get()) {182 error.SetErrorString("no value to read from");183 } else {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");188 }189 return value;190}191 192uint16_t SBData::GetUnsignedInt16(lldb::SBError &error, lldb::offset_t offset) {193 LLDB_INSTRUMENT_VA(this, error, offset);194 195 uint16_t value = 0;196 if (!m_opaque_sp.get()) {197 error.SetErrorString("no value to read from");198 } else {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");203 }204 return value;205}206 207uint32_t SBData::GetUnsignedInt32(lldb::SBError &error, lldb::offset_t offset) {208 LLDB_INSTRUMENT_VA(this, error, offset);209 210 uint32_t value = 0;211 if (!m_opaque_sp.get()) {212 error.SetErrorString("no value to read from");213 } else {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");218 }219 return value;220}221 222uint64_t SBData::GetUnsignedInt64(lldb::SBError &error, lldb::offset_t offset) {223 LLDB_INSTRUMENT_VA(this, error, offset);224 225 uint64_t value = 0;226 if (!m_opaque_sp.get()) {227 error.SetErrorString("no value to read from");228 } else {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");233 }234 return value;235}236 237int8_t SBData::GetSignedInt8(lldb::SBError &error, lldb::offset_t offset) {238 LLDB_INSTRUMENT_VA(this, error, offset);239 240 int8_t value = 0;241 if (!m_opaque_sp.get()) {242 error.SetErrorString("no value to read from");243 } else {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");248 }249 return value;250}251 252int16_t SBData::GetSignedInt16(lldb::SBError &error, lldb::offset_t offset) {253 LLDB_INSTRUMENT_VA(this, error, offset);254 255 int16_t value = 0;256 if (!m_opaque_sp.get()) {257 error.SetErrorString("no value to read from");258 } else {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");263 }264 return value;265}266 267int32_t SBData::GetSignedInt32(lldb::SBError &error, lldb::offset_t offset) {268 LLDB_INSTRUMENT_VA(this, error, offset);269 270 int32_t value = 0;271 if (!m_opaque_sp.get()) {272 error.SetErrorString("no value to read from");273 } else {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");278 }279 return value;280}281 282int64_t SBData::GetSignedInt64(lldb::SBError &error, lldb::offset_t offset) {283 LLDB_INSTRUMENT_VA(this, error, offset);284 285 int64_t value = 0;286 if (!m_opaque_sp.get()) {287 error.SetErrorString("no value to read from");288 } else {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");293 }294 return value;295}296 297const char *SBData::GetString(lldb::SBError &error, lldb::offset_t offset) {298 LLDB_INSTRUMENT_VA(this, error, offset);299 300 if (!m_opaque_sp) {301 error.SetErrorString("no value to read from");302 return nullptr;303 }304 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");309 return nullptr;310 }311 312 return ConstString(value).GetCString();313}314 315bool SBData::GetDescription(lldb::SBStream &description,316 lldb::addr_t base_addr) {317 LLDB_INSTRUMENT_VA(this, description, base_addr);318 319 Stream &strm = description.ref();320 321 if (m_opaque_sp) {322 DumpDataExtractor(*m_opaque_sp, &strm, 0, lldb::eFormatBytesWithASCII, 1,323 m_opaque_sp->GetByteSize(), 16, base_addr, 0, 0);324 } else325 strm.PutCString("No value");326 327 return true;328}329 330size_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);333 334 void *ok = nullptr;335 if (!m_opaque_sp.get()) {336 error.SetErrorString("no value to read from");337 } else {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");342 }343 return ok ? size : 0;344}345 346void 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);349 350 if (!m_opaque_sp.get())351 m_opaque_sp = std::make_shared<DataExtractor>(buf, size, endian, addr_size);352 else353 {354 m_opaque_sp->SetData(buf, size, endian);355 m_opaque_sp->SetAddressByteSize(addr_size);356 }357}358 359void SBData::SetDataWithOwnership(lldb::SBError &error, const void *buf,360 size_t size, lldb::ByteOrder endian,361 uint8_t addr_size) {362 LLDB_INSTRUMENT_VA(this, error, buf, size, endian, addr_size);363 364 lldb::DataBufferSP buffer_sp = std::make_shared<DataBufferHeap>(buf, size);365 366 if (!m_opaque_sp.get())367 m_opaque_sp = std::make_shared<DataExtractor>(buf, size, endian, addr_size);368 else {369 m_opaque_sp->SetData(buffer_sp);370 m_opaque_sp->SetByteOrder(endian);371 m_opaque_sp->SetAddressByteSize(addr_size);372 }373}374 375bool SBData::Append(const SBData &rhs) {376 LLDB_INSTRUMENT_VA(this, rhs);377 378 bool value = false;379 if (m_opaque_sp.get() && rhs.m_opaque_sp.get())380 value = m_opaque_sp.get()->Append(*rhs.m_opaque_sp);381 return value;382}383 384lldb::SBData SBData::CreateDataFromCString(lldb::ByteOrder endian,385 uint32_t addr_byte_size,386 const char *data) {387 LLDB_INSTRUMENT_VA(endian, addr_byte_size, data);388 389 if (!data || !data[0])390 return SBData();391 392 uint32_t data_len = strlen(data);393 394 lldb::DataBufferSP buffer_sp(new DataBufferHeap(data, data_len));395 lldb::DataExtractorSP data_sp(396 new DataExtractor(buffer_sp, endian, addr_byte_size));397 398 SBData ret(data_sp);399 400 return ret;401}402 403lldb::SBData SBData::CreateDataFromUInt64Array(lldb::ByteOrder endian,404 uint32_t addr_byte_size,405 uint64_t *array,406 size_t array_len) {407 LLDB_INSTRUMENT_VA(endian, addr_byte_size, array, array_len);408 409 if (!array || array_len == 0)410 return SBData();411 412 size_t data_len = array_len * sizeof(uint64_t);413 414 lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len));415 lldb::DataExtractorSP data_sp(416 new DataExtractor(buffer_sp, endian, addr_byte_size));417 418 SBData ret(data_sp);419 420 return ret;421}422 423lldb::SBData SBData::CreateDataFromUInt32Array(lldb::ByteOrder endian,424 uint32_t addr_byte_size,425 uint32_t *array,426 size_t array_len) {427 LLDB_INSTRUMENT_VA(endian, addr_byte_size, array, array_len);428 429 if (!array || array_len == 0)430 return SBData();431 432 size_t data_len = array_len * sizeof(uint32_t);433 434 lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len));435 lldb::DataExtractorSP data_sp(436 new DataExtractor(buffer_sp, endian, addr_byte_size));437 438 SBData ret(data_sp);439 440 return ret;441}442 443lldb::SBData SBData::CreateDataFromSInt64Array(lldb::ByteOrder endian,444 uint32_t addr_byte_size,445 int64_t *array,446 size_t array_len) {447 LLDB_INSTRUMENT_VA(endian, addr_byte_size, array, array_len);448 449 if (!array || array_len == 0)450 return SBData();451 452 size_t data_len = array_len * sizeof(int64_t);453 454 lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len));455 lldb::DataExtractorSP data_sp(456 new DataExtractor(buffer_sp, endian, addr_byte_size));457 458 SBData ret(data_sp);459 460 return ret;461}462 463lldb::SBData SBData::CreateDataFromSInt32Array(lldb::ByteOrder endian,464 uint32_t addr_byte_size,465 int32_t *array,466 size_t array_len) {467 LLDB_INSTRUMENT_VA(endian, addr_byte_size, array, array_len);468 469 if (!array || array_len == 0)470 return SBData();471 472 size_t data_len = array_len * sizeof(int32_t);473 474 lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len));475 lldb::DataExtractorSP data_sp(476 new DataExtractor(buffer_sp, endian, addr_byte_size));477 478 SBData ret(data_sp);479 480 return ret;481}482 483lldb::SBData SBData::CreateDataFromDoubleArray(lldb::ByteOrder endian,484 uint32_t addr_byte_size,485 double *array,486 size_t array_len) {487 LLDB_INSTRUMENT_VA(endian, addr_byte_size, array, array_len);488 489 if (!array || array_len == 0)490 return SBData();491 492 size_t data_len = array_len * sizeof(double);493 494 lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len));495 lldb::DataExtractorSP data_sp(496 new DataExtractor(buffer_sp, endian, addr_byte_size));497 498 SBData ret(data_sp);499 500 return ret;501}502 503bool SBData::SetDataFromCString(const char *data) {504 LLDB_INSTRUMENT_VA(this, data);505 506 if (!data) {507 return false;508 }509 510 size_t data_len = strlen(data);511 512 lldb::DataBufferSP buffer_sp(new DataBufferHeap(data, data_len));513 514 if (!m_opaque_sp.get())515 m_opaque_sp = std::make_shared<DataExtractor>(buffer_sp, GetByteOrder(),516 GetAddressByteSize());517 else518 m_opaque_sp->SetData(buffer_sp);519 520 521 return true;522}523 524bool SBData::SetDataFromUInt64Array(uint64_t *array, size_t array_len) {525 LLDB_INSTRUMENT_VA(this, array, array_len);526 527 if (!array || array_len == 0) {528 return false;529 }530 531 size_t data_len = array_len * sizeof(uint64_t);532 533 lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len));534 535 if (!m_opaque_sp.get())536 m_opaque_sp = std::make_shared<DataExtractor>(buffer_sp, GetByteOrder(),537 GetAddressByteSize());538 else539 m_opaque_sp->SetData(buffer_sp);540 541 542 return true;543}544 545bool SBData::SetDataFromUInt32Array(uint32_t *array, size_t array_len) {546 LLDB_INSTRUMENT_VA(this, array, array_len);547 548 if (!array || array_len == 0) {549 return false;550 }551 552 size_t data_len = array_len * sizeof(uint32_t);553 554 lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len));555 556 if (!m_opaque_sp.get())557 m_opaque_sp = std::make_shared<DataExtractor>(buffer_sp, GetByteOrder(),558 GetAddressByteSize());559 else560 m_opaque_sp->SetData(buffer_sp);561 562 return true;563}564 565bool SBData::SetDataFromSInt64Array(int64_t *array, size_t array_len) {566 LLDB_INSTRUMENT_VA(this, array, array_len);567 568 if (!array || array_len == 0) {569 return false;570 }571 572 size_t data_len = array_len * sizeof(int64_t);573 574 lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len));575 576 if (!m_opaque_sp.get())577 m_opaque_sp = std::make_shared<DataExtractor>(buffer_sp, GetByteOrder(),578 GetAddressByteSize());579 else580 m_opaque_sp->SetData(buffer_sp);581 582 return true;583}584 585bool SBData::SetDataFromSInt32Array(int32_t *array, size_t array_len) {586 LLDB_INSTRUMENT_VA(this, array, array_len);587 588 if (!array || array_len == 0) {589 return false;590 }591 592 size_t data_len = array_len * sizeof(int32_t);593 594 lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len));595 596 if (!m_opaque_sp.get())597 m_opaque_sp = std::make_shared<DataExtractor>(buffer_sp, GetByteOrder(),598 GetAddressByteSize());599 else600 m_opaque_sp->SetData(buffer_sp);601 602 return true;603}604 605bool SBData::SetDataFromDoubleArray(double *array, size_t array_len) {606 LLDB_INSTRUMENT_VA(this, array, array_len);607 608 if (!array || array_len == 0) {609 return false;610 }611 612 size_t data_len = array_len * sizeof(double);613 614 lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len));615 616 if (!m_opaque_sp.get())617 m_opaque_sp = std::make_shared<DataExtractor>(buffer_sp, GetByteOrder(),618 GetAddressByteSize());619 else620 m_opaque_sp->SetData(buffer_sp);621 622 return true;623}624