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