1//===- ELF.h - ELF object file implementation -------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file declares the ELFFile template class.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_OBJECT_ELF_H
14#define LLVM_OBJECT_ELF_H
15
16#include "llvm/ADT/ArrayRef.h"
17#include "llvm/ADT/SmallVector.h"
18#include "llvm/ADT/StringRef.h"
19#include "llvm/BinaryFormat/ELF.h"
20#include "llvm/Object/ELFTypes.h"
21#include "llvm/Object/Error.h"
22#include "llvm/Support/Endian.h"
23#include "llvm/Support/Error.h"
24#include <cassert>
25#include <cstddef>
26#include <cstdint>
27#include <limits>
28#include <utility>
29
30namespace llvm {
31namespace object {
32
33struct VerdAux {
34 unsigned Offset;
35 std::string Name;
36};
37
38struct VerDef {
39 unsigned Offset;
40 unsigned Version;
41 unsigned Flags;
42 unsigned Ndx;
43 unsigned Cnt;
44 unsigned Hash;
45 std::string Name;
46 std::vector<VerdAux> AuxV;
47};
48
49struct VernAux {
50 unsigned Hash;
51 unsigned Flags;
52 unsigned Other;
53 unsigned Offset;
54 std::string Name;
55};
56
57struct VerNeed {
58 unsigned Version;
59 unsigned Cnt;
60 unsigned Offset;
61 std::string File;
62 std::vector<VernAux> AuxV;
63};
64
65struct VersionEntry {
66 std::string Name;
67 bool IsVerDef;
68};
69
70StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type);
71uint32_t getELFRelativeRelocationType(uint32_t Machine);
72StringRef getELFSectionTypeName(uint32_t Machine, uint32_t Type);
73
74// Subclasses of ELFFile may need this for template instantiation
75inline std::pair<unsigned char, unsigned char>
76getElfArchType(StringRef Object) {
77 if (Object.size() < ELF::EI_NIDENT)
78 return std::make_pair((uint8_t)ELF::ELFCLASSNONE,
79 (uint8_t)ELF::ELFDATANONE);
80 return std::make_pair((uint8_t)Object[ELF::EI_CLASS],
81 (uint8_t)Object[ELF::EI_DATA]);
82}
83
84enum PPCInstrMasks : uint64_t {
85 PADDI_R12_NO_DISP = 0x0610000039800000,
86 ADDIS_R12_TO_R2_NO_DISP = 0x3D820000,
87 ADDI_R12_TO_R2_NO_DISP = 0x39820000,
88 ADDI_R12_TO_R12_NO_DISP = 0x398C0000,
89 PLD_R12_NO_DISP = 0x04100000E5800000,
90 MTCTR_R12 = 0x7D8903A6,
91 BCTR = 0x4E800420,
92};
93
94template <class ELFT> class ELFFile;
95
96template <class T> struct DataRegion {
97 // This constructor is used when we know the start and the size of a data
98 // region. We assume that Arr does not go past the end of the file.
99 DataRegion(ArrayRef<T> Arr) : First(Arr.data()), Size(Arr.size()) {}
100
101 // Sometimes we only know the start of a data region. We still don't want to
102 // read past the end of the file, so we provide the end of a buffer.
103 DataRegion(const T *Data, const uint8_t *BufferEnd)
104 : First(Data), BufEnd(BufferEnd) {}
105
106 Expected<T> operator[](uint64_t N) {
107 assert(Size || BufEnd);
108 if (Size) {
109 if (N >= *Size)
110 return createError(
111 "the index is greater than or equal to the number of entries (" +
112 Twine(*Size) + ")");
113 } else {
114 const uint8_t *EntryStart = (const uint8_t *)First + N * sizeof(T);
115 if (EntryStart + sizeof(T) > BufEnd)
116 return createError("can't read past the end of the file");
117 }
118 return *(First + N);
119 }
120
121 const T *First;
122 Optional<uint64_t> Size = None;
123 const uint8_t *BufEnd = nullptr;
124};
125
126template <class ELFT>
127std::string getSecIndexForError(const ELFFile<ELFT> &Obj,
128 const typename ELFT::Shdr &Sec) {
129 auto TableOrErr = Obj.sections();
130 if (TableOrErr)
131 return "[index " + std::to_string(&Sec - &TableOrErr->front()) + "]";
132 // To make this helper be more convenient for error reporting purposes we
133 // drop the error. But really it should never be triggered. Before this point,
134 // our code should have called 'sections()' and reported a proper error on
135 // failure.
136 llvm::consumeError(TableOrErr.takeError());
137 return "[unknown index]";
138}
139
140template <class ELFT>
141static std::string describe(const ELFFile<ELFT> &Obj,
142 const typename ELFT::Shdr &Sec) {
143 unsigned SecNdx = &Sec - &cantFail(Obj.sections()).front();
144 return (object::getELFSectionTypeName(Obj.getHeader().e_machine,
145 Sec.sh_type) +
146 " section with index " + Twine(SecNdx))
147 .str();
148}
149
150template <class ELFT>
151std::string getPhdrIndexForError(const ELFFile<ELFT> &Obj,
152 const typename ELFT::Phdr &Phdr) {
153 auto Headers = Obj.program_headers();
154 if (Headers)
155 return ("[index " + Twine(&Phdr - &Headers->front()) + "]").str();
156 // See comment in the getSecIndexForError() above.
157 llvm::consumeError(Headers.takeError());
158 return "[unknown index]";
159}
160
161static inline Error defaultWarningHandler(const Twine &Msg) {
162 return createError(Msg);
163}
164
165template <class ELFT>
166class ELFFile {
167public:
168 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
169
170 // This is a callback that can be passed to a number of functions.
171 // It can be used to ignore non-critical errors (warnings), which is
172 // useful for dumpers, like llvm-readobj.
173 // It accepts a warning message string and returns a success
174 // when the warning should be ignored or an error otherwise.
175 using WarningHandler = llvm::function_ref<Error(const Twine &Msg)>;
176
177 const uint8_t *base() const { return Buf.bytes_begin(); }
178 const uint8_t *end() const { return base() + getBufSize(); }
179
180 size_t getBufSize() const { return Buf.size(); }
181
182private:
183 StringRef Buf;
184 std::vector<Elf_Shdr> FakeSections;
185
186 ELFFile(StringRef Object);
187
188public:
189 const Elf_Ehdr &getHeader() const {
190 return *reinterpret_cast<const Elf_Ehdr *>(base());
191 }
192
193 template <typename T>
194 Expected<const T *> getEntry(uint32_t Section, uint32_t Entry) const;
195 template <typename T>
196 Expected<const T *> getEntry(const Elf_Shdr &Section, uint32_t Entry) const;
197
198 Expected<std::vector<VerDef>>
199 getVersionDefinitions(const Elf_Shdr &Sec) const;
200 Expected<std::vector<VerNeed>> getVersionDependencies(
201 const Elf_Shdr &Sec,
202 WarningHandler WarnHandler = &defaultWarningHandler) const;
203 Expected<StringRef>
204 getSymbolVersionByIndex(uint32_t SymbolVersionIndex, bool &IsDefault,
205 SmallVector<Optional<VersionEntry>, 0> &VersionMap,
206 Optional<bool> IsSymHidden) const;
207
208 Expected<StringRef>
209 getStringTable(const Elf_Shdr &Section,
210 WarningHandler WarnHandler = &defaultWarningHandler) const;
211 Expected<StringRef> getStringTableForSymtab(const Elf_Shdr &Section) const;
212 Expected<StringRef> getStringTableForSymtab(const Elf_Shdr &Section,
213 Elf_Shdr_Range Sections) const;
214 Expected<StringRef> getLinkAsStrtab(const typename ELFT::Shdr &Sec) const;
215
216 Expected<ArrayRef<Elf_Word>> getSHNDXTable(const Elf_Shdr &Section) const;
217 Expected<ArrayRef<Elf_Word>> getSHNDXTable(const Elf_Shdr &Section,
218 Elf_Shdr_Range Sections) const;
219
220 Expected<uint64_t> getDynSymtabSize() const;
221
222 StringRef getRelocationTypeName(uint32_t Type) const;
223 void getRelocationTypeName(uint32_t Type,
224 SmallVectorImpl<char> &Result) const;
225 uint32_t getRelativeRelocationType() const;
226
227 std::string getDynamicTagAsString(unsigned Arch, uint64_t Type) const;
228 std::string getDynamicTagAsString(uint64_t Type) const;
229
230 /// Get the symbol for a given relocation.
231 Expected<const Elf_Sym *> getRelocationSymbol(const Elf_Rel &Rel,
232 const Elf_Shdr *SymTab) const;
233
234 Expected<SmallVector<Optional<VersionEntry>, 0>>
235 loadVersionMap(const Elf_Shdr *VerNeedSec, const Elf_Shdr *VerDefSec) const;
236
237 static Expected<ELFFile> create(StringRef Object);
238
239 bool isLE() const {
240 return getHeader().getDataEncoding() == ELF::ELFDATA2LSB;
241 }
242
243 bool isMipsELF64() const {
244 return getHeader().e_machine == ELF::EM_MIPS &&
245 getHeader().getFileClass() == ELF::ELFCLASS64;
246 }
247
248 bool isMips64EL() const { return isMipsELF64() && isLE(); }
249
250 Expected<Elf_Shdr_Range> sections() const;
251
252 Expected<Elf_Dyn_Range> dynamicEntries() const;
253
254 Expected<const uint8_t *>
255 toMappedAddr(uint64_t VAddr,
256 WarningHandler WarnHandler = &defaultWarningHandler) const;
257
258 Expected<Elf_Sym_Range> symbols(const Elf_Shdr *Sec) const {
259 if (!Sec)
260 return makeArrayRef<Elf_Sym>(nullptr, nullptr);
261 return getSectionContentsAsArray<Elf_Sym>(*Sec);
262 }
263
264 Expected<Elf_Rela_Range> relas(const Elf_Shdr &Sec) const {
265 return getSectionContentsAsArray<Elf_Rela>(Sec);
266 }
267
268 Expected<Elf_Rel_Range> rels(const Elf_Shdr &Sec) const {
269 return getSectionContentsAsArray<Elf_Rel>(Sec);
270 }
271
272 Expected<Elf_Relr_Range> relrs(const Elf_Shdr &Sec) const {
273 return getSectionContentsAsArray<Elf_Relr>(Sec);
274 }
275
276 std::vector<Elf_Rel> decode_relrs(Elf_Relr_Range relrs) const;
277
278 Expected<std::vector<Elf_Rela>> android_relas(const Elf_Shdr &Sec) const;
279
280 /// Iterate over program header table.
281 Expected<Elf_Phdr_Range> program_headers() const {
282 if (getHeader().e_phnum && getHeader().e_phentsize != sizeof(Elf_Phdr))
283 return createError("invalid e_phentsize: " +
284 Twine(getHeader().e_phentsize));
285
286 uint64_t HeadersSize =
287 (uint64_t)getHeader().e_phnum * getHeader().e_phentsize;
288 uint64_t PhOff = getHeader().e_phoff;
289 if (PhOff + HeadersSize < PhOff || PhOff + HeadersSize > getBufSize())
290 return createError("program headers are longer than binary of size " +
291 Twine(getBufSize()) + ": e_phoff = 0x" +
292 Twine::utohexstr(getHeader().e_phoff) +
293 ", e_phnum = " + Twine(getHeader().e_phnum) +
294 ", e_phentsize = " + Twine(getHeader().e_phentsize));
295
296 auto *Begin = reinterpret_cast<const Elf_Phdr *>(base() + PhOff);
297 return makeArrayRef(Begin, Begin + getHeader().e_phnum);
298 }
299
300 /// Get an iterator over notes in a program header.
301 ///
302 /// The program header must be of type \c PT_NOTE.
303 ///
304 /// \param Phdr the program header to iterate over.
305 /// \param Err [out] an error to support fallible iteration, which should
306 /// be checked after iteration ends.
307 Elf_Note_Iterator notes_begin(const Elf_Phdr &Phdr, Error &Err) const {
308 assert(Phdr.p_type == ELF::PT_NOTE && "Phdr is not of type PT_NOTE");
309 ErrorAsOutParameter ErrAsOutParam(&Err);
310 if (Phdr.p_offset + Phdr.p_filesz > getBufSize()) {
311 Err =
312 createError("invalid offset (0x" + Twine::utohexstr(Phdr.p_offset) +
313 ") or size (0x" + Twine::utohexstr(Phdr.p_filesz) + ")");
314 return Elf_Note_Iterator(Err);
315 }
316 return Elf_Note_Iterator(base() + Phdr.p_offset, Phdr.p_filesz, Err);
317 }
318
319 /// Get an iterator over notes in a section.
320 ///
321 /// The section must be of type \c SHT_NOTE.
322 ///
323 /// \param Shdr the section to iterate over.
324 /// \param Err [out] an error to support fallible iteration, which should
325 /// be checked after iteration ends.
326 Elf_Note_Iterator notes_begin(const Elf_Shdr &Shdr, Error &Err) const {
327 assert(Shdr.sh_type == ELF::SHT_NOTE && "Shdr is not of type SHT_NOTE");
328 ErrorAsOutParameter ErrAsOutParam(&Err);
329 if (Shdr.sh_offset + Shdr.sh_size > getBufSize()) {
330 Err =
331 createError("invalid offset (0x" + Twine::utohexstr(Shdr.sh_offset) +
332 ") or size (0x" + Twine::utohexstr(Shdr.sh_size) + ")");
333 return Elf_Note_Iterator(Err);
334 }
335 return Elf_Note_Iterator(base() + Shdr.sh_offset, Shdr.sh_size, Err);
336 }
337
338 /// Get the end iterator for notes.
339 Elf_Note_Iterator notes_end() const {
340 return Elf_Note_Iterator();
341 }
342
343 /// Get an iterator range over notes of a program header.
344 ///
345 /// The program header must be of type \c PT_NOTE.
346 ///
347 /// \param Phdr the program header to iterate over.
348 /// \param Err [out] an error to support fallible iteration, which should
349 /// be checked after iteration ends.
350 iterator_range<Elf_Note_Iterator> notes(const Elf_Phdr &Phdr,
351 Error &Err) const {
352 return make_range(notes_begin(Phdr, Err), notes_end());
353 }
354
355 /// Get an iterator range over notes of a section.
356 ///
357 /// The section must be of type \c SHT_NOTE.
358 ///
359 /// \param Shdr the section to iterate over.
360 /// \param Err [out] an error to support fallible iteration, which should
361 /// be checked after iteration ends.
362 iterator_range<Elf_Note_Iterator> notes(const Elf_Shdr &Shdr,
363 Error &Err) const {
364 return make_range(notes_begin(Shdr, Err), notes_end());
365 }
366
367 Expected<StringRef> getSectionStringTable(
368 Elf_Shdr_Range Sections,
369 WarningHandler WarnHandler = &defaultWarningHandler) const;
370 Expected<uint32_t> getSectionIndex(const Elf_Sym &Sym, Elf_Sym_Range Syms,
371 DataRegion<Elf_Word> ShndxTable) const;
372 Expected<const Elf_Shdr *> getSection(const Elf_Sym &Sym,
373 const Elf_Shdr *SymTab,
374 DataRegion<Elf_Word> ShndxTable) const;
375 Expected<const Elf_Shdr *> getSection(const Elf_Sym &Sym,
376 Elf_Sym_Range Symtab,
377 DataRegion<Elf_Word> ShndxTable) const;
378 Expected<const Elf_Shdr *> getSection(uint32_t Index) const;
379
380 Expected<const Elf_Sym *> getSymbol(const Elf_Shdr *Sec,
381 uint32_t Index) const;
382
383 Expected<StringRef>
384 getSectionName(const Elf_Shdr &Section,
385 WarningHandler WarnHandler = &defaultWarningHandler) const;
386 Expected<StringRef> getSectionName(const Elf_Shdr &Section,
387 StringRef DotShstrtab) const;
388 template <typename T>
389 Expected<ArrayRef<T>> getSectionContentsAsArray(const Elf_Shdr &Sec) const;
390 Expected<ArrayRef<uint8_t>> getSectionContents(const Elf_Shdr &Sec) const;
391 Expected<ArrayRef<uint8_t>> getSegmentContents(const Elf_Phdr &Phdr) const;
392 Expected<std::vector<BBAddrMap>> decodeBBAddrMap(const Elf_Shdr &Sec) const;
393
394 void createFakeSections();
395};
396
397using ELF32LEFile = ELFFile<ELF32LE>;
398using ELF64LEFile = ELFFile<ELF64LE>;
399using ELF32BEFile = ELFFile<ELF32BE>;
400using ELF64BEFile = ELFFile<ELF64BE>;
401
402template <class ELFT>
403inline Expected<const typename ELFT::Shdr *>
404getSection(typename ELFT::ShdrRange Sections, uint32_t Index) {
405 if (Index >= Sections.size())
406 return createError("invalid section index: " + Twine(Index));
407 return &Sections[Index];
408}
409
410template <class ELFT>
411inline Expected<uint32_t>
412getExtendedSymbolTableIndex(const typename ELFT::Sym &Sym, unsigned SymIndex,
413 DataRegion<typename ELFT::Word> ShndxTable) {
414 assert(Sym.st_shndx == ELF::SHN_XINDEX);
415 if (!ShndxTable.First)
416 return createError(
417 "found an extended symbol index (" + Twine(SymIndex) +
418 "), but unable to locate the extended symbol index table");
419
420 Expected<typename ELFT::Word> TableOrErr = ShndxTable[SymIndex];
421 if (!TableOrErr)
422 return createError("unable to read an extended symbol table at index " +
423 Twine(SymIndex) + ": " +
424 toString(TableOrErr.takeError()));
425 return *TableOrErr;
426}
427
428template <class ELFT>
429Expected<uint32_t>
430ELFFile<ELFT>::getSectionIndex(const Elf_Sym &Sym, Elf_Sym_Range Syms,
431 DataRegion<Elf_Word> ShndxTable) const {
432 uint32_t Index = Sym.st_shndx;
433 if (Index == ELF::SHN_XINDEX) {
434 Expected<uint32_t> ErrorOrIndex =
435 getExtendedSymbolTableIndex<ELFT>(Sym, &Sym - Syms.begin(), ShndxTable);
436 if (!ErrorOrIndex)
437 return ErrorOrIndex.takeError();
438 return *ErrorOrIndex;
439 }
440 if (Index == ELF::SHN_UNDEF || Index >= ELF::SHN_LORESERVE)
441 return 0;
442 return Index;
443}
444
445template <class ELFT>
446Expected<const typename ELFT::Shdr *>
447ELFFile<ELFT>::getSection(const Elf_Sym &Sym, const Elf_Shdr *SymTab,
448 DataRegion<Elf_Word> ShndxTable) const {
449 auto SymsOrErr = symbols(SymTab);
450 if (!SymsOrErr)
451 return SymsOrErr.takeError();
452 return getSection(Sym, *SymsOrErr, ShndxTable);
453}
454
455template <class ELFT>
456Expected<const typename ELFT::Shdr *>
457ELFFile<ELFT>::getSection(const Elf_Sym &Sym, Elf_Sym_Range Symbols,
458 DataRegion<Elf_Word> ShndxTable) const {
459 auto IndexOrErr = getSectionIndex(Sym, Symbols, ShndxTable);
460 if (!IndexOrErr)
461 return IndexOrErr.takeError();
462 uint32_t Index = *IndexOrErr;
463 if (Index == 0)
464 return nullptr;
465 return getSection(Index);
466}
467
468template <class ELFT>
469Expected<const typename ELFT::Sym *>
470ELFFile<ELFT>::getSymbol(const Elf_Shdr *Sec, uint32_t Index) const {
471 auto SymsOrErr = symbols(Sec);
472 if (!SymsOrErr)
473 return SymsOrErr.takeError();
474
475 Elf_Sym_Range Symbols = *SymsOrErr;
476 if (Index >= Symbols.size())
477 return createError("unable to get symbol from section " +
478 getSecIndexForError(*this, *Sec) +
479 ": invalid symbol index (" + Twine(Index) + ")");
480 return &Symbols[Index];
481}
482
483template <class ELFT>
484template <typename T>
485Expected<ArrayRef<T>>
486ELFFile<ELFT>::getSectionContentsAsArray(const Elf_Shdr &Sec) const {
487 if (Sec.sh_entsize != sizeof(T) && sizeof(T) != 1)
488 return createError("section " + getSecIndexForError(*this, Sec) +
489 " has invalid sh_entsize: expected " + Twine(sizeof(T)) +
490 ", but got " + Twine(Sec.sh_entsize));
491
492 uintX_t Offset = Sec.sh_offset;
493 uintX_t Size = Sec.sh_size;
494
495 if (Size % sizeof(T))
496 return createError("section " + getSecIndexForError(*this, Sec) +
497 " has an invalid sh_size (" + Twine(Size) +
498 ") which is not a multiple of its sh_entsize (" +
499 Twine(Sec.sh_entsize) + ")");
500 if (std::numeric_limits<uintX_t>::max() - Offset < Size)
501 return createError("section " + getSecIndexForError(*this, Sec) +
502 " has a sh_offset (0x" + Twine::utohexstr(Offset) +
503 ") + sh_size (0x" + Twine::utohexstr(Size) +
504 ") that cannot be represented");
505 if (Offset + Size > Buf.size())
506 return createError("section " + getSecIndexForError(*this, Sec) +
507 " has a sh_offset (0x" + Twine::utohexstr(Offset) +
508 ") + sh_size (0x" + Twine::utohexstr(Size) +
509 ") that is greater than the file size (0x" +
510 Twine::utohexstr(Buf.size()) + ")");
511
512 if (Offset % alignof(T))
513 // TODO: this error is untested.
514 return createError("unaligned data");
515
516 const T *Start = reinterpret_cast<const T *>(base() + Offset);
517 return makeArrayRef(Start, Size / sizeof(T));
518}
519
520template <class ELFT>
521Expected<ArrayRef<uint8_t>>
522ELFFile<ELFT>::getSegmentContents(const Elf_Phdr &Phdr) const {
523 uintX_t Offset = Phdr.p_offset;
524 uintX_t Size = Phdr.p_filesz;
525
526 if (std::numeric_limits<uintX_t>::max() - Offset < Size)
527 return createError("program header " + getPhdrIndexForError(*this, Phdr) +
528 " has a p_offset (0x" + Twine::utohexstr(Offset) +
529 ") + p_filesz (0x" + Twine::utohexstr(Size) +
530 ") that cannot be represented");
531 if (Offset + Size > Buf.size())
532 return createError("program header " + getPhdrIndexForError(*this, Phdr) +
533 " has a p_offset (0x" + Twine::utohexstr(Offset) +
534 ") + p_filesz (0x" + Twine::utohexstr(Size) +
535 ") that is greater than the file size (0x" +
536 Twine::utohexstr(Buf.size()) + ")");
537 return makeArrayRef(base() + Offset, Size);
538}
539
540template <class ELFT>
541Expected<ArrayRef<uint8_t>>
542ELFFile<ELFT>::getSectionContents(const Elf_Shdr &Sec) const {
543 return getSectionContentsAsArray<uint8_t>(Sec);
544}
545
546template <class ELFT>
547StringRef ELFFile<ELFT>::getRelocationTypeName(uint32_t Type) const {
548 return getELFRelocationTypeName(getHeader().e_machine, Type);
549}
550
551template <class ELFT>
552void ELFFile<ELFT>::getRelocationTypeName(uint32_t Type,
553 SmallVectorImpl<char> &Result) const {
554 if (!isMipsELF64()) {
555 StringRef Name = getRelocationTypeName(Type);
556 Result.append(Name.begin(), Name.end());
557 } else {
558 // The Mips N64 ABI allows up to three operations to be specified per
559 // relocation record. Unfortunately there's no easy way to test for the
560 // presence of N64 ELFs as they have no special flag that identifies them
561 // as being N64. We can safely assume at the moment that all Mips
562 // ELFCLASS64 ELFs are N64. New Mips64 ABIs should provide enough
563 // information to disambiguate between old vs new ABIs.
564 uint8_t Type1 = (Type >> 0) & 0xFF;
565 uint8_t Type2 = (Type >> 8) & 0xFF;
566 uint8_t Type3 = (Type >> 16) & 0xFF;
567
568 // Concat all three relocation type names.
569 StringRef Name = getRelocationTypeName(Type1);
570 Result.append(Name.begin(), Name.end());
571
572 Name = getRelocationTypeName(Type2);
573 Result.append(1, '/');
574 Result.append(Name.begin(), Name.end());
575
576 Name = getRelocationTypeName(Type3);
577 Result.append(1, '/');
578 Result.append(Name.begin(), Name.end());
579 }
580}
581
582template <class ELFT>
583uint32_t ELFFile<ELFT>::getRelativeRelocationType() const {
584 return getELFRelativeRelocationType(getHeader().e_machine);
585}
586
587template <class ELFT>
588Expected<SmallVector<Optional<VersionEntry>, 0>>
589ELFFile<ELFT>::loadVersionMap(const Elf_Shdr *VerNeedSec,
590 const Elf_Shdr *VerDefSec) const {
591 SmallVector<Optional<VersionEntry>, 0> VersionMap;
592
593 // The first two version indexes are reserved.
594 // Index 0 is VER_NDX_LOCAL, index 1 is VER_NDX_GLOBAL.
595 VersionMap.push_back(VersionEntry());
596 VersionMap.push_back(VersionEntry());
597
598 auto InsertEntry = [&](unsigned N, StringRef Version, bool IsVerdef) {
599 if (N >= VersionMap.size())
600 VersionMap.resize(N + 1);
601 VersionMap[N] = {std::string(Version), IsVerdef};
602 };
603
604 if (VerDefSec) {
605 Expected<std::vector<VerDef>> Defs = getVersionDefinitions(*VerDefSec);
606 if (!Defs)
607 return Defs.takeError();
608 for (const VerDef &Def : *Defs)
609 InsertEntry(Def.Ndx & ELF::VERSYM_VERSION, Def.Name, true);
610 }
611
612 if (VerNeedSec) {
613 Expected<std::vector<VerNeed>> Deps = getVersionDependencies(*VerNeedSec);
614 if (!Deps)
615 return Deps.takeError();
616 for (const VerNeed &Dep : *Deps)
617 for (const VernAux &Aux : Dep.AuxV)
618 InsertEntry(Aux.Other & ELF::VERSYM_VERSION, Aux.Name, false);
619 }
620
621 return VersionMap;
622}
623
624template <class ELFT>
625Expected<const typename ELFT::Sym *>
626ELFFile<ELFT>::getRelocationSymbol(const Elf_Rel &Rel,
627 const Elf_Shdr *SymTab) const {
628 uint32_t Index = Rel.getSymbol(isMips64EL());
629 if (Index == 0)
630 return nullptr;
631 return getEntry<Elf_Sym>(*SymTab, Index);
632}
633
634template <class ELFT>
635Expected<StringRef>
636ELFFile<ELFT>::getSectionStringTable(Elf_Shdr_Range Sections,
637 WarningHandler WarnHandler) const {
638 uint32_t Index = getHeader().e_shstrndx;
639 if (Index == ELF::SHN_XINDEX) {
640 // If the section name string table section index is greater than
641 // or equal to SHN_LORESERVE, then the actual index of the section name
642 // string table section is contained in the sh_link field of the section
643 // header at index 0.
644 if (Sections.empty())
645 return createError(
646 "e_shstrndx == SHN_XINDEX, but the section header table is empty");
647
648 Index = Sections[0].sh_link;
649 }
650
651 if (!Index) // no section string table.
652 return "";
653 if (Index >= Sections.size())
654 return createError("section header string table index " + Twine(Index) +
655 " does not exist");
656 return getStringTable(Sections[Index], WarnHandler);
657}
658
659/// This function finds the number of dynamic symbols using a GNU hash table.
660///
661/// @param Table The GNU hash table for .dynsym.
662template <class ELFT>
663static Expected<uint64_t>
664getDynSymtabSizeFromGnuHash(const typename ELFT::GnuHash &Table,
665 const void *BufEnd) {
666 using Elf_Word = typename ELFT::Word;
667 if (Table.nbuckets == 0)
668 return Table.symndx + 1;
669 uint64_t LastSymIdx = 0;
670 // Find the index of the first symbol in the last chain.
671 for (Elf_Word Val : Table.buckets())
672 LastSymIdx = std::max(LastSymIdx, (uint64_t)Val);
673 const Elf_Word *It =
674 reinterpret_cast<const Elf_Word *>(Table.values(LastSymIdx).end());
675 // Locate the end of the chain to find the last symbol index.
676 while (It < BufEnd && (*It & 1) == 0) {
677 ++LastSymIdx;
678 ++It;
679 }
680 if (It >= BufEnd) {
681 return createStringError(
682 object_error::parse_failed,
683 "no terminator found for GNU hash section before buffer end");
684 }
685 return LastSymIdx + 1;
686}
687
688/// This function determines the number of dynamic symbols. It reads section
689/// headers first. If section headers are not available, the number of
690/// symbols will be inferred by parsing dynamic hash tables.
691template <class ELFT>
692Expected<uint64_t> ELFFile<ELFT>::getDynSymtabSize() const {
693 // Read .dynsym section header first if available.
694 Expected<Elf_Shdr_Range> SectionsOrError = sections();
695 if (!SectionsOrError)
696 return SectionsOrError.takeError();
697 for (const Elf_Shdr &Sec : *SectionsOrError) {
698 if (Sec.sh_type == ELF::SHT_DYNSYM) {
699 if (Sec.sh_size % Sec.sh_entsize != 0) {
700 return createStringError(object_error::parse_failed,
701 "SHT_DYNSYM section has sh_size (" +
702 Twine(Sec.sh_size) + ") % sh_entsize (" +
703 Twine(Sec.sh_entsize) + ") that is not 0");
704 }
705 return Sec.sh_size / Sec.sh_entsize;
706 }
707 }
708
709 if (!SectionsOrError->empty()) {
710 // Section headers are available but .dynsym header is not found.
711 // Return 0 as .dynsym does not exist.
712 return 0;
713 }
714
715 // Section headers do not exist. Falling back to infer
716 // upper bound of .dynsym from .gnu.hash and .hash.
717 Expected<Elf_Dyn_Range> DynTable = dynamicEntries();
718 if (!DynTable)
719 return DynTable.takeError();
720 llvm::Optional<uint64_t> ElfHash;
721 llvm::Optional<uint64_t> ElfGnuHash;
722 for (const Elf_Dyn &Entry : *DynTable) {
723 switch (Entry.d_tag) {
724 case ELF::DT_HASH:
725 ElfHash = Entry.d_un.d_ptr;
726 break;
727 case ELF::DT_GNU_HASH:
728 ElfGnuHash = Entry.d_un.d_ptr;
729 break;
730 }
731 }
732 if (ElfGnuHash) {
733 Expected<const uint8_t *> TablePtr = toMappedAddr(*ElfGnuHash);
734 if (!TablePtr)
735 return TablePtr.takeError();
736 const Elf_GnuHash *Table =
737 reinterpret_cast<const Elf_GnuHash *>(TablePtr.get());
738 return getDynSymtabSizeFromGnuHash<ELFT>(*Table, this->Buf.bytes_end());
739 }
740
741 // Search SYSV hash table to try to find the upper bound of dynsym.
742 if (ElfHash) {
743 Expected<const uint8_t *> TablePtr = toMappedAddr(*ElfHash);
744 if (!TablePtr)
745 return TablePtr.takeError();
746 const Elf_Hash *Table = reinterpret_cast<const Elf_Hash *>(TablePtr.get());
747 return Table->nchain;
748 }
749 return 0;
750}
751
752template <class ELFT> ELFFile<ELFT>::ELFFile(StringRef Object) : Buf(Object) {}
753
754template <class ELFT>
755Expected<ELFFile<ELFT>> ELFFile<ELFT>::create(StringRef Object) {
756 if (sizeof(Elf_Ehdr) > Object.size())
757 return createError("invalid buffer: the size (" + Twine(Object.size()) +
758 ") is smaller than an ELF header (" +
759 Twine(sizeof(Elf_Ehdr)) + ")");
760 return ELFFile(Object);
761}
762
763/// Used by llvm-objdump -d (which needs sections for disassembly) to
764/// disassemble objects without a section header table (e.g. ET_CORE objects
765/// analyzed by linux perf or ET_EXEC with llvm-strip --strip-sections).
766template <class ELFT> void ELFFile<ELFT>::createFakeSections() {
767 if (!FakeSections.empty())
768 return;
769 auto PhdrsOrErr = program_headers();
770 if (!PhdrsOrErr)
771 return;
772
773 for (auto Phdr : *PhdrsOrErr) {
774 if (!(Phdr.p_type & ELF::PT_LOAD) || !(Phdr.p_flags & ELF::PF_X))
775 continue;
776 Elf_Shdr FakeShdr = {};
777 FakeShdr.sh_type = ELF::SHT_PROGBITS;
778 FakeShdr.sh_flags = ELF::SHF_ALLOC | ELF::SHF_EXECINSTR;
779 FakeShdr.sh_addr = Phdr.p_vaddr;
780 FakeShdr.sh_size = Phdr.p_memsz;
781 FakeShdr.sh_offset = Phdr.p_offset;
782 FakeSections.push_back(FakeShdr);
783 }
784}
785
786template <class ELFT>
787Expected<typename ELFT::ShdrRange> ELFFile<ELFT>::sections() const {
788 const uintX_t SectionTableOffset = getHeader().e_shoff;
789 if (SectionTableOffset == 0) {
790 if (!FakeSections.empty())
791 return makeArrayRef(FakeSections.data(), FakeSections.size());
792 return ArrayRef<Elf_Shdr>();
793 }
794
795 if (getHeader().e_shentsize != sizeof(Elf_Shdr))
796 return createError("invalid e_shentsize in ELF header: " +
797 Twine(getHeader().e_shentsize));
798
799 const uint64_t FileSize = Buf.size();
800 if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize ||
801 SectionTableOffset + (uintX_t)sizeof(Elf_Shdr) < SectionTableOffset)
802 return createError(
803 "section header table goes past the end of the file: e_shoff = 0x" +
804 Twine::utohexstr(SectionTableOffset));
805
806 // Invalid address alignment of section headers
807 if (SectionTableOffset & (alignof(Elf_Shdr) - 1))
808 // TODO: this error is untested.
809 return createError("invalid alignment of section headers");
810
811 const Elf_Shdr *First =
812 reinterpret_cast<const Elf_Shdr *>(base() + SectionTableOffset);
813
814 uintX_t NumSections = getHeader().e_shnum;
815 if (NumSections == 0)
816 NumSections = First->sh_size;
817
818 if (NumSections > UINT64_MAX / sizeof(Elf_Shdr))
819 return createError("invalid number of sections specified in the NULL "
820 "section's sh_size field (" +
821 Twine(NumSections) + ")");
822
823 const uint64_t SectionTableSize = NumSections * sizeof(Elf_Shdr);
824 if (SectionTableOffset + SectionTableSize < SectionTableOffset)
825 return createError(
826 "invalid section header table offset (e_shoff = 0x" +
827 Twine::utohexstr(SectionTableOffset) +
828 ") or invalid number of sections specified in the first section "
829 "header's sh_size field (0x" +
830 Twine::utohexstr(NumSections) + ")");
831
832 // Section table goes past end of file!
833 if (SectionTableOffset + SectionTableSize > FileSize)
834 return createError("section table goes past the end of file");
835 return makeArrayRef(First, NumSections);
836}
837
838template <class ELFT>
839template <typename T>
840Expected<const T *> ELFFile<ELFT>::getEntry(uint32_t Section,
841 uint32_t Entry) const {
842 auto SecOrErr = getSection(Section);
843 if (!SecOrErr)
844 return SecOrErr.takeError();
845 return getEntry<T>(**SecOrErr, Entry);
846}
847
848template <class ELFT>
849template <typename T>
850Expected<const T *> ELFFile<ELFT>::getEntry(const Elf_Shdr &Section,
851 uint32_t Entry) const {
852 Expected<ArrayRef<T>> EntriesOrErr = getSectionContentsAsArray<T>(Section);
853 if (!EntriesOrErr)
854 return EntriesOrErr.takeError();
855
856 ArrayRef<T> Arr = *EntriesOrErr;
857 if (Entry >= Arr.size())
858 return createError(
859 "can't read an entry at 0x" +
860 Twine::utohexstr(Entry * static_cast<uint64_t>(sizeof(T))) +
861 ": it goes past the end of the section (0x" +
862 Twine::utohexstr(Section.sh_size) + ")");
863 return &Arr[Entry];
864}
865
866template <typename ELFT>
867Expected<StringRef> ELFFile<ELFT>::getSymbolVersionByIndex(
868 uint32_t SymbolVersionIndex, bool &IsDefault,
869 SmallVector<Optional<VersionEntry>, 0> &VersionMap,
870 Optional<bool> IsSymHidden) const {
871 size_t VersionIndex = SymbolVersionIndex & llvm::ELF::VERSYM_VERSION;
872
873 // Special markers for unversioned symbols.
874 if (VersionIndex == llvm::ELF::VER_NDX_LOCAL ||
875 VersionIndex == llvm::ELF::VER_NDX_GLOBAL) {
876 IsDefault = false;
877 return "";
878 }
879
880 // Lookup this symbol in the version table.
881 if (VersionIndex >= VersionMap.size() || !VersionMap[VersionIndex])
882 return createError("SHT_GNU_versym section refers to a version index " +
883 Twine(VersionIndex) + " which is missing");
884
885 const VersionEntry &Entry = *VersionMap[VersionIndex];
886 // A default version (@@) is only available for defined symbols.
887 if (!Entry.IsVerDef || IsSymHidden.value_or(false))
888 IsDefault = false;
889 else
890 IsDefault = !(SymbolVersionIndex & llvm::ELF::VERSYM_HIDDEN);
891 return Entry.Name.c_str();
892}
893
894template <class ELFT>
895Expected<std::vector<VerDef>>
896ELFFile<ELFT>::getVersionDefinitions(const Elf_Shdr &Sec) const {
897 Expected<StringRef> StrTabOrErr = getLinkAsStrtab(Sec);
898 if (!StrTabOrErr)
899 return StrTabOrErr.takeError();
900
901 Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec);
902 if (!ContentsOrErr)
903 return createError("cannot read content of " + describe(*this, Sec) + ": " +
904 toString(ContentsOrErr.takeError()));
905
906 const uint8_t *Start = ContentsOrErr->data();
907 const uint8_t *End = Start + ContentsOrErr->size();
908
909 auto ExtractNextAux = [&](const uint8_t *&VerdauxBuf,
910 unsigned VerDefNdx) -> Expected<VerdAux> {
911 if (VerdauxBuf + sizeof(Elf_Verdaux) > End)
912 return createError("invalid " + describe(*this, Sec) +
913 ": version definition " + Twine(VerDefNdx) +
914 " refers to an auxiliary entry that goes past the end "
915 "of the section");
916
917 auto *Verdaux = reinterpret_cast<const Elf_Verdaux *>(VerdauxBuf);
918 VerdauxBuf += Verdaux->vda_next;
919
920 VerdAux Aux;
921 Aux.Offset = VerdauxBuf - Start;
922 if (Verdaux->vda_name <= StrTabOrErr->size())
923 Aux.Name = std::string(StrTabOrErr->drop_front(Verdaux->vda_name));
924 else
925 Aux.Name = ("<invalid vda_name: " + Twine(Verdaux->vda_name) + ">").str();
926 return Aux;
927 };
928
929 std::vector<VerDef> Ret;
930 const uint8_t *VerdefBuf = Start;
931 for (unsigned I = 1; I <= /*VerDefsNum=*/Sec.sh_info; ++I) {
932 if (VerdefBuf + sizeof(Elf_Verdef) > End)
933 return createError("invalid " + describe(*this, Sec) +
934 ": version definition " + Twine(I) +
935 " goes past the end of the section");
936
937 if (reinterpret_cast<uintptr_t>(VerdefBuf) % sizeof(uint32_t) != 0)
938 return createError(
939 "invalid " + describe(*this, Sec) +
940 ": found a misaligned version definition entry at offset 0x" +
941 Twine::utohexstr(VerdefBuf - Start));
942
943 unsigned Version = *reinterpret_cast<const Elf_Half *>(VerdefBuf);
944 if (Version != 1)
945 return createError("unable to dump " + describe(*this, Sec) +
946 ": version " + Twine(Version) +
947 " is not yet supported");
948
949 const Elf_Verdef *D = reinterpret_cast<const Elf_Verdef *>(VerdefBuf);
950 VerDef &VD = *Ret.emplace(Ret.end());
951 VD.Offset = VerdefBuf - Start;
952 VD.Version = D->vd_version;
953 VD.Flags = D->vd_flags;
954 VD.Ndx = D->vd_ndx;
955 VD.Cnt = D->vd_cnt;
956 VD.Hash = D->vd_hash;
957
958 const uint8_t *VerdauxBuf = VerdefBuf + D->vd_aux;
959 for (unsigned J = 0; J < D->vd_cnt; ++J) {
960 if (reinterpret_cast<uintptr_t>(VerdauxBuf) % sizeof(uint32_t) != 0)
961 return createError("invalid " + describe(*this, Sec) +
962 ": found a misaligned auxiliary entry at offset 0x" +
963 Twine::utohexstr(VerdauxBuf - Start));
964
965 Expected<VerdAux> AuxOrErr = ExtractNextAux(VerdauxBuf, I);
966 if (!AuxOrErr)
967 return AuxOrErr.takeError();
968
969 if (J == 0)
970 VD.Name = AuxOrErr->Name;
971 else
972 VD.AuxV.push_back(*AuxOrErr);
973 }
974
975 VerdefBuf += D->vd_next;
976 }
977
978 return Ret;
979}
980
981template <class ELFT>
982Expected<std::vector<VerNeed>>
983ELFFile<ELFT>::getVersionDependencies(const Elf_Shdr &Sec,
984 WarningHandler WarnHandler) const {
985 StringRef StrTab;
986 Expected<StringRef> StrTabOrErr = getLinkAsStrtab(Sec);
987 if (!StrTabOrErr) {
988 if (Error E = WarnHandler(toString(StrTabOrErr.takeError())))
989 return std::move(E);
990 } else {
991 StrTab = *StrTabOrErr;
992 }
993
994 Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec);
995 if (!ContentsOrErr)
996 return createError("cannot read content of " + describe(*this, Sec) + ": " +
997 toString(ContentsOrErr.takeError()));
998
999 const uint8_t *Start = ContentsOrErr->data();
1000 const uint8_t *End = Start + ContentsOrErr->size();
1001 const uint8_t *VerneedBuf = Start;
1002
1003 std::vector<VerNeed> Ret;
1004 for (unsigned I = 1; I <= /*VerneedNum=*/Sec.sh_info; ++I) {
1005 if (VerneedBuf + sizeof(Elf_Verdef) > End)
1006 return createError("invalid " + describe(*this, Sec) +
1007 ": version dependency " + Twine(I) +
1008 " goes past the end of the section");
1009
1010 if (reinterpret_cast<uintptr_t>(VerneedBuf) % sizeof(uint32_t) != 0)
1011 return createError(
1012 "invalid " + describe(*this, Sec) +
1013 ": found a misaligned version dependency entry at offset 0x" +
1014 Twine::utohexstr(VerneedBuf - Start));
1015
1016 unsigned Version = *reinterpret_cast<const Elf_Half *>(VerneedBuf);
1017 if (Version != 1)
1018 return createError("unable to dump " + describe(*this, Sec) +
1019 ": version " + Twine(Version) +
1020 " is not yet supported");
1021
1022 const Elf_Verneed *Verneed =
1023 reinterpret_cast<const Elf_Verneed *>(VerneedBuf);
1024
1025 VerNeed &VN = *Ret.emplace(Ret.end());
1026 VN.Version = Verneed->vn_version;
1027 VN.Cnt = Verneed->vn_cnt;
1028 VN.Offset = VerneedBuf - Start;
1029
1030 if (Verneed->vn_file < StrTab.size())
1031 VN.File = std::string(StrTab.drop_front(Verneed->vn_file));
1032 else
1033 VN.File = ("<corrupt vn_file: " + Twine(Verneed->vn_file) + ">").str();
1034
1035 const uint8_t *VernauxBuf = VerneedBuf + Verneed->vn_aux;
1036 for (unsigned J = 0; J < Verneed->vn_cnt; ++J) {
1037 if (reinterpret_cast<uintptr_t>(VernauxBuf) % sizeof(uint32_t) != 0)
1038 return createError("invalid " + describe(*this, Sec) +
1039 ": found a misaligned auxiliary entry at offset 0x" +
1040 Twine::utohexstr(VernauxBuf - Start));
1041
1042 if (VernauxBuf + sizeof(Elf_Vernaux) > End)
1043 return createError(
1044 "invalid " + describe(*this, Sec) + ": version dependency " +
1045 Twine(I) +
1046 " refers to an auxiliary entry that goes past the end "
1047 "of the section");
1048
1049 const Elf_Vernaux *Vernaux =
1050 reinterpret_cast<const Elf_Vernaux *>(VernauxBuf);
1051
1052 VernAux &Aux = *VN.AuxV.emplace(VN.AuxV.end());
1053 Aux.Hash = Vernaux->vna_hash;
1054 Aux.Flags = Vernaux->vna_flags;
1055 Aux.Other = Vernaux->vna_other;
1056 Aux.Offset = VernauxBuf - Start;
1057 if (StrTab.size() <= Vernaux->vna_name)
1058 Aux.Name = "<corrupt>";
1059 else
1060 Aux.Name = std::string(StrTab.drop_front(Vernaux->vna_name));
1061
1062 VernauxBuf += Vernaux->vna_next;
1063 }
1064 VerneedBuf += Verneed->vn_next;
1065 }
1066 return Ret;
1067}
1068
1069template <class ELFT>
1070Expected<const typename ELFT::Shdr *>
1071ELFFile<ELFT>::getSection(uint32_t Index) const {
1072 auto TableOrErr = sections();
1073 if (!TableOrErr)
1074 return TableOrErr.takeError();
1075 return object::getSection<ELFT>(*TableOrErr, Index);
1076}
1077
1078template <class ELFT>
1079Expected<StringRef>
1080ELFFile<ELFT>::getStringTable(const Elf_Shdr &Section,
1081 WarningHandler WarnHandler) const {
1082 if (Section.sh_type != ELF::SHT_STRTAB)
1083 if (Error E = WarnHandler("invalid sh_type for string table section " +
1084 getSecIndexForError(*this, Section) +
1085 ": expected SHT_STRTAB, but got " +
1086 object::getELFSectionTypeName(
1087 getHeader().e_machine, Section.sh_type)))
1088 return std::move(E);
1089
1090 auto V = getSectionContentsAsArray<char>(Section);
1091 if (!V)
1092 return V.takeError();
1093 ArrayRef<char> Data = *V;
1094 if (Data.empty())
1095 return createError("SHT_STRTAB string table section " +
1096 getSecIndexForError(*this, Section) + " is empty");
1097 if (Data.back() != '\0')
1098 return createError("SHT_STRTAB string table section " +
1099 getSecIndexForError(*this, Section) +
1100 " is non-null terminated");
1101 return StringRef(Data.begin(), Data.size());
1102}
1103
1104template <class ELFT>
1105Expected<ArrayRef<typename ELFT::Word>>
1106ELFFile<ELFT>::getSHNDXTable(const Elf_Shdr &Section) const {
1107 auto SectionsOrErr = sections();
1108 if (!SectionsOrErr)
1109 return SectionsOrErr.takeError();
1110 return getSHNDXTable(Section, *SectionsOrErr);
1111}
1112
1113template <class ELFT>
1114Expected<ArrayRef<typename ELFT::Word>>
1115ELFFile<ELFT>::getSHNDXTable(const Elf_Shdr &Section,
1116 Elf_Shdr_Range Sections) const {
1117 assert(Section.sh_type == ELF::SHT_SYMTAB_SHNDX);
1118 auto VOrErr = getSectionContentsAsArray<Elf_Word>(Section);
1119 if (!VOrErr)
1120 return VOrErr.takeError();
1121 ArrayRef<Elf_Word> V = *VOrErr;
1122 auto SymTableOrErr = object::getSection<ELFT>(Sections, Section.sh_link);
1123 if (!SymTableOrErr)
1124 return SymTableOrErr.takeError();
1125 const Elf_Shdr &SymTable = **SymTableOrErr;
1126 if (SymTable.sh_type != ELF::SHT_SYMTAB &&
1127 SymTable.sh_type != ELF::SHT_DYNSYM)
1128 return createError(
1129 "SHT_SYMTAB_SHNDX section is linked with " +
1130 object::getELFSectionTypeName(getHeader().e_machine, SymTable.sh_type) +
1131 " section (expected SHT_SYMTAB/SHT_DYNSYM)");
1132
1133 uint64_t Syms = SymTable.sh_size / sizeof(Elf_Sym);
1134 if (V.size() != Syms)
1135 return createError("SHT_SYMTAB_SHNDX has " + Twine(V.size()) +
1136 " entries, but the symbol table associated has " +
1137 Twine(Syms));
1138
1139 return V;
1140}
1141
1142template <class ELFT>
1143Expected<StringRef>
1144ELFFile<ELFT>::getStringTableForSymtab(const Elf_Shdr &Sec) const {
1145 auto SectionsOrErr = sections();
1146 if (!SectionsOrErr)
1147 return SectionsOrErr.takeError();
1148 return getStringTableForSymtab(Sec, *SectionsOrErr);
1149}
1150
1151template <class ELFT>
1152Expected<StringRef>
1153ELFFile<ELFT>::getStringTableForSymtab(const Elf_Shdr &Sec,
1154 Elf_Shdr_Range Sections) const {
1155
1156 if (Sec.sh_type != ELF::SHT_SYMTAB && Sec.sh_type != ELF::SHT_DYNSYM)
1157 return createError(
1158 "invalid sh_type for symbol table, expected SHT_SYMTAB or SHT_DYNSYM");
1159 Expected<const Elf_Shdr *> SectionOrErr =
1160 object::getSection<ELFT>(Sections, Sec.sh_link);
1161 if (!SectionOrErr)
1162 return SectionOrErr.takeError();
1163 return getStringTable(**SectionOrErr);
1164}
1165
1166template <class ELFT>
1167Expected<StringRef>
1168ELFFile<ELFT>::getLinkAsStrtab(const typename ELFT::Shdr &Sec) const {
1169 Expected<const typename ELFT::Shdr *> StrTabSecOrErr =
1170 getSection(Sec.sh_link);
1171 if (!StrTabSecOrErr)
1172 return createError("invalid section linked to " + describe(*this, Sec) +
1173 ": " + toString(StrTabSecOrErr.takeError()));
1174
1175 Expected<StringRef> StrTabOrErr = getStringTable(**StrTabSecOrErr);
1176 if (!StrTabOrErr)
1177 return createError("invalid string table linked to " +
1178 describe(*this, Sec) + ": " +
1179 toString(StrTabOrErr.takeError()));
1180 return *StrTabOrErr;
1181}
1182
1183template <class ELFT>
1184Expected<StringRef>
1185ELFFile<ELFT>::getSectionName(const Elf_Shdr &Section,
1186 WarningHandler WarnHandler) const {
1187 auto SectionsOrErr = sections();
1188 if (!SectionsOrErr)
1189 return SectionsOrErr.takeError();
1190 auto Table = getSectionStringTable(*SectionsOrErr, WarnHandler);
1191 if (!Table)
1192 return Table.takeError();
1193 return getSectionName(Section, *Table);
1194}
1195
1196template <class ELFT>
1197Expected<StringRef> ELFFile<ELFT>::getSectionName(const Elf_Shdr &Section,
1198 StringRef DotShstrtab) const {
1199 uint32_t Offset = Section.sh_name;
1200 if (Offset == 0)
1201 return StringRef();
1202 if (Offset >= DotShstrtab.size())
1203 return createError("a section " + getSecIndexForError(*this, Section) +
1204 " has an invalid sh_name (0x" +
1205 Twine::utohexstr(Offset) +
1206 ") offset which goes past the end of the "
1207 "section name string table");
1208 return StringRef(DotShstrtab.data() + Offset);
1209}
1210
1211/// This function returns the hash value for a symbol in the .dynsym section
1212/// Name of the API remains consistent as specified in the libelf
1213/// REF : http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#hash
1214inline unsigned hashSysV(StringRef SymbolName) {
1215 unsigned h = 0, g;
1216 for (char C : SymbolName) {
1217 h = (h << 4) + C;
1218 g = h & 0xf0000000L;
1219 if (g != 0)
1220 h ^= g >> 24;
1221 h &= ~g;
1222 }
1223 return h;
1224}
1225
1226} // end namespace object
1227} // end namespace llvm
1228
1229#endif // LLVM_OBJECT_ELF_H
1230

source code of llvm/include/llvm/Object/ELF.h