1 | //===-- SymbolContext.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_SYMBOL_SYMBOLCONTEXT_H |
10 | #define LLDB_SYMBOL_SYMBOLCONTEXT_H |
11 | |
12 | #include <memory> |
13 | #include <string> |
14 | #include <vector> |
15 | |
16 | #include "lldb/Core/Address.h" |
17 | #include "lldb/Core/Mangled.h" |
18 | #include "lldb/Symbol/LineEntry.h" |
19 | #include "lldb/Utility/Iterable.h" |
20 | #include "lldb/lldb-private.h" |
21 | |
22 | namespace lldb_private { |
23 | |
24 | class SymbolContextScope; |
25 | |
26 | /// \class SymbolContext SymbolContext.h "lldb/Symbol/SymbolContext.h" Defines |
27 | /// a symbol context baton that can be handed other debug core functions. |
28 | /// |
29 | /// Many debugger functions require a context when doing lookups. This class |
30 | /// provides a common structure that can be used as the result of a query that |
31 | /// can contain a single result. Examples of such queries include |
32 | /// \li Looking up a load address. |
33 | class SymbolContext { |
34 | public: |
35 | /// Default constructor. |
36 | /// |
37 | /// Initialize all pointer members to nullptr and all struct members to |
38 | /// their default state. |
39 | SymbolContext(); |
40 | |
41 | /// Construct with an object that knows how to reconstruct its symbol |
42 | /// context. |
43 | /// |
44 | /// \param[in] sc_scope |
45 | /// A symbol context scope object that knows how to reconstruct |
46 | /// it's context. |
47 | explicit SymbolContext(SymbolContextScope *sc_scope); |
48 | |
49 | /// Construct with module, and optional compile unit, function, block, line |
50 | /// table, line entry and symbol. |
51 | /// |
52 | /// Initialize all pointer to the specified values. |
53 | /// |
54 | /// \param[in] module_sp |
55 | /// A Module pointer to the module for this context. |
56 | /// |
57 | /// \param[in] comp_unit |
58 | /// A CompileUnit pointer to the compile unit for this context. |
59 | /// |
60 | /// \param[in] function |
61 | /// A Function pointer to the function for this context. |
62 | /// |
63 | /// \param[in] block |
64 | /// A Block pointer to the deepest block for this context. |
65 | /// |
66 | /// \param[in] line_entry |
67 | /// A LineEntry pointer to the line entry for this context. |
68 | /// |
69 | /// \param[in] symbol |
70 | /// A Symbol pointer to the symbol for this context. |
71 | explicit SymbolContext(const lldb::TargetSP &target_sp, |
72 | const lldb::ModuleSP &module_sp, |
73 | CompileUnit *comp_unit = nullptr, |
74 | Function *function = nullptr, Block *block = nullptr, |
75 | LineEntry *line_entry = nullptr, |
76 | Symbol *symbol = nullptr); |
77 | |
78 | // This version sets the target to a NULL TargetSP if you don't know it. |
79 | explicit SymbolContext(const lldb::ModuleSP &module_sp, |
80 | CompileUnit *comp_unit = nullptr, |
81 | Function *function = nullptr, Block *block = nullptr, |
82 | LineEntry *line_entry = nullptr, |
83 | Symbol *symbol = nullptr); |
84 | |
85 | ~SymbolContext(); |
86 | |
87 | /// Clear the object's state. |
88 | /// |
89 | /// Resets all pointer members to nullptr, and clears any class objects to |
90 | /// their default state. |
91 | void Clear(bool clear_target); |
92 | |
93 | /// Dump a description of this object to a Stream. |
94 | /// |
95 | /// Dump a description of the contents of this object to the supplied stream |
96 | /// \a s. |
97 | /// |
98 | /// \param[in] s |
99 | /// The stream to which to dump the object description. |
100 | void Dump(Stream *s, Target *target) const; |
101 | |
102 | /// Dump the stop context in this object to a Stream. |
103 | /// |
104 | /// Dump the best description of this object to the stream. The information |
105 | /// displayed depends on the amount and quality of the information in this |
106 | /// context. If a module, function, file and line number are available, they |
107 | /// will be dumped. If only a module and function or symbol name with offset |
108 | /// is available, that will be output. Else just the address at which the |
109 | /// target was stopped will be displayed. |
110 | /// |
111 | /// \param[in] s |
112 | /// The stream to which to dump the object description. |
113 | /// |
114 | /// \param[in] so_addr |
115 | /// The resolved section offset address. |
116 | /// |
117 | /// \param[in] show_fullpaths |
118 | /// When printing file paths (with the Module), whether the |
119 | /// base name of the Module should be printed or the full path. |
120 | /// |
121 | /// \param[in] show_module |
122 | /// Whether the module name should be printed followed by a |
123 | /// grave accent "`" character. |
124 | /// |
125 | /// \param[in] show_inlined_frames |
126 | /// If a given pc is in inlined function(s), whether the inlined |
127 | /// functions should be printed on separate lines in addition to |
128 | /// the concrete function containing the pc. |
129 | /// |
130 | /// \param[in] show_function_arguments |
131 | /// If false, this method will try to elide the function argument |
132 | /// types when printing the function name. This may be ambiguous |
133 | /// for languages that have function overloading - but it may |
134 | /// make the "function name" too long to include all the argument |
135 | /// types. |
136 | /// |
137 | /// \param[in] show_function_name |
138 | /// Normally this should be true - the function/symbol name should |
139 | /// be printed. In disassembly formatting, where we want a format |
140 | /// like "<*+36>", this should be false and "*" will be printed |
141 | /// instead. |
142 | /// |
143 | /// \param[in] show_inline_callsite_line_info |
144 | /// When processing an inline block, the line info of the callsite |
145 | /// is dumped if this flag is \b true, otherwise the line info |
146 | /// of the actual inlined function is dumped. |
147 | /// |
148 | /// \return |
149 | /// \b true if some text was dumped, \b false otherwise. |
150 | bool DumpStopContext(Stream *s, ExecutionContextScope *exe_scope, |
151 | const Address &so_addr, bool show_fullpaths, |
152 | bool show_module, bool show_inlined_frames, |
153 | bool show_function_arguments, |
154 | bool show_function_name) const; |
155 | |
156 | /// Get the address range contained within a symbol context. |
157 | /// |
158 | /// Address range priority is as follows: |
159 | /// - line_entry address range if line_entry is valid and |
160 | /// eSymbolContextLineEntry is set in \a scope |
161 | /// - block address range if block is not nullptr and eSymbolContextBlock |
162 | /// is set in \a scope |
163 | /// - function address range if function is not nullptr and |
164 | /// eSymbolContextFunction is set in \a scope |
165 | /// - symbol address range if symbol is not nullptr and |
166 | /// eSymbolContextSymbol is set in \a scope |
167 | /// |
168 | /// \param[in] scope |
169 | /// A mask of symbol context bits telling this function which |
170 | /// address ranges it can use when trying to extract one from |
171 | /// the valid (non-nullptr) symbol context classes. |
172 | /// |
173 | /// \param[in] range_idx |
174 | /// The address range index to grab. Since many functions and |
175 | /// blocks are not always contiguous, they may have more than |
176 | /// one address range. |
177 | /// |
178 | /// \param[in] use_inline_block_range |
179 | /// If \a scope has the eSymbolContextBlock bit set, and there |
180 | /// is a valid block in the symbol context, return the block |
181 | /// address range for the containing inline function block, not |
182 | /// the deepest most block. This allows us to extract information |
183 | /// for the address range of the inlined function block, not |
184 | /// the deepest lexical block. |
185 | /// |
186 | /// \param[out] range |
187 | /// An address range object that will be filled in if \b true |
188 | /// is returned. |
189 | /// |
190 | /// \return |
191 | /// \b True if this symbol context contains items that describe |
192 | /// an address range, \b false otherwise. |
193 | bool GetAddressRange(uint32_t scope, uint32_t range_idx, |
194 | bool use_inline_block_range, AddressRange &range) const; |
195 | |
196 | bool GetAddressRangeFromHereToEndLine(uint32_t end_line, AddressRange &range, |
197 | Status &error); |
198 | |
199 | /// Find the best global data symbol visible from this context. |
200 | /// |
201 | /// Symbol priority is: |
202 | /// - extern symbol in the current module if there is one |
203 | /// - non-extern symbol in the current module if there is one |
204 | /// - extern symbol in the target |
205 | /// - non-extern symbol in the target |
206 | /// It is an error if the highest-priority result is ambiguous. |
207 | /// |
208 | /// \param[in] name |
209 | /// The name of the symbol to search for. |
210 | /// |
211 | /// \param[out] error |
212 | /// An error that will be populated with a message if there was an |
213 | /// ambiguous result. The error will not be populated if no result |
214 | /// was found. |
215 | /// |
216 | /// \return |
217 | /// The symbol that was found, or \b nullptr if none was found. |
218 | const Symbol *FindBestGlobalDataSymbol(ConstString name, Status &error); |
219 | |
220 | void GetDescription(Stream *s, lldb::DescriptionLevel level, |
221 | Target *target) const; |
222 | |
223 | uint32_t GetResolvedMask() const; |
224 | |
225 | lldb::LanguageType GetLanguage() const; |
226 | |
227 | /// Find a block that defines the function represented by this symbol |
228 | /// context. |
229 | /// |
230 | /// If this symbol context points to a block that is an inlined function, or |
231 | /// is contained within an inlined function, the block that defines the |
232 | /// inlined function is returned. |
233 | /// |
234 | /// If this symbol context has no block in it, or the block is not itself an |
235 | /// inlined function block or contained within one, we return the top level |
236 | /// function block. |
237 | /// |
238 | /// This is a handy function to call when you want to get the block whose |
239 | /// variable list will include the arguments for the function that is |
240 | /// represented by this symbol context (whether the function is an inline |
241 | /// function or not). |
242 | /// |
243 | /// \return |
244 | /// The block object pointer that defines the function that is |
245 | /// represented by this symbol context object, nullptr otherwise. |
246 | Block *GetFunctionBlock(); |
247 | |
248 | /// If this symbol context represents a function that is a method, return |
249 | /// true and provide information about the method. |
250 | /// |
251 | /// \param[out] language |
252 | /// If \b true is returned, the language for the method. |
253 | /// |
254 | /// \param[out] is_instance_method |
255 | /// If \b true is returned, \b true if this is a instance method, |
256 | /// \b false if this is a static/class function. |
257 | /// |
258 | /// \param[out] language_object_name |
259 | /// If \b true is returned, the name of the artificial variable |
260 | /// for the language ("this" for C++, "self" for ObjC). |
261 | /// |
262 | /// \return |
263 | /// \b True if this symbol context represents a function that |
264 | /// is a method of a class, \b false otherwise. |
265 | bool GetFunctionMethodInfo(lldb::LanguageType &language, |
266 | bool &is_instance_method, |
267 | ConstString &language_object_name); |
268 | |
269 | /// Sorts the types in TypeMap according to SymbolContext to TypeList |
270 | /// |
271 | void SortTypeList(TypeMap &type_map, TypeList &type_list) const; |
272 | |
273 | /// Find a name of the innermost function for the symbol context. |
274 | /// |
275 | /// For instance, if the symbol context contains an inlined block, it will |
276 | /// return the inlined function name. |
277 | /// |
278 | /// \return |
279 | /// The name of the function represented by this symbol context. |
280 | ConstString GetFunctionName( |
281 | Mangled::NamePreference preference = Mangled::ePreferDemangled) const; |
282 | |
283 | /// Get the line entry that corresponds to the function. |
284 | /// |
285 | /// If the symbol context contains an inlined block, the line entry for the |
286 | /// start address of the inlined function will be returned, otherwise the |
287 | /// line entry for the start address of the function will be returned. This |
288 | /// can be used after doing a Module::FindFunctions(...) or |
289 | /// ModuleList::FindFunctions(...) call in order to get the correct line |
290 | /// table information for the symbol context. it will return the inlined |
291 | /// function name. |
292 | LineEntry GetFunctionStartLineEntry() const; |
293 | |
294 | /// Find the block containing the inlined block that contains this block. |
295 | /// |
296 | /// For instance, if the symbol context contains an inlined block, it will |
297 | /// return the inlined function name. |
298 | /// |
299 | /// \param[in] curr_frame_pc |
300 | /// The address within the block of this object. |
301 | /// |
302 | /// \param[out] next_frame_sc |
303 | /// A new symbol context that does what the title says it does. |
304 | /// |
305 | /// \param[out] inlined_frame_addr |
306 | /// This is what you should report as the PC in \a next_frame_sc. |
307 | /// |
308 | /// \return |
309 | /// \b true if this SymbolContext specifies a block contained in an |
310 | /// inlined block. If this returns \b true, \a next_frame_sc and |
311 | /// \a inlined_frame_addr will be filled in correctly. |
312 | bool GetParentOfInlinedScope(const Address &curr_frame_pc, |
313 | SymbolContext &next_frame_sc, |
314 | Address &inlined_frame_addr) const; |
315 | |
316 | // Member variables |
317 | lldb::TargetSP target_sp; ///< The Target for a given query |
318 | lldb::ModuleSP module_sp; ///< The Module for a given query |
319 | CompileUnit *comp_unit; ///< The CompileUnit for a given query |
320 | Function *function; ///< The Function for a given query |
321 | Block *block; ///< The Block for a given query |
322 | LineEntry line_entry; ///< The LineEntry for a given query |
323 | Symbol *symbol; ///< The Symbol for a given query |
324 | Variable *variable; ///< The global variable matching the given query |
325 | }; |
326 | |
327 | class SymbolContextSpecifier { |
328 | public: |
329 | enum SpecificationType { |
330 | eNothingSpecified = 0, |
331 | eModuleSpecified = 1 << 0, |
332 | eFileSpecified = 1 << 1, |
333 | eLineStartSpecified = 1 << 2, |
334 | eLineEndSpecified = 1 << 3, |
335 | eFunctionSpecified = 1 << 4, |
336 | eClassOrNamespaceSpecified = 1 << 5, |
337 | eAddressRangeSpecified = 1 << 6 |
338 | }; |
339 | |
340 | // This one produces a specifier that matches everything... |
341 | SymbolContextSpecifier(const lldb::TargetSP &target_sp); |
342 | |
343 | ~SymbolContextSpecifier(); |
344 | |
345 | bool AddSpecification(const char *spec_string, SpecificationType type); |
346 | |
347 | bool AddLineSpecification(uint32_t line_no, SpecificationType type); |
348 | |
349 | void Clear(); |
350 | |
351 | bool SymbolContextMatches(const SymbolContext &sc); |
352 | |
353 | bool AddressMatches(lldb::addr_t addr); |
354 | |
355 | void GetDescription(Stream *s, lldb::DescriptionLevel level) const; |
356 | |
357 | private: |
358 | lldb::TargetSP m_target_sp; |
359 | std::string m_module_spec; |
360 | lldb::ModuleSP m_module_sp; |
361 | std::unique_ptr<FileSpec> m_file_spec_up; |
362 | size_t m_start_line; |
363 | size_t m_end_line; |
364 | std::string m_function_spec; |
365 | std::string m_class_name; |
366 | std::unique_ptr<AddressRange> m_address_range_up; |
367 | uint32_t m_type; // Or'ed bits from SpecificationType |
368 | }; |
369 | |
370 | /// \class SymbolContextList SymbolContext.h "lldb/Symbol/SymbolContext.h" |
371 | /// Defines a list of symbol context objects. |
372 | /// |
373 | /// This class provides a common structure that can be used to contain the |
374 | /// result of a query that can contain a multiple results. Examples of such |
375 | /// queries include: |
376 | /// \li Looking up a function by name. |
377 | /// \li Finding all addresses for a specified file and line number. |
378 | class SymbolContextList { |
379 | public: |
380 | /// Default constructor. |
381 | /// |
382 | /// Initialize with an empty list. |
383 | SymbolContextList(); |
384 | |
385 | /// Destructor. |
386 | ~SymbolContextList(); |
387 | |
388 | /// Append a new symbol context to the list. |
389 | /// |
390 | /// \param[in] sc |
391 | /// A symbol context to append to the list. |
392 | void Append(const SymbolContext &sc); |
393 | |
394 | void Append(const SymbolContextList &sc_list); |
395 | |
396 | bool AppendIfUnique(const SymbolContext &sc, bool merge_symbol_into_function); |
397 | |
398 | uint32_t AppendIfUnique(const SymbolContextList &sc_list, |
399 | bool merge_symbol_into_function); |
400 | |
401 | /// Clear the object's state. |
402 | /// |
403 | /// Clears the symbol context list. |
404 | void Clear(); |
405 | |
406 | /// Dump a description of this object to a Stream. |
407 | /// |
408 | /// Dump a description of the contents of each symbol context in the list to |
409 | /// the supplied stream \a s. |
410 | /// |
411 | /// \param[in] s |
412 | /// The stream to which to dump the object description. |
413 | void Dump(Stream *s, Target *target) const; |
414 | |
415 | /// Get accessor for a symbol context at index \a idx. |
416 | /// |
417 | /// Dump a description of the contents of each symbol context in the list to |
418 | /// the supplied stream \a s. |
419 | /// |
420 | /// \param[in] idx |
421 | /// The zero based index into the symbol context list. |
422 | /// |
423 | /// \param[out] sc |
424 | /// A reference to the symbol context to fill in. |
425 | /// |
426 | /// \return |
427 | /// Returns \b true if \a idx was a valid index into this |
428 | /// symbol context list and \a sc was filled in, \b false |
429 | /// otherwise. |
430 | bool GetContextAtIndex(size_t idx, SymbolContext &sc) const; |
431 | |
432 | /// Direct reference accessor for a symbol context at index \a idx. |
433 | /// |
434 | /// The index \a idx must be a valid index, no error checking will be done |
435 | /// to ensure that it is valid. |
436 | /// |
437 | /// \param[in] idx |
438 | /// The zero based index into the symbol context list. |
439 | /// |
440 | /// \return |
441 | /// A const reference to the symbol context to fill in. |
442 | SymbolContext &operator[](size_t idx) { return m_symbol_contexts[idx]; } |
443 | |
444 | const SymbolContext &operator[](size_t idx) const { |
445 | return m_symbol_contexts[idx]; |
446 | } |
447 | |
448 | bool RemoveContextAtIndex(size_t idx); |
449 | |
450 | /// Get accessor for a symbol context list size. |
451 | /// |
452 | /// \return |
453 | /// Returns the number of symbol context objects in the list. |
454 | uint32_t GetSize() const; |
455 | |
456 | bool IsEmpty() const; |
457 | |
458 | uint32_t NumLineEntriesWithLine(uint32_t line) const; |
459 | |
460 | void GetDescription(Stream *s, lldb::DescriptionLevel level, |
461 | Target *target) const; |
462 | |
463 | protected: |
464 | typedef std::vector<SymbolContext> |
465 | collection; ///< The collection type for the list. |
466 | |
467 | // Member variables. |
468 | collection m_symbol_contexts; ///< The list of symbol contexts. |
469 | |
470 | public: |
471 | typedef AdaptedIterable<collection, SymbolContext, vector_adapter> |
472 | SymbolContextIterable; |
473 | SymbolContextIterable SymbolContexts() { |
474 | return SymbolContextIterable(m_symbol_contexts); |
475 | } |
476 | }; |
477 | |
478 | bool operator==(const SymbolContext &lhs, const SymbolContext &rhs); |
479 | bool operator!=(const SymbolContext &lhs, const SymbolContext &rhs); |
480 | |
481 | bool operator==(const SymbolContextList &lhs, const SymbolContextList &rhs); |
482 | bool operator!=(const SymbolContextList &lhs, const SymbolContextList &rhs); |
483 | |
484 | } // namespace lldb_private |
485 | |
486 | #endif // LLDB_SYMBOL_SYMBOLCONTEXT_H |
487 | |