Coverage Report

Created: 2022-01-18 06:27

/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/DWARFExpression.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
39
namespace lldb_private {
40
class ExecutionContextScope;
41
}
42
namespace lldb_private {
43
class StackFrame;
44
}
45
namespace lldb_private {
46
struct RegisterInfo;
47
}
48
using namespace lldb_private;
49
50
lldb::ValueObjectSP
51
ValueObjectVariable::Create(ExecutionContextScope *exe_scope,
52
38.5k
                            const lldb::VariableSP &var_sp) {
53
38.5k
  auto manager_sp = ValueObjectManager::Create();
54
38.5k
  return (new ValueObjectVariable(exe_scope, *manager_sp, var_sp))->GetSP();
55
38.5k
}
56
57
ValueObjectVariable::ValueObjectVariable(ExecutionContextScope *exe_scope,
58
                                         ValueObjectManager &manager,
59
                                         const lldb::VariableSP &var_sp)
60
38.5k
    : ValueObject(exe_scope, manager), m_variable_sp(var_sp) {
61
  // Do not attempt to construct one of these objects with no variable!
62
38.5k
  assert(m_variable_sp.get() != nullptr);
63
0
  m_name = var_sp->GetName();
64
38.5k
}
65
66
38.3k
ValueObjectVariable::~ValueObjectVariable() = default;
67
68
489k
CompilerType ValueObjectVariable::GetCompilerTypeImpl() {
69
489k
  Type *var_type = m_variable_sp->GetType();
70
489k
  if (var_type)
71
489k
    return var_type->GetForwardCompilerType();
72
0
  return CompilerType();
73
489k
}
74
75
2.63k
ConstString ValueObjectVariable::GetTypeName() {
76
2.63k
  Type *var_type = m_variable_sp->GetType();
77
2.63k
  if (var_type)
78
2.63k
    return var_type->GetName();
79
0
  return ConstString();
80
2.63k
}
81
82
6.31k
ConstString ValueObjectVariable::GetDisplayTypeName() {
83
6.31k
  Type *var_type = m_variable_sp->GetType();
84
6.31k
  if (var_type)
85
6.31k
    return var_type->GetForwardCompilerType().GetDisplayTypeName();
86
0
  return ConstString();
87
6.31k
}
88
89
43.0k
ConstString ValueObjectVariable::GetQualifiedTypeName() {
90
43.0k
  Type *var_type = m_variable_sp->GetType();
91
43.0k
  if (var_type)
92
43.0k
    return var_type->GetQualifiedName();
93
0
  return ConstString();
94
43.0k
}
95
96
4.06k
size_t ValueObjectVariable::CalculateNumChildren(uint32_t max) {
97
4.06k
  CompilerType type(GetCompilerType());
98
99
4.06k
  if (!type.IsValid())
100
0
    return 0;
101
102
4.06k
  ExecutionContext exe_ctx(GetExecutionContextRef());
103
4.06k
  const bool omit_empty_base_classes = true;
104
4.06k
  auto child_count = type.GetNumChildren(omit_empty_base_classes, &exe_ctx);
105
4.06k
  return child_count <= max ? child_count : 
max0
;
106
4.06k
}
107
108
266
llvm::Optional<uint64_t> ValueObjectVariable::GetByteSize() {
109
266
  ExecutionContext exe_ctx(GetExecutionContextRef());
110
111
266
  CompilerType type(GetCompilerType());
112
113
266
  if (!type.IsValid())
114
0
    return {};
115
116
266
  return type.GetByteSize(exe_ctx.GetBestExecutionContextScope());
117
266
}
118
119
183
lldb::ValueType ValueObjectVariable::GetValueType() const {
120
183
  if (m_variable_sp)
121
183
    return m_variable_sp->GetScope();
122
0
  return lldb::eValueTypeInvalid;
123
183
}
124
125
20.2k
bool ValueObjectVariable::UpdateValue() {
126
20.2k
  SetValueIsValid(false);
127
20.2k
  m_error.Clear();
128
129
20.2k
  Variable *variable = m_variable_sp.get();
130
20.2k
  DWARFExpression &expr = variable->LocationExpression();
131
132
20.2k
  if (variable->GetLocationIsConstantValueData()) {
133
    // expr doesn't contain DWARF bytes, it contains the constant variable
134
    // value bytes themselves...
135
53
    if (expr.GetExpressionData(m_data)) {
136
52
       if (m_data.GetDataStart() && m_data.GetByteSize())
137
52
        m_value.SetBytes(m_data.GetDataStart(), m_data.GetByteSize());
138
52
      m_value.SetContext(Value::ContextType::Variable, variable);
139
52
    }
140
1
    else
141
1
      m_error.SetErrorString("empty constant data");
142
    // constant bytes can't be edited - sorry
143
53
    m_resolved_value.SetContext(Value::ContextType::Invalid, nullptr);
144
20.2k
  } else {
145
20.2k
    lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS;
146
20.2k
    ExecutionContext exe_ctx(GetExecutionContextRef());
147
148
20.2k
    Target *target = exe_ctx.GetTargetPtr();
149
20.2k
    if (target) {
150
20.2k
      m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
151
20.2k
      m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
152
20.2k
    }
153
154
20.2k
    if (expr.IsLocationList()) {
155
305
      SymbolContext sc;
156
305
      variable->CalculateSymbolContext(&sc);
157
305
      if (sc.function)
158
305
        loclist_base_load_addr =
159
305
            sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress(
160
305
                target);
161
305
    }
162
20.2k
    Value old_value(m_value);
163
20.2k
    if (expr.Evaluate(&exe_ctx, nullptr, loclist_base_load_addr, nullptr,
164
20.2k
                      nullptr, m_value, &m_error)) {
165
20.0k
      m_resolved_value = m_value;
166
20.0k
      m_value.SetContext(Value::ContextType::Variable, variable);
167
168
20.0k
      CompilerType compiler_type = GetCompilerType();
169
20.0k
      if (compiler_type.IsValid())
170
20.0k
        m_value.SetCompilerType(compiler_type);
171
172
20.0k
      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
20.0k
      if (value_type == Value::ValueType::HostAddress &&
187
20.0k
          
compiler_type.IsValid()17
) {
188
17
        if (size_t value_buf_size = m_value.GetBuffer().GetByteSize()) {
189
17
          size_t value_size = m_value.GetValueByteSize(&m_error, &exe_ctx);
190
17
          if (m_error.Success() && value_buf_size < value_size)
191
7
            m_value.ResizeData(value_size);
192
17
        }
193
17
      }
194
195
20.0k
      Process *process = exe_ctx.GetProcessPtr();
196
20.0k
      const bool process_is_alive = process && 
process->IsAlive()19.4k
;
197
198
20.0k
      switch (value_type) {
199
0
      case Value::ValueType::Invalid:
200
0
        m_error.SetErrorString("invalid value");
201
0
        break;
202
207
      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
207
        m_error =
206
207
            m_value.GetValueAsData(&exe_ctx, m_data, GetModule().get());
207
207
        break;
208
209
695
      case Value::ValueType::FileAddress:
210
19.8k
      case Value::ValueType::LoadAddress:
211
19.8k
      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
19.8k
        if (value_type == Value::ValueType::FileAddress && 
process_is_alive695
)
221
75
          m_value.ConvertToLoadAddress(GetModule().get(), target);
222
223
19.8k
        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
6.40k
          SetValueDidChange(value_type != old_value.GetValueType() ||
228
6.40k
                            
m_value.GetScalar() != old_value.GetScalar()33
);
229
13.4k
        } 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
13.4k
          Value value(m_value);
233
13.4k
          value.SetContext(Value::ContextType::Variable, variable);
234
13.4k
          m_error =
235
13.4k
              value.GetValueAsData(&exe_ctx, m_data, GetModule().get());
236
237
13.4k
          SetValueDidChange(value_type != old_value.GetValueType() ||
238
13.4k
                            
m_value.GetScalar() != old_value.GetScalar()327
);
239
13.4k
        }
240
19.8k
        break;
241
20.0k
      }
242
243
20.0k
      SetValueIsValid(m_error.Success());
244
20.0k
    } else {
245
      // could not find location, won't allow editing
246
141
      m_resolved_value.SetContext(Value::ContextType::Invalid, nullptr);
247
141
    }
248
20.2k
  }
249
  
250
20.2k
  return m_error.Success();
251
20.2k
}
252
253
62.8k
void ValueObjectVariable::DoUpdateChildrenAddressType(ValueObject &valobj) {
254
62.8k
  Value::ValueType value_type = valobj.GetValue().GetValueType();
255
62.8k
  ExecutionContext exe_ctx(GetExecutionContextRef());
256
62.8k
  Process *process = exe_ctx.GetProcessPtr();
257
62.8k
  const bool process_is_alive = process && 
process->IsAlive()62.1k
;
258
62.8k
  const uint32_t type_info = valobj.GetCompilerType().GetTypeInfo();
259
62.8k
  const bool is_pointer_or_ref =
260
62.8k
      (type_info & (lldb::eTypeIsPointer | lldb::eTypeIsReference)) != 0;
261
262
62.8k
  switch (value_type) {
263
0
  case Value::ValueType::Invalid:
264
0
    break;
265
741
  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
741
    if (process_is_alive && 
is_pointer_or_ref0
)
284
0
      valobj.SetAddressTypeOfChildren(eAddressTypeLoad);
285
741
    else
286
741
      valobj.SetAddressTypeOfChildren(eAddressTypeFile);
287
741
    break;
288
105
  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
105
    if (is_pointer_or_ref)
295
6
      valobj.SetAddressTypeOfChildren(eAddressTypeLoad);
296
99
    else
297
99
      valobj.SetAddressTypeOfChildren(eAddressTypeHost);
298
105
    break;
299
61.5k
  case Value::ValueType::LoadAddress:
300
62.0k
  case Value::ValueType::Scalar:
301
62.0k
    valobj.SetAddressTypeOfChildren(eAddressTypeLoad);
302
62.0k
    break;
303
62.8k
  }
304
62.8k
}
305
306
307
308
74.6k
bool ValueObjectVariable::IsInScope() {
309
74.6k
  const ExecutionContextRef &exe_ctx_ref = GetExecutionContextRef();
310
74.6k
  if (exe_ctx_ref.HasFrameRef()) {
311
73.3k
    ExecutionContext exe_ctx(exe_ctx_ref);
312
73.3k
    StackFrame *frame = exe_ctx.GetFramePtr();
313
73.3k
    if (frame) {
314
73.3k
      return m_variable_sp->IsInScope(frame);
315
73.3k
    } 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
18
      return false;
319
18
    }
320
73.3k
  }
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.33k
  return true;
324
74.6k
}
325
326
68.3k
lldb::ModuleSP ValueObjectVariable::GetModule() {
327
68.3k
  if (m_variable_sp) {
328
68.3k
    SymbolContextScope *sc_scope = m_variable_sp->GetSymbolContextScope();
329
68.3k
    if (sc_scope) {
330
68.3k
      return sc_scope->CalculateSymbolContextModule();
331
68.3k
    }
332
68.3k
  }
333
0
  return lldb::ModuleSP();
334
68.3k
}
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
285
const char *ValueObjectVariable::GetLocationAsCString() {
351
285
  if (m_resolved_value.GetContextType() == Value::ContextType::RegisterInfo)
352
6
    return GetLocationAsCStringImpl(m_resolved_value, m_data);
353
279
  else
354
279
    return ValueObject::GetLocationAsCString();
355
285
}
356
357
bool ValueObjectVariable::SetValueFromCString(const char *value_str,
358
10
                                              Status &error) {
359
10
  if (!UpdateValueIfNeeded()) {
360
0
    error.SetErrorString("unable to update value before writing");
361
0
    return false;
362
0
  }
363
364
10
  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
10
    return ValueObject::SetValueFromCString(value_str, error);
385
10
}
386
387
3
bool ValueObjectVariable::SetData(DataExtractor &data, Status &error) {
388
3
  if (!UpdateValueIfNeeded()) {
389
0
    error.SetErrorString("unable to update value before writing");
390
0
    return false;
391
0
  }
392
393
3
  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
3
    return ValueObject::SetData(data, error);
414
3
}