1 //===-- Scalar.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/Scalar.h" 10 #include "lldb/Utility/DataBufferHeap.h" 11 #include "lldb/Utility/DataExtractor.h" 12 #include "lldb/Utility/Endian.h" 13 #include "lldb/Utility/Status.h" 14 #include "lldb/Utility/Stream.h" 15 #include "lldb/Utility/StreamString.h" 16 #include "lldb/lldb-types.h" 17 #include "llvm/ADT/APSInt.h" 18 #include "llvm/ADT/SmallString.h" 19 20 #include <cinttypes> 21 #include <cstdio> 22 23 using namespace lldb; 24 using namespace lldb_private; 25 26 using llvm::APFloat; 27 using llvm::APInt; 28 using llvm::APSInt; 29 30 Scalar::PromotionKey Scalar::GetPromoKey() const { 31 switch (m_type) { 32 case e_void: 33 return PromotionKey{e_void, 0, false}; 34 case e_int: 35 return PromotionKey{e_int, m_integer.getBitWidth(), m_integer.isUnsigned()}; 36 case e_float: 37 return GetFloatPromoKey(m_float.getSemantics()); 38 } 39 llvm_unreachable("Unhandled category!"); 40 } 41 42 Scalar::PromotionKey Scalar::GetFloatPromoKey(const llvm::fltSemantics &sem) { 43 static const llvm::fltSemantics *const order[] = { 44 &APFloat::IEEEsingle(), &APFloat::IEEEdouble(), 45 &APFloat::x87DoubleExtended()}; 46 for (const auto &entry : llvm::enumerate(order)) { 47 if (entry.value() == &sem) 48 return PromotionKey{e_float, entry.index(), false}; 49 } 50 llvm_unreachable("Unsupported semantics!"); 51 } 52 53 // Promote to max type currently follows the ANSI C rule for type promotion in 54 // expressions. 55 Scalar::Type Scalar::PromoteToMaxType(Scalar &lhs, Scalar &rhs) { 56 const auto &Promote = [](Scalar &a, const Scalar &b) { 57 switch (b.GetType()) { 58 case e_void: 59 break; 60 case e_int: 61 a.IntegralPromote(b.m_integer.getBitWidth(), b.m_integer.isSigned()); 62 break; 63 case e_float: 64 a.FloatPromote(b.m_float.getSemantics()); 65 } 66 }; 67 68 PromotionKey lhs_key = lhs.GetPromoKey(); 69 PromotionKey rhs_key = rhs.GetPromoKey(); 70 71 if (lhs_key > rhs_key) 72 Promote(rhs, lhs); 73 else if (rhs_key > lhs_key) 74 Promote(lhs, rhs); 75 76 // Make sure our type promotion worked as expected 77 if (lhs.GetPromoKey() == rhs.GetPromoKey()) 78 return lhs.GetType(); // Return the resulting type 79 80 // Return the void type (zero) if we fail to promote either of the values. 81 return Scalar::e_void; 82 } 83 84 bool Scalar::GetData(DataExtractor &data, size_t limit_byte_size) const { 85 size_t byte_size = GetByteSize(); 86 if (byte_size == 0) { 87 data.Clear(); 88 return false; 89 } 90 auto buffer_up = std::make_unique<DataBufferHeap>(byte_size, 0); 91 GetBytes(buffer_up->GetData()); 92 lldb::offset_t offset = 0; 93 94 if (limit_byte_size < byte_size) { 95 if (endian::InlHostByteOrder() == eByteOrderLittle) { 96 // On little endian systems if we want fewer bytes from the current 97 // type we just specify fewer bytes since the LSByte is first... 98 byte_size = limit_byte_size; 99 } else if (endian::InlHostByteOrder() == eByteOrderBig) { 100 // On big endian systems if we want fewer bytes from the current type 101 // have to advance our initial byte pointer and trim down the number of 102 // bytes since the MSByte is first 103 offset = byte_size - limit_byte_size; 104 byte_size = limit_byte_size; 105 } 106 } 107 108 data.SetData(std::move(buffer_up), offset, byte_size); 109 data.SetByteOrder(endian::InlHostByteOrder()); 110 return true; 111 } 112 113 void Scalar::GetBytes(llvm::MutableArrayRef<uint8_t> storage) const { 114 assert(storage.size() >= GetByteSize()); 115 116 const auto &store = [&](const llvm::APInt &val) { 117 StoreIntToMemory(val, storage.data(), (val.getBitWidth() + 7) / 8); 118 }; 119 switch (m_type) { 120 case e_void: 121 break; 122 case e_int: 123 store(m_integer); 124 break; 125 case e_float: 126 store(m_float.bitcastToAPInt()); 127 break; 128 } 129 } 130 131 size_t Scalar::GetByteSize() const { 132 switch (m_type) { 133 case e_void: 134 break; 135 case e_int: 136 return (m_integer.getBitWidth() / 8); 137 case e_float: 138 return m_float.bitcastToAPInt().getBitWidth() / 8; 139 } 140 return 0; 141 } 142 143 bool Scalar::IsZero() const { 144 switch (m_type) { 145 case e_void: 146 break; 147 case e_int: 148 return m_integer.isNullValue(); 149 case e_float: 150 return m_float.isZero(); 151 } 152 return false; 153 } 154 155 void Scalar::GetValue(Stream *s, bool show_type) const { 156 if (show_type) 157 s->Printf("(%s) ", GetTypeAsCString()); 158 159 switch (m_type) { 160 case e_void: 161 break; 162 case e_int: 163 s->PutCString(m_integer.toString(10)); 164 break; 165 case e_float: 166 llvm::SmallString<24> string; 167 m_float.toString(string); 168 s->PutCString(string); 169 break; 170 } 171 } 172 173 void Scalar::TruncOrExtendTo(uint16_t bits, bool sign) { 174 m_integer.setIsSigned(sign); 175 m_integer = m_integer.extOrTrunc(bits); 176 } 177 178 bool Scalar::IntegralPromote(uint16_t bits, bool sign) { 179 switch (m_type) { 180 case e_void: 181 case e_float: 182 break; 183 case e_int: 184 if (GetPromoKey() > PromotionKey(e_int, bits, !sign)) 185 break; 186 m_integer = m_integer.extOrTrunc(bits); 187 m_integer.setIsSigned(sign); 188 return true; 189 } 190 return false; 191 } 192 193 bool Scalar::FloatPromote(const llvm::fltSemantics &semantics) { 194 bool success = false; 195 switch (m_type) { 196 case e_void: 197 break; 198 case e_int: 199 m_float = llvm::APFloat(semantics); 200 m_float.convertFromAPInt(m_integer, m_integer.isSigned(), 201 llvm::APFloat::rmNearestTiesToEven); 202 success = true; 203 break; 204 case e_float: 205 if (GetFloatPromoKey(semantics) < GetFloatPromoKey(m_float.getSemantics())) 206 break; 207 bool ignore; 208 success = true; 209 m_float.convert(semantics, llvm::APFloat::rmNearestTiesToEven, &ignore); 210 } 211 212 if (success) 213 m_type = e_float; 214 return success; 215 } 216 217 const char *Scalar::GetValueTypeAsCString(Scalar::Type type) { 218 switch (type) { 219 case e_void: 220 return "void"; 221 case e_int: 222 return "int"; 223 case e_float: 224 return "float"; 225 } 226 return "???"; 227 } 228 229 bool Scalar::IsSigned() const { 230 switch (m_type) { 231 case e_void: 232 return false; 233 case e_int: 234 return m_integer.isSigned(); 235 case e_float: 236 return true; 237 } 238 llvm_unreachable("Unrecognized type!"); 239 } 240 241 bool Scalar::MakeSigned() { 242 bool success = false; 243 244 switch (m_type) { 245 case e_void: 246 break; 247 case e_int: 248 m_integer.setIsSigned(true); 249 success = true; 250 break; 251 case e_float: 252 success = true; 253 break; 254 } 255 256 return success; 257 } 258 259 bool Scalar::MakeUnsigned() { 260 bool success = false; 261 262 switch (m_type) { 263 case e_void: 264 break; 265 case e_int: 266 m_integer.setIsUnsigned(true); 267 success = true; 268 break; 269 case e_float: 270 success = true; 271 break; 272 } 273 274 return success; 275 } 276 277 static llvm::APInt ToAPInt(const llvm::APFloat &f, unsigned bits, 278 bool is_unsigned) { 279 llvm::APSInt result(bits, is_unsigned); 280 bool isExact; 281 f.convertToInteger(result, llvm::APFloat::rmTowardZero, &isExact); 282 return std::move(result); 283 } 284 285 template <typename T> T Scalar::GetAs(T fail_value) const { 286 switch (m_type) { 287 case e_void: 288 break; 289 case e_int: { 290 APSInt ext = m_integer.extOrTrunc(sizeof(T) * 8); 291 if (ext.isSigned()) 292 return ext.getSExtValue(); 293 return ext.getZExtValue(); 294 } 295 case e_float: 296 return ToAPInt(m_float, sizeof(T) * 8, std::is_unsigned<T>::value) 297 .getSExtValue(); 298 } 299 return fail_value; 300 } 301 302 signed char Scalar::SChar(signed char fail_value) const { 303 return GetAs<signed char>(fail_value); 304 } 305 306 unsigned char Scalar::UChar(unsigned char fail_value) const { 307 return GetAs<unsigned char>(fail_value); 308 } 309 310 short Scalar::SShort(short fail_value) const { 311 return GetAs<short>(fail_value); 312 } 313 314 unsigned short Scalar::UShort(unsigned short fail_value) const { 315 return GetAs<unsigned short>(fail_value); 316 } 317 318 int Scalar::SInt(int fail_value) const { return GetAs<int>(fail_value); } 319 320 unsigned int Scalar::UInt(unsigned int fail_value) const { 321 return GetAs<unsigned int>(fail_value); 322 } 323 324 long Scalar::SLong(long fail_value) const { return GetAs<long>(fail_value); } 325 326 unsigned long Scalar::ULong(unsigned long fail_value) const { 327 return GetAs<unsigned long>(fail_value); 328 } 329 330 long long Scalar::SLongLong(long long fail_value) const { 331 return GetAs<long long>(fail_value); 332 } 333 334 unsigned long long Scalar::ULongLong(unsigned long long fail_value) const { 335 return GetAs<unsigned long long>(fail_value); 336 } 337 338 llvm::APInt Scalar::SInt128(const llvm::APInt &fail_value) const { 339 switch (m_type) { 340 case e_void: 341 break; 342 case e_int: 343 return m_integer; 344 case e_float: 345 return ToAPInt(m_float, 128, /*is_unsigned=*/false); 346 } 347 return fail_value; 348 } 349 350 llvm::APInt Scalar::UInt128(const llvm::APInt &fail_value) const { 351 switch (m_type) { 352 case e_void: 353 break; 354 case e_int: 355 return m_integer; 356 case e_float: 357 return ToAPInt(m_float, 128, /*is_unsigned=*/true); 358 } 359 return fail_value; 360 } 361 362 float Scalar::Float(float fail_value) const { 363 switch (m_type) { 364 case e_void: 365 break; 366 case e_int: 367 if (m_integer.isSigned()) 368 return llvm::APIntOps::RoundSignedAPIntToFloat(m_integer); 369 return llvm::APIntOps::RoundAPIntToFloat(m_integer); 370 371 case e_float: { 372 APFloat result = m_float; 373 bool losesInfo; 374 result.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, 375 &losesInfo); 376 return result.convertToFloat(); 377 } 378 } 379 return fail_value; 380 } 381 382 double Scalar::Double(double fail_value) const { 383 switch (m_type) { 384 case e_void: 385 break; 386 case e_int: 387 if (m_integer.isSigned()) 388 return llvm::APIntOps::RoundSignedAPIntToDouble(m_integer); 389 return llvm::APIntOps::RoundAPIntToDouble(m_integer); 390 391 case e_float: { 392 APFloat result = m_float; 393 bool losesInfo; 394 result.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, 395 &losesInfo); 396 return result.convertToDouble(); 397 } 398 } 399 return fail_value; 400 } 401 402 long double Scalar::LongDouble(long double fail_value) const { 403 /// No way to get more precision at the moment. 404 return static_cast<long double>(Double(fail_value)); 405 } 406 407 Scalar &Scalar::operator+=(Scalar rhs) { 408 Scalar copy = *this; 409 if ((m_type = PromoteToMaxType(copy, rhs)) != Scalar::e_void) { 410 switch (m_type) { 411 case e_void: 412 break; 413 case e_int: 414 m_integer = copy.m_integer + rhs.m_integer; 415 break; 416 417 case e_float: 418 m_float = copy.m_float + rhs.m_float; 419 break; 420 } 421 } 422 return *this; 423 } 424 425 Scalar &Scalar::operator<<=(const Scalar &rhs) { 426 if (m_type == e_int && rhs.m_type == e_int) 427 static_cast<APInt &>(m_integer) <<= rhs.m_integer; 428 else 429 m_type = e_void; 430 return *this; 431 } 432 433 bool Scalar::ShiftRightLogical(const Scalar &rhs) { 434 if (m_type == e_int && rhs.m_type == e_int) { 435 m_integer = m_integer.lshr(rhs.m_integer); 436 return true; 437 } 438 m_type = e_void; 439 return false; 440 } 441 442 Scalar &Scalar::operator>>=(const Scalar &rhs) { 443 switch (m_type) { 444 case e_void: 445 case e_float: 446 m_type = e_void; 447 break; 448 449 case e_int: 450 switch (rhs.m_type) { 451 case e_void: 452 case e_float: 453 m_type = e_void; 454 break; 455 case e_int: 456 m_integer = m_integer.ashr(rhs.m_integer); 457 break; 458 } 459 break; 460 } 461 return *this; 462 } 463 464 Scalar &Scalar::operator&=(const Scalar &rhs) { 465 if (m_type == e_int && rhs.m_type == e_int) 466 m_integer &= rhs.m_integer; 467 else 468 m_type = e_void; 469 return *this; 470 } 471 472 bool Scalar::AbsoluteValue() { 473 switch (m_type) { 474 case e_void: 475 break; 476 477 case e_int: 478 if (m_integer.isNegative()) 479 m_integer = -m_integer; 480 return true; 481 482 case e_float: 483 m_float.clearSign(); 484 return true; 485 } 486 return false; 487 } 488 489 bool Scalar::UnaryNegate() { 490 switch (m_type) { 491 case e_void: 492 break; 493 case e_int: 494 m_integer = -m_integer; 495 return true; 496 case e_float: 497 m_float.changeSign(); 498 return true; 499 } 500 return false; 501 } 502 503 bool Scalar::OnesComplement() { 504 if (m_type == e_int) { 505 m_integer = ~m_integer; 506 return true; 507 } 508 509 return false; 510 } 511 512 const Scalar lldb_private::operator+(const Scalar &lhs, const Scalar &rhs) { 513 Scalar result = lhs; 514 result += rhs; 515 return result; 516 } 517 518 const Scalar lldb_private::operator-(Scalar lhs, Scalar rhs) { 519 Scalar result; 520 if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) { 521 switch (result.m_type) { 522 case Scalar::e_void: 523 break; 524 case Scalar::e_int: 525 result.m_integer = lhs.m_integer - rhs.m_integer; 526 break; 527 case Scalar::e_float: 528 result.m_float = lhs.m_float - rhs.m_float; 529 break; 530 } 531 } 532 return result; 533 } 534 535 const Scalar lldb_private::operator/(Scalar lhs, Scalar rhs) { 536 Scalar result; 537 if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void && 538 !rhs.IsZero()) { 539 switch (result.m_type) { 540 case Scalar::e_void: 541 break; 542 case Scalar::e_int: 543 result.m_integer = lhs.m_integer / rhs.m_integer; 544 return result; 545 case Scalar::e_float: 546 result.m_float = lhs.m_float / rhs.m_float; 547 return result; 548 } 549 } 550 // For division only, the only way it should make it here is if a promotion 551 // failed, or if we are trying to do a divide by zero. 552 result.m_type = Scalar::e_void; 553 return result; 554 } 555 556 const Scalar lldb_private::operator*(Scalar lhs, Scalar rhs) { 557 Scalar result; 558 if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) { 559 switch (result.m_type) { 560 case Scalar::e_void: 561 break; 562 case Scalar::e_int: 563 result.m_integer = lhs.m_integer * rhs.m_integer; 564 break; 565 case Scalar::e_float: 566 result.m_float = lhs.m_float * rhs.m_float; 567 break; 568 } 569 } 570 return result; 571 } 572 573 const Scalar lldb_private::operator&(Scalar lhs, Scalar rhs) { 574 Scalar result; 575 if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) { 576 if (result.m_type == Scalar::e_int) 577 result.m_integer = lhs.m_integer & rhs.m_integer; 578 else 579 result.m_type = Scalar::e_void; 580 } 581 return result; 582 } 583 584 const Scalar lldb_private::operator|(Scalar lhs, Scalar rhs) { 585 Scalar result; 586 if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) { 587 if (result.m_type == Scalar::e_int) 588 result.m_integer = lhs.m_integer | rhs.m_integer; 589 else 590 result.m_type = Scalar::e_void; 591 } 592 return result; 593 } 594 595 const Scalar lldb_private::operator%(Scalar lhs, Scalar rhs) { 596 Scalar result; 597 if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) { 598 if (!rhs.IsZero() && result.m_type == Scalar::e_int) { 599 result.m_integer = lhs.m_integer % rhs.m_integer; 600 return result; 601 } 602 } 603 result.m_type = Scalar::e_void; 604 return result; 605 } 606 607 const Scalar lldb_private::operator^(Scalar lhs, Scalar rhs) { 608 Scalar result; 609 if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) { 610 if (result.m_type == Scalar::e_int) 611 result.m_integer = lhs.m_integer ^ rhs.m_integer; 612 else 613 result.m_type = Scalar::e_void; 614 } 615 return result; 616 } 617 618 const Scalar lldb_private::operator<<(const Scalar &lhs, const Scalar &rhs) { 619 Scalar result = lhs; 620 result <<= rhs; 621 return result; 622 } 623 624 const Scalar lldb_private::operator>>(const Scalar &lhs, const Scalar &rhs) { 625 Scalar result = lhs; 626 result >>= rhs; 627 return result; 628 } 629 630 Status Scalar::SetValueFromCString(const char *value_str, Encoding encoding, 631 size_t byte_size) { 632 Status error; 633 if (value_str == nullptr || value_str[0] == '\0') { 634 error.SetErrorString("Invalid c-string value string."); 635 return error; 636 } 637 switch (encoding) { 638 case eEncodingInvalid: 639 error.SetErrorString("Invalid encoding."); 640 break; 641 642 case eEncodingSint: 643 case eEncodingUint: { 644 llvm::StringRef str = value_str; 645 bool is_signed = encoding == eEncodingSint; 646 bool is_negative = is_signed && str.consume_front("-"); 647 APInt integer; 648 if (str.getAsInteger(0, integer)) { 649 error.SetErrorStringWithFormatv( 650 "'{0}' is not a valid integer string value", value_str); 651 break; 652 } 653 bool fits; 654 if (is_signed) { 655 integer = integer.zext(integer.getBitWidth() + 1); 656 if (is_negative) 657 integer.negate(); 658 fits = integer.isSignedIntN(byte_size * 8); 659 } else 660 fits = integer.isIntN(byte_size * 8); 661 if (!fits) { 662 error.SetErrorStringWithFormatv( 663 "value {0} is too large to fit in a {1} byte integer value", 664 value_str, byte_size); 665 break; 666 } 667 m_type = e_int; 668 m_integer = 669 APSInt(std::move(integer), !is_signed).extOrTrunc(8 * byte_size); 670 break; 671 } 672 673 case eEncodingIEEE754: { 674 // FIXME: It's not possible to unambiguously map a byte size to a floating 675 // point type. This function should be refactored to take an explicit 676 // semantics argument. 677 const llvm::fltSemantics &sem = 678 byte_size <= 4 ? APFloat::IEEEsingle() 679 : byte_size <= 8 ? APFloat::IEEEdouble() 680 : APFloat::x87DoubleExtended(); 681 APFloat f(sem); 682 if (llvm::Expected<APFloat::opStatus> op = 683 f.convertFromString(value_str, APFloat::rmNearestTiesToEven)) { 684 m_type = e_float; 685 m_float = std::move(f); 686 } else 687 error = op.takeError(); 688 break; 689 } 690 691 case eEncodingVector: 692 error.SetErrorString("vector encoding unsupported."); 693 break; 694 } 695 if (error.Fail()) 696 m_type = e_void; 697 698 return error; 699 } 700 701 Status Scalar::SetValueFromData(const DataExtractor &data, 702 lldb::Encoding encoding, size_t byte_size) { 703 Status error; 704 switch (encoding) { 705 case lldb::eEncodingInvalid: 706 error.SetErrorString("invalid encoding"); 707 break; 708 case lldb::eEncodingVector: 709 error.SetErrorString("vector encoding unsupported"); 710 break; 711 case lldb::eEncodingUint: 712 case lldb::eEncodingSint: { 713 if (data.GetByteSize() < byte_size) 714 return Status("insufficient data"); 715 m_type = e_int; 716 m_integer = 717 APSInt(APInt::getNullValue(8 * byte_size), encoding == eEncodingUint); 718 if (data.GetByteOrder() == endian::InlHostByteOrder()) { 719 llvm::LoadIntFromMemory(m_integer, data.GetDataStart(), byte_size); 720 } else { 721 std::vector<uint8_t> buffer(byte_size); 722 std::copy_n(data.GetDataStart(), byte_size, buffer.rbegin()); 723 llvm::LoadIntFromMemory(m_integer, buffer.data(), byte_size); 724 } 725 break; 726 } 727 case lldb::eEncodingIEEE754: { 728 lldb::offset_t offset = 0; 729 730 if (byte_size == sizeof(float)) 731 operator=(data.GetFloat(&offset)); 732 else if (byte_size == sizeof(double)) 733 operator=(data.GetDouble(&offset)); 734 else if (byte_size == sizeof(long double)) 735 operator=(data.GetLongDouble(&offset)); 736 else 737 error.SetErrorStringWithFormat("unsupported float byte size: %" PRIu64 "", 738 static_cast<uint64_t>(byte_size)); 739 } break; 740 } 741 742 return error; 743 } 744 745 bool Scalar::SignExtend(uint32_t sign_bit_pos) { 746 const uint32_t max_bit_pos = GetByteSize() * 8; 747 748 if (sign_bit_pos < max_bit_pos) { 749 switch (m_type) { 750 case Scalar::e_void: 751 case Scalar::e_float: 752 return false; 753 754 case Scalar::e_int: 755 if (max_bit_pos == sign_bit_pos) 756 return true; 757 else if (sign_bit_pos < (max_bit_pos - 1)) { 758 llvm::APInt sign_bit = llvm::APInt::getSignMask(sign_bit_pos + 1); 759 llvm::APInt bitwize_and = m_integer & sign_bit; 760 if (bitwize_and.getBoolValue()) { 761 llvm::APInt mask = 762 ~(sign_bit) + llvm::APInt(m_integer.getBitWidth(), 1); 763 m_integer |= APSInt(std::move(mask), m_integer.isUnsigned()); 764 } 765 return true; 766 } 767 break; 768 } 769 } 770 return false; 771 } 772 773 size_t Scalar::GetAsMemoryData(void *dst, size_t dst_len, 774 lldb::ByteOrder dst_byte_order, 775 Status &error) const { 776 // Get a data extractor that points to the native scalar data 777 DataExtractor data; 778 if (!GetData(data)) { 779 error.SetErrorString("invalid scalar value"); 780 return 0; 781 } 782 783 const size_t src_len = data.GetByteSize(); 784 785 // Prepare a memory buffer that contains some or all of the register value 786 const size_t bytes_copied = 787 data.CopyByteOrderedData(0, // src offset 788 src_len, // src length 789 dst, // dst buffer 790 dst_len, // dst length 791 dst_byte_order); // dst byte order 792 if (bytes_copied == 0) 793 error.SetErrorString("failed to copy data"); 794 795 return bytes_copied; 796 } 797 798 bool Scalar::ExtractBitfield(uint32_t bit_size, uint32_t bit_offset) { 799 if (bit_size == 0) 800 return true; 801 802 switch (m_type) { 803 case Scalar::e_void: 804 case Scalar::e_float: 805 break; 806 807 case Scalar::e_int: 808 m_integer >>= bit_offset; 809 m_integer = m_integer.extOrTrunc(bit_size).extOrTrunc(8 * GetByteSize()); 810 return true; 811 } 812 return false; 813 } 814 815 bool lldb_private::operator==(Scalar lhs, Scalar rhs) { 816 // If either entry is void then we can just compare the types 817 if (lhs.m_type == Scalar::e_void || rhs.m_type == Scalar::e_void) 818 return lhs.m_type == rhs.m_type; 819 820 llvm::APFloat::cmpResult result; 821 switch (Scalar::PromoteToMaxType(lhs, rhs)) { 822 case Scalar::e_void: 823 break; 824 case Scalar::e_int: 825 return lhs.m_integer == rhs.m_integer; 826 case Scalar::e_float: 827 result = lhs.m_float.compare(rhs.m_float); 828 if (result == llvm::APFloat::cmpEqual) 829 return true; 830 } 831 return false; 832 } 833 834 bool lldb_private::operator!=(const Scalar &lhs, const Scalar &rhs) { 835 return !(lhs == rhs); 836 } 837 838 bool lldb_private::operator<(Scalar lhs, Scalar rhs) { 839 if (lhs.m_type == Scalar::e_void || rhs.m_type == Scalar::e_void) 840 return false; 841 842 llvm::APFloat::cmpResult result; 843 switch (Scalar::PromoteToMaxType(lhs, rhs)) { 844 case Scalar::e_void: 845 break; 846 case Scalar::e_int: 847 return lhs.m_integer < rhs.m_integer; 848 case Scalar::e_float: 849 result = lhs.m_float.compare(rhs.m_float); 850 if (result == llvm::APFloat::cmpLessThan) 851 return true; 852 } 853 return false; 854 } 855 856 bool lldb_private::operator<=(const Scalar &lhs, const Scalar &rhs) { 857 return !(rhs < lhs); 858 } 859 860 bool lldb_private::operator>(const Scalar &lhs, const Scalar &rhs) { 861 return rhs < lhs; 862 } 863 864 bool lldb_private::operator>=(const Scalar &lhs, const Scalar &rhs) { 865 return !(lhs < rhs); 866 } 867 868 bool Scalar::ClearBit(uint32_t bit) { 869 switch (m_type) { 870 case e_void: 871 break; 872 case e_int: 873 m_integer.clearBit(bit); 874 return true; 875 case e_float: 876 break; 877 } 878 return false; 879 } 880 881 bool Scalar::SetBit(uint32_t bit) { 882 switch (m_type) { 883 case e_void: 884 break; 885 case e_int: 886 m_integer.setBit(bit); 887 return true; 888 case e_float: 889 break; 890 } 891 return false; 892 } 893 894 llvm::raw_ostream &lldb_private::operator<<(llvm::raw_ostream &os, const Scalar &scalar) { 895 StreamString s; 896 scalar.GetValue(&s, /*show_type*/ true); 897 return os << s.GetString(); 898 } 899