• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- ELFObjectFile.h - ELF object file implementation ---------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file declares the ELFObjectFile template class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_OBJECT_ELF_OBJECT_FILE_H
15 #define LLVM_OBJECT_ELF_OBJECT_FILE_H
16 
17 #include "llvm/ADT/DenseMap.h"
18 #include "llvm/ADT/PointerIntPair.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/ADT/StringSwitch.h"
21 #include "llvm/ADT/Triple.h"
22 #include "llvm/Object/ELF.h"
23 #include "llvm/Object/ObjectFile.h"
24 #include "llvm/Support/Casting.h"
25 #include "llvm/Support/ELF.h"
26 #include "llvm/Support/Endian.h"
27 #include "llvm/Support/ErrorHandling.h"
28 #include "llvm/Support/MemoryBuffer.h"
29 #include "llvm/Support/raw_ostream.h"
30 #include <algorithm>
31 #include <cctype>
32 #include <limits>
33 #include <utility>
34 
35 namespace llvm {
36 namespace object {
37 
38 template <class ELFT>
39 class ELFObjectFile : public ObjectFile {
40 public:
41   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
42 
43   typedef typename ELFFile<ELFT>::uintX_t uintX_t;
44 
45   typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym;
46   typedef typename ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
47   typedef typename ELFFile<ELFT>::Elf_Ehdr Elf_Ehdr;
48   typedef typename ELFFile<ELFT>::Elf_Rel Elf_Rel;
49   typedef typename ELFFile<ELFT>::Elf_Rela Elf_Rela;
50   typedef typename ELFFile<ELFT>::Elf_Dyn Elf_Dyn;
51 
52   typedef typename ELFFile<ELFT>::Elf_Sym_Iter Elf_Sym_Iter;
53   typedef typename ELFFile<ELFT>::Elf_Shdr_Iter Elf_Shdr_Iter;
54   typedef typename ELFFile<ELFT>::Elf_Dyn_Iter Elf_Dyn_Iter;
55 
56 protected:
57   ELFFile<ELFT> EF;
58 
59   void moveSymbolNext(DataRefImpl &Symb) const override;
60   std::error_code getSymbolName(DataRefImpl Symb,
61                                 StringRef &Res) const override;
62   std::error_code getSymbolAddress(DataRefImpl Symb,
63                                    uint64_t &Res) const override;
64   std::error_code getSymbolAlignment(DataRefImpl Symb,
65                                      uint32_t &Res) const override;
66   std::error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const override;
67   uint32_t getSymbolFlags(DataRefImpl Symb) const override;
68   std::error_code getSymbolType(DataRefImpl Symb,
69                                 SymbolRef::Type &Res) const override;
70   std::error_code getSymbolSection(DataRefImpl Symb,
71                                    section_iterator &Res) const override;
72 
73   std::error_code getLibraryNext(DataRefImpl Data,
74                                  LibraryRef &Result) const override;
75   std::error_code getLibraryPath(DataRefImpl Data,
76                                  StringRef &Res) const override;
77 
78   void moveSectionNext(DataRefImpl &Sec) const override;
79   std::error_code getSectionName(DataRefImpl Sec,
80                                  StringRef &Res) const override;
81   std::error_code getSectionAddress(DataRefImpl Sec,
82                                     uint64_t &Res) const override;
83   std::error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const override;
84   std::error_code getSectionContents(DataRefImpl Sec,
85                                      StringRef &Res) const override;
86   std::error_code getSectionAlignment(DataRefImpl Sec,
87                                       uint64_t &Res) const override;
88   std::error_code isSectionText(DataRefImpl Sec, bool &Res) const override;
89   std::error_code isSectionData(DataRefImpl Sec, bool &Res) const override;
90   std::error_code isSectionBSS(DataRefImpl Sec, bool &Res) const override;
91   std::error_code isSectionRequiredForExecution(DataRefImpl Sec,
92                                                 bool &Res) const override;
93   std::error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const override;
94   std::error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const override;
95   std::error_code isSectionReadOnlyData(DataRefImpl Sec,
96                                         bool &Res) const override;
97   std::error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
98                                         bool &Result) const override;
99   relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
100   relocation_iterator section_rel_end(DataRefImpl Sec) const override;
101   section_iterator getRelocatedSection(DataRefImpl Sec) const override;
102 
103   void moveRelocationNext(DataRefImpl &Rel) const override;
104   std::error_code getRelocationAddress(DataRefImpl Rel,
105                                        uint64_t &Res) const override;
106   std::error_code getRelocationOffset(DataRefImpl Rel,
107                                       uint64_t &Res) const override;
108   symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
109   std::error_code getRelocationType(DataRefImpl Rel,
110                                     uint64_t &Res) const override;
111   std::error_code
112   getRelocationTypeName(DataRefImpl Rel,
113                         SmallVectorImpl<char> &Result) const override;
114   std::error_code
115   getRelocationValueString(DataRefImpl Rel,
116                            SmallVectorImpl<char> &Result) const override;
117 
118   uint64_t getROffset(DataRefImpl Rel) const;
119   StringRef getRelocationTypeName(uint32_t Type) const;
120 
121   /// \brief Get the relocation section that contains \a Rel.
getRelSection(DataRefImpl Rel)122   const Elf_Shdr *getRelSection(DataRefImpl Rel) const {
123     return EF.getSection(Rel.d.a);
124   }
125 
126   const Elf_Rel *getRel(DataRefImpl Rel) const;
127   const Elf_Rela *getRela(DataRefImpl Rela) const;
128 
toELFSymIter(DataRefImpl Symb)129   Elf_Sym_Iter toELFSymIter(DataRefImpl Symb) const {
130     bool IsDynamic = Symb.p & 1;
131     if (IsDynamic)
132       return Elf_Sym_Iter(
133           EF.begin_dynamic_symbols().getEntSize(),
134           reinterpret_cast<const char *>(Symb.p & ~uintptr_t(1)), IsDynamic);
135     return Elf_Sym_Iter(EF.begin_symbols().getEntSize(),
136                         reinterpret_cast<const char *>(Symb.p), IsDynamic);
137   }
138 
toDRI(Elf_Sym_Iter Symb)139   DataRefImpl toDRI(Elf_Sym_Iter Symb) const {
140     DataRefImpl DRI;
141     DRI.p = reinterpret_cast<uintptr_t>(Symb.get()) |
142       static_cast<uintptr_t>(Symb.isDynamic());
143     return DRI;
144   }
145 
toELFShdrIter(DataRefImpl Sec)146   Elf_Shdr_Iter toELFShdrIter(DataRefImpl Sec) const {
147     return Elf_Shdr_Iter(EF.getHeader()->e_shentsize,
148                          reinterpret_cast<const char *>(Sec.p));
149   }
150 
toDRI(Elf_Shdr_Iter Sec)151   DataRefImpl toDRI(Elf_Shdr_Iter Sec) const {
152     DataRefImpl DRI;
153     DRI.p = reinterpret_cast<uintptr_t>(Sec.get());
154     return DRI;
155   }
156 
toDRI(const Elf_Shdr * Sec)157   DataRefImpl toDRI(const Elf_Shdr *Sec) const {
158     DataRefImpl DRI;
159     DRI.p = reinterpret_cast<uintptr_t>(Sec);
160     return DRI;
161   }
162 
toELFDynIter(DataRefImpl Dyn)163   Elf_Dyn_Iter toELFDynIter(DataRefImpl Dyn) const {
164     return Elf_Dyn_Iter(EF.begin_dynamic_table().getEntSize(),
165                         reinterpret_cast<const char *>(Dyn.p));
166   }
167 
toDRI(Elf_Dyn_Iter Dyn)168   DataRefImpl toDRI(Elf_Dyn_Iter Dyn) const {
169     DataRefImpl DRI;
170     DRI.p = reinterpret_cast<uintptr_t>(Dyn.get());
171     return DRI;
172   }
173 
174   // This flag is used for classof, to distinguish ELFObjectFile from
175   // its subclass. If more subclasses will be created, this flag will
176   // have to become an enum.
177   bool isDyldELFObject;
178 
179 public:
180   ELFObjectFile(std::unique_ptr<MemoryBuffer> Object, std::error_code &EC);
181 
182   const Elf_Sym *getSymbol(DataRefImpl Symb) const;
183 
184   basic_symbol_iterator symbol_begin_impl() const override;
185   basic_symbol_iterator symbol_end_impl() const override;
186 
187   symbol_iterator dynamic_symbol_begin() const;
188   symbol_iterator dynamic_symbol_end() const;
189 
190   section_iterator section_begin() const override;
191   section_iterator section_end() const override;
192 
193   library_iterator needed_library_begin() const override;
194   library_iterator needed_library_end() const override;
195 
196   std::error_code getRelocationAddend(DataRefImpl Rel, int64_t &Res) const;
197   std::error_code getSymbolVersion(SymbolRef Symb, StringRef &Version,
198                                    bool &IsDefault) const;
199 
200   uint8_t getBytesInAddress() const override;
201   StringRef getFileFormatName() const override;
202   unsigned getArch() const override;
203   StringRef getLoadName() const override;
204 
getELFFile()205   const ELFFile<ELFT> *getELFFile() const { return &EF; }
206 
isDyldType()207   bool isDyldType() const { return isDyldELFObject; }
classof(const Binary * v)208   static inline bool classof(const Binary *v) {
209     return v->getType() == getELFType(ELFT::TargetEndianness == support::little,
210                                       ELFT::Is64Bits);
211   }
212 };
213 
214 // Use an alignment of 2 for the typedefs since that is the worst case for
215 // ELF files in archives.
216 typedef ELFObjectFile<ELFType<support::little, 2, false> > ELF32LEObjectFile;
217 typedef ELFObjectFile<ELFType<support::little, 2, true> > ELF64LEObjectFile;
218 typedef ELFObjectFile<ELFType<support::big, 2, false> > ELF32BEObjectFile;
219 typedef ELFObjectFile<ELFType<support::big, 2, true> > ELF64BEObjectFile;
220 
221 template <class ELFT>
moveSymbolNext(DataRefImpl & Symb)222 void ELFObjectFile<ELFT>::moveSymbolNext(DataRefImpl &Symb) const {
223   Symb = toDRI(++toELFSymIter(Symb));
224 }
225 
226 template <class ELFT>
getSymbolName(DataRefImpl Symb,StringRef & Result)227 std::error_code ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Symb,
228                                                    StringRef &Result) const {
229   ErrorOr<StringRef> Name = EF.getSymbolName(toELFSymIter(Symb));
230   if (!Name)
231     return Name.getError();
232   Result = *Name;
233   return object_error::success;
234 }
235 
236 template <class ELFT>
getSymbolVersion(SymbolRef SymRef,StringRef & Version,bool & IsDefault)237 std::error_code ELFObjectFile<ELFT>::getSymbolVersion(SymbolRef SymRef,
238                                                       StringRef &Version,
239                                                       bool &IsDefault) const {
240   DataRefImpl Symb = SymRef.getRawDataRefImpl();
241   const Elf_Sym *symb = getSymbol(Symb);
242   ErrorOr<StringRef> Ver =
243       EF.getSymbolVersion(EF.getSection(Symb.d.b), symb, IsDefault);
244   if (!Ver)
245     return Ver.getError();
246   Version = *Ver;
247   return object_error::success;
248 }
249 
250 template <class ELFT>
getSymbolAddress(DataRefImpl Symb,uint64_t & Result)251 std::error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb,
252                                                       uint64_t &Result) const {
253   const Elf_Sym *ESym = getSymbol(Symb);
254   switch (EF.getSymbolTableIndex(ESym)) {
255   case ELF::SHN_COMMON:
256   case ELF::SHN_UNDEF:
257     Result = UnknownAddressOrSize;
258     return object_error::success;
259   case ELF::SHN_ABS:
260     Result = ESym->st_value;
261     return object_error::success;
262   default:
263     break;
264   }
265 
266   const Elf_Ehdr *Header = EF.getHeader();
267   Result = ESym->st_value;
268 
269   // Clear the ARM/Thumb indicator flag.
270   if (Header->e_machine == ELF::EM_ARM && ESym->getType() == ELF::STT_FUNC)
271     Result &= ~1;
272 
273   if (Header->e_type == ELF::ET_REL)
274     Result += EF.getSection(ESym)->sh_addr;
275 
276   return object_error::success;
277 }
278 
279 template <class ELFT>
getSymbolAlignment(DataRefImpl Symb,uint32_t & Res)280 std::error_code ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb,
281                                                         uint32_t &Res) const {
282   Elf_Sym_Iter Sym = toELFSymIter(Symb);
283   if (Sym->st_shndx == ELF::SHN_COMMON)
284     Res = Sym->st_value;
285   else
286     Res = 0;
287   return object_error::success;
288 }
289 
290 template <class ELFT>
getSymbolSize(DataRefImpl Symb,uint64_t & Result)291 std::error_code ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Symb,
292                                                    uint64_t &Result) const {
293   Result = toELFSymIter(Symb)->st_size;
294   return object_error::success;
295 }
296 
297 template <class ELFT>
298 std::error_code
getSymbolType(DataRefImpl Symb,SymbolRef::Type & Result)299 ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb,
300                                    SymbolRef::Type &Result) const {
301   const Elf_Sym *ESym = getSymbol(Symb);
302 
303   switch (ESym->getType()) {
304   case ELF::STT_NOTYPE:
305     Result = SymbolRef::ST_Unknown;
306     break;
307   case ELF::STT_SECTION:
308     Result = SymbolRef::ST_Debug;
309     break;
310   case ELF::STT_FILE:
311     Result = SymbolRef::ST_File;
312     break;
313   case ELF::STT_FUNC:
314     Result = SymbolRef::ST_Function;
315     break;
316   case ELF::STT_OBJECT:
317   case ELF::STT_COMMON:
318   case ELF::STT_TLS:
319     Result = SymbolRef::ST_Data;
320     break;
321   default:
322     Result = SymbolRef::ST_Other;
323     break;
324   }
325   return object_error::success;
326 }
327 
328 template <class ELFT>
getSymbolFlags(DataRefImpl Symb)329 uint32_t ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Symb) const {
330   Elf_Sym_Iter EIter = toELFSymIter(Symb);
331   const Elf_Sym *ESym = &*EIter;
332 
333   uint32_t Result = SymbolRef::SF_None;
334 
335   if (ESym->getBinding() != ELF::STB_LOCAL)
336     Result |= SymbolRef::SF_Global;
337 
338   if (ESym->getBinding() == ELF::STB_WEAK)
339     Result |= SymbolRef::SF_Weak;
340 
341   if (ESym->st_shndx == ELF::SHN_ABS)
342     Result |= SymbolRef::SF_Absolute;
343 
344   if (ESym->getType() == ELF::STT_FILE || ESym->getType() == ELF::STT_SECTION ||
345       EIter == EF.begin_symbols() || EIter == EF.begin_dynamic_symbols())
346     Result |= SymbolRef::SF_FormatSpecific;
347 
348   if (EF.getSymbolTableIndex(ESym) == ELF::SHN_UNDEF)
349     Result |= SymbolRef::SF_Undefined;
350 
351   if (ESym->getType() == ELF::STT_COMMON ||
352       EF.getSymbolTableIndex(ESym) == ELF::SHN_COMMON)
353     Result |= SymbolRef::SF_Common;
354 
355   return Result;
356 }
357 
358 template <class ELFT>
359 std::error_code
getSymbolSection(DataRefImpl Symb,section_iterator & Res)360 ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb,
361                                       section_iterator &Res) const {
362   const Elf_Sym *ESym = getSymbol(Symb);
363   const Elf_Shdr *ESec = EF.getSection(ESym);
364   if (!ESec)
365     Res = section_end();
366   else {
367     DataRefImpl Sec;
368     Sec.p = reinterpret_cast<intptr_t>(ESec);
369     Res = section_iterator(SectionRef(Sec, this));
370   }
371   return object_error::success;
372 }
373 
374 template <class ELFT>
moveSectionNext(DataRefImpl & Sec)375 void ELFObjectFile<ELFT>::moveSectionNext(DataRefImpl &Sec) const {
376   Sec = toDRI(++toELFShdrIter(Sec));
377 }
378 
379 template <class ELFT>
getSectionName(DataRefImpl Sec,StringRef & Result)380 std::error_code ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec,
381                                                     StringRef &Result) const {
382   ErrorOr<StringRef> Name = EF.getSectionName(&*toELFShdrIter(Sec));
383   if (!Name)
384     return Name.getError();
385   Result = *Name;
386   return object_error::success;
387 }
388 
389 template <class ELFT>
getSectionAddress(DataRefImpl Sec,uint64_t & Result)390 std::error_code ELFObjectFile<ELFT>::getSectionAddress(DataRefImpl Sec,
391                                                        uint64_t &Result) const {
392   Result = toELFShdrIter(Sec)->sh_addr;
393   return object_error::success;
394 }
395 
396 template <class ELFT>
getSectionSize(DataRefImpl Sec,uint64_t & Result)397 std::error_code ELFObjectFile<ELFT>::getSectionSize(DataRefImpl Sec,
398                                                     uint64_t &Result) const {
399   Result = toELFShdrIter(Sec)->sh_size;
400   return object_error::success;
401 }
402 
403 template <class ELFT>
404 std::error_code
getSectionContents(DataRefImpl Sec,StringRef & Result)405 ELFObjectFile<ELFT>::getSectionContents(DataRefImpl Sec,
406                                         StringRef &Result) const {
407   Elf_Shdr_Iter EShdr = toELFShdrIter(Sec);
408   Result = StringRef((const char *)base() + EShdr->sh_offset, EShdr->sh_size);
409   return object_error::success;
410 }
411 
412 template <class ELFT>
413 std::error_code
getSectionAlignment(DataRefImpl Sec,uint64_t & Result)414 ELFObjectFile<ELFT>::getSectionAlignment(DataRefImpl Sec,
415                                          uint64_t &Result) const {
416   Result = toELFShdrIter(Sec)->sh_addralign;
417   return object_error::success;
418 }
419 
420 template <class ELFT>
isSectionText(DataRefImpl Sec,bool & Result)421 std::error_code ELFObjectFile<ELFT>::isSectionText(DataRefImpl Sec,
422                                                    bool &Result) const {
423   Result = toELFShdrIter(Sec)->sh_flags & ELF::SHF_EXECINSTR;
424   return object_error::success;
425 }
426 
427 template <class ELFT>
isSectionData(DataRefImpl Sec,bool & Result)428 std::error_code ELFObjectFile<ELFT>::isSectionData(DataRefImpl Sec,
429                                                    bool &Result) const {
430   Elf_Shdr_Iter EShdr = toELFShdrIter(Sec);
431   Result = EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) &&
432            EShdr->sh_type == ELF::SHT_PROGBITS;
433   return object_error::success;
434 }
435 
436 template <class ELFT>
isSectionBSS(DataRefImpl Sec,bool & Result)437 std::error_code ELFObjectFile<ELFT>::isSectionBSS(DataRefImpl Sec,
438                                                   bool &Result) const {
439   Elf_Shdr_Iter EShdr = toELFShdrIter(Sec);
440   Result = EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) &&
441            EShdr->sh_type == ELF::SHT_NOBITS;
442   return object_error::success;
443 }
444 
445 template <class ELFT>
446 std::error_code
isSectionRequiredForExecution(DataRefImpl Sec,bool & Result)447 ELFObjectFile<ELFT>::isSectionRequiredForExecution(DataRefImpl Sec,
448                                                    bool &Result) const {
449   Result = toELFShdrIter(Sec)->sh_flags & ELF::SHF_ALLOC;
450   return object_error::success;
451 }
452 
453 template <class ELFT>
isSectionVirtual(DataRefImpl Sec,bool & Result)454 std::error_code ELFObjectFile<ELFT>::isSectionVirtual(DataRefImpl Sec,
455                                                       bool &Result) const {
456   Result = toELFShdrIter(Sec)->sh_type == ELF::SHT_NOBITS;
457   return object_error::success;
458 }
459 
460 template <class ELFT>
isSectionZeroInit(DataRefImpl Sec,bool & Result)461 std::error_code ELFObjectFile<ELFT>::isSectionZeroInit(DataRefImpl Sec,
462                                                        bool &Result) const {
463   Result = toELFShdrIter(Sec)->sh_type == ELF::SHT_NOBITS;
464   return object_error::success;
465 }
466 
467 template <class ELFT>
isSectionReadOnlyData(DataRefImpl Sec,bool & Result)468 std::error_code ELFObjectFile<ELFT>::isSectionReadOnlyData(DataRefImpl Sec,
469                                                            bool &Result) const {
470   Elf_Shdr_Iter EShdr = toELFShdrIter(Sec);
471   Result = !(EShdr->sh_flags & (ELF::SHF_WRITE | ELF::SHF_EXECINSTR));
472   return object_error::success;
473 }
474 
475 template <class ELFT>
sectionContainsSymbol(DataRefImpl Sec,DataRefImpl Symb,bool & Result)476 std::error_code ELFObjectFile<ELFT>::sectionContainsSymbol(DataRefImpl Sec,
477                                                            DataRefImpl Symb,
478                                                            bool &Result) const {
479   Elf_Sym_Iter ESym = toELFSymIter(Symb);
480 
481   uintX_t Index = ESym->st_shndx;
482   bool Reserved = Index >= ELF::SHN_LORESERVE && Index <= ELF::SHN_HIRESERVE;
483 
484   Result = !Reserved && (&*toELFShdrIter(Sec) == EF.getSection(ESym->st_shndx));
485   return object_error::success;
486 }
487 
488 template <class ELFT>
489 relocation_iterator
section_rel_begin(DataRefImpl Sec)490 ELFObjectFile<ELFT>::section_rel_begin(DataRefImpl Sec) const {
491   DataRefImpl RelData;
492   uintptr_t SHT = reinterpret_cast<uintptr_t>(EF.begin_sections().get());
493   RelData.d.a = (Sec.p - SHT) / EF.getHeader()->e_shentsize;
494   RelData.d.b = 0;
495   return relocation_iterator(RelocationRef(RelData, this));
496 }
497 
498 template <class ELFT>
499 relocation_iterator
section_rel_end(DataRefImpl Sec)500 ELFObjectFile<ELFT>::section_rel_end(DataRefImpl Sec) const {
501   DataRefImpl RelData;
502   uintptr_t SHT = reinterpret_cast<uintptr_t>(EF.begin_sections().get());
503   const Elf_Shdr *S = reinterpret_cast<const Elf_Shdr *>(Sec.p);
504   RelData.d.a = (Sec.p - SHT) / EF.getHeader()->e_shentsize;
505   if (S->sh_type != ELF::SHT_RELA && S->sh_type != ELF::SHT_REL)
506     RelData.d.b = 0;
507   else
508     RelData.d.b = S->sh_size / S->sh_entsize;
509 
510   return relocation_iterator(RelocationRef(RelData, this));
511 }
512 
513 template <class ELFT>
514 section_iterator
getRelocatedSection(DataRefImpl Sec)515 ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const {
516   if (EF.getHeader()->e_type != ELF::ET_REL)
517     return section_end();
518 
519   Elf_Shdr_Iter EShdr = toELFShdrIter(Sec);
520   uintX_t Type = EShdr->sh_type;
521   if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA)
522     return section_end();
523 
524   const Elf_Shdr *R = EF.getSection(EShdr->sh_info);
525   return section_iterator(SectionRef(toDRI(R), this));
526 }
527 
528 // Relocations
529 template <class ELFT>
moveRelocationNext(DataRefImpl & Rel)530 void ELFObjectFile<ELFT>::moveRelocationNext(DataRefImpl &Rel) const {
531   ++Rel.d.b;
532 }
533 
534 template <class ELFT>
535 symbol_iterator
getRelocationSymbol(DataRefImpl Rel)536 ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const {
537   uint32_t symbolIdx;
538   const Elf_Shdr *sec = getRelSection(Rel);
539   switch (sec->sh_type) {
540   default:
541     report_fatal_error("Invalid section type in Rel!");
542   case ELF::SHT_REL: {
543     symbolIdx = getRel(Rel)->getSymbol(EF.isMips64EL());
544     break;
545   }
546   case ELF::SHT_RELA: {
547     symbolIdx = getRela(Rel)->getSymbol(EF.isMips64EL());
548     break;
549   }
550   }
551   if (!symbolIdx)
552     return symbol_end();
553 
554   const Elf_Shdr *SymSec = EF.getSection(sec->sh_link);
555 
556   DataRefImpl SymbolData;
557   switch (SymSec->sh_type) {
558   default:
559     report_fatal_error("Invalid symbol table section type!");
560   case ELF::SHT_SYMTAB:
561     SymbolData = toDRI(EF.begin_symbols() + symbolIdx);
562     break;
563   case ELF::SHT_DYNSYM:
564     SymbolData = toDRI(EF.begin_dynamic_symbols() + symbolIdx);
565     break;
566   }
567 
568   return symbol_iterator(SymbolRef(SymbolData, this));
569 }
570 
571 template <class ELFT>
572 std::error_code
getRelocationAddress(DataRefImpl Rel,uint64_t & Result)573 ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel,
574                                           uint64_t &Result) const {
575   uint64_t ROffset = getROffset(Rel);
576   const Elf_Ehdr *Header = EF.getHeader();
577 
578   if (Header->e_type == ELF::ET_REL) {
579     const Elf_Shdr *RelocationSec = getRelSection(Rel);
580     const Elf_Shdr *RelocatedSec = EF.getSection(RelocationSec->sh_info);
581     Result = ROffset + RelocatedSec->sh_addr;
582   } else {
583     Result = ROffset;
584   }
585 
586   return object_error::success;
587 }
588 
589 template <class ELFT>
590 std::error_code
getRelocationOffset(DataRefImpl Rel,uint64_t & Result)591 ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel,
592                                          uint64_t &Result) const {
593   assert(EF.getHeader()->e_type == ELF::ET_REL &&
594          "Only relocatable object files have relocation offsets");
595   Result = getROffset(Rel);
596   return object_error::success;
597 }
598 
599 template <class ELFT>
getROffset(DataRefImpl Rel)600 uint64_t ELFObjectFile<ELFT>::getROffset(DataRefImpl Rel) const {
601   const Elf_Shdr *sec = getRelSection(Rel);
602   switch (sec->sh_type) {
603   default:
604     report_fatal_error("Invalid section type in Rel!");
605   case ELF::SHT_REL:
606     return getRel(Rel)->r_offset;
607   case ELF::SHT_RELA:
608     return getRela(Rel)->r_offset;
609   }
610 }
611 
612 template <class ELFT>
getRelocationType(DataRefImpl Rel,uint64_t & Result)613 std::error_code ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel,
614                                                        uint64_t &Result) const {
615   const Elf_Shdr *sec = getRelSection(Rel);
616   switch (sec->sh_type) {
617   default:
618     report_fatal_error("Invalid section type in Rel!");
619   case ELF::SHT_REL: {
620     Result = getRel(Rel)->getType(EF.isMips64EL());
621     break;
622   }
623   case ELF::SHT_RELA: {
624     Result = getRela(Rel)->getType(EF.isMips64EL());
625     break;
626   }
627   }
628   return object_error::success;
629 }
630 
631 template <class ELFT>
getRelocationTypeName(uint32_t Type)632 StringRef ELFObjectFile<ELFT>::getRelocationTypeName(uint32_t Type) const {
633   return getELFRelocationTypeName(EF.getHeader()->e_machine, Type);
634 }
635 
636 template <class ELFT>
getRelocationTypeName(DataRefImpl Rel,SmallVectorImpl<char> & Result)637 std::error_code ELFObjectFile<ELFT>::getRelocationTypeName(
638     DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
639   const Elf_Shdr *sec = getRelSection(Rel);
640   uint32_t type;
641   switch (sec->sh_type) {
642   default:
643     return object_error::parse_failed;
644   case ELF::SHT_REL: {
645     type = getRel(Rel)->getType(EF.isMips64EL());
646     break;
647   }
648   case ELF::SHT_RELA: {
649     type = getRela(Rel)->getType(EF.isMips64EL());
650     break;
651   }
652   }
653 
654   EF.getRelocationTypeName(type, Result);
655   return object_error::success;
656 }
657 
658 template <class ELFT>
659 std::error_code
getRelocationAddend(DataRefImpl Rel,int64_t & Result)660 ELFObjectFile<ELFT>::getRelocationAddend(DataRefImpl Rel,
661                                          int64_t &Result) const {
662   const Elf_Shdr *sec = getRelSection(Rel);
663   switch (sec->sh_type) {
664   default:
665     report_fatal_error("Invalid section type in Rel!");
666   case ELF::SHT_REL: {
667     Result = 0;
668     return object_error::success;
669   }
670   case ELF::SHT_RELA: {
671     Result = getRela(Rel)->r_addend;
672     return object_error::success;
673   }
674   }
675 }
676 
677 template <class ELFT>
getRelocationValueString(DataRefImpl Rel,SmallVectorImpl<char> & Result)678 std::error_code ELFObjectFile<ELFT>::getRelocationValueString(
679     DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
680   const Elf_Shdr *sec = getRelSection(Rel);
681   uint8_t type;
682   StringRef res;
683   int64_t addend = 0;
684   uint16_t symbol_index = 0;
685   switch (sec->sh_type) {
686   default:
687     return object_error::parse_failed;
688   case ELF::SHT_REL: {
689     type = getRel(Rel)->getType(EF.isMips64EL());
690     symbol_index = getRel(Rel)->getSymbol(EF.isMips64EL());
691     // TODO: Read implicit addend from section data.
692     break;
693   }
694   case ELF::SHT_RELA: {
695     type = getRela(Rel)->getType(EF.isMips64EL());
696     symbol_index = getRela(Rel)->getSymbol(EF.isMips64EL());
697     addend = getRela(Rel)->r_addend;
698     break;
699   }
700   }
701   const Elf_Sym *symb =
702       EF.template getEntry<Elf_Sym>(sec->sh_link, symbol_index);
703   ErrorOr<StringRef> SymName =
704       EF.getSymbolName(EF.getSection(sec->sh_link), symb);
705   if (!SymName)
706     return SymName.getError();
707   switch (EF.getHeader()->e_machine) {
708   case ELF::EM_X86_64:
709     switch (type) {
710     case ELF::R_X86_64_PC8:
711     case ELF::R_X86_64_PC16:
712     case ELF::R_X86_64_PC32: {
713       std::string fmtbuf;
714       raw_string_ostream fmt(fmtbuf);
715       fmt << *SymName << (addend < 0 ? "" : "+") << addend << "-P";
716       fmt.flush();
717       Result.append(fmtbuf.begin(), fmtbuf.end());
718     } break;
719     case ELF::R_X86_64_8:
720     case ELF::R_X86_64_16:
721     case ELF::R_X86_64_32:
722     case ELF::R_X86_64_32S:
723     case ELF::R_X86_64_64: {
724       std::string fmtbuf;
725       raw_string_ostream fmt(fmtbuf);
726       fmt << *SymName << (addend < 0 ? "" : "+") << addend;
727       fmt.flush();
728       Result.append(fmtbuf.begin(), fmtbuf.end());
729     } break;
730     default:
731       res = "Unknown";
732     }
733     break;
734   case ELF::EM_AARCH64: {
735     std::string fmtbuf;
736     raw_string_ostream fmt(fmtbuf);
737     fmt << *SymName;
738     if (addend != 0)
739       fmt << (addend < 0 ? "" : "+") << addend;
740     fmt.flush();
741     Result.append(fmtbuf.begin(), fmtbuf.end());
742     break;
743   }
744   case ELF::EM_ARM:
745   case ELF::EM_HEXAGON:
746   case ELF::EM_MIPS:
747     res = *SymName;
748     break;
749   default:
750     res = "Unknown";
751   }
752   if (Result.empty())
753     Result.append(res.begin(), res.end());
754   return object_error::success;
755 }
756 
757 template <class ELFT>
758 const typename ELFFile<ELFT>::Elf_Sym *
getSymbol(DataRefImpl Symb)759 ELFObjectFile<ELFT>::getSymbol(DataRefImpl Symb) const {
760   return &*toELFSymIter(Symb);
761 }
762 
763 template <class ELFT>
764 const typename ELFObjectFile<ELFT>::Elf_Rel *
getRel(DataRefImpl Rel)765 ELFObjectFile<ELFT>::getRel(DataRefImpl Rel) const {
766   return EF.template getEntry<Elf_Rel>(Rel.d.a, Rel.d.b);
767 }
768 
769 template <class ELFT>
770 const typename ELFObjectFile<ELFT>::Elf_Rela *
getRela(DataRefImpl Rela)771 ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const {
772   return EF.template getEntry<Elf_Rela>(Rela.d.a, Rela.d.b);
773 }
774 
775 template <class ELFT>
ELFObjectFile(std::unique_ptr<MemoryBuffer> Object,std::error_code & EC)776 ELFObjectFile<ELFT>::ELFObjectFile(std::unique_ptr<MemoryBuffer> Object,
777                                    std::error_code &EC)
778     : ObjectFile(getELFType(static_cast<endianness>(ELFT::TargetEndianness) ==
779                                 support::little,
780                             ELFT::Is64Bits),
781                  std::move(Object)),
782       EF(Data->getBuffer(), EC) {}
783 
784 template <class ELFT>
symbol_begin_impl()785 basic_symbol_iterator ELFObjectFile<ELFT>::symbol_begin_impl() const {
786   return basic_symbol_iterator(SymbolRef(toDRI(EF.begin_symbols()), this));
787 }
788 
789 template <class ELFT>
symbol_end_impl()790 basic_symbol_iterator ELFObjectFile<ELFT>::symbol_end_impl() const {
791   return basic_symbol_iterator(SymbolRef(toDRI(EF.end_symbols()), this));
792 }
793 
794 template <class ELFT>
dynamic_symbol_begin()795 symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_begin() const {
796   return symbol_iterator(SymbolRef(toDRI(EF.begin_dynamic_symbols()), this));
797 }
798 
799 template <class ELFT>
dynamic_symbol_end()800 symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_end() const {
801   return symbol_iterator(SymbolRef(toDRI(EF.end_dynamic_symbols()), this));
802 }
803 
804 template <class ELFT>
section_begin()805 section_iterator ELFObjectFile<ELFT>::section_begin() const {
806   return section_iterator(SectionRef(toDRI(EF.begin_sections()), this));
807 }
808 
809 template <class ELFT>
section_end()810 section_iterator ELFObjectFile<ELFT>::section_end() const {
811   return section_iterator(SectionRef(toDRI(EF.end_sections()), this));
812 }
813 
814 template <class ELFT>
getLoadName()815 StringRef ELFObjectFile<ELFT>::getLoadName() const {
816   Elf_Dyn_Iter DI = EF.begin_dynamic_table();
817   Elf_Dyn_Iter DE = EF.end_dynamic_table();
818 
819   while (DI != DE && DI->getTag() != ELF::DT_SONAME)
820     ++DI;
821 
822   if (DI != DE)
823     return EF.getDynamicString(DI->getVal());
824   return "";
825 }
826 
827 template <class ELFT>
needed_library_begin()828 library_iterator ELFObjectFile<ELFT>::needed_library_begin() const {
829   Elf_Dyn_Iter DI = EF.begin_dynamic_table();
830   Elf_Dyn_Iter DE = EF.end_dynamic_table();
831 
832   while (DI != DE && DI->getTag() != ELF::DT_SONAME)
833     ++DI;
834 
835   return library_iterator(LibraryRef(toDRI(DI), this));
836 }
837 
838 template <class ELFT>
getLibraryNext(DataRefImpl Data,LibraryRef & Result)839 std::error_code ELFObjectFile<ELFT>::getLibraryNext(DataRefImpl Data,
840                                                     LibraryRef &Result) const {
841   Elf_Dyn_Iter DI = toELFDynIter(Data);
842   Elf_Dyn_Iter DE = EF.end_dynamic_table();
843 
844   // Skip to the next DT_NEEDED entry.
845   do
846     ++DI;
847   while (DI != DE && DI->getTag() != ELF::DT_NEEDED);
848 
849   Result = LibraryRef(toDRI(DI), this);
850   return object_error::success;
851 }
852 
853 template <class ELFT>
getLibraryPath(DataRefImpl Data,StringRef & Res)854 std::error_code ELFObjectFile<ELFT>::getLibraryPath(DataRefImpl Data,
855                                                     StringRef &Res) const {
856   Res = EF.getDynamicString(toELFDynIter(Data)->getVal());
857   return object_error::success;
858 }
859 
860 template <class ELFT>
needed_library_end()861 library_iterator ELFObjectFile<ELFT>::needed_library_end() const {
862   return library_iterator(LibraryRef(toDRI(EF.end_dynamic_table()), this));
863 }
864 
865 template <class ELFT>
getBytesInAddress()866 uint8_t ELFObjectFile<ELFT>::getBytesInAddress() const {
867   return ELFT::Is64Bits ? 8 : 4;
868 }
869 
870 template <class ELFT>
getFileFormatName()871 StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
872   switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) {
873   case ELF::ELFCLASS32:
874     switch (EF.getHeader()->e_machine) {
875     case ELF::EM_386:
876       return "ELF32-i386";
877     case ELF::EM_X86_64:
878       return "ELF32-x86-64";
879     case ELF::EM_ARM:
880       return "ELF32-arm";
881     case ELF::EM_HEXAGON:
882       return "ELF32-hexagon";
883     case ELF::EM_MIPS:
884       return "ELF32-mips";
885     case ELF::EM_PPC:
886       return "ELF32-ppc";
887     case ELF::EM_SPARC:
888     case ELF::EM_SPARC32PLUS:
889       return "ELF32-sparc";
890     default:
891       return "ELF32-unknown";
892     }
893   case ELF::ELFCLASS64:
894     switch (EF.getHeader()->e_machine) {
895     case ELF::EM_386:
896       return "ELF64-i386";
897     case ELF::EM_X86_64:
898       return "ELF64-x86-64";
899     case ELF::EM_AARCH64:
900       return "ELF64-aarch64";
901     case ELF::EM_PPC64:
902       return "ELF64-ppc64";
903     case ELF::EM_S390:
904       return "ELF64-s390";
905     case ELF::EM_SPARCV9:
906       return "ELF64-sparc";
907     case ELF::EM_MIPS:
908       return "ELF64-mips";
909     default:
910       return "ELF64-unknown";
911     }
912   default:
913     // FIXME: Proper error handling.
914     report_fatal_error("Invalid ELFCLASS!");
915   }
916 }
917 
918 template <class ELFT>
getArch()919 unsigned ELFObjectFile<ELFT>::getArch() const {
920   bool IsLittleEndian = ELFT::TargetEndianness == support::little;
921   switch (EF.getHeader()->e_machine) {
922   case ELF::EM_386:
923     return Triple::x86;
924   case ELF::EM_X86_64:
925     return Triple::x86_64;
926   case ELF::EM_AARCH64:
927     return Triple::aarch64;
928   case ELF::EM_ARM:
929     return Triple::arm;
930   case ELF::EM_HEXAGON:
931     return Triple::hexagon;
932   case ELF::EM_MIPS:
933     switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) {
934     case ELF::ELFCLASS32:
935       return IsLittleEndian ? Triple::mipsel : Triple::mips;
936     case ELF::ELFCLASS64:
937       return IsLittleEndian ? Triple::mips64el : Triple::mips64;
938     default:
939       report_fatal_error("Invalid ELFCLASS!");
940     }
941   case ELF::EM_PPC64:
942     return IsLittleEndian ? Triple::ppc64le : Triple::ppc64;
943   case ELF::EM_S390:
944     return Triple::systemz;
945 
946   case ELF::EM_SPARC:
947   case ELF::EM_SPARC32PLUS:
948     return Triple::sparc;
949   case ELF::EM_SPARCV9:
950     return Triple::sparcv9;
951 
952   default:
953     return Triple::UnknownArch;
954   }
955 }
956 
957 /// FIXME: Maybe we should have a base ElfObjectFile that is not a template
958 /// and make these member functions?
getELFRelocationAddend(const RelocationRef R,int64_t & Addend)959 inline std::error_code getELFRelocationAddend(const RelocationRef R,
960                                               int64_t &Addend) {
961   const ObjectFile *Obj = R.getObjectFile();
962   DataRefImpl DRI = R.getRawDataRefImpl();
963   // Little-endian 32-bit
964   if (const ELF32LEObjectFile *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
965     return ELFObj->getRelocationAddend(DRI, Addend);
966 
967   // Big-endian 32-bit
968   if (const ELF32BEObjectFile *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj))
969     return ELFObj->getRelocationAddend(DRI, Addend);
970 
971   // Little-endian 64-bit
972   if (const ELF64LEObjectFile *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj))
973     return ELFObj->getRelocationAddend(DRI, Addend);
974 
975   // Big-endian 64-bit
976   if (const ELF64BEObjectFile *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj))
977     return ELFObj->getRelocationAddend(DRI, Addend);
978 
979   llvm_unreachable("Object passed to getELFRelocationAddend() is not ELF");
980 }
981 
982 inline std::pair<symbol_iterator, symbol_iterator>
getELFDynamicSymbolIterators(SymbolicFile * Obj)983 getELFDynamicSymbolIterators(SymbolicFile *Obj) {
984   if (const ELF32LEObjectFile *ELF = dyn_cast<ELF32LEObjectFile>(Obj))
985     return std::make_pair(ELF->dynamic_symbol_begin(),
986                           ELF->dynamic_symbol_end());
987   if (const ELF64LEObjectFile *ELF = dyn_cast<ELF64LEObjectFile>(Obj))
988     return std::make_pair(ELF->dynamic_symbol_begin(),
989                           ELF->dynamic_symbol_end());
990   if (const ELF32BEObjectFile *ELF = dyn_cast<ELF32BEObjectFile>(Obj))
991     return std::make_pair(ELF->dynamic_symbol_begin(),
992                           ELF->dynamic_symbol_end());
993   if (const ELF64BEObjectFile *ELF = cast<ELF64BEObjectFile>(Obj))
994     return std::make_pair(ELF->dynamic_symbol_begin(),
995                           ELF->dynamic_symbol_end());
996 
997   llvm_unreachable(
998       "Object passed to getELFDynamicSymbolIterators() is not ELF");
999 }
1000 
1001 /// This is a generic interface for retrieving GNU symbol version
1002 /// information from an ELFObjectFile.
GetELFSymbolVersion(const ObjectFile * Obj,const SymbolRef & Sym,StringRef & Version,bool & IsDefault)1003 inline std::error_code GetELFSymbolVersion(const ObjectFile *Obj,
1004                                            const SymbolRef &Sym,
1005                                            StringRef &Version,
1006                                            bool &IsDefault) {
1007   // Little-endian 32-bit
1008   if (const ELF32LEObjectFile *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
1009     return ELFObj->getSymbolVersion(Sym, Version, IsDefault);
1010 
1011   // Big-endian 32-bit
1012   if (const ELF32BEObjectFile *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj))
1013     return ELFObj->getSymbolVersion(Sym, Version, IsDefault);
1014 
1015   // Little-endian 64-bit
1016   if (const ELF64LEObjectFile *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj))
1017     return ELFObj->getSymbolVersion(Sym, Version, IsDefault);
1018 
1019   // Big-endian 64-bit
1020   if (const ELF64BEObjectFile *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj))
1021     return ELFObj->getSymbolVersion(Sym, Version, IsDefault);
1022 
1023   llvm_unreachable("Object passed to GetELFSymbolVersion() is not ELF");
1024 }
1025 }
1026 }
1027 
1028 #endif
1029