LLDB  mainline
DumpDataExtractor.cpp
Go to the documentation of this file.
1 //===-- DumpDataExtractor.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/lldb-defines.h"
12 #include "lldb/lldb-forward.h"
13 
14 #include "lldb/Core/Address.h"
15 #include "lldb/Core/Disassembler.h"
16 #include "lldb/Core/ModuleList.h"
21 #include "lldb/Target/Target.h"
23 #include "lldb/Utility/Stream.h"
24 
25 #include "clang/AST/ASTContext.h"
26 #include "clang/AST/CanonicalType.h"
27 
28 #include "llvm/ADT/APFloat.h"
29 #include "llvm/ADT/APInt.h"
30 #include "llvm/ADT/ArrayRef.h"
31 #include "llvm/ADT/SmallVector.h"
32 
33 #include <limits>
34 #include <memory>
35 #include <string>
36 
37 #include <assert.h>
38 #include <ctype.h>
39 #include <inttypes.h>
40 #include <math.h>
41 
42 #include <bitset>
43 #include <sstream>
44 
45 using namespace lldb_private;
46 using namespace lldb;
47 
48 #define NON_PRINTABLE_CHAR '.'
49 
50 static float half2float(uint16_t half) {
51  union {
52  float f;
53  uint32_t u;
54  } u;
55  int32_t v = (int16_t)half;
56 
57  if (0 == (v & 0x7c00)) {
58  u.u = v & 0x80007FFFU;
59  return u.f * ldexpf(1, 125);
60  }
61 
62  v <<= 13;
63  u.u = v | 0x70000000U;
64  return u.f * ldexpf(1, -112);
65 }
66 
67 static bool GetAPInt(const DataExtractor &data, lldb::offset_t *offset_ptr,
68  lldb::offset_t byte_size, llvm::APInt &result) {
69  llvm::SmallVector<uint64_t, 2> uint64_array;
70  lldb::offset_t bytes_left = byte_size;
71  uint64_t u64;
72  const lldb::ByteOrder byte_order = data.GetByteOrder();
73  if (byte_order == lldb::eByteOrderLittle) {
74  while (bytes_left > 0) {
75  if (bytes_left >= 8) {
76  u64 = data.GetU64(offset_ptr);
77  bytes_left -= 8;
78  } else {
79  u64 = data.GetMaxU64(offset_ptr, (uint32_t)bytes_left);
80  bytes_left = 0;
81  }
82  uint64_array.push_back(u64);
83  }
84  result = llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array));
85  return true;
86  } else if (byte_order == lldb::eByteOrderBig) {
87  lldb::offset_t be_offset = *offset_ptr + byte_size;
88  lldb::offset_t temp_offset;
89  while (bytes_left > 0) {
90  if (bytes_left >= 8) {
91  be_offset -= 8;
92  temp_offset = be_offset;
93  u64 = data.GetU64(&temp_offset);
94  bytes_left -= 8;
95  } else {
96  be_offset -= bytes_left;
97  temp_offset = be_offset;
98  u64 = data.GetMaxU64(&temp_offset, (uint32_t)bytes_left);
99  bytes_left = 0;
100  }
101  uint64_array.push_back(u64);
102  }
103  *offset_ptr += byte_size;
104  result = llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array));
105  return true;
106  }
107  return false;
108 }
109 
111  lldb::offset_t offset, lldb::offset_t byte_size,
112  bool is_signed, unsigned radix) {
113  llvm::APInt apint;
114  if (GetAPInt(data, &offset, byte_size, apint)) {
115  std::string apint_str(apint.toString(radix, is_signed));
116  switch (radix) {
117  case 2:
118  s->Write("0b", 2);
119  break;
120  case 8:
121  s->Write("0", 1);
122  break;
123  case 10:
124  break;
125  }
126  s->Write(apint_str.c_str(), apint_str.size());
127  }
128  return offset;
129 }
130 
132  const DataExtractor &DE, Stream *s, offset_t start_offset,
133  lldb::Format item_format, size_t item_byte_size, size_t item_count,
134  size_t num_per_line, uint64_t base_addr,
135  uint32_t item_bit_size, // If zero, this is not a bitfield value, if
136  // non-zero, the value is a bitfield
137  uint32_t item_bit_offset, // If "item_bit_size" is non-zero, this is the
138  // shift amount to apply to a bitfield
139  ExecutionContextScope *exe_scope) {
140  if (s == nullptr)
141  return start_offset;
142 
143  if (item_format == eFormatPointer) {
144  if (item_byte_size != 4 && item_byte_size != 8)
145  item_byte_size = s->GetAddressByteSize();
146  }
147 
148  offset_t offset = start_offset;
149 
150  if (item_format == eFormatInstruction) {
151  TargetSP target_sp;
152  if (exe_scope)
153  target_sp = exe_scope->CalculateTarget();
154  if (target_sp) {
155  DisassemblerSP disassembler_sp(Disassembler::FindPlugin(
156  target_sp->GetArchitecture(),
157  target_sp->GetDisassemblyFlavor(), nullptr));
158  if (disassembler_sp) {
159  lldb::addr_t addr = base_addr + start_offset;
160  lldb_private::Address so_addr;
161  bool data_from_file = true;
162  if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr, so_addr)) {
163  data_from_file = false;
164  } else {
165  if (target_sp->GetSectionLoadList().IsEmpty() ||
166  !target_sp->GetImages().ResolveFileAddress(addr, so_addr))
167  so_addr.SetRawAddress(addr);
168  }
169 
170  size_t bytes_consumed = disassembler_sp->DecodeInstructions(
171  so_addr, DE, start_offset, item_count, false, data_from_file);
172 
173  if (bytes_consumed) {
174  offset += bytes_consumed;
175  const bool show_address = base_addr != LLDB_INVALID_ADDRESS;
176  const bool show_bytes = true;
177  ExecutionContext exe_ctx;
178  exe_scope->CalculateExecutionContext(exe_ctx);
179  disassembler_sp->GetInstructionList().Dump(s, show_address,
180  show_bytes, &exe_ctx);
181  }
182  }
183  } else
184  s->Printf("invalid target");
185 
186  return offset;
187  }
188 
189  if ((item_format == eFormatOSType || item_format == eFormatAddressInfo) &&
190  item_byte_size > 8)
191  item_format = eFormatHex;
192 
193  lldb::offset_t line_start_offset = start_offset;
194  for (uint32_t count = 0; DE.ValidOffset(offset) && count < item_count;
195  ++count) {
196  if ((count % num_per_line) == 0) {
197  if (count > 0) {
198  if (item_format == eFormatBytesWithASCII &&
199  offset > line_start_offset) {
200  s->Printf("%*s",
201  static_cast<int>(
202  (num_per_line - (offset - line_start_offset)) * 3 + 2),
203  "");
204  DumpDataExtractor(DE, s, line_start_offset, eFormatCharPrintable, 1,
205  offset - line_start_offset, SIZE_MAX,
206  LLDB_INVALID_ADDRESS, 0, 0);
207  }
208  s->EOL();
209  }
210  if (base_addr != LLDB_INVALID_ADDRESS)
211  s->Printf("0x%8.8" PRIx64 ": ",
212  (uint64_t)(base_addr +
213  (offset - start_offset) / DE.getTargetByteSize()));
214 
215  line_start_offset = offset;
216  } else if (item_format != eFormatChar &&
217  item_format != eFormatCharPrintable &&
218  item_format != eFormatCharArray && count > 0) {
219  s->PutChar(' ');
220  }
221 
222  switch (item_format) {
223  case eFormatBoolean:
224  if (item_byte_size <= 8)
225  s->Printf("%s", DE.GetMaxU64Bitfield(&offset, item_byte_size,
226  item_bit_size, item_bit_offset)
227  ? "true"
228  : "false");
229  else {
230  s->Printf("error: unsupported byte size (%" PRIu64
231  ") for boolean format",
232  (uint64_t)item_byte_size);
233  return offset;
234  }
235  break;
236 
237  case eFormatBinary:
238  if (item_byte_size <= 8) {
239  uint64_t uval64 = DE.GetMaxU64Bitfield(&offset, item_byte_size,
240  item_bit_size, item_bit_offset);
241  // Avoid std::bitset<64>::to_string() since it is missing in earlier
242  // C++ libraries
243  std::string binary_value(64, '0');
244  std::bitset<64> bits(uval64);
245  for (uint32_t i = 0; i < 64; ++i)
246  if (bits[i])
247  binary_value[64 - 1 - i] = '1';
248  if (item_bit_size > 0)
249  s->Printf("0b%s", binary_value.c_str() + 64 - item_bit_size);
250  else if (item_byte_size > 0 && item_byte_size <= 8)
251  s->Printf("0b%s", binary_value.c_str() + 64 - item_byte_size * 8);
252  } else {
253  const bool is_signed = false;
254  const unsigned radix = 2;
255  offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix);
256  }
257  break;
258 
259  case eFormatBytes:
261  for (uint32_t i = 0; i < item_byte_size; ++i) {
262  s->Printf("%2.2x", DE.GetU8(&offset));
263  }
264 
265  // Put an extra space between the groups of bytes if more than one is
266  // being dumped in a group (item_byte_size is more than 1).
267  if (item_byte_size > 1)
268  s->PutChar(' ');
269  break;
270 
271  case eFormatChar:
273  case eFormatCharArray: {
274  // Reject invalid item_byte_size.
275  if (item_byte_size > 8) {
276  s->Printf("error: unsupported byte size (%" PRIu64 ") for char format",
277  (uint64_t)item_byte_size);
278  return offset;
279  }
280 
281  // If we are only printing one character surround it with single quotes
282  if (item_count == 1 && item_format == eFormatChar)
283  s->PutChar('\'');
284 
285  const uint64_t ch = DE.GetMaxU64Bitfield(&offset, item_byte_size,
286  item_bit_size, item_bit_offset);
287  if (isprint(ch))
288  s->Printf("%c", (char)ch);
289  else if (item_format != eFormatCharPrintable) {
290  switch (ch) {
291  case '\033':
292  s->Printf("\\e");
293  break;
294  case '\a':
295  s->Printf("\\a");
296  break;
297  case '\b':
298  s->Printf("\\b");
299  break;
300  case '\f':
301  s->Printf("\\f");
302  break;
303  case '\n':
304  s->Printf("\\n");
305  break;
306  case '\r':
307  s->Printf("\\r");
308  break;
309  case '\t':
310  s->Printf("\\t");
311  break;
312  case '\v':
313  s->Printf("\\v");
314  break;
315  case '\0':
316  s->Printf("\\0");
317  break;
318  default:
319  if (item_byte_size == 1)
320  s->Printf("\\x%2.2x", (uint8_t)ch);
321  else
322  s->Printf("%" PRIu64, ch);
323  break;
324  }
325  } else {
327  }
328 
329  // If we are only printing one character surround it with single quotes
330  if (item_count == 1 && item_format == eFormatChar)
331  s->PutChar('\'');
332  } break;
333 
334  case eFormatEnum: // Print enum value as a signed integer when we don't get
335  // the enum type
336  case eFormatDecimal:
337  if (item_byte_size <= 8)
338  s->Printf("%" PRId64,
339  DE.GetMaxS64Bitfield(&offset, item_byte_size, item_bit_size,
340  item_bit_offset));
341  else {
342  const bool is_signed = true;
343  const unsigned radix = 10;
344  offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix);
345  }
346  break;
347 
348  case eFormatUnsigned:
349  if (item_byte_size <= 8)
350  s->Printf("%" PRIu64,
351  DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size,
352  item_bit_offset));
353  else {
354  const bool is_signed = false;
355  const unsigned radix = 10;
356  offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix);
357  }
358  break;
359 
360  case eFormatOctal:
361  if (item_byte_size <= 8)
362  s->Printf("0%" PRIo64,
363  DE.GetMaxS64Bitfield(&offset, item_byte_size, item_bit_size,
364  item_bit_offset));
365  else {
366  const bool is_signed = false;
367  const unsigned radix = 8;
368  offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix);
369  }
370  break;
371 
372  case eFormatOSType: {
373  uint64_t uval64 = DE.GetMaxU64Bitfield(&offset, item_byte_size,
374  item_bit_size, item_bit_offset);
375  s->PutChar('\'');
376  for (uint32_t i = 0; i < item_byte_size; ++i) {
377  uint8_t ch = (uint8_t)(uval64 >> ((item_byte_size - i - 1) * 8));
378  if (isprint(ch))
379  s->Printf("%c", ch);
380  else {
381  switch (ch) {
382  case '\033':
383  s->Printf("\\e");
384  break;
385  case '\a':
386  s->Printf("\\a");
387  break;
388  case '\b':
389  s->Printf("\\b");
390  break;
391  case '\f':
392  s->Printf("\\f");
393  break;
394  case '\n':
395  s->Printf("\\n");
396  break;
397  case '\r':
398  s->Printf("\\r");
399  break;
400  case '\t':
401  s->Printf("\\t");
402  break;
403  case '\v':
404  s->Printf("\\v");
405  break;
406  case '\0':
407  s->Printf("\\0");
408  break;
409  default:
410  s->Printf("\\x%2.2x", ch);
411  break;
412  }
413  }
414  }
415  s->PutChar('\'');
416  } break;
417 
418  case eFormatCString: {
419  const char *cstr = DE.GetCStr(&offset);
420 
421  if (!cstr) {
422  s->Printf("NULL");
423  offset = LLDB_INVALID_OFFSET;
424  } else {
425  s->PutChar('\"');
426 
427  while (const char c = *cstr) {
428  if (isprint(c)) {
429  s->PutChar(c);
430  } else {
431  switch (c) {
432  case '\033':
433  s->Printf("\\e");
434  break;
435  case '\a':
436  s->Printf("\\a");
437  break;
438  case '\b':
439  s->Printf("\\b");
440  break;
441  case '\f':
442  s->Printf("\\f");
443  break;
444  case '\n':
445  s->Printf("\\n");
446  break;
447  case '\r':
448  s->Printf("\\r");
449  break;
450  case '\t':
451  s->Printf("\\t");
452  break;
453  case '\v':
454  s->Printf("\\v");
455  break;
456  default:
457  s->Printf("\\x%2.2x", c);
458  break;
459  }
460  }
461 
462  ++cstr;
463  }
464 
465  s->PutChar('\"');
466  }
467  } break;
468 
469  case eFormatPointer:
470  s->Address(DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size,
471  item_bit_offset),
472  sizeof(addr_t));
473  break;
474 
475  case eFormatComplexInteger: {
476  size_t complex_int_byte_size = item_byte_size / 2;
477 
478  if (complex_int_byte_size > 0 && complex_int_byte_size <= 8) {
479  s->Printf("%" PRIu64,
480  DE.GetMaxU64Bitfield(&offset, complex_int_byte_size, 0, 0));
481  s->Printf(" + %" PRIu64 "i",
482  DE.GetMaxU64Bitfield(&offset, complex_int_byte_size, 0, 0));
483  } else {
484  s->Printf("error: unsupported byte size (%" PRIu64
485  ") for complex integer format",
486  (uint64_t)item_byte_size);
487  return offset;
488  }
489  } break;
490 
491  case eFormatComplex:
492  if (sizeof(float) * 2 == item_byte_size) {
493  float f32_1 = DE.GetFloat(&offset);
494  float f32_2 = DE.GetFloat(&offset);
495 
496  s->Printf("%g + %gi", f32_1, f32_2);
497  break;
498  } else if (sizeof(double) * 2 == item_byte_size) {
499  double d64_1 = DE.GetDouble(&offset);
500  double d64_2 = DE.GetDouble(&offset);
501 
502  s->Printf("%lg + %lgi", d64_1, d64_2);
503  break;
504  } else if (sizeof(long double) * 2 == item_byte_size) {
505  long double ld64_1 = DE.GetLongDouble(&offset);
506  long double ld64_2 = DE.GetLongDouble(&offset);
507  s->Printf("%Lg + %Lgi", ld64_1, ld64_2);
508  break;
509  } else {
510  s->Printf("error: unsupported byte size (%" PRIu64
511  ") for complex float format",
512  (uint64_t)item_byte_size);
513  return offset;
514  }
515  break;
516 
517  default:
518  case eFormatDefault:
519  case eFormatHex:
520  case eFormatHexUppercase: {
521  bool wantsuppercase = (item_format == eFormatHexUppercase);
522  switch (item_byte_size) {
523  case 1:
524  case 2:
525  case 4:
526  case 8:
527  s->Printf(wantsuppercase ? "0x%*.*" PRIX64 : "0x%*.*" PRIx64,
528  (int)(2 * item_byte_size), (int)(2 * item_byte_size),
529  DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size,
530  item_bit_offset));
531  break;
532  default: {
533  assert(item_bit_size == 0 && item_bit_offset == 0);
534  const uint8_t *bytes =
535  (const uint8_t *)DE.GetData(&offset, item_byte_size);
536  if (bytes) {
537  s->PutCString("0x");
538  uint32_t idx;
539  if (DE.GetByteOrder() == eByteOrderBig) {
540  for (idx = 0; idx < item_byte_size; ++idx)
541  s->Printf(wantsuppercase ? "%2.2X" : "%2.2x", bytes[idx]);
542  } else {
543  for (idx = 0; idx < item_byte_size; ++idx)
544  s->Printf(wantsuppercase ? "%2.2X" : "%2.2x",
545  bytes[item_byte_size - 1 - idx]);
546  }
547  }
548  } break;
549  }
550  } break;
551 
552  case eFormatFloat: {
553  TargetSP target_sp;
554  bool used_upfloat = false;
555  if (exe_scope)
556  target_sp = exe_scope->CalculateTarget();
557  if (target_sp) {
558  ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext();
559  if (clang_ast) {
560  clang::ASTContext *ast = clang_ast->getASTContext();
561  if (ast) {
562  llvm::SmallVector<char, 256> sv;
563  // Show full precision when printing float values
564  const unsigned format_precision = 0;
565  const unsigned format_max_padding = 100;
566  size_t item_bit_size = item_byte_size * 8;
567 
568  if (item_bit_size == ast->getTypeSize(ast->FloatTy)) {
569  llvm::APInt apint(item_bit_size,
570  DE.GetMaxU64(&offset, item_byte_size));
571  llvm::APFloat apfloat(ast->getFloatTypeSemantics(ast->FloatTy),
572  apint);
573  apfloat.toString(sv, format_precision, format_max_padding);
574  } else if (item_bit_size == ast->getTypeSize(ast->DoubleTy)) {
575  llvm::APInt apint;
576  if (GetAPInt(DE, &offset, item_byte_size, apint)) {
577  llvm::APFloat apfloat(ast->getFloatTypeSemantics(ast->DoubleTy),
578  apint);
579  apfloat.toString(sv, format_precision, format_max_padding);
580  }
581  } else if (item_bit_size == ast->getTypeSize(ast->LongDoubleTy)) {
582  const auto &semantics =
583  ast->getFloatTypeSemantics(ast->LongDoubleTy);
584 
585  offset_t byte_size = item_byte_size;
586  if (&semantics == &llvm::APFloatBase::x87DoubleExtended())
587  byte_size = (llvm::APFloat::getSizeInBits(semantics) + 7) / 8;
588 
589  llvm::APInt apint;
590  if (GetAPInt(DE, &offset, byte_size, apint)) {
591  llvm::APFloat apfloat(semantics, apint);
592  apfloat.toString(sv, format_precision, format_max_padding);
593  }
594  } else if (item_bit_size == ast->getTypeSize(ast->HalfTy)) {
595  llvm::APInt apint(item_bit_size, DE.GetU16(&offset));
596  llvm::APFloat apfloat(ast->getFloatTypeSemantics(ast->HalfTy),
597  apint);
598  apfloat.toString(sv, format_precision, format_max_padding);
599  }
600 
601  if (!sv.empty()) {
602  s->Printf("%*.*s", (int)sv.size(), (int)sv.size(), sv.data());
603  used_upfloat = true;
604  }
605  }
606  }
607  }
608 
609  if (!used_upfloat) {
610  std::ostringstream ss;
611  if (item_byte_size == sizeof(float) || item_byte_size == 2) {
612  float f;
613  if (item_byte_size == 2) {
614  uint16_t half = DE.GetU16(&offset);
615  f = half2float(half);
616  } else {
617  f = DE.GetFloat(&offset);
618  }
619  ss.precision(std::numeric_limits<float>::digits10);
620  ss << f;
621  } else if (item_byte_size == sizeof(double)) {
622  ss.precision(std::numeric_limits<double>::digits10);
623  ss << DE.GetDouble(&offset);
624  } else if (item_byte_size == sizeof(long double) ||
625  item_byte_size == 10) {
626  ss.precision(std::numeric_limits<long double>::digits10);
627  ss << DE.GetLongDouble(&offset);
628  } else {
629  s->Printf("error: unsupported byte size (%" PRIu64
630  ") for float format",
631  (uint64_t)item_byte_size);
632  return offset;
633  }
634  ss.flush();
635  s->Printf("%s", ss.str().c_str());
636  }
637  } break;
638 
639  case eFormatUnicode16:
640  s->Printf("U+%4.4x", DE.GetU16(&offset));
641  break;
642 
643  case eFormatUnicode32:
644  s->Printf("U+0x%8.8x", DE.GetU32(&offset));
645  break;
646 
647  case eFormatAddressInfo: {
648  addr_t addr = DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size,
649  item_bit_offset);
650  s->Printf("0x%*.*" PRIx64, (int)(2 * item_byte_size),
651  (int)(2 * item_byte_size), addr);
652  if (exe_scope) {
653  TargetSP target_sp(exe_scope->CalculateTarget());
654  lldb_private::Address so_addr;
655  if (target_sp) {
656  if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr,
657  so_addr)) {
658  s->PutChar(' ');
659  so_addr.Dump(s, exe_scope, Address::DumpStyleResolvedDescription,
661  } else {
662  so_addr.SetOffset(addr);
663  so_addr.Dump(s, exe_scope,
665  }
666  }
667  }
668  } break;
669 
670  case eFormatHexFloat:
671  if (sizeof(float) == item_byte_size) {
672  char float_cstr[256];
673  llvm::APFloat ap_float(DE.GetFloat(&offset));
674  ap_float.convertToHexString(float_cstr, 0, false,
675  llvm::APFloat::rmNearestTiesToEven);
676  s->Printf("%s", float_cstr);
677  break;
678  } else if (sizeof(double) == item_byte_size) {
679  char float_cstr[256];
680  llvm::APFloat ap_float(DE.GetDouble(&offset));
681  ap_float.convertToHexString(float_cstr, 0, false,
682  llvm::APFloat::rmNearestTiesToEven);
683  s->Printf("%s", float_cstr);
684  break;
685  } else {
686  s->Printf("error: unsupported byte size (%" PRIu64
687  ") for hex float format",
688  (uint64_t)item_byte_size);
689  return offset;
690  }
691  break;
692 
693  // please keep the single-item formats below in sync with
694  // FormatManager::GetSingleItemFormat if you fail to do so, users will
695  // start getting different outputs depending on internal implementation
696  // details they should not care about ||
697  case eFormatVectorOfChar: // ||
698  s->PutChar('{'); // \/
699  offset =
700  DumpDataExtractor(DE, s, offset, eFormatCharArray, 1, item_byte_size,
701  item_byte_size, LLDB_INVALID_ADDRESS, 0, 0);
702  s->PutChar('}');
703  break;
704 
706  s->PutChar('{');
707  offset =
708  DumpDataExtractor(DE, s, offset, eFormatDecimal, 1, item_byte_size,
709  item_byte_size, LLDB_INVALID_ADDRESS, 0, 0);
710  s->PutChar('}');
711  break;
712 
714  s->PutChar('{');
715  offset = DumpDataExtractor(DE, s, offset, eFormatHex, 1, item_byte_size,
716  item_byte_size, LLDB_INVALID_ADDRESS, 0, 0);
717  s->PutChar('}');
718  break;
719 
721  s->PutChar('{');
722  offset = DumpDataExtractor(
723  DE, s, offset, eFormatDecimal, sizeof(uint16_t),
724  item_byte_size / sizeof(uint16_t), item_byte_size / sizeof(uint16_t),
725  LLDB_INVALID_ADDRESS, 0, 0);
726  s->PutChar('}');
727  break;
728 
730  s->PutChar('{');
731  offset = DumpDataExtractor(DE, s, offset, eFormatHex, sizeof(uint16_t),
732  item_byte_size / sizeof(uint16_t),
733  item_byte_size / sizeof(uint16_t),
734  LLDB_INVALID_ADDRESS, 0, 0);
735  s->PutChar('}');
736  break;
737 
739  s->PutChar('{');
740  offset = DumpDataExtractor(
741  DE, s, offset, eFormatDecimal, sizeof(uint32_t),
742  item_byte_size / sizeof(uint32_t), item_byte_size / sizeof(uint32_t),
743  LLDB_INVALID_ADDRESS, 0, 0);
744  s->PutChar('}');
745  break;
746 
748  s->PutChar('{');
749  offset = DumpDataExtractor(DE, s, offset, eFormatHex, sizeof(uint32_t),
750  item_byte_size / sizeof(uint32_t),
751  item_byte_size / sizeof(uint32_t),
752  LLDB_INVALID_ADDRESS, 0, 0);
753  s->PutChar('}');
754  break;
755 
757  s->PutChar('{');
758  offset = DumpDataExtractor(
759  DE, s, offset, eFormatDecimal, sizeof(uint64_t),
760  item_byte_size / sizeof(uint64_t), item_byte_size / sizeof(uint64_t),
761  LLDB_INVALID_ADDRESS, 0, 0);
762  s->PutChar('}');
763  break;
764 
766  s->PutChar('{');
767  offset = DumpDataExtractor(DE, s, offset, eFormatHex, sizeof(uint64_t),
768  item_byte_size / sizeof(uint64_t),
769  item_byte_size / sizeof(uint64_t),
770  LLDB_INVALID_ADDRESS, 0, 0);
771  s->PutChar('}');
772  break;
773 
775  s->PutChar('{');
776  offset =
777  DumpDataExtractor(DE, s, offset, eFormatFloat, 2, item_byte_size / 2,
778  item_byte_size / 2, LLDB_INVALID_ADDRESS, 0, 0);
779  s->PutChar('}');
780  break;
781 
783  s->PutChar('{');
784  offset =
785  DumpDataExtractor(DE, s, offset, eFormatFloat, 4, item_byte_size / 4,
786  item_byte_size / 4, LLDB_INVALID_ADDRESS, 0, 0);
787  s->PutChar('}');
788  break;
789 
791  s->PutChar('{');
792  offset =
793  DumpDataExtractor(DE, s, offset, eFormatFloat, 8, item_byte_size / 8,
794  item_byte_size / 8, LLDB_INVALID_ADDRESS, 0, 0);
795  s->PutChar('}');
796  break;
797 
799  s->PutChar('{');
800  offset =
801  DumpDataExtractor(DE, s, offset, eFormatHex, 16, item_byte_size / 16,
802  item_byte_size / 16, LLDB_INVALID_ADDRESS, 0, 0);
803  s->PutChar('}');
804  break;
805  }
806  }
807 
808  if (item_format == eFormatBytesWithASCII && offset > line_start_offset) {
809  s->Printf("%*s", static_cast<int>(
810  (num_per_line - (offset - line_start_offset)) * 3 + 2),
811  "");
812  DumpDataExtractor(DE, s, line_start_offset, eFormatCharPrintable, 1,
813  offset - line_start_offset, SIZE_MAX,
814  LLDB_INVALID_ADDRESS, 0, 0);
815  }
816  return offset; // Return the offset at which we ended up
817 }
818 
819 void lldb_private::DumpHexBytes(Stream *s, const void *src, size_t src_len,
820  uint32_t bytes_per_line,
821  lldb::addr_t base_addr) {
822  DataExtractor data(src, src_len, lldb::eByteOrderLittle, 4);
823  DumpDataExtractor(data, s,
824  0, // Offset into "src"
825  lldb::eFormatBytes, // Dump as hex bytes
826  1, // Size of each item is 1 for single bytes
827  src_len, // Number of bytes
828  bytes_per_line, // Num bytes per line
829  base_addr, // Base address
830  0, 0); // Bitfield info
831 }
void Address(uint64_t addr, uint32_t addr_size, const char *prefix=nullptr, const char *suffix=nullptr)
Output an address value to this stream.
Definition: Stream.cpp:79
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition: Stream.cpp:61
An data extractor class.
Definition: DataExtractor.h:47
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
static bool isprint(char32_t codepoint)
const void * GetData(lldb::offset_t *offset_ptr, lldb::offset_t length) const
Extract length bytes from *offset_ptr.
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
virtual void CalculateExecutionContext(ExecutionContext &exe_ctx)=0
Reconstruct the object&#39;s execution context into sc.
const char * GetCStr(lldb::offset_t *offset_ptr) const
Extract a C string from *offset_ptr.
uint32_t GetU32(lldb::offset_t *offset_ptr) const
Extract a uint32_t value from *offset_ptr.
int64_t GetMaxS64Bitfield(lldb::offset_t *offset_ptr, size_t size, uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset) const
Extract an signed integer of size byte_size from *offset_ptr, then extract and signe extend the bitfi...
clang::ASTContext * getASTContext()
void DumpHexBytes(Stream *s, const void *src, size_t src_len, uint32_t bytes_per_line, lldb::addr_t base_addr)
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
static bool GetAPInt(const DataExtractor &data, lldb::offset_t *offset_ptr, lldb::offset_t byte_size, llvm::APInt &result)
uint64_t GetMaxU64Bitfield(lldb::offset_t *offset_ptr, size_t size, uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset) const
Extract an unsigned integer of size byte_size from *offset_ptr, then extract the bitfield from this v...
size_t Write(const void *src, size_t src_len)
Output character bytes to the stream.
Definition: Stream.h:100
float GetFloat(lldb::offset_t *offset_ptr) const
Extract a float from *offset_ptr.
virtual lldb::TargetSP CalculateTarget()=0
static lldb::DisassemblerSP FindPlugin(const ArchSpec &arch, const char *flavor, const char *plugin_name)
#define LLDB_INVALID_OFFSET
Definition: lldb-defines.h:96
long double GetLongDouble(lldb::offset_t *offset_ptr) const
#define LLDB_INVALID_ADDRESS
Invalid value definitions.
Definition: lldb-defines.h:85
uint64_t offset_t
Definition: lldb-types.h:87
size_t EOL()
Output and End of Line character to the stream.
Definition: Stream.cpp:127
lldb::ByteOrder GetByteOrder() const
Get the current byte order value.
#define NON_PRINTABLE_CHAR
"lldb/Target/ExecutionContextScope.h" Inherit from this if your object can reconstruct its execution ...
double GetDouble(lldb::offset_t *offset_ptr) const
static float half2float(uint16_t half)
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:106
uint32_t getTargetByteSize() const
void SetRawAddress(lldb::addr_t addr)
Definition: Address.h:425
A section + offset based address class.
Definition: Address.h:80
lldb::offset_t DumpDataExtractor(const DataExtractor &DE, Stream *s, lldb::offset_t offset, lldb::Format item_format, size_t item_byte_size, size_t item_count, size_t num_per_line, uint64_t base_addr, uint32_t item_bit_size, uint32_t item_bit_offset, ExecutionContextScope *exe_scope=nullptr)
Dumps item_count objects into the stream s.
bool ValidOffset(lldb::offset_t offset) const
Test the validity of offset.
uint64_t GetMaxU64(lldb::offset_t *offset_ptr, size_t byte_size) const
Extract an unsigned integer of size byte_size from *offset_ptr.
Dereference a pointer at the current address and then lookup the.
Definition: Address.h:121
size_t PutChar(char ch)
Definition: Stream.cpp:103
Display the details about what an address resolves to.
Definition: Address.h:108
uint64_t addr_t
Definition: lldb-types.h:83
static uint32_t bits(const uint32_t val, const uint32_t msbit, const uint32_t lsbit)
Definition: ARMUtils.h:264
Definition: SBAddress.h:15
static lldb::offset_t DumpAPInt(Stream *s, const DataExtractor &data, lldb::offset_t offset, lldb::offset_t byte_size, bool is_signed, unsigned radix)
uint32_t GetAddressByteSize() const
Get the address size in bytes.
Definition: Stream.cpp:229
Display as the file address with the module name prepended (if any).
Definition: Address.h:99
uint8_t GetU8(lldb::offset_t *offset_ptr) const
Extract a uint8_t value from *offset_ptr.
uint16_t GetU16(lldb::offset_t *offset_ptr) const
Extract a uint16_t value from *offset_ptr.
uint64_t GetU64(lldb::offset_t *offset_ptr) const
Extract a uint64_t value from *offset_ptr.