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