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-exception 6 // 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 22 using namespace lldb; 23 using namespace lldb_private; 24 25 SBData::SBData() : m_opaque_sp(new DataExtractor()) { 26 LLDB_INSTRUMENT_VA(this); 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_INSTRUMENT_VA(this, rhs); 33 } 34 35 const 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 43 SBData::~SBData() = default; 44 45 void SBData::SetOpaque(const lldb::DataExtractorSP &data_sp) { 46 m_opaque_sp = data_sp; 47 } 48 49 lldb_private::DataExtractor *SBData::get() const { return m_opaque_sp.get(); } 50 51 lldb_private::DataExtractor *SBData::operator->() const { 52 return m_opaque_sp.operator->(); 53 } 54 55 lldb::DataExtractorSP &SBData::operator*() { return m_opaque_sp; } 56 57 const lldb::DataExtractorSP &SBData::operator*() const { return m_opaque_sp; } 58 59 bool SBData::IsValid() { 60 LLDB_INSTRUMENT_VA(this); 61 return this->operator bool(); 62 } 63 SBData::operator bool() const { 64 LLDB_INSTRUMENT_VA(this); 65 66 return m_opaque_sp.get() != nullptr; 67 } 68 69 uint8_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 78 void 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 85 void SBData::Clear() { 86 LLDB_INSTRUMENT_VA(this); 87 88 if (m_opaque_sp.get()) 89 m_opaque_sp->Clear(); 90 } 91 92 size_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 101 lldb::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 110 void 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 117 float 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 132 double 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 147 long 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 162 lldb::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 177 uint8_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 192 uint16_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 207 uint32_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 222 uint64_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 237 int8_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 252 int16_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 267 int32_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 282 int64_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 297 const 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 315 bool 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 } else 325 strm.PutCString("No value"); 326 327 return true; 328 } 329 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); 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 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); 349 350 if (!m_opaque_sp.get()) 351 m_opaque_sp = std::make_shared<DataExtractor>(buf, size, endian, addr_size); 352 else 353 { 354 m_opaque_sp->SetData(buf, size, endian); 355 m_opaque_sp->SetAddressByteSize(addr_size); 356 } 357 } 358 359 void 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 375 bool 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 384 lldb::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 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_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 423 lldb::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 443 lldb::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 463 lldb::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 483 lldb::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 503 bool 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 else 518 m_opaque_sp->SetData(buffer_sp); 519 520 521 return true; 522 } 523 524 bool 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 else 539 m_opaque_sp->SetData(buffer_sp); 540 541 542 return true; 543 } 544 545 bool 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 else 560 m_opaque_sp->SetData(buffer_sp); 561 562 return true; 563 } 564 565 bool 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 else 580 m_opaque_sp->SetData(buffer_sp); 581 582 return true; 583 } 584 585 bool 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 else 600 m_opaque_sp->SetData(buffer_sp); 601 602 return true; 603 } 604 605 bool 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 else 620 m_opaque_sp->SetData(buffer_sp); 621 622 return true; 623 } 624