1 //===-- DataExtractor.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/Utility/DataExtractor.h" 10 11 #include "lldb/lldb-defines.h" 12 #include "lldb/lldb-enumerations.h" 13 #include "lldb/lldb-forward.h" 14 #include "lldb/lldb-types.h" 15 16 #include "lldb/Utility/DataBuffer.h" 17 #include "lldb/Utility/DataBufferHeap.h" 18 #include "lldb/Utility/LLDBAssert.h" 19 #include "lldb/Utility/Log.h" 20 #include "lldb/Utility/Stream.h" 21 #include "lldb/Utility/StreamString.h" 22 #include "lldb/Utility/UUID.h" 23 24 #include "llvm/ADT/ArrayRef.h" 25 #include "llvm/ADT/SmallVector.h" 26 #include "llvm/ADT/StringExtras.h" 27 #include "llvm/Support/LEB128.h" 28 #include "llvm/Support/MD5.h" 29 #include "llvm/Support/MathExtras.h" 30 31 #include <algorithm> 32 #include <array> 33 #include <cassert> 34 #include <cstdint> 35 #include <string> 36 37 #include <cctype> 38 #include <cinttypes> 39 #include <cstring> 40 41 using namespace lldb; 42 using namespace lldb_private; 43 44 static inline uint16_t ReadInt16(const unsigned char *ptr, offset_t offset) { 45 uint16_t value; 46 memcpy(&value, ptr + offset, 2); 47 return value; 48 } 49 50 static inline uint32_t ReadInt32(const unsigned char *ptr, 51 offset_t offset = 0) { 52 uint32_t value; 53 memcpy(&value, ptr + offset, 4); 54 return value; 55 } 56 57 static inline uint64_t ReadInt64(const unsigned char *ptr, 58 offset_t offset = 0) { 59 uint64_t value; 60 memcpy(&value, ptr + offset, 8); 61 return value; 62 } 63 64 static inline uint16_t ReadInt16(const void *ptr) { 65 uint16_t value; 66 memcpy(&value, ptr, 2); 67 return value; 68 } 69 70 static inline uint16_t ReadSwapInt16(const unsigned char *ptr, 71 offset_t offset) { 72 uint16_t value; 73 memcpy(&value, ptr + offset, 2); 74 return llvm::byteswap<uint16_t>(value); 75 } 76 77 static inline uint32_t ReadSwapInt32(const unsigned char *ptr, 78 offset_t offset) { 79 uint32_t value; 80 memcpy(&value, ptr + offset, 4); 81 return llvm::byteswap<uint32_t>(value); 82 } 83 84 static inline uint64_t ReadSwapInt64(const unsigned char *ptr, 85 offset_t offset) { 86 uint64_t value; 87 memcpy(&value, ptr + offset, 8); 88 return llvm::byteswap<uint64_t>(value); 89 } 90 91 static inline uint16_t ReadSwapInt16(const void *ptr) { 92 uint16_t value; 93 memcpy(&value, ptr, 2); 94 return llvm::byteswap<uint16_t>(value); 95 } 96 97 static inline uint32_t ReadSwapInt32(const void *ptr) { 98 uint32_t value; 99 memcpy(&value, ptr, 4); 100 return llvm::byteswap<uint32_t>(value); 101 } 102 103 static inline uint64_t ReadSwapInt64(const void *ptr) { 104 uint64_t value; 105 memcpy(&value, ptr, 8); 106 return llvm::byteswap<uint64_t>(value); 107 } 108 109 static inline uint64_t ReadMaxInt64(const uint8_t *data, size_t byte_size, 110 ByteOrder byte_order) { 111 uint64_t res = 0; 112 if (byte_order == eByteOrderBig) 113 for (size_t i = 0; i < byte_size; ++i) 114 res = (res << 8) | data[i]; 115 else { 116 assert(byte_order == eByteOrderLittle); 117 for (size_t i = 0; i < byte_size; ++i) 118 res = (res << 8) | data[byte_size - 1 - i]; 119 } 120 return res; 121 } 122 123 DataExtractor::DataExtractor() 124 : m_byte_order(endian::InlHostByteOrder()), m_addr_size(sizeof(void *)), 125 m_data_sp() {} 126 127 // This constructor allows us to use data that is owned by someone else. The 128 // data must stay around as long as this object is valid. 129 DataExtractor::DataExtractor(const void *data, offset_t length, 130 ByteOrder endian, uint32_t addr_size, 131 uint32_t target_byte_size /*=1*/) 132 : m_start(const_cast<uint8_t *>(static_cast<const uint8_t *>(data))), 133 m_end(const_cast<uint8_t *>(static_cast<const uint8_t *>(data)) + length), 134 m_byte_order(endian), m_addr_size(addr_size), m_data_sp(), 135 m_target_byte_size(target_byte_size) { 136 assert(addr_size >= 1 && addr_size <= 8); 137 } 138 139 // Make a shared pointer reference to the shared data in "data_sp" and set the 140 // endian swapping setting to "swap", and the address size to "addr_size". The 141 // shared data reference will ensure the data lives as long as any 142 // DataExtractor objects exist that have a reference to this data. 143 DataExtractor::DataExtractor(const DataBufferSP &data_sp, ByteOrder endian, 144 uint32_t addr_size, 145 uint32_t target_byte_size /*=1*/) 146 : m_byte_order(endian), m_addr_size(addr_size), m_data_sp(), 147 m_target_byte_size(target_byte_size) { 148 assert(addr_size >= 1 && addr_size <= 8); 149 SetData(data_sp); 150 } 151 152 // Initialize this object with a subset of the data bytes in "data". If "data" 153 // contains shared data, then a reference to this shared data will added and 154 // the shared data will stay around as long as any object contains a reference 155 // to that data. The endian swap and address size settings are copied from 156 // "data". 157 DataExtractor::DataExtractor(const DataExtractor &data, offset_t offset, 158 offset_t length, uint32_t target_byte_size /*=1*/) 159 : m_byte_order(data.m_byte_order), m_addr_size(data.m_addr_size), 160 m_data_sp(), m_target_byte_size(target_byte_size) { 161 assert(m_addr_size >= 1 && m_addr_size <= 8); 162 if (data.ValidOffset(offset)) { 163 offset_t bytes_available = data.GetByteSize() - offset; 164 if (length > bytes_available) 165 length = bytes_available; 166 SetData(data, offset, length); 167 } 168 } 169 170 DataExtractor::DataExtractor(const DataExtractor &rhs) 171 : m_start(rhs.m_start), m_end(rhs.m_end), m_byte_order(rhs.m_byte_order), 172 m_addr_size(rhs.m_addr_size), m_data_sp(rhs.m_data_sp), 173 m_target_byte_size(rhs.m_target_byte_size) { 174 assert(m_addr_size >= 1 && m_addr_size <= 8); 175 } 176 177 // Assignment operator 178 const DataExtractor &DataExtractor::operator=(const DataExtractor &rhs) { 179 if (this != &rhs) { 180 m_start = rhs.m_start; 181 m_end = rhs.m_end; 182 m_byte_order = rhs.m_byte_order; 183 m_addr_size = rhs.m_addr_size; 184 m_data_sp = rhs.m_data_sp; 185 } 186 return *this; 187 } 188 189 DataExtractor::~DataExtractor() = default; 190 191 // Clears the object contents back to a default invalid state, and release any 192 // references to shared data that this object may contain. 193 void DataExtractor::Clear() { 194 m_start = nullptr; 195 m_end = nullptr; 196 m_byte_order = endian::InlHostByteOrder(); 197 m_addr_size = sizeof(void *); 198 m_data_sp.reset(); 199 } 200 201 // If this object contains shared data, this function returns the offset into 202 // that shared data. Else zero is returned. 203 size_t DataExtractor::GetSharedDataOffset() const { 204 if (m_start != nullptr) { 205 const DataBuffer *data = m_data_sp.get(); 206 if (data != nullptr) { 207 const uint8_t *data_bytes = data->GetBytes(); 208 if (data_bytes != nullptr) { 209 assert(m_start >= data_bytes); 210 return m_start - data_bytes; 211 } 212 } 213 } 214 return 0; 215 } 216 217 // Set the data with which this object will extract from to data starting at 218 // BYTES and set the length of the data to LENGTH bytes long. The data is 219 // externally owned must be around at least as long as this object points to 220 // the data. No copy of the data is made, this object just refers to this data 221 // and can extract from it. If this object refers to any shared data upon 222 // entry, the reference to that data will be released. Is SWAP is set to true, 223 // any data extracted will be endian swapped. 224 lldb::offset_t DataExtractor::SetData(const void *bytes, offset_t length, 225 ByteOrder endian) { 226 m_byte_order = endian; 227 m_data_sp.reset(); 228 if (bytes == nullptr || length == 0) { 229 m_start = nullptr; 230 m_end = nullptr; 231 } else { 232 m_start = const_cast<uint8_t *>(static_cast<const uint8_t *>(bytes)); 233 m_end = m_start + length; 234 } 235 return GetByteSize(); 236 } 237 238 // Assign the data for this object to be a subrange in "data" starting 239 // "data_offset" bytes into "data" and ending "data_length" bytes later. If 240 // "data_offset" is not a valid offset into "data", then this object will 241 // contain no bytes. If "data_offset" is within "data" yet "data_length" is too 242 // large, the length will be capped at the number of bytes remaining in "data". 243 // If "data" contains a shared pointer to other data, then a ref counted 244 // pointer to that data will be made in this object. If "data" doesn't contain 245 // a shared pointer to data, then the bytes referred to in "data" will need to 246 // exist at least as long as this object refers to those bytes. The address 247 // size and endian swap settings are copied from the current values in "data". 248 lldb::offset_t DataExtractor::SetData(const DataExtractor &data, 249 offset_t data_offset, 250 offset_t data_length) { 251 m_addr_size = data.m_addr_size; 252 assert(m_addr_size >= 1 && m_addr_size <= 8); 253 // If "data" contains shared pointer to data, then we can use that 254 if (data.m_data_sp) { 255 m_byte_order = data.m_byte_order; 256 return SetData(data.m_data_sp, data.GetSharedDataOffset() + data_offset, 257 data_length); 258 } 259 260 // We have a DataExtractor object that just has a pointer to bytes 261 if (data.ValidOffset(data_offset)) { 262 if (data_length > data.GetByteSize() - data_offset) 263 data_length = data.GetByteSize() - data_offset; 264 return SetData(data.GetDataStart() + data_offset, data_length, 265 data.GetByteOrder()); 266 } 267 return 0; 268 } 269 270 // Assign the data for this object to be a subrange of the shared data in 271 // "data_sp" starting "data_offset" bytes into "data_sp" and ending 272 // "data_length" bytes later. If "data_offset" is not a valid offset into 273 // "data_sp", then this object will contain no bytes. If "data_offset" is 274 // within "data_sp" yet "data_length" is too large, the length will be capped 275 // at the number of bytes remaining in "data_sp". A ref counted pointer to the 276 // data in "data_sp" will be made in this object IF the number of bytes this 277 // object refers to in greater than zero (if at least one byte was available 278 // starting at "data_offset") to ensure the data stays around as long as it is 279 // needed. The address size and endian swap settings will remain unchanged from 280 // their current settings. 281 lldb::offset_t DataExtractor::SetData(const DataBufferSP &data_sp, 282 offset_t data_offset, 283 offset_t data_length) { 284 m_start = m_end = nullptr; 285 286 if (data_length > 0) { 287 m_data_sp = data_sp; 288 if (data_sp) { 289 const size_t data_size = data_sp->GetByteSize(); 290 if (data_offset < data_size) { 291 m_start = data_sp->GetBytes() + data_offset; 292 const size_t bytes_left = data_size - data_offset; 293 // Cap the length of we asked for too many 294 if (data_length <= bytes_left) 295 m_end = m_start + data_length; // We got all the bytes we wanted 296 else 297 m_end = m_start + bytes_left; // Not all the bytes requested were 298 // available in the shared data 299 } 300 } 301 } 302 303 size_t new_size = GetByteSize(); 304 305 // Don't hold a shared pointer to the data buffer if we don't share any valid 306 // bytes in the shared buffer. 307 if (new_size == 0) 308 m_data_sp.reset(); 309 310 return new_size; 311 } 312 313 // Extract a single unsigned char from the binary data and update the offset 314 // pointed to by "offset_ptr". 315 // 316 // RETURNS the byte that was extracted, or zero on failure. 317 uint8_t DataExtractor::GetU8(offset_t *offset_ptr) const { 318 const uint8_t *data = static_cast<const uint8_t *>(GetData(offset_ptr, 1)); 319 if (data) 320 return *data; 321 return 0; 322 } 323 324 // Extract "count" unsigned chars from the binary data and update the offset 325 // pointed to by "offset_ptr". The extracted data is copied into "dst". 326 // 327 // RETURNS the non-nullptr buffer pointer upon successful extraction of 328 // all the requested bytes, or nullptr when the data is not available in the 329 // buffer due to being out of bounds, or insufficient data. 330 void *DataExtractor::GetU8(offset_t *offset_ptr, void *dst, 331 uint32_t count) const { 332 const uint8_t *data = 333 static_cast<const uint8_t *>(GetData(offset_ptr, count)); 334 if (data) { 335 // Copy the data into the buffer 336 memcpy(dst, data, count); 337 // Return a non-nullptr pointer to the converted data as an indicator of 338 // success 339 return dst; 340 } 341 return nullptr; 342 } 343 344 // Extract a single uint16_t from the data and update the offset pointed to by 345 // "offset_ptr". 346 // 347 // RETURNS the uint16_t that was extracted, or zero on failure. 348 uint16_t DataExtractor::GetU16(offset_t *offset_ptr) const { 349 uint16_t val = 0; 350 const uint8_t *data = 351 static_cast<const uint8_t *>(GetData(offset_ptr, sizeof(val))); 352 if (data) { 353 if (m_byte_order != endian::InlHostByteOrder()) 354 val = ReadSwapInt16(data); 355 else 356 val = ReadInt16(data); 357 } 358 return val; 359 } 360 361 uint16_t DataExtractor::GetU16_unchecked(offset_t *offset_ptr) const { 362 uint16_t val; 363 if (m_byte_order == endian::InlHostByteOrder()) 364 val = ReadInt16(m_start, *offset_ptr); 365 else 366 val = ReadSwapInt16(m_start, *offset_ptr); 367 *offset_ptr += sizeof(val); 368 return val; 369 } 370 371 uint32_t DataExtractor::GetU32_unchecked(offset_t *offset_ptr) const { 372 uint32_t val; 373 if (m_byte_order == endian::InlHostByteOrder()) 374 val = ReadInt32(m_start, *offset_ptr); 375 else 376 val = ReadSwapInt32(m_start, *offset_ptr); 377 *offset_ptr += sizeof(val); 378 return val; 379 } 380 381 uint64_t DataExtractor::GetU64_unchecked(offset_t *offset_ptr) const { 382 uint64_t val; 383 if (m_byte_order == endian::InlHostByteOrder()) 384 val = ReadInt64(m_start, *offset_ptr); 385 else 386 val = ReadSwapInt64(m_start, *offset_ptr); 387 *offset_ptr += sizeof(val); 388 return val; 389 } 390 391 // Extract "count" uint16_t values from the binary data and update the offset 392 // pointed to by "offset_ptr". The extracted data is copied into "dst". 393 // 394 // RETURNS the non-nullptr buffer pointer upon successful extraction of 395 // all the requested bytes, or nullptr when the data is not available in the 396 // buffer due to being out of bounds, or insufficient data. 397 void *DataExtractor::GetU16(offset_t *offset_ptr, void *void_dst, 398 uint32_t count) const { 399 const size_t src_size = sizeof(uint16_t) * count; 400 const uint16_t *src = 401 static_cast<const uint16_t *>(GetData(offset_ptr, src_size)); 402 if (src) { 403 if (m_byte_order != endian::InlHostByteOrder()) { 404 uint16_t *dst_pos = static_cast<uint16_t *>(void_dst); 405 uint16_t *dst_end = dst_pos + count; 406 const uint16_t *src_pos = src; 407 while (dst_pos < dst_end) { 408 *dst_pos = ReadSwapInt16(src_pos); 409 ++dst_pos; 410 ++src_pos; 411 } 412 } else { 413 memcpy(void_dst, src, src_size); 414 } 415 // Return a non-nullptr pointer to the converted data as an indicator of 416 // success 417 return void_dst; 418 } 419 return nullptr; 420 } 421 422 // Extract a single uint32_t from the data and update the offset pointed to by 423 // "offset_ptr". 424 // 425 // RETURNS the uint32_t that was extracted, or zero on failure. 426 uint32_t DataExtractor::GetU32(offset_t *offset_ptr) const { 427 uint32_t val = 0; 428 const uint8_t *data = 429 static_cast<const uint8_t *>(GetData(offset_ptr, sizeof(val))); 430 if (data) { 431 if (m_byte_order != endian::InlHostByteOrder()) { 432 val = ReadSwapInt32(data); 433 } else { 434 memcpy(&val, data, 4); 435 } 436 } 437 return val; 438 } 439 440 // Extract "count" uint32_t values from the binary data and update the offset 441 // pointed to by "offset_ptr". The extracted data is copied into "dst". 442 // 443 // RETURNS the non-nullptr buffer pointer upon successful extraction of 444 // all the requested bytes, or nullptr when the data is not available in the 445 // buffer due to being out of bounds, or insufficient data. 446 void *DataExtractor::GetU32(offset_t *offset_ptr, void *void_dst, 447 uint32_t count) const { 448 const size_t src_size = sizeof(uint32_t) * count; 449 const uint32_t *src = 450 static_cast<const uint32_t *>(GetData(offset_ptr, src_size)); 451 if (src) { 452 if (m_byte_order != endian::InlHostByteOrder()) { 453 uint32_t *dst_pos = static_cast<uint32_t *>(void_dst); 454 uint32_t *dst_end = dst_pos + count; 455 const uint32_t *src_pos = src; 456 while (dst_pos < dst_end) { 457 *dst_pos = ReadSwapInt32(src_pos); 458 ++dst_pos; 459 ++src_pos; 460 } 461 } else { 462 memcpy(void_dst, src, src_size); 463 } 464 // Return a non-nullptr pointer to the converted data as an indicator of 465 // success 466 return void_dst; 467 } 468 return nullptr; 469 } 470 471 // Extract a single uint64_t from the data and update the offset pointed to by 472 // "offset_ptr". 473 // 474 // RETURNS the uint64_t that was extracted, or zero on failure. 475 uint64_t DataExtractor::GetU64(offset_t *offset_ptr) const { 476 uint64_t val = 0; 477 const uint8_t *data = 478 static_cast<const uint8_t *>(GetData(offset_ptr, sizeof(val))); 479 if (data) { 480 if (m_byte_order != endian::InlHostByteOrder()) { 481 val = ReadSwapInt64(data); 482 } else { 483 memcpy(&val, data, 8); 484 } 485 } 486 return val; 487 } 488 489 // GetU64 490 // 491 // Get multiple consecutive 64 bit values. Return true if the entire read 492 // succeeds and increment the offset pointed to by offset_ptr, else return 493 // false and leave the offset pointed to by offset_ptr unchanged. 494 void *DataExtractor::GetU64(offset_t *offset_ptr, void *void_dst, 495 uint32_t count) const { 496 const size_t src_size = sizeof(uint64_t) * count; 497 const uint64_t *src = 498 static_cast<const uint64_t *>(GetData(offset_ptr, src_size)); 499 if (src) { 500 if (m_byte_order != endian::InlHostByteOrder()) { 501 uint64_t *dst_pos = static_cast<uint64_t *>(void_dst); 502 uint64_t *dst_end = dst_pos + count; 503 const uint64_t *src_pos = src; 504 while (dst_pos < dst_end) { 505 *dst_pos = ReadSwapInt64(src_pos); 506 ++dst_pos; 507 ++src_pos; 508 } 509 } else { 510 memcpy(void_dst, src, src_size); 511 } 512 // Return a non-nullptr pointer to the converted data as an indicator of 513 // success 514 return void_dst; 515 } 516 return nullptr; 517 } 518 519 uint32_t DataExtractor::GetMaxU32(offset_t *offset_ptr, 520 size_t byte_size) const { 521 lldbassert(byte_size > 0 && byte_size <= 4 && "GetMaxU32 invalid byte_size!"); 522 return GetMaxU64(offset_ptr, byte_size); 523 } 524 525 uint64_t DataExtractor::GetMaxU64(offset_t *offset_ptr, 526 size_t byte_size) const { 527 lldbassert(byte_size > 0 && byte_size <= 8 && "GetMaxU64 invalid byte_size!"); 528 switch (byte_size) { 529 case 1: 530 return GetU8(offset_ptr); 531 case 2: 532 return GetU16(offset_ptr); 533 case 4: 534 return GetU32(offset_ptr); 535 case 8: 536 return GetU64(offset_ptr); 537 default: { 538 // General case. 539 const uint8_t *data = 540 static_cast<const uint8_t *>(GetData(offset_ptr, byte_size)); 541 if (data == nullptr) 542 return 0; 543 return ReadMaxInt64(data, byte_size, m_byte_order); 544 } 545 } 546 return 0; 547 } 548 549 uint64_t DataExtractor::GetMaxU64_unchecked(offset_t *offset_ptr, 550 size_t byte_size) const { 551 switch (byte_size) { 552 case 1: 553 return GetU8_unchecked(offset_ptr); 554 case 2: 555 return GetU16_unchecked(offset_ptr); 556 case 4: 557 return GetU32_unchecked(offset_ptr); 558 case 8: 559 return GetU64_unchecked(offset_ptr); 560 default: { 561 uint64_t res = ReadMaxInt64(&m_start[*offset_ptr], byte_size, m_byte_order); 562 *offset_ptr += byte_size; 563 return res; 564 } 565 } 566 return 0; 567 } 568 569 int64_t DataExtractor::GetMaxS64(offset_t *offset_ptr, size_t byte_size) const { 570 uint64_t u64 = GetMaxU64(offset_ptr, byte_size); 571 return llvm::SignExtend64(u64, 8 * byte_size); 572 } 573 574 uint64_t DataExtractor::GetMaxU64Bitfield(offset_t *offset_ptr, size_t size, 575 uint32_t bitfield_bit_size, 576 uint32_t bitfield_bit_offset) const { 577 assert(bitfield_bit_size <= 64); 578 uint64_t uval64 = GetMaxU64(offset_ptr, size); 579 580 if (bitfield_bit_size == 0) 581 return uval64; 582 583 int32_t lsbcount = bitfield_bit_offset; 584 if (m_byte_order == eByteOrderBig) 585 lsbcount = size * 8 - bitfield_bit_offset - bitfield_bit_size; 586 587 if (lsbcount > 0) 588 uval64 >>= lsbcount; 589 590 uint64_t bitfield_mask = 591 (bitfield_bit_size == 64 592 ? std::numeric_limits<uint64_t>::max() 593 : ((static_cast<uint64_t>(1) << bitfield_bit_size) - 1)); 594 if (!bitfield_mask && bitfield_bit_offset == 0 && bitfield_bit_size == 64) 595 return uval64; 596 597 uval64 &= bitfield_mask; 598 599 return uval64; 600 } 601 602 int64_t DataExtractor::GetMaxS64Bitfield(offset_t *offset_ptr, size_t size, 603 uint32_t bitfield_bit_size, 604 uint32_t bitfield_bit_offset) const { 605 assert(size >= 1 && "GetMaxS64Bitfield size must be >= 1"); 606 assert(size <= 8 && "GetMaxS64Bitfield size must be <= 8"); 607 int64_t sval64 = GetMaxS64(offset_ptr, size); 608 if (bitfield_bit_size == 0) 609 return sval64; 610 int32_t lsbcount = bitfield_bit_offset; 611 if (m_byte_order == eByteOrderBig) 612 lsbcount = size * 8 - bitfield_bit_offset - bitfield_bit_size; 613 if (lsbcount > 0) 614 sval64 >>= lsbcount; 615 uint64_t bitfield_mask = llvm::maskTrailingOnes<uint64_t>(bitfield_bit_size); 616 sval64 &= bitfield_mask; 617 // sign extend if needed 618 if (sval64 & ((static_cast<uint64_t>(1)) << (bitfield_bit_size - 1))) 619 sval64 |= ~bitfield_mask; 620 return sval64; 621 } 622 623 float DataExtractor::GetFloat(offset_t *offset_ptr) const { 624 return Get<float>(offset_ptr, 0.0f); 625 } 626 627 double DataExtractor::GetDouble(offset_t *offset_ptr) const { 628 return Get<double>(offset_ptr, 0.0); 629 } 630 631 long double DataExtractor::GetLongDouble(offset_t *offset_ptr) const { 632 long double val = 0.0; 633 #if defined(__i386__) || defined(__amd64__) || defined(__x86_64__) || \ 634 defined(_M_IX86) || defined(_M_IA64) || defined(_M_X64) 635 *offset_ptr += CopyByteOrderedData(*offset_ptr, 10, &val, sizeof(val), 636 endian::InlHostByteOrder()); 637 #else 638 *offset_ptr += CopyByteOrderedData(*offset_ptr, sizeof(val), &val, 639 sizeof(val), endian::InlHostByteOrder()); 640 #endif 641 return val; 642 } 643 644 // Extract a single address from the data and update the offset pointed to by 645 // "offset_ptr". The size of the extracted address comes from the 646 // "this->m_addr_size" member variable and should be set correctly prior to 647 // extracting any address values. 648 // 649 // RETURNS the address that was extracted, or zero on failure. 650 uint64_t DataExtractor::GetAddress(offset_t *offset_ptr) const { 651 assert(m_addr_size >= 1 && m_addr_size <= 8); 652 return GetMaxU64(offset_ptr, m_addr_size); 653 } 654 655 uint64_t DataExtractor::GetAddress_unchecked(offset_t *offset_ptr) const { 656 assert(m_addr_size >= 1 && m_addr_size <= 8); 657 return GetMaxU64_unchecked(offset_ptr, m_addr_size); 658 } 659 660 size_t DataExtractor::ExtractBytes(offset_t offset, offset_t length, 661 ByteOrder dst_byte_order, void *dst) const { 662 const uint8_t *src = PeekData(offset, length); 663 if (src) { 664 if (dst_byte_order != GetByteOrder()) { 665 // Validate that only a word- or register-sized dst is byte swapped 666 assert(length == 1 || length == 2 || length == 4 || length == 8 || 667 length == 10 || length == 16 || length == 32); 668 669 for (uint32_t i = 0; i < length; ++i) 670 (static_cast<uint8_t *>(dst))[i] = src[length - i - 1]; 671 } else 672 ::memcpy(dst, src, length); 673 return length; 674 } 675 return 0; 676 } 677 678 // Extract data as it exists in target memory 679 lldb::offset_t DataExtractor::CopyData(offset_t offset, offset_t length, 680 void *dst) const { 681 const uint8_t *src = PeekData(offset, length); 682 if (src) { 683 ::memcpy(dst, src, length); 684 return length; 685 } 686 return 0; 687 } 688 689 // Extract data and swap if needed when doing the copy 690 lldb::offset_t 691 DataExtractor::CopyByteOrderedData(offset_t src_offset, offset_t src_len, 692 void *dst_void_ptr, offset_t dst_len, 693 ByteOrder dst_byte_order) const { 694 // Validate the source info 695 if (!ValidOffsetForDataOfSize(src_offset, src_len)) 696 assert(ValidOffsetForDataOfSize(src_offset, src_len)); 697 assert(src_len > 0); 698 assert(m_byte_order == eByteOrderBig || m_byte_order == eByteOrderLittle); 699 700 // Validate the destination info 701 assert(dst_void_ptr != nullptr); 702 assert(dst_len > 0); 703 assert(dst_byte_order == eByteOrderBig || dst_byte_order == eByteOrderLittle); 704 705 // Validate that only a word- or register-sized dst is byte swapped 706 assert(dst_byte_order == m_byte_order || dst_len == 1 || dst_len == 2 || 707 dst_len == 4 || dst_len == 8 || dst_len == 10 || dst_len == 16 || 708 dst_len == 32); 709 710 // Must have valid byte orders set in this object and for destination 711 if (!(dst_byte_order == eByteOrderBig || 712 dst_byte_order == eByteOrderLittle) || 713 !(m_byte_order == eByteOrderBig || m_byte_order == eByteOrderLittle)) 714 return 0; 715 716 uint8_t *dst = static_cast<uint8_t *>(dst_void_ptr); 717 const uint8_t *src = PeekData(src_offset, src_len); 718 if (src) { 719 if (dst_len >= src_len) { 720 // We are copying the entire value from src into dst. Calculate how many, 721 // if any, zeroes we need for the most significant bytes if "dst_len" is 722 // greater than "src_len"... 723 const size_t num_zeroes = dst_len - src_len; 724 if (dst_byte_order == eByteOrderBig) { 725 // Big endian, so we lead with zeroes... 726 if (num_zeroes > 0) 727 ::memset(dst, 0, num_zeroes); 728 // Then either copy or swap the rest 729 if (m_byte_order == eByteOrderBig) { 730 ::memcpy(dst + num_zeroes, src, src_len); 731 } else { 732 for (uint32_t i = 0; i < src_len; ++i) 733 dst[i + num_zeroes] = src[src_len - 1 - i]; 734 } 735 } else { 736 // Little endian destination, so we lead the value bytes 737 if (m_byte_order == eByteOrderBig) { 738 for (uint32_t i = 0; i < src_len; ++i) 739 dst[i] = src[src_len - 1 - i]; 740 } else { 741 ::memcpy(dst, src, src_len); 742 } 743 // And zero the rest... 744 if (num_zeroes > 0) 745 ::memset(dst + src_len, 0, num_zeroes); 746 } 747 return src_len; 748 } else { 749 // We are only copying some of the value from src into dst.. 750 751 if (dst_byte_order == eByteOrderBig) { 752 // Big endian dst 753 if (m_byte_order == eByteOrderBig) { 754 // Big endian dst, with big endian src 755 ::memcpy(dst, src + (src_len - dst_len), dst_len); 756 } else { 757 // Big endian dst, with little endian src 758 for (uint32_t i = 0; i < dst_len; ++i) 759 dst[i] = src[dst_len - 1 - i]; 760 } 761 } else { 762 // Little endian dst 763 if (m_byte_order == eByteOrderBig) { 764 // Little endian dst, with big endian src 765 for (uint32_t i = 0; i < dst_len; ++i) 766 dst[i] = src[src_len - 1 - i]; 767 } else { 768 // Little endian dst, with big endian src 769 ::memcpy(dst, src, dst_len); 770 } 771 } 772 return dst_len; 773 } 774 } 775 return 0; 776 } 777 778 // Extracts a variable length NULL terminated C string from the data at the 779 // offset pointed to by "offset_ptr". The "offset_ptr" will be updated with 780 // the offset of the byte that follows the NULL terminator byte. 781 // 782 // If the offset pointed to by "offset_ptr" is out of bounds, or if "length" is 783 // non-zero and there aren't enough available bytes, nullptr will be returned 784 // and "offset_ptr" will not be updated. 785 const char *DataExtractor::GetCStr(offset_t *offset_ptr) const { 786 const char *start = reinterpret_cast<const char *>(PeekData(*offset_ptr, 1)); 787 // Already at the end of the data. 788 if (!start) 789 return nullptr; 790 791 const char *end = reinterpret_cast<const char *>(m_end); 792 793 // Check all bytes for a null terminator that terminates a C string. 794 const char *terminator_or_end = std::find(start, end, '\0'); 795 796 // We didn't find a null terminator, so return nullptr to indicate that there 797 // is no valid C string at that offset. 798 if (terminator_or_end == end) 799 return nullptr; 800 801 // Update offset_ptr for the caller to point to the data behind the 802 // terminator (which is 1 byte long). 803 *offset_ptr += (terminator_or_end - start + 1UL); 804 return start; 805 } 806 807 // Extracts a NULL terminated C string from the fixed length field of length 808 // "len" at the offset pointed to by "offset_ptr". The "offset_ptr" will be 809 // updated with the offset of the byte that follows the fixed length field. 810 // 811 // If the offset pointed to by "offset_ptr" is out of bounds, or if the offset 812 // plus the length of the field is out of bounds, or if the field does not 813 // contain a NULL terminator byte, nullptr will be returned and "offset_ptr" 814 // will not be updated. 815 const char *DataExtractor::GetCStr(offset_t *offset_ptr, offset_t len) const { 816 const char *cstr = reinterpret_cast<const char *>(PeekData(*offset_ptr, len)); 817 if (cstr != nullptr) { 818 if (memchr(cstr, '\0', len) == nullptr) { 819 return nullptr; 820 } 821 *offset_ptr += len; 822 return cstr; 823 } 824 return nullptr; 825 } 826 827 // Peeks at a string in the contained data. No verification is done to make 828 // sure the entire string lies within the bounds of this object's data, only 829 // "offset" is verified to be a valid offset. 830 // 831 // Returns a valid C string pointer if "offset" is a valid offset in this 832 // object's data, else nullptr is returned. 833 const char *DataExtractor::PeekCStr(offset_t offset) const { 834 return reinterpret_cast<const char *>(PeekData(offset, 1)); 835 } 836 837 // Extracts an unsigned LEB128 number from this object's data starting at the 838 // offset pointed to by "offset_ptr". The offset pointed to by "offset_ptr" 839 // will be updated with the offset of the byte following the last extracted 840 // byte. 841 // 842 // Returned the extracted integer value. 843 uint64_t DataExtractor::GetULEB128(offset_t *offset_ptr) const { 844 const uint8_t *src = PeekData(*offset_ptr, 1); 845 if (src == nullptr) 846 return 0; 847 848 unsigned byte_count = 0; 849 uint64_t result = llvm::decodeULEB128(src, &byte_count, m_end); 850 *offset_ptr += byte_count; 851 return result; 852 } 853 854 // Extracts an signed LEB128 number from this object's data starting at the 855 // offset pointed to by "offset_ptr". The offset pointed to by "offset_ptr" 856 // will be updated with the offset of the byte following the last extracted 857 // byte. 858 // 859 // Returned the extracted integer value. 860 int64_t DataExtractor::GetSLEB128(offset_t *offset_ptr) const { 861 const uint8_t *src = PeekData(*offset_ptr, 1); 862 if (src == nullptr) 863 return 0; 864 865 unsigned byte_count = 0; 866 int64_t result = llvm::decodeSLEB128(src, &byte_count, m_end); 867 *offset_ptr += byte_count; 868 return result; 869 } 870 871 // Skips a ULEB128 number (signed or unsigned) from this object's data starting 872 // at the offset pointed to by "offset_ptr". The offset pointed to by 873 // "offset_ptr" will be updated with the offset of the byte following the last 874 // extracted byte. 875 // 876 // Returns the number of bytes consumed during the extraction. 877 uint32_t DataExtractor::Skip_LEB128(offset_t *offset_ptr) const { 878 uint32_t bytes_consumed = 0; 879 const uint8_t *src = PeekData(*offset_ptr, 1); 880 if (src == nullptr) 881 return 0; 882 883 const uint8_t *end = m_end; 884 885 if (src < end) { 886 const uint8_t *src_pos = src; 887 while ((src_pos < end) && (*src_pos++ & 0x80)) 888 ++bytes_consumed; 889 *offset_ptr += src_pos - src; 890 } 891 return bytes_consumed; 892 } 893 894 // Dumps bytes from this object's data to the stream "s" starting 895 // "start_offset" bytes into this data, and ending with the byte before 896 // "end_offset". "base_addr" will be added to the offset into the dumped data 897 // when showing the offset into the data in the output information. 898 // "num_per_line" objects of type "type" will be dumped with the option to 899 // override the format for each object with "type_format". "type_format" is a 900 // printf style formatting string. If "type_format" is nullptr, then an 901 // appropriate format string will be used for the supplied "type". If the 902 // stream "s" is nullptr, then the output will be send to Log(). 903 lldb::offset_t DataExtractor::PutToLog(Log *log, offset_t start_offset, 904 offset_t length, uint64_t base_addr, 905 uint32_t num_per_line, 906 DataExtractor::Type type) const { 907 if (log == nullptr) 908 return start_offset; 909 910 offset_t offset; 911 offset_t end_offset; 912 uint32_t count; 913 StreamString sstr; 914 for (offset = start_offset, end_offset = offset + length, count = 0; 915 ValidOffset(offset) && offset < end_offset; ++count) { 916 if ((count % num_per_line) == 0) { 917 // Print out any previous string 918 if (sstr.GetSize() > 0) { 919 log->PutString(sstr.GetString()); 920 sstr.Clear(); 921 } 922 // Reset string offset and fill the current line string with address: 923 if (base_addr != LLDB_INVALID_ADDRESS) 924 sstr.Printf("0x%8.8" PRIx64 ":", 925 static_cast<uint64_t>(base_addr + (offset - start_offset))); 926 } 927 928 switch (type) { 929 case TypeUInt8: 930 sstr.Printf(" %2.2x", GetU8(&offset)); 931 break; 932 case TypeChar: { 933 char ch = GetU8(&offset); 934 sstr.Printf(" %c", llvm::isPrint(ch) ? ch : ' '); 935 } break; 936 case TypeUInt16: 937 sstr.Printf(" %4.4x", GetU16(&offset)); 938 break; 939 case TypeUInt32: 940 sstr.Printf(" %8.8x", GetU32(&offset)); 941 break; 942 case TypeUInt64: 943 sstr.Printf(" %16.16" PRIx64, GetU64(&offset)); 944 break; 945 case TypePointer: 946 sstr.Printf(" 0x%" PRIx64, GetAddress(&offset)); 947 break; 948 case TypeULEB128: 949 sstr.Printf(" 0x%" PRIx64, GetULEB128(&offset)); 950 break; 951 case TypeSLEB128: 952 sstr.Printf(" %" PRId64, GetSLEB128(&offset)); 953 break; 954 } 955 } 956 957 if (!sstr.Empty()) 958 log->PutString(sstr.GetString()); 959 960 return offset; // Return the offset at which we ended up 961 } 962 963 size_t DataExtractor::Copy(DataExtractor &dest_data) const { 964 if (m_data_sp) { 965 // we can pass along the SP to the data 966 dest_data.SetData(m_data_sp); 967 } else { 968 const uint8_t *base_ptr = m_start; 969 size_t data_size = GetByteSize(); 970 dest_data.SetData(DataBufferSP(new DataBufferHeap(base_ptr, data_size))); 971 } 972 return GetByteSize(); 973 } 974 975 bool DataExtractor::Append(DataExtractor &rhs) { 976 if (rhs.GetByteOrder() != GetByteOrder()) 977 return false; 978 979 if (rhs.GetByteSize() == 0) 980 return true; 981 982 if (GetByteSize() == 0) 983 return (rhs.Copy(*this) > 0); 984 985 size_t bytes = GetByteSize() + rhs.GetByteSize(); 986 987 DataBufferHeap *buffer_heap_ptr = nullptr; 988 DataBufferSP buffer_sp(buffer_heap_ptr = new DataBufferHeap(bytes, 0)); 989 990 if (!buffer_sp || buffer_heap_ptr == nullptr) 991 return false; 992 993 uint8_t *bytes_ptr = buffer_heap_ptr->GetBytes(); 994 995 memcpy(bytes_ptr, GetDataStart(), GetByteSize()); 996 memcpy(bytes_ptr + GetByteSize(), rhs.GetDataStart(), rhs.GetByteSize()); 997 998 SetData(buffer_sp); 999 1000 return true; 1001 } 1002 1003 bool DataExtractor::Append(void *buf, offset_t length) { 1004 if (buf == nullptr) 1005 return false; 1006 1007 if (length == 0) 1008 return true; 1009 1010 size_t bytes = GetByteSize() + length; 1011 1012 DataBufferHeap *buffer_heap_ptr = nullptr; 1013 DataBufferSP buffer_sp(buffer_heap_ptr = new DataBufferHeap(bytes, 0)); 1014 1015 if (!buffer_sp || buffer_heap_ptr == nullptr) 1016 return false; 1017 1018 uint8_t *bytes_ptr = buffer_heap_ptr->GetBytes(); 1019 1020 if (GetByteSize() > 0) 1021 memcpy(bytes_ptr, GetDataStart(), GetByteSize()); 1022 1023 memcpy(bytes_ptr + GetByteSize(), buf, length); 1024 1025 SetData(buffer_sp); 1026 1027 return true; 1028 } 1029 1030 void DataExtractor::Checksum(llvm::SmallVectorImpl<uint8_t> &dest, 1031 uint64_t max_data) { 1032 if (max_data == 0) 1033 max_data = GetByteSize(); 1034 else 1035 max_data = std::min(max_data, GetByteSize()); 1036 1037 llvm::MD5 md5; 1038 1039 const llvm::ArrayRef<uint8_t> data(GetDataStart(), max_data); 1040 md5.update(data); 1041 1042 llvm::MD5::MD5Result result; 1043 md5.final(result); 1044 1045 dest.clear(); 1046 dest.append(result.begin(), result.end()); 1047 } 1048