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 const char *value = nullptr; 301 if (!m_opaque_sp.get()) { 302 error.SetErrorString("no value to read from"); 303 } else { 304 uint32_t old_offset = offset; 305 value = m_opaque_sp->GetCStr(&offset); 306 if (offset == old_offset || (value == nullptr)) 307 error.SetErrorString("unable to read data"); 308 } 309 return value; 310 } 311 312 bool SBData::GetDescription(lldb::SBStream &description, 313 lldb::addr_t base_addr) { 314 LLDB_INSTRUMENT_VA(this, description, base_addr); 315 316 Stream &strm = description.ref(); 317 318 if (m_opaque_sp) { 319 DumpDataExtractor(*m_opaque_sp, &strm, 0, lldb::eFormatBytesWithASCII, 1, 320 m_opaque_sp->GetByteSize(), 16, base_addr, 0, 0); 321 } else 322 strm.PutCString("No value"); 323 324 return true; 325 } 326 327 size_t SBData::ReadRawData(lldb::SBError &error, lldb::offset_t offset, 328 void *buf, size_t size) { 329 LLDB_INSTRUMENT_VA(this, error, offset, buf, size); 330 331 void *ok = nullptr; 332 if (!m_opaque_sp.get()) { 333 error.SetErrorString("no value to read from"); 334 } else { 335 uint32_t old_offset = offset; 336 ok = m_opaque_sp->GetU8(&offset, buf, size); 337 if ((offset == old_offset) || (ok == nullptr)) 338 error.SetErrorString("unable to read data"); 339 } 340 return ok ? size : 0; 341 } 342 343 void SBData::SetData(lldb::SBError &error, const void *buf, size_t size, 344 lldb::ByteOrder endian, uint8_t addr_size) { 345 LLDB_INSTRUMENT_VA(this, error, buf, size, endian, addr_size); 346 347 if (!m_opaque_sp.get()) 348 m_opaque_sp = std::make_shared<DataExtractor>(buf, size, endian, addr_size); 349 else 350 { 351 m_opaque_sp->SetData(buf, size, endian); 352 m_opaque_sp->SetAddressByteSize(addr_size); 353 } 354 } 355 356 void SBData::SetDataWithOwnership(lldb::SBError &error, const void *buf, 357 size_t size, lldb::ByteOrder endian, 358 uint8_t addr_size) { 359 LLDB_INSTRUMENT_VA(this, error, buf, size, endian, addr_size); 360 361 lldb::DataBufferSP buffer_sp = std::make_shared<DataBufferHeap>(buf, size); 362 363 if (!m_opaque_sp.get()) 364 m_opaque_sp = std::make_shared<DataExtractor>(buf, size, endian, addr_size); 365 else { 366 m_opaque_sp->SetData(buffer_sp); 367 m_opaque_sp->SetByteOrder(endian); 368 m_opaque_sp->SetAddressByteSize(addr_size); 369 } 370 } 371 372 bool SBData::Append(const SBData &rhs) { 373 LLDB_INSTRUMENT_VA(this, rhs); 374 375 bool value = false; 376 if (m_opaque_sp.get() && rhs.m_opaque_sp.get()) 377 value = m_opaque_sp.get()->Append(*rhs.m_opaque_sp); 378 return value; 379 } 380 381 lldb::SBData SBData::CreateDataFromCString(lldb::ByteOrder endian, 382 uint32_t addr_byte_size, 383 const char *data) { 384 LLDB_INSTRUMENT_VA(endian, addr_byte_size, data); 385 386 if (!data || !data[0]) 387 return SBData(); 388 389 uint32_t data_len = strlen(data); 390 391 lldb::DataBufferSP buffer_sp(new DataBufferHeap(data, data_len)); 392 lldb::DataExtractorSP data_sp( 393 new DataExtractor(buffer_sp, endian, addr_byte_size)); 394 395 SBData ret(data_sp); 396 397 return ret; 398 } 399 400 lldb::SBData SBData::CreateDataFromUInt64Array(lldb::ByteOrder endian, 401 uint32_t addr_byte_size, 402 uint64_t *array, 403 size_t array_len) { 404 LLDB_INSTRUMENT_VA(endian, addr_byte_size, array, array_len); 405 406 if (!array || array_len == 0) 407 return SBData(); 408 409 size_t data_len = array_len * sizeof(uint64_t); 410 411 lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); 412 lldb::DataExtractorSP data_sp( 413 new DataExtractor(buffer_sp, endian, addr_byte_size)); 414 415 SBData ret(data_sp); 416 417 return ret; 418 } 419 420 lldb::SBData SBData::CreateDataFromUInt32Array(lldb::ByteOrder endian, 421 uint32_t addr_byte_size, 422 uint32_t *array, 423 size_t array_len) { 424 LLDB_INSTRUMENT_VA(endian, addr_byte_size, array, array_len); 425 426 if (!array || array_len == 0) 427 return SBData(); 428 429 size_t data_len = array_len * sizeof(uint32_t); 430 431 lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); 432 lldb::DataExtractorSP data_sp( 433 new DataExtractor(buffer_sp, endian, addr_byte_size)); 434 435 SBData ret(data_sp); 436 437 return ret; 438 } 439 440 lldb::SBData SBData::CreateDataFromSInt64Array(lldb::ByteOrder endian, 441 uint32_t addr_byte_size, 442 int64_t *array, 443 size_t array_len) { 444 LLDB_INSTRUMENT_VA(endian, addr_byte_size, array, array_len); 445 446 if (!array || array_len == 0) 447 return SBData(); 448 449 size_t data_len = array_len * sizeof(int64_t); 450 451 lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); 452 lldb::DataExtractorSP data_sp( 453 new DataExtractor(buffer_sp, endian, addr_byte_size)); 454 455 SBData ret(data_sp); 456 457 return ret; 458 } 459 460 lldb::SBData SBData::CreateDataFromSInt32Array(lldb::ByteOrder endian, 461 uint32_t addr_byte_size, 462 int32_t *array, 463 size_t array_len) { 464 LLDB_INSTRUMENT_VA(endian, addr_byte_size, array, array_len); 465 466 if (!array || array_len == 0) 467 return SBData(); 468 469 size_t data_len = array_len * sizeof(int32_t); 470 471 lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); 472 lldb::DataExtractorSP data_sp( 473 new DataExtractor(buffer_sp, endian, addr_byte_size)); 474 475 SBData ret(data_sp); 476 477 return ret; 478 } 479 480 lldb::SBData SBData::CreateDataFromDoubleArray(lldb::ByteOrder endian, 481 uint32_t addr_byte_size, 482 double *array, 483 size_t array_len) { 484 LLDB_INSTRUMENT_VA(endian, addr_byte_size, array, array_len); 485 486 if (!array || array_len == 0) 487 return SBData(); 488 489 size_t data_len = array_len * sizeof(double); 490 491 lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); 492 lldb::DataExtractorSP data_sp( 493 new DataExtractor(buffer_sp, endian, addr_byte_size)); 494 495 SBData ret(data_sp); 496 497 return ret; 498 } 499 500 bool SBData::SetDataFromCString(const char *data) { 501 LLDB_INSTRUMENT_VA(this, data); 502 503 if (!data) { 504 return false; 505 } 506 507 size_t data_len = strlen(data); 508 509 lldb::DataBufferSP buffer_sp(new DataBufferHeap(data, data_len)); 510 511 if (!m_opaque_sp.get()) 512 m_opaque_sp = std::make_shared<DataExtractor>(buffer_sp, GetByteOrder(), 513 GetAddressByteSize()); 514 else 515 m_opaque_sp->SetData(buffer_sp); 516 517 518 return true; 519 } 520 521 bool SBData::SetDataFromUInt64Array(uint64_t *array, size_t array_len) { 522 LLDB_INSTRUMENT_VA(this, array, array_len); 523 524 if (!array || array_len == 0) { 525 return false; 526 } 527 528 size_t data_len = array_len * sizeof(uint64_t); 529 530 lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); 531 532 if (!m_opaque_sp.get()) 533 m_opaque_sp = std::make_shared<DataExtractor>(buffer_sp, GetByteOrder(), 534 GetAddressByteSize()); 535 else 536 m_opaque_sp->SetData(buffer_sp); 537 538 539 return true; 540 } 541 542 bool SBData::SetDataFromUInt32Array(uint32_t *array, size_t array_len) { 543 LLDB_INSTRUMENT_VA(this, array, array_len); 544 545 if (!array || array_len == 0) { 546 return false; 547 } 548 549 size_t data_len = array_len * sizeof(uint32_t); 550 551 lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); 552 553 if (!m_opaque_sp.get()) 554 m_opaque_sp = std::make_shared<DataExtractor>(buffer_sp, GetByteOrder(), 555 GetAddressByteSize()); 556 else 557 m_opaque_sp->SetData(buffer_sp); 558 559 return true; 560 } 561 562 bool SBData::SetDataFromSInt64Array(int64_t *array, size_t array_len) { 563 LLDB_INSTRUMENT_VA(this, array, array_len); 564 565 if (!array || array_len == 0) { 566 return false; 567 } 568 569 size_t data_len = array_len * sizeof(int64_t); 570 571 lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); 572 573 if (!m_opaque_sp.get()) 574 m_opaque_sp = std::make_shared<DataExtractor>(buffer_sp, GetByteOrder(), 575 GetAddressByteSize()); 576 else 577 m_opaque_sp->SetData(buffer_sp); 578 579 return true; 580 } 581 582 bool SBData::SetDataFromSInt32Array(int32_t *array, size_t array_len) { 583 LLDB_INSTRUMENT_VA(this, array, array_len); 584 585 if (!array || array_len == 0) { 586 return false; 587 } 588 589 size_t data_len = array_len * sizeof(int32_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::SetDataFromDoubleArray(double *array, size_t array_len) { 603 LLDB_INSTRUMENT_VA(this, array, array_len); 604 605 if (!array || array_len == 0) { 606 return false; 607 } 608 609 size_t data_len = array_len * sizeof(double); 610 611 lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); 612 613 if (!m_opaque_sp.get()) 614 m_opaque_sp = std::make_shared<DataExtractor>(buffer_sp, GetByteOrder(), 615 GetAddressByteSize()); 616 else 617 m_opaque_sp->SetData(buffer_sp); 618 619 return true; 620 } 621