LLDB mainline
DWARFExpressionList.cpp
Go to the documentation of this file.
1//===-- DWARFExpressionList.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
14#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
15#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
16
17using namespace lldb;
18using namespace lldb_private;
19
21 return GetAlwaysValidExpr() != nullptr;
22}
23
25 if (m_exprs.GetSize() != 1)
26 return nullptr;
27 const auto *expr = m_exprs.GetEntryAtIndex(0);
28 if (expr->base == 0 && expr->size == LLDB_INVALID_ADDRESS)
29 return &expr->data;
30 return nullptr;
31}
32
34 DWARFExpression expr) {
35 if (IsAlwaysValidSingleExpr() || base >= end)
36 return false;
37 m_exprs.Append({base, end - base, expr});
38 return true;
39}
40
42 lldb::addr_t func_load_addr,
43 lldb::addr_t file_addr) const {
44 if (const DWARFExpression *expr =
45 GetExpressionAtAddress(func_load_addr, file_addr))
46 return expr->GetExpressionData(data);
47 return false;
48}
49
51 lldb::addr_t addr) const {
53 return true;
54 return GetExpressionAtAddress(func_load_addr, addr) != nullptr;
55}
56
57const DWARFExpression *
59 lldb::addr_t load_addr) const {
60 if (const DWARFExpression *expr = GetAlwaysValidExpr())
61 return expr;
62 if (func_load_addr == LLDB_INVALID_ADDRESS)
63 func_load_addr = m_func_file_addr;
64 addr_t addr = load_addr - func_load_addr + m_func_file_addr;
65 uint32_t index = m_exprs.FindEntryIndexThatContains(addr);
66 if (index == UINT32_MAX)
67 return nullptr;
68 return &m_exprs.GetEntryAtIndex(index)->data;
69}
70
73 lldb::addr_t load_addr) {
76 if (func_load_addr == LLDB_INVALID_ADDRESS)
77 func_load_addr = m_func_file_addr;
78 addr_t addr = load_addr - func_load_addr + m_func_file_addr;
79 uint32_t index = m_exprs.FindEntryIndexThatContains(addr);
80 if (index == UINT32_MAX)
81 return nullptr;
82 return &m_exprs.GetMutableEntryAtIndex(index)->data;
83}
84
86 // We are assuming for now that any thread local variable will not have a
87 // location list. This has been true for all thread local variables we have
88 // seen so far produced by any compiler.
90 return false;
91
92 const DWARFExpression &expr = m_exprs.GetEntryRef(0).data;
94}
95
97 lldb::ModuleSP new_module_sp,
98 std::function<lldb::addr_t(lldb::addr_t file_addr)> const
99 &link_address_callback) {
100 // We are assuming for now that any thread local variable will not have a
101 // location list. This has been true for all thread local variables we have
102 // seen so far produced by any compiler.
104 return false;
105
107 // If we linked the TLS address correctly, update the module so that when the
108 // expression is evaluated it can resolve the file address to a load address
109 // and read the TLS data
110 if (expr.LinkThreadLocalStorage(m_dwarf_cu, link_address_callback))
111 m_module_wp = new_module_sp;
112 return true;
113}
114
116 StackFrame &frame, const Instruction::Operand &operand) const {
117 RegisterContextSP reg_ctx_sp = frame.GetRegisterContext();
118 if (!reg_ctx_sp) {
119 return false;
120 }
121 const DWARFExpression *expr = nullptr;
123 expr = &m_exprs.GetEntryAtIndex(0)->data;
124 else {
125 SymbolContext sc = frame.GetSymbolContext(eSymbolContextFunction);
126 if (!sc.function)
127 return false;
128
129 addr_t load_function_start = sc.function->GetAddress().GetFileAddress();
130 if (load_function_start == LLDB_INVALID_ADDRESS)
131 return false;
132
135 }
136 if (!expr)
137 return false;
138 return expr->MatchesOperand(frame, operand);
139}
140
142 lldb::addr_t func_load_addr,
143 lldb::addr_t file_addr,
144 ABI *abi) const {
145 llvm::raw_ostream &os = s->AsRawOstream();
146 llvm::ListSeparator separator;
147 if (const DWARFExpression *expr = GetAlwaysValidExpr()) {
148 expr->DumpLocation(s, level, abi);
149 return true;
150 }
151 for (const Entry &entry : *this) {
152 addr_t load_base = entry.GetRangeBase() + func_load_addr - m_func_file_addr;
153 addr_t load_end = entry.GetRangeEnd() + func_load_addr - m_func_file_addr;
154 if (file_addr != LLDB_INVALID_ADDRESS &&
155 (file_addr < load_base || file_addr >= load_end))
156 continue;
157 const auto &expr = entry.data;
158 DataExtractor data;
159 expr.GetExpressionData(data);
160 uint32_t addr_size = data.GetAddressByteSize();
161
162 os << separator;
163 os << "[";
164 os << llvm::format_hex(load_base, 2 + 2 * addr_size);
165 os << ", ";
166 os << llvm::format_hex(load_end, 2 + 2 * addr_size);
167 os << ") -> ";
168 expr.DumpLocation(s, level, abi);
169 if (file_addr != LLDB_INVALID_ADDRESS)
170 break;
171 }
172 return true;
173}
174
177 ABI *abi) const {
178 llvm::raw_ostream &os = s->AsRawOstream();
180 m_exprs.Back()->data.DumpLocation(s, level, abi);
181 return;
182 }
183 os << llvm::format("0x%8.8" PRIx64 ": ", 0);
184 for (const Entry &entry : *this) {
185 const auto &expr = entry.data;
186 DataExtractor data;
187 expr.GetExpressionData(data);
188 uint32_t addr_size = data.GetAddressByteSize();
189 os << "\n";
190 os.indent(s->GetIndentLevel() + 2);
191 os << "[";
192 llvm::DWARFFormValue::dumpAddress(os, addr_size, entry.GetRangeBase());
193 os << ", ";
194 llvm::DWARFFormValue::dumpAddress(os, addr_size, entry.GetRangeEnd());
195 os << "): ";
196 expr.DumpLocation(s, level, abi);
197 }
198}
199
200llvm::Expected<Value> DWARFExpressionList::Evaluate(
201 ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
202 lldb::addr_t func_load_addr, const Value *initial_value_ptr,
203 const Value *object_address_ptr) const {
204 ModuleSP module_sp = m_module_wp.lock();
205 DataExtractor data;
206 RegisterKind reg_kind;
207 DWARFExpression expr;
209 expr = m_exprs.Back()->data;
210 } else {
211 Address pc;
212 StackFrame *frame = nullptr;
213 if (!reg_ctx || !reg_ctx->GetPCForSymbolication(pc)) {
214 if (exe_ctx)
215 frame = exe_ctx->GetFramePtr();
216 if (!frame)
217 return llvm::createStringError("no frame");
218 RegisterContextSP reg_ctx_sp = frame->GetRegisterContext();
219 if (!reg_ctx_sp)
220 return llvm::createStringError("no register context");
221 reg_ctx_sp->GetPCForSymbolication(pc);
222 }
223
224 if (!pc.IsValid()) {
225 return llvm::createStringError("Invalid PC in frame.");
226 }
227 addr_t pc_load_addr = pc.GetLoadAddress(exe_ctx->GetTargetPtr());
228 const DWARFExpression *entry =
229 GetExpressionAtAddress(func_load_addr, pc_load_addr);
230 if (!entry)
231 return llvm::createStringError("variable not available");
232 expr = *entry;
233 }
234 expr.GetExpressionData(data);
235 reg_kind = expr.GetRegisterKind();
236 return DWARFExpression::Evaluate(exe_ctx, reg_ctx, module_sp, data,
237 m_dwarf_cu, reg_kind, initial_value_ptr,
238 object_address_ptr);
239}
A section + offset based address class.
Definition: Address.h:62
lldb::addr_t GetFileAddress() const
Get the file address.
Definition: Address.cpp:293
bool AddExpression(lldb::addr_t base, lldb::addr_t end, DWARFExpression expr)
const DWARFExpression * GetExpressionAtAddress(lldb::addr_t func_load_addr, lldb::addr_t load_addr) const
void GetDescription(Stream *s, lldb::DescriptionLevel level, ABI *abi) const
Dump all locaitons with each separated by new line.
bool MatchesOperand(StackFrame &frame, const Instruction::Operand &operand) const
llvm::Expected< Value > Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx, lldb::addr_t func_load_addr, const Value *initial_value_ptr, const Value *object_address_ptr) const
const DWARFExpression * GetAlwaysValidExpr() const
lldb::ModuleWP m_module_wp
Module which defined this expression.
bool GetExpressionData(DataExtractor &data, lldb::addr_t func_load_addr=LLDB_INVALID_ADDRESS, lldb::addr_t file_addr=0) const
Get the expression data at the file address.
bool DumpLocations(Stream *s, lldb::DescriptionLevel level, lldb::addr_t func_load_addr, lldb::addr_t file_addr, ABI *abi) const
Dump locations that contains file_addr if it's valid.
bool LinkThreadLocalStorage(lldb::ModuleSP new_module_sp, std::function< lldb::addr_t(lldb::addr_t file_addr)> const &link_address_callback)
const plugin::dwarf::DWARFUnit * m_dwarf_cu
The DWARF compile unit this expression belongs to.
bool ContainsAddress(lldb::addr_t func_load_addr, lldb::addr_t addr) const
Search for a load address in the dwarf location list.
DWARFExpression * GetMutableExpressionAtAddress(lldb::addr_t func_load_addr=LLDB_INVALID_ADDRESS, lldb::addr_t load_addr=0)
"lldb/Expression/DWARFExpression.h" Encapsulates a DWARF location expression and interprets it.
static llvm::Expected< Value > Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx, lldb::ModuleSP module_sp, const DataExtractor &opcodes, const plugin::dwarf::DWARFUnit *dwarf_cu, const lldb::RegisterKind reg_set, const Value *initial_value_ptr, const Value *object_address_ptr)
Evaluate a DWARF location expression in a particular context.
bool LinkThreadLocalStorage(const plugin::dwarf::DWARFUnit *dwarf_cu, std::function< lldb::addr_t(lldb::addr_t file_addr)> const &link_address_callback)
bool GetExpressionData(DataExtractor &data) const
bool ContainsThreadLocalStorage(const plugin::dwarf::DWARFUnit *dwarf_cu) const
bool MatchesOperand(StackFrame &frame, const Instruction::Operand &op) const
lldb::RegisterKind GetRegisterKind() const
Return the call-frame-info style register kind.
An data extractor class.
Definition: DataExtractor.h:48
uint32_t GetAddressByteSize() const
Get the current address size.
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
StackFrame * GetFramePtr() const
Returns a pointer to the frame object.
Target * GetTargetPtr() const
Returns a pointer to the target object.
const Address & GetAddress() const
Return the address of the function (its entry point).
Definition: Function.h:455
Entry & GetEntryRef(size_t i)
Definition: RangeMap.h:544
uint32_t FindEntryIndexThatContains(B addr) const
Definition: RangeMap.h:551
const Entry * GetEntryAtIndex(size_t i) const
Definition: RangeMap.h:534
Entry * GetMutableEntryAtIndex(size_t i)
Definition: RangeMap.h:538
void Append(const Entry &entry)
Definition: RangeMap.h:451
bool GetPCForSymbolication(Address &address)
Get an address suitable for symbolication.
This base class provides an interface to stack frames.
Definition: StackFrame.h:44
lldb::RegisterContextSP GetRegisterContext()
Get the RegisterContext for this frame, if possible.
Address GetFrameCodeAddressForSymbolication()
Get the current code Address suitable for symbolication, may not be the same as GetFrameCodeAddress()...
Definition: StackFrame.cpp:223
const SymbolContext & GetSymbolContext(lldb::SymbolContextItem resolve_scope)
Provide a SymbolContext for this StackFrame's current pc value.
Definition: StackFrame.cpp:301
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
llvm::raw_ostream & AsRawOstream()
Returns a raw_ostream that forwards the data to this Stream object.
Definition: Stream.h:401
unsigned GetIndentLevel() const
Get the current indentation level.
Definition: Stream.cpp:187
Defines a symbol context baton that can be handed other debug core functions.
Definition: SymbolContext.h:34
Function * function
The Function for a given query.
#define LLDB_INVALID_ADDRESS
Definition: lldb-defines.h:82
#define UINT32_MAX
Definition: lldb-defines.h:19
A class that represents a running process on the host machine.
Definition: SBAddress.h:15
DescriptionLevel
Description levels for "void GetDescription(Stream *, DescriptionLevel)" calls.
uint64_t addr_t
Definition: lldb-types.h:80
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
Definition: lldb-forward.h:394
std::shared_ptr< lldb_private::Module > ModuleSP
Definition: lldb-forward.h:373
RegisterKind
Register numbering types.
BaseType GetRangeBase() const
Definition: RangeMap.h:45
BaseType GetRangeEnd() const
Definition: RangeMap.h:78