1 //===-- RegisterValue.cpp ---------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "lldb/Utility/RegisterValue.h" 10 11 #include "lldb/Utility/DataExtractor.h" 12 #include "lldb/Utility/Scalar.h" 13 #include "lldb/Utility/Status.h" 14 #include "lldb/Utility/Stream.h" 15 #include "lldb/Utility/StreamString.h" 16 #include "lldb/lldb-defines.h" 17 #include "lldb/lldb-private-types.h" 18 19 #include "llvm/ADT/ArrayRef.h" 20 #include "llvm/ADT/StringRef.h" 21 22 #include <cstdint> 23 #include <string> 24 #include <tuple> 25 #include <vector> 26 27 #include <assert.h> 28 #include <inttypes.h> 29 #include <stdio.h> 30 31 using namespace lldb; 32 using namespace lldb_private; 33 34 bool RegisterValue::GetData(DataExtractor &data) const { 35 return data.SetData(GetBytes(), GetByteSize(), GetByteOrder()) > 0; 36 } 37 38 uint32_t RegisterValue::GetAsMemoryData(const RegisterInfo *reg_info, void *dst, 39 uint32_t dst_len, 40 lldb::ByteOrder dst_byte_order, 41 Status &error) const { 42 if (reg_info == nullptr) { 43 error.SetErrorString("invalid register info argument."); 44 return 0; 45 } 46 47 // ReadRegister should have already been called on this object prior to 48 // calling this. 49 if (GetType() == eTypeInvalid) { 50 // No value has been read into this object... 51 error.SetErrorStringWithFormat( 52 "invalid register value type for register %s", reg_info->name); 53 return 0; 54 } 55 56 if (dst_len > kMaxRegisterByteSize) { 57 error.SetErrorString("destination is too big"); 58 return 0; 59 } 60 61 const uint32_t src_len = reg_info->byte_size; 62 63 // Extract the register data into a data extractor 64 DataExtractor reg_data; 65 if (!GetData(reg_data)) { 66 error.SetErrorString("invalid register value to copy into"); 67 return 0; 68 } 69 70 // Prepare a memory buffer that contains some or all of the register value 71 const uint32_t bytes_copied = 72 reg_data.CopyByteOrderedData(0, // src offset 73 src_len, // src length 74 dst, // dst buffer 75 dst_len, // dst length 76 dst_byte_order); // dst byte order 77 if (bytes_copied == 0) 78 error.SetErrorStringWithFormat( 79 "failed to copy data for register write of %s", reg_info->name); 80 81 return bytes_copied; 82 } 83 84 uint32_t RegisterValue::SetFromMemoryData(const RegisterInfo *reg_info, 85 const void *src, uint32_t src_len, 86 lldb::ByteOrder src_byte_order, 87 Status &error) { 88 if (reg_info == nullptr) { 89 error.SetErrorString("invalid register info argument."); 90 return 0; 91 } 92 93 // Moving from addr into a register 94 // 95 // Case 1: src_len == dst_len 96 // 97 // |AABBCCDD| Address contents 98 // |AABBCCDD| Register contents 99 // 100 // Case 2: src_len > dst_len 101 // 102 // Status! (The register should always be big enough to hold the data) 103 // 104 // Case 3: src_len < dst_len 105 // 106 // |AABB| Address contents 107 // |AABB0000| Register contents [on little-endian hardware] 108 // |0000AABB| Register contents [on big-endian hardware] 109 if (src_len > kMaxRegisterByteSize) { 110 error.SetErrorStringWithFormat( 111 "register buffer is too small to receive %u bytes of data.", src_len); 112 return 0; 113 } 114 115 const uint32_t dst_len = reg_info->byte_size; 116 117 if (src_len > dst_len) { 118 error.SetErrorStringWithFormat( 119 "%u bytes is too big to store in register %s (%u bytes)", src_len, 120 reg_info->name, dst_len); 121 return 0; 122 } 123 124 // Use a data extractor to correctly copy and pad the bytes read into the 125 // register value 126 DataExtractor src_data(src, src_len, src_byte_order, 4); 127 128 error = SetValueFromData(reg_info, src_data, 0, true); 129 if (error.Fail()) 130 return 0; 131 132 // If SetValueFromData succeeded, we must have copied all of src_len 133 return src_len; 134 } 135 136 bool RegisterValue::GetScalarValue(Scalar &scalar) const { 137 switch (m_type) { 138 case eTypeInvalid: 139 break; 140 case eTypeBytes: { 141 switch (buffer.length) { 142 default: 143 break; 144 case 1: 145 scalar = *(const uint8_t *)buffer.bytes; 146 return true; 147 case 2: 148 scalar = *reinterpret_cast<const uint16_t *>(buffer.bytes); 149 return true; 150 case 4: 151 scalar = *reinterpret_cast<const uint32_t *>(buffer.bytes); 152 return true; 153 case 8: 154 scalar = *reinterpret_cast<const uint64_t *>(buffer.bytes); 155 return true; 156 case 16: 157 case 32: 158 case 64: 159 if (buffer.length % sizeof(uint64_t) == 0) { 160 const auto length_in_bits = buffer.length * 8; 161 const auto length_in_uint64 = buffer.length / sizeof(uint64_t); 162 scalar = 163 llvm::APInt(length_in_bits, 164 llvm::ArrayRef<uint64_t>( 165 reinterpret_cast<const uint64_t *>(buffer.bytes), 166 length_in_uint64)); 167 return true; 168 } 169 break; 170 } 171 } break; 172 case eTypeUInt8: 173 case eTypeUInt16: 174 case eTypeUInt32: 175 case eTypeUInt64: 176 case eTypeUInt128: 177 case eTypeFloat: 178 case eTypeDouble: 179 case eTypeLongDouble: 180 scalar = m_scalar; 181 return true; 182 } 183 return false; 184 } 185 186 void RegisterValue::Clear() { m_type = eTypeInvalid; } 187 188 RegisterValue::Type RegisterValue::SetType(const RegisterInfo *reg_info) { 189 // To change the type, we simply copy the data in again, using the new format 190 RegisterValue copy; 191 DataExtractor copy_data; 192 if (copy.CopyValue(*this) && copy.GetData(copy_data)) 193 SetValueFromData(reg_info, copy_data, 0, true); 194 195 return m_type; 196 } 197 198 Status RegisterValue::SetValueFromData(const RegisterInfo *reg_info, 199 DataExtractor &src, 200 lldb::offset_t src_offset, 201 bool partial_data_ok) { 202 Status error; 203 204 if (src.GetByteSize() == 0) { 205 error.SetErrorString("empty data."); 206 return error; 207 } 208 209 if (reg_info->byte_size == 0) { 210 error.SetErrorString("invalid register info."); 211 return error; 212 } 213 214 uint32_t src_len = src.GetByteSize() - src_offset; 215 216 if (!partial_data_ok && (src_len < reg_info->byte_size)) { 217 error.SetErrorString("not enough data."); 218 return error; 219 } 220 221 // Cap the data length if there is more than enough bytes for this register 222 // value 223 if (src_len > reg_info->byte_size) 224 src_len = reg_info->byte_size; 225 226 // Zero out the value in case we get partial data... 227 memset(buffer.bytes, 0, sizeof(buffer.bytes)); 228 229 type128 int128; 230 231 m_type = eTypeInvalid; 232 switch (reg_info->encoding) { 233 case eEncodingInvalid: 234 break; 235 case eEncodingUint: 236 case eEncodingSint: 237 if (reg_info->byte_size == 1) 238 SetUInt8(src.GetMaxU32(&src_offset, src_len)); 239 else if (reg_info->byte_size <= 2) 240 SetUInt16(src.GetMaxU32(&src_offset, src_len)); 241 else if (reg_info->byte_size <= 4) 242 SetUInt32(src.GetMaxU32(&src_offset, src_len)); 243 else if (reg_info->byte_size <= 8) 244 SetUInt64(src.GetMaxU64(&src_offset, src_len)); 245 else if (reg_info->byte_size <= 16) { 246 uint64_t data1 = src.GetU64(&src_offset); 247 uint64_t data2 = src.GetU64(&src_offset); 248 if (src.GetByteSize() == eByteOrderBig) { 249 int128.x[0] = data1; 250 int128.x[1] = data2; 251 } else { 252 int128.x[0] = data2; 253 int128.x[1] = data1; 254 } 255 SetUInt128(llvm::APInt(128, 2, int128.x)); 256 } 257 break; 258 case eEncodingIEEE754: 259 if (reg_info->byte_size == sizeof(float)) 260 SetFloat(src.GetFloat(&src_offset)); 261 else if (reg_info->byte_size == sizeof(double)) 262 SetDouble(src.GetDouble(&src_offset)); 263 else if (reg_info->byte_size == sizeof(long double)) 264 SetLongDouble(src.GetLongDouble(&src_offset)); 265 break; 266 case eEncodingVector: { 267 m_type = eTypeBytes; 268 buffer.length = reg_info->byte_size; 269 buffer.byte_order = src.GetByteOrder(); 270 assert(buffer.length <= kMaxRegisterByteSize); 271 if (buffer.length > kMaxRegisterByteSize) 272 buffer.length = kMaxRegisterByteSize; 273 if (src.CopyByteOrderedData( 274 src_offset, // offset within "src" to start extracting data 275 src_len, // src length 276 buffer.bytes, // dst buffer 277 buffer.length, // dst length 278 buffer.byte_order) == 0) // dst byte order 279 { 280 error.SetErrorStringWithFormat( 281 "failed to copy data for register write of %s", reg_info->name); 282 return error; 283 } 284 } 285 } 286 287 if (m_type == eTypeInvalid) 288 error.SetErrorStringWithFormat( 289 "invalid register value type for register %s", reg_info->name); 290 return error; 291 } 292 293 // Helper function for RegisterValue::SetValueFromString() 294 static bool ParseVectorEncoding(const RegisterInfo *reg_info, 295 llvm::StringRef vector_str, 296 const uint32_t byte_size, 297 RegisterValue *reg_value) { 298 // Example: vector_str = "{0x2c 0x4b 0x2a 0x3e 0xd0 0x4f 0x2a 0x3e 0xac 0x4a 299 // 0x2a 0x3e 0x84 0x4f 0x2a 0x3e}". 300 vector_str = vector_str.trim(); 301 vector_str.consume_front("{"); 302 vector_str.consume_back("}"); 303 vector_str = vector_str.trim(); 304 305 char Sep = ' '; 306 307 // The first split should give us: 308 // ('0x2c', '0x4b 0x2a 0x3e 0xd0 0x4f 0x2a 0x3e 0xac 0x4a 0x2a 0x3e 0x84 0x4f 309 // 0x2a 0x3e'). 310 llvm::StringRef car; 311 llvm::StringRef cdr = vector_str; 312 std::tie(car, cdr) = vector_str.split(Sep); 313 std::vector<uint8_t> bytes; 314 unsigned byte = 0; 315 316 // Using radix auto-sensing by passing 0 as the radix. Keep on processing the 317 // vector elements as long as the parsing succeeds and the vector size is < 318 // byte_size. 319 while (!car.getAsInteger(0, byte) && bytes.size() < byte_size) { 320 bytes.push_back(byte); 321 std::tie(car, cdr) = cdr.split(Sep); 322 } 323 324 // Check for vector of exact byte_size elements. 325 if (bytes.size() != byte_size) 326 return false; 327 328 reg_value->SetBytes(&(bytes.front()), byte_size, eByteOrderLittle); 329 return true; 330 } 331 332 static bool UInt64ValueIsValidForByteSize(uint64_t uval64, 333 size_t total_byte_size) { 334 if (total_byte_size > 8) 335 return false; 336 337 if (total_byte_size == 8) 338 return true; 339 340 const uint64_t max = 341 (static_cast<uint64_t>(1) << static_cast<uint64_t>(total_byte_size * 8)) - 342 1; 343 return uval64 <= max; 344 } 345 346 static bool SInt64ValueIsValidForByteSize(int64_t sval64, 347 size_t total_byte_size) { 348 if (total_byte_size > 8) 349 return false; 350 351 if (total_byte_size == 8) 352 return true; 353 354 const int64_t max = (static_cast<int64_t>(1) 355 << static_cast<uint64_t>(total_byte_size * 8 - 1)) - 356 1; 357 const int64_t min = ~(max); 358 return min <= sval64 && sval64 <= max; 359 } 360 361 Status RegisterValue::SetValueFromString(const RegisterInfo *reg_info, 362 llvm::StringRef value_str) { 363 Status error; 364 if (reg_info == nullptr) { 365 error.SetErrorString("Invalid register info argument."); 366 return error; 367 } 368 369 m_type = eTypeInvalid; 370 if (value_str.empty()) { 371 error.SetErrorString("Invalid c-string value string."); 372 return error; 373 } 374 const uint32_t byte_size = reg_info->byte_size; 375 376 uint64_t uval64; 377 int64_t ival64; 378 float flt_val; 379 double dbl_val; 380 long double ldbl_val; 381 switch (reg_info->encoding) { 382 case eEncodingInvalid: 383 error.SetErrorString("Invalid encoding."); 384 break; 385 386 case eEncodingUint: 387 if (byte_size > sizeof(uint64_t)) { 388 error.SetErrorStringWithFormat( 389 "unsupported unsigned integer byte size: %u", byte_size); 390 break; 391 } 392 if (value_str.getAsInteger(0, uval64)) { 393 error.SetErrorStringWithFormat( 394 "'%s' is not a valid unsigned integer string value", 395 value_str.str().c_str()); 396 break; 397 } 398 399 if (!UInt64ValueIsValidForByteSize(uval64, byte_size)) { 400 error.SetErrorStringWithFormat( 401 "value 0x%" PRIx64 402 " is too large to fit in a %u byte unsigned integer value", 403 uval64, byte_size); 404 break; 405 } 406 407 if (!SetUInt(uval64, reg_info->byte_size)) { 408 error.SetErrorStringWithFormat( 409 "unsupported unsigned integer byte size: %u", byte_size); 410 break; 411 } 412 break; 413 414 case eEncodingSint: 415 if (byte_size > sizeof(long long)) { 416 error.SetErrorStringWithFormat("unsupported signed integer byte size: %u", 417 byte_size); 418 break; 419 } 420 421 if (value_str.getAsInteger(0, ival64)) { 422 error.SetErrorStringWithFormat( 423 "'%s' is not a valid signed integer string value", 424 value_str.str().c_str()); 425 break; 426 } 427 428 if (!SInt64ValueIsValidForByteSize(ival64, byte_size)) { 429 error.SetErrorStringWithFormat( 430 "value 0x%" PRIx64 431 " is too large to fit in a %u byte signed integer value", 432 ival64, byte_size); 433 break; 434 } 435 436 if (!SetUInt(ival64, reg_info->byte_size)) { 437 error.SetErrorStringWithFormat("unsupported signed integer byte size: %u", 438 byte_size); 439 break; 440 } 441 break; 442 443 case eEncodingIEEE754: { 444 std::string value_string = value_str; 445 if (byte_size == sizeof(float)) { 446 if (::sscanf(value_string.c_str(), "%f", &flt_val) != 1) { 447 error.SetErrorStringWithFormat("'%s' is not a valid float string value", 448 value_string.c_str()); 449 break; 450 } 451 m_scalar = flt_val; 452 m_type = eTypeFloat; 453 } else if (byte_size == sizeof(double)) { 454 if (::sscanf(value_string.c_str(), "%lf", &dbl_val) != 1) { 455 error.SetErrorStringWithFormat("'%s' is not a valid float string value", 456 value_string.c_str()); 457 break; 458 } 459 m_scalar = dbl_val; 460 m_type = eTypeDouble; 461 } else if (byte_size == sizeof(long double)) { 462 if (::sscanf(value_string.c_str(), "%Lf", &ldbl_val) != 1) { 463 error.SetErrorStringWithFormat("'%s' is not a valid float string value", 464 value_string.c_str()); 465 break; 466 } 467 m_scalar = ldbl_val; 468 m_type = eTypeLongDouble; 469 } else { 470 error.SetErrorStringWithFormat("unsupported float byte size: %u", 471 byte_size); 472 return error; 473 } 474 break; 475 } 476 case eEncodingVector: 477 if (!ParseVectorEncoding(reg_info, value_str, byte_size, this)) 478 error.SetErrorString("unrecognized vector encoding string value."); 479 break; 480 } 481 482 return error; 483 } 484 485 bool RegisterValue::SignExtend(uint32_t sign_bitpos) { 486 switch (m_type) { 487 case eTypeInvalid: 488 break; 489 490 case eTypeUInt8: 491 case eTypeUInt16: 492 case eTypeUInt32: 493 case eTypeUInt64: 494 case eTypeUInt128: 495 return m_scalar.SignExtend(sign_bitpos); 496 case eTypeFloat: 497 case eTypeDouble: 498 case eTypeLongDouble: 499 case eTypeBytes: 500 break; 501 } 502 return false; 503 } 504 505 bool RegisterValue::CopyValue(const RegisterValue &rhs) { 506 if (this == &rhs) 507 return rhs.m_type != eTypeInvalid; 508 509 m_type = rhs.m_type; 510 switch (m_type) { 511 case eTypeInvalid: 512 return false; 513 case eTypeUInt8: 514 case eTypeUInt16: 515 case eTypeUInt32: 516 case eTypeUInt64: 517 case eTypeUInt128: 518 case eTypeFloat: 519 case eTypeDouble: 520 case eTypeLongDouble: 521 m_scalar = rhs.m_scalar; 522 break; 523 case eTypeBytes: 524 assert(rhs.buffer.length <= kMaxRegisterByteSize); 525 ::memcpy(buffer.bytes, rhs.buffer.bytes, kMaxRegisterByteSize); 526 buffer.length = rhs.buffer.length; 527 buffer.byte_order = rhs.buffer.byte_order; 528 break; 529 } 530 return true; 531 } 532 533 uint16_t RegisterValue::GetAsUInt16(uint16_t fail_value, 534 bool *success_ptr) const { 535 if (success_ptr) 536 *success_ptr = true; 537 538 switch (m_type) { 539 default: 540 break; 541 case eTypeUInt8: 542 case eTypeUInt16: 543 return m_scalar.UShort(fail_value); 544 case eTypeBytes: { 545 switch (buffer.length) { 546 default: 547 break; 548 case 1: 549 case 2: 550 return *reinterpret_cast<const uint16_t *>(buffer.bytes); 551 } 552 } break; 553 } 554 if (success_ptr) 555 *success_ptr = false; 556 return fail_value; 557 } 558 559 uint32_t RegisterValue::GetAsUInt32(uint32_t fail_value, 560 bool *success_ptr) const { 561 if (success_ptr) 562 *success_ptr = true; 563 switch (m_type) { 564 default: 565 break; 566 case eTypeUInt8: 567 case eTypeUInt16: 568 case eTypeUInt32: 569 case eTypeFloat: 570 case eTypeDouble: 571 case eTypeLongDouble: 572 return m_scalar.UInt(fail_value); 573 case eTypeBytes: { 574 switch (buffer.length) { 575 default: 576 break; 577 case 1: 578 case 2: 579 case 4: 580 return *reinterpret_cast<const uint32_t *>(buffer.bytes); 581 } 582 } break; 583 } 584 if (success_ptr) 585 *success_ptr = false; 586 return fail_value; 587 } 588 589 uint64_t RegisterValue::GetAsUInt64(uint64_t fail_value, 590 bool *success_ptr) const { 591 if (success_ptr) 592 *success_ptr = true; 593 switch (m_type) { 594 default: 595 break; 596 case eTypeUInt8: 597 case eTypeUInt16: 598 case eTypeUInt32: 599 case eTypeUInt64: 600 case eTypeFloat: 601 case eTypeDouble: 602 case eTypeLongDouble: 603 return m_scalar.ULongLong(fail_value); 604 case eTypeBytes: { 605 switch (buffer.length) { 606 default: 607 break; 608 case 1: 609 return *(const uint8_t *)buffer.bytes; 610 case 2: 611 return *reinterpret_cast<const uint16_t *>(buffer.bytes); 612 case 4: 613 return *reinterpret_cast<const uint32_t *>(buffer.bytes); 614 case 8: 615 return *reinterpret_cast<const uint64_t *>(buffer.bytes); 616 } 617 } break; 618 } 619 if (success_ptr) 620 *success_ptr = false; 621 return fail_value; 622 } 623 624 llvm::APInt RegisterValue::GetAsUInt128(const llvm::APInt &fail_value, 625 bool *success_ptr) const { 626 if (success_ptr) 627 *success_ptr = true; 628 switch (m_type) { 629 default: 630 break; 631 case eTypeUInt8: 632 case eTypeUInt16: 633 case eTypeUInt32: 634 case eTypeUInt64: 635 case eTypeUInt128: 636 case eTypeFloat: 637 case eTypeDouble: 638 case eTypeLongDouble: 639 return m_scalar.UInt128(fail_value); 640 case eTypeBytes: { 641 switch (buffer.length) { 642 default: 643 break; 644 case 1: 645 case 2: 646 case 4: 647 case 8: 648 case 16: 649 return llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, 650 (reinterpret_cast<const type128 *>(buffer.bytes))->x); 651 } 652 } break; 653 } 654 if (success_ptr) 655 *success_ptr = false; 656 return fail_value; 657 } 658 659 float RegisterValue::GetAsFloat(float fail_value, bool *success_ptr) const { 660 if (success_ptr) 661 *success_ptr = true; 662 switch (m_type) { 663 default: 664 break; 665 case eTypeUInt32: 666 case eTypeUInt64: 667 case eTypeUInt128: 668 case eTypeFloat: 669 case eTypeDouble: 670 case eTypeLongDouble: 671 return m_scalar.Float(fail_value); 672 } 673 if (success_ptr) 674 *success_ptr = false; 675 return fail_value; 676 } 677 678 double RegisterValue::GetAsDouble(double fail_value, bool *success_ptr) const { 679 if (success_ptr) 680 *success_ptr = true; 681 switch (m_type) { 682 default: 683 break; 684 685 case eTypeUInt32: 686 case eTypeUInt64: 687 case eTypeUInt128: 688 case eTypeFloat: 689 case eTypeDouble: 690 case eTypeLongDouble: 691 return m_scalar.Double(fail_value); 692 } 693 if (success_ptr) 694 *success_ptr = false; 695 return fail_value; 696 } 697 698 long double RegisterValue::GetAsLongDouble(long double fail_value, 699 bool *success_ptr) const { 700 if (success_ptr) 701 *success_ptr = true; 702 switch (m_type) { 703 default: 704 break; 705 706 case eTypeUInt32: 707 case eTypeUInt64: 708 case eTypeUInt128: 709 case eTypeFloat: 710 case eTypeDouble: 711 case eTypeLongDouble: 712 return m_scalar.LongDouble(); 713 } 714 if (success_ptr) 715 *success_ptr = false; 716 return fail_value; 717 } 718 719 const void *RegisterValue::GetBytes() const { 720 switch (m_type) { 721 case eTypeInvalid: 722 break; 723 case eTypeUInt8: 724 case eTypeUInt16: 725 case eTypeUInt32: 726 case eTypeUInt64: 727 case eTypeUInt128: 728 case eTypeFloat: 729 case eTypeDouble: 730 case eTypeLongDouble: 731 return m_scalar.GetBytes(); 732 case eTypeBytes: 733 return buffer.bytes; 734 } 735 return nullptr; 736 } 737 738 uint32_t RegisterValue::GetByteSize() const { 739 switch (m_type) { 740 case eTypeInvalid: 741 break; 742 case eTypeUInt8: 743 return 1; 744 case eTypeUInt16: 745 return 2; 746 case eTypeUInt32: 747 case eTypeUInt64: 748 case eTypeUInt128: 749 case eTypeFloat: 750 case eTypeDouble: 751 case eTypeLongDouble: 752 return m_scalar.GetByteSize(); 753 case eTypeBytes: 754 return buffer.length; 755 } 756 return 0; 757 } 758 759 bool RegisterValue::SetUInt(uint64_t uint, uint32_t byte_size) { 760 if (byte_size == 0) { 761 SetUInt64(uint); 762 } else if (byte_size == 1) { 763 SetUInt8(uint); 764 } else if (byte_size <= 2) { 765 SetUInt16(uint); 766 } else if (byte_size <= 4) { 767 SetUInt32(uint); 768 } else if (byte_size <= 8) { 769 SetUInt64(uint); 770 } else if (byte_size <= 16) { 771 SetUInt128(llvm::APInt(128, uint)); 772 } else 773 return false; 774 return true; 775 } 776 777 void RegisterValue::SetBytes(const void *bytes, size_t length, 778 lldb::ByteOrder byte_order) { 779 // If this assertion fires off we need to increase the size of buffer.bytes, 780 // or make it something that is allocated on the heap. Since the data buffer 781 // is in a union, we can't make it a collection class like SmallVector... 782 if (bytes && length > 0) { 783 assert(length <= sizeof(buffer.bytes) && 784 "Storing too many bytes in a RegisterValue."); 785 m_type = eTypeBytes; 786 buffer.length = length; 787 memcpy(buffer.bytes, bytes, length); 788 buffer.byte_order = byte_order; 789 } else { 790 m_type = eTypeInvalid; 791 buffer.length = 0; 792 } 793 } 794 795 bool RegisterValue::operator==(const RegisterValue &rhs) const { 796 if (m_type == rhs.m_type) { 797 switch (m_type) { 798 case eTypeInvalid: 799 return true; 800 case eTypeUInt8: 801 case eTypeUInt16: 802 case eTypeUInt32: 803 case eTypeUInt64: 804 case eTypeUInt128: 805 case eTypeFloat: 806 case eTypeDouble: 807 case eTypeLongDouble: 808 return m_scalar == rhs.m_scalar; 809 case eTypeBytes: 810 if (buffer.length != rhs.buffer.length) 811 return false; 812 else { 813 uint8_t length = buffer.length; 814 if (length > kMaxRegisterByteSize) 815 length = kMaxRegisterByteSize; 816 return memcmp(buffer.bytes, rhs.buffer.bytes, length) == 0; 817 } 818 break; 819 } 820 } 821 return false; 822 } 823 824 bool RegisterValue::operator!=(const RegisterValue &rhs) const { 825 return !(*this == rhs); 826 } 827 828 bool RegisterValue::ClearBit(uint32_t bit) { 829 switch (m_type) { 830 case eTypeInvalid: 831 break; 832 833 case eTypeUInt8: 834 case eTypeUInt16: 835 case eTypeUInt32: 836 case eTypeUInt64: 837 case eTypeUInt128: 838 if (bit < (GetByteSize() * 8)) { 839 return m_scalar.ClearBit(bit); 840 } 841 break; 842 843 case eTypeFloat: 844 case eTypeDouble: 845 case eTypeLongDouble: 846 break; 847 848 case eTypeBytes: 849 if (buffer.byte_order == eByteOrderBig || 850 buffer.byte_order == eByteOrderLittle) { 851 uint32_t byte_idx; 852 if (buffer.byte_order == eByteOrderBig) 853 byte_idx = buffer.length - (bit / 8) - 1; 854 else 855 byte_idx = bit / 8; 856 857 const uint32_t byte_bit = bit % 8; 858 if (byte_idx < buffer.length) { 859 buffer.bytes[byte_idx] &= ~(1u << byte_bit); 860 return true; 861 } 862 } 863 break; 864 } 865 return false; 866 } 867 868 bool RegisterValue::SetBit(uint32_t bit) { 869 switch (m_type) { 870 case eTypeInvalid: 871 break; 872 873 case eTypeUInt8: 874 case eTypeUInt16: 875 case eTypeUInt32: 876 case eTypeUInt64: 877 case eTypeUInt128: 878 if (bit < (GetByteSize() * 8)) { 879 return m_scalar.SetBit(bit); 880 } 881 break; 882 883 case eTypeFloat: 884 case eTypeDouble: 885 case eTypeLongDouble: 886 break; 887 888 case eTypeBytes: 889 if (buffer.byte_order == eByteOrderBig || 890 buffer.byte_order == eByteOrderLittle) { 891 uint32_t byte_idx; 892 if (buffer.byte_order == eByteOrderBig) 893 byte_idx = buffer.length - (bit / 8) - 1; 894 else 895 byte_idx = bit / 8; 896 897 const uint32_t byte_bit = bit % 8; 898 if (byte_idx < buffer.length) { 899 buffer.bytes[byte_idx] |= (1u << byte_bit); 900 return true; 901 } 902 } 903 break; 904 } 905 return false; 906 } 907