ELFReader.h revision 87f34658dec9097d987d254a990ea7f311bfc95f
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_LD_ELFREADER_H
10#define MCLD_LD_ELFREADER_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/LD/ELFReaderIf.h>
20#include <mcld/LD/ResolveInfo.h>
21#include <mcld/LD/LDSymbol.h>
22#include <mcld/Target/GNULDBackend.h>
23
24namespace mcld {
25
26//class Module;
27class IRBuilder;
28class SectionData;
29class LDSection;
30
31/** \class ELFReader
32 *  \brief ELFReader is a template scaffolding for partial specification.
33 */
34template<size_t BIT, bool LITTLEENDIAN>
35class ELFReader
36{ };
37
38/** \class ELFReader<32, true>
39 *  \brief ELFReader<32, true> is a 32-bit, little endian ELFReader.
40 */
41template<>
42class ELFReader<32, true> : public ELFReaderIF
43{
44public:
45  typedef llvm::ELF::Elf32_Ehdr ELFHeader;
46  typedef llvm::ELF::Elf32_Shdr SectionHeader;
47  typedef llvm::ELF::Elf32_Sym  Symbol;
48  typedef llvm::ELF::Elf32_Rel  Rel;
49  typedef llvm::ELF::Elf32_Rela Rela;
50
51public:
52  ELFReader(GNULDBackend& pBackend);
53
54  ~ELFReader();
55
56  /// ELFHeaderSize - return the size of the ELFHeader
57  size_t getELFHeaderSize() const
58  { return sizeof(ELFHeader); }
59
60  /// isELF - is this a ELF file
61  bool isELF(const void* pELFHeader) const;
62
63  /// isMyEndian - is this ELF file in the same endian to me?
64  bool isMyEndian(const void* pELFHeader) const;
65
66  /// isMyMachine - is this ELF file generated for the same machine.
67  bool isMyMachine(const void* pELFHeader) const;
68
69  /// fileType - the file type of this file
70  Input::Type fileType(const void* pELFHeader) const;
71
72  /// readSectionHeaders - read ELF section header table and create LDSections
73  bool readSectionHeaders(Input& pInput, const void* pELFHeader) const;
74
75  /// readRegularSection - read a regular section and create fragments.
76  bool readRegularSection(Input& pInput, SectionData& pSD) const;
77
78  /// readSymbols - read ELF symbols and create LDSymbol
79  bool readSymbols(Input& pInput,
80                   IRBuilder& pBuilder,
81                   llvm::StringRef pRegion,
82                   const char* StrTab) const;
83
84  /// readSignature - read a symbol from the given Input and index in symtab
85  /// This is used to get the signature of a group section.
86  ResolveInfo* readSignature(Input& pInput,
87                             LDSection& pSymTab,
88                             uint32_t pSymIdx) const;
89
90  /// readRela - read ELF rela and create Relocation
91  bool readRela(Input& pInput,
92                LDSection& pSection,
93                llvm::StringRef pRegion) const;
94
95  /// readRel - read ELF rel and create Relocation
96  bool readRel(Input& pInput,
97               LDSection& pSection,
98               llvm::StringRef pRegion) const;
99
100  /// readDynamic - read ELF .dynamic in input dynobj
101  bool readDynamic(Input& pInput) const;
102
103private:
104  struct AliasInfo {
105    LDSymbol* pt_alias; ///potential alias
106    uint64_t ld_value;
107    ResolveInfo::Binding ld_binding;
108  };
109
110  /// comparison function to sort symbols for analyzing weak alias.
111  /// sort symbols by symbol value and then weak before strong.
112  /// ref. to gold symtabl.cc 1595
113  static bool less(AliasInfo p1, AliasInfo p2) {
114    if (p1.ld_value != p2.ld_value)
115      return (p1.ld_value < p2.ld_value);
116    if (p1.ld_binding != p2.ld_binding) {
117      if (ResolveInfo::Weak==p1.ld_binding)
118        return true;
119      else if (ResolveInfo::Weak==p2.ld_binding)
120        return false;
121    }
122    return p1.pt_alias->str() < p2.pt_alias->str();
123  }
124
125};
126
127
128/** \class ELFReader<64, true>
129 *  \brief ELFReader<64, true> is a 64-bit, little endian ELFReader.
130 */
131template<>
132class ELFReader<64, true> : public ELFReaderIF
133{
134public:
135  typedef llvm::ELF::Elf64_Ehdr ELFHeader;
136  typedef llvm::ELF::Elf64_Shdr SectionHeader;
137  typedef llvm::ELF::Elf64_Sym  Symbol;
138  typedef llvm::ELF::Elf64_Rel  Rel;
139  typedef llvm::ELF::Elf64_Rela Rela;
140
141public:
142  ELFReader(GNULDBackend& pBackend);
143
144  ~ELFReader();
145
146  /// ELFHeaderSize - return the size of the ELFHeader
147  size_t getELFHeaderSize() const
148  { return sizeof(ELFHeader); }
149
150  /// isELF - is this a ELF file
151  bool isELF(const void* pELFHeader) const;
152
153  /// isMyEndian - is this ELF file in the same endian to me?
154  bool isMyEndian(const void* pELFHeader) const;
155
156  /// isMyMachine - is this ELF file generated for the same machine.
157  bool isMyMachine(const void* pELFHeader) const;
158
159  /// fileType - the file type of this file
160  Input::Type fileType(const void* pELFHeader) const;
161
162  /// readSectionHeaders - read ELF section header table and create LDSections
163  bool readSectionHeaders(Input& pInput, const void* pELFHeader) const;
164
165  /// readRegularSection - read a regular section and create fragments.
166  bool readRegularSection(Input& pInput, SectionData& pSD) const;
167
168  /// readSymbols - read ELF symbols and create LDSymbol
169  bool readSymbols(Input& pInput,
170                   IRBuilder& pBuilder,
171                   llvm::StringRef pRegion,
172                   const char* StrTab) const;
173
174  /// readSignature - read a symbol from the given Input and index in symtab
175  /// This is used to get the signature of a group section.
176  ResolveInfo* readSignature(Input& pInput,
177                             LDSection& pSymTab,
178                             uint32_t pSymIdx) const;
179
180  /// readRela - read ELF rela and create Relocation
181  bool readRela(Input& pInput,
182                LDSection& pSection,
183                llvm::StringRef pRegion) const;
184
185  /// readRel - read ELF rel and create Relocation
186  bool readRel(Input& pInput,
187               LDSection& pSection,
188               llvm::StringRef pRegion) const;
189
190  /// readDynamic - read ELF .dynamic in input dynobj
191  bool readDynamic(Input& pInput) const;
192
193private:
194  struct AliasInfo {
195    LDSymbol* pt_alias; ///potential alias
196    uint64_t ld_value;
197    ResolveInfo::Binding ld_binding;
198  };
199
200  /// comparison function to sort symbols for analyzing weak alias.
201  /// sort symbols by symbol value and then weak before strong.
202  /// ref. to gold symtabl.cc 1595
203  static bool less(AliasInfo p1, AliasInfo p2) {
204    if (p1.ld_value != p2.ld_value)
205      return (p1.ld_value < p2.ld_value);
206    if (p1.ld_binding != p2.ld_binding) {
207      if (ResolveInfo::Weak==p1.ld_binding)
208        return true;
209      else if (ResolveInfo::Weak==p2.ld_binding)
210        return false;
211    }
212    return p1.pt_alias->str() < p2.pt_alias->str();
213  }
214
215};
216
217} // namespace of mcld
218
219#endif
220
221