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