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