LLDB mainline
RegisterValue.cpp
Go to the documentation of this file.
1//===-- RegisterValue.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
10
12#include "lldb/Utility/Scalar.h"
13#include "lldb/Utility/Status.h"
14#include "lldb/Utility/Stream.h"
16#include "lldb/lldb-defines.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 <cassert>
28#include <cinttypes>
29#include <cstdio>
30
31using namespace lldb;
32using namespace lldb_private;
33
35 return data.SetData(GetBytes(), GetByteSize(), GetByteOrder()) > 0;
36}
37
38uint32_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 // ReadRegister should have already been called on this object prior to
43 // calling this.
44 if (GetType() == eTypeInvalid) {
45 // No value has been read into this object...
47 "invalid register value type for register {0}", reg_info.name);
48 return 0;
49 }
50
51 const uint32_t src_len = reg_info.byte_size;
52
53 // Extract the register data into a data extractor
54 DataExtractor reg_data;
55 if (!GetData(reg_data)) {
56 error = Status::FromErrorString("invalid register value to copy into");
57 return 0;
58 }
59
60 // Prepare a memory buffer that contains some or all of the register value
61 const uint32_t bytes_copied =
62 reg_data.CopyByteOrderedData(0, // src offset
63 src_len, // src length
64 dst, // dst buffer
65 dst_len, // dst length
66 dst_byte_order); // dst byte order
67 if (bytes_copied == 0)
69 "failed to copy data for register write of %s", reg_info.name);
70
71 return bytes_copied;
72}
73
75 const void *src, uint32_t src_len,
76 lldb::ByteOrder src_byte_order,
77 Status &error) {
78 // Moving from addr into a register
79 //
80 // Case 1: src_len == dst_len
81 //
82 // |AABBCCDD| Address contents
83 // |AABBCCDD| Register contents
84 //
85 // Case 2: src_len > dst_len
86 //
87 // Status! (The register should always be big enough to hold the data)
88 //
89 // Case 3: src_len < dst_len
90 //
91 // |AABB| Address contents
92 // |AABB0000| Register contents [on little-endian hardware]
93 // |0000AABB| Register contents [on big-endian hardware]
94 const uint32_t dst_len = reg_info.byte_size;
95
96 if (src_len > dst_len) {
98 "%u bytes is too big to store in register %s (%u bytes)", src_len,
99 reg_info.name, dst_len);
100 return 0;
101 }
102
103 // Use a data extractor to correctly copy and pad the bytes read into the
104 // register value
105 DataExtractor src_data(src, src_len, src_byte_order, 4);
106
107 error = SetValueFromData(reg_info, src_data, 0, true);
108 if (error.Fail())
109 return 0;
110
111 // If SetValueFromData succeeded, we must have copied all of src_len
112 return src_len;
113}
114
116 switch (m_type) {
117 case eTypeInvalid:
118 break;
119 case eTypeBytes: {
120 DataExtractor data(buffer.bytes.data(), buffer.bytes.size(),
121 buffer.byte_order, 1);
122 if (scalar.SetValueFromData(data, lldb::eEncodingUint, buffer.bytes.size())
123 .Success())
124 return true;
125 } break;
126 case eTypeUInt8:
127 case eTypeUInt16:
128 case eTypeUInt32:
129 case eTypeUInt64:
130 case eTypeUIntN:
131 case eTypeFloat:
132 case eTypeDouble:
133 case eTypeLongDouble:
134 scalar = m_scalar;
135 return true;
136 }
137 return false;
138}
139
141
143 // To change the type, we simply copy the data in again, using the new format
144 RegisterValue copy;
145 DataExtractor copy_data;
146 if (copy.CopyValue(*this) && copy.GetData(copy_data)) {
147 Status error = SetValueFromData(reg_info, copy_data, 0, true);
148 assert(error.Success() && "Expected SetValueFromData to succeed.");
150 }
151
152 return m_type;
153}
154
156 DataExtractor &src,
157 lldb::offset_t src_offset,
158 bool partial_data_ok) {
160
161 if (src.GetByteSize() == 0) {
162 error = Status::FromErrorString("empty data.");
163 return error;
164 }
165
166 if (reg_info.byte_size == 0) {
167 error = Status::FromErrorString("invalid register info.");
168 return error;
169 }
170
171 uint32_t src_len = src.GetByteSize() - src_offset;
172
173 if (!partial_data_ok && (src_len < reg_info.byte_size)) {
174 error = Status::FromErrorString("not enough data.");
175 return error;
176 }
177
178 // Cap the data length if there is more than enough bytes for this register
179 // value
180 if (src_len > reg_info.byte_size)
181 src_len = reg_info.byte_size;
182
184 switch (reg_info.encoding) {
185 case eEncodingInvalid:
186 break;
187 case eEncodingUint:
188 case eEncodingSint:
189 if (reg_info.byte_size == 1)
190 SetUInt8(src.GetMaxU32(&src_offset, src_len));
191 else if (reg_info.byte_size <= 2)
192 SetUInt16(src.GetMaxU32(&src_offset, src_len));
193 else if (reg_info.byte_size <= 4)
194 SetUInt32(src.GetMaxU32(&src_offset, src_len));
195 else if (reg_info.byte_size <= 8)
196 SetUInt64(src.GetMaxU64(&src_offset, src_len));
197 else {
198 std::vector<uint8_t> native_endian_src(src_len, 0);
199 src.ExtractBytes(src_offset, src_len, endian::InlHostByteOrder(),
200 native_endian_src.data());
201 llvm::APInt uint = llvm::APInt::getZero(src_len * 8);
202 llvm::LoadIntFromMemory(uint, native_endian_src.data(), src_len);
203 SetUIntN(uint);
204 }
205 break;
206 case eEncodingIEEE754:
207 if (reg_info.byte_size == sizeof(float))
208 SetFloat(src.GetFloat(&src_offset));
209 else if (reg_info.byte_size == sizeof(double))
210 SetDouble(src.GetDouble(&src_offset));
211 else if (reg_info.byte_size == sizeof(long double))
212 SetLongDouble(src.GetLongDouble(&src_offset));
213 break;
214 case eEncodingVector: {
216 assert(reg_info.byte_size <= kMaxRegisterByteSize);
217 buffer.bytes.resize(reg_info.byte_size);
218 buffer.byte_order = src.GetByteOrder();
219 if (src.CopyByteOrderedData(
220 src_offset, // offset within "src" to start extracting data
221 src_len, // src length
222 buffer.bytes.data(), // dst buffer
223 buffer.bytes.size(), // dst length
224 buffer.byte_order) == 0) // dst byte order
225 {
227 "failed to copy data for register write of %s", reg_info.name);
228 return error;
229 }
230 }
231 }
232
233 if (m_type == eTypeInvalid)
235 "invalid register value type for register %s", reg_info.name);
236 return error;
237}
238
239// Helper function for RegisterValue::SetValueFromString()
240static bool ParseVectorEncoding(const RegisterInfo *reg_info,
241 llvm::StringRef vector_str,
242 const uint32_t byte_size,
243 RegisterValue *reg_value) {
244 // Example: vector_str = "{0x2c 0x4b 0x2a 0x3e 0xd0 0x4f 0x2a 0x3e 0xac 0x4a
245 // 0x2a 0x3e 0x84 0x4f 0x2a 0x3e}".
246 vector_str = vector_str.trim();
247 vector_str.consume_front("{");
248 vector_str.consume_back("}");
249 vector_str = vector_str.trim();
250
251 char Sep = ' ';
252
253 // The first split should give us:
254 // ('0x2c', '0x4b 0x2a 0x3e 0xd0 0x4f 0x2a 0x3e 0xac 0x4a 0x2a 0x3e 0x84 0x4f
255 // 0x2a 0x3e').
256 llvm::StringRef car;
257 llvm::StringRef cdr = vector_str;
258 std::tie(car, cdr) = vector_str.split(Sep);
259 std::vector<uint8_t> bytes;
260 unsigned byte = 0;
261
262 // Using radix auto-sensing by passing 0 as the radix. Keep on processing the
263 // vector elements as long as the parsing succeeds and the vector size is <
264 // byte_size.
265 while (!car.getAsInteger(0, byte) && bytes.size() < byte_size) {
266 bytes.push_back(byte);
267 std::tie(car, cdr) = cdr.split(Sep);
268 }
269
270 // Check for vector of exact byte_size elements.
271 if (bytes.size() != byte_size)
272 return false;
273
274 reg_value->SetBytes(&(bytes.front()), byte_size, eByteOrderLittle);
275 return true;
276}
277
278static bool UInt64ValueIsValidForByteSize(uint64_t uval64,
279 size_t total_byte_size) {
280 if (total_byte_size > 8)
281 return false;
282
283 if (total_byte_size == 8)
284 return true;
285
286 const uint64_t max =
287 (static_cast<uint64_t>(1) << static_cast<uint64_t>(total_byte_size * 8)) -
288 1;
289 return uval64 <= max;
290}
291
292static bool SInt64ValueIsValidForByteSize(int64_t sval64,
293 size_t total_byte_size) {
294 if (total_byte_size > 8)
295 return false;
296
297 if (total_byte_size == 8)
298 return true;
299
300 const int64_t max = (static_cast<int64_t>(1)
301 << static_cast<uint64_t>(total_byte_size * 8 - 1)) -
302 1;
303 const int64_t min = ~(max);
304 return min <= sval64 && sval64 <= max;
305}
306
308 llvm::StringRef value_str) {
310 if (reg_info == nullptr) {
311 error = Status::FromErrorString("Invalid register info argument.");
312 return error;
313 }
314
316 if (value_str.empty()) {
317 error = Status::FromErrorString("Invalid c-string value string.");
318 return error;
319 }
320 const uint32_t byte_size = reg_info->byte_size;
321
322 uint64_t uval64;
323 int64_t ival64;
324 float flt_val;
325 double dbl_val;
326 long double ldbl_val;
327 switch (reg_info->encoding) {
328 case eEncodingInvalid:
329 error = Status::FromErrorString("Invalid encoding.");
330 break;
331
332 case eEncodingUint:
333 if (byte_size > sizeof(uint64_t)) {
335 "unsupported unsigned integer byte size: %u", byte_size);
336 break;
337 }
338 if (value_str.getAsInteger(0, uval64)) {
340 "'{0}' is not a valid unsigned integer string value", value_str);
341 break;
342 }
343
344 if (!UInt64ValueIsValidForByteSize(uval64, byte_size)) {
346 "value 0x%" PRIx64
347 " is too large to fit in a %u byte unsigned integer value",
348 uval64, byte_size);
349 break;
350 }
351
352 if (!SetUInt(uval64, reg_info->byte_size)) {
354 "unsupported unsigned integer byte size: %u", byte_size);
355 break;
356 }
357 break;
358
359 case eEncodingSint:
360 if (byte_size > sizeof(long long)) {
362 "unsupported signed integer byte size: %u", byte_size);
363 break;
364 }
365
366 if (value_str.getAsInteger(0, ival64)) {
368 "'{0}' is not a valid signed integer string value", value_str);
369 break;
370 }
371
372 if (!SInt64ValueIsValidForByteSize(ival64, byte_size)) {
374 "value 0x%" PRIx64
375 " is too large to fit in a %u byte signed integer value",
376 ival64, byte_size);
377 break;
378 }
379
380 if (!SetUInt(ival64, reg_info->byte_size)) {
382 "unsupported signed integer byte size: %u", byte_size);
383 break;
384 }
385 break;
386
387 case eEncodingIEEE754: {
388 std::string value_string = std::string(value_str);
389 if (byte_size == sizeof(float)) {
390 if (::sscanf(value_string.c_str(), "%f", &flt_val) != 1) {
392 "'%s' is not a valid float string value", value_string.c_str());
393 break;
394 }
395 m_scalar = flt_val;
397 } else if (byte_size == sizeof(double)) {
398 if (::sscanf(value_string.c_str(), "%lf", &dbl_val) != 1) {
400 "'%s' is not a valid float string value", value_string.c_str());
401 break;
402 }
403 m_scalar = dbl_val;
405 } else if (byte_size == sizeof(long double)) {
406 if (::sscanf(value_string.c_str(), "%Lf", &ldbl_val) != 1) {
408 "'%s' is not a valid float string value", value_string.c_str());
409 break;
410 }
411 m_scalar = ldbl_val;
413 } else {
415 "unsupported float byte size: %u", byte_size);
416 return error;
417 }
418 break;
419 }
420 case eEncodingVector:
421 if (!ParseVectorEncoding(reg_info, value_str, byte_size, this))
422 error =
423 Status::FromErrorString("unrecognized vector encoding string value.");
424 break;
425 }
426
427 return error;
428}
429
430bool RegisterValue::SignExtend(uint32_t sign_bitpos) {
431 switch (m_type) {
432 case eTypeInvalid:
433 break;
434
435 case eTypeUInt8:
436 case eTypeUInt16:
437 case eTypeUInt32:
438 case eTypeUInt64:
439 case eTypeUIntN:
440 return m_scalar.SignExtend(sign_bitpos);
441 case eTypeFloat:
442 case eTypeDouble:
443 case eTypeLongDouble:
444 case eTypeBytes:
445 break;
446 }
447 return false;
448}
449
451 if (this == &rhs)
452 return rhs.m_type != eTypeInvalid;
453
454 m_type = rhs.m_type;
455 switch (m_type) {
456 case eTypeInvalid:
457 return false;
458 case eTypeUInt8:
459 case eTypeUInt16:
460 case eTypeUInt32:
461 case eTypeUInt64:
462 case eTypeUIntN:
463 case eTypeFloat:
464 case eTypeDouble:
465 case eTypeLongDouble:
466 m_scalar = rhs.m_scalar;
467 break;
468 case eTypeBytes:
469 buffer.bytes = rhs.buffer.bytes;
470 buffer.byte_order = rhs.buffer.byte_order;
471 break;
472 }
473 return true;
474}
475
476uint16_t RegisterValue::GetAsUInt16(uint16_t fail_value,
477 bool *success_ptr) const {
478 if (success_ptr)
479 *success_ptr = true;
480
481 switch (m_type) {
482 default:
483 break;
484 case eTypeUInt8:
485 case eTypeUInt16:
486 return m_scalar.UShort(fail_value);
487 case eTypeBytes: {
488 switch (buffer.bytes.size()) {
489 default:
490 break;
491 case 1:
492 case 2:
493 return *reinterpret_cast<const uint16_t *>(buffer.bytes.data());
494 }
495 } break;
496 }
497 if (success_ptr)
498 *success_ptr = false;
499 return fail_value;
500}
501
502uint32_t RegisterValue::GetAsUInt32(uint32_t fail_value,
503 bool *success_ptr) const {
504 if (success_ptr)
505 *success_ptr = true;
506 switch (m_type) {
507 default:
508 break;
509 case eTypeUInt8:
510 case eTypeUInt16:
511 case eTypeUInt32:
512 case eTypeFloat:
513 case eTypeDouble:
514 case eTypeLongDouble:
515 return m_scalar.UInt(fail_value);
516 case eTypeBytes: {
517 switch (buffer.bytes.size()) {
518 default:
519 break;
520 case 1:
521 case 2:
522 case 4:
523 return *reinterpret_cast<const uint32_t *>(buffer.bytes.data());
524 }
525 } break;
526 }
527 if (success_ptr)
528 *success_ptr = false;
529 return fail_value;
530}
531
532uint64_t RegisterValue::GetAsUInt64(uint64_t fail_value,
533 bool *success_ptr) const {
534 if (success_ptr)
535 *success_ptr = true;
536 switch (m_type) {
537 default:
538 break;
539 case eTypeUInt8:
540 case eTypeUInt16:
541 case eTypeUInt32:
542 case eTypeUInt64:
543 case eTypeFloat:
544 case eTypeDouble:
545 case eTypeLongDouble:
546 return m_scalar.ULongLong(fail_value);
547 case eTypeBytes: {
548 switch (buffer.bytes.size()) {
549 default:
550 break;
551 case 1:
552 return *(const uint8_t *)buffer.bytes.data();
553 case 2:
554 return *reinterpret_cast<const uint16_t *>(buffer.bytes.data());
555 case 4:
556 return *reinterpret_cast<const uint32_t *>(buffer.bytes.data());
557 case 8:
558 return *reinterpret_cast<const uint64_t *>(buffer.bytes.data());
559 }
560 } break;
561 }
562 if (success_ptr)
563 *success_ptr = false;
564 return fail_value;
565}
566
567llvm::APInt RegisterValue::GetAsUInt128(const llvm::APInt &fail_value,
568 bool *success_ptr) const {
569 if (success_ptr)
570 *success_ptr = true;
571 switch (m_type) {
572 default:
573 break;
574 case eTypeUInt8:
575 case eTypeUInt16:
576 case eTypeUInt32:
577 case eTypeUInt64:
578 case eTypeUIntN:
579 case eTypeFloat:
580 case eTypeDouble:
581 case eTypeLongDouble:
582 return m_scalar.UInt128(fail_value);
583 case eTypeBytes: {
584 switch (buffer.bytes.size()) {
585 default:
586 break;
587 case 1:
588 case 2:
589 case 4:
590 case 8:
591 case 16:
592 return llvm::APInt(
594 llvm::ArrayRef(
595 (reinterpret_cast<const type128 *>(buffer.bytes.data()))->x,
597 }
598 } break;
599 }
600 if (success_ptr)
601 *success_ptr = false;
602 return fail_value;
603}
604
605float RegisterValue::GetAsFloat(float fail_value, bool *success_ptr) const {
606 if (success_ptr)
607 *success_ptr = true;
608 switch (m_type) {
609 default:
610 break;
611 case eTypeUInt32:
612 case eTypeUInt64:
613 case eTypeUIntN:
614 case eTypeFloat:
615 case eTypeDouble:
616 case eTypeLongDouble:
617 return m_scalar.Float(fail_value);
618 }
619 if (success_ptr)
620 *success_ptr = false;
621 return fail_value;
622}
623
624double RegisterValue::GetAsDouble(double fail_value, bool *success_ptr) const {
625 if (success_ptr)
626 *success_ptr = true;
627 switch (m_type) {
628 default:
629 break;
630
631 case eTypeUInt32:
632 case eTypeUInt64:
633 case eTypeUIntN:
634 case eTypeFloat:
635 case eTypeDouble:
636 case eTypeLongDouble:
637 return m_scalar.Double(fail_value);
638 }
639 if (success_ptr)
640 *success_ptr = false;
641 return fail_value;
642}
643
644long double RegisterValue::GetAsLongDouble(long double fail_value,
645 bool *success_ptr) const {
646 if (success_ptr)
647 *success_ptr = true;
648 switch (m_type) {
649 default:
650 break;
651
652 case eTypeUInt32:
653 case eTypeUInt64:
654 case eTypeUIntN:
655 case eTypeFloat:
656 case eTypeDouble:
657 case eTypeLongDouble:
658 return m_scalar.LongDouble();
659 }
660 if (success_ptr)
661 *success_ptr = false;
662 return fail_value;
663}
664
665const void *RegisterValue::GetBytes() const {
666 switch (m_type) {
667 case eTypeInvalid:
668 break;
669 case eTypeUInt8:
670 case eTypeUInt16:
671 case eTypeUInt32:
672 case eTypeUInt64:
673 case eTypeUIntN:
674 case eTypeFloat:
675 case eTypeDouble:
676 case eTypeLongDouble:
677 m_scalar.GetBytes(buffer.bytes);
678 return buffer.bytes.data();
679 case eTypeBytes:
680 return buffer.bytes.data();
681 }
682 return nullptr;
683}
684
686 switch (m_type) {
687 case eTypeInvalid:
688 break;
689 case eTypeUInt8:
690 return 1;
691 case eTypeUInt16:
692 return 2;
693 case eTypeUInt32:
694 case eTypeUInt64:
695 case eTypeUIntN:
696 case eTypeFloat:
697 case eTypeDouble:
698 case eTypeLongDouble:
699 return m_scalar.GetByteSize();
700 case eTypeBytes:
701 return buffer.bytes.size();
702 }
703 return 0;
704}
705
706bool RegisterValue::SetUInt(uint64_t uint, uint32_t byte_size) {
707 if (byte_size == 0) {
708 SetUInt64(uint);
709 } else if (byte_size == 1) {
710 SetUInt8(uint);
711 } else if (byte_size <= 2) {
712 SetUInt16(uint);
713 } else if (byte_size <= 4) {
714 SetUInt32(uint);
715 } else if (byte_size <= 8) {
716 SetUInt64(uint);
717 } else if (byte_size <= 16) {
718 SetUIntN(llvm::APInt(128, uint));
719 } else
720 return false;
721 return true;
722}
723
724void RegisterValue::SetBytes(const void *bytes, size_t length,
725 lldb::ByteOrder byte_order) {
726 if (bytes && length > 0) {
728 buffer.bytes.resize(length);
729 memcpy(buffer.bytes.data(), bytes, length);
730 buffer.byte_order = byte_order;
731 } else {
733 buffer.bytes.resize(0);
734 }
735}
736
738 if (m_type == rhs.m_type) {
739 switch (m_type) {
740 case eTypeInvalid:
741 return true;
742 case eTypeUInt8:
743 case eTypeUInt16:
744 case eTypeUInt32:
745 case eTypeUInt64:
746 case eTypeUIntN:
747 case eTypeFloat:
748 case eTypeDouble:
749 case eTypeLongDouble:
750 return m_scalar == rhs.m_scalar;
751 case eTypeBytes:
752 return buffer.bytes == rhs.buffer.bytes;
753 }
754 }
755 return false;
756}
757
759 return !(*this == rhs);
760}
761
763 switch (m_type) {
764 case eTypeInvalid:
765 break;
766
767 case eTypeUInt8:
768 case eTypeUInt16:
769 case eTypeUInt32:
770 case eTypeUInt64:
771 case eTypeUIntN:
772 if (bit < (GetByteSize() * 8)) {
773 return m_scalar.ClearBit(bit);
774 }
775 break;
776
777 case eTypeFloat:
778 case eTypeDouble:
779 case eTypeLongDouble:
780 break;
781
782 case eTypeBytes:
783 if (buffer.byte_order == eByteOrderBig ||
784 buffer.byte_order == eByteOrderLittle) {
785 uint32_t byte_idx;
786 if (buffer.byte_order == eByteOrderBig)
787 byte_idx = buffer.bytes.size() - (bit / 8) - 1;
788 else
789 byte_idx = bit / 8;
790
791 const uint32_t byte_bit = bit % 8;
792 if (byte_idx < buffer.bytes.size()) {
793 buffer.bytes[byte_idx] &= ~(1u << byte_bit);
794 return true;
795 }
796 }
797 break;
798 }
799 return false;
800}
801
803 switch (m_type) {
804 case eTypeInvalid:
805 break;
806
807 case eTypeUInt8:
808 case eTypeUInt16:
809 case eTypeUInt32:
810 case eTypeUInt64:
811 case eTypeUIntN:
812 if (bit < (GetByteSize() * 8)) {
813 return m_scalar.SetBit(bit);
814 }
815 break;
816
817 case eTypeFloat:
818 case eTypeDouble:
819 case eTypeLongDouble:
820 break;
821
822 case eTypeBytes:
823 if (buffer.byte_order == eByteOrderBig ||
824 buffer.byte_order == eByteOrderLittle) {
825 uint32_t byte_idx;
826 if (buffer.byte_order == eByteOrderBig)
827 byte_idx = buffer.bytes.size() - (bit / 8) - 1;
828 else
829 byte_idx = bit / 8;
830
831 const uint32_t byte_bit = bit % 8;
832 if (byte_idx < buffer.bytes.size()) {
833 buffer.bytes[byte_idx] |= (1u << byte_bit);
834 return true;
835 }
836 }
837 break;
838 }
839 return false;
840}
static llvm::raw_ostream & error(Stream &strm)
static bool ParseVectorEncoding(const RegisterInfo *reg_info, llvm::StringRef vector_str, const uint32_t byte_size, RegisterValue *reg_value)
static bool UInt64ValueIsValidForByteSize(uint64_t uval64, size_t total_byte_size)
static bool SInt64ValueIsValidForByteSize(int64_t sval64, size_t total_byte_size)
#define NUM_OF_WORDS_INT128
Definition Scalar.h:27
#define BITWIDTH_INT128
Definition Scalar.h:28
An data extractor class.
float GetFloat(lldb::offset_t *offset_ptr) const
Extract a float from *offset_ptr.
long double GetLongDouble(lldb::offset_t *offset_ptr) const
uint32_t GetMaxU32(lldb::offset_t *offset_ptr, size_t byte_size) const
Extract an integer of size byte_size from *offset_ptr.
uint64_t GetByteSize() const
Get the number of bytes contained in this object.
lldb::offset_t SetData(const void *bytes, lldb::offset_t length, lldb::ByteOrder byte_order)
Set data with a buffer that is caller owned.
uint64_t GetMaxU64(lldb::offset_t *offset_ptr, size_t byte_size) const
Extract an unsigned integer of size byte_size from *offset_ptr.
lldb::ByteOrder GetByteOrder() const
Get the current byte order value.
lldb::offset_t CopyByteOrderedData(lldb::offset_t src_offset, lldb::offset_t src_len, void *dst, lldb::offset_t dst_len, lldb::ByteOrder dst_byte_order) const
Copy dst_len bytes from *offset_ptr and ensure the copied data is treated as a value that can be swap...
double GetDouble(lldb::offset_t *offset_ptr) const
size_t ExtractBytes(lldb::offset_t offset, lldb::offset_t length, lldb::ByteOrder dst_byte_order, void *dst) const
Extract an arbitrary number of bytes in the specified byte order.
bool operator==(const RegisterValue &rhs) const
RegisterValue::Type m_type
uint16_t GetAsUInt16(uint16_t fail_value=UINT16_MAX, bool *success_ptr=nullptr) const
bool SignExtend(uint32_t sign_bitpos)
uint32_t SetFromMemoryData(const RegisterInfo &reg_info, const void *src, uint32_t src_len, lldb::ByteOrder src_byte_order, Status &error)
long double GetAsLongDouble(long double fail_value=0.0, bool *success_ptr=nullptr) const
bool GetData(DataExtractor &data) const
void SetUInt64(uint64_t uint, Type t=eTypeUInt64)
void SetUInt16(uint16_t uint)
double GetAsDouble(double fail_value=0.0, bool *success_ptr=nullptr) const
void SetUIntN(llvm::APInt uint)
bool SetUInt(uint64_t uint, uint32_t byte_size)
Status SetValueFromString(const RegisterInfo *reg_info, llvm::StringRef value_str)
uint32_t GetAsMemoryData(const RegisterInfo &reg_info, void *dst, uint32_t dst_len, lldb::ByteOrder dst_byte_order, Status &error) const
uint64_t GetAsUInt64(uint64_t fail_value=UINT64_MAX, bool *success_ptr=nullptr) const
float GetAsFloat(float fail_value=0.0f, bool *success_ptr=nullptr) const
void SetUInt8(uint8_t uint)
llvm::APInt GetAsUInt128(const llvm::APInt &fail_value, bool *success_ptr=nullptr) const
struct lldb_private::RegisterValue::RegisterValueBuffer buffer
void SetBytes(const void *bytes, size_t length, lldb::ByteOrder byte_order)
bool GetScalarValue(Scalar &scalar) const
const void * GetBytes() const
RegisterValue::Type GetType() const
void SetLongDouble(long double f)
bool operator!=(const RegisterValue &rhs) const
Status SetValueFromData(const RegisterInfo &reg_info, DataExtractor &data, lldb::offset_t offset, bool partial_data_ok)
void SetType(RegisterValue::Type type)
uint32_t GetAsUInt32(uint32_t fail_value=UINT32_MAX, bool *success_ptr=nullptr) const
bool CopyValue(const RegisterValue &rhs)
void SetUInt32(uint32_t uint, Type t=eTypeUInt32)
lldb::ByteOrder GetByteOrder() const
@ eTypeFloat
< This value is used when the (integer) register is larger than 64-bits.
Status SetValueFromData(const DataExtractor &data, lldb::Encoding encoding, size_t byte_size)
Definition Scalar.cpp:718
An error handling class.
Definition Status.h:118
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Definition Status.cpp:106
static Status FromErrorString(const char *str)
Definition Status.h:141
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
Definition Status.h:151
bool Success() const
Test for success condition.
Definition Status.cpp:304
#define UNUSED_IF_ASSERT_DISABLED(x)
lldb::ByteOrder InlHostByteOrder()
Definition Endian.h:25
A class that represents a running process on the host machine.
static uint32_t bit(const uint32_t val, const uint32_t msbit)
Definition ARMUtils.h:270
uint64_t offset_t
Definition lldb-types.h:85
@ eEncodingIEEE754
float
@ eEncodingVector
vector registers
@ eEncodingUint
unsigned integer
@ eEncodingSint
signed integer
ByteOrder
Byte ordering definitions.
Every register is described in detail including its name, alternate name (optional),...
lldb::Encoding encoding
Encoding of the register bits.
uint32_t byte_size
Size in bytes of the register.
const char * name
Name of this register, can't be NULL.