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