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