EhFrame.h revision 87f34658dec9097d987d254a990ea7f311bfc95f
1//===- EhFrame.h ----------------------------------------------------------===// 2// 3// The MCLinker Project 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9#ifndef MCLD_LD_EHFRAME_H 10#define MCLD_LD_EHFRAME_H 11#ifdef ENABLE_UNITTEST 12#include <gtest.h> 13#endif 14 15#include <mcld/Config/Config.h> 16#include <mcld/Fragment/RegionFragment.h> 17#include <mcld/LD/SectionData.h> 18#include <mcld/Support/Allocators.h> 19 20#include <llvm/ADT/StringRef.h> 21#include <list> 22#include <map> 23#include <set> 24#include <vector> 25 26namespace mcld { 27 28class Input; 29class Module; 30class LDSection; 31class ObjectLinker; 32class Relocation; 33 34/** \class EhFrame 35 * \brief EhFrame represents .eh_frame section 36 */ 37class EhFrame 38{ 39private: 40 friend class Chunk<EhFrame, MCLD_SECTIONS_PER_INPUT>; 41 42 EhFrame(); 43 explicit EhFrame(LDSection& pSection); 44 45 ~EhFrame(); 46 47 EhFrame(const EhFrame&); // DO NOT IMPLEMENT 48 EhFrame& operator=(const EhFrame&); // DO NOT IMPLEMENT 49 50public: 51 enum RecordType { 52 RECORD_UNKNOWN, 53 RECORD_INPUT, 54 RECORD_GENERATED 55 }; 56 57 class CIE; 58 class FDE; 59 60 typedef std::vector<CIE*> CIEList; 61 typedef CIEList::iterator cie_iterator; 62 typedef CIEList::const_iterator const_cie_iterator; 63 64 typedef std::list<FDE*> FDEList; 65 typedef FDEList::iterator fde_iterator; 66 typedef FDEList::const_iterator const_fde_iterator; 67 68 typedef std::map</*offset*/size_t, CIE*> CIEMap; 69 70 // A super class of CIE and FDE, containing the same part 71 class Record : public RegionFragment 72 { 73 public: 74 Record(llvm::StringRef pRegion); 75 virtual ~Record(); 76 77 const llvm::StringRef getRegion() const { return RegionFragment::getRegion(); } 78 llvm::StringRef getRegion() { return RegionFragment::getRegion(); } 79 virtual RecordType getRecordType() const { return RECORD_UNKNOWN; } 80 81 private: 82 Record(const Record&); // DO NOT IMPLEMENT 83 Record& operator=(const Record&); // DO NOT IMPLEMENT 84 }; 85 86 /** \class CIE 87 * \brief Common Information Entry. 88 * The CIE structure refers to LSB Core Spec 4.1, chap.10.6. Exception Frames. 89 */ 90 class CIE : public Record 91 { 92 public: 93 CIE(llvm::StringRef pRegion); 94 ~CIE(); 95 96 virtual RecordType getRecordType() const { return RECORD_INPUT; } 97 98 void setFDEEncode(uint8_t pEncode) { m_FDEEncode = pEncode; } 99 uint8_t getFDEEncode() const { return m_FDEEncode; } 100 101 void setMergeable(bool pVal = true) { m_Mergeable = pVal; } 102 virtual bool getMergeable() const { return m_Mergeable; } 103 104 void setRelocation(const Relocation& pReloc) { m_pReloc = &pReloc; } 105 const Relocation* getRelocation() const { return m_pReloc; } 106 107 void setPersonalityOffset(uint64_t pOffset) { m_PersonalityOffset = pOffset; } 108 uint64_t getPersonalityOffset() const { return m_PersonalityOffset; } 109 110 void setPersonalityName(const std::string& pStr) { m_PersonalityName = pStr; } 111 const std::string& getPersonalityName() const { return m_PersonalityName; } 112 113 void setAugmentationData(const std::string& pStr) { m_AugmentationData = pStr; } 114 const std::string& getAugmentationData() const { return m_AugmentationData; } 115 116 void add(FDE& pFDE) { m_FDEs.push_back(&pFDE); } 117 void remove(FDE& pFDE) { m_FDEs.remove(&pFDE); } 118 void clearFDEs() { m_FDEs.clear(); } 119 size_t numOfFDEs() const { return m_FDEs.size(); } 120 121 const_fde_iterator begin() const { return m_FDEs.begin(); } 122 fde_iterator begin() { return m_FDEs.begin(); } 123 const_fde_iterator end() const { return m_FDEs.end(); } 124 fde_iterator end() { return m_FDEs.end(); } 125 126 private: 127 uint8_t m_FDEEncode; 128 bool m_Mergeable; 129 const Relocation* m_pReloc; 130 uint64_t m_PersonalityOffset; 131 std::string m_PersonalityName; 132 std::string m_AugmentationData; 133 FDEList m_FDEs; 134 }; 135 136 /** \class FDE 137 * \brief Frame Description Entry 138 * The FDE structure refers to LSB Core Spec 4.1, chap.10.6. Exception Frames. 139 */ 140 class FDE : public Record 141 { 142 public: 143 FDE(llvm::StringRef pRegion, CIE& pCIE); 144 ~FDE(); 145 146 void setCIE(CIE& pCIE); 147 const CIE& getCIE() const { return *m_pCIE; } 148 CIE& getCIE() { return *m_pCIE; } 149 150 private: 151 CIE* m_pCIE; // Referenced CIE may change when merging. 152 }; 153 154 // These are created for PLT 155 class GeneratedCIE : public CIE 156 { 157 public: 158 GeneratedCIE(llvm::StringRef pRegion); 159 ~GeneratedCIE(); 160 161 virtual RecordType getRecordType() const { return RECORD_GENERATED; } 162 virtual bool getMergeable() const { return true; } 163 }; 164 165 class GeneratedFDE : public FDE 166 { 167 public: 168 GeneratedFDE(llvm::StringRef pRegion, CIE& pCIE); 169 ~GeneratedFDE(); 170 171 virtual RecordType getRecordType() const { return RECORD_GENERATED; } 172 }; 173 174public: 175 static EhFrame* Create(LDSection& pSection); 176 177 static void Destroy(EhFrame*& pSection); 178 179 static void Clear(); 180 181 /// merge - move all data from pOther to this object. 182 EhFrame& merge(const Input& pInput, EhFrame& pInFrame); 183 184 const LDSection& getSection() const; 185 LDSection& getSection(); 186 187 const SectionData* getSectionData() const { return m_pSectionData; } 188 SectionData* getSectionData() { return m_pSectionData; } 189 190 // ----- fragment ----- // 191 void addFragment(Fragment& pFrag); 192 193 /// addCIE - add a CIE entry in EhFrame 194 void addCIE(CIE& pCIE, bool pAlsoAddFragment = true); 195 196 /// addFDE - add a FDE entry in EhFrame 197 void addFDE(FDE& pFDE, bool pAlsoAddFragment = true); 198 199 // ----- CIE ----- // 200 const_cie_iterator cie_begin() const { return m_CIEs.begin(); } 201 cie_iterator cie_begin() { return m_CIEs.begin(); } 202 const_cie_iterator cie_end () const { return m_CIEs.end(); } 203 cie_iterator cie_end () { return m_CIEs.end(); } 204 205 const CIE& cie_front() const { return *m_CIEs.front(); } 206 CIE& cie_front() { return *m_CIEs.front(); } 207 const CIE& cie_back () const { return *m_CIEs.back(); } 208 CIE& cie_back () { return *m_CIEs.back(); } 209 210 bool emptyCIEs() const { return m_CIEs.empty(); } 211 size_t numOfCIEs() const { return m_CIEs.size(); } 212 size_t numOfFDEs() const; 213 214 const CIEMap& getCIEMap() const { return m_FoundCIEs; } 215 CIEMap& getCIEMap() { return m_FoundCIEs; } 216 217public: 218 size_t computeOffsetSize(); 219 220 /// getDataStartOffset - Get the offset after length and ID field. 221 /// The offset is 8byte for 32b, and 16byte for 64b. 222 /// We can just use "BITCLASS/4" to represent offset. 223 template <size_t BITCLASS> 224 static size_t getDataStartOffset() { return BITCLASS / 4; } 225 226private: 227 // We needs to check if it is mergeable and check personality name 228 // before merging them. The important note is we must do this after 229 // ALL readSections done, that is the reason why we don't check this 230 // immediately when reading. 231 void setupAttributes(const LDSection* reloc_sect); 232 void removeDiscardedFDE(CIE& pCIE, const LDSection* pRelocEhFrameSect); 233 234private: 235 void removeAndUpdateCIEForFDE(EhFrame& pInFrame, CIE& pInCIE, CIE& pOutCIE, 236 const LDSection* reloc_sect); 237 void moveInputFragments(EhFrame& pInFrame); 238 void moveInputFragments(EhFrame& pInFrame, CIE& pInCIE, CIE* pOutCIE = 0); 239 240private: 241 LDSection* m_pSection; 242 SectionData* m_pSectionData; 243 244 // Each eh_frame has a list of CIE, and each CIE has a list of FDE 245 // pointing to the CIE itself. This is used by management when we are 246 // processing eh_frame merge. 247 // However, don't forget we need to handle the Fragments inside SectionData 248 // correctly since they are truly used when output emission. 249 CIEList m_CIEs; 250 251 // We need this map to find the corresponding CIE for FDE. Not all FDE point 252 // to the nearest CIE. 253 CIEMap m_FoundCIEs; 254}; 255 256bool operator==(const EhFrame::CIE&, const EhFrame::CIE&); 257 258} // namespace of mcld 259 260#endif 261 262