Home | History | Annotate | Download | only in Expression
      1 //===-- DWARFExpression.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_DWARFExpression_h_
     11 #define liblldb_DWARFExpression_h_
     12 
     13 #include "lldb/lldb-private.h"
     14 #include "lldb/Core/ClangForward.h"
     15 #include "lldb/Core/Address.h"
     16 #include "lldb/Core/DataExtractor.h"
     17 #include "lldb/Core/Error.h"
     18 #include "lldb/Core/Scalar.h"
     19 
     20 namespace lldb_private {
     21 
     22 class ClangExpressionVariable;
     23 class ClangExpressionVariableList;
     24 
     25 class ClangExpressionDeclMap;
     26 
     27 //----------------------------------------------------------------------
     28 /// @class DWARFExpression DWARFExpression.h "lldb/Expression/DWARFExpression.h"
     29 /// @brief Encapsulates a DWARF location expression and interprets it.
     30 ///
     31 /// DWARF location expressions are used in two ways by LLDB.  The first
     32 /// use is to find entities specified in the debug information, since
     33 /// their locations are specified in precisely this language.  The second
     34 /// is to interpret expressions without having to run the target in cases
     35 /// where the overhead from copying JIT-compiled code into the target is
     36 /// too high or where the target cannot be run.  This class encapsulates
     37 /// a single DWARF location expression or a location list and interprets
     38 /// it.
     39 //----------------------------------------------------------------------
     40 class DWARFExpression
     41 {
     42 public:
     43     //------------------------------------------------------------------
     44     /// Constructor
     45     //------------------------------------------------------------------
     46     DWARFExpression();
     47 
     48     //------------------------------------------------------------------
     49     /// Constructor
     50     ///
     51     /// @param[in] data
     52     ///     A data extractor configured to read the DWARF location expression's
     53     ///     bytecode.
     54     ///
     55     /// @param[in] data_offset
     56     ///     The offset of the location expression in the extractor.
     57     ///
     58     /// @param[in] data_length
     59     ///     The byte length of the location expression.
     60     //------------------------------------------------------------------
     61     DWARFExpression(const DataExtractor& data,
     62                     lldb::offset_t data_offset,
     63                     lldb::offset_t data_length);
     64 
     65     //------------------------------------------------------------------
     66     /// Copy constructor
     67     //------------------------------------------------------------------
     68     DWARFExpression(const DWARFExpression& rhs);
     69 
     70     //------------------------------------------------------------------
     71     /// Destructor
     72     //------------------------------------------------------------------
     73     virtual
     74     ~DWARFExpression();
     75 
     76     //------------------------------------------------------------------
     77     /// Print the description of the expression to a stream
     78     ///
     79     /// @param[in] s
     80     ///     The stream to print to.
     81     ///
     82     /// @param[in] level
     83     ///     The level of verbosity to use.
     84     ///
     85     /// @param[in] location_list_base_addr
     86     ///     If this is a location list based expression, this is the
     87     ///     address of the object that owns it. NOTE: this value is
     88     ///     different from the DWARF version of the location list base
     89     ///     address which is compile unit relative. This base address
     90     ///     is the address of the object that owns the location list.
     91     ///
     92     /// @param[in] abi
     93     ///     An optional ABI plug-in that can be used to resolve register
     94     ///     names.
     95     //------------------------------------------------------------------
     96     void
     97     GetDescription (Stream *s,
     98                     lldb::DescriptionLevel level,
     99                     lldb::addr_t location_list_base_addr,
    100                     ABI *abi) const;
    101 
    102     //------------------------------------------------------------------
    103     /// Return true if the location expression contains data
    104     //------------------------------------------------------------------
    105     bool
    106     IsValid() const;
    107 
    108     //------------------------------------------------------------------
    109     /// Return true if a location list was provided
    110     //------------------------------------------------------------------
    111     bool
    112     IsLocationList() const;
    113 
    114     //------------------------------------------------------------------
    115     /// Search for a load address in the location list
    116     ///
    117     /// @param[in] process
    118     ///     The process to use when resolving the load address
    119     ///
    120     /// @param[in] addr
    121     ///     The address to resolve
    122     ///
    123     /// @return
    124     ///     True if IsLocationList() is true and the address was found;
    125     ///     false otherwise.
    126     //------------------------------------------------------------------
    127 //    bool
    128 //    LocationListContainsLoadAddress (Process* process, const Address &addr) const;
    129 //
    130     bool
    131     LocationListContainsAddress (lldb::addr_t loclist_base_addr, lldb::addr_t addr) const;
    132 
    133     //------------------------------------------------------------------
    134     /// If a location is not a location list, return true if the location
    135     /// contains a DW_OP_addr () opcode in the stream that matches \a
    136     /// file_addr. If file_addr is LLDB_INVALID_ADDRESS, the this
    137     /// function will return true if the variable there is any DW_OP_addr
    138     /// in a location that (yet still is NOT a location list). This helps
    139     /// us detect if a variable is a global or static variable since
    140     /// there is no other indication from DWARF debug info.
    141     ///
    142     /// @param[in] op_addr_idx
    143     ///     The DW_OP_addr index to retrieve in case there is more than
    144     ///     one DW_OP_addr opcode in the location byte stream.
    145     ///
    146     /// @param[out] error
    147     ///     If the location stream contains unknown DW_OP opcodes or the
    148     ///     data is missing, \a error will be set to \b true.
    149     ///
    150     /// @return
    151     ///     LLDB_INVALID_ADDRESS if the location doesn't contain a
    152     ///     DW_OP_addr for \a op_addr_idx, otherwise a valid file address
    153     //------------------------------------------------------------------
    154     lldb::addr_t
    155     GetLocation_DW_OP_addr (uint32_t op_addr_idx, bool &error) const;
    156 
    157     bool
    158     Update_DW_OP_addr (lldb::addr_t file_addr);
    159 
    160     //------------------------------------------------------------------
    161     /// Make the expression parser read its location information from a
    162     /// given data source.  Does not change the offset and length
    163     ///
    164     /// @param[in] data
    165     ///     A data extractor configured to read the DWARF location expression's
    166     ///     bytecode.
    167     //------------------------------------------------------------------
    168     void
    169     SetOpcodeData(const DataExtractor& data);
    170 
    171     //------------------------------------------------------------------
    172     /// Make the expression parser read its location information from a
    173     /// given data source
    174     ///
    175     /// @param[in] data
    176     ///     A data extractor configured to read the DWARF location expression's
    177     ///     bytecode.
    178     ///
    179     /// @param[in] data_offset
    180     ///     The offset of the location expression in the extractor.
    181     ///
    182     /// @param[in] data_length
    183     ///     The byte length of the location expression.
    184     //------------------------------------------------------------------
    185     void
    186     SetOpcodeData(const DataExtractor& data, lldb::offset_t data_offset, lldb::offset_t data_length);
    187 
    188     //------------------------------------------------------------------
    189     /// Copy the DWARF location expression into a local buffer.
    190     ///
    191     /// It is a good idea to copy the data so we don't keep the entire
    192     /// object file worth of data around just for a few bytes of location
    193     /// expression. LLDB typically will mmap the entire contents of debug
    194     /// information files, and if we use SetOpcodeData, it will get a
    195     /// shared reference to all of this data for the and cause the object
    196     /// file to have to stay around. Even worse, a very very large ".a"
    197     /// that contains one or more .o files could end up being referenced.
    198     /// Location lists are typically small so even though we are copying
    199     /// the data, it shouldn't amount to that much for the variables we
    200     /// end up parsing.
    201     ///
    202     /// @param[in] data
    203     ///     A data extractor configured to read and copy the DWARF
    204     ///     location expression's bytecode.
    205     ///
    206     /// @param[in] data_offset
    207     ///     The offset of the location expression in the extractor.
    208     ///
    209     /// @param[in] data_length
    210     ///     The byte length of the location expression.
    211     //------------------------------------------------------------------
    212     void
    213     CopyOpcodeData (const DataExtractor& data,
    214                     lldb::offset_t data_offset,
    215                     lldb::offset_t data_length);
    216 
    217 
    218     //------------------------------------------------------------------
    219     /// Tells the expression that it refers to a location list.
    220     ///
    221     /// @param[in] slide
    222     ///     This value should be a slide that is applied to any values
    223     ///     in the location list data so the values become zero based
    224     ///     offsets into the object that owns the location list. We need
    225     ///     to make location lists relative to the objects that own them
    226     ///     so we can relink addresses on the fly.
    227     //------------------------------------------------------------------
    228     void
    229     SetLocationListSlide (lldb::addr_t slide);
    230 
    231     //------------------------------------------------------------------
    232     /// Return the call-frame-info style register kind
    233     //------------------------------------------------------------------
    234     int
    235     GetRegisterKind ();
    236 
    237     //------------------------------------------------------------------
    238     /// Set the call-frame-info style register kind
    239     ///
    240     /// @param[in] reg_kind
    241     ///     The register kind.
    242     //------------------------------------------------------------------
    243     void
    244     SetRegisterKind (lldb::RegisterKind reg_kind);
    245 
    246     //------------------------------------------------------------------
    247     /// Wrapper for the static evaluate function that accepts an
    248     /// ExecutionContextScope instead of an ExecutionContext and uses
    249     /// member variables to populate many operands
    250     //------------------------------------------------------------------
    251     bool
    252     Evaluate (ExecutionContextScope *exe_scope,
    253               ClangExpressionVariableList *expr_locals,
    254               ClangExpressionDeclMap *decl_map,
    255               lldb::addr_t loclist_base_load_addr,
    256               const Value* initial_value_ptr,
    257               Value& result,
    258               Error *error_ptr) const;
    259 
    260     //------------------------------------------------------------------
    261     /// Wrapper for the static evaluate function that uses member
    262     /// variables to populate many operands
    263     //------------------------------------------------------------------
    264     bool
    265     Evaluate (ExecutionContext *exe_ctx,
    266               ClangExpressionVariableList *expr_locals,
    267               ClangExpressionDeclMap *decl_map,
    268               RegisterContext *reg_ctx,
    269               lldb::addr_t loclist_base_load_addr,
    270               const Value* initial_value_ptr,
    271               Value& result,
    272               Error *error_ptr) const;
    273 
    274     //------------------------------------------------------------------
    275     /// Evaluate a DWARF location expression in a particular context
    276     ///
    277     /// @param[in] exe_ctx
    278     ///     The execution context in which to evaluate the location
    279     ///     expression.  The location expression may access the target's
    280     ///     memory, especially if it comes from the expression parser.
    281     ///
    282     /// @param[in] opcodes
    283     ///     This is a static method so the opcodes need to be provided
    284     ///     explicitly.
    285     ///
    286     /// @param[in] expr_locals
    287     ///     If the location expression was produced by the expression parser,
    288     ///     the list of local variables referenced by the DWARF expression.
    289     ///     This list should already have been populated during parsing;
    290     ///     the DWARF expression refers to variables by index.  Can be NULL if
    291     ///     the location expression uses no locals.
    292     ///
    293     /// @param[in] decl_map
    294     ///     If the location expression was produced by the expression parser,
    295     ///     the list of external variables referenced by the location
    296     ///     expression.  Can be NULL if the location expression uses no
    297     ///     external variables.
    298     ///
    299     ///  @param[in] reg_ctx
    300     ///     An optional parameter which provides a RegisterContext for use
    301     ///     when evaluating the expression (i.e. for fetching register values).
    302     ///     Normally this will come from the ExecutionContext's StackFrame but
    303     ///     in the case where an expression needs to be evaluated while building
    304     ///     the stack frame list, this short-cut is available.
    305     ///
    306     /// @param[in] offset
    307     ///     The offset of the location expression in the data extractor.
    308     ///
    309     /// @param[in] length
    310     ///     The length in bytes of the location expression.
    311     ///
    312     /// @param[in] reg_set
    313     ///     The call-frame-info style register kind.
    314     ///
    315     /// @param[in] initial_value_ptr
    316     ///     A value to put on top of the interpreter stack before evaluating
    317     ///     the expression, if the expression is parametrized.  Can be NULL.
    318     ///
    319     /// @param[in] result
    320     ///     A value into which the result of evaluating the expression is
    321     ///     to be placed.
    322     ///
    323     /// @param[in] error_ptr
    324     ///     If non-NULL, used to report errors in expression evaluation.
    325     ///
    326     /// @return
    327     ///     True on success; false otherwise.  If error_ptr is non-NULL,
    328     ///     details of the failure are provided through it.
    329     //------------------------------------------------------------------
    330     static bool
    331     Evaluate (ExecutionContext *exe_ctx,
    332               ClangExpressionVariableList *expr_locals,
    333               ClangExpressionDeclMap *decl_map,
    334               RegisterContext *reg_ctx,
    335               const DataExtractor& opcodes,
    336               const lldb::offset_t offset,
    337               const lldb::offset_t length,
    338               const uint32_t reg_set,
    339               const Value* initial_value_ptr,
    340               Value& result,
    341               Error *error_ptr);
    342 
    343     //------------------------------------------------------------------
    344     /// Loads a ClangExpressionVariableList into the object
    345     ///
    346     /// @param[in] locals
    347     ///     If non-NULL, the list of locals used by this expression.
    348     ///     See Evaluate().
    349     //------------------------------------------------------------------
    350     void
    351     SetExpressionLocalVariableList (ClangExpressionVariableList *locals);
    352 
    353     //------------------------------------------------------------------
    354     /// Loads a ClangExpressionDeclMap into the object
    355     ///
    356     /// @param[in] locals
    357     ///     If non-NULL, the list of external variables used by this
    358     ///     expression.  See Evaluate().
    359     //------------------------------------------------------------------
    360     void
    361     SetExpressionDeclMap (ClangExpressionDeclMap *decl_map);
    362 
    363     bool
    364     GetExpressionData (DataExtractor &data) const
    365     {
    366         data = m_data;
    367         return data.GetByteSize() > 0;
    368     }
    369 
    370     bool
    371     DumpLocationForAddress (Stream *s,
    372                             lldb::DescriptionLevel level,
    373                             lldb::addr_t loclist_base_load_addr,
    374                             lldb::addr_t address,
    375                             ABI *abi);
    376 
    377 protected:
    378     //------------------------------------------------------------------
    379     /// Pretty-prints the location expression to a stream
    380     ///
    381     /// @param[in] stream
    382     ///     The stream to use for pretty-printing.
    383     ///
    384     /// @param[in] offset
    385     ///     The offset into the data buffer of the opcodes to be printed.
    386     ///
    387     /// @param[in] length
    388     ///     The length in bytes of the opcodes to be printed.
    389     ///
    390     /// @param[in] level
    391     ///     The level of detail to use in pretty-printing.
    392     ///
    393     /// @param[in] abi
    394     ///     An optional ABI plug-in that can be used to resolve register
    395     ///     names.
    396     //------------------------------------------------------------------
    397     void
    398     DumpLocation(Stream *s,
    399                  lldb::offset_t offset,
    400                  lldb::offset_t length,
    401                  lldb::DescriptionLevel level,
    402                  ABI *abi) const;
    403 
    404     bool
    405     GetLocation (lldb::addr_t base_addr,
    406                  lldb::addr_t pc,
    407                  lldb::offset_t &offset,
    408                  lldb::offset_t &len);
    409 
    410     //------------------------------------------------------------------
    411     /// Classes that inherit from DWARFExpression can see and modify these
    412     //------------------------------------------------------------------
    413 
    414     DataExtractor m_data;                       ///< A data extractor capable of reading opcode bytes
    415     lldb::RegisterKind m_reg_kind;              ///< One of the defines that starts with LLDB_REGKIND_
    416     lldb::addr_t m_loclist_slide;               ///< A value used to slide the location list offsets so that
    417                                                 ///< they are relative to the object that owns the location list
    418                                                 ///< (the function for frame base and variable location lists)
    419 
    420 };
    421 
    422 } // namespace lldb_private
    423 
    424 #endif  // liblldb_DWARFExpression_h_
    425