1 | //===-- DWARFExpressionList.h -----------------------------------*- C++ -*-===// |
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 | #ifndef LLDB_EXPRESSION_DWARFEXPRESSIONLIST_H |
10 | #define LLDB_EXPRESSION_DWARFEXPRESSIONLIST_H |
11 | |
12 | #include "lldb/Expression/DWARFExpression.h" |
13 | #include "lldb/Utility/RangeMap.h" |
14 | #include "lldb/lldb-private.h" |
15 | |
16 | namespace lldb_private { |
17 | |
18 | namespace plugin { |
19 | namespace dwarf { |
20 | class DWARFUnit; |
21 | } // namespace dwarf |
22 | } // namespace plugin |
23 | |
24 | /// \class DWARFExpressionList DWARFExpressionList.h |
25 | /// "lldb/Expression/DWARFExpressionList.h" Encapsulates a range map from file |
26 | /// address range to a single DWARF location expression. |
27 | class DWARFExpressionList { |
28 | public: |
29 | DWARFExpressionList() = default; |
30 | |
31 | DWARFExpressionList(lldb::ModuleSP module_sp, |
32 | const plugin::dwarf::DWARFUnit *dwarf_cu, |
33 | lldb::addr_t func_file_addr) |
34 | : m_module_wp(module_sp), m_dwarf_cu(dwarf_cu), |
35 | m_func_file_addr(func_file_addr) {} |
36 | |
37 | DWARFExpressionList(lldb::ModuleSP module_sp, DWARFExpression expr, |
38 | const plugin::dwarf::DWARFUnit *dwarf_cu) |
39 | : m_module_wp(module_sp), m_dwarf_cu(dwarf_cu) { |
40 | AddExpression(base: 0, LLDB_INVALID_ADDRESS, expr); |
41 | } |
42 | |
43 | /// Return true if the location expression contains data |
44 | bool IsValid() const { return !m_exprs.IsEmpty(); } |
45 | |
46 | void Clear() { m_exprs.Clear(); } |
47 | |
48 | // Return true if the location expression is always valid. |
49 | bool IsAlwaysValidSingleExpr() const; |
50 | |
51 | bool AddExpression(lldb::addr_t base, lldb::addr_t end, DWARFExpression expr); |
52 | |
53 | /// Get the expression data at the file address. |
54 | bool (DataExtractor &data, |
55 | lldb::addr_t func_load_addr = LLDB_INVALID_ADDRESS, |
56 | lldb::addr_t file_addr = 0) const; |
57 | |
58 | /// Sort m_expressions. |
59 | void Sort() { m_exprs.Sort(); } |
60 | |
61 | void SetFuncFileAddress(lldb::addr_t func_file_addr) { |
62 | m_func_file_addr = func_file_addr; |
63 | } |
64 | |
65 | lldb::addr_t GetFuncFileAddress() { return m_func_file_addr; } |
66 | |
67 | const DWARFExpression *GetExpressionAtAddress(lldb::addr_t func_load_addr, |
68 | lldb::addr_t load_addr) const; |
69 | |
70 | const DWARFExpression *GetAlwaysValidExpr() const; |
71 | |
72 | DWARFExpression *GetMutableExpressionAtAddress( |
73 | lldb::addr_t func_load_addr = LLDB_INVALID_ADDRESS, |
74 | lldb::addr_t load_addr = 0); |
75 | |
76 | size_t GetSize() const { return m_exprs.GetSize(); } |
77 | |
78 | bool ContainsThreadLocalStorage() const; |
79 | |
80 | bool LinkThreadLocalStorage( |
81 | lldb::ModuleSP new_module_sp, |
82 | std::function<lldb::addr_t(lldb::addr_t file_addr)> const |
83 | &link_address_callback); |
84 | |
85 | bool MatchesOperand(StackFrame &frame, |
86 | const Instruction::Operand &operand) const; |
87 | |
88 | /// Dump locations that contains file_addr if it's valid. Otherwise. dump all |
89 | /// locations. |
90 | bool DumpLocations(Stream *s, lldb::DescriptionLevel level, |
91 | lldb::addr_t func_load_addr, lldb::addr_t file_addr, |
92 | ABI *abi) const; |
93 | |
94 | /// Dump all locaitons with each seperated by new line. |
95 | void GetDescription(Stream *s, lldb::DescriptionLevel level, ABI *abi) const; |
96 | |
97 | /// Search for a load address in the dwarf location list |
98 | /// |
99 | /// \param[in] func_load_addr |
100 | /// The actual address of the function containing this location list. |
101 | /// |
102 | /// \param[in] addr |
103 | /// The address to resolve. |
104 | /// |
105 | /// \return |
106 | /// True if IsLocationList() is true and the address was found; |
107 | /// false otherwise. |
108 | // bool |
109 | // LocationListContainsLoadAddress (Process* process, const Address &addr) |
110 | // const; |
111 | // |
112 | bool ContainsAddress(lldb::addr_t func_load_addr, lldb::addr_t addr) const; |
113 | |
114 | void SetModule(const lldb::ModuleSP &module) { m_module_wp = module; } |
115 | |
116 | bool Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx, |
117 | lldb::addr_t func_load_addr, const Value *initial_value_ptr, |
118 | const Value *object_address_ptr, Value &result, |
119 | Status *error_ptr) const; |
120 | |
121 | private: |
122 | // RangeDataVector requires a comparator for DWARFExpression, but it doesn't |
123 | // make sense to do so. |
124 | struct DWARFExpressionCompare { |
125 | public: |
126 | bool operator()(const DWARFExpression &lhs, |
127 | const DWARFExpression &rhs) const { |
128 | return false; |
129 | } |
130 | }; |
131 | using ExprVec = RangeDataVector<lldb::addr_t, lldb::addr_t, DWARFExpression, |
132 | 0, DWARFExpressionCompare>; |
133 | using Entry = ExprVec::Entry; |
134 | |
135 | // File address range mapping to single dwarf expression. |
136 | ExprVec m_exprs; |
137 | |
138 | /// Module which defined this expression. |
139 | lldb::ModuleWP m_module_wp; |
140 | |
141 | /// The DWARF compile unit this expression belongs to. It is used to evaluate |
142 | /// values indexing into the .debug_addr section (e.g. DW_OP_GNU_addr_index, |
143 | /// DW_OP_GNU_const_index) |
144 | const plugin::dwarf::DWARFUnit *m_dwarf_cu = nullptr; |
145 | |
146 | // Function base file address. |
147 | lldb::addr_t m_func_file_addr = LLDB_INVALID_ADDRESS; |
148 | |
149 | using const_iterator = ExprVec::Collection::const_iterator; |
150 | const_iterator begin() const { return m_exprs.begin(); } |
151 | const_iterator end() const { return m_exprs.end(); } |
152 | }; |
153 | } // namespace lldb_private |
154 | |
155 | #endif // LLDB_EXPRESSION_DWARFEXPRESSIONLIST_H |
156 | |