aboutsummaryrefslogtreecommitdiffstats
path: root/include/lldb/Symbol/SymbolContext.h
blob: 76ec1a7de68ef94b2f4a1106e8475fc09178281e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
//===-- SymbolContext.h -----------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef liblldb_SymbolContext_h_
#define liblldb_SymbolContext_h_

#include <memory>
#include <string>
#include <vector>

#include "lldb/Core/Address.h"
#include "lldb/Core/Mangled.h"
#include "lldb/Symbol/LineEntry.h"
#include "lldb/Utility/Iterable.h"
#include "lldb/lldb-private.h"

namespace lldb_private {

class SymbolContextScope;

/// \class SymbolContext SymbolContext.h "lldb/Symbol/SymbolContext.h" Defines
/// a symbol context baton that can be handed other debug core functions.
///
/// Many debugger functions require a context when doing lookups. This class
/// provides a common structure that can be used as the result of a query that
/// can contain a single result. Examples of such queries include
///     \li Looking up a load address.
class SymbolContext {
public:
  /// Default constructor.
  ///
  /// Initialize all pointer members to nullptr and all struct members to
  /// their default state.
  SymbolContext();

  /// Construct with an object that knows how to reconstruct its symbol
  /// context.
  ///
  /// \param[in] sc_scope
  ///     A symbol context scope object that knows how to reconstruct
  ///     it's context.
  explicit SymbolContext(SymbolContextScope *sc_scope);

  /// Construct with module, and optional compile unit, function, block, line
  /// table, line entry and symbol.
  ///
  /// Initialize all pointer to the specified values.
  ///
  /// \param[in] module
  ///     A Module pointer to the module for this context.
  ///
  /// \param[in] comp_unit
  ///     A CompileUnit pointer to the compile unit for this context.
  ///
  /// \param[in] function
  ///     A Function pointer to the function for this context.
  ///
  /// \param[in] block
  ///     A Block pointer to the deepest block for this context.
  ///
  /// \param[in] line_entry
  ///     A LineEntry pointer to the line entry for this context.
  ///
  /// \param[in] symbol
  ///     A Symbol pointer to the symbol for this context.
  explicit SymbolContext(const lldb::TargetSP &target_sp,
                         const lldb::ModuleSP &module_sp,
                         CompileUnit *comp_unit = nullptr,
                         Function *function = nullptr, Block *block = nullptr,
                         LineEntry *line_entry = nullptr,
                         Symbol *symbol = nullptr);

  // This version sets the target to a NULL TargetSP if you don't know it.
  explicit SymbolContext(const lldb::ModuleSP &module_sp,
                         CompileUnit *comp_unit = nullptr,
                         Function *function = nullptr, Block *block = nullptr,
                         LineEntry *line_entry = nullptr,
                         Symbol *symbol = nullptr);

  ~SymbolContext();

  /// Assignment operator.
  ///
  /// Copies the address value from another SymbolContext object \a rhs into
  /// \a this object.
  ///
  /// \param[in] rhs
  ///     A const SymbolContext object reference to copy.
  ///
  /// \return
  ///     A const SymbolContext object reference to \a this.
  const SymbolContext &operator=(const SymbolContext &rhs);

  /// Clear the object's state.
  ///
  /// Resets all pointer members to nullptr, and clears any class objects to
  /// their default state.
  void Clear(bool clear_target);

  /// Dump a description of this object to a Stream.
  ///
  /// Dump a description of the contents of this object to the supplied stream
  /// \a s.
  ///
  /// \param[in] s
  ///     The stream to which to dump the object description.
  void Dump(Stream *s, Target *target) const;

  /// Dump the stop context in this object to a Stream.
  ///
  /// Dump the best description of this object to the stream. The information
  /// displayed depends on the amount and quality of the information in this
  /// context. If a module, function, file and line number are available, they
  /// will be dumped. If only a module and function or symbol name with offset
  /// is available, that will be output. Else just the address at which the
  /// target was stopped will be displayed.
  ///
  /// \param[in] s
  ///     The stream to which to dump the object description.
  ///
  /// \param[in] so_addr
  ///     The resolved section offset address.
  ///
  /// \param[in] show_fullpaths
  ///     When printing file paths (with the Module), whether the
  ///     base name of the Module should be printed or the full path.
  ///
  /// \param[in] show_module
  ///     Whether the module name should be printed followed by a
  ///     grave accent "`" character.
  ///
  /// \param[in] show_inlined_frames
  ///     If a given pc is in inlined function(s), whether the inlined
  ///     functions should be printed on separate lines in addition to
  ///     the concrete function containing the pc.
  ///
  /// \param[in] show_function_arguments
  ///     If false, this method will try to elide the function argument
  ///     types when printing the function name.  This may be ambiguous
  ///     for languages that have function overloading - but it may
  ///     make the "function name" too long to include all the argument
  ///     types.
  ///
  /// \param[in] show_function_name
  ///     Normally this should be true - the function/symbol name should
  ///     be printed.  In disassembly formatting, where we want a format
  ///     like "<*+36>", this should be false and "*" will be printed
  ///     instead.
  bool DumpStopContext(Stream *s, ExecutionContextScope *exe_scope,
                       const Address &so_addr, bool show_fullpaths,
                       bool show_module, bool show_inlined_frames,
                       bool show_function_arguments,
                       bool show_function_name) const;

  /// Get the address range contained within a symbol context.
  ///
  /// Address range priority is as follows:
  ///     - line_entry address range if line_entry is valid and
  ///     eSymbolContextLineEntry is set in \a scope
  ///     - block address range if block is not nullptr and eSymbolContextBlock
  ///     is set in \a scope
  ///     - function address range if function is not nullptr and
  ///     eSymbolContextFunction is set in \a scope
  ///     - symbol address range if symbol is not nullptr and
  ///     eSymbolContextSymbol is set in \a scope
  ///
  /// \param[in] scope
  ///     A mask of symbol context bits telling this function which
  ///     address ranges it can use when trying to extract one from
  ///     the valid (non-nullptr) symbol context classes.
  ///
  /// \param[in] range_idx
  ///     The address range index to grab. Since many functions and
  ///     blocks are not always contiguous, they may have more than
  ///     one address range.
  ///
  /// \param[in] use_inline_block_range
  ///     If \a scope has the eSymbolContextBlock bit set, and there
  ///     is a valid block in the symbol context, return the block
  ///     address range for the containing inline function block, not
  ///     the deepest most block. This allows us to extract information
  ///     for the address range of the inlined function block, not
  ///     the deepest lexical block.
  ///
  /// \param[out] range
  ///     An address range object that will be filled in if \b true
  ///     is returned.
  ///
  /// \return
  ///     \b True if this symbol context contains items that describe
  ///     an address range, \b false otherwise.
  bool GetAddressRange(uint32_t scope, uint32_t range_idx,
                       bool use_inline_block_range, AddressRange &range) const;

  bool GetAddressRangeFromHereToEndLine(uint32_t end_line, AddressRange &range,
                                        Status &error);

  /// Find the best global data symbol visible from this context.
  ///
  /// Symbol priority is:
  ///     - extern symbol in the current module if there is one
  ///     - non-extern symbol in the current module if there is one
  ///     - extern symbol in the target
  ///     - non-extern symbol in the target
  /// It is an error if the highest-priority result is ambiguous.
  ///
  /// \param[in] name
  ///     The name of the symbol to search for.
  ///
  /// \param[out] error
  ///     An error that will be populated with a message if there was an
  ///     ambiguous result.  The error will not be populated if no result
  ///     was found.
  ///
  /// \return
  ///     The symbol that was found, or \b nullptr if none was found.
  const Symbol *FindBestGlobalDataSymbol(ConstString name, Status &error);

  void GetDescription(Stream *s, lldb::DescriptionLevel level,
                      Target *target) const;

  uint32_t GetResolvedMask() const;

  lldb::LanguageType GetLanguage() const;

  /// Find a block that defines the function represented by this symbol
  /// context.
  ///
  /// If this symbol context points to a block that is an inlined function, or
  /// is contained within an inlined function, the block that defines the
  /// inlined function is returned.
  ///
  /// If this symbol context has no block in it, or the block is not itself an
  /// inlined function block or contained within one, we return the top level
  /// function block.
  ///
  /// This is a handy function to call when you want to get the block whose
  /// variable list will include the arguments for the function that is
  /// represented by this symbol context (whether the function is an inline
  /// function or not).
  ///
  /// \return
  ///     The block object pointer that defines the function that is
  ///     represented by this symbol context object, nullptr otherwise.
  Block *GetFunctionBlock();

  /// If this symbol context represents a function that is a method, return
  /// true and provide information about the method.
  ///
  /// \param[out] language
  ///     If \b true is returned, the language for the method.
  ///
  /// \param[out] is_instance_method
  ///     If \b true is returned, \b true if this is a instance method,
  ///     \b false if this is a static/class function.
  ///
  /// \param[out] language_object_name
  ///     If \b true is returned, the name of the artificial variable
  ///     for the language ("this" for C++, "self" for ObjC).
  ///
  /// \return
  ///     \b True if this symbol context represents a function that
  ///     is a method of a class, \b false otherwise.
  bool GetFunctionMethodInfo(lldb::LanguageType &language,
                             bool &is_instance_method,
                             ConstString &language_object_name);

  /// Sorts the types in TypeMap according to SymbolContext to TypeList
  ///
  void SortTypeList(TypeMap &type_map, TypeList &type_list) const;

  /// Find a name of the innermost function for the symbol context.
  ///
  /// For instance, if the symbol context contains an inlined block, it will
  /// return the inlined function name.
  ///
  /// \param[in] prefer_mangled
  ///    if \btrue, then the mangled name will be returned if there
  ///    is one.  Otherwise the unmangled name will be returned if it
  ///    is available.
  ///
  /// \return
  ///     The name of the function represented by this symbol context.
  ConstString GetFunctionName(
      Mangled::NamePreference preference = Mangled::ePreferDemangled) const;

  /// Get the line entry that corresponds to the function.
  ///
  /// If the symbol context contains an inlined block, the line entry for the
  /// start address of the inlined function will be returned, otherwise the
  /// line entry for the start address of the function will be returned. This
  /// can be used after doing a Module::FindFunctions(...) or
  /// ModuleList::FindFunctions(...) call in order to get the correct line
  /// table information for the symbol context. it will return the inlined
  /// function name.
  ///
  /// \param[in] prefer_mangled
  ///    if \btrue, then the mangled name will be returned if there
  ///    is one.  Otherwise the unmangled name will be returned if it
  ///    is available.
  ///
  /// \return
  ///     The name of the function represented by this symbol context.
  LineEntry GetFunctionStartLineEntry() const;

  /// Find the block containing the inlined block that contains this block.
  ///
  /// For instance, if the symbol context contains an inlined block, it will
  /// return the inlined function name.
  ///
  /// \param[in] curr_frame_pc
  ///    The address within the block of this object.
  ///
  /// \param[out] next_frame_sc
  ///     A new symbol context that does what the title says it does.
  ///
  /// \param[out] next_frame_addr
  ///     This is what you should report as the PC in \a next_frame_sc.
  ///
  /// \return
  ///     \b true if this SymbolContext specifies a block contained in an
  ///     inlined block.  If this returns \b true, \a next_frame_sc and
  ///     \a next_frame_addr will be filled in correctly.
  bool GetParentOfInlinedScope(const Address &curr_frame_pc,
                               SymbolContext &next_frame_sc,
                               Address &inlined_frame_addr) const;

  // Member variables
  lldb::TargetSP target_sp; ///< The Target for a given query
  lldb::ModuleSP module_sp; ///< The Module for a given query
  CompileUnit *comp_unit;   ///< The CompileUnit for a given query
  Function *function;       ///< The Function for a given query
  Block *block;             ///< The Block for a given query
  LineEntry line_entry;     ///< The LineEntry for a given query
  Symbol *symbol;           ///< The Symbol for a given query
  Variable *variable;       ///< The global variable matching the given query
};

class SymbolContextSpecifier {
public:
  enum SpecificationType {
    eNothingSpecified = 0,
    eModuleSpecified = 1 << 0,
    eFileSpecified = 1 << 1,
    eLineStartSpecified = 1 << 2,
    eLineEndSpecified = 1 << 3,
    eFunctionSpecified = 1 << 4,
    eClassOrNamespaceSpecified = 1 << 5,
    eAddressRangeSpecified = 1 << 6
  };

  // This one produces a specifier that matches everything...
  SymbolContextSpecifier(const lldb::TargetSP &target_sp);

  ~SymbolContextSpecifier();

  bool AddSpecification(const char *spec_string, SpecificationType type);

  bool AddLineSpecification(uint32_t line_no, SpecificationType type);

  void Clear();

  bool SymbolContextMatches(SymbolContext &sc);

  bool AddressMatches(lldb::addr_t addr);

  void GetDescription(Stream *s, lldb::DescriptionLevel level) const;

private:
  lldb::TargetSP m_target_sp;
  std::string m_module_spec;
  lldb::ModuleSP m_module_sp;
  std::unique_ptr<FileSpec> m_file_spec_up;
  size_t m_start_line;
  size_t m_end_line;
  std::string m_function_spec;
  std::string m_class_name;
  std::unique_ptr<AddressRange> m_address_range_up;
  uint32_t m_type; // Or'ed bits from SpecificationType
};

/// \class SymbolContextList SymbolContext.h "lldb/Symbol/SymbolContext.h"
/// Defines a list of symbol context objects.
///
/// This class provides a common structure that can be used to contain the
/// result of a query that can contain a multiple results. Examples of such
/// queries include:
///     \li Looking up a function by name.
///     \li Finding all addresses for a specified file and line number.
class SymbolContextList {
public:
  /// Default constructor.
  ///
  /// Initialize with an empty list.
  SymbolContextList();

  /// Destructor.
  ~SymbolContextList();

  /// Append a new symbol context to the list.
  ///
  /// \param[in] sc
  ///     A symbol context to append to the list.
  void Append(const SymbolContext &sc);

  void Append(const SymbolContextList &sc_list);

  bool AppendIfUnique(const SymbolContext &sc, bool merge_symbol_into_function);

  uint32_t AppendIfUnique(const SymbolContextList &sc_list,
                          bool merge_symbol_into_function);

  /// Clear the object's state.
  ///
  /// Clears the symbol context list.
  void Clear();

  /// Dump a description of this object to a Stream.
  ///
  /// Dump a description of the contents of each symbol context in the list to
  /// the supplied stream \a s.
  ///
  /// \param[in] s
  ///     The stream to which to dump the object description.
  void Dump(Stream *s, Target *target) const;

  /// Get accessor for a symbol context at index \a idx.
  ///
  /// Dump a description of the contents of each symbol context in the list to
  /// the supplied stream \a s.
  ///
  /// \param[in] idx
  ///     The zero based index into the symbol context list.
  ///
  /// \param[out] sc
  ///     A reference to the symbol context to fill in.
  ///
  /// \return
  ///     Returns \b true if \a idx was a valid index into this
  ///     symbol context list and \a sc was filled in, \b false
  ///     otherwise.
  bool GetContextAtIndex(size_t idx, SymbolContext &sc) const;

  /// Direct reference accessor for a symbol context at index \a idx.
  ///
  /// The index \a idx must be a valid index, no error checking will be done
  /// to ensure that it is valid.
  ///
  /// \param[in] idx
  ///     The zero based index into the symbol context list.
  ///
  /// \return
  ///     A const reference to the symbol context to fill in.
  SymbolContext &operator[](size_t idx) { return m_symbol_contexts[idx]; }

  const SymbolContext &operator[](size_t idx) const {
    return m_symbol_contexts[idx];
  }

  bool RemoveContextAtIndex(size_t idx);

  /// Get accessor for a symbol context list size.
  ///
  /// \return
  ///     Returns the number of symbol context objects in the list.
  uint32_t GetSize() const;

  bool IsEmpty() const;

  uint32_t NumLineEntriesWithLine(uint32_t line) const;

  void GetDescription(Stream *s, lldb::DescriptionLevel level,
                      Target *target) const;

protected:
  typedef std::vector<SymbolContext>
      collection; ///< The collection type for the list.

  // Member variables.
  collection m_symbol_contexts; ///< The list of symbol contexts.

public:
  typedef AdaptedIterable<collection, SymbolContext, vector_adapter>
      SymbolContextIterable;
  SymbolContextIterable SymbolContexts() {
    return SymbolContextIterable(m_symbol_contexts);
  }
};

bool operator==(const SymbolContext &lhs, const SymbolContext &rhs);
bool operator!=(const SymbolContext &lhs, const SymbolContext &rhs);

bool operator==(const SymbolContextList &lhs, const SymbolContextList &rhs);
bool operator!=(const SymbolContextList &lhs, const SymbolContextList &rhs);

} // namespace lldb_private

#endif // liblldb_SymbolContext_h_