aboutsummaryrefslogtreecommitdiff
path: root/include/lldb/Symbol/SymbolContext.h
blob: c26b7a0b9a100c2c0cda0414c195a49be3f5fc9f (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
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
//===-- SymbolContext.h -----------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//


#ifndef liblldb_SymbolContext_h_
#define liblldb_SymbolContext_h_

#include <vector>

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

namespace lldb_private {

class SymbolContextScope;
//----------------------------------------------------------------------
/// @class SymbolContext SymbolContext.h "lldb/Symbol/SymbolContext.h"
/// @brief 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 NULL 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 = NULL,
                   Function *function = NULL,
                   Block *block = NULL,
                   LineEntry *line_entry = NULL,
                   Symbol *symbol = NULL);

    // 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 = NULL,
                   Function *function = NULL,
                   Block *block = NULL,
                   LineEntry *line_entry = NULL,
                   Symbol *symbol = NULL);

    ~SymbolContext ();
    //------------------------------------------------------------------
    /// Copy constructor
    ///
    /// Makes a copy of the another SymbolContext object \a rhs.
    ///
    /// @param[in] rhs
    ///     A const SymbolContext object reference to copy.
    //------------------------------------------------------------------
    SymbolContext (const SymbolContext& rhs);

    //------------------------------------------------------------------
    /// 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 NULL, 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.
    //------------------------------------------------------------------
    bool
    DumpStopContext (Stream *s,
                     ExecutionContextScope *exe_scope,
                     const Address &so_addr,
                     bool show_fullpaths,
                     bool show_module,
                     bool show_inlined_frames) 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 NULL and eSymbolContextBlock is set in \a scope
    ///     - function address range if function is not NULL and eSymbolContextFunction is set in \a scope
    ///     - symbol address range if symbol is not NULL 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-NULL) 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;


    void
    GetDescription(Stream *s, 
                   lldb::DescriptionLevel level, 
                   Target *target) const;
    
    uint32_t
    GetResolvedMask () 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, NULL 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);

    //------------------------------------------------------------------
    /// 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
};


class SymbolContextSpecifier
{
public:
    typedef 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
    } SpecificationType;
    
    // 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_ap;
    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_ap;
    uint32_t                       m_type; // Or'ed bits from SpecificationType

};

//----------------------------------------------------------------------
/// @class SymbolContextList SymbolContext.h "lldb/Symbol/SymbolContext.h"
/// @brief 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);

    bool
    MergeSymbolContextIntoFunctionContext (const SymbolContext& symbol_sc,
                                           uint32_t start_idx = 0,
                                           uint32_t stop_idx = UINT32_MAX);

    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];
    }

    //------------------------------------------------------------------
    /// Get accessor for the last symbol context in the list.
    ///
    /// @param[out] sc
    ///     A reference to the symbol context to fill in.
    ///
    /// @return
    ///     Returns \b true if \a sc was filled in, \b false if the
    ///     list is empty.
    //------------------------------------------------------------------
    bool
    GetLastContext(SymbolContext& sc) const;

    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;

    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_