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