1 //===- EhFrameReader.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_EHFRAMEREADER_H_
10 #define MCLD_LD_EHFRAMEREADER_H_
11 #include "mcld/LD/EhFrame.h"
12 
13 #include <llvm/ADT/StringRef.h>
14 #include <llvm/Support/DataTypes.h>
15 
16 namespace mcld {
17 
18 class Input;
19 class LDSection;
20 
21 /** \class EhFrameReader
22  *  \brief EhFrameReader reads .eh_frame section
23  *
24  *  EhFrameReader is responsible to parse the input eh_frame sections and create
25  *  the corresponding CIE and FDE entries.
26  */
27 class EhFrameReader {
28  public:
29   typedef const char* ConstAddress;
30   typedef char* Address;
31 
32  public:
33   /// read - read an .eh_frame section and create the corresponding
34   /// CIEs and FDEs
35   /// @param pInput [in] the Input contains this eh_frame
36   /// @param pEhFrame [inout] the input eh_frame
37   /// @return if we read all CIEs and FDEs successfully, return true. Otherwise,
38   /// return false;
39   template <size_t BITCLASS, bool SAME_ENDIAN>
40   bool read(Input& pInput, EhFrame& pEhFrame);
41 
42  private:
43   enum TokenKind { CIE, FDE, Terminator, Unknown, NumOfTokenKinds };
44 
45   enum State { Q0, Q1, Accept, NumOfStates = 2, Reject = -1 };
46 
47   struct Token {
48     TokenKind kind;
49     size_t file_off;
50     size_t data_off;
51     uint64_t size;
52   };
53 
54   /// Action - the transition function of autometa.
55   /// @param pEhFrame - the output .eh_frame section
56   /// @param pSection - the input .eh_frame section
57   /// @param pRegion - the memory region that needs to handle with.
58   typedef bool (*Action)(EhFrame& pEhFrame,
59                          llvm::StringRef pRegion,
60                          const Token& pToken);
61 
62  private:
63   /// scan - scan pData from pHandler for a token.
64   template <bool SAME_ENDIAN>
65   Token scan(ConstAddress pHandler,
66              uint64_t pOffset,
67              llvm::StringRef pData) const;
68 
69   static bool addCIE(EhFrame& pEhFrame,
70                      llvm::StringRef pRegion,
71                      const Token& pToken);
72 
73   static bool addFDE(EhFrame& pEhFrame,
74                      llvm::StringRef pRegion,
75                      const Token& pToken);
76 
77   static bool addTerm(EhFrame& pEhFrame,
78                       llvm::StringRef pRegion,
79                       const Token& pToken);
80 
81   static bool reject(EhFrame& pEhFrame,
82                      llvm::StringRef pRegion,
83                      const Token& pToken);
84 };
85 
86 template <>
87 bool EhFrameReader::read<32, true>(Input& pInput, EhFrame& pEhFrame);
88 
89 template <>
90 EhFrameReader::Token EhFrameReader::scan<true>(ConstAddress pHandler,
91                                                uint64_t pOffset,
92                                                llvm::StringRef pData) const;
93 
94 }  // namespace mcld
95 
96 #endif  // MCLD_LD_EHFRAMEREADER_H_
97