ELFReader.h revision cedee4b38f4786845183be7f5916dd520a170ae0
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
32namespace mcld
33{
34
35/** \class ELFReaderIF
36 *  \brief ELFReaderIF provides common interface for all kind of ELF readers.
37 */
38class ELFReaderIF
39{
40public:
41  ELFReaderIF(GNULDBackend& pBackend)
42    : m_Backend(pBackend)
43  { }
44
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
63  GNULDBackend& target()
64  { return m_Backend; }
65
66  /// target - the target backend
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
117protected:
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
127protected:
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
149private:
150  GNULDBackend& m_Backend;
151};
152
153/** \class ELFReader
154 *  \brief ELFReader is a template scaffolding for partial specification.
155 */
156template<size_t BIT, bool LITTLEENDIAN>
157class ELFReader
158{ };
159
160/** \class ELFReader<32, true>
161 *  \brief ELFReader<32, true> is a 32-bit, little endian ELFReader.
162 */
163template<>
164class ELFReader<32, true> : public ELFReaderIF
165{
166public:
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
173public:
174  inline ELFReader(GNULDBackend& pBackend);
175
176  inline ~ELFReader();
177
178  /// ELFHeaderSize - return the size of the ELFHeader
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