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