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 void *ok = NULL; 342 if (!m_opaque_sp.get()) { 343 error.SetErrorString("no value to read from"); 344 } else { 345 uint32_t old_offset = offset; 346 ok = m_opaque_sp->GetU8(&offset, buf, size); 347 if ((offset == old_offset) || (ok == NULL)) 348 error.SetErrorString("unable to read data"); 349 } 350 return ok ? size : 0; 351 } 352 353 void SBData::SetData(lldb::SBError &error, const void *buf, size_t size, 354 lldb::ByteOrder endian, uint8_t addr_size) { 355 if (!m_opaque_sp.get()) 356 m_opaque_sp = std::make_shared<DataExtractor>(buf, size, endian, addr_size); 357 else 358 { 359 m_opaque_sp->SetData(buf, size, endian); 360 m_opaque_sp->SetAddressByteSize(addr_size); 361 } 362 363 } 364 365 bool SBData::Append(const SBData &rhs) { 366 LLDB_RECORD_METHOD(bool, SBData, Append, (const lldb::SBData &), rhs); 367 368 bool value = false; 369 if (m_opaque_sp.get() && rhs.m_opaque_sp.get()) 370 value = m_opaque_sp.get()->Append(*rhs.m_opaque_sp); 371 return value; 372 } 373 374 lldb::SBData SBData::CreateDataFromCString(lldb::ByteOrder endian, 375 uint32_t addr_byte_size, 376 const char *data) { 377 LLDB_RECORD_STATIC_METHOD(lldb::SBData, SBData, CreateDataFromCString, 378 (lldb::ByteOrder, uint32_t, const char *), endian, 379 addr_byte_size, data); 380 381 if (!data || !data[0]) 382 return LLDB_RECORD_RESULT(SBData()); 383 384 uint32_t data_len = strlen(data); 385 386 lldb::DataBufferSP buffer_sp(new DataBufferHeap(data, data_len)); 387 lldb::DataExtractorSP data_sp( 388 new DataExtractor(buffer_sp, endian, addr_byte_size)); 389 390 SBData ret(data_sp); 391 392 return LLDB_RECORD_RESULT(ret); 393 } 394 395 lldb::SBData SBData::CreateDataFromUInt64Array(lldb::ByteOrder endian, 396 uint32_t addr_byte_size, 397 uint64_t *array, 398 size_t array_len) { 399 LLDB_RECORD_STATIC_METHOD(lldb::SBData, SBData, CreateDataFromUInt64Array, 400 (lldb::ByteOrder, uint32_t, uint64_t *, size_t), 401 endian, addr_byte_size, array, array_len); 402 403 if (!array || array_len == 0) 404 return LLDB_RECORD_RESULT(SBData()); 405 406 size_t data_len = array_len * sizeof(uint64_t); 407 408 lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); 409 lldb::DataExtractorSP data_sp( 410 new DataExtractor(buffer_sp, endian, addr_byte_size)); 411 412 SBData ret(data_sp); 413 414 return LLDB_RECORD_RESULT(ret); 415 } 416 417 lldb::SBData SBData::CreateDataFromUInt32Array(lldb::ByteOrder endian, 418 uint32_t addr_byte_size, 419 uint32_t *array, 420 size_t array_len) { 421 LLDB_RECORD_STATIC_METHOD(lldb::SBData, SBData, CreateDataFromUInt32Array, 422 (lldb::ByteOrder, uint32_t, uint32_t *, size_t), 423 endian, addr_byte_size, array, array_len); 424 425 if (!array || array_len == 0) 426 return LLDB_RECORD_RESULT(SBData()); 427 428 size_t data_len = array_len * sizeof(uint32_t); 429 430 lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); 431 lldb::DataExtractorSP data_sp( 432 new DataExtractor(buffer_sp, endian, addr_byte_size)); 433 434 SBData ret(data_sp); 435 436 return LLDB_RECORD_RESULT(ret); 437 } 438 439 lldb::SBData SBData::CreateDataFromSInt64Array(lldb::ByteOrder endian, 440 uint32_t addr_byte_size, 441 int64_t *array, 442 size_t array_len) { 443 LLDB_RECORD_STATIC_METHOD(lldb::SBData, SBData, CreateDataFromSInt64Array, 444 (lldb::ByteOrder, uint32_t, int64_t *, size_t), 445 endian, addr_byte_size, array, array_len); 446 447 if (!array || array_len == 0) 448 return LLDB_RECORD_RESULT(SBData()); 449 450 size_t data_len = array_len * sizeof(int64_t); 451 452 lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); 453 lldb::DataExtractorSP data_sp( 454 new DataExtractor(buffer_sp, endian, addr_byte_size)); 455 456 SBData ret(data_sp); 457 458 return LLDB_RECORD_RESULT(ret); 459 } 460 461 lldb::SBData SBData::CreateDataFromSInt32Array(lldb::ByteOrder endian, 462 uint32_t addr_byte_size, 463 int32_t *array, 464 size_t array_len) { 465 LLDB_RECORD_STATIC_METHOD(lldb::SBData, SBData, CreateDataFromSInt32Array, 466 (lldb::ByteOrder, uint32_t, int32_t *, size_t), 467 endian, addr_byte_size, array, array_len); 468 469 if (!array || array_len == 0) 470 return LLDB_RECORD_RESULT(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 LLDB_RECORD_RESULT(ret); 481 } 482 483 lldb::SBData SBData::CreateDataFromDoubleArray(lldb::ByteOrder endian, 484 uint32_t addr_byte_size, 485 double *array, 486 size_t array_len) { 487 LLDB_RECORD_STATIC_METHOD(lldb::SBData, SBData, CreateDataFromDoubleArray, 488 (lldb::ByteOrder, uint32_t, double *, size_t), 489 endian, addr_byte_size, array, array_len); 490 491 if (!array || array_len == 0) 492 return LLDB_RECORD_RESULT(SBData()); 493 494 size_t data_len = array_len * sizeof(double); 495 496 lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); 497 lldb::DataExtractorSP data_sp( 498 new DataExtractor(buffer_sp, endian, addr_byte_size)); 499 500 SBData ret(data_sp); 501 502 return LLDB_RECORD_RESULT(ret); 503 } 504 505 bool SBData::SetDataFromCString(const char *data) { 506 LLDB_RECORD_METHOD(bool, SBData, SetDataFromCString, (const char *), data); 507 508 509 if (!data) { 510 return false; 511 } 512 513 size_t data_len = strlen(data); 514 515 lldb::DataBufferSP buffer_sp(new DataBufferHeap(data, data_len)); 516 517 if (!m_opaque_sp.get()) 518 m_opaque_sp = std::make_shared<DataExtractor>(buffer_sp, GetByteOrder(), 519 GetAddressByteSize()); 520 else 521 m_opaque_sp->SetData(buffer_sp); 522 523 524 return true; 525 } 526 527 bool SBData::SetDataFromUInt64Array(uint64_t *array, size_t array_len) { 528 LLDB_RECORD_METHOD(bool, SBData, SetDataFromUInt64Array, (uint64_t *, size_t), 529 array, array_len); 530 531 532 if (!array || array_len == 0) { 533 return false; 534 } 535 536 size_t data_len = array_len * sizeof(uint64_t); 537 538 lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); 539 540 if (!m_opaque_sp.get()) 541 m_opaque_sp = std::make_shared<DataExtractor>(buffer_sp, GetByteOrder(), 542 GetAddressByteSize()); 543 else 544 m_opaque_sp->SetData(buffer_sp); 545 546 547 return true; 548 } 549 550 bool SBData::SetDataFromUInt32Array(uint32_t *array, size_t array_len) { 551 LLDB_RECORD_METHOD(bool, SBData, SetDataFromUInt32Array, (uint32_t *, size_t), 552 array, array_len); 553 554 555 if (!array || array_len == 0) { 556 return false; 557 } 558 559 size_t data_len = array_len * sizeof(uint32_t); 560 561 lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); 562 563 if (!m_opaque_sp.get()) 564 m_opaque_sp = std::make_shared<DataExtractor>(buffer_sp, GetByteOrder(), 565 GetAddressByteSize()); 566 else 567 m_opaque_sp->SetData(buffer_sp); 568 569 return true; 570 } 571 572 bool SBData::SetDataFromSInt64Array(int64_t *array, size_t array_len) { 573 LLDB_RECORD_METHOD(bool, SBData, SetDataFromSInt64Array, (int64_t *, size_t), 574 array, array_len); 575 576 577 if (!array || array_len == 0) { 578 return false; 579 } 580 581 size_t data_len = array_len * sizeof(int64_t); 582 583 lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); 584 585 if (!m_opaque_sp.get()) 586 m_opaque_sp = std::make_shared<DataExtractor>(buffer_sp, GetByteOrder(), 587 GetAddressByteSize()); 588 else 589 m_opaque_sp->SetData(buffer_sp); 590 591 return true; 592 } 593 594 bool SBData::SetDataFromSInt32Array(int32_t *array, size_t array_len) { 595 LLDB_RECORD_METHOD(bool, SBData, SetDataFromSInt32Array, (int32_t *, size_t), 596 array, array_len); 597 598 599 if (!array || array_len == 0) { 600 return false; 601 } 602 603 size_t data_len = array_len * sizeof(int32_t); 604 605 lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); 606 607 if (!m_opaque_sp.get()) 608 m_opaque_sp = std::make_shared<DataExtractor>(buffer_sp, GetByteOrder(), 609 GetAddressByteSize()); 610 else 611 m_opaque_sp->SetData(buffer_sp); 612 613 return true; 614 } 615 616 bool SBData::SetDataFromDoubleArray(double *array, size_t array_len) { 617 LLDB_RECORD_METHOD(bool, SBData, SetDataFromDoubleArray, (double *, size_t), 618 array, array_len); 619 620 621 if (!array || array_len == 0) { 622 return false; 623 } 624 625 size_t data_len = array_len * sizeof(double); 626 627 lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); 628 629 if (!m_opaque_sp.get()) 630 m_opaque_sp = std::make_shared<DataExtractor>(buffer_sp, GetByteOrder(), 631 GetAddressByteSize()); 632 else 633 m_opaque_sp->SetData(buffer_sp); 634 635 return true; 636 } 637