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