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