Home | History | Annotate | Download | only in Symbol
      1 //===-- DWARFCallFrameInfo.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_DWARFCallFrameInfo_h_
     11 #define liblldb_DWARFCallFrameInfo_h_
     12 
     13 #include <map>
     14 
     15 #include "lldb/Core/AddressRange.h"
     16 #include "lldb/Core/DataExtractor.h"
     17 #include "lldb/Core/Flags.h"
     18 #include "lldb/Core/RangeMap.h"
     19 #include "lldb/Core/VMRange.h"
     20 #include "lldb/Core/dwarf.h"
     21 #include "lldb/Host/Mutex.h"
     22 #include "lldb/Symbol/ObjectFile.h"
     23 #include "lldb/Symbol/UnwindPlan.h"
     24 #include "lldb/lldb-private.h"
     25 
     26 namespace lldb_private {
     27 
     28 // DWARFCallFrameInfo is a class which can read eh_frame and DWARF
     29 // Call Frame Information FDEs.  It stores little information internally.
     30 // Only two APIs are exported - one to find the high/low pc values
     31 // of a function given a text address via the information in the
     32 // eh_frame / debug_frame, and one to generate an UnwindPlan based
     33 // on the FDE in the eh_frame / debug_frame section.
     34 
     35 class DWARFCallFrameInfo
     36 {
     37 public:
     38 
     39     DWARFCallFrameInfo (ObjectFile& objfile,
     40                         lldb::SectionSP& section,
     41                         lldb::RegisterKind reg_kind,
     42                         bool is_eh_frame);
     43 
     44     ~DWARFCallFrameInfo();
     45 
     46     // Locate an AddressRange that includes the provided Address in this
     47     // object's eh_frame/debug_info
     48     // Returns true if a range is found to cover that address.
     49     bool
     50     GetAddressRange (Address addr, AddressRange &range);
     51 
     52     // Return an UnwindPlan based on the call frame information encoded
     53     // in the FDE of this DWARFCallFrameInfo section.
     54     bool
     55     GetUnwindPlan (Address addr, UnwindPlan& unwind_plan);
     56 
     57     typedef RangeVector<lldb::addr_t, uint32_t> FunctionAddressAndSizeVector;
     58 
     59     //------------------------------------------------------------------
     60     // Build a vector of file address and size for all functions in this Module
     61     // based on the eh_frame FDE entries.
     62     //
     63     // The eh_frame information can be a useful source of file address and size of
     64     // the functions in a Module.  Often a binary's non-exported symbols are stripped
     65     // before shipping so lldb won't know the start addr / size of many functions
     66     // in the Module.  But the eh_frame can help to give the addresses of these
     67     // stripped symbols, at least.
     68     //
     69     // @param[out] function_info
     70     //      A vector provided by the caller is filled out.  May be empty if no FDEs/no eh_frame
     71     //      is present in this Module.
     72 
     73     void
     74     GetFunctionAddressAndSizeVector (FunctionAddressAndSizeVector &function_info);
     75 
     76 private:
     77     enum
     78     {
     79         CFI_AUG_MAX_SIZE = 8,
     80         CFI_HEADER_SIZE = 8
     81     };
     82 
     83     struct CIE
     84     {
     85         dw_offset_t cie_offset;
     86         uint8_t     version;
     87         char        augmentation[CFI_AUG_MAX_SIZE];  // This is typically empty or very short.
     88         uint32_t    code_align;
     89         int32_t     data_align;
     90         uint32_t    return_addr_reg_num;
     91         dw_offset_t inst_offset;        // offset of CIE instructions in mCFIData
     92         uint32_t    inst_length;        // length of CIE instructions in mCFIData
     93         uint8_t     ptr_encoding;
     94         lldb_private::UnwindPlan::Row initial_row;
     95 
     96         CIE(dw_offset_t offset) : cie_offset(offset), version (-1), code_align (0),
     97                                   data_align (0), return_addr_reg_num (LLDB_INVALID_REGNUM), inst_offset (0),
     98                                   inst_length (0), ptr_encoding (0), initial_row() {}
     99     };
    100 
    101     typedef std::shared_ptr<CIE> CIESP;
    102 
    103     typedef std::map<off_t, CIESP> cie_map_t;
    104 
    105     // Start address (file address), size, offset of FDE location
    106     // used for finding an FDE for a given File address; the start address field is
    107     // an offset into an individual Module.
    108     typedef RangeDataVector<lldb::addr_t, uint32_t, dw_offset_t> FDEEntryMap;
    109 
    110     bool
    111     IsEHFrame() const;
    112 
    113     bool
    114     GetFDEEntryByFileAddress (lldb::addr_t file_offset, FDEEntryMap::Entry& fde_entry);
    115 
    116     void
    117     GetFDEIndex ();
    118 
    119     bool
    120     FDEToUnwindPlan (uint32_t offset, Address startaddr, UnwindPlan& unwind_plan);
    121 
    122     const CIE*
    123     GetCIE(dw_offset_t cie_offset);
    124 
    125     void
    126     GetCFIData();
    127 
    128     ObjectFile&                 m_objfile;
    129     lldb::SectionSP             m_section_sp;
    130     lldb::RegisterKind          m_reg_kind;
    131     Flags                       m_flags;
    132     cie_map_t                   m_cie_map;
    133 
    134     DataExtractor               m_cfi_data;
    135     bool                        m_cfi_data_initialized;   // only copy the section into the DE once
    136 
    137     FDEEntryMap                 m_fde_index;
    138     bool                        m_fde_index_initialized;  // only scan the section for FDEs once
    139     Mutex                       m_fde_index_mutex;        // and isolate the thread that does it
    140 
    141     bool                        m_is_eh_frame;
    142 
    143     CIESP
    144     ParseCIE (const uint32_t cie_offset);
    145 
    146 };
    147 
    148 } // namespace lldb_private
    149 
    150 #endif  // liblldb_DWARFCallFrameInfo_h_
    151