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