Coverage Report

Created: 2023-09-12 09:32

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Core/ValueObjectVariable.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- ValueObjectVariable.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/ValueObjectVariable.h"
10
11
#include "lldb/Core/Address.h"
12
#include "lldb/Core/AddressRange.h"
13
#include "lldb/Core/Declaration.h"
14
#include "lldb/Core/Module.h"
15
#include "lldb/Core/Value.h"
16
#include "lldb/Expression/DWARFExpressionList.h"
17
#include "lldb/Symbol/Function.h"
18
#include "lldb/Symbol/ObjectFile.h"
19
#include "lldb/Symbol/SymbolContext.h"
20
#include "lldb/Symbol/SymbolContextScope.h"
21
#include "lldb/Symbol/Type.h"
22
#include "lldb/Symbol/Variable.h"
23
#include "lldb/Target/ExecutionContext.h"
24
#include "lldb/Target/Process.h"
25
#include "lldb/Target/RegisterContext.h"
26
#include "lldb/Target/Target.h"
27
#include "lldb/Utility/DataExtractor.h"
28
#include "lldb/Utility/RegisterValue.h"
29
#include "lldb/Utility/Scalar.h"
30
#include "lldb/Utility/Status.h"
31
#include "lldb/lldb-private-enumerations.h"
32
#include "lldb/lldb-types.h"
33
34
#include "llvm/ADT/StringRef.h"
35
36
#include <cassert>
37
#include <memory>
38
#include <optional>
39
40
namespace lldb_private {
41
class ExecutionContextScope;
42
}
43
namespace lldb_private {
44
class StackFrame;
45
}
46
namespace lldb_private {
47
struct RegisterInfo;
48
}
49
using namespace lldb_private;
50
51
lldb::ValueObjectSP
52
ValueObjectVariable::Create(ExecutionContextScope *exe_scope,
53
26.1k
                            const lldb::VariableSP &var_sp) {
54
26.1k
  auto manager_sp = ValueObjectManager::Create();
55
26.1k
  return (new ValueObjectVariable(exe_scope, *manager_sp, var_sp))->GetSP();
56
26.1k
}
57
58
ValueObjectVariable::ValueObjectVariable(ExecutionContextScope *exe_scope,
59
                                         ValueObjectManager &manager,
60
                                         const lldb::VariableSP &var_sp)
61
26.1k
    : ValueObject(exe_scope, manager), m_variable_sp(var_sp) {
62
  // Do not attempt to construct one of these objects with no variable!
63
26.1k
  assert(m_variable_sp.get() != nullptr);
64
26.1k
  m_name = var_sp->GetName();
65
26.1k
}
66
67
25.9k
ValueObjectVariable::~ValueObjectVariable() = default;
68
69
408k
CompilerType ValueObjectVariable::GetCompilerTypeImpl() {
70
408k
  Type *var_type = m_variable_sp->GetType();
71
408k
  if (var_type)
72
408k
    return var_type->GetForwardCompilerType();
73
3
  return CompilerType();
74
408k
}
75
76
1.49k
ConstString ValueObjectVariable::GetTypeName() {
77
1.49k
  Type *var_type = m_variable_sp->GetType();
78
1.49k
  if (var_type)
79
1.49k
    return var_type->GetName();
80
0
  return ConstString();
81
1.49k
}
82
83
4.42k
ConstString ValueObjectVariable::GetDisplayTypeName() {
84
4.42k
  Type *var_type = m_variable_sp->GetType();
85
4.42k
  if (var_type)
86
4.42k
    return var_type->GetForwardCompilerType().GetDisplayTypeName();
87
0
  return ConstString();
88
4.42k
}
89
90
27.8k
ConstString ValueObjectVariable::GetQualifiedTypeName() {
91
27.8k
  Type *var_type = m_variable_sp->GetType();
92
27.8k
  if (var_type)
93
27.8k
    return var_type->GetQualifiedName();
94
0
  return ConstString();
95
27.8k
}
96
97
2.81k
size_t ValueObjectVariable::CalculateNumChildren(uint32_t max) {
98
2.81k
  CompilerType type(GetCompilerType());
99
100
2.81k
  if (!type.IsValid())
101
0
    return 0;
102
103
2.81k
  ExecutionContext exe_ctx(GetExecutionContextRef());
104
2.81k
  const bool omit_empty_base_classes = true;
105
2.81k
  auto child_count = type.GetNumChildren(omit_empty_base_classes, &exe_ctx);
106
2.81k
  return child_count <= max ? child_count : 
max0
;
107
2.81k
}
108
109
175
std::optional<uint64_t> ValueObjectVariable::GetByteSize() {
110
175
  ExecutionContext exe_ctx(GetExecutionContextRef());
111
112
175
  CompilerType type(GetCompilerType());
113
114
175
  if (!type.IsValid())
115
0
    return {};
116
117
175
  return type.GetByteSize(exe_ctx.GetBestExecutionContextScope());
118
175
}
119
120
106
lldb::ValueType ValueObjectVariable::GetValueType() const {
121
106
  if (m_variable_sp)
122
106
    return m_variable_sp->GetScope();
123
0
  return lldb::eValueTypeInvalid;
124
106
}
125
126
13.7k
bool ValueObjectVariable::UpdateValue() {
127
13.7k
  SetValueIsValid(false);
128
13.7k
  m_error.Clear();
129
130
13.7k
  Variable *variable = m_variable_sp.get();
131
13.7k
  DWARFExpressionList &expr_list = variable->LocationExpressionList();
132
133
13.7k
  if (variable->GetLocationIsConstantValueData()) {
134
    // expr doesn't contain DWARF bytes, it contains the constant variable
135
    // value bytes themselves...
136
39
    if (expr_list.GetExpressionData(m_data)) {
137
38
      if (m_data.GetDataStart() && m_data.GetByteSize())
138
38
        m_value.SetBytes(m_data.GetDataStart(), m_data.GetByteSize());
139
38
      m_value.SetContext(Value::ContextType::Variable, variable);
140
38
    } else
141
1
      m_error.SetErrorString("empty constant data");
142
    // constant bytes can't be edited - sorry
143
39
    m_resolved_value.SetContext(Value::ContextType::Invalid, nullptr);
144
13.6k
  } else {
145
13.6k
    lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS;
146
13.6k
    ExecutionContext exe_ctx(GetExecutionContextRef());
147
148
13.6k
    Target *target = exe_ctx.GetTargetPtr();
149
13.6k
    if (target) {
150
13.6k
      m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
151
13.6k
      m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
152
13.6k
    }
153
154
13.6k
    if (!expr_list.IsAlwaysValidSingleExpr()) {
155
177
      SymbolContext sc;
156
177
      variable->CalculateSymbolContext(&sc);
157
177
      if (sc.function)
158
177
        loclist_base_load_addr =
159
177
            sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress(
160
177
                target);
161
177
    }
162
13.6k
    Value old_value(m_value);
163
13.6k
    if (expr_list.Evaluate(&exe_ctx, nullptr, loclist_base_load_addr, nullptr,
164
13.6k
                           nullptr, m_value, &m_error)) {
165
13.6k
      m_resolved_value = m_value;
166
13.6k
      m_value.SetContext(Value::ContextType::Variable, variable);
167
168
13.6k
      CompilerType compiler_type = GetCompilerType();
169
13.6k
      if (compiler_type.IsValid())
170
13.6k
        m_value.SetCompilerType(compiler_type);
171
172
13.6k
      Value::ValueType value_type = m_value.GetValueType();
173
174
      // The size of the buffer within m_value can be less than the size
175
      // prescribed by its type. E.g. this can happen when an expression only
176
      // partially describes an object (say, because it contains DW_OP_piece).
177
      //
178
      // In this case, grow m_value to the expected size. An alternative way to
179
      // handle this is to teach Value::GetValueAsData() and ValueObjectChild
180
      // not to read past the end of a host buffer, but this gets impractically
181
      // complicated as a Value's host buffer may be shared with a distant
182
      // ancestor or sibling in the ValueObject hierarchy.
183
      //
184
      // FIXME: When we grow m_value, we should represent the added bits as
185
      // undefined somehow instead of as 0's.
186
13.6k
      if (value_type == Value::ValueType::HostAddress &&
187
13.6k
          
compiler_type.IsValid()12
) {
188
12
        if (size_t value_buf_size = m_value.GetBuffer().GetByteSize()) {
189
12
          size_t value_size = m_value.GetValueByteSize(&m_error, &exe_ctx);
190
12
          if (m_error.Success() && value_buf_size < value_size)
191
1
            m_value.ResizeData(value_size);
192
12
        }
193
12
      }
194
195
13.6k
      Process *process = exe_ctx.GetProcessPtr();
196
13.6k
      const bool process_is_alive = process && 
process->IsAlive()13.0k
;
197
198
13.6k
      switch (value_type) {
199
0
      case Value::ValueType::Invalid:
200
0
        m_error.SetErrorString("invalid value");
201
0
        break;
202
115
      case Value::ValueType::Scalar:
203
        // The variable value is in the Scalar value inside the m_value. We can
204
        // point our m_data right to it.
205
115
        m_error =
206
115
            m_value.GetValueAsData(&exe_ctx, m_data, GetModule().get());
207
115
        break;
208
209
1.26k
      case Value::ValueType::FileAddress:
210
13.4k
      case Value::ValueType::LoadAddress:
211
13.4k
      case Value::ValueType::HostAddress:
212
        // The DWARF expression result was an address in the inferior process.
213
        // If this variable is an aggregate type, we just need the address as
214
        // the main value as all child variable objects will rely upon this
215
        // location and add an offset and then read their own values as needed.
216
        // If this variable is a simple type, we read all data for it into
217
        // m_data. Make sure this type has a value before we try and read it
218
219
        // If we have a file address, convert it to a load address if we can.
220
13.4k
        if (value_type == Value::ValueType::FileAddress && 
process_is_alive1.26k
)
221
736
          m_value.ConvertToLoadAddress(GetModule().get(), target);
222
223
13.4k
        if (!CanProvideValue()) {
224
          // this value object represents an aggregate type whose children have
225
          // values, but this object does not. So we say we are changed if our
226
          // location has changed.
227
4.37k
          SetValueDidChange(value_type != old_value.GetValueType() ||
228
4.37k
                            
m_value.GetScalar() != old_value.GetScalar()35
);
229
9.11k
        } else {
230
          // Copy the Value and set the context to use our Variable so it can
231
          // extract read its value into m_data appropriately
232
9.11k
          Value value(m_value);
233
9.11k
          value.SetContext(Value::ContextType::Variable, variable);
234
9.11k
          m_error =
235
9.11k
              value.GetValueAsData(&exe_ctx, m_data, GetModule().get());
236
237
9.11k
          SetValueDidChange(value_type != old_value.GetValueType() ||
238
9.11k
                            
m_value.GetScalar() != old_value.GetScalar()287
);
239
9.11k
        }
240
13.4k
        break;
241
13.6k
      }
242
243
13.6k
      SetValueIsValid(m_error.Success());
244
13.6k
    } else {
245
      // could not find location, won't allow editing
246
81
      m_resolved_value.SetContext(Value::ContextType::Invalid, nullptr);
247
81
    }
248
13.6k
  }
249
250
13.7k
  return m_error.Success();
251
13.7k
}
252
253
49.7k
void ValueObjectVariable::DoUpdateChildrenAddressType(ValueObject &valobj) {
254
49.7k
  Value::ValueType value_type = valobj.GetValue().GetValueType();
255
49.7k
  ExecutionContext exe_ctx(GetExecutionContextRef());
256
49.7k
  Process *process = exe_ctx.GetProcessPtr();
257
49.7k
  const bool process_is_alive = process && 
process->IsAlive()48.7k
;
258
49.7k
  const uint32_t type_info = valobj.GetCompilerType().GetTypeInfo();
259
49.7k
  const bool is_pointer_or_ref =
260
49.7k
      (type_info & (lldb::eTypeIsPointer | lldb::eTypeIsReference)) != 0;
261
262
49.7k
  switch (value_type) {
263
0
  case Value::ValueType::Invalid:
264
0
    break;
265
1.01k
  case Value::ValueType::FileAddress:
266
    // If this type is a pointer, then its children will be considered load
267
    // addresses if the pointer or reference is dereferenced, but only if
268
    // the process is alive.
269
    //
270
    // There could be global variables like in the following code:
271
    // struct LinkedListNode { Foo* foo; LinkedListNode* next; };
272
    // Foo g_foo1;
273
    // Foo g_foo2;
274
    // LinkedListNode g_second_node = { &g_foo2, NULL };
275
    // LinkedListNode g_first_node = { &g_foo1, &g_second_node };
276
    //
277
    // When we aren't running, we should be able to look at these variables
278
    // using the "target variable" command. Children of the "g_first_node"
279
    // always will be of the same address type as the parent. But children
280
    // of the "next" member of LinkedListNode will become load addresses if
281
    // we have a live process, or remain a file address if it was a file
282
    // address.
283
1.01k
    if (process_is_alive && 
is_pointer_or_ref0
)
284
0
      valobj.SetAddressTypeOfChildren(eAddressTypeLoad);
285
1.01k
    else
286
1.01k
      valobj.SetAddressTypeOfChildren(eAddressTypeFile);
287
1.01k
    break;
288
78
  case Value::ValueType::HostAddress:
289
    // Same as above for load addresses, except children of pointer or refs
290
    // are always load addresses. Host addresses are used to store freeze
291
    // dried variables. If this type is a struct, the entire struct
292
    // contents will be copied into the heap of the
293
    // LLDB process, but we do not currently follow any pointers.
294
78
    if (is_pointer_or_ref)
295
5
      valobj.SetAddressTypeOfChildren(eAddressTypeLoad);
296
73
    else
297
73
      valobj.SetAddressTypeOfChildren(eAddressTypeHost);
298
78
    break;
299
48.1k
  case Value::ValueType::LoadAddress:
300
48.7k
  case Value::ValueType::Scalar:
301
48.7k
    valobj.SetAddressTypeOfChildren(eAddressTypeLoad);
302
48.7k
    break;
303
49.7k
  }
304
49.7k
}
305
306
307
308
58.5k
bool ValueObjectVariable::IsInScope() {
309
58.5k
  const ExecutionContextRef &exe_ctx_ref = GetExecutionContextRef();
310
58.5k
  if (exe_ctx_ref.HasFrameRef()) {
311
57.0k
    ExecutionContext exe_ctx(exe_ctx_ref);
312
57.0k
    StackFrame *frame = exe_ctx.GetFramePtr();
313
57.0k
    if (frame) {
314
57.0k
      return m_variable_sp->IsInScope(frame);
315
57.0k
    } else {
316
      // This ValueObject had a frame at one time, but now we can't locate it,
317
      // so return false since we probably aren't in scope.
318
12
      return false;
319
12
    }
320
57.0k
  }
321
  // We have a variable that wasn't tied to a frame, which means it is a global
322
  // and is always in scope.
323
1.50k
  return true;
324
58.5k
}
325
326
52.7k
lldb::ModuleSP ValueObjectVariable::GetModule() {
327
52.7k
  if (m_variable_sp) {
328
52.7k
    SymbolContextScope *sc_scope = m_variable_sp->GetSymbolContextScope();
329
52.7k
    if (sc_scope) {
330
52.7k
      return sc_scope->CalculateSymbolContextModule();
331
52.7k
    }
332
52.7k
  }
333
0
  return lldb::ModuleSP();
334
52.7k
}
335
336
0
SymbolContextScope *ValueObjectVariable::GetSymbolContextScope() {
337
0
  if (m_variable_sp)
338
0
    return m_variable_sp->GetSymbolContextScope();
339
0
  return nullptr;
340
0
}
341
342
10
bool ValueObjectVariable::GetDeclaration(Declaration &decl) {
343
10
  if (m_variable_sp) {
344
10
    decl = m_variable_sp->GetDeclaration();
345
10
    return true;
346
10
  }
347
0
  return false;
348
10
}
349
350
121
const char *ValueObjectVariable::GetLocationAsCString() {
351
121
  if (m_resolved_value.GetContextType() == Value::ContextType::RegisterInfo)
352
4
    return GetLocationAsCStringImpl(m_resolved_value, m_data);
353
117
  else
354
117
    return ValueObject::GetLocationAsCString();
355
121
}
356
357
bool ValueObjectVariable::SetValueFromCString(const char *value_str,
358
8
                                              Status &error) {
359
8
  if (!UpdateValueIfNeeded()) {
360
0
    error.SetErrorString("unable to update value before writing");
361
0
    return false;
362
0
  }
363
364
8
  if (m_resolved_value.GetContextType() == Value::ContextType::RegisterInfo) {
365
0
    RegisterInfo *reg_info = m_resolved_value.GetRegisterInfo();
366
0
    ExecutionContext exe_ctx(GetExecutionContextRef());
367
0
    RegisterContext *reg_ctx = exe_ctx.GetRegisterContext();
368
0
    RegisterValue reg_value;
369
0
    if (!reg_info || !reg_ctx) {
370
0
      error.SetErrorString("unable to retrieve register info");
371
0
      return false;
372
0
    }
373
0
    error = reg_value.SetValueFromString(reg_info, llvm::StringRef(value_str));
374
0
    if (error.Fail())
375
0
      return false;
376
0
    if (reg_ctx->WriteRegister(reg_info, reg_value)) {
377
0
      SetNeedsUpdate();
378
0
      return true;
379
0
    } else {
380
0
      error.SetErrorString("unable to write back to register");
381
0
      return false;
382
0
    }
383
0
  } else
384
8
    return ValueObject::SetValueFromCString(value_str, error);
385
8
}
386
387
0
bool ValueObjectVariable::SetData(DataExtractor &data, Status &error) {
388
0
  if (!UpdateValueIfNeeded()) {
389
0
    error.SetErrorString("unable to update value before writing");
390
0
    return false;
391
0
  }
392
393
0
  if (m_resolved_value.GetContextType() == Value::ContextType::RegisterInfo) {
394
0
    RegisterInfo *reg_info = m_resolved_value.GetRegisterInfo();
395
0
    ExecutionContext exe_ctx(GetExecutionContextRef());
396
0
    RegisterContext *reg_ctx = exe_ctx.GetRegisterContext();
397
0
    RegisterValue reg_value;
398
0
    if (!reg_info || !reg_ctx) {
399
0
      error.SetErrorString("unable to retrieve register info");
400
0
      return false;
401
0
    }
402
0
    error = reg_value.SetValueFromData(*reg_info, data, 0, true);
403
0
    if (error.Fail())
404
0
      return false;
405
0
    if (reg_ctx->WriteRegister(reg_info, reg_value)) {
406
0
      SetNeedsUpdate();
407
0
      return true;
408
0
    } else {
409
0
      error.SetErrorString("unable to write back to register");
410
0
      return false;
411
0
    }
412
0
  } else
413
0
    return ValueObject::SetData(data, error);
414
0
}