DWARFCallFrameInfo.h revision 13d24fb1817faa7ccc4cfd799113ba1a2b8968eb
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/lldb-private.h"
16#include "lldb/Core/DataExtractor.h"
17#include "lldb/Core/Flags.h"
18#include "lldb/Core/AddressRange.h"
19#include "lldb/Core/VMRange.h"
20#include "lldb/Core/dwarf.h"
21#include "lldb/Symbol/UnwindPlan.h"
22#include "lldb/Symbol/ObjectFile.h"
23
24namespace lldb_private {
25
26// DWARFCallFrameInfo is a class which can read eh_frame and DWARF
27// Call Frame Information FDEs.  It stores little information internally.
28// Only two APIs are exported - one to find the high/low pc values
29// of a function given a text address via the information in the
30// eh_frame / debug_frame, and one to generate an UnwindPlan based
31// on the FDE in the eh_frame / debug_frame section.
32
33class DWARFCallFrameInfo
34{
35public:
36
37    DWARFCallFrameInfo (ObjectFile& objfile,
38                        lldb::SectionSP& section,
39                        lldb::RegisterKind reg_kind,
40                        bool is_eh_frame);
41
42    ~DWARFCallFrameInfo();
43
44    // Locate an AddressRange that includes the provided Address in this
45    // object's eh_frame/debug_info
46    // Returns true if a range is found to cover that address.
47    bool
48    GetAddressRange (Address addr, AddressRange &range);
49
50    // Return an UnwindPlan based on the call frame information encoded
51    // in the FDE of this DWARFCallFrameInfo section.
52    bool
53    GetUnwindPlan (Address addr, UnwindPlan& unwind_plan);
54
55
56private:
57    enum
58    {
59        CFI_AUG_MAX_SIZE = 8,
60        CFI_HEADER_SIZE = 8
61    };
62
63    struct CIE
64    {
65        dw_offset_t cie_offset;
66        uint8_t     version;
67        char        augmentation[CFI_AUG_MAX_SIZE];  // This is typically empty or very short.
68        uint32_t    code_align;
69        int32_t     data_align;
70        uint32_t    return_addr_reg_num;
71        dw_offset_t inst_offset;        // offset of CIE instructions in mCFIData
72        uint32_t    inst_length;        // length of CIE instructions in mCFIData
73        uint8_t     ptr_encoding;
74        lldb_private::UnwindPlan::Row initial_row;
75
76        CIE(dw_offset_t offset) : cie_offset(offset), version (-1), code_align (0),
77                                  data_align (0), return_addr_reg_num (-1), inst_offset (0),
78                                  inst_length (0), ptr_encoding (0), initial_row() {}
79    };
80
81    typedef SHARED_PTR(CIE) CIESP;
82
83    struct FDEEntry
84    {
85        AddressRange bounds;   // function bounds
86        dw_offset_t offset;    // offset to this FDE within the Section
87
88        FDEEntry () : bounds (), offset (0) { }
89
90        inline bool
91        operator<(const DWARFCallFrameInfo::FDEEntry& b) const
92        {
93            if (bounds.GetBaseAddress().GetOffset() < b.bounds.GetBaseAddress().GetOffset())
94                return true;
95            else
96                return false;
97        }
98    };
99
100    typedef std::map<off_t, CIESP> cie_map_t;
101
102    bool
103    IsEHFrame() const;
104
105    bool
106    GetFDEEntryByAddress (Address addr, FDEEntry& fde_entry);
107
108    void
109    GetFDEIndex ();
110
111    bool
112    FDEToUnwindPlan (uint32_t offset, Address startaddr, UnwindPlan& unwind_plan);
113
114    const CIE*
115    GetCIE(dw_offset_t cie_offset);
116
117    void
118    GetCFIData();
119
120    ObjectFile&                 m_objfile;
121    lldb::SectionSP             m_section;
122    lldb::RegisterKind          m_reg_kind;
123    Flags                       m_flags;
124    cie_map_t                   m_cie_map;
125
126    DataExtractor               m_cfi_data;
127    bool                        m_cfi_data_initialized;   // only copy the section into the DE once
128
129    std::vector<FDEEntry>       m_fde_index;
130    bool                        m_fde_index_initialized;  // only scan the section for FDEs once
131
132    bool                        m_is_eh_frame;
133
134    CIESP
135    ParseCIE (const uint32_t cie_offset);
136
137};
138
139} // namespace lldb_private
140
141#endif  // liblldb_DWARFCallFrameInfo_h_
142