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