1 //===-- RegisterValue.cpp ---------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "lldb/Utility/RegisterValue.h"
10
11 #include "lldb/Utility/DataExtractor.h"
12 #include "lldb/Utility/Scalar.h"
13 #include "lldb/Utility/Status.h"
14 #include "lldb/Utility/Stream.h"
15 #include "lldb/Utility/StreamString.h"
16 #include "lldb/lldb-defines.h"
17 #include "lldb/lldb-private-types.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 <assert.h>
28 #include <inttypes.h>
29 #include <stdio.h>
30
31 using namespace lldb;
32 using namespace lldb_private;
33
GetData(DataExtractor & data) const34 bool RegisterValue::GetData(DataExtractor &data) const {
35 return data.SetData(GetBytes(), GetByteSize(), GetByteOrder()) > 0;
36 }
37
GetAsMemoryData(const RegisterInfo * reg_info,void * dst,uint32_t dst_len,lldb::ByteOrder dst_byte_order,Status & error) const38 uint32_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 if (reg_info == nullptr) {
43 error.SetErrorString("invalid register info argument.");
44 return 0;
45 }
46
47 // ReadRegister should have already been called on this object prior to
48 // calling this.
49 if (GetType() == eTypeInvalid) {
50 // No value has been read into this object...
51 error.SetErrorStringWithFormat(
52 "invalid register value type for register %s", reg_info->name);
53 return 0;
54 }
55
56 if (dst_len > kMaxRegisterByteSize) {
57 error.SetErrorString("destination is too big");
58 return 0;
59 }
60
61 const uint32_t src_len = reg_info->byte_size;
62
63 // Extract the register data into a data extractor
64 DataExtractor reg_data;
65 if (!GetData(reg_data)) {
66 error.SetErrorString("invalid register value to copy into");
67 return 0;
68 }
69
70 // Prepare a memory buffer that contains some or all of the register value
71 const uint32_t bytes_copied =
72 reg_data.CopyByteOrderedData(0, // src offset
73 src_len, // src length
74 dst, // dst buffer
75 dst_len, // dst length
76 dst_byte_order); // dst byte order
77 if (bytes_copied == 0)
78 error.SetErrorStringWithFormat(
79 "failed to copy data for register write of %s", reg_info->name);
80
81 return bytes_copied;
82 }
83
SetFromMemoryData(const RegisterInfo * reg_info,const void * src,uint32_t src_len,lldb::ByteOrder src_byte_order,Status & error)84 uint32_t RegisterValue::SetFromMemoryData(const RegisterInfo *reg_info,
85 const void *src, uint32_t src_len,
86 lldb::ByteOrder src_byte_order,
87 Status &error) {
88 if (reg_info == nullptr) {
89 error.SetErrorString("invalid register info argument.");
90 return 0;
91 }
92
93 // Moving from addr into a register
94 //
95 // Case 1: src_len == dst_len
96 //
97 // |AABBCCDD| Address contents
98 // |AABBCCDD| Register contents
99 //
100 // Case 2: src_len > dst_len
101 //
102 // Status! (The register should always be big enough to hold the data)
103 //
104 // Case 3: src_len < dst_len
105 //
106 // |AABB| Address contents
107 // |AABB0000| Register contents [on little-endian hardware]
108 // |0000AABB| Register contents [on big-endian hardware]
109 if (src_len > kMaxRegisterByteSize) {
110 error.SetErrorStringWithFormat(
111 "register buffer is too small to receive %u bytes of data.", src_len);
112 return 0;
113 }
114
115 const uint32_t dst_len = reg_info->byte_size;
116
117 if (src_len > dst_len) {
118 error.SetErrorStringWithFormat(
119 "%u bytes is too big to store in register %s (%u bytes)", src_len,
120 reg_info->name, dst_len);
121 return 0;
122 }
123
124 // Use a data extractor to correctly copy and pad the bytes read into the
125 // register value
126 DataExtractor src_data(src, src_len, src_byte_order, 4);
127
128 error = SetValueFromData(reg_info, src_data, 0, true);
129 if (error.Fail())
130 return 0;
131
132 // If SetValueFromData succeeded, we must have copied all of src_len
133 return src_len;
134 }
135
GetScalarValue(Scalar & scalar) const136 bool RegisterValue::GetScalarValue(Scalar &scalar) const {
137 switch (m_type) {
138 case eTypeInvalid:
139 break;
140 case eTypeBytes: {
141 switch (buffer.length) {
142 default:
143 break;
144 case 1:
145 scalar = *(const uint8_t *)buffer.bytes;
146 return true;
147 case 2:
148 scalar = *reinterpret_cast<const uint16_t *>(buffer.bytes);
149 return true;
150 case 4:
151 scalar = *reinterpret_cast<const uint32_t *>(buffer.bytes);
152 return true;
153 case 8:
154 scalar = *reinterpret_cast<const uint64_t *>(buffer.bytes);
155 return true;
156 case 16:
157 case 32:
158 case 64:
159 if (buffer.length % sizeof(uint64_t) == 0) {
160 const auto length_in_bits = buffer.length * 8;
161 const auto length_in_uint64 = buffer.length / sizeof(uint64_t);
162 scalar =
163 llvm::APInt(length_in_bits,
164 llvm::ArrayRef<uint64_t>(
165 reinterpret_cast<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
UInt64ValueIsValidForByteSize(uint64_t uval64,size_t total_byte_size)332 static bool UInt64ValueIsValidForByteSize(uint64_t uval64,
333 size_t total_byte_size) {
334 if (total_byte_size > 8)
335 return false;
336
337 if (total_byte_size == 8)
338 return true;
339
340 const uint64_t max =
341 (static_cast<uint64_t>(1) << static_cast<uint64_t>(total_byte_size * 8)) -
342 1;
343 return uval64 <= max;
344 }
345
SInt64ValueIsValidForByteSize(int64_t sval64,size_t total_byte_size)346 static bool SInt64ValueIsValidForByteSize(int64_t sval64,
347 size_t total_byte_size) {
348 if (total_byte_size > 8)
349 return false;
350
351 if (total_byte_size == 8)
352 return true;
353
354 const int64_t max = (static_cast<int64_t>(1)
355 << static_cast<uint64_t>(total_byte_size * 8 - 1)) -
356 1;
357 const int64_t min = ~(max);
358 return min <= sval64 && sval64 <= max;
359 }
360
SetValueFromString(const RegisterInfo * reg_info,llvm::StringRef value_str)361 Status RegisterValue::SetValueFromString(const RegisterInfo *reg_info,
362 llvm::StringRef value_str) {
363 Status error;
364 if (reg_info == nullptr) {
365 error.SetErrorString("Invalid register info argument.");
366 return error;
367 }
368
369 m_type = eTypeInvalid;
370 if (value_str.empty()) {
371 error.SetErrorString("Invalid c-string value string.");
372 return error;
373 }
374 const uint32_t byte_size = reg_info->byte_size;
375
376 uint64_t uval64;
377 int64_t ival64;
378 float flt_val;
379 double dbl_val;
380 long double ldbl_val;
381 switch (reg_info->encoding) {
382 case eEncodingInvalid:
383 error.SetErrorString("Invalid encoding.");
384 break;
385
386 case eEncodingUint:
387 if (byte_size > sizeof(uint64_t)) {
388 error.SetErrorStringWithFormat(
389 "unsupported unsigned integer byte size: %u", byte_size);
390 break;
391 }
392 if (value_str.getAsInteger(0, uval64)) {
393 error.SetErrorStringWithFormat(
394 "'%s' is not a valid unsigned integer string value",
395 value_str.str().c_str());
396 break;
397 }
398
399 if (!UInt64ValueIsValidForByteSize(uval64, byte_size)) {
400 error.SetErrorStringWithFormat(
401 "value 0x%" PRIx64
402 " is too large to fit in a %u byte unsigned integer value",
403 uval64, byte_size);
404 break;
405 }
406
407 if (!SetUInt(uval64, reg_info->byte_size)) {
408 error.SetErrorStringWithFormat(
409 "unsupported unsigned integer byte size: %u", byte_size);
410 break;
411 }
412 break;
413
414 case eEncodingSint:
415 if (byte_size > sizeof(long long)) {
416 error.SetErrorStringWithFormat("unsupported signed integer byte size: %u",
417 byte_size);
418 break;
419 }
420
421 if (value_str.getAsInteger(0, ival64)) {
422 error.SetErrorStringWithFormat(
423 "'%s' is not a valid signed integer string value",
424 value_str.str().c_str());
425 break;
426 }
427
428 if (!SInt64ValueIsValidForByteSize(ival64, byte_size)) {
429 error.SetErrorStringWithFormat(
430 "value 0x%" PRIx64
431 " is too large to fit in a %u byte signed integer value",
432 ival64, byte_size);
433 break;
434 }
435
436 if (!SetUInt(ival64, reg_info->byte_size)) {
437 error.SetErrorStringWithFormat("unsupported signed integer byte size: %u",
438 byte_size);
439 break;
440 }
441 break;
442
443 case eEncodingIEEE754: {
444 std::string value_string = value_str;
445 if (byte_size == sizeof(float)) {
446 if (::sscanf(value_string.c_str(), "%f", &flt_val) != 1) {
447 error.SetErrorStringWithFormat("'%s' is not a valid float string value",
448 value_string.c_str());
449 break;
450 }
451 m_scalar = flt_val;
452 m_type = eTypeFloat;
453 } else if (byte_size == sizeof(double)) {
454 if (::sscanf(value_string.c_str(), "%lf", &dbl_val) != 1) {
455 error.SetErrorStringWithFormat("'%s' is not a valid float string value",
456 value_string.c_str());
457 break;
458 }
459 m_scalar = dbl_val;
460 m_type = eTypeDouble;
461 } else if (byte_size == sizeof(long double)) {
462 if (::sscanf(value_string.c_str(), "%Lf", &ldbl_val) != 1) {
463 error.SetErrorStringWithFormat("'%s' is not a valid float string value",
464 value_string.c_str());
465 break;
466 }
467 m_scalar = ldbl_val;
468 m_type = eTypeLongDouble;
469 } else {
470 error.SetErrorStringWithFormat("unsupported float byte size: %u",
471 byte_size);
472 return error;
473 }
474 break;
475 }
476 case eEncodingVector:
477 if (!ParseVectorEncoding(reg_info, value_str, byte_size, this))
478 error.SetErrorString("unrecognized vector encoding string value.");
479 break;
480 }
481
482 return error;
483 }
484
SignExtend(uint32_t sign_bitpos)485 bool RegisterValue::SignExtend(uint32_t sign_bitpos) {
486 switch (m_type) {
487 case eTypeInvalid:
488 break;
489
490 case eTypeUInt8:
491 case eTypeUInt16:
492 case eTypeUInt32:
493 case eTypeUInt64:
494 case eTypeUInt128:
495 return m_scalar.SignExtend(sign_bitpos);
496 case eTypeFloat:
497 case eTypeDouble:
498 case eTypeLongDouble:
499 case eTypeBytes:
500 break;
501 }
502 return false;
503 }
504
CopyValue(const RegisterValue & rhs)505 bool RegisterValue::CopyValue(const RegisterValue &rhs) {
506 if (this == &rhs)
507 return rhs.m_type != eTypeInvalid;
508
509 m_type = rhs.m_type;
510 switch (m_type) {
511 case eTypeInvalid:
512 return false;
513 case eTypeUInt8:
514 case eTypeUInt16:
515 case eTypeUInt32:
516 case eTypeUInt64:
517 case eTypeUInt128:
518 case eTypeFloat:
519 case eTypeDouble:
520 case eTypeLongDouble:
521 m_scalar = rhs.m_scalar;
522 break;
523 case eTypeBytes:
524 assert(rhs.buffer.length <= kMaxRegisterByteSize);
525 ::memcpy(buffer.bytes, rhs.buffer.bytes, kMaxRegisterByteSize);
526 buffer.length = rhs.buffer.length;
527 buffer.byte_order = rhs.buffer.byte_order;
528 break;
529 }
530 return true;
531 }
532
GetAsUInt16(uint16_t fail_value,bool * success_ptr) const533 uint16_t RegisterValue::GetAsUInt16(uint16_t fail_value,
534 bool *success_ptr) const {
535 if (success_ptr)
536 *success_ptr = true;
537
538 switch (m_type) {
539 default:
540 break;
541 case eTypeUInt8:
542 case eTypeUInt16:
543 return m_scalar.UShort(fail_value);
544 case eTypeBytes: {
545 switch (buffer.length) {
546 default:
547 break;
548 case 1:
549 case 2:
550 return *reinterpret_cast<const uint16_t *>(buffer.bytes);
551 }
552 } break;
553 }
554 if (success_ptr)
555 *success_ptr = false;
556 return fail_value;
557 }
558
GetAsUInt32(uint32_t fail_value,bool * success_ptr) const559 uint32_t RegisterValue::GetAsUInt32(uint32_t fail_value,
560 bool *success_ptr) const {
561 if (success_ptr)
562 *success_ptr = true;
563 switch (m_type) {
564 default:
565 break;
566 case eTypeUInt8:
567 case eTypeUInt16:
568 case eTypeUInt32:
569 case eTypeFloat:
570 case eTypeDouble:
571 case eTypeLongDouble:
572 return m_scalar.UInt(fail_value);
573 case eTypeBytes: {
574 switch (buffer.length) {
575 default:
576 break;
577 case 1:
578 case 2:
579 case 4:
580 return *reinterpret_cast<const uint32_t *>(buffer.bytes);
581 }
582 } break;
583 }
584 if (success_ptr)
585 *success_ptr = false;
586 return fail_value;
587 }
588
GetAsUInt64(uint64_t fail_value,bool * success_ptr) const589 uint64_t RegisterValue::GetAsUInt64(uint64_t fail_value,
590 bool *success_ptr) const {
591 if (success_ptr)
592 *success_ptr = true;
593 switch (m_type) {
594 default:
595 break;
596 case eTypeUInt8:
597 case eTypeUInt16:
598 case eTypeUInt32:
599 case eTypeUInt64:
600 case eTypeFloat:
601 case eTypeDouble:
602 case eTypeLongDouble:
603 return m_scalar.ULongLong(fail_value);
604 case eTypeBytes: {
605 switch (buffer.length) {
606 default:
607 break;
608 case 1:
609 return *(const uint8_t *)buffer.bytes;
610 case 2:
611 return *reinterpret_cast<const uint16_t *>(buffer.bytes);
612 case 4:
613 return *reinterpret_cast<const uint32_t *>(buffer.bytes);
614 case 8:
615 return *reinterpret_cast<const uint64_t *>(buffer.bytes);
616 }
617 } break;
618 }
619 if (success_ptr)
620 *success_ptr = false;
621 return fail_value;
622 }
623
GetAsUInt128(const llvm::APInt & fail_value,bool * success_ptr) const624 llvm::APInt RegisterValue::GetAsUInt128(const llvm::APInt &fail_value,
625 bool *success_ptr) const {
626 if (success_ptr)
627 *success_ptr = true;
628 switch (m_type) {
629 default:
630 break;
631 case eTypeUInt8:
632 case eTypeUInt16:
633 case eTypeUInt32:
634 case eTypeUInt64:
635 case eTypeUInt128:
636 case eTypeFloat:
637 case eTypeDouble:
638 case eTypeLongDouble:
639 return m_scalar.UInt128(fail_value);
640 case eTypeBytes: {
641 switch (buffer.length) {
642 default:
643 break;
644 case 1:
645 case 2:
646 case 4:
647 case 8:
648 case 16:
649 return llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128,
650 (reinterpret_cast<const type128 *>(buffer.bytes))->x);
651 }
652 } break;
653 }
654 if (success_ptr)
655 *success_ptr = false;
656 return fail_value;
657 }
658
GetAsFloat(float fail_value,bool * success_ptr) const659 float RegisterValue::GetAsFloat(float fail_value, bool *success_ptr) const {
660 if (success_ptr)
661 *success_ptr = true;
662 switch (m_type) {
663 default:
664 break;
665 case eTypeUInt32:
666 case eTypeUInt64:
667 case eTypeUInt128:
668 case eTypeFloat:
669 case eTypeDouble:
670 case eTypeLongDouble:
671 return m_scalar.Float(fail_value);
672 }
673 if (success_ptr)
674 *success_ptr = false;
675 return fail_value;
676 }
677
GetAsDouble(double fail_value,bool * success_ptr) const678 double RegisterValue::GetAsDouble(double fail_value, 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 eTypeUInt128:
688 case eTypeFloat:
689 case eTypeDouble:
690 case eTypeLongDouble:
691 return m_scalar.Double(fail_value);
692 }
693 if (success_ptr)
694 *success_ptr = false;
695 return fail_value;
696 }
697
GetAsLongDouble(long double fail_value,bool * success_ptr) const698 long double RegisterValue::GetAsLongDouble(long double fail_value,
699 bool *success_ptr) const {
700 if (success_ptr)
701 *success_ptr = true;
702 switch (m_type) {
703 default:
704 break;
705
706 case eTypeUInt32:
707 case eTypeUInt64:
708 case eTypeUInt128:
709 case eTypeFloat:
710 case eTypeDouble:
711 case eTypeLongDouble:
712 return m_scalar.LongDouble();
713 }
714 if (success_ptr)
715 *success_ptr = false;
716 return fail_value;
717 }
718
GetBytes() const719 const void *RegisterValue::GetBytes() const {
720 switch (m_type) {
721 case eTypeInvalid:
722 break;
723 case eTypeUInt8:
724 case eTypeUInt16:
725 case eTypeUInt32:
726 case eTypeUInt64:
727 case eTypeUInt128:
728 case eTypeFloat:
729 case eTypeDouble:
730 case eTypeLongDouble:
731 return m_scalar.GetBytes();
732 case eTypeBytes:
733 return buffer.bytes;
734 }
735 return nullptr;
736 }
737
GetByteSize() const738 uint32_t RegisterValue::GetByteSize() const {
739 switch (m_type) {
740 case eTypeInvalid:
741 break;
742 case eTypeUInt8:
743 return 1;
744 case eTypeUInt16:
745 return 2;
746 case eTypeUInt32:
747 case eTypeUInt64:
748 case eTypeUInt128:
749 case eTypeFloat:
750 case eTypeDouble:
751 case eTypeLongDouble:
752 return m_scalar.GetByteSize();
753 case eTypeBytes:
754 return buffer.length;
755 }
756 return 0;
757 }
758
SetUInt(uint64_t uint,uint32_t byte_size)759 bool RegisterValue::SetUInt(uint64_t uint, uint32_t byte_size) {
760 if (byte_size == 0) {
761 SetUInt64(uint);
762 } else if (byte_size == 1) {
763 SetUInt8(uint);
764 } else if (byte_size <= 2) {
765 SetUInt16(uint);
766 } else if (byte_size <= 4) {
767 SetUInt32(uint);
768 } else if (byte_size <= 8) {
769 SetUInt64(uint);
770 } else if (byte_size <= 16) {
771 SetUInt128(llvm::APInt(128, uint));
772 } else
773 return false;
774 return true;
775 }
776
SetBytes(const void * bytes,size_t length,lldb::ByteOrder byte_order)777 void RegisterValue::SetBytes(const void *bytes, size_t length,
778 lldb::ByteOrder byte_order) {
779 // If this assertion fires off we need to increase the size of buffer.bytes,
780 // or make it something that is allocated on the heap. Since the data buffer
781 // is in a union, we can't make it a collection class like SmallVector...
782 if (bytes && length > 0) {
783 assert(length <= sizeof(buffer.bytes) &&
784 "Storing too many bytes in a RegisterValue.");
785 m_type = eTypeBytes;
786 buffer.length = length;
787 memcpy(buffer.bytes, bytes, length);
788 buffer.byte_order = byte_order;
789 } else {
790 m_type = eTypeInvalid;
791 buffer.length = 0;
792 }
793 }
794
operator ==(const RegisterValue & rhs) const795 bool RegisterValue::operator==(const RegisterValue &rhs) const {
796 if (m_type == rhs.m_type) {
797 switch (m_type) {
798 case eTypeInvalid:
799 return true;
800 case eTypeUInt8:
801 case eTypeUInt16:
802 case eTypeUInt32:
803 case eTypeUInt64:
804 case eTypeUInt128:
805 case eTypeFloat:
806 case eTypeDouble:
807 case eTypeLongDouble:
808 return m_scalar == rhs.m_scalar;
809 case eTypeBytes:
810 if (buffer.length != rhs.buffer.length)
811 return false;
812 else {
813 uint8_t length = buffer.length;
814 if (length > kMaxRegisterByteSize)
815 length = kMaxRegisterByteSize;
816 return memcmp(buffer.bytes, rhs.buffer.bytes, length) == 0;
817 }
818 break;
819 }
820 }
821 return false;
822 }
823
operator !=(const RegisterValue & rhs) const824 bool RegisterValue::operator!=(const RegisterValue &rhs) const {
825 return !(*this == rhs);
826 }
827
ClearBit(uint32_t bit)828 bool RegisterValue::ClearBit(uint32_t bit) {
829 switch (m_type) {
830 case eTypeInvalid:
831 break;
832
833 case eTypeUInt8:
834 case eTypeUInt16:
835 case eTypeUInt32:
836 case eTypeUInt64:
837 case eTypeUInt128:
838 if (bit < (GetByteSize() * 8)) {
839 return m_scalar.ClearBit(bit);
840 }
841 break;
842
843 case eTypeFloat:
844 case eTypeDouble:
845 case eTypeLongDouble:
846 break;
847
848 case eTypeBytes:
849 if (buffer.byte_order == eByteOrderBig ||
850 buffer.byte_order == eByteOrderLittle) {
851 uint32_t byte_idx;
852 if (buffer.byte_order == eByteOrderBig)
853 byte_idx = buffer.length - (bit / 8) - 1;
854 else
855 byte_idx = bit / 8;
856
857 const uint32_t byte_bit = bit % 8;
858 if (byte_idx < buffer.length) {
859 buffer.bytes[byte_idx] &= ~(1u << byte_bit);
860 return true;
861 }
862 }
863 break;
864 }
865 return false;
866 }
867
SetBit(uint32_t bit)868 bool RegisterValue::SetBit(uint32_t bit) {
869 switch (m_type) {
870 case eTypeInvalid:
871 break;
872
873 case eTypeUInt8:
874 case eTypeUInt16:
875 case eTypeUInt32:
876 case eTypeUInt64:
877 case eTypeUInt128:
878 if (bit < (GetByteSize() * 8)) {
879 return m_scalar.SetBit(bit);
880 }
881 break;
882
883 case eTypeFloat:
884 case eTypeDouble:
885 case eTypeLongDouble:
886 break;
887
888 case eTypeBytes:
889 if (buffer.byte_order == eByteOrderBig ||
890 buffer.byte_order == eByteOrderLittle) {
891 uint32_t byte_idx;
892 if (buffer.byte_order == eByteOrderBig)
893 byte_idx = buffer.length - (bit / 8) - 1;
894 else
895 byte_idx = bit / 8;
896
897 const uint32_t byte_bit = bit % 8;
898 if (byte_idx < buffer.length) {
899 buffer.bytes[byte_idx] |= (1u << byte_bit);
900 return true;
901 }
902 }
903 break;
904 }
905 return false;
906 }
907