DWARFCallFrameInfo.h revision c953b5647a8c451113c21e0e367194cad9efeb0e
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
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    // Start address, size, offset of FDE location
85    // used for finding an FDE for a given File address; the start address field is
86    // an offset into an individual Module.
87    typedef RangeDataVector<lldb::addr_t, uint32_t, dw_offset_t> FDEEntryMap;
88
89    typedef std::map<off_t, CIESP> cie_map_t;
90
91    bool
92    IsEHFrame() const;
93
94    bool
95    GetFDEEntryByFileAddress (lldb::addr_t file_offset, FDEEntryMap::Entry& fde_entry);
96
97    void
98    GetFDEIndex ();
99
100    bool
101    FDEToUnwindPlan (uint32_t offset, Address startaddr, UnwindPlan& unwind_plan);
102
103    const CIE*
104    GetCIE(dw_offset_t cie_offset);
105
106    void
107    GetCFIData();
108
109    ObjectFile&                 m_objfile;
110    lldb::SectionSP             m_section_sp;
111    lldb::RegisterKind          m_reg_kind;
112    Flags                       m_flags;
113    cie_map_t                   m_cie_map;
114
115    DataExtractor               m_cfi_data;
116    bool                        m_cfi_data_initialized;   // only copy the section into the DE once
117
118    FDEEntryMap                 m_fde_index;
119    bool                        m_fde_index_initialized;  // only scan the section for FDEs once
120    Mutex                       m_fde_index_mutex;        // and isolate the thread that does it
121
122    bool                        m_is_eh_frame;
123
124    CIESP
125    ParseCIE (const uint32_t cie_offset);
126
127};
128
129} // namespace lldb_private
130
131#endif  // liblldb_DWARFCallFrameInfo_h_
132