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