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 
31 using namespace lldb;
32 using namespace lldb_private;
33 
34 bool RegisterValue::GetData(DataExtractor &data) const {
35  return data.SetData(GetBytes(), GetByteSize(), GetByteOrder()) > 0;
36 }
37 
38 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 
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 
136 bool RegisterValue::GetScalarValue(Scalar &scalar) const {
137  switch (m_type) {
138  case eTypeInvalid:
139  break;
140  case eTypeBytes: {
141  DataExtractor data(buffer.bytes, buffer.length, buffer.byte_order, 1);
142  if (scalar.SetValueFromData(data, lldb::eEncodingUint,
143  buffer.length).Success())
144  return true;
145  } break;
146  case eTypeUInt8:
147  case eTypeUInt16:
148  case eTypeUInt32:
149  case eTypeUInt64:
150  case eTypeUInt128:
151  case eTypeFloat:
152  case eTypeDouble:
153  case eTypeLongDouble:
154  scalar = m_scalar;
155  return true;
156  }
157  return false;
158 }
159 
160 void RegisterValue::Clear() { m_type = eTypeInvalid; }
161 
162 RegisterValue::Type RegisterValue::SetType(const RegisterInfo *reg_info) {
163  // To change the type, we simply copy the data in again, using the new format
164  RegisterValue copy;
165  DataExtractor copy_data;
166  if (copy.CopyValue(*this) && copy.GetData(copy_data))
167  SetValueFromData(reg_info, copy_data, 0, true);
168 
169  return m_type;
170 }
171 
172 Status RegisterValue::SetValueFromData(const RegisterInfo *reg_info,
173  DataExtractor &src,
174  lldb::offset_t src_offset,
175  bool partial_data_ok) {
176  Status error;
177 
178  if (src.GetByteSize() == 0) {
179  error.SetErrorString("empty data.");
180  return error;
181  }
182 
183  if (reg_info->byte_size == 0) {
184  error.SetErrorString("invalid register info.");
185  return error;
186  }
187 
188  uint32_t src_len = src.GetByteSize() - src_offset;
189 
190  if (!partial_data_ok && (src_len < reg_info->byte_size)) {
191  error.SetErrorString("not enough data.");
192  return error;
193  }
194 
195  // Cap the data length if there is more than enough bytes for this register
196  // value
197  if (src_len > reg_info->byte_size)
198  src_len = reg_info->byte_size;
199 
200  // Zero out the value in case we get partial data...
201  memset(buffer.bytes, 0, sizeof(buffer.bytes));
202 
203  type128 int128;
204 
205  m_type = eTypeInvalid;
206  switch (reg_info->encoding) {
207  case eEncodingInvalid:
208  break;
209  case eEncodingUint:
210  case eEncodingSint:
211  if (reg_info->byte_size == 1)
212  SetUInt8(src.GetMaxU32(&src_offset, src_len));
213  else if (reg_info->byte_size <= 2)
214  SetUInt16(src.GetMaxU32(&src_offset, src_len));
215  else if (reg_info->byte_size <= 4)
216  SetUInt32(src.GetMaxU32(&src_offset, src_len));
217  else if (reg_info->byte_size <= 8)
218  SetUInt64(src.GetMaxU64(&src_offset, src_len));
219  else if (reg_info->byte_size <= 16) {
220  uint64_t data1 = src.GetU64(&src_offset);
221  uint64_t data2 = src.GetU64(&src_offset);
222  if (src.GetByteSize() == eByteOrderBig) {
223  int128.x[0] = data1;
224  int128.x[1] = data2;
225  } else {
226  int128.x[0] = data2;
227  int128.x[1] = data1;
228  }
229  SetUInt128(llvm::APInt(128, 2, int128.x));
230  }
231  break;
232  case eEncodingIEEE754:
233  if (reg_info->byte_size == sizeof(float))
234  SetFloat(src.GetFloat(&src_offset));
235  else if (reg_info->byte_size == sizeof(double))
236  SetDouble(src.GetDouble(&src_offset));
237  else if (reg_info->byte_size == sizeof(long double))
238  SetLongDouble(src.GetLongDouble(&src_offset));
239  break;
240  case eEncodingVector: {
241  m_type = eTypeBytes;
242  buffer.length = reg_info->byte_size;
243  buffer.byte_order = src.GetByteOrder();
244  assert(buffer.length <= kMaxRegisterByteSize);
245  if (buffer.length > kMaxRegisterByteSize)
246  buffer.length = kMaxRegisterByteSize;
247  if (src.CopyByteOrderedData(
248  src_offset, // offset within "src" to start extracting data
249  src_len, // src length
250  buffer.bytes, // dst buffer
251  buffer.length, // dst length
252  buffer.byte_order) == 0) // dst byte order
253  {
254  error.SetErrorStringWithFormat(
255  "failed to copy data for register write of %s", reg_info->name);
256  return error;
257  }
258  }
259  }
260 
261  if (m_type == eTypeInvalid)
262  error.SetErrorStringWithFormat(
263  "invalid register value type for register %s", reg_info->name);
264  return error;
265 }
266 
267 // Helper function for RegisterValue::SetValueFromString()
268 static bool ParseVectorEncoding(const RegisterInfo *reg_info,
269  llvm::StringRef vector_str,
270  const uint32_t byte_size,
271  RegisterValue *reg_value) {
272  // Example: vector_str = "{0x2c 0x4b 0x2a 0x3e 0xd0 0x4f 0x2a 0x3e 0xac 0x4a
273  // 0x2a 0x3e 0x84 0x4f 0x2a 0x3e}".
274  vector_str = vector_str.trim();
275  vector_str.consume_front("{");
276  vector_str.consume_back("}");
277  vector_str = vector_str.trim();
278 
279  char Sep = ' ';
280 
281  // The first split should give us:
282  // ('0x2c', '0x4b 0x2a 0x3e 0xd0 0x4f 0x2a 0x3e 0xac 0x4a 0x2a 0x3e 0x84 0x4f
283  // 0x2a 0x3e').
284  llvm::StringRef car;
285  llvm::StringRef cdr = vector_str;
286  std::tie(car, cdr) = vector_str.split(Sep);
287  std::vector<uint8_t> bytes;
288  unsigned byte = 0;
289 
290  // Using radix auto-sensing by passing 0 as the radix. Keep on processing the
291  // vector elements as long as the parsing succeeds and the vector size is <
292  // byte_size.
293  while (!car.getAsInteger(0, byte) && bytes.size() < byte_size) {
294  bytes.push_back(byte);
295  std::tie(car, cdr) = cdr.split(Sep);
296  }
297 
298  // Check for vector of exact byte_size elements.
299  if (bytes.size() != byte_size)
300  return false;
301 
302  reg_value->SetBytes(&(bytes.front()), byte_size, eByteOrderLittle);
303  return true;
304 }
305 
306 static bool UInt64ValueIsValidForByteSize(uint64_t uval64,
307  size_t total_byte_size) {
308  if (total_byte_size > 8)
309  return false;
310 
311  if (total_byte_size == 8)
312  return true;
313 
314  const uint64_t max =
315  (static_cast<uint64_t>(1) << static_cast<uint64_t>(total_byte_size * 8)) -
316  1;
317  return uval64 <= max;
318 }
319 
320 static bool SInt64ValueIsValidForByteSize(int64_t sval64,
321  size_t total_byte_size) {
322  if (total_byte_size > 8)
323  return false;
324 
325  if (total_byte_size == 8)
326  return true;
327 
328  const int64_t max = (static_cast<int64_t>(1)
329  << static_cast<uint64_t>(total_byte_size * 8 - 1)) -
330  1;
331  const int64_t min = ~(max);
332  return min <= sval64 && sval64 <= max;
333 }
334 
335 Status RegisterValue::SetValueFromString(const RegisterInfo *reg_info,
336  llvm::StringRef value_str) {
337  Status error;
338  if (reg_info == nullptr) {
339  error.SetErrorString("Invalid register info argument.");
340  return error;
341  }
342 
343  m_type = eTypeInvalid;
344  if (value_str.empty()) {
345  error.SetErrorString("Invalid c-string value string.");
346  return error;
347  }
348  const uint32_t byte_size = reg_info->byte_size;
349 
350  uint64_t uval64;
351  int64_t ival64;
352  float flt_val;
353  double dbl_val;
354  long double ldbl_val;
355  switch (reg_info->encoding) {
356  case eEncodingInvalid:
357  error.SetErrorString("Invalid encoding.");
358  break;
359 
360  case eEncodingUint:
361  if (byte_size > sizeof(uint64_t)) {
362  error.SetErrorStringWithFormat(
363  "unsupported unsigned integer byte size: %u", byte_size);
364  break;
365  }
366  if (value_str.getAsInteger(0, uval64)) {
367  error.SetErrorStringWithFormat(
368  "'%s' is not a valid unsigned integer string value",
369  value_str.str().c_str());
370  break;
371  }
372 
373  if (!UInt64ValueIsValidForByteSize(uval64, byte_size)) {
374  error.SetErrorStringWithFormat(
375  "value 0x%" PRIx64
376  " is too large to fit in a %u byte unsigned integer value",
377  uval64, byte_size);
378  break;
379  }
380 
381  if (!SetUInt(uval64, reg_info->byte_size)) {
382  error.SetErrorStringWithFormat(
383  "unsupported unsigned integer byte size: %u", byte_size);
384  break;
385  }
386  break;
387 
388  case eEncodingSint:
389  if (byte_size > sizeof(long long)) {
390  error.SetErrorStringWithFormat("unsupported signed integer byte size: %u",
391  byte_size);
392  break;
393  }
394 
395  if (value_str.getAsInteger(0, ival64)) {
396  error.SetErrorStringWithFormat(
397  "'%s' is not a valid signed integer string value",
398  value_str.str().c_str());
399  break;
400  }
401 
402  if (!SInt64ValueIsValidForByteSize(ival64, byte_size)) {
403  error.SetErrorStringWithFormat(
404  "value 0x%" PRIx64
405  " is too large to fit in a %u byte signed integer value",
406  ival64, byte_size);
407  break;
408  }
409 
410  if (!SetUInt(ival64, reg_info->byte_size)) {
411  error.SetErrorStringWithFormat("unsupported signed integer byte size: %u",
412  byte_size);
413  break;
414  }
415  break;
416 
417  case eEncodingIEEE754: {
418  std::string value_string = std::string(value_str);
419  if (byte_size == sizeof(float)) {
420  if (::sscanf(value_string.c_str(), "%f", &flt_val) != 1) {
421  error.SetErrorStringWithFormat("'%s' is not a valid float string value",
422  value_string.c_str());
423  break;
424  }
425  m_scalar = flt_val;
426  m_type = eTypeFloat;
427  } else if (byte_size == sizeof(double)) {
428  if (::sscanf(value_string.c_str(), "%lf", &dbl_val) != 1) {
429  error.SetErrorStringWithFormat("'%s' is not a valid float string value",
430  value_string.c_str());
431  break;
432  }
433  m_scalar = dbl_val;
434  m_type = eTypeDouble;
435  } else if (byte_size == sizeof(long double)) {
436  if (::sscanf(value_string.c_str(), "%Lf", &ldbl_val) != 1) {
437  error.SetErrorStringWithFormat("'%s' is not a valid float string value",
438  value_string.c_str());
439  break;
440  }
441  m_scalar = ldbl_val;
442  m_type = eTypeLongDouble;
443  } else {
444  error.SetErrorStringWithFormat("unsupported float byte size: %u",
445  byte_size);
446  return error;
447  }
448  break;
449  }
450  case eEncodingVector:
451  if (!ParseVectorEncoding(reg_info, value_str, byte_size, this))
452  error.SetErrorString("unrecognized vector encoding string value.");
453  break;
454  }
455 
456  return error;
457 }
458 
459 bool RegisterValue::SignExtend(uint32_t sign_bitpos) {
460  switch (m_type) {
461  case eTypeInvalid:
462  break;
463 
464  case eTypeUInt8:
465  case eTypeUInt16:
466  case eTypeUInt32:
467  case eTypeUInt64:
468  case eTypeUInt128:
469  return m_scalar.SignExtend(sign_bitpos);
470  case eTypeFloat:
471  case eTypeDouble:
472  case eTypeLongDouble:
473  case eTypeBytes:
474  break;
475  }
476  return false;
477 }
478 
479 bool RegisterValue::CopyValue(const RegisterValue &rhs) {
480  if (this == &rhs)
481  return rhs.m_type != eTypeInvalid;
482 
483  m_type = rhs.m_type;
484  switch (m_type) {
485  case eTypeInvalid:
486  return false;
487  case eTypeUInt8:
488  case eTypeUInt16:
489  case eTypeUInt32:
490  case eTypeUInt64:
491  case eTypeUInt128:
492  case eTypeFloat:
493  case eTypeDouble:
494  case eTypeLongDouble:
495  m_scalar = rhs.m_scalar;
496  break;
497  case eTypeBytes:
498  assert(rhs.buffer.length <= kMaxRegisterByteSize);
499  ::memcpy(buffer.bytes, rhs.buffer.bytes, kMaxRegisterByteSize);
500  buffer.length = rhs.buffer.length;
501  buffer.byte_order = rhs.buffer.byte_order;
502  break;
503  }
504  return true;
505 }
506 
507 uint16_t RegisterValue::GetAsUInt16(uint16_t fail_value,
508  bool *success_ptr) const {
509  if (success_ptr)
510  *success_ptr = true;
511 
512  switch (m_type) {
513  default:
514  break;
515  case eTypeUInt8:
516  case eTypeUInt16:
517  return m_scalar.UShort(fail_value);
518  case eTypeBytes: {
519  switch (buffer.length) {
520  default:
521  break;
522  case 1:
523  case 2:
524  return *reinterpret_cast<const uint16_t *>(buffer.bytes);
525  }
526  } break;
527  }
528  if (success_ptr)
529  *success_ptr = false;
530  return fail_value;
531 }
532 
533 uint32_t RegisterValue::GetAsUInt32(uint32_t fail_value,
534  bool *success_ptr) const {
535  if (success_ptr)
536  *success_ptr = true;
537  switch (m_type) {
538  default:
539  break;
540  case eTypeUInt8:
541  case eTypeUInt16:
542  case eTypeUInt32:
543  case eTypeFloat:
544  case eTypeDouble:
545  case eTypeLongDouble:
546  return m_scalar.UInt(fail_value);
547  case eTypeBytes: {
548  switch (buffer.length) {
549  default:
550  break;
551  case 1:
552  case 2:
553  case 4:
554  return *reinterpret_cast<const uint32_t *>(buffer.bytes);
555  }
556  } break;
557  }
558  if (success_ptr)
559  *success_ptr = false;
560  return fail_value;
561 }
562 
563 uint64_t RegisterValue::GetAsUInt64(uint64_t fail_value,
564  bool *success_ptr) const {
565  if (success_ptr)
566  *success_ptr = true;
567  switch (m_type) {
568  default:
569  break;
570  case eTypeUInt8:
571  case eTypeUInt16:
572  case eTypeUInt32:
573  case eTypeUInt64:
574  case eTypeFloat:
575  case eTypeDouble:
576  case eTypeLongDouble:
577  return m_scalar.ULongLong(fail_value);
578  case eTypeBytes: {
579  switch (buffer.length) {
580  default:
581  break;
582  case 1:
583  return *(const uint8_t *)buffer.bytes;
584  case 2:
585  return *reinterpret_cast<const uint16_t *>(buffer.bytes);
586  case 4:
587  return *reinterpret_cast<const uint32_t *>(buffer.bytes);
588  case 8:
589  return *reinterpret_cast<const uint64_t *>(buffer.bytes);
590  }
591  } break;
592  }
593  if (success_ptr)
594  *success_ptr = false;
595  return fail_value;
596 }
597 
598 llvm::APInt RegisterValue::GetAsUInt128(const llvm::APInt &fail_value,
599  bool *success_ptr) const {
600  if (success_ptr)
601  *success_ptr = true;
602  switch (m_type) {
603  default:
604  break;
605  case eTypeUInt8:
606  case eTypeUInt16:
607  case eTypeUInt32:
608  case eTypeUInt64:
609  case eTypeUInt128:
610  case eTypeFloat:
611  case eTypeDouble:
612  case eTypeLongDouble:
613  return m_scalar.UInt128(fail_value);
614  case eTypeBytes: {
615  switch (buffer.length) {
616  default:
617  break;
618  case 1:
619  case 2:
620  case 4:
621  case 8:
622  case 16:
623  return llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128,
624  (reinterpret_cast<const type128 *>(buffer.bytes))->x);
625  }
626  } break;
627  }
628  if (success_ptr)
629  *success_ptr = false;
630  return fail_value;
631 }
632 
633 float RegisterValue::GetAsFloat(float fail_value, bool *success_ptr) const {
634  if (success_ptr)
635  *success_ptr = true;
636  switch (m_type) {
637  default:
638  break;
639  case eTypeUInt32:
640  case eTypeUInt64:
641  case eTypeUInt128:
642  case eTypeFloat:
643  case eTypeDouble:
644  case eTypeLongDouble:
645  return m_scalar.Float(fail_value);
646  }
647  if (success_ptr)
648  *success_ptr = false;
649  return fail_value;
650 }
651 
652 double RegisterValue::GetAsDouble(double fail_value, bool *success_ptr) const {
653  if (success_ptr)
654  *success_ptr = true;
655  switch (m_type) {
656  default:
657  break;
658 
659  case eTypeUInt32:
660  case eTypeUInt64:
661  case eTypeUInt128:
662  case eTypeFloat:
663  case eTypeDouble:
664  case eTypeLongDouble:
665  return m_scalar.Double(fail_value);
666  }
667  if (success_ptr)
668  *success_ptr = false;
669  return fail_value;
670 }
671 
672 long double RegisterValue::GetAsLongDouble(long double fail_value,
673  bool *success_ptr) const {
674  if (success_ptr)
675  *success_ptr = true;
676  switch (m_type) {
677  default:
678  break;
679 
680  case eTypeUInt32:
681  case eTypeUInt64:
682  case eTypeUInt128:
683  case eTypeFloat:
684  case eTypeDouble:
685  case eTypeLongDouble:
686  return m_scalar.LongDouble();
687  }
688  if (success_ptr)
689  *success_ptr = false;
690  return fail_value;
691 }
692 
693 const void *RegisterValue::GetBytes() const {
694  switch (m_type) {
695  case eTypeInvalid:
696  break;
697  case eTypeUInt8:
698  case eTypeUInt16:
699  case eTypeUInt32:
700  case eTypeUInt64:
701  case eTypeUInt128:
702  case eTypeFloat:
703  case eTypeDouble:
704  case eTypeLongDouble:
705  m_scalar.GetBytes(buffer.bytes);
706  return buffer.bytes;
707  case eTypeBytes:
708  return buffer.bytes;
709  }
710  return nullptr;
711 }
712 
713 uint32_t RegisterValue::GetByteSize() const {
714  switch (m_type) {
715  case eTypeInvalid:
716  break;
717  case eTypeUInt8:
718  return 1;
719  case eTypeUInt16:
720  return 2;
721  case eTypeUInt32:
722  case eTypeUInt64:
723  case eTypeUInt128:
724  case eTypeFloat:
725  case eTypeDouble:
726  case eTypeLongDouble:
727  return m_scalar.GetByteSize();
728  case eTypeBytes:
729  return buffer.length;
730  }
731  return 0;
732 }
733 
734 bool RegisterValue::SetUInt(uint64_t uint, uint32_t byte_size) {
735  if (byte_size == 0) {
736  SetUInt64(uint);
737  } else if (byte_size == 1) {
738  SetUInt8(uint);
739  } else if (byte_size <= 2) {
740  SetUInt16(uint);
741  } else if (byte_size <= 4) {
742  SetUInt32(uint);
743  } else if (byte_size <= 8) {
744  SetUInt64(uint);
745  } else if (byte_size <= 16) {
746  SetUInt128(llvm::APInt(128, uint));
747  } else
748  return false;
749  return true;
750 }
751 
752 void RegisterValue::SetBytes(const void *bytes, size_t length,
753  lldb::ByteOrder byte_order) {
754  // If this assertion fires off we need to increase the size of buffer.bytes,
755  // or make it something that is allocated on the heap. Since the data buffer
756  // is in a union, we can't make it a collection class like SmallVector...
757  if (bytes && length > 0) {
758  assert(length <= sizeof(buffer.bytes) &&
759  "Storing too many bytes in a RegisterValue.");
760  m_type = eTypeBytes;
761  buffer.length = length;
762  memcpy(buffer.bytes, bytes, length);
763  buffer.byte_order = byte_order;
764  } else {
765  m_type = eTypeInvalid;
766  buffer.length = 0;
767  }
768 }
769 
770 bool RegisterValue::operator==(const RegisterValue &rhs) const {
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 eTypeUInt128:
780  case eTypeFloat:
781  case eTypeDouble:
782  case eTypeLongDouble:
783  return m_scalar == rhs.m_scalar;
784  case eTypeBytes:
785  if (buffer.length != rhs.buffer.length)
786  return false;
787  else {
788  uint16_t length = buffer.length;
789  if (length > kMaxRegisterByteSize)
790  length = kMaxRegisterByteSize;
791  return memcmp(buffer.bytes, rhs.buffer.bytes, length) == 0;
792  }
793  break;
794  }
795  }
796  return false;
797 }
798 
799 bool RegisterValue::operator!=(const RegisterValue &rhs) const {
800  return !(*this == rhs);
801 }
802 
803 bool RegisterValue::ClearBit(uint32_t bit) {
804  switch (m_type) {
805  case eTypeInvalid:
806  break;
807 
808  case eTypeUInt8:
809  case eTypeUInt16:
810  case eTypeUInt32:
811  case eTypeUInt64:
812  case eTypeUInt128:
813  if (bit < (GetByteSize() * 8)) {
814  return m_scalar.ClearBit(bit);
815  }
816  break;
817 
818  case eTypeFloat:
819  case eTypeDouble:
820  case eTypeLongDouble:
821  break;
822 
823  case eTypeBytes:
824  if (buffer.byte_order == eByteOrderBig ||
825  buffer.byte_order == eByteOrderLittle) {
826  uint32_t byte_idx;
827  if (buffer.byte_order == eByteOrderBig)
828  byte_idx = buffer.length - (bit / 8) - 1;
829  else
830  byte_idx = bit / 8;
831 
832  const uint32_t byte_bit = bit % 8;
833  if (byte_idx < buffer.length) {
834  buffer.bytes[byte_idx] &= ~(1u << byte_bit);
835  return true;
836  }
837  }
838  break;
839  }
840  return false;
841 }
842 
843 bool RegisterValue::SetBit(uint32_t bit) {
844  switch (m_type) {
845  case eTypeInvalid:
846  break;
847 
848  case eTypeUInt8:
849  case eTypeUInt16:
850  case eTypeUInt32:
851  case eTypeUInt64:
852  case eTypeUInt128:
853  if (bit < (GetByteSize() * 8)) {
854  return m_scalar.SetBit(bit);
855  }
856  break;
857 
858  case eTypeFloat:
859  case eTypeDouble:
860  case eTypeLongDouble:
861  break;
862 
863  case eTypeBytes:
864  if (buffer.byte_order == eByteOrderBig ||
865  buffer.byte_order == eByteOrderLittle) {
866  uint32_t byte_idx;
867  if (buffer.byte_order == eByteOrderBig)
868  byte_idx = buffer.length - (bit / 8) - 1;
869  else
870  byte_idx = bit / 8;
871 
872  const uint32_t byte_bit = bit % 8;
873  if (byte_idx < buffer.length) {
874  buffer.bytes[byte_idx] |= (1u << byte_bit);
875  return true;
876  }
877  }
878  break;
879  }
880  return false;
881 }
lldb-private-types.h
Scalar.h
lldb_private::RegisterValue::Type
Type
Definition: RegisterValue.h:33
lldb_private::RegisterValue
Definition: RegisterValue.h:28
lldb-defines.h
lldb_private::RegisterValue::length
uint16_t length
Definition: RegisterValue.h:266
lldb_private::Scalar
Definition: Scalar.h:34
lldb::eEncodingIEEE754
@ eEncodingIEEE754
float
Definition: lldb-enumerations.h:150
lldb_private::RegisterValue::m_scalar
Scalar m_scalar
Definition: RegisterValue.h:260
SInt64ValueIsValidForByteSize
static bool SInt64ValueIsValidForByteSize(int64_t sval64, size_t total_byte_size)
Definition: RegisterValue.cpp:320
lldb::offset_t
uint64_t offset_t
Definition: lldb-types.h:87
RegisterValue.h
lldb_private::DataExtractor::GetU64
uint64_t GetU64(lldb::offset_t *offset_ptr) const
Extract a uint64_t value from *offset_ptr.
Definition: DataExtractor.cpp:476
UInt64ValueIsValidForByteSize
static bool UInt64ValueIsValidForByteSize(uint64_t uval64, size_t total_byte_size)
Definition: RegisterValue.cpp:306
lldb_private::DataExtractor::SetData
lldb::offset_t SetData(const void *bytes, lldb::offset_t length, lldb::ByteOrder byte_order)
Set data with a buffer that is caller owned.
Definition: DataExtractor.cpp:225
lldb_private::RegisterValue::SetBytes
void SetBytes(const void *bytes, size_t length, lldb::ByteOrder byte_order)
Definition: RegisterValue.cpp:752
lldb_private::Scalar::SetValueFromData
Status SetValueFromData(const DataExtractor &data, lldb::Encoding encoding, size_t byte_size)
Definition: Scalar.cpp:701
lldb_private::RegisterValue::CopyValue
bool CopyValue(const RegisterValue &rhs)
Definition: RegisterValue.cpp:479
lldb::eEncodingInvalid
@ eEncodingInvalid
Definition: lldb-enumerations.h:147
error
static llvm::raw_ostream & error(Stream &strm)
Definition: CommandReturnObject.cpp:17
lldb_private::Status::Success
bool Success() const
Test for success condition.
Definition: Status.cpp:288
lldb::eEncodingSint
@ eEncodingSint
signed integer
Definition: lldb-enumerations.h:149
lldb_private::DataExtractor
Definition: DataExtractor.h:48
lldb_private::DataExtractor::GetMaxU32
uint32_t GetMaxU32(lldb::offset_t *offset_ptr, size_t byte_size) const
Extract an integer of size byte_size from *offset_ptr.
Definition: DataExtractor.cpp:520
lldb_private::RegisterValue::buffer
struct lldb_private::RegisterValue::@42 buffer
StreamString.h
lldb_private::DataExtractor::GetDouble
double GetDouble(lldb::offset_t *offset_ptr) const
Definition: DataExtractor.cpp:628
lldb_private::RegisterValue::GetData
bool GetData(DataExtractor &data) const
Definition: RegisterValue.cpp:34
lldb_private::DataExtractor::GetByteOrder
lldb::ByteOrder GetByteOrder() const
Get the current byte order value.
Definition: DataExtractor.h:594
lldb::eEncodingUint
@ eEncodingUint
unsigned integer
Definition: lldb-enumerations.h:148
bit
#define bit
Definition: EmulateInstructionARM64.cpp:73
lldb::operator==
bool LLDB_API operator==(const SBAddress &lhs, const SBAddress &rhs)
Definition: SBAddress.cpp:63
BITWIDTH_INT128
#define BITWIDTH_INT128
Definition: Scalar.h:28
string
string(SUBSTRING ${p} 10 -1 pStripped) if($
Definition: Plugins/CMakeLists.txt:40
lldb_private::DataExtractor::GetFloat
float GetFloat(lldb::offset_t *offset_ptr) const
Extract a float from *offset_ptr.
Definition: DataExtractor.cpp:624
ParseVectorEncoding
static bool ParseVectorEncoding(const RegisterInfo *reg_info, llvm::StringRef vector_str, const uint32_t byte_size, RegisterValue *reg_value)
Definition: RegisterValue.cpp:268
lldb_private::operator!=
bool operator!=(const Address &lhs, const Address &rhs)
Definition: Address.cpp:1005
NUM_OF_WORDS_INT128
#define NUM_OF_WORDS_INT128
Definition: Scalar.h:27
lldb_private::RegisterValue::byte_order
lldb::ByteOrder byte_order
Definition: RegisterValue.h:267
lldb::eEncodingVector
@ eEncodingVector
vector registers
Definition: lldb-enumerations.h:151
lldb_private::Status
Definition: Status.h:44
uint32_t
lldb_private::DataExtractor::GetMaxU64
uint64_t GetMaxU64(lldb::offset_t *offset_ptr, size_t byte_size) const
Extract an unsigned integer of size byte_size from *offset_ptr.
Definition: DataExtractor.cpp:526
lldb_private::RegisterValue::bytes
uint8_t bytes[kMaxRegisterByteSize]
Definition: RegisterValue.h:264
lldb_private::RegisterValue::m_type
RegisterValue::Type m_type
Definition: RegisterValue.h:259
uint16_t
DataExtractor.h
Status.h
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::DataExtractor::GetLongDouble
long double GetLongDouble(lldb::offset_t *offset_ptr) const
Definition: DataExtractor.cpp:632
lldb::eByteOrderBig
@ eByteOrderBig
Definition: lldb-enumerations.h:140
lldb_private::DataExtractor::CopyByteOrderedData
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...
Definition: DataExtractor.cpp:692
Stream.h
lldb_private::DataExtractor::GetByteSize
uint64_t GetByteSize() const
Get the number of bytes contained in this object.
Definition: DataExtractor.h:270
lldb::eByteOrderLittle
@ eByteOrderLittle
Definition: lldb-enumerations.h:142
lldb
Definition: SBAddress.h:15
lldb::ByteOrder
ByteOrder
Byte ordering definitions.
Definition: lldb-enumerations.h:138