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