blob: 752d468fd25b8e1b5ffe8692253eb015a9bbc061 [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- ELF.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 ELFFile template class.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_OBJECT_ELF_H
15#define LLVM_OBJECT_ELF_H
16
17#include "llvm/ADT/ArrayRef.h"
18#include "llvm/ADT/SmallVector.h"
19#include "llvm/ADT/StringRef.h"
20#include "llvm/BinaryFormat/ELF.h"
21#include "llvm/Object/ELFTypes.h"
22#include "llvm/Object/Error.h"
23#include "llvm/Support/Endian.h"
24#include "llvm/Support/Error.h"
25#include <cassert>
26#include <cstddef>
27#include <cstdint>
28#include <limits>
29#include <utility>
30
31namespace llvm {
32namespace object {
33
34StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type);
Andrew Scullcdfcccc2018-10-05 20:58:37 +010035uint32_t getELFRelrRelocationType(uint32_t Machine);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010036StringRef getELFSectionTypeName(uint32_t Machine, uint32_t Type);
37
38// Subclasses of ELFFile may need this for template instantiation
39inline std::pair<unsigned char, unsigned char>
40getElfArchType(StringRef Object) {
41 if (Object.size() < ELF::EI_NIDENT)
42 return std::make_pair((uint8_t)ELF::ELFCLASSNONE,
43 (uint8_t)ELF::ELFDATANONE);
44 return std::make_pair((uint8_t)Object[ELF::EI_CLASS],
45 (uint8_t)Object[ELF::EI_DATA]);
46}
47
48static inline Error createError(StringRef Err) {
49 return make_error<StringError>(Err, object_error::parse_failed);
50}
51
52template <class ELFT>
53class ELFFile {
54public:
55 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
56 using uintX_t = typename ELFT::uint;
57 using Elf_Ehdr = typename ELFT::Ehdr;
58 using Elf_Shdr = typename ELFT::Shdr;
59 using Elf_Sym = typename ELFT::Sym;
60 using Elf_Dyn = typename ELFT::Dyn;
61 using Elf_Phdr = typename ELFT::Phdr;
62 using Elf_Rel = typename ELFT::Rel;
63 using Elf_Rela = typename ELFT::Rela;
Andrew Scullcdfcccc2018-10-05 20:58:37 +010064 using Elf_Relr = typename ELFT::Relr;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010065 using Elf_Verdef = typename ELFT::Verdef;
66 using Elf_Verdaux = typename ELFT::Verdaux;
67 using Elf_Verneed = typename ELFT::Verneed;
68 using Elf_Vernaux = typename ELFT::Vernaux;
69 using Elf_Versym = typename ELFT::Versym;
70 using Elf_Hash = typename ELFT::Hash;
71 using Elf_GnuHash = typename ELFT::GnuHash;
72 using Elf_Nhdr = typename ELFT::Nhdr;
73 using Elf_Note = typename ELFT::Note;
74 using Elf_Note_Iterator = typename ELFT::NoteIterator;
75 using Elf_Dyn_Range = typename ELFT::DynRange;
76 using Elf_Shdr_Range = typename ELFT::ShdrRange;
77 using Elf_Sym_Range = typename ELFT::SymRange;
78 using Elf_Rel_Range = typename ELFT::RelRange;
79 using Elf_Rela_Range = typename ELFT::RelaRange;
Andrew Scullcdfcccc2018-10-05 20:58:37 +010080 using Elf_Relr_Range = typename ELFT::RelrRange;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010081 using Elf_Phdr_Range = typename ELFT::PhdrRange;
82
83 const uint8_t *base() const {
84 return reinterpret_cast<const uint8_t *>(Buf.data());
85 }
86
87 size_t getBufSize() const { return Buf.size(); }
88
89private:
90 StringRef Buf;
91
92 ELFFile(StringRef Object);
93
94public:
95 const Elf_Ehdr *getHeader() const {
96 return reinterpret_cast<const Elf_Ehdr *>(base());
97 }
98
99 template <typename T>
100 Expected<const T *> getEntry(uint32_t Section, uint32_t Entry) const;
101 template <typename T>
102 Expected<const T *> getEntry(const Elf_Shdr *Section, uint32_t Entry) const;
103
104 Expected<StringRef> getStringTable(const Elf_Shdr *Section) const;
105 Expected<StringRef> getStringTableForSymtab(const Elf_Shdr &Section) const;
106 Expected<StringRef> getStringTableForSymtab(const Elf_Shdr &Section,
107 Elf_Shdr_Range Sections) const;
108
109 Expected<ArrayRef<Elf_Word>> getSHNDXTable(const Elf_Shdr &Section) const;
110 Expected<ArrayRef<Elf_Word>> getSHNDXTable(const Elf_Shdr &Section,
111 Elf_Shdr_Range Sections) const;
112
113 StringRef getRelocationTypeName(uint32_t Type) const;
114 void getRelocationTypeName(uint32_t Type,
115 SmallVectorImpl<char> &Result) const;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100116 uint32_t getRelrRelocationType() const;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100117
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100118 const char *getDynamicTagAsString(unsigned Arch, uint64_t Type) const;
119 const char *getDynamicTagAsString(uint64_t Type) const;
120
121 /// Get the symbol for a given relocation.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100122 Expected<const Elf_Sym *> getRelocationSymbol(const Elf_Rel *Rel,
123 const Elf_Shdr *SymTab) const;
124
125 static Expected<ELFFile> create(StringRef Object);
126
127 bool isMipsELF64() const {
128 return getHeader()->e_machine == ELF::EM_MIPS &&
129 getHeader()->getFileClass() == ELF::ELFCLASS64;
130 }
131
132 bool isMips64EL() const {
133 return isMipsELF64() &&
134 getHeader()->getDataEncoding() == ELF::ELFDATA2LSB;
135 }
136
137 Expected<Elf_Shdr_Range> sections() const;
138
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100139 Expected<Elf_Dyn_Range> dynamicEntries() const;
140
141 Expected<const uint8_t *> toMappedAddr(uint64_t VAddr) const;
142
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100143 Expected<Elf_Sym_Range> symbols(const Elf_Shdr *Sec) const {
144 if (!Sec)
145 return makeArrayRef<Elf_Sym>(nullptr, nullptr);
146 return getSectionContentsAsArray<Elf_Sym>(Sec);
147 }
148
149 Expected<Elf_Rela_Range> relas(const Elf_Shdr *Sec) const {
150 return getSectionContentsAsArray<Elf_Rela>(Sec);
151 }
152
153 Expected<Elf_Rel_Range> rels(const Elf_Shdr *Sec) const {
154 return getSectionContentsAsArray<Elf_Rel>(Sec);
155 }
156
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100157 Expected<Elf_Relr_Range> relrs(const Elf_Shdr *Sec) const {
158 return getSectionContentsAsArray<Elf_Relr>(Sec);
159 }
160
161 Expected<std::vector<Elf_Rela>> decode_relrs(Elf_Relr_Range relrs) const;
162
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100163 Expected<std::vector<Elf_Rela>> android_relas(const Elf_Shdr *Sec) const;
164
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100165 /// Iterate over program header table.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100166 Expected<Elf_Phdr_Range> program_headers() const {
167 if (getHeader()->e_phnum && getHeader()->e_phentsize != sizeof(Elf_Phdr))
168 return createError("invalid e_phentsize");
169 if (getHeader()->e_phoff +
170 (getHeader()->e_phnum * getHeader()->e_phentsize) >
171 getBufSize())
172 return createError("program headers longer than binary");
173 auto *Begin =
174 reinterpret_cast<const Elf_Phdr *>(base() + getHeader()->e_phoff);
175 return makeArrayRef(Begin, Begin + getHeader()->e_phnum);
176 }
177
178 /// Get an iterator over notes in a program header.
179 ///
180 /// The program header must be of type \c PT_NOTE.
181 ///
182 /// \param Phdr the program header to iterate over.
183 /// \param Err [out] an error to support fallible iteration, which should
184 /// be checked after iteration ends.
185 Elf_Note_Iterator notes_begin(const Elf_Phdr &Phdr, Error &Err) const {
186 if (Phdr.p_type != ELF::PT_NOTE) {
187 Err = createError("attempt to iterate notes of non-note program header");
188 return Elf_Note_Iterator(Err);
189 }
190 if (Phdr.p_offset + Phdr.p_filesz > getBufSize()) {
191 Err = createError("invalid program header offset/size");
192 return Elf_Note_Iterator(Err);
193 }
194 return Elf_Note_Iterator(base() + Phdr.p_offset, Phdr.p_filesz, Err);
195 }
196
197 /// Get an iterator over notes in a section.
198 ///
199 /// The section must be of type \c SHT_NOTE.
200 ///
201 /// \param Shdr the section to iterate over.
202 /// \param Err [out] an error to support fallible iteration, which should
203 /// be checked after iteration ends.
204 Elf_Note_Iterator notes_begin(const Elf_Shdr &Shdr, Error &Err) const {
205 if (Shdr.sh_type != ELF::SHT_NOTE) {
206 Err = createError("attempt to iterate notes of non-note section");
207 return Elf_Note_Iterator(Err);
208 }
209 if (Shdr.sh_offset + Shdr.sh_size > getBufSize()) {
210 Err = createError("invalid section offset/size");
211 return Elf_Note_Iterator(Err);
212 }
213 return Elf_Note_Iterator(base() + Shdr.sh_offset, Shdr.sh_size, Err);
214 }
215
216 /// Get the end iterator for notes.
217 Elf_Note_Iterator notes_end() const {
218 return Elf_Note_Iterator();
219 }
220
221 /// Get an iterator range over notes of a program header.
222 ///
223 /// The program header must be of type \c PT_NOTE.
224 ///
225 /// \param Phdr the program header to iterate over.
226 /// \param Err [out] an error to support fallible iteration, which should
227 /// be checked after iteration ends.
228 iterator_range<Elf_Note_Iterator> notes(const Elf_Phdr &Phdr,
229 Error &Err) const {
230 return make_range(notes_begin(Phdr, Err), notes_end());
231 }
232
233 /// Get an iterator range over notes of a section.
234 ///
235 /// The section must be of type \c SHT_NOTE.
236 ///
237 /// \param Shdr the section to iterate over.
238 /// \param Err [out] an error to support fallible iteration, which should
239 /// be checked after iteration ends.
240 iterator_range<Elf_Note_Iterator> notes(const Elf_Shdr &Shdr,
241 Error &Err) const {
242 return make_range(notes_begin(Shdr, Err), notes_end());
243 }
244
245 Expected<StringRef> getSectionStringTable(Elf_Shdr_Range Sections) const;
246 Expected<uint32_t> getSectionIndex(const Elf_Sym *Sym, Elf_Sym_Range Syms,
247 ArrayRef<Elf_Word> ShndxTable) const;
248 Expected<const Elf_Shdr *> getSection(const Elf_Sym *Sym,
249 const Elf_Shdr *SymTab,
250 ArrayRef<Elf_Word> ShndxTable) const;
251 Expected<const Elf_Shdr *> getSection(const Elf_Sym *Sym,
252 Elf_Sym_Range Symtab,
253 ArrayRef<Elf_Word> ShndxTable) const;
254 Expected<const Elf_Shdr *> getSection(uint32_t Index) const;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100255 Expected<const Elf_Shdr *> getSection(const StringRef SectionName) const;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100256
257 Expected<const Elf_Sym *> getSymbol(const Elf_Shdr *Sec,
258 uint32_t Index) const;
259
260 Expected<StringRef> getSectionName(const Elf_Shdr *Section) const;
261 Expected<StringRef> getSectionName(const Elf_Shdr *Section,
262 StringRef DotShstrtab) const;
263 template <typename T>
264 Expected<ArrayRef<T>> getSectionContentsAsArray(const Elf_Shdr *Sec) const;
265 Expected<ArrayRef<uint8_t>> getSectionContents(const Elf_Shdr *Sec) const;
266};
267
268using ELF32LEFile = ELFFile<ELF32LE>;
269using ELF64LEFile = ELFFile<ELF64LE>;
270using ELF32BEFile = ELFFile<ELF32BE>;
271using ELF64BEFile = ELFFile<ELF64BE>;
272
273template <class ELFT>
274inline Expected<const typename ELFT::Shdr *>
275getSection(typename ELFT::ShdrRange Sections, uint32_t Index) {
276 if (Index >= Sections.size())
277 return createError("invalid section index");
278 return &Sections[Index];
279}
280
281template <class ELFT>
282inline Expected<uint32_t>
283getExtendedSymbolTableIndex(const typename ELFT::Sym *Sym,
284 const typename ELFT::Sym *FirstSym,
285 ArrayRef<typename ELFT::Word> ShndxTable) {
286 assert(Sym->st_shndx == ELF::SHN_XINDEX);
287 unsigned Index = Sym - FirstSym;
288 if (Index >= ShndxTable.size())
289 return createError("index past the end of the symbol table");
290
291 // The size of the table was checked in getSHNDXTable.
292 return ShndxTable[Index];
293}
294
295template <class ELFT>
296Expected<uint32_t>
297ELFFile<ELFT>::getSectionIndex(const Elf_Sym *Sym, Elf_Sym_Range Syms,
298 ArrayRef<Elf_Word> ShndxTable) const {
299 uint32_t Index = Sym->st_shndx;
300 if (Index == ELF::SHN_XINDEX) {
301 auto ErrorOrIndex = getExtendedSymbolTableIndex<ELFT>(
302 Sym, Syms.begin(), ShndxTable);
303 if (!ErrorOrIndex)
304 return ErrorOrIndex.takeError();
305 return *ErrorOrIndex;
306 }
307 if (Index == ELF::SHN_UNDEF || Index >= ELF::SHN_LORESERVE)
308 return 0;
309 return Index;
310}
311
312template <class ELFT>
313Expected<const typename ELFT::Shdr *>
314ELFFile<ELFT>::getSection(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
315 ArrayRef<Elf_Word> ShndxTable) const {
316 auto SymsOrErr = symbols(SymTab);
317 if (!SymsOrErr)
318 return SymsOrErr.takeError();
319 return getSection(Sym, *SymsOrErr, ShndxTable);
320}
321
322template <class ELFT>
323Expected<const typename ELFT::Shdr *>
324ELFFile<ELFT>::getSection(const Elf_Sym *Sym, Elf_Sym_Range Symbols,
325 ArrayRef<Elf_Word> ShndxTable) const {
326 auto IndexOrErr = getSectionIndex(Sym, Symbols, ShndxTable);
327 if (!IndexOrErr)
328 return IndexOrErr.takeError();
329 uint32_t Index = *IndexOrErr;
330 if (Index == 0)
331 return nullptr;
332 return getSection(Index);
333}
334
335template <class ELFT>
336inline Expected<const typename ELFT::Sym *>
337getSymbol(typename ELFT::SymRange Symbols, uint32_t Index) {
338 if (Index >= Symbols.size())
339 return createError("invalid symbol index");
340 return &Symbols[Index];
341}
342
343template <class ELFT>
344Expected<const typename ELFT::Sym *>
345ELFFile<ELFT>::getSymbol(const Elf_Shdr *Sec, uint32_t Index) const {
346 auto SymtabOrErr = symbols(Sec);
347 if (!SymtabOrErr)
348 return SymtabOrErr.takeError();
349 return object::getSymbol<ELFT>(*SymtabOrErr, Index);
350}
351
352template <class ELFT>
353template <typename T>
354Expected<ArrayRef<T>>
355ELFFile<ELFT>::getSectionContentsAsArray(const Elf_Shdr *Sec) const {
356 if (Sec->sh_entsize != sizeof(T) && sizeof(T) != 1)
357 return createError("invalid sh_entsize");
358
359 uintX_t Offset = Sec->sh_offset;
360 uintX_t Size = Sec->sh_size;
361
362 if (Size % sizeof(T))
363 return createError("size is not a multiple of sh_entsize");
364 if ((std::numeric_limits<uintX_t>::max() - Offset < Size) ||
365 Offset + Size > Buf.size())
366 return createError("invalid section offset");
367
368 if (Offset % alignof(T))
369 return createError("unaligned data");
370
371 const T *Start = reinterpret_cast<const T *>(base() + Offset);
372 return makeArrayRef(Start, Size / sizeof(T));
373}
374
375template <class ELFT>
376Expected<ArrayRef<uint8_t>>
377ELFFile<ELFT>::getSectionContents(const Elf_Shdr *Sec) const {
378 return getSectionContentsAsArray<uint8_t>(Sec);
379}
380
381template <class ELFT>
382StringRef ELFFile<ELFT>::getRelocationTypeName(uint32_t Type) const {
383 return getELFRelocationTypeName(getHeader()->e_machine, Type);
384}
385
386template <class ELFT>
387void ELFFile<ELFT>::getRelocationTypeName(uint32_t Type,
388 SmallVectorImpl<char> &Result) const {
389 if (!isMipsELF64()) {
390 StringRef Name = getRelocationTypeName(Type);
391 Result.append(Name.begin(), Name.end());
392 } else {
393 // The Mips N64 ABI allows up to three operations to be specified per
394 // relocation record. Unfortunately there's no easy way to test for the
395 // presence of N64 ELFs as they have no special flag that identifies them
396 // as being N64. We can safely assume at the moment that all Mips
397 // ELFCLASS64 ELFs are N64. New Mips64 ABIs should provide enough
398 // information to disambiguate between old vs new ABIs.
399 uint8_t Type1 = (Type >> 0) & 0xFF;
400 uint8_t Type2 = (Type >> 8) & 0xFF;
401 uint8_t Type3 = (Type >> 16) & 0xFF;
402
403 // Concat all three relocation type names.
404 StringRef Name = getRelocationTypeName(Type1);
405 Result.append(Name.begin(), Name.end());
406
407 Name = getRelocationTypeName(Type2);
408 Result.append(1, '/');
409 Result.append(Name.begin(), Name.end());
410
411 Name = getRelocationTypeName(Type3);
412 Result.append(1, '/');
413 Result.append(Name.begin(), Name.end());
414 }
415}
416
417template <class ELFT>
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100418uint32_t ELFFile<ELFT>::getRelrRelocationType() const {
419 return getELFRelrRelocationType(getHeader()->e_machine);
420}
421
422template <class ELFT>
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100423Expected<const typename ELFT::Sym *>
424ELFFile<ELFT>::getRelocationSymbol(const Elf_Rel *Rel,
425 const Elf_Shdr *SymTab) const {
426 uint32_t Index = Rel->getSymbol(isMips64EL());
427 if (Index == 0)
428 return nullptr;
429 return getEntry<Elf_Sym>(SymTab, Index);
430}
431
432template <class ELFT>
433Expected<StringRef>
434ELFFile<ELFT>::getSectionStringTable(Elf_Shdr_Range Sections) const {
435 uint32_t Index = getHeader()->e_shstrndx;
436 if (Index == ELF::SHN_XINDEX)
437 Index = Sections[0].sh_link;
438
439 if (!Index) // no section string table.
440 return "";
441 if (Index >= Sections.size())
442 return createError("invalid section index");
443 return getStringTable(&Sections[Index]);
444}
445
446template <class ELFT> ELFFile<ELFT>::ELFFile(StringRef Object) : Buf(Object) {}
447
448template <class ELFT>
449Expected<ELFFile<ELFT>> ELFFile<ELFT>::create(StringRef Object) {
450 if (sizeof(Elf_Ehdr) > Object.size())
451 return createError("Invalid buffer");
452 return ELFFile(Object);
453}
454
455template <class ELFT>
456Expected<typename ELFT::ShdrRange> ELFFile<ELFT>::sections() const {
457 const uintX_t SectionTableOffset = getHeader()->e_shoff;
458 if (SectionTableOffset == 0)
459 return ArrayRef<Elf_Shdr>();
460
461 if (getHeader()->e_shentsize != sizeof(Elf_Shdr))
462 return createError(
463 "invalid section header entry size (e_shentsize) in ELF header");
464
465 const uint64_t FileSize = Buf.size();
466
467 if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize)
468 return createError("section header table goes past the end of the file");
469
470 // Invalid address alignment of section headers
471 if (SectionTableOffset & (alignof(Elf_Shdr) - 1))
472 return createError("invalid alignment of section headers");
473
474 const Elf_Shdr *First =
475 reinterpret_cast<const Elf_Shdr *>(base() + SectionTableOffset);
476
477 uintX_t NumSections = getHeader()->e_shnum;
478 if (NumSections == 0)
479 NumSections = First->sh_size;
480
481 if (NumSections > UINT64_MAX / sizeof(Elf_Shdr))
482 return createError("section table goes past the end of file");
483
484 const uint64_t SectionTableSize = NumSections * sizeof(Elf_Shdr);
485
486 // Section table goes past end of file!
487 if (SectionTableOffset + SectionTableSize > FileSize)
488 return createError("section table goes past the end of file");
489
490 return makeArrayRef(First, NumSections);
491}
492
493template <class ELFT>
494template <typename T>
495Expected<const T *> ELFFile<ELFT>::getEntry(uint32_t Section,
496 uint32_t Entry) const {
497 auto SecOrErr = getSection(Section);
498 if (!SecOrErr)
499 return SecOrErr.takeError();
500 return getEntry<T>(*SecOrErr, Entry);
501}
502
503template <class ELFT>
504template <typename T>
505Expected<const T *> ELFFile<ELFT>::getEntry(const Elf_Shdr *Section,
506 uint32_t Entry) const {
507 if (sizeof(T) != Section->sh_entsize)
508 return createError("invalid sh_entsize");
509 size_t Pos = Section->sh_offset + Entry * sizeof(T);
510 if (Pos + sizeof(T) > Buf.size())
511 return createError("invalid section offset");
512 return reinterpret_cast<const T *>(base() + Pos);
513}
514
515template <class ELFT>
516Expected<const typename ELFT::Shdr *>
517ELFFile<ELFT>::getSection(uint32_t Index) const {
518 auto TableOrErr = sections();
519 if (!TableOrErr)
520 return TableOrErr.takeError();
521 return object::getSection<ELFT>(*TableOrErr, Index);
522}
523
524template <class ELFT>
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100525Expected<const typename ELFT::Shdr *>
526ELFFile<ELFT>::getSection(const StringRef SectionName) const {
527 auto TableOrErr = sections();
528 if (!TableOrErr)
529 return TableOrErr.takeError();
530 for (auto &Sec : *TableOrErr) {
531 auto SecNameOrErr = getSectionName(&Sec);
532 if (!SecNameOrErr)
533 return SecNameOrErr.takeError();
534 if (*SecNameOrErr == SectionName)
535 return &Sec;
536 }
537 return createError("invalid section name");
538}
539
540template <class ELFT>
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100541Expected<StringRef>
542ELFFile<ELFT>::getStringTable(const Elf_Shdr *Section) const {
543 if (Section->sh_type != ELF::SHT_STRTAB)
544 return createError("invalid sh_type for string table, expected SHT_STRTAB");
545 auto V = getSectionContentsAsArray<char>(Section);
546 if (!V)
547 return V.takeError();
548 ArrayRef<char> Data = *V;
549 if (Data.empty())
550 return createError("empty string table");
551 if (Data.back() != '\0')
552 return createError("string table non-null terminated");
553 return StringRef(Data.begin(), Data.size());
554}
555
556template <class ELFT>
557Expected<ArrayRef<typename ELFT::Word>>
558ELFFile<ELFT>::getSHNDXTable(const Elf_Shdr &Section) const {
559 auto SectionsOrErr = sections();
560 if (!SectionsOrErr)
561 return SectionsOrErr.takeError();
562 return getSHNDXTable(Section, *SectionsOrErr);
563}
564
565template <class ELFT>
566Expected<ArrayRef<typename ELFT::Word>>
567ELFFile<ELFT>::getSHNDXTable(const Elf_Shdr &Section,
568 Elf_Shdr_Range Sections) const {
569 assert(Section.sh_type == ELF::SHT_SYMTAB_SHNDX);
570 auto VOrErr = getSectionContentsAsArray<Elf_Word>(&Section);
571 if (!VOrErr)
572 return VOrErr.takeError();
573 ArrayRef<Elf_Word> V = *VOrErr;
574 auto SymTableOrErr = object::getSection<ELFT>(Sections, Section.sh_link);
575 if (!SymTableOrErr)
576 return SymTableOrErr.takeError();
577 const Elf_Shdr &SymTable = **SymTableOrErr;
578 if (SymTable.sh_type != ELF::SHT_SYMTAB &&
579 SymTable.sh_type != ELF::SHT_DYNSYM)
580 return createError("invalid sh_type");
581 if (V.size() != (SymTable.sh_size / sizeof(Elf_Sym)))
582 return createError("invalid section contents size");
583 return V;
584}
585
586template <class ELFT>
587Expected<StringRef>
588ELFFile<ELFT>::getStringTableForSymtab(const Elf_Shdr &Sec) const {
589 auto SectionsOrErr = sections();
590 if (!SectionsOrErr)
591 return SectionsOrErr.takeError();
592 return getStringTableForSymtab(Sec, *SectionsOrErr);
593}
594
595template <class ELFT>
596Expected<StringRef>
597ELFFile<ELFT>::getStringTableForSymtab(const Elf_Shdr &Sec,
598 Elf_Shdr_Range Sections) const {
599
600 if (Sec.sh_type != ELF::SHT_SYMTAB && Sec.sh_type != ELF::SHT_DYNSYM)
601 return createError(
602 "invalid sh_type for symbol table, expected SHT_SYMTAB or SHT_DYNSYM");
603 auto SectionOrErr = object::getSection<ELFT>(Sections, Sec.sh_link);
604 if (!SectionOrErr)
605 return SectionOrErr.takeError();
606 return getStringTable(*SectionOrErr);
607}
608
609template <class ELFT>
610Expected<StringRef>
611ELFFile<ELFT>::getSectionName(const Elf_Shdr *Section) const {
612 auto SectionsOrErr = sections();
613 if (!SectionsOrErr)
614 return SectionsOrErr.takeError();
615 auto Table = getSectionStringTable(*SectionsOrErr);
616 if (!Table)
617 return Table.takeError();
618 return getSectionName(Section, *Table);
619}
620
621template <class ELFT>
622Expected<StringRef> ELFFile<ELFT>::getSectionName(const Elf_Shdr *Section,
623 StringRef DotShstrtab) const {
624 uint32_t Offset = Section->sh_name;
625 if (Offset == 0)
626 return StringRef();
627 if (Offset >= DotShstrtab.size())
628 return createError("invalid string offset");
629 return StringRef(DotShstrtab.data() + Offset);
630}
631
632/// This function returns the hash value for a symbol in the .dynsym section
633/// Name of the API remains consistent as specified in the libelf
634/// REF : http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#hash
635inline unsigned hashSysV(StringRef SymbolName) {
636 unsigned h = 0, g;
637 for (char C : SymbolName) {
638 h = (h << 4) + C;
639 g = h & 0xf0000000L;
640 if (g != 0)
641 h ^= g >> 24;
642 h &= ~g;
643 }
644 return h;
645}
646
647} // end namespace object
648} // end namespace llvm
649
650#endif // LLVM_OBJECT_ELF_H