DWARFCallFrameInfo.h revision 102b2c2681c9a830afe25bfea35557421905e42c
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
26namespace 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
35class DWARFCallFrameInfo
36{
37public:
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
76private:
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