Coverage Report

Created: 2022-01-18 06:27

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Core/DumpDataExtractor.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- DumpDataExtractor.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
9
#include "lldb/Core/DumpDataExtractor.h"
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"
17
#include "lldb/Target/ABI.h"
18
#include "lldb/Target/ExecutionContext.h"
19
#include "lldb/Target/ExecutionContextScope.h"
20
#include "lldb/Target/Process.h"
21
#include "lldb/Target/SectionLoadList.h"
22
#include "lldb/Target/Target.h"
23
#include "lldb/Utility/DataExtractor.h"
24
#include "lldb/Utility/Log.h"
25
#include "lldb/Utility/Stream.h"
26
27
#include "llvm/ADT/APFloat.h"
28
#include "llvm/ADT/APInt.h"
29
#include "llvm/ADT/ArrayRef.h"
30
#include "llvm/ADT/Optional.h"
31
#include "llvm/ADT/SmallVector.h"
32
33
#include <limits>
34
#include <memory>
35
#include <string>
36
37
#include <cassert>
38
#include <cctype>
39
#include <cinttypes>
40
#include <cmath>
41
42
#include <bitset>
43
#include <sstream>
44
45
using namespace lldb_private;
46
using namespace lldb;
47
48
368
#define NON_PRINTABLE_CHAR '.'
49
50
19
static float half2float(uint16_t half) {
51
19
  union {
52
19
    float f;
53
19
    uint32_t u;
54
19
  } u;
55
  // Sign extend to 4 byte.
56
19
  int32_t sign_extended = static_cast<int16_t>(half);
57
19
  uint32_t v = static_cast<uint32_t>(sign_extended);
58
59
19
  if (0 == (v & 0x7c00)) {
60
6
    u.u = v & 0x80007FFFU;
61
6
    return u.f * ldexpf(1, 125);
62
6
  }
63
64
13
  v <<= 13;
65
13
  u.u = v | 0x70000000U;
66
13
  return u.f * ldexpf(1, -112);
67
19
}
68
69
static llvm::Optional<llvm::APInt> GetAPInt(const DataExtractor &data,
70
                                            lldb::offset_t *offset_ptr,
71
1.98k
                                            lldb::offset_t byte_size) {
72
1.98k
  if (byte_size == 0)
73
2
    return llvm::None;
74
75
1.98k
  llvm::SmallVector<uint64_t, 2> uint64_array;
76
1.98k
  lldb::offset_t bytes_left = byte_size;
77
1.98k
  uint64_t u64;
78
1.98k
  const lldb::ByteOrder byte_order = data.GetByteOrder();
79
1.98k
  if (byte_order == lldb::eByteOrderLittle) {
80
3.98k
    while (bytes_left > 0) {
81
2.00k
      if (bytes_left >= 8) {
82
963
        u64 = data.GetU64(offset_ptr);
83
963
        bytes_left -= 8;
84
1.04k
      } else {
85
1.04k
        u64 = data.GetMaxU64(offset_ptr, (uint32_t)bytes_left);
86
1.04k
        bytes_left = 0;
87
1.04k
      }
88
2.00k
      uint64_array.push_back(u64);
89
2.00k
    }
90
1.98k
    return llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array));
91
1.98k
  } else 
if (0
byte_order == lldb::eByteOrderBig0
) {
92
0
    lldb::offset_t be_offset = *offset_ptr + byte_size;
93
0
    lldb::offset_t temp_offset;
94
0
    while (bytes_left > 0) {
95
0
      if (bytes_left >= 8) {
96
0
        be_offset -= 8;
97
0
        temp_offset = be_offset;
98
0
        u64 = data.GetU64(&temp_offset);
99
0
        bytes_left -= 8;
100
0
      } else {
101
0
        be_offset -= bytes_left;
102
0
        temp_offset = be_offset;
103
0
        u64 = data.GetMaxU64(&temp_offset, (uint32_t)bytes_left);
104
0
        bytes_left = 0;
105
0
      }
106
0
      uint64_array.push_back(u64);
107
0
    }
108
0
    *offset_ptr += byte_size;
109
0
    return llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array));
110
0
  }
111
0
  return llvm::None;
112
1.98k
}
113
114
static lldb::offset_t DumpAPInt(Stream *s, const DataExtractor &data,
115
                                lldb::offset_t offset, lldb::offset_t byte_size,
116
16
                                bool is_signed, unsigned radix) {
117
16
  llvm::Optional<llvm::APInt> apint = GetAPInt(data, &offset, byte_size);
118
16
  if (apint.hasValue()) {
119
16
    std::string apint_str = toString(apint.getValue(), radix, is_signed);
120
16
    switch (radix) {
121
1
    case 2:
122
1
      s->Write("0b", 2);
123
1
      break;
124
1
    case 8:
125
1
      s->Write("0", 1);
126
1
      break;
127
14
    case 10:
128
14
      break;
129
16
    }
130
16
    s->Write(apint_str.c_str(), apint_str.size());
131
16
  }
132
16
  return offset;
133
16
}
134
135
/// Dumps decoded instructions to a stream.
136
static lldb::offset_t DumpInstructions(const DataExtractor &DE, Stream *s,
137
                                       ExecutionContextScope *exe_scope,
138
                                       offset_t start_offset,
139
                                       uint64_t base_addr,
140
2
                                       size_t number_of_instructions) {
141
2
  offset_t offset = start_offset;
142
143
2
  TargetSP target_sp;
144
2
  if (exe_scope)
145
1
    target_sp = exe_scope->CalculateTarget();
146
2
  if (target_sp) {
147
1
    DisassemblerSP disassembler_sp(
148
1
        Disassembler::FindPlugin(target_sp->GetArchitecture(),
149
1
                                 target_sp->GetDisassemblyFlavor(), nullptr));
150
1
    if (disassembler_sp) {
151
1
      lldb::addr_t addr = base_addr + start_offset;
152
1
      lldb_private::Address so_addr;
153
1
      bool data_from_file = true;
154
1
      if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr, so_addr)) {
155
0
        data_from_file = false;
156
1
      } else {
157
1
        if (target_sp->GetSectionLoadList().IsEmpty() ||
158
1
            
!target_sp->GetImages().ResolveFileAddress(addr, so_addr)0
)
159
1
          so_addr.SetRawAddress(addr);
160
1
      }
161
162
1
      size_t bytes_consumed = disassembler_sp->DecodeInstructions(
163
1
          so_addr, DE, start_offset, number_of_instructions, false,
164
1
          data_from_file);
165
166
1
      if (bytes_consumed) {
167
1
        offset += bytes_consumed;
168
1
        const bool show_address = base_addr != LLDB_INVALID_ADDRESS;
169
1
        const bool show_bytes = true;
170
1
        ExecutionContext exe_ctx;
171
1
        exe_scope->CalculateExecutionContext(exe_ctx);
172
1
        disassembler_sp->GetInstructionList().Dump(s, show_address, show_bytes,
173
1
                                                   &exe_ctx);
174
1
      }
175
1
    }
176
1
  } else
177
1
    s->Printf("invalid target");
178
179
2
  return offset;
180
2
}
181
182
/// Prints the specific escape sequence of the given character to the stream.
183
/// If the character doesn't have a known specific escape sequence (e.g., '\a',
184
/// '\n' but not generic escape sequences such as'\x12'), this function will
185
/// not modify the stream and return false.
186
963
static bool TryDumpSpecialEscapedChar(Stream &s, const char c) {
187
963
  switch (c) {
188
4
  case '\033':
189
    // Common non-standard escape code for 'escape'.
190
4
    s.Printf("\\e");
191
4
    return true;
192
20
  case '\a':
193
20
    s.Printf("\\a");
194
20
    return true;
195
7
  case '\b':
196
7
    s.Printf("\\b");
197
7
    return true;
198
10
  case '\f':
199
10
    s.Printf("\\f");
200
10
    return true;
201
474
  case '\n':
202
474
    s.Printf("\\n");
203
474
    return true;
204
8
  case '\r':
205
8
    s.Printf("\\r");
206
8
    return true;
207
46
  case '\t':
208
46
    s.Printf("\\t");
209
46
    return true;
210
11
  case '\v':
211
11
    s.Printf("\\v");
212
11
    return true;
213
200
  case '\0':
214
200
    s.Printf("\\0");
215
200
    return true;
216
183
  default:
217
183
    return false;
218
963
  }
219
963
}
220
221
/// Dump the character to a stream. A character that is not printable will be
222
/// represented by its escape sequence.
223
105
static void DumpCharacter(Stream &s, const char c) {
224
105
  if (TryDumpSpecialEscapedChar(s, c))
225
17
    return;
226
88
  if (llvm::isPrint(c)) {
227
88
    s.PutChar(c);
228
88
    return;
229
88
  }
230
0
  s.Printf("\\x%2.2x", c);
231
0
}
232
233
/// Dump a floating point type.
234
template <typename FloatT>
235
583
void DumpFloatingPoint(std::ostringstream &ss, FloatT f) {
236
583
  static_assert(std::is_floating_point<FloatT>::value,
237
583
                "Only floating point types can be dumped.");
238
  // NaN and Inf are potentially implementation defined and on Darwin it
239
  // seems NaNs are printed without their sign. Manually implement dumping them
240
  // here to avoid having to deal with platform differences.
241
583
  if (std::isnan(f)) {
242
12
    if (std::signbit(f))
243
6
      ss << '-';
244
12
    ss << "nan";
245
12
    return;
246
12
  }
247
571
  if (std::isinf(f)) {
248
2
    if (std::signbit(f))
249
1
      ss << '-';
250
2
    ss << "inf";
251
2
    return;
252
2
  }
253
569
  ss << f;
254
569
}
void DumpFloatingPoint<float>(std::__1::basic_ostringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, float)
Line
Count
Source
235
322
void DumpFloatingPoint(std::ostringstream &ss, FloatT f) {
236
322
  static_assert(std::is_floating_point<FloatT>::value,
237
322
                "Only floating point types can be dumped.");
238
  // NaN and Inf are potentially implementation defined and on Darwin it
239
  // seems NaNs are printed without their sign. Manually implement dumping them
240
  // here to avoid having to deal with platform differences.
241
322
  if (std::isnan(f)) {
242
8
    if (std::signbit(f))
243
4
      ss << '-';
244
8
    ss << "nan";
245
8
    return;
246
8
  }
247
314
  if (std::isinf(f)) {
248
2
    if (std::signbit(f))
249
1
      ss << '-';
250
2
    ss << "inf";
251
2
    return;
252
2
  }
253
312
  ss << f;
254
312
}
void DumpFloatingPoint<double>(std::__1::basic_ostringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, double)
Line
Count
Source
235
260
void DumpFloatingPoint(std::ostringstream &ss, FloatT f) {
236
260
  static_assert(std::is_floating_point<FloatT>::value,
237
260
                "Only floating point types can be dumped.");
238
  // NaN and Inf are potentially implementation defined and on Darwin it
239
  // seems NaNs are printed without their sign. Manually implement dumping them
240
  // here to avoid having to deal with platform differences.
241
260
  if (std::isnan(f)) {
242
4
    if (std::signbit(f))
243
2
      ss << '-';
244
4
    ss << "nan";
245
4
    return;
246
4
  }
247
256
  if (std::isinf(f)) {
248
0
    if (std::signbit(f))
249
0
      ss << '-';
250
0
    ss << "inf";
251
0
    return;
252
0
  }
253
256
  ss << f;
254
256
}
void DumpFloatingPoint<long double>(std::__1::basic_ostringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, long double)
Line
Count
Source
235
1
void DumpFloatingPoint(std::ostringstream &ss, FloatT f) {
236
1
  static_assert(std::is_floating_point<FloatT>::value,
237
1
                "Only floating point types can be dumped.");
238
  // NaN and Inf are potentially implementation defined and on Darwin it
239
  // seems NaNs are printed without their sign. Manually implement dumping them
240
  // here to avoid having to deal with platform differences.
241
1
  if (std::isnan(f)) {
242
0
    if (std::signbit(f))
243
0
      ss << '-';
244
0
    ss << "nan";
245
0
    return;
246
0
  }
247
1
  if (std::isinf(f)) {
248
0
    if (std::signbit(f))
249
0
      ss << '-';
250
0
    ss << "inf";
251
0
    return;
252
0
  }
253
1
  ss << f;
254
1
}
255
256
lldb::offset_t lldb_private::DumpDataExtractor(
257
    const DataExtractor &DE, Stream *s, offset_t start_offset,
258
    lldb::Format item_format, size_t item_byte_size, size_t item_count,
259
    size_t num_per_line, uint64_t base_addr,
260
    uint32_t item_bit_size,   // If zero, this is not a bitfield value, if
261
                              // non-zero, the value is a bitfield
262
    uint32_t item_bit_offset, // If "item_bit_size" is non-zero, this is the
263
                              // shift amount to apply to a bitfield
264
115k
    ExecutionContextScope *exe_scope) {
265
115k
  if (s == nullptr)
266
1
    return start_offset;
267
268
115k
  if (item_format == eFormatPointer) {
269
16
    if (item_byte_size != 4 && 
item_byte_size != 814
)
270
1
      item_byte_size = s->GetAddressByteSize();
271
16
  }
272
273
115k
  offset_t offset = start_offset;
274
275
115k
  if (item_format == eFormatInstruction)
276
2
    return DumpInstructions(DE, s, exe_scope, start_offset, base_addr,
277
2
                            item_count);
278
279
115k
  if ((item_format == eFormatOSType || 
item_format == eFormatAddressInfo115k
) &&
280
115k
      
item_byte_size > 836
)
281
1
    item_format = eFormatHex;
282
283
115k
  lldb::offset_t line_start_offset = start_offset;
284
1.60M
  for (uint32_t count = 0; DE.ValidOffset(offset) && 
count < item_count1.55M
;
285
1.48M
       
++count1.48M
) {
286
1.48M
    if ((count % num_per_line) == 0) {
287
116k
      if (count > 0) {
288
1.23k
        if (item_format == eFormatBytesWithASCII &&
289
1.23k
            
offset > line_start_offset12
) {
290
12
          s->Printf("%*s",
291
12
                    static_cast<int>(
292
12
                        (num_per_line - (offset - line_start_offset)) * 3 + 2),
293
12
                    "");
294
12
          DumpDataExtractor(DE, s, line_start_offset, eFormatCharPrintable, 1,
295
12
                            offset - line_start_offset, SIZE_MAX,
296
12
                            LLDB_INVALID_ADDRESS, 0, 0);
297
12
        }
298
1.23k
        s->EOL();
299
1.23k
      }
300
116k
      if (base_addr != LLDB_INVALID_ADDRESS)
301
1.37k
        s->Printf("0x%8.8" PRIx64 ": ",
302
1.37k
                  (uint64_t)(base_addr +
303
1.37k
                             (offset - start_offset) / DE.getTargetByteSize()));
304
305
116k
      line_start_offset = offset;
306
1.37M
    } else if (item_format != eFormatChar &&
307
1.37M
               
item_format != eFormatCharPrintable30.2k
&&
308
1.37M
               
item_format != eFormatCharArray29.7k
&&
count > 029.6k
) {
309
29.6k
      s->PutChar(' ');
310
29.6k
    }
311
312
1.48M
    switch (item_format) {
313
10.3k
    case eFormatBoolean:
314
10.3k
      if (item_byte_size <= 8)
315
10.3k
        s->Printf("%s", DE.GetMaxU64Bitfield(&offset, item_byte_size,
316
10.3k
                                             item_bit_size, item_bit_offset)
317
10.3k
                            ? 
"true"2.10k
318
10.3k
                            : 
"false"8.25k
);
319
2
      else {
320
2
        s->Printf("error: unsupported byte size (%" PRIu64
321
2
                  ") for boolean format",
322
2
                  (uint64_t)item_byte_size);
323
2
        return offset;
324
2
      }
325
10.3k
      break;
326
327
10.3k
    case eFormatBinary:
328
13
      if (item_byte_size <= 8) {
329
12
        uint64_t uval64 = DE.GetMaxU64Bitfield(&offset, item_byte_size,
330
12
                                               item_bit_size, item_bit_offset);
331
        // Avoid std::bitset<64>::to_string() since it is missing in earlier
332
        // C++ libraries
333
12
        std::string binary_value(64, '0');
334
12
        std::bitset<64> bits(uval64);
335
780
        for (uint32_t i = 0; i < 64; 
++i768
)
336
768
          if (bits[i])
337
33
            binary_value[64 - 1 - i] = '1';
338
12
        if (item_bit_size > 0)
339
0
          s->Printf("0b%s", binary_value.c_str() + 64 - item_bit_size);
340
12
        else if (item_byte_size > 0 && item_byte_size <= 8)
341
12
          s->Printf("0b%s", binary_value.c_str() + 64 - item_byte_size * 8);
342
12
      } else {
343
1
        const bool is_signed = false;
344
1
        const unsigned radix = 2;
345
1
        offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix);
346
1
      }
347
13
      break;
348
349
921
    case eFormatBytes:
350
1.54k
    case eFormatBytesWithASCII:
351
3.09k
      for (uint32_t i = 0; i < item_byte_size; 
++i1.54k
) {
352
1.54k
        s->Printf("%2.2x", DE.GetU8(&offset));
353
1.54k
      }
354
355
      // Put an extra space between the groups of bytes if more than one is
356
      // being dumped in a group (item_byte_size is more than 1).
357
1.54k
      if (item_byte_size > 1)
358
0
        s->PutChar(' ');
359
1.54k
      break;
360
361
1.40M
    case eFormatChar:
362
1.40M
    case eFormatCharPrintable:
363
1.40M
    case eFormatCharArray: {
364
      // Reject invalid item_byte_size.
365
1.40M
      if (item_byte_size > 8) {
366
1
        s->Printf("error: unsupported byte size (%" PRIu64 ") for char format",
367
1
                  (uint64_t)item_byte_size);
368
1
        return offset;
369
1
      }
370
371
      // If we are only printing one character surround it with single quotes
372
1.40M
      if (item_count == 1 && 
item_format == eFormatChar2.26k
)
373
2.23k
        s->PutChar('\'');
374
375
1.40M
      const uint64_t ch = DE.GetMaxU64Bitfield(&offset, item_byte_size,
376
1.40M
                                               item_bit_size, item_bit_offset);
377
1.40M
      if (llvm::isPrint(ch))
378
1.40M
        s->Printf("%c", (char)ch);
379
1.22k
      else if (item_format != eFormatCharPrintable) {
380
858
        if (!TryDumpSpecialEscapedChar(*s, ch)) {
381
95
          if (item_byte_size == 1)
382
95
            s->Printf("\\x%2.2x", (uint8_t)ch);
383
0
          else
384
0
            s->Printf("%" PRIu64, ch);
385
95
        }
386
858
      } else {
387
368
        s->PutChar(NON_PRINTABLE_CHAR);
388
368
      }
389
390
      // If we are only printing one character surround it with single quotes
391
1.40M
      if (item_count == 1 && 
item_format == eFormatChar2.26k
)
392
2.23k
        s->PutChar('\'');
393
1.40M
    } break;
394
395
4
    case eFormatEnum: // Print enum value as a signed integer when we don't get
396
                      // the enum type
397
16.8k
    case eFormatDecimal:
398
16.8k
      if (item_byte_size <= 8)
399
16.8k
        s->Printf("%" PRId64,
400
16.8k
                  DE.GetMaxS64Bitfield(&offset, item_byte_size, item_bit_size,
401
16.8k
                                       item_bit_offset));
402
10
      else {
403
10
        const bool is_signed = true;
404
10
        const unsigned radix = 10;
405
10
        offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix);
406
10
      }
407
16.8k
      break;
408
409
3.29k
    case eFormatUnsigned:
410
3.29k
      if (item_byte_size <= 8)
411
3.29k
        s->Printf("%" PRIu64,
412
3.29k
                  DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size,
413
3.29k
                                       item_bit_offset));
414
4
      else {
415
4
        const bool is_signed = false;
416
4
        const unsigned radix = 10;
417
4
        offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix);
418
4
      }
419
3.29k
      break;
420
421
4
    case eFormatOctal:
422
4
      if (item_byte_size <= 8)
423
3
        s->Printf("0%" PRIo64,
424
3
                  DE.GetMaxS64Bitfield(&offset, item_byte_size, item_bit_size,
425
3
                                       item_bit_offset));
426
1
      else {
427
1
        const bool is_signed = false;
428
1
        const unsigned radix = 8;
429
1
        offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix);
430
1
      }
431
4
      break;
432
433
15
    case eFormatOSType: {
434
15
      uint64_t uval64 = DE.GetMaxU64Bitfield(&offset, item_byte_size,
435
15
                                             item_bit_size, item_bit_offset);
436
15
      s->PutChar('\'');
437
83
      for (uint32_t i = 0; i < item_byte_size; 
++i68
) {
438
68
        uint8_t ch = (uint8_t)(uval64 >> ((item_byte_size - i - 1) * 8));
439
68
        DumpCharacter(*s, ch);
440
68
      }
441
15
      s->PutChar('\'');
442
15
    } break;
443
444
5
    case eFormatCString: {
445
5
      const char *cstr = DE.GetCStr(&offset);
446
447
5
      if (!cstr) {
448
0
        s->Printf("NULL");
449
0
        offset = LLDB_INVALID_OFFSET;
450
5
      } else {
451
5
        s->PutChar('\"');
452
453
42
        while (const char c = *cstr) {
454
37
          DumpCharacter(*s, c);
455
37
          ++cstr;
456
37
        }
457
458
5
        s->PutChar('\"');
459
5
      }
460
5
    } break;
461
462
16
    case eFormatPointer:
463
16
      DumpAddress(s->AsRawOstream(),
464
16
                  DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size,
465
16
                                       item_bit_offset),
466
16
                  sizeof(addr_t));
467
16
      break;
468
469
9
    case eFormatComplexInteger: {
470
9
      size_t complex_int_byte_size = item_byte_size / 2;
471
472
9
      if (complex_int_byte_size > 0 && 
complex_int_byte_size <= 88
) {
473
7
        s->Printf("%" PRIu64,
474
7
                  DE.GetMaxU64Bitfield(&offset, complex_int_byte_size, 0, 0));
475
7
        s->Printf(" + %" PRIu64 "i",
476
7
                  DE.GetMaxU64Bitfield(&offset, complex_int_byte_size, 0, 0));
477
7
      } else {
478
2
        s->Printf("error: unsupported byte size (%" PRIu64
479
2
                  ") for complex integer format",
480
2
                  (uint64_t)item_byte_size);
481
2
        return offset;
482
2
      }
483
9
    } 
break7
;
484
485
10
    case eFormatComplex:
486
10
      if (sizeof(float) * 2 == item_byte_size) {
487
3
        float f32_1 = DE.GetFloat(&offset);
488
3
        float f32_2 = DE.GetFloat(&offset);
489
490
3
        s->Printf("%g + %gi", f32_1, f32_2);
491
3
        break;
492
7
      } else if (sizeof(double) * 2 == item_byte_size) {
493
3
        double d64_1 = DE.GetDouble(&offset);
494
3
        double d64_2 = DE.GetDouble(&offset);
495
496
3
        s->Printf("%lg + %lgi", d64_1, d64_2);
497
3
        break;
498
4
      } else if (sizeof(long double) * 2 == item_byte_size) {
499
1
        long double ld64_1 = DE.GetLongDouble(&offset);
500
1
        long double ld64_2 = DE.GetLongDouble(&offset);
501
1
        s->Printf("%Lg + %Lgi", ld64_1, ld64_2);
502
1
        break;
503
3
      } else {
504
3
        s->Printf("error: unsupported byte size (%" PRIu64
505
3
                  ") for complex float format",
506
3
                  (uint64_t)item_byte_size);
507
3
        return offset;
508
3
      }
509
0
      break;
510
511
106
    default:
512
167
    case eFormatDefault:
513
43.5k
    case eFormatHex:
514
43.5k
    case eFormatHexUppercase: {
515
43.5k
      bool wantsuppercase = (item_format == eFormatHexUppercase);
516
43.5k
      switch (item_byte_size) {
517
31.0k
      case 1:
518
32.1k
      case 2:
519
34.2k
      case 4:
520
43.4k
      case 8:
521
43.4k
        s->Printf(wantsuppercase ? 
"0x%*.*" PRIX6426
:
"0x%*.*" PRIx6443.4k
,
522
43.4k
                  (int)(2 * item_byte_size), (int)(2 * item_byte_size),
523
43.4k
                  DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size,
524
43.4k
                                       item_bit_offset));
525
43.4k
        break;
526
67
      default: {
527
67
        assert(item_bit_size == 0 && item_bit_offset == 0);
528
0
        const uint8_t *bytes =
529
67
            (const uint8_t *)DE.GetData(&offset, item_byte_size);
530
67
        if (bytes) {
531
67
          s->PutCString("0x");
532
67
          uint32_t idx;
533
67
          if (DE.GetByteOrder() == eByteOrderBig) {
534
0
            for (idx = 0; idx < item_byte_size; ++idx)
535
0
              s->Printf(wantsuppercase ? "%2.2X" : "%2.2x", bytes[idx]);
536
67
          } else {
537
1.13k
            for (idx = 0; idx < item_byte_size; 
++idx1.07k
)
538
1.07k
              s->Printf(wantsuppercase ? 
"%2.2X"0
: "%2.2x",
539
1.07k
                        bytes[item_byte_size - 1 - idx]);
540
67
          }
541
67
        }
542
67
      } break;
543
43.5k
      }
544
43.5k
    } break;
545
546
43.5k
    case eFormatFloat: {
547
2.55k
      TargetSP target_sp;
548
2.55k
      bool used_upfloat = false;
549
2.55k
      if (exe_scope)
550
1.96k
        target_sp = exe_scope->CalculateTarget();
551
2.55k
      if (target_sp) {
552
1.96k
        auto type_system_or_err =
553
1.96k
            target_sp->GetScratchTypeSystemForLanguage(eLanguageTypeC);
554
1.96k
        if (!type_system_or_err) {
555
0
          llvm::consumeError(type_system_or_err.takeError());
556
1.96k
        } else {
557
1.96k
          auto &type_system = *type_system_or_err;
558
1.96k
          llvm::SmallVector<char, 256> sv;
559
          // Show full precision when printing float values
560
1.96k
          const unsigned format_precision = 0;
561
1.96k
          const unsigned format_max_padding =
562
1.96k
              target_sp->GetMaxZeroPaddingInFloatFormat();
563
564
1.96k
          const auto &semantics =
565
1.96k
              type_system.GetFloatTypeSemantics(item_byte_size);
566
567
          // Recalculate the byte size in case of a difference. This is possible
568
          // when item_byte_size is 16 (128-bit), because you could get back the
569
          // x87DoubleExtended semantics which has a byte size of 10 (80-bit).
570
1.96k
          const size_t semantics_byte_size =
571
1.96k
              (llvm::APFloat::getSizeInBits(semantics) + 7) / 8;
572
1.96k
          llvm::Optional<llvm::APInt> apint =
573
1.96k
              GetAPInt(DE, &offset, semantics_byte_size);
574
1.96k
          if (apint.hasValue()) {
575
1.96k
            llvm::APFloat apfloat(semantics, apint.getValue());
576
1.96k
            apfloat.toString(sv, format_precision, format_max_padding);
577
1.96k
            if (!sv.empty()) {
578
1.96k
              s->Printf("%*.*s", (int)sv.size(), (int)sv.size(), sv.data());
579
1.96k
              used_upfloat = true;
580
1.96k
            }
581
1.96k
          }
582
1.96k
        }
583
1.96k
      }
584
585
2.55k
      if (!used_upfloat) {
586
587
        std::ostringstream ss;
587
587
        if (item_byte_size == sizeof(float) || 
item_byte_size == 2284
) {
588
322
          float f;
589
322
          if (item_byte_size == 2) {
590
19
            uint16_t half = DE.GetU16(&offset);
591
19
            f = half2float(half);
592
303
          } else {
593
303
            f = DE.GetFloat(&offset);
594
303
          }
595
322
          ss.precision(std::numeric_limits<float>::digits10);
596
322
          DumpFloatingPoint(ss, f);
597
322
        } else 
if (265
item_byte_size == sizeof(double)265
) {
598
260
          ss.precision(std::numeric_limits<double>::digits10);
599
260
          DumpFloatingPoint(ss, DE.GetDouble(&offset));
600
260
        } else 
if (5
item_byte_size == sizeof(long double)5
||
601
5
                   item_byte_size == 10) {
602
1
          ss.precision(std::numeric_limits<long double>::digits10);
603
1
          DumpFloatingPoint(ss, DE.GetLongDouble(&offset));
604
4
        } else {
605
4
          s->Printf("error: unsupported byte size (%" PRIu64
606
4
                    ") for float format",
607
4
                    (uint64_t)item_byte_size);
608
4
          return offset;
609
4
        }
610
583
        ss.flush();
611
583
        s->Printf("%s", ss.str().c_str());
612
583
      }
613
2.55k
    } 
break2.54k
;
614
615
2.54k
    case eFormatUnicode16:
616
387
      s->Printf("U+%4.4x", DE.GetU16(&offset));
617
387
      break;
618
619
33
    case eFormatUnicode32:
620
33
      s->Printf("U+0x%8.8x", DE.GetU32(&offset));
621
33
      break;
622
623
28
    case eFormatAddressInfo: {
624
28
      addr_t addr = DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size,
625
28
                                         item_bit_offset);
626
28
      s->Printf("0x%*.*" PRIx64, (int)(2 * item_byte_size),
627
28
                (int)(2 * item_byte_size), addr);
628
28
      if (exe_scope) {
629
14
        TargetSP target_sp(exe_scope->CalculateTarget());
630
14
        lldb_private::Address so_addr;
631
14
        if (target_sp) {
632
14
          if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr,
633
14
                                                                 so_addr)) {
634
4
            s->PutChar(' ');
635
4
            so_addr.Dump(s, exe_scope, Address::DumpStyleResolvedDescription,
636
4
                         Address::DumpStyleModuleWithFileAddress);
637
10
          } else {
638
10
            so_addr.SetOffset(addr);
639
10
            so_addr.Dump(s, exe_scope,
640
10
                         Address::DumpStyleResolvedPointerDescription);
641
10
            if (ProcessSP process_sp = exe_scope->CalculateProcess()) {
642
10
              if (ABISP abi_sp = process_sp->GetABI()) {
643
10
                addr_t addr_fixed = abi_sp->FixCodeAddress(addr);
644
10
                if (target_sp->GetSectionLoadList().ResolveLoadAddress(
645
10
                        addr_fixed, so_addr)) {
646
0
                  s->PutChar(' ');
647
0
                  s->Printf("(0x%*.*" PRIx64 ")", (int)(2 * item_byte_size),
648
0
                            (int)(2 * item_byte_size), addr_fixed);
649
0
                  s->PutChar(' ');
650
0
                  so_addr.Dump(s, exe_scope,
651
0
                               Address::DumpStyleResolvedDescription,
652
0
                               Address::DumpStyleModuleWithFileAddress);
653
0
                }
654
10
              }
655
10
            }
656
10
          }
657
14
        }
658
14
      }
659
28
    } break;
660
661
8
    case eFormatHexFloat:
662
8
      if (sizeof(float) == item_byte_size) {
663
2
        char float_cstr[256];
664
2
        llvm::APFloat ap_float(DE.GetFloat(&offset));
665
2
        ap_float.convertToHexString(float_cstr, 0, false,
666
2
                                    llvm::APFloat::rmNearestTiesToEven);
667
2
        s->Printf("%s", float_cstr);
668
2
        break;
669
6
      } else if (sizeof(double) == item_byte_size) {
670
2
        char float_cstr[256];
671
2
        llvm::APFloat ap_float(DE.GetDouble(&offset));
672
2
        ap_float.convertToHexString(float_cstr, 0, false,
673
2
                                    llvm::APFloat::rmNearestTiesToEven);
674
2
        s->Printf("%s", float_cstr);
675
2
        break;
676
4
      } else {
677
4
        s->Printf("error: unsupported byte size (%" PRIu64
678
4
                  ") for hex float format",
679
4
                  (uint64_t)item_byte_size);
680
4
        return offset;
681
4
      }
682
0
      break;
683
684
    // please keep the single-item formats below in sync with
685
    // FormatManager::GetSingleItemFormat if you fail to do so, users will
686
    // start getting different outputs depending on internal implementation
687
    // details they should not care about ||
688
26
    case eFormatVectorOfChar: //   ||
689
26
      s->PutChar('{');        //   \/
690
26
      offset =
691
26
          DumpDataExtractor(DE, s, offset, eFormatCharArray, 1, item_byte_size,
692
26
                            item_byte_size, LLDB_INVALID_ADDRESS, 0, 0);
693
26
      s->PutChar('}');
694
26
      break;
695
696
2
    case eFormatVectorOfSInt8:
697
2
      s->PutChar('{');
698
2
      offset =
699
2
          DumpDataExtractor(DE, s, offset, eFormatDecimal, 1, item_byte_size,
700
2
                            item_byte_size, LLDB_INVALID_ADDRESS, 0, 0);
701
2
      s->PutChar('}');
702
2
      break;
703
704
1.62k
    case eFormatVectorOfUInt8:
705
1.62k
      s->PutChar('{');
706
1.62k
      offset = DumpDataExtractor(DE, s, offset, eFormatHex, 1, item_byte_size,
707
1.62k
                                 item_byte_size, LLDB_INVALID_ADDRESS, 0, 0);
708
1.62k
      s->PutChar('}');
709
1.62k
      break;
710
711
2
    case eFormatVectorOfSInt16:
712
2
      s->PutChar('{');
713
2
      offset = DumpDataExtractor(
714
2
          DE, s, offset, eFormatDecimal, sizeof(uint16_t),
715
2
          item_byte_size / sizeof(uint16_t), item_byte_size / sizeof(uint16_t),
716
2
          LLDB_INVALID_ADDRESS, 0, 0);
717
2
      s->PutChar('}');
718
2
      break;
719
720
2
    case eFormatVectorOfUInt16:
721
2
      s->PutChar('{');
722
2
      offset = DumpDataExtractor(DE, s, offset, eFormatHex, sizeof(uint16_t),
723
2
                                 item_byte_size / sizeof(uint16_t),
724
2
                                 item_byte_size / sizeof(uint16_t),
725
2
                                 LLDB_INVALID_ADDRESS, 0, 0);
726
2
      s->PutChar('}');
727
2
      break;
728
729
6
    case eFormatVectorOfSInt32:
730
6
      s->PutChar('{');
731
6
      offset = DumpDataExtractor(
732
6
          DE, s, offset, eFormatDecimal, sizeof(uint32_t),
733
6
          item_byte_size / sizeof(uint32_t), item_byte_size / sizeof(uint32_t),
734
6
          LLDB_INVALID_ADDRESS, 0, 0);
735
6
      s->PutChar('}');
736
6
      break;
737
738
37
    case eFormatVectorOfUInt32:
739
37
      s->PutChar('{');
740
37
      offset = DumpDataExtractor(DE, s, offset, eFormatHex, sizeof(uint32_t),
741
37
                                 item_byte_size / sizeof(uint32_t),
742
37
                                 item_byte_size / sizeof(uint32_t),
743
37
                                 LLDB_INVALID_ADDRESS, 0, 0);
744
37
      s->PutChar('}');
745
37
      break;
746
747
2
    case eFormatVectorOfSInt64:
748
2
      s->PutChar('{');
749
2
      offset = DumpDataExtractor(
750
2
          DE, s, offset, eFormatDecimal, sizeof(uint64_t),
751
2
          item_byte_size / sizeof(uint64_t), item_byte_size / sizeof(uint64_t),
752
2
          LLDB_INVALID_ADDRESS, 0, 0);
753
2
      s->PutChar('}');
754
2
      break;
755
756
2
    case eFormatVectorOfUInt64:
757
2
      s->PutChar('{');
758
2
      offset = DumpDataExtractor(DE, s, offset, eFormatHex, sizeof(uint64_t),
759
2
                                 item_byte_size / sizeof(uint64_t),
760
2
                                 item_byte_size / sizeof(uint64_t),
761
2
                                 LLDB_INVALID_ADDRESS, 0, 0);
762
2
      s->PutChar('}');
763
2
      break;
764
765
9
    case eFormatVectorOfFloat16:
766
9
      s->PutChar('{');
767
9
      offset =
768
9
          DumpDataExtractor(DE, s, offset, eFormatFloat, 2, item_byte_size / 2,
769
9
                            item_byte_size / 2, LLDB_INVALID_ADDRESS, 0, 0);
770
9
      s->PutChar('}');
771
9
      break;
772
773
48
    case eFormatVectorOfFloat32:
774
48
      s->PutChar('{');
775
48
      offset =
776
48
          DumpDataExtractor(DE, s, offset, eFormatFloat, 4, item_byte_size / 4,
777
48
                            item_byte_size / 4, LLDB_INVALID_ADDRESS, 0, 0);
778
48
      s->PutChar('}');
779
48
      break;
780
781
3
    case eFormatVectorOfFloat64:
782
3
      s->PutChar('{');
783
3
      offset =
784
3
          DumpDataExtractor(DE, s, offset, eFormatFloat, 8, item_byte_size / 8,
785
3
                            item_byte_size / 8, LLDB_INVALID_ADDRESS, 0, 0);
786
3
      s->PutChar('}');
787
3
      break;
788
789
2
    case eFormatVectorOfUInt128:
790
2
      s->PutChar('{');
791
2
      offset =
792
2
          DumpDataExtractor(DE, s, offset, eFormatHex, 16, item_byte_size / 16,
793
2
                            item_byte_size / 16, LLDB_INVALID_ADDRESS, 0, 0);
794
2
      s->PutChar('}');
795
2
      break;
796
1.48M
    }
797
1.48M
  }
798
799
115k
  if (item_format == eFormatBytesWithASCII && 
offset > line_start_offset89
) {
800
89
    s->Printf("%*s", static_cast<int>(
801
89
                         (num_per_line - (offset - line_start_offset)) * 3 + 2),
802
89
              "");
803
89
    DumpDataExtractor(DE, s, line_start_offset, eFormatCharPrintable, 1,
804
89
                      offset - line_start_offset, SIZE_MAX,
805
89
                      LLDB_INVALID_ADDRESS, 0, 0);
806
89
  }
807
115k
  return offset; // Return the offset at which we ended up
808
115k
}
809
810
void lldb_private::DumpHexBytes(Stream *s, const void *src, size_t src_len,
811
                                uint32_t bytes_per_line,
812
144
                                lldb::addr_t base_addr) {
813
144
  DataExtractor data(src, src_len, lldb::eByteOrderLittle, 4);
814
144
  DumpDataExtractor(data, s,
815
144
                    0,                  // Offset into "src"
816
144
                    lldb::eFormatBytes, // Dump as hex bytes
817
144
                    1,              // Size of each item is 1 for single bytes
818
144
                    src_len,        // Number of bytes
819
144
                    bytes_per_line, // Num bytes per line
820
144
                    base_addr,      // Base address
821
144
                    0, 0);          // Bitfield info
822
144
}