LLDB  mainline
RegisterValue.cpp
Go to the documentation of this file.
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 
10 
11 #include "lldb/Utility/Args.h"
13 #include "lldb/Utility/Scalar.h"
14 #include "lldb/Utility/Status.h"
15 #include "lldb/Utility/Stream.h"
17 #include "lldb/lldb-defines.h"
19 
20 #include "llvm/ADT/ArrayRef.h"
21 #include "llvm/ADT/StringRef.h"
22 
23 #include <cstdint>
24 #include <string>
25 #include <tuple>
26 #include <vector>
27 
28 #include <assert.h>
29 #include <inttypes.h>
30 #include <stdio.h>
31 
32 using namespace lldb;
33 using namespace lldb_private;
34 
35 bool RegisterValue::GetData(DataExtractor &data) const {
36  return data.SetData(GetBytes(), GetByteSize(), GetByteOrder()) > 0;
37 }
38 
39 uint32_t RegisterValue::GetAsMemoryData(const RegisterInfo *reg_info, void *dst,
40  uint32_t dst_len,
41  lldb::ByteOrder dst_byte_order,
42  Status &error) const {
43  if (reg_info == nullptr) {
44  error.SetErrorString("invalid register info argument.");
45  return 0;
46  }
47 
48  // ReadRegister should have already been called on this object prior to
49  // calling this.
50  if (GetType() == eTypeInvalid) {
51  // No value has been read into this object...
53  "invalid register value type for register %s", reg_info->name);
54  return 0;
55  }
56 
57  if (dst_len > kMaxRegisterByteSize) {
58  error.SetErrorString("destination is too big");
59  return 0;
60  }
61 
62  const uint32_t src_len = reg_info->byte_size;
63 
64  // Extract the register data into a data extractor
65  DataExtractor reg_data;
66  if (!GetData(reg_data)) {
67  error.SetErrorString("invalid register value to copy into");
68  return 0;
69  }
70 
71  // Prepare a memory buffer that contains some or all of the register value
72  const uint32_t bytes_copied =
73  reg_data.CopyByteOrderedData(0, // src offset
74  src_len, // src length
75  dst, // dst buffer
76  dst_len, // dst length
77  dst_byte_order); // dst byte order
78  if (bytes_copied == 0)
80  "failed to copy data for register write of %s", reg_info->name);
81 
82  return bytes_copied;
83 }
84 
85 uint32_t RegisterValue::SetFromMemoryData(const RegisterInfo *reg_info,
86  const void *src, uint32_t src_len,
87  lldb::ByteOrder src_byte_order,
88  Status &error) {
89  if (reg_info == nullptr) {
90  error.SetErrorString("invalid register info argument.");
91  return 0;
92  }
93 
94  // Moving from addr into a register
95  //
96  // Case 1: src_len == dst_len
97  //
98  // |AABBCCDD| Address contents
99  // |AABBCCDD| Register contents
100  //
101  // Case 2: src_len > dst_len
102  //
103  // Status! (The register should always be big enough to hold the data)
104  //
105  // Case 3: src_len < dst_len
106  //
107  // |AABB| Address contents
108  // |AABB0000| Register contents [on little-endian hardware]
109  // |0000AABB| Register contents [on big-endian hardware]
110  if (src_len > kMaxRegisterByteSize) {
112  "register buffer is too small to receive %u bytes of data.", src_len);
113  return 0;
114  }
115 
116  const uint32_t dst_len = reg_info->byte_size;
117 
118  if (src_len > dst_len) {
120  "%u bytes is too big to store in register %s (%u bytes)", src_len,
121  reg_info->name, dst_len);
122  return 0;
123  }
124 
125  // Use a data extractor to correctly copy and pad the bytes read into the
126  // register value
127  DataExtractor src_data(src, src_len, src_byte_order, 4);
128 
129  error = SetValueFromData(reg_info, src_data, 0, true);
130  if (error.Fail())
131  return 0;
132 
133  // If SetValueFromData succeeded, we must have copied all of src_len
134  return src_len;
135 }
136 
137 bool RegisterValue::GetScalarValue(Scalar &scalar) const {
138  switch (m_type) {
139  case eTypeInvalid:
140  break;
141  case eTypeBytes: {
142  switch (buffer.length) {
143  default:
144  break;
145  case 1:
146  scalar = *(const uint8_t *)buffer.bytes;
147  return true;
148  case 2:
149  scalar = *(const uint16_t *)buffer.bytes;
150  return true;
151  case 4:
152  scalar = *(const uint32_t *)buffer.bytes;
153  return true;
154  case 8:
155  scalar = *(const uint64_t *)buffer.bytes;
156  return true;
157  case 16:
158  case 32:
159  case 64:
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 
186 void RegisterValue::Clear() { m_type = eTypeInvalid; }
187 
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 
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  {
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)
289  "invalid register value type for register %s", reg_info->name);
290  return error;
291 }
292 
293 // Helper function for RegisterValue::SetValueFromString()
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 
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)) {
360  "unsupported unsigned integer byte size: %u", byte_size);
361  break;
362  }
363  if (value_str.getAsInteger(0, uval64)) {
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)) {
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)) {
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)) {
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)) {
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 
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 
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 
504 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 
530 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 
560 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 
595 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 
630 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 
649 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 
669 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 
690 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 
709 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 
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 
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 
766 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 
795 bool RegisterValue::operator!=(const RegisterValue &rhs) const {
796  return !(*this == rhs);
797 }
798 
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 
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 }
struct lldb_private::RegisterValue::@41 buffer
An data extractor class.
Definition: DataExtractor.h:47
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
bool LLDB_API operator==(const SBAddress &lhs, const SBAddress &rhs)
Definition: SBAddress.cpp:66
bool CopyValue(const RegisterValue &rhs)
RegisterValue::Type m_type
#define NUM_OF_WORDS_INT128
Definition: Scalar.h:26
float GetFloat(lldb::offset_t *offset_ptr) const
Extract a float from *offset_ptr.
long double GetLongDouble(lldb::offset_t *offset_ptr) const
lldb::offset_t SetData(const void *bytes, lldb::offset_t length, lldb::ByteOrder byte_order)
Set data with a buffer that is caller owned.
#define bit
uint64_t offset_t
Definition: lldb-types.h:87
lldb::ByteOrder GetByteOrder() const
Get the current byte order value.
void SetErrorString(llvm::StringRef err_str)
Set the current error string to err_str.
Definition: Status.cpp:241
double GetDouble(lldb::offset_t *offset_ptr) const
uint8_t bytes[kMaxRegisterByteSize]
bool operator!=(const Address &lhs, const Address &rhs)
Definition: Address.cpp:979
uint64_t GetMaxU64(lldb::offset_t *offset_ptr, size_t byte_size) const
Extract an unsigned integer of size byte_size from *offset_ptr.
uint64_t GetByteSize() const
Get the number of bytes contained in this object.
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...
static bool ParseVectorEncoding(const RegisterInfo *reg_info, llvm::StringRef vector_str, const uint32_t byte_size, RegisterValue *reg_value)
bool GetData(DataExtractor &data) const
bool Fail() const
Test for error condition.
Definition: Status.cpp:181
uint32_t GetMaxU32(lldb::offset_t *offset_ptr, size_t byte_size) const
Extract an integer of size byte_size from *offset_ptr.
Definition: SBAddress.h:15
void SetBytes(const void *bytes, size_t length, lldb::ByteOrder byte_order)
int SetErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Set the current error string to a formatted error string.
Definition: Status.cpp:255
#define BITWIDTH_INT128
Definition: Scalar.h:27
uint64_t GetU64(lldb::offset_t *offset_ptr) const
Extract a uint64_t value from *offset_ptr.
An error handling class.
Definition: Status.h:44