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