• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- ELFReader.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_ELF_READER_INTERFACE_H
10 #define MCLD_ELF_READER_INTERFACE_H
11 #ifdef ENABLE_UNITTEST
12 #include <gtest.h>
13 #endif
14 
15 #include <llvm/ADT/StringRef.h>
16 #include <llvm/Support/ELF.h>
17 #include <llvm/Support/Host.h>
18 
19 #include <mcld/MC/MCLDInfo.h>
20 #include <mcld/MC/MCLDInput.h>
21 #include <mcld/MC/MCLinker.h>
22 #include <mcld/LD/Fragment.h>
23 #include <mcld/LD/FillFragment.h>
24 #include <mcld/LD/AlignFragment.h>
25 #include <mcld/LD/RegionFragment.h>
26 #include <mcld/LD/ResolveInfo.h>
27 #include <mcld/LD/LDContext.h>
28 #include <mcld/Target/GNULDBackend.h>
29 #include <mcld/Support/MemoryRegion.h>
30 #include <mcld/Support/MsgHandling.h>
31 
32 namespace mcld
33 {
34 
35 /** \class ELFReaderIF
36  *  \brief ELFReaderIF provides common interface for all kind of ELF readers.
37  */
38 class ELFReaderIF
39 {
40 public:
ELFReaderIF(GNULDBackend & pBackend)41   ELFReaderIF(GNULDBackend& pBackend)
42     : m_Backend(pBackend)
43   { }
44 
~ELFReaderIF()45   virtual ~ELFReaderIF() { }
46 
47   /// ELFHeaderSize - return the size of the ELFHeader
48   virtual size_t getELFHeaderSize() const = 0;
49 
50   /// isELF - is this a ELF file
51   virtual bool isELF(void* pELFHeader) const = 0;
52 
53   /// isMyEndian - is this ELF file in the same endian to me?
54   virtual bool isMyEndian(void* pELFHeader) const = 0;
55 
56   /// isMyMachine - is this ELF file generated for the same machine.
57   virtual bool isMyMachine(void* pELFHeader) const = 0;
58 
59   /// fileType - the file type of this file
60   virtual MCLDFile::Type fileType(void* pELFHeader) const = 0;
61 
62   /// target - the target backend
target()63   GNULDBackend& target()
64   { return m_Backend; }
65 
66   /// target - the target backend
target()67   const GNULDBackend& target() const
68   { return m_Backend; }
69 
70   /// readSectionHeaders - read ELF section header table and create LDSections
71   virtual bool readSectionHeaders(Input& pInput,
72                                   MCLinker& pLinker,
73                                   void* pELFHeader) const = 0;
74 
75   /// readRegularSection - read a regular section and create fragments.
76   virtual bool readRegularSection(Input& pInput,
77                                   MCLinker& pLinker,
78                                   LDSection& pSectHdr) const = 0;
79 
80   /// readRegularSection - read a target section and create fragments.
81   virtual bool readTargetSection(Input& pInput,
82                                  MCLinker& pLinker,
83                                  LDSection& pSectHdr) = 0;
84 
85   /// readSymbols - read ELF symbols and create LDSymbol
86   virtual bool readSymbols(Input& pInput,
87                            MCLinker& pLinker,
88                            const MemoryRegion& pRegion,
89                            const char* StrTab) const = 0;
90 
91   /// readSymbol - read a symbol from the given Input and index in symtab
92   /// This is used to get the signature of a group section.
93   virtual ResolveInfo* readSymbol(Input& pInput,
94                                   LDSection& pSymTab,
95                                   MCLDInfo& pLDInfo,
96                                   uint32_t pSymIdx) const = 0;
97 
98   /// readRela - read ELF rela and create Relocation
99   virtual bool readRela(Input& pInput,
100                         MCLinker& pLinker,
101                         LDSection& pSection,
102                         const MemoryRegion& pRegion) const = 0;
103 
104   /// readRel - read ELF rel and create Relocation
105   virtual bool readRel(Input& pInput,
106                        MCLinker& pLinker,
107                        LDSection& pSection,
108                        const MemoryRegion& pRegion) const = 0;
109 
110   bool readEhFrame(Input& pInput,
111                    MCLinker& pLinker,
112                    LDSection& pSection) const;
113 
114   /// readDynamic - read ELF .dynamic in input dynobj
115   virtual bool readDynamic(Input& pInput) const = 0;
116 
117 protected:
118   /// LinkInfo - some section needs sh_link and sh_info, remember them.
119   struct LinkInfo {
120     LDSection* section;
121     uint32_t sh_link;
122     uint32_t sh_info;
123   };
124 
125   typedef std::vector<LinkInfo> LinkInfoList;
126 
127 protected:
128   LDFileFormat::Kind getLDSectionKind(uint32_t pType, const char* pName) const;
129 
130   ResolveInfo::Type getSymType(uint8_t pInfo, uint16_t pShndx) const;
131 
132   ResolveInfo::Desc getSymDesc(uint16_t pShndx, const Input& pInput) const;
133 
134   ResolveInfo::Binding getSymBinding(uint8_t pBinding,
135                                      uint16_t pShndx,
136                                      uint8_t pVisibility) const;
137 
138   uint64_t getSymValue(uint64_t pValue,
139                        uint16_t pShndx,
140                        const Input& pInput) const;
141 
142   FragmentRef* getSymFragmentRef(Input& pInput,
143                                  MCLinker& pLinker,
144                                  uint16_t pShndx,
145                                  uint32_t pOffset) const;
146 
147   ResolveInfo::Visibility getSymVisibility(uint8_t pVis) const;
148 
149 private:
150   GNULDBackend& m_Backend;
151 };
152 
153 /** \class ELFReader
154  *  \brief ELFReader is a template scaffolding for partial specification.
155  */
156 template<size_t BIT, bool LITTLEENDIAN>
157 class ELFReader
158 { };
159 
160 /** \class ELFReader<32, true>
161  *  \brief ELFReader<32, true> is a 32-bit, little endian ELFReader.
162  */
163 template<>
164 class ELFReader<32, true> : public ELFReaderIF
165 {
166 public:
167   typedef llvm::ELF::Elf32_Ehdr ELFHeader;
168   typedef llvm::ELF::Elf32_Shdr SectionHeader;
169   typedef llvm::ELF::Elf32_Sym  Symbol;
170   typedef llvm::ELF::Elf32_Rel  Rel;
171   typedef llvm::ELF::Elf32_Rela Rela;
172 
173 public:
174   inline ELFReader(GNULDBackend& pBackend);
175 
176   inline ~ELFReader();
177 
178   /// ELFHeaderSize - return the size of the ELFHeader
getELFHeaderSize()179   inline size_t getELFHeaderSize() const
180   { return sizeof(ELFHeader); }
181 
182   /// isELF - is this a ELF file
183   inline bool isELF(void* pELFHeader) const;
184 
185   /// isMyEndian - is this ELF file in the same endian to me?
186   inline bool isMyEndian(void* pELFHeader) const;
187 
188   /// isMyMachine - is this ELF file generated for the same machine.
189   inline bool isMyMachine(void* pELFHeader) const;
190 
191   /// fileType - the file type of this file
192   inline MCLDFile::Type fileType(void* pELFHeader) const;
193 
194   /// readSectionHeaders - read ELF section header table and create LDSections
195   inline bool readSectionHeaders(Input& pInput,
196                           MCLinker& pLinker,
197                           void* pELFHeader) const;
198 
199   /// readRegularSection - read a regular section and create fragments.
200   inline bool readRegularSection(Input& pInput,
201                                  MCLinker& pLinker,
202                                  LDSection& pInputSectHdr) const;
203 
204   /// readRegularSection - read a target section and create fragments.
205   inline bool readTargetSection(Input& pInput,
206                                 MCLinker& pLinker,
207                                 LDSection& pInputSectHdr);
208 
209   /// readSymbols - read ELF symbols and create LDSymbol
210   inline bool readSymbols(Input& pInput,
211                           MCLinker& pLinker,
212                           const MemoryRegion& pRegion,
213                           const char* StrTab) const;
214 
215   /// readSymbol - read a symbol from the given Input and index in symtab
216   /// This is used to get the signature of a group section.
217   inline ResolveInfo* readSymbol(Input& pInput,
218                                  LDSection& pSymTab,
219                                  MCLDInfo& pLDInfo,
220                                  uint32_t pSymIdx) const;
221 
222   /// readRela - read ELF rela and create Relocation
223   inline bool readRela(Input& pInput,
224                        MCLinker& pLinker,
225                        LDSection& pSection,
226                        const MemoryRegion& pRegion) const;
227 
228   /// readRel - read ELF rel and create Relocation
229   inline bool readRel(Input& pInput,
230                       MCLinker& pLinker,
231                       LDSection& pSection,
232                       const MemoryRegion& pRegion) const;
233 
234   /// readDynamic - read ELF .dynamic in input dynobj
235   inline bool readDynamic(Input& pInput) const;
236 };
237 
238 #include "ELFReader.tcc"
239 
240 } // namespace of mcld
241 
242 #endif
243 
244