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...
46 error.SetErrorStringWithFormat(
47 "invalid register value type for register %s", 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.SetErrorString("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)
68 error.SetErrorStringWithFormat(
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) {
97 error.SetErrorStringWithFormat(
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 eTypeUInt128:
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.SetErrorString("empty data.");
163 return error;
164 }
165
166 if (reg_info.byte_size == 0) {
167 error.SetErrorString("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.SetErrorString("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
183 type128 int128;
184
186 switch (reg_info.encoding) {
187 case eEncodingInvalid:
188 break;
189 case eEncodingUint:
190 case eEncodingSint:
191 if (reg_info.byte_size == 1)
192 SetUInt8(src.GetMaxU32(&src_offset, src_len));
193 else if (reg_info.byte_size <= 2)
194 SetUInt16(src.GetMaxU32(&src_offset, src_len));
195 else if (reg_info.byte_size <= 4)
196 SetUInt32(src.GetMaxU32(&src_offset, src_len));
197 else if (reg_info.byte_size <= 8)
198 SetUInt64(src.GetMaxU64(&src_offset, src_len));
199 else if (reg_info.byte_size <= 16) {
200 uint64_t data1 = src.GetU64(&src_offset);
201 uint64_t data2 = src.GetU64(&src_offset);
202 if (src.GetByteOrder() == eByteOrderBig) {
203 int128.x[0] = data1;
204 int128.x[1] = data2;
205 } else {
206 int128.x[0] = data2;
207 int128.x[1] = data1;
208 }
209 SetUInt128(llvm::APInt(128, 2, int128.x));
210 }
211 break;
212 case eEncodingIEEE754:
213 if (reg_info.byte_size == sizeof(float))
214 SetFloat(src.GetFloat(&src_offset));
215 else if (reg_info.byte_size == sizeof(double))
216 SetDouble(src.GetDouble(&src_offset));
217 else if (reg_info.byte_size == sizeof(long double))
218 SetLongDouble(src.GetLongDouble(&src_offset));
219 break;
220 case eEncodingVector: {
222 assert(reg_info.byte_size <= kMaxRegisterByteSize);
223 buffer.bytes.resize(reg_info.byte_size);
225 if (src.CopyByteOrderedData(
226 src_offset, // offset within "src" to start extracting data
227 src_len, // src length
228 buffer.bytes.data(), // dst buffer
229 buffer.bytes.size(), // dst length
230 buffer.byte_order) == 0) // dst byte order
231 {
232 error.SetErrorStringWithFormat(
233 "failed to copy data for register write of %s", reg_info.name);
234 return error;
235 }
236 }
237 }
238
239 if (m_type == eTypeInvalid)
240 error.SetErrorStringWithFormat(
241 "invalid register value type for register %s", reg_info.name);
242 return error;
243}
244
245// Helper function for RegisterValue::SetValueFromString()
246static bool ParseVectorEncoding(const RegisterInfo *reg_info,
247 llvm::StringRef vector_str,
248 const uint32_t byte_size,
249 RegisterValue *reg_value) {
250 // Example: vector_str = "{0x2c 0x4b 0x2a 0x3e 0xd0 0x4f 0x2a 0x3e 0xac 0x4a
251 // 0x2a 0x3e 0x84 0x4f 0x2a 0x3e}".
252 vector_str = vector_str.trim();
253 vector_str.consume_front("{");
254 vector_str.consume_back("}");
255 vector_str = vector_str.trim();
256
257 char Sep = ' ';
258
259 // The first split should give us:
260 // ('0x2c', '0x4b 0x2a 0x3e 0xd0 0x4f 0x2a 0x3e 0xac 0x4a 0x2a 0x3e 0x84 0x4f
261 // 0x2a 0x3e').
262 llvm::StringRef car;
263 llvm::StringRef cdr = vector_str;
264 std::tie(car, cdr) = vector_str.split(Sep);
265 std::vector<uint8_t> bytes;
266 unsigned byte = 0;
267
268 // Using radix auto-sensing by passing 0 as the radix. Keep on processing the
269 // vector elements as long as the parsing succeeds and the vector size is <
270 // byte_size.
271 while (!car.getAsInteger(0, byte) && bytes.size() < byte_size) {
272 bytes.push_back(byte);
273 std::tie(car, cdr) = cdr.split(Sep);
274 }
275
276 // Check for vector of exact byte_size elements.
277 if (bytes.size() != byte_size)
278 return false;
279
280 reg_value->SetBytes(&(bytes.front()), byte_size, eByteOrderLittle);
281 return true;
282}
283
284static bool UInt64ValueIsValidForByteSize(uint64_t uval64,
285 size_t total_byte_size) {
286 if (total_byte_size > 8)
287 return false;
288
289 if (total_byte_size == 8)
290 return true;
291
292 const uint64_t max =
293 (static_cast<uint64_t>(1) << static_cast<uint64_t>(total_byte_size * 8)) -
294 1;
295 return uval64 <= max;
296}
297
298static bool SInt64ValueIsValidForByteSize(int64_t sval64,
299 size_t total_byte_size) {
300 if (total_byte_size > 8)
301 return false;
302
303 if (total_byte_size == 8)
304 return true;
305
306 const int64_t max = (static_cast<int64_t>(1)
307 << static_cast<uint64_t>(total_byte_size * 8 - 1)) -
308 1;
309 const int64_t min = ~(max);
310 return min <= sval64 && sval64 <= max;
311}
312
314 llvm::StringRef value_str) {
316 if (reg_info == nullptr) {
317 error.SetErrorString("Invalid register info argument.");
318 return error;
319 }
320
322 if (value_str.empty()) {
323 error.SetErrorString("Invalid c-string value string.");
324 return error;
325 }
326 const uint32_t byte_size = reg_info->byte_size;
327
328 uint64_t uval64;
329 int64_t ival64;
330 float flt_val;
331 double dbl_val;
332 long double ldbl_val;
333 switch (reg_info->encoding) {
334 case eEncodingInvalid:
335 error.SetErrorString("Invalid encoding.");
336 break;
337
338 case eEncodingUint:
339 if (byte_size > sizeof(uint64_t)) {
340 error.SetErrorStringWithFormat(
341 "unsupported unsigned integer byte size: %u", byte_size);
342 break;
343 }
344 if (value_str.getAsInteger(0, uval64)) {
345 error.SetErrorStringWithFormatv(
346 "'{0}' is not a valid unsigned integer string value", value_str);
347 break;
348 }
349
350 if (!UInt64ValueIsValidForByteSize(uval64, byte_size)) {
351 error.SetErrorStringWithFormat(
352 "value 0x%" PRIx64
353 " is too large to fit in a %u byte unsigned integer value",
354 uval64, byte_size);
355 break;
356 }
357
358 if (!SetUInt(uval64, reg_info->byte_size)) {
359 error.SetErrorStringWithFormat(
360 "unsupported unsigned integer byte size: %u", byte_size);
361 break;
362 }
363 break;
364
365 case eEncodingSint:
366 if (byte_size > sizeof(long long)) {
367 error.SetErrorStringWithFormat("unsupported signed integer byte size: %u",
368 byte_size);
369 break;
370 }
371
372 if (value_str.getAsInteger(0, ival64)) {
373 error.SetErrorStringWithFormatv(
374 "'{0}' is not a valid signed integer string value", value_str);
375 break;
376 }
377
378 if (!SInt64ValueIsValidForByteSize(ival64, byte_size)) {
379 error.SetErrorStringWithFormat(
380 "value 0x%" PRIx64
381 " is too large to fit in a %u byte signed integer value",
382 ival64, byte_size);
383 break;
384 }
385
386 if (!SetUInt(ival64, reg_info->byte_size)) {
387 error.SetErrorStringWithFormat("unsupported signed integer byte size: %u",
388 byte_size);
389 break;
390 }
391 break;
392
393 case eEncodingIEEE754: {
394 std::string value_string = std::string(value_str);
395 if (byte_size == sizeof(float)) {
396 if (::sscanf(value_string.c_str(), "%f", &flt_val) != 1) {
397 error.SetErrorStringWithFormat("'%s' is not a valid float string value",
398 value_string.c_str());
399 break;
400 }
401 m_scalar = flt_val;
403 } else if (byte_size == sizeof(double)) {
404 if (::sscanf(value_string.c_str(), "%lf", &dbl_val) != 1) {
405 error.SetErrorStringWithFormat("'%s' is not a valid float string value",
406 value_string.c_str());
407 break;
408 }
409 m_scalar = dbl_val;
411 } else if (byte_size == sizeof(long double)) {
412 if (::sscanf(value_string.c_str(), "%Lf", &ldbl_val) != 1) {
413 error.SetErrorStringWithFormat("'%s' is not a valid float string value",
414 value_string.c_str());
415 break;
416 }
417 m_scalar = ldbl_val;
419 } else {
420 error.SetErrorStringWithFormat("unsupported float byte size: %u",
421 byte_size);
422 return error;
423 }
424 break;
425 }
426 case eEncodingVector:
427 if (!ParseVectorEncoding(reg_info, value_str, byte_size, this))
428 error.SetErrorString("unrecognized vector encoding string value.");
429 break;
430 }
431
432 return error;
433}
434
435bool RegisterValue::SignExtend(uint32_t sign_bitpos) {
436 switch (m_type) {
437 case eTypeInvalid:
438 break;
439
440 case eTypeUInt8:
441 case eTypeUInt16:
442 case eTypeUInt32:
443 case eTypeUInt64:
444 case eTypeUInt128:
445 return m_scalar.SignExtend(sign_bitpos);
446 case eTypeFloat:
447 case eTypeDouble:
448 case eTypeLongDouble:
449 case eTypeBytes:
450 break;
451 }
452 return false;
453}
454
456 if (this == &rhs)
457 return rhs.m_type != eTypeInvalid;
458
459 m_type = rhs.m_type;
460 switch (m_type) {
461 case eTypeInvalid:
462 return false;
463 case eTypeUInt8:
464 case eTypeUInt16:
465 case eTypeUInt32:
466 case eTypeUInt64:
467 case eTypeUInt128:
468 case eTypeFloat:
469 case eTypeDouble:
470 case eTypeLongDouble:
471 m_scalar = rhs.m_scalar;
472 break;
473 case eTypeBytes:
474 buffer.bytes = rhs.buffer.bytes;
476 break;
477 }
478 return true;
479}
480
481uint16_t RegisterValue::GetAsUInt16(uint16_t fail_value,
482 bool *success_ptr) const {
483 if (success_ptr)
484 *success_ptr = true;
485
486 switch (m_type) {
487 default:
488 break;
489 case eTypeUInt8:
490 case eTypeUInt16:
491 return m_scalar.UShort(fail_value);
492 case eTypeBytes: {
493 switch (buffer.bytes.size()) {
494 default:
495 break;
496 case 1:
497 case 2:
498 return *reinterpret_cast<const uint16_t *>(buffer.bytes.data());
499 }
500 } break;
501 }
502 if (success_ptr)
503 *success_ptr = false;
504 return fail_value;
505}
506
507uint32_t RegisterValue::GetAsUInt32(uint32_t fail_value,
508 bool *success_ptr) const {
509 if (success_ptr)
510 *success_ptr = true;
511 switch (m_type) {
512 default:
513 break;
514 case eTypeUInt8:
515 case eTypeUInt16:
516 case eTypeUInt32:
517 case eTypeFloat:
518 case eTypeDouble:
519 case eTypeLongDouble:
520 return m_scalar.UInt(fail_value);
521 case eTypeBytes: {
522 switch (buffer.bytes.size()) {
523 default:
524 break;
525 case 1:
526 case 2:
527 case 4:
528 return *reinterpret_cast<const uint32_t *>(buffer.bytes.data());
529 }
530 } break;
531 }
532 if (success_ptr)
533 *success_ptr = false;
534 return fail_value;
535}
536
537uint64_t RegisterValue::GetAsUInt64(uint64_t fail_value,
538 bool *success_ptr) const {
539 if (success_ptr)
540 *success_ptr = true;
541 switch (m_type) {
542 default:
543 break;
544 case eTypeUInt8:
545 case eTypeUInt16:
546 case eTypeUInt32:
547 case eTypeUInt64:
548 case eTypeFloat:
549 case eTypeDouble:
550 case eTypeLongDouble:
551 return m_scalar.ULongLong(fail_value);
552 case eTypeBytes: {
553 switch (buffer.bytes.size()) {
554 default:
555 break;
556 case 1:
557 return *(const uint8_t *)buffer.bytes.data();
558 case 2:
559 return *reinterpret_cast<const uint16_t *>(buffer.bytes.data());
560 case 4:
561 return *reinterpret_cast<const uint32_t *>(buffer.bytes.data());
562 case 8:
563 return *reinterpret_cast<const uint64_t *>(buffer.bytes.data());
564 }
565 } break;
566 }
567 if (success_ptr)
568 *success_ptr = false;
569 return fail_value;
570}
571
572llvm::APInt RegisterValue::GetAsUInt128(const llvm::APInt &fail_value,
573 bool *success_ptr) const {
574 if (success_ptr)
575 *success_ptr = true;
576 switch (m_type) {
577 default:
578 break;
579 case eTypeUInt8:
580 case eTypeUInt16:
581 case eTypeUInt32:
582 case eTypeUInt64:
583 case eTypeUInt128:
584 case eTypeFloat:
585 case eTypeDouble:
586 case eTypeLongDouble:
587 return m_scalar.UInt128(fail_value);
588 case eTypeBytes: {
589 switch (buffer.bytes.size()) {
590 default:
591 break;
592 case 1:
593 case 2:
594 case 4:
595 case 8:
596 case 16:
597 return llvm::APInt(
599 (reinterpret_cast<const type128 *>(buffer.bytes.data()))->x);
600 }
601 } break;
602 }
603 if (success_ptr)
604 *success_ptr = false;
605 return fail_value;
606}
607
608float RegisterValue::GetAsFloat(float fail_value, bool *success_ptr) const {
609 if (success_ptr)
610 *success_ptr = true;
611 switch (m_type) {
612 default:
613 break;
614 case eTypeUInt32:
615 case eTypeUInt64:
616 case eTypeUInt128:
617 case eTypeFloat:
618 case eTypeDouble:
619 case eTypeLongDouble:
620 return m_scalar.Float(fail_value);
621 }
622 if (success_ptr)
623 *success_ptr = false;
624 return fail_value;
625}
626
627double RegisterValue::GetAsDouble(double fail_value, bool *success_ptr) const {
628 if (success_ptr)
629 *success_ptr = true;
630 switch (m_type) {
631 default:
632 break;
633
634 case eTypeUInt32:
635 case eTypeUInt64:
636 case eTypeUInt128:
637 case eTypeFloat:
638 case eTypeDouble:
639 case eTypeLongDouble:
640 return m_scalar.Double(fail_value);
641 }
642 if (success_ptr)
643 *success_ptr = false;
644 return fail_value;
645}
646
647long double RegisterValue::GetAsLongDouble(long double fail_value,
648 bool *success_ptr) const {
649 if (success_ptr)
650 *success_ptr = true;
651 switch (m_type) {
652 default:
653 break;
654
655 case eTypeUInt32:
656 case eTypeUInt64:
657 case eTypeUInt128:
658 case eTypeFloat:
659 case eTypeDouble:
660 case eTypeLongDouble:
661 return m_scalar.LongDouble();
662 }
663 if (success_ptr)
664 *success_ptr = false;
665 return fail_value;
666}
667
668const void *RegisterValue::GetBytes() const {
669 switch (m_type) {
670 case eTypeInvalid:
671 break;
672 case eTypeUInt8:
673 case eTypeUInt16:
674 case eTypeUInt32:
675 case eTypeUInt64:
676 case eTypeUInt128:
677 case eTypeFloat:
678 case eTypeDouble:
679 case eTypeLongDouble:
681 return buffer.bytes.data();
682 case eTypeBytes:
683 return buffer.bytes.data();
684 }
685 return nullptr;
686}
687
689 switch (m_type) {
690 case eTypeInvalid:
691 break;
692 case eTypeUInt8:
693 return 1;
694 case eTypeUInt16:
695 return 2;
696 case eTypeUInt32:
697 case eTypeUInt64:
698 case eTypeUInt128:
699 case eTypeFloat:
700 case eTypeDouble:
701 case eTypeLongDouble:
702 return m_scalar.GetByteSize();
703 case eTypeBytes:
704 return buffer.bytes.size();
705 }
706 return 0;
707}
708
709bool RegisterValue::SetUInt(uint64_t uint, uint32_t byte_size) {
710 if (byte_size == 0) {
711 SetUInt64(uint);
712 } else if (byte_size == 1) {
713 SetUInt8(uint);
714 } else if (byte_size <= 2) {
715 SetUInt16(uint);
716 } else if (byte_size <= 4) {
717 SetUInt32(uint);
718 } else if (byte_size <= 8) {
719 SetUInt64(uint);
720 } else if (byte_size <= 16) {
721 SetUInt128(llvm::APInt(128, uint));
722 } else
723 return false;
724 return true;
725}
726
727void RegisterValue::SetBytes(const void *bytes, size_t length,
728 lldb::ByteOrder byte_order) {
729 if (bytes && length > 0) {
731 buffer.bytes.resize(length);
732 memcpy(buffer.bytes.data(), bytes, length);
733 buffer.byte_order = byte_order;
734 } else {
736 buffer.bytes.resize(0);
737 }
738}
739
741 if (m_type == rhs.m_type) {
742 switch (m_type) {
743 case eTypeInvalid:
744 return true;
745 case eTypeUInt8:
746 case eTypeUInt16:
747 case eTypeUInt32:
748 case eTypeUInt64:
749 case eTypeUInt128:
750 case eTypeFloat:
751 case eTypeDouble:
752 case eTypeLongDouble:
753 return m_scalar == rhs.m_scalar;
754 case eTypeBytes:
755 return buffer.bytes == rhs.buffer.bytes;
756 }
757 }
758 return false;
759}
760
762 return !(*this == rhs);
763}
764
766 switch (m_type) {
767 case eTypeInvalid:
768 break;
769
770 case eTypeUInt8:
771 case eTypeUInt16:
772 case eTypeUInt32:
773 case eTypeUInt64:
774 case eTypeUInt128:
775 if (bit < (GetByteSize() * 8)) {
776 return m_scalar.ClearBit(bit);
777 }
778 break;
779
780 case eTypeFloat:
781 case eTypeDouble:
782 case eTypeLongDouble:
783 break;
784
785 case eTypeBytes:
788 uint32_t byte_idx;
790 byte_idx = buffer.bytes.size() - (bit / 8) - 1;
791 else
792 byte_idx = bit / 8;
793
794 const uint32_t byte_bit = bit % 8;
795 if (byte_idx < buffer.bytes.size()) {
796 buffer.bytes[byte_idx] &= ~(1u << byte_bit);
797 return true;
798 }
799 }
800 break;
801 }
802 return false;
803}
804
806 switch (m_type) {
807 case eTypeInvalid:
808 break;
809
810 case eTypeUInt8:
811 case eTypeUInt16:
812 case eTypeUInt32:
813 case eTypeUInt64:
814 case eTypeUInt128:
815 if (bit < (GetByteSize() * 8)) {
816 return m_scalar.SetBit(bit);
817 }
818 break;
819
820 case eTypeFloat:
821 case eTypeDouble:
822 case eTypeLongDouble:
823 break;
824
825 case eTypeBytes:
828 uint32_t byte_idx;
830 byte_idx = buffer.bytes.size() - (bit / 8) - 1;
831 else
832 byte_idx = bit / 8;
833
834 const uint32_t byte_bit = bit % 8;
835 if (byte_idx < buffer.bytes.size()) {
836 buffer.bytes[byte_idx] |= (1u << byte_bit);
837 return true;
838 }
839 }
840 break;
841 }
842 return false;
843}
static llvm::raw_ostream & error(Stream &strm)
#define bit
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.
Definition: DataExtractor.h:48
float GetFloat(lldb::offset_t *offset_ptr) const
Extract a float from *offset_ptr.
uint64_t GetU64(lldb::offset_t *offset_ptr) const
Extract a uint64_t value 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
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
bool ClearBit(uint32_t bit)
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
Definition: RegisterValue.h:91
void SetLongDouble(long double f)
void SetUInt128(llvm::APInt uint)
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)
Definition: RegisterValue.h:95
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
unsigned int UInt(unsigned int fail_value=0) const
Definition: Scalar.cpp:321
bool SetBit(uint32_t bit)
Definition: Scalar.cpp:924
size_t GetByteSize() const
Definition: Scalar.cpp:132
Status SetValueFromData(const DataExtractor &data, lldb::Encoding encoding, size_t byte_size)
Definition: Scalar.cpp:702
bool SignExtend(uint32_t bit_pos)
Definition: Scalar.cpp:746
unsigned long long ULongLong(unsigned long long fail_value=0) const
Definition: Scalar.cpp:335
void GetBytes(llvm::MutableArrayRef< uint8_t > storage) const
Store the binary representation of this value into the given storage.
Definition: Scalar.cpp:114
bool ClearBit(uint32_t bit)
Definition: Scalar.cpp:911
float Float(float fail_value=0.0f) const
Definition: Scalar.cpp:363
double Double(double fail_value=0.0) const
Definition: Scalar.cpp:383
unsigned short UShort(unsigned short fail_value=0) const
Definition: Scalar.cpp:315
long double LongDouble(long double fail_value=0.0) const
Definition: Scalar.cpp:403
llvm::APInt UInt128(const llvm::APInt &fail_value) const
Definition: Scalar.cpp:351
An error handling class.
Definition: Status.h:44
bool Success() const
Test for success condition.
Definition: Status.cpp:279
#define UNUSED_IF_ASSERT_DISABLED(x)
Definition: lldb-defines.h:140
A class that represents a running process on the host machine.
Definition: SBAttachInfo.h:14
Definition: SBAddress.h:15
uint64_t offset_t
Definition: lldb-types.h:83
@ eEncodingIEEE754
float
@ eEncodingVector
vector registers
@ eEncodingUint
unsigned integer
@ eEncodingInvalid
@ eEncodingSint
signed integer
ByteOrder
Byte ordering definitions.
@ eByteOrderLittle
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.