Coverage Report

Created: 2022-01-18 06:27

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Core/Value.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- Value.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/Value.h"
10
11
#include "lldb/Core/Address.h"
12
#include "lldb/Core/Module.h"
13
#include "lldb/Symbol/CompilerType.h"
14
#include "lldb/Symbol/ObjectFile.h"
15
#include "lldb/Symbol/SymbolContext.h"
16
#include "lldb/Symbol/Type.h"
17
#include "lldb/Symbol/Variable.h"
18
#include "lldb/Target/ExecutionContext.h"
19
#include "lldb/Target/Process.h"
20
#include "lldb/Target/SectionLoadList.h"
21
#include "lldb/Target/Target.h"
22
#include "lldb/Utility/ConstString.h"
23
#include "lldb/Utility/DataBufferHeap.h"
24
#include "lldb/Utility/DataExtractor.h"
25
#include "lldb/Utility/Endian.h"
26
#include "lldb/Utility/FileSpec.h"
27
#include "lldb/Utility/State.h"
28
#include "lldb/Utility/Stream.h"
29
#include "lldb/lldb-defines.h"
30
#include "lldb/lldb-forward.h"
31
#include "lldb/lldb-types.h"
32
33
#include <memory>
34
#include <string>
35
36
#include <cinttypes>
37
38
using namespace lldb;
39
using namespace lldb_private;
40
41
298k
Value::Value() : m_value(), m_compiler_type(), m_data_buffer() {}
42
43
Value::Value(const Scalar &scalar)
44
    : m_value(scalar), m_compiler_type(), m_context(nullptr),
45
      m_value_type(ValueType::Scalar), m_context_type(ContextType::Invalid),
46
20.1k
      m_data_buffer() {}
47
48
Value::Value(const void *bytes, int len)
49
    : m_value(), m_compiler_type(), m_context(nullptr),
50
      m_value_type(ValueType::HostAddress), m_context_type(ContextType::Invalid),
51
32
      m_data_buffer() {
52
32
  SetBytes(bytes, len);
53
32
}
54
55
Value::Value(const Value &v)
56
    : m_value(v.m_value), m_compiler_type(v.m_compiler_type),
57
      m_context(v.m_context), m_value_type(v.m_value_type),
58
240k
      m_context_type(v.m_context_type), m_data_buffer() {
59
240k
  const uintptr_t rhs_value =
60
240k
      (uintptr_t)v.m_value.ULongLong(LLDB_INVALID_ADDRESS);
61
240k
  if ((rhs_value != 0) &&
62
240k
      
(rhs_value == (uintptr_t)v.m_data_buffer.GetBytes())240k
) {
63
1.14k
    m_data_buffer.CopyData(v.m_data_buffer.GetBytes(),
64
1.14k
                           v.m_data_buffer.GetByteSize());
65
66
1.14k
    m_value = (uintptr_t)m_data_buffer.GetBytes();
67
1.14k
  }
68
240k
}
69
70
69.8k
Value &Value::operator=(const Value &rhs) {
71
69.8k
  if (this != &rhs) {
72
69.8k
    m_value = rhs.m_value;
73
69.8k
    m_compiler_type = rhs.m_compiler_type;
74
69.8k
    m_context = rhs.m_context;
75
69.8k
    m_value_type = rhs.m_value_type;
76
69.8k
    m_context_type = rhs.m_context_type;
77
69.8k
    const uintptr_t rhs_value =
78
69.8k
        (uintptr_t)rhs.m_value.ULongLong(LLDB_INVALID_ADDRESS);
79
69.8k
    if ((rhs_value != 0) &&
80
69.8k
        
(rhs_value == (uintptr_t)rhs.m_data_buffer.GetBytes())69.8k
) {
81
608
      m_data_buffer.CopyData(rhs.m_data_buffer.GetBytes(),
82
608
                             rhs.m_data_buffer.GetByteSize());
83
84
608
      m_value = (uintptr_t)m_data_buffer.GetBytes();
85
608
    }
86
69.8k
  }
87
69.8k
  return *this;
88
69.8k
}
89
90
84
void Value::SetBytes(const void *bytes, int len) {
91
84
  m_value_type = ValueType::HostAddress;
92
84
  m_data_buffer.CopyData(bytes, len);
93
84
  m_value = (uintptr_t)m_data_buffer.GetBytes();
94
84
}
95
96
0
void Value::AppendBytes(const void *bytes, int len) {
97
0
  m_value_type = ValueType::HostAddress;
98
0
  m_data_buffer.AppendData(bytes, len);
99
0
  m_value = (uintptr_t)m_data_buffer.GetBytes();
100
0
}
101
102
0
void Value::Dump(Stream *strm) {
103
0
  m_value.GetValue(strm, true);
104
0
  strm->Printf(", value_type = %s, context = %p, context_type = %s",
105
0
               Value::GetValueTypeAsCString(m_value_type), m_context,
106
0
               Value::GetContextTypeAsCString(m_context_type));
107
0
}
108
109
324k
Value::ValueType Value::GetValueType() const { return m_value_type; }
110
111
8.27k
AddressType Value::GetValueAddressType() const {
112
8.27k
  switch (m_value_type) {
113
0
  case ValueType::Invalid:
114
0
  case ValueType::Scalar:
115
0
    break;
116
7.66k
  case ValueType::LoadAddress:
117
7.66k
    return eAddressTypeLoad;
118
243
  case ValueType::FileAddress:
119
243
    return eAddressTypeFile;
120
369
  case ValueType::HostAddress:
121
369
    return eAddressTypeHost;
122
8.27k
  }
123
0
  return eAddressTypeInvalid;
124
8.27k
}
125
126
30.1k
RegisterInfo *Value::GetRegisterInfo() const {
127
30.1k
  if (m_context_type == ContextType::RegisterInfo)
128
13.6k
    return static_cast<RegisterInfo *>(m_context);
129
16.5k
  return nullptr;
130
30.1k
}
131
132
0
Type *Value::GetType() {
133
0
  if (m_context_type == ContextType::LLDBType)
134
0
    return static_cast<Type *>(m_context);
135
0
  return nullptr;
136
0
}
137
138
28
size_t Value::AppendDataToHostBuffer(const Value &rhs) {
139
28
  if (this == &rhs)
140
0
    return 0;
141
142
28
  size_t curr_size = m_data_buffer.GetByteSize();
143
28
  Status error;
144
28
  switch (rhs.GetValueType()) {
145
0
  case ValueType::Invalid:
146
0
    return 0;
147
21
  case ValueType::Scalar: {
148
21
    const size_t scalar_size = rhs.m_value.GetByteSize();
149
21
    if (scalar_size > 0) {
150
21
      const size_t new_size = curr_size + scalar_size;
151
21
      if (ResizeData(new_size) == new_size) {
152
21
        rhs.m_value.GetAsMemoryData(m_data_buffer.GetBytes() + curr_size,
153
21
                                    scalar_size, endian::InlHostByteOrder(),
154
21
                                    error);
155
21
        return scalar_size;
156
21
      }
157
21
    }
158
21
  } 
break0
;
159
0
  case ValueType::FileAddress:
160
0
  case ValueType::LoadAddress:
161
7
  case ValueType::HostAddress: {
162
7
    const uint8_t *src = rhs.GetBuffer().GetBytes();
163
7
    const size_t src_len = rhs.GetBuffer().GetByteSize();
164
7
    if (src && src_len > 0) {
165
7
      const size_t new_size = curr_size + src_len;
166
7
      if (ResizeData(new_size) == new_size) {
167
7
        ::memcpy(m_data_buffer.GetBytes() + curr_size, src, src_len);
168
7
        return src_len;
169
7
      }
170
7
    }
171
7
  } 
break0
;
172
28
  }
173
0
  return 0;
174
28
}
175
176
8.80k
size_t Value::ResizeData(size_t len) {
177
8.80k
  m_value_type = ValueType::HostAddress;
178
8.80k
  m_data_buffer.SetByteSize(len);
179
8.80k
  m_value = (uintptr_t)m_data_buffer.GetBytes();
180
8.80k
  return m_data_buffer.GetByteSize();
181
8.80k
}
182
183
0
bool Value::ValueOf(ExecutionContext *exe_ctx) {
184
0
  switch (m_context_type) {
185
0
  case ContextType::Invalid:
186
0
  case ContextType::RegisterInfo: // RegisterInfo *
187
0
  case ContextType::LLDBType:     // Type *
188
0
    break;
189
190
0
  case ContextType::Variable: // Variable *
191
0
    ResolveValue(exe_ctx);
192
0
    return true;
193
0
  }
194
0
  return false;
195
0
}
196
197
161k
uint64_t Value::GetValueByteSize(Status *error_ptr, ExecutionContext *exe_ctx) {
198
161k
  switch (m_context_type) {
199
1.84k
  case ContextType::RegisterInfo: // RegisterInfo *
200
1.84k
    if (GetRegisterInfo()) {
201
1.84k
      if (error_ptr)
202
1.84k
        error_ptr->Clear();
203
1.84k
      return GetRegisterInfo()->byte_size;
204
1.84k
    }
205
0
    break;
206
207
129k
  case ContextType::Invalid:
208
129k
  case ContextType::LLDBType: // Type *
209
159k
  case ContextType::Variable: // Variable *
210
159k
  {
211
159k
    auto *scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : 
nullptr0
;
212
159k
    if (llvm::Optional<uint64_t> size = GetCompilerType().GetByteSize(scope)) {
213
159k
      if (error_ptr)
214
159k
        error_ptr->Clear();
215
159k
      return *size;
216
159k
    }
217
0
    break;
218
159k
  }
219
161k
  }
220
0
  if (error_ptr && error_ptr->Success())
221
0
    error_ptr->SetErrorString("Unable to determine byte size.");
222
0
  return 0;
223
161k
}
224
225
1.40M
const CompilerType &Value::GetCompilerType() {
226
1.40M
  if (!m_compiler_type.IsValid()) {
227
11.1k
    switch (m_context_type) {
228
3.82k
    case ContextType::Invalid:
229
3.82k
      break;
230
231
7.27k
    case ContextType::RegisterInfo:
232
7.27k
      break; // TODO: Eventually convert into a compiler type?
233
234
0
    case ContextType::LLDBType: {
235
0
      Type *lldb_type = GetType();
236
0
      if (lldb_type)
237
0
        m_compiler_type = lldb_type->GetForwardCompilerType();
238
0
    } break;
239
240
52
    case ContextType::Variable: {
241
52
      Variable *variable = GetVariable();
242
52
      if (variable) {
243
52
        Type *variable_type = variable->GetType();
244
52
        if (variable_type)
245
52
          m_compiler_type = variable_type->GetForwardCompilerType();
246
52
      }
247
52
    } break;
248
11.1k
    }
249
11.1k
  }
250
251
1.40M
  return m_compiler_type;
252
1.40M
}
253
254
156k
void Value::SetCompilerType(const CompilerType &compiler_type) {
255
156k
  m_compiler_type = compiler_type;
256
156k
}
257
258
0
lldb::Format Value::GetValueDefaultFormat() {
259
0
  switch (m_context_type) {
260
0
  case ContextType::RegisterInfo:
261
0
    if (GetRegisterInfo())
262
0
      return GetRegisterInfo()->format;
263
0
    break;
264
265
0
  case ContextType::Invalid:
266
0
  case ContextType::LLDBType:
267
0
  case ContextType::Variable: {
268
0
    const CompilerType &ast_type = GetCompilerType();
269
0
    if (ast_type.IsValid())
270
0
      return ast_type.GetFormat();
271
0
  } break;
272
0
  }
273
274
  // Return a good default in case we can't figure anything out
275
0
  return eFormatHex;
276
0
}
277
278
8.75k
bool Value::GetData(DataExtractor &data) {
279
8.75k
  switch (m_value_type) {
280
0
  case ValueType::Invalid:
281
0
    return false;
282
0
  case ValueType::Scalar:
283
0
    if (m_value.GetData(data))
284
0
      return true;
285
0
    break;
286
287
0
  case ValueType::LoadAddress:
288
0
  case ValueType::FileAddress:
289
8.75k
  case ValueType::HostAddress:
290
8.75k
    if (m_data_buffer.GetByteSize()) {
291
8.75k
      data.SetData(m_data_buffer.GetBytes(), m_data_buffer.GetByteSize(),
292
8.75k
                   data.GetByteOrder());
293
8.75k
      return true;
294
8.75k
    }
295
0
    break;
296
8.75k
  }
297
298
0
  return false;
299
8.75k
}
300
301
Status Value::GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data,
302
164k
                             Module *module) {
303
164k
  data.Clear();
304
305
164k
  Status error;
306
164k
  lldb::addr_t address = LLDB_INVALID_ADDRESS;
307
164k
  AddressType address_type = eAddressTypeFile;
308
164k
  Address file_so_addr;
309
164k
  const CompilerType &ast_type = GetCompilerType();
310
164k
  llvm::Optional<uint64_t> type_size = ast_type.GetByteSize(
311
164k
      exe_ctx ? exe_ctx->GetBestExecutionContextScope() : 
nullptr0
);
312
  // Nothing to be done for a zero-sized type.
313
164k
  if (type_size && 
*type_size == 0162k
)
314
24
    return error;
315
316
164k
  switch (m_value_type) {
317
0
  case ValueType::Invalid:
318
0
    error.SetErrorString("invalid value");
319
0
    break;
320
3.00k
  case ValueType::Scalar: {
321
3.00k
    data.SetByteOrder(endian::InlHostByteOrder());
322
3.00k
    if (ast_type.IsValid())
323
3.00k
      data.SetAddressByteSize(ast_type.GetPointerByteSize());
324
0
    else
325
0
      data.SetAddressByteSize(sizeof(void *));
326
327
3.00k
    uint32_t limit_byte_size = UINT32_MAX;
328
329
3.00k
    if (type_size)
330
3.00k
      limit_byte_size = *type_size;
331
332
3.00k
    if (limit_byte_size <= m_value.GetByteSize()) {
333
3.00k
      if (m_value.GetData(data, limit_byte_size))
334
3.00k
        return error; // Success;
335
3.00k
    }
336
337
0
    error.SetErrorString("extracting data from value failed");
338
0
    break;
339
3.00k
  }
340
103k
  case ValueType::LoadAddress:
341
103k
    if (exe_ctx == nullptr) {
342
0
      error.SetErrorString("can't read load address (no execution context)");
343
103k
    } else {
344
103k
      Process *process = exe_ctx->GetProcessPtr();
345
103k
      if (process == nullptr || 
!process->IsAlive()103k
) {
346
3
        Target *target = exe_ctx->GetTargetPtr();
347
3
        if (target) {
348
          // Allow expressions to run and evaluate things when the target has
349
          // memory sections loaded. This allows you to use "target modules
350
          // load" to load your executable and any shared libraries, then
351
          // execute commands where you can look at types in data sections.
352
3
          const SectionLoadList &target_sections = target->GetSectionLoadList();
353
3
          if (!target_sections.IsEmpty()) {
354
0
            address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
355
0
            if (target_sections.ResolveLoadAddress(address, file_so_addr)) {
356
0
              address_type = eAddressTypeLoad;
357
0
              data.SetByteOrder(target->GetArchitecture().GetByteOrder());
358
0
              data.SetAddressByteSize(
359
0
                  target->GetArchitecture().GetAddressByteSize());
360
0
            } else
361
0
              address = LLDB_INVALID_ADDRESS;
362
0
          }
363
3
        } else {
364
0
          error.SetErrorString("can't read load address (invalid process)");
365
0
        }
366
103k
      } else {
367
103k
        address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
368
103k
        address_type = eAddressTypeLoad;
369
103k
        data.SetByteOrder(
370
103k
            process->GetTarget().GetArchitecture().GetByteOrder());
371
103k
        data.SetAddressByteSize(
372
103k
            process->GetTarget().GetArchitecture().GetAddressByteSize());
373
103k
      }
374
103k
    }
375
103k
    break;
376
377
1.05k
  case ValueType::FileAddress:
378
1.05k
    if (exe_ctx == nullptr) {
379
0
      error.SetErrorString("can't read file address (no execution context)");
380
1.05k
    } else if (exe_ctx->GetTargetPtr() == nullptr) {
381
0
      error.SetErrorString("can't read file address (invalid target)");
382
1.05k
    } else {
383
1.05k
      address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
384
1.05k
      if (address == LLDB_INVALID_ADDRESS) {
385
0
        error.SetErrorString("invalid file address");
386
1.05k
      } else {
387
1.05k
        if (module == nullptr) {
388
          // The only thing we can currently lock down to a module so that we
389
          // can resolve a file address, is a variable.
390
12
          Variable *variable = GetVariable();
391
12
          if (variable) {
392
12
            SymbolContext var_sc;
393
12
            variable->CalculateSymbolContext(&var_sc);
394
12
            module = var_sc.module_sp.get();
395
12
          }
396
12
        }
397
398
1.05k
        if (module) {
399
1.05k
          bool resolved = false;
400
1.05k
          ObjectFile *objfile = module->GetObjectFile();
401
1.05k
          if (objfile) {
402
1.05k
            Address so_addr(address, objfile->GetSectionList());
403
1.05k
            addr_t load_address =
404
1.05k
                so_addr.GetLoadAddress(exe_ctx->GetTargetPtr());
405
1.05k
            bool process_launched_and_stopped =
406
1.05k
                exe_ctx->GetProcessPtr()
407
1.05k
                    ? StateIsStoppedState(exe_ctx->GetProcessPtr()->GetState(),
408
45
                                          true /* must_exist */)
409
1.05k
                    : 
false1.00k
;
410
            // Don't use the load address if the process has exited.
411
1.05k
            if (load_address != LLDB_INVALID_ADDRESS &&
412
1.05k
                
process_launched_and_stopped45
) {
413
0
              resolved = true;
414
0
              address = load_address;
415
0
              address_type = eAddressTypeLoad;
416
0
              data.SetByteOrder(
417
0
                  exe_ctx->GetTargetRef().GetArchitecture().GetByteOrder());
418
0
              data.SetAddressByteSize(exe_ctx->GetTargetRef()
419
0
                                          .GetArchitecture()
420
0
                                          .GetAddressByteSize());
421
1.05k
            } else {
422
1.05k
              if (so_addr.IsSectionOffset()) {
423
1.05k
                resolved = true;
424
1.05k
                file_so_addr = so_addr;
425
1.05k
                data.SetByteOrder(objfile->GetByteOrder());
426
1.05k
                data.SetAddressByteSize(objfile->GetAddressByteSize());
427
1.05k
              }
428
1.05k
            }
429
1.05k
          }
430
1.05k
          if (!resolved) {
431
0
            Variable *variable = GetVariable();
432
433
0
            if (module) {
434
0
              if (variable)
435
0
                error.SetErrorStringWithFormat(
436
0
                    "unable to resolve the module for file address 0x%" PRIx64
437
0
                    " for variable '%s' in %s",
438
0
                    address, variable->GetName().AsCString(""),
439
0
                    module->GetFileSpec().GetPath().c_str());
440
0
              else
441
0
                error.SetErrorStringWithFormat(
442
0
                    "unable to resolve the module for file address 0x%" PRIx64
443
0
                    " in %s",
444
0
                    address, module->GetFileSpec().GetPath().c_str());
445
0
            } else {
446
0
              if (variable)
447
0
                error.SetErrorStringWithFormat(
448
0
                    "unable to resolve the module for file address 0x%" PRIx64
449
0
                    " for variable '%s'",
450
0
                    address, variable->GetName().AsCString(""));
451
0
              else
452
0
                error.SetErrorStringWithFormat(
453
0
                    "unable to resolve the module for file address 0x%" PRIx64,
454
0
                    address);
455
0
            }
456
0
          }
457
1.05k
        } else {
458
          // Can't convert a file address to anything valid without more
459
          // context (which Module it came from)
460
0
          error.SetErrorString(
461
0
              "can't read memory from file address without more context");
462
0
        }
463
1.05k
      }
464
1.05k
    }
465
1.05k
    break;
466
467
57.1k
  case ValueType::HostAddress:
468
57.1k
    address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
469
57.1k
    address_type = eAddressTypeHost;
470
57.1k
    if (exe_ctx) {
471
57.1k
      Target *target = exe_ctx->GetTargetPtr();
472
57.1k
      if (target) {
473
57.1k
        data.SetByteOrder(target->GetArchitecture().GetByteOrder());
474
57.1k
        data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
475
57.1k
        break;
476
57.1k
      }
477
57.1k
    }
478
    // fallback to host settings
479
0
    data.SetByteOrder(endian::InlHostByteOrder());
480
0
    data.SetAddressByteSize(sizeof(void *));
481
0
    break;
482
164k
  }
483
484
  // Bail if we encountered any errors
485
161k
  if (error.Fail())
486
0
    return error;
487
488
161k
  if (address == LLDB_INVALID_ADDRESS) {
489
3
    error.SetErrorStringWithFormat("invalid %s address",
490
3
                                   address_type == eAddressTypeHost ? 
"host"0
491
3
                                                                    : "load");
492
3
    return error;
493
3
  }
494
495
  // If we got here, we need to read the value from memory.
496
161k
  size_t byte_size = GetValueByteSize(&error, exe_ctx);
497
498
  // Bail if we encountered any errors getting the byte size.
499
161k
  if (error.Fail())
500
0
    return error;
501
502
  // No memory to read for zero-sized types.
503
161k
  if (byte_size == 0)
504
0
    return error;
505
506
  // Make sure we have enough room within "data", and if we don't make
507
  // something large enough that does
508
161k
  if (!data.ValidOffsetForDataOfSize(0, byte_size)) {
509
161k
    auto data_sp = std::make_shared<DataBufferHeap>(byte_size, '\0');
510
161k
    data.SetData(data_sp);
511
161k
  }
512
513
161k
  uint8_t *dst = const_cast<uint8_t *>(data.PeekData(0, byte_size));
514
161k
  if (dst != nullptr) {
515
161k
    if (address_type == eAddressTypeHost) {
516
      // The address is an address in this process, so just copy it.
517
57.1k
      if (address == 0) {
518
0
        error.SetErrorString("trying to read from host address of 0.");
519
0
        return error;
520
0
      }
521
57.1k
      memcpy(dst, reinterpret_cast<uint8_t *>(address), byte_size);
522
104k
    } else if ((address_type == eAddressTypeLoad) ||
523
104k
               
(address_type == eAddressTypeFile)1.05k
) {
524
104k
      if (file_so_addr.IsValid()) {
525
1.05k
        const bool force_live_memory = true;
526
1.05k
        if (exe_ctx->GetTargetRef().ReadMemory(file_so_addr, dst, byte_size,
527
1.05k
                                               error, force_live_memory) !=
528
1.05k
            byte_size) {
529
0
          error.SetErrorStringWithFormat(
530
0
              "read memory from 0x%" PRIx64 " failed", (uint64_t)address);
531
0
        }
532
103k
      } else {
533
        // The execution context might have a NULL process, but it might have a
534
        // valid process in the exe_ctx->target, so use the
535
        // ExecutionContext::GetProcess accessor to ensure we get the process
536
        // if there is one.
537
103k
        Process *process = exe_ctx->GetProcessPtr();
538
539
103k
        if (process) {
540
103k
          const size_t bytes_read =
541
103k
              process->ReadMemory(address, dst, byte_size, error);
542
103k
          if (bytes_read != byte_size)
543
66
            error.SetErrorStringWithFormat(
544
66
                "read memory from 0x%" PRIx64 " failed (%u of %u bytes read)",
545
66
                (uint64_t)address, (uint32_t)bytes_read, (uint32_t)byte_size);
546
103k
        } else {
547
0
          error.SetErrorStringWithFormat("read memory from 0x%" PRIx64
548
0
                                         " failed (invalid process)",
549
0
                                         (uint64_t)address);
550
0
        }
551
103k
      }
552
104k
    } else {
553
0
      error.SetErrorStringWithFormat("unsupported AddressType value (%i)",
554
0
                                     address_type);
555
0
    }
556
161k
  } else {
557
0
    error.SetErrorString("out of memory");
558
0
  }
559
560
161k
  return error;
561
161k
}
562
563
76.8k
Scalar &Value::ResolveValue(ExecutionContext *exe_ctx) {
564
76.8k
  const CompilerType &compiler_type = GetCompilerType();
565
76.8k
  if (compiler_type.IsValid()) {
566
71.2k
    switch (m_value_type) {
567
0
    case ValueType::Invalid:
568
15.0k
    case ValueType::Scalar: // raw scalar value
569
15.0k
      break;
570
571
12
    case ValueType::FileAddress:
572
33.2k
    case ValueType::LoadAddress: // load address value
573
56.1k
    case ValueType::HostAddress: // host address value (for memory in the process
574
                                // that is using liblldb)
575
56.1k
    {
576
56.1k
      DataExtractor data;
577
56.1k
      lldb::addr_t addr = m_value.ULongLong(LLDB_INVALID_ADDRESS);
578
56.1k
      Status error(GetValueAsData(exe_ctx, data, nullptr));
579
56.1k
      if (error.Success()) {
580
56.1k
        Scalar scalar;
581
56.1k
        if (compiler_type.GetValueAsScalar(
582
56.1k
                data, 0, data.GetByteSize(), scalar,
583
56.1k
                exe_ctx ? exe_ctx->GetBestExecutionContextScope() : 
nullptr0
)) {
584
56.1k
          m_value = scalar;
585
56.1k
          m_value_type = ValueType::Scalar;
586
56.1k
        } else {
587
0
          if ((uintptr_t)addr != (uintptr_t)m_data_buffer.GetBytes()) {
588
0
            m_value.Clear();
589
0
            m_value_type = ValueType::Scalar;
590
0
          }
591
0
        }
592
56.1k
      } else {
593
0
        if ((uintptr_t)addr != (uintptr_t)m_data_buffer.GetBytes()) {
594
0
          m_value.Clear();
595
0
          m_value_type = ValueType::Scalar;
596
0
        }
597
0
      }
598
56.1k
    } break;
599
71.2k
    }
600
71.2k
  }
601
76.8k
  return m_value;
602
76.8k
}
603
604
64
Variable *Value::GetVariable() {
605
64
  if (m_context_type == ContextType::Variable)
606
64
    return static_cast<Variable *>(m_context);
607
0
  return nullptr;
608
64
}
609
610
177
void Value::Clear() {
611
177
  m_value.Clear();
612
177
  m_compiler_type.Clear();
613
177
  m_value_type = ValueType::Scalar;
614
177
  m_context = nullptr;
615
177
  m_context_type = ContextType::Invalid;
616
177
  m_data_buffer.Clear();
617
177
}
618
619
0
const char *Value::GetValueTypeAsCString(ValueType value_type) {
620
0
  switch (value_type) {
621
0
  case ValueType::Invalid:
622
0
    return "invalid";
623
0
  case ValueType::Scalar:
624
0
    return "scalar";
625
0
  case ValueType::FileAddress:
626
0
    return "file address";
627
0
  case ValueType::LoadAddress:
628
0
    return "load address";
629
0
  case ValueType::HostAddress:
630
0
    return "host address";
631
0
  };
632
0
  llvm_unreachable("enum cases exhausted.");
633
0
}
634
635
0
const char *Value::GetContextTypeAsCString(ContextType context_type) {
636
0
  switch (context_type) {
637
0
  case ContextType::Invalid:
638
0
    return "invalid";
639
0
  case ContextType::RegisterInfo:
640
0
    return "RegisterInfo *";
641
0
  case ContextType::LLDBType:
642
0
    return "Type *";
643
0
  case ContextType::Variable:
644
0
    return "Variable *";
645
0
  };
646
0
  llvm_unreachable("enum cases exhausted.");
647
0
}
648
649
892
void Value::ConvertToLoadAddress(Module *module, Target *target) {
650
892
  if (!module || !target || (GetValueType() != ValueType::FileAddress))
651
0
    return;
652
653
892
  lldb::addr_t file_addr = GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
654
892
  if (file_addr == LLDB_INVALID_ADDRESS)
655
0
    return;
656
657
892
  Address so_addr;
658
892
  if (!module->ResolveFileAddress(file_addr, so_addr))
659
0
    return;
660
892
  lldb::addr_t load_addr = so_addr.GetLoadAddress(target);
661
892
  if (load_addr == LLDB_INVALID_ADDRESS)
662
0
    return;
663
664
892
  SetValueType(Value::ValueType::LoadAddress);
665
892
  GetScalar() = load_addr;
666
892
}
667
668
4.98k
ValueList::ValueList(const ValueList &rhs) { m_values = rhs.m_values; }
669
670
11
const ValueList &ValueList::operator=(const ValueList &rhs) {
671
11
  m_values = rhs.m_values;
672
11
  return *this;
673
11
}
674
675
20.4k
void ValueList::PushValue(const Value &value) { m_values.push_back(value); }
676
677
63.5k
size_t ValueList::GetSize() { return m_values.size(); }
678
679
52.8k
Value *ValueList::GetValueAtIndex(size_t idx) {
680
52.8k
  if (idx < GetSize()) {
681
52.8k
    return &(m_values[idx]);
682
52.8k
  } else
683
0
    return nullptr;
684
52.8k
}
685
686
0
void ValueList::Clear() { m_values.clear(); }