File indexing completed on 2026-05-10 08:44:18
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_OBJECT_ELF_H
0014 #define LLVM_OBJECT_ELF_H
0015
0016 #include "llvm/ADT/ArrayRef.h"
0017 #include "llvm/ADT/MapVector.h"
0018 #include "llvm/ADT/SmallString.h"
0019 #include "llvm/ADT/SmallVector.h"
0020 #include "llvm/ADT/StringRef.h"
0021 #include "llvm/BinaryFormat/ELF.h"
0022 #include "llvm/Object/ELFTypes.h"
0023 #include "llvm/Object/Error.h"
0024 #include "llvm/Support/Compiler.h"
0025 #include "llvm/Support/DataExtractor.h"
0026 #include "llvm/Support/Error.h"
0027 #include <cassert>
0028 #include <cstddef>
0029 #include <cstdint>
0030 #include <limits>
0031 #include <type_traits>
0032 #include <utility>
0033
0034 namespace llvm {
0035 namespace object {
0036
0037 struct VerdAux {
0038 unsigned Offset;
0039 std::string Name;
0040 };
0041
0042 struct VerDef {
0043 unsigned Offset;
0044 unsigned Version;
0045 unsigned Flags;
0046 unsigned Ndx;
0047 unsigned Cnt;
0048 unsigned Hash;
0049 std::string Name;
0050 std::vector<VerdAux> AuxV;
0051 };
0052
0053 struct VernAux {
0054 unsigned Hash;
0055 unsigned Flags;
0056 unsigned Other;
0057 unsigned Offset;
0058 std::string Name;
0059 };
0060
0061 struct VerNeed {
0062 unsigned Version;
0063 unsigned Cnt;
0064 unsigned Offset;
0065 std::string File;
0066 std::vector<VernAux> AuxV;
0067 };
0068
0069 struct VersionEntry {
0070 std::string Name;
0071 bool IsVerDef;
0072 };
0073
0074 StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type);
0075 uint32_t getELFRelativeRelocationType(uint32_t Machine);
0076 StringRef getELFSectionTypeName(uint32_t Machine, uint32_t Type);
0077
0078
0079 inline std::pair<unsigned char, unsigned char>
0080 getElfArchType(StringRef Object) {
0081 if (Object.size() < ELF::EI_NIDENT)
0082 return std::make_pair((uint8_t)ELF::ELFCLASSNONE,
0083 (uint8_t)ELF::ELFDATANONE);
0084 return std::make_pair((uint8_t)Object[ELF::EI_CLASS],
0085 (uint8_t)Object[ELF::EI_DATA]);
0086 }
0087
0088 enum PPCInstrMasks : uint64_t {
0089 PADDI_R12_NO_DISP = 0x0610000039800000,
0090 ADDIS_R12_TO_R2_NO_DISP = 0x3D820000,
0091 ADDI_R12_TO_R2_NO_DISP = 0x39820000,
0092 ADDI_R12_TO_R12_NO_DISP = 0x398C0000,
0093 PLD_R12_NO_DISP = 0x04100000E5800000,
0094 MTCTR_R12 = 0x7D8903A6,
0095 BCTR = 0x4E800420,
0096 };
0097
0098 template <class ELFT> class ELFFile;
0099
0100 template <class T> struct DataRegion {
0101
0102
0103 DataRegion(ArrayRef<T> Arr) : First(Arr.data()), Size(Arr.size()) {}
0104
0105
0106
0107 DataRegion(const T *Data, const uint8_t *BufferEnd)
0108 : First(Data), BufEnd(BufferEnd) {}
0109
0110 Expected<T> operator[](uint64_t N) {
0111 assert(Size || BufEnd);
0112 if (Size) {
0113 if (N >= *Size)
0114 return createError(
0115 "the index is greater than or equal to the number of entries (" +
0116 Twine(*Size) + ")");
0117 } else {
0118 const uint8_t *EntryStart = (const uint8_t *)First + N * sizeof(T);
0119 if (EntryStart + sizeof(T) > BufEnd)
0120 return createError("can't read past the end of the file");
0121 }
0122 return *(First + N);
0123 }
0124
0125 const T *First;
0126 std::optional<uint64_t> Size;
0127 const uint8_t *BufEnd = nullptr;
0128 };
0129
0130 template <class ELFT>
0131 static std::string getSecIndexForError(const ELFFile<ELFT> &Obj,
0132 const typename ELFT::Shdr &Sec) {
0133 auto TableOrErr = Obj.sections();
0134 if (TableOrErr)
0135 return "[index " + std::to_string(&Sec - &TableOrErr->front()) + "]";
0136
0137
0138
0139
0140 llvm::consumeError(TableOrErr.takeError());
0141 return "[unknown index]";
0142 }
0143
0144 template <class ELFT>
0145 static std::string describe(const ELFFile<ELFT> &Obj,
0146 const typename ELFT::Shdr &Sec) {
0147 unsigned SecNdx = &Sec - &cantFail(Obj.sections()).front();
0148 return (object::getELFSectionTypeName(Obj.getHeader().e_machine,
0149 Sec.sh_type) +
0150 " section with index " + Twine(SecNdx))
0151 .str();
0152 }
0153
0154 template <class ELFT>
0155 static std::string getPhdrIndexForError(const ELFFile<ELFT> &Obj,
0156 const typename ELFT::Phdr &Phdr) {
0157 auto Headers = Obj.program_headers();
0158 if (Headers)
0159 return ("[index " + Twine(&Phdr - &Headers->front()) + "]").str();
0160
0161 llvm::consumeError(Headers.takeError());
0162 return "[unknown index]";
0163 }
0164
0165 static inline Error defaultWarningHandler(const Twine &Msg) {
0166 return createError(Msg);
0167 }
0168
0169 template <class ELFT>
0170 static bool checkSectionOffsets(const typename ELFT::Phdr &Phdr,
0171 const typename ELFT::Shdr &Sec) {
0172
0173 if (Sec.sh_type == ELF::SHT_NOBITS)
0174 return true;
0175
0176 if (Sec.sh_offset < Phdr.p_offset)
0177 return false;
0178
0179
0180 if (Sec.sh_size == 0)
0181 return (Sec.sh_offset + 1 <= Phdr.p_offset + Phdr.p_filesz);
0182 return Sec.sh_offset + Sec.sh_size <= Phdr.p_offset + Phdr.p_filesz;
0183 }
0184
0185
0186
0187 template <class ELFT>
0188 static bool checkSectionVMA(const typename ELFT::Phdr &Phdr,
0189 const typename ELFT::Shdr &Sec) {
0190 if (!(Sec.sh_flags & ELF::SHF_ALLOC))
0191 return true;
0192
0193 if (Sec.sh_addr < Phdr.p_vaddr)
0194 return false;
0195
0196 bool IsTbss =
0197 (Sec.sh_type == ELF::SHT_NOBITS) && ((Sec.sh_flags & ELF::SHF_TLS) != 0);
0198
0199 bool IsTbssInNonTLS = IsTbss && Phdr.p_type != ELF::PT_TLS;
0200
0201 if (Sec.sh_size == 0 || IsTbssInNonTLS)
0202 return Sec.sh_addr + 1 <= Phdr.p_vaddr + Phdr.p_memsz;
0203 return Sec.sh_addr + Sec.sh_size <= Phdr.p_vaddr + Phdr.p_memsz;
0204 }
0205
0206 template <class ELFT>
0207 static bool isSectionInSegment(const typename ELFT::Phdr &Phdr,
0208 const typename ELFT::Shdr &Sec) {
0209 return checkSectionOffsets<ELFT>(Phdr, Sec) &&
0210 checkSectionVMA<ELFT>(Phdr, Sec);
0211 }
0212
0213
0214
0215 template <bool Is64>
0216 static Error decodeCrel(
0217 ArrayRef<uint8_t> Content,
0218 function_ref<void(uint64_t , bool )>
0219 HdrHandler,
0220 function_ref<void(Elf_Crel_Impl<Is64>)> EntryHandler) {
0221 DataExtractor Data(Content, true, 8);
0222 DataExtractor::Cursor Cur(0);
0223 const uint64_t Hdr = Data.getULEB128(Cur);
0224 size_t Count = Hdr / 8;
0225 const size_t FlagBits = Hdr & ELF::CREL_HDR_ADDEND ? 3 : 2;
0226 const size_t Shift = Hdr % ELF::CREL_HDR_ADDEND;
0227 using uint = typename Elf_Crel_Impl<Is64>::uint;
0228 uint Offset = 0, Addend = 0;
0229 HdrHandler(Count, Hdr & ELF::CREL_HDR_ADDEND);
0230 uint32_t SymIdx = 0, Type = 0;
0231 for (; Count; --Count) {
0232
0233
0234
0235 const uint8_t B = Data.getU8(Cur);
0236 Offset += B >> FlagBits;
0237 if (B >= 0x80)
0238 Offset += (Data.getULEB128(Cur) << (7 - FlagBits)) - (0x80 >> FlagBits);
0239
0240 if (B & 1)
0241 SymIdx += Data.getSLEB128(Cur);
0242 if (B & 2)
0243 Type += Data.getSLEB128(Cur);
0244 if (B & 4 & Hdr)
0245 Addend += Data.getSLEB128(Cur);
0246 if (!Cur)
0247 break;
0248 EntryHandler(
0249 {Offset << Shift, SymIdx, Type, std::make_signed_t<uint>(Addend)});
0250 }
0251 return Cur.takeError();
0252 }
0253
0254 template <class ELFT>
0255 class ELFFile {
0256 public:
0257 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
0258
0259
0260
0261
0262
0263
0264 using WarningHandler = llvm::function_ref<Error(const Twine &Msg)>;
0265
0266 const uint8_t *base() const { return Buf.bytes_begin(); }
0267 const uint8_t *end() const { return base() + getBufSize(); }
0268
0269 size_t getBufSize() const { return Buf.size(); }
0270
0271 private:
0272 StringRef Buf;
0273 std::vector<Elf_Shdr> FakeSections;
0274 SmallString<0> FakeSectionStrings;
0275
0276 ELFFile(StringRef Object);
0277
0278 public:
0279 const Elf_Ehdr &getHeader() const {
0280 return *reinterpret_cast<const Elf_Ehdr *>(base());
0281 }
0282
0283 template <typename T>
0284 Expected<const T *> getEntry(uint32_t Section, uint32_t Entry) const;
0285 template <typename T>
0286 Expected<const T *> getEntry(const Elf_Shdr &Section, uint32_t Entry) const;
0287
0288 Expected<std::vector<VerDef>>
0289 getVersionDefinitions(const Elf_Shdr &Sec) const;
0290 Expected<std::vector<VerNeed>> getVersionDependencies(
0291 const Elf_Shdr &Sec,
0292 WarningHandler WarnHandler = &defaultWarningHandler) const;
0293 Expected<StringRef> getSymbolVersionByIndex(
0294 uint32_t SymbolVersionIndex, bool &IsDefault,
0295 SmallVector<std::optional<VersionEntry>, 0> &VersionMap,
0296 std::optional<bool> IsSymHidden) const;
0297
0298 Expected<StringRef>
0299 getStringTable(const Elf_Shdr &Section,
0300 WarningHandler WarnHandler = &defaultWarningHandler) const;
0301 Expected<StringRef> getStringTableForSymtab(const Elf_Shdr &Section) const;
0302 Expected<StringRef> getStringTableForSymtab(const Elf_Shdr &Section,
0303 Elf_Shdr_Range Sections) const;
0304 Expected<StringRef> getLinkAsStrtab(const typename ELFT::Shdr &Sec) const;
0305
0306 Expected<ArrayRef<Elf_Word>> getSHNDXTable(const Elf_Shdr &Section) const;
0307 Expected<ArrayRef<Elf_Word>> getSHNDXTable(const Elf_Shdr &Section,
0308 Elf_Shdr_Range Sections) const;
0309
0310 Expected<uint64_t> getDynSymtabSize() const;
0311
0312 StringRef getRelocationTypeName(uint32_t Type) const;
0313 void getRelocationTypeName(uint32_t Type,
0314 SmallVectorImpl<char> &Result) const;
0315 uint32_t getRelativeRelocationType() const;
0316
0317 std::string getDynamicTagAsString(unsigned Arch, uint64_t Type) const;
0318 std::string getDynamicTagAsString(uint64_t Type) const;
0319
0320
0321 Expected<const Elf_Sym *> getRelocationSymbol(const Elf_Rel &Rel,
0322 const Elf_Shdr *SymTab) const;
0323
0324 Expected<SmallVector<std::optional<VersionEntry>, 0>>
0325 loadVersionMap(const Elf_Shdr *VerNeedSec, const Elf_Shdr *VerDefSec) const;
0326
0327 static Expected<ELFFile> create(StringRef Object);
0328
0329 bool isLE() const {
0330 return getHeader().getDataEncoding() == ELF::ELFDATA2LSB;
0331 }
0332
0333 bool isMipsELF64() const {
0334 return getHeader().e_machine == ELF::EM_MIPS &&
0335 getHeader().getFileClass() == ELF::ELFCLASS64;
0336 }
0337
0338 bool isMips64EL() const { return isMipsELF64() && isLE(); }
0339
0340 Expected<Elf_Shdr_Range> sections() const;
0341
0342 Expected<Elf_Dyn_Range> dynamicEntries() const;
0343
0344 Expected<const uint8_t *>
0345 toMappedAddr(uint64_t VAddr,
0346 WarningHandler WarnHandler = &defaultWarningHandler) const;
0347
0348 Expected<Elf_Sym_Range> symbols(const Elf_Shdr *Sec) const {
0349 if (!Sec)
0350 return ArrayRef<Elf_Sym>(nullptr, nullptr);
0351 return getSectionContentsAsArray<Elf_Sym>(*Sec);
0352 }
0353
0354 Expected<Elf_Rela_Range> relas(const Elf_Shdr &Sec) const {
0355 return getSectionContentsAsArray<Elf_Rela>(Sec);
0356 }
0357
0358 Expected<Elf_Rel_Range> rels(const Elf_Shdr &Sec) const {
0359 return getSectionContentsAsArray<Elf_Rel>(Sec);
0360 }
0361
0362 Expected<Elf_Relr_Range> relrs(const Elf_Shdr &Sec) const {
0363 return getSectionContentsAsArray<Elf_Relr>(Sec);
0364 }
0365
0366 std::vector<Elf_Rel> decode_relrs(Elf_Relr_Range relrs) const;
0367
0368 Expected<uint64_t> getCrelHeader(ArrayRef<uint8_t> Content) const;
0369 using RelsOrRelas = std::pair<std::vector<Elf_Rel>, std::vector<Elf_Rela>>;
0370 Expected<RelsOrRelas> decodeCrel(ArrayRef<uint8_t> Content) const;
0371 Expected<RelsOrRelas> crels(const Elf_Shdr &Sec) const;
0372
0373 Expected<std::vector<Elf_Rela>> android_relas(const Elf_Shdr &Sec) const;
0374
0375
0376 Expected<Elf_Phdr_Range> program_headers() const {
0377 if (getHeader().e_phnum && getHeader().e_phentsize != sizeof(Elf_Phdr))
0378 return createError("invalid e_phentsize: " +
0379 Twine(getHeader().e_phentsize));
0380
0381 uint64_t HeadersSize =
0382 (uint64_t)getHeader().e_phnum * getHeader().e_phentsize;
0383 uint64_t PhOff = getHeader().e_phoff;
0384 if (PhOff + HeadersSize < PhOff || PhOff + HeadersSize > getBufSize())
0385 return createError("program headers are longer than binary of size " +
0386 Twine(getBufSize()) + ": e_phoff = 0x" +
0387 Twine::utohexstr(getHeader().e_phoff) +
0388 ", e_phnum = " + Twine(getHeader().e_phnum) +
0389 ", e_phentsize = " + Twine(getHeader().e_phentsize));
0390
0391 auto *Begin = reinterpret_cast<const Elf_Phdr *>(base() + PhOff);
0392 return ArrayRef(Begin, Begin + getHeader().e_phnum);
0393 }
0394
0395
0396
0397
0398
0399
0400
0401
0402 Elf_Note_Iterator notes_begin(const Elf_Phdr &Phdr, Error &Err) const {
0403 assert(Phdr.p_type == ELF::PT_NOTE && "Phdr is not of type PT_NOTE");
0404 ErrorAsOutParameter ErrAsOutParam(Err);
0405 if (Phdr.p_offset + Phdr.p_filesz > getBufSize()) {
0406 Err =
0407 createError("invalid offset (0x" + Twine::utohexstr(Phdr.p_offset) +
0408 ") or size (0x" + Twine::utohexstr(Phdr.p_filesz) + ")");
0409 return Elf_Note_Iterator(Err);
0410 }
0411
0412
0413 if (Phdr.p_align != 0 && Phdr.p_align != 1 && Phdr.p_align != 4 &&
0414 Phdr.p_align != 8) {
0415 Err =
0416 createError("alignment (" + Twine(Phdr.p_align) + ") is not 4 or 8");
0417 return Elf_Note_Iterator(Err);
0418 }
0419 return Elf_Note_Iterator(base() + Phdr.p_offset, Phdr.p_filesz,
0420 std::max<size_t>(Phdr.p_align, 4), Err);
0421 }
0422
0423
0424
0425
0426
0427
0428
0429
0430 Elf_Note_Iterator notes_begin(const Elf_Shdr &Shdr, Error &Err) const {
0431 assert(Shdr.sh_type == ELF::SHT_NOTE && "Shdr is not of type SHT_NOTE");
0432 ErrorAsOutParameter ErrAsOutParam(Err);
0433 if (Shdr.sh_offset + Shdr.sh_size > getBufSize()) {
0434 Err =
0435 createError("invalid offset (0x" + Twine::utohexstr(Shdr.sh_offset) +
0436 ") or size (0x" + Twine::utohexstr(Shdr.sh_size) + ")");
0437 return Elf_Note_Iterator(Err);
0438 }
0439
0440 if (Shdr.sh_addralign != 0 && Shdr.sh_addralign != 1 &&
0441 Shdr.sh_addralign != 4 && Shdr.sh_addralign != 8) {
0442 Err = createError("alignment (" + Twine(Shdr.sh_addralign) +
0443 ") is not 4 or 8");
0444 return Elf_Note_Iterator(Err);
0445 }
0446 return Elf_Note_Iterator(base() + Shdr.sh_offset, Shdr.sh_size,
0447 std::max<size_t>(Shdr.sh_addralign, 4), Err);
0448 }
0449
0450
0451 Elf_Note_Iterator notes_end() const {
0452 return Elf_Note_Iterator();
0453 }
0454
0455
0456
0457
0458
0459
0460
0461
0462 iterator_range<Elf_Note_Iterator> notes(const Elf_Phdr &Phdr,
0463 Error &Err) const {
0464 return make_range(notes_begin(Phdr, Err), notes_end());
0465 }
0466
0467
0468
0469
0470
0471
0472
0473
0474 iterator_range<Elf_Note_Iterator> notes(const Elf_Shdr &Shdr,
0475 Error &Err) const {
0476 return make_range(notes_begin(Shdr, Err), notes_end());
0477 }
0478
0479 Expected<StringRef> getSectionStringTable(
0480 Elf_Shdr_Range Sections,
0481 WarningHandler WarnHandler = &defaultWarningHandler) const;
0482 Expected<uint32_t> getSectionIndex(const Elf_Sym &Sym, Elf_Sym_Range Syms,
0483 DataRegion<Elf_Word> ShndxTable) const;
0484 Expected<const Elf_Shdr *> getSection(const Elf_Sym &Sym,
0485 const Elf_Shdr *SymTab,
0486 DataRegion<Elf_Word> ShndxTable) const;
0487 Expected<const Elf_Shdr *> getSection(const Elf_Sym &Sym,
0488 Elf_Sym_Range Symtab,
0489 DataRegion<Elf_Word> ShndxTable) const;
0490 Expected<const Elf_Shdr *> getSection(uint32_t Index) const;
0491
0492 Expected<const Elf_Sym *> getSymbol(const Elf_Shdr *Sec,
0493 uint32_t Index) const;
0494
0495 Expected<StringRef>
0496 getSectionName(const Elf_Shdr &Section,
0497 WarningHandler WarnHandler = &defaultWarningHandler) const;
0498 Expected<StringRef> getSectionName(const Elf_Shdr &Section,
0499 StringRef DotShstrtab) const;
0500 template <typename T>
0501 Expected<ArrayRef<T>> getSectionContentsAsArray(const Elf_Shdr &Sec) const;
0502 Expected<ArrayRef<uint8_t>> getSectionContents(const Elf_Shdr &Sec) const;
0503 Expected<ArrayRef<uint8_t>> getSegmentContents(const Elf_Phdr &Phdr) const;
0504
0505
0506
0507
0508
0509
0510
0511
0512 Expected<std::vector<BBAddrMap>>
0513 decodeBBAddrMap(const Elf_Shdr &Sec, const Elf_Shdr *RelaSec = nullptr,
0514 std::vector<PGOAnalysisMap> *PGOAnalyses = nullptr) const;
0515
0516
0517
0518
0519
0520 Expected<MapVector<const Elf_Shdr *, const Elf_Shdr *>>
0521 getSectionAndRelocations(
0522 std::function<Expected<bool>(const Elf_Shdr &)> IsMatch) const;
0523
0524 void createFakeSections();
0525 };
0526
0527 using ELF32LEFile = ELFFile<ELF32LE>;
0528 using ELF64LEFile = ELFFile<ELF64LE>;
0529 using ELF32BEFile = ELFFile<ELF32BE>;
0530 using ELF64BEFile = ELFFile<ELF64BE>;
0531
0532 template <class ELFT>
0533 inline Expected<const typename ELFT::Shdr *>
0534 getSection(typename ELFT::ShdrRange Sections, uint32_t Index) {
0535 if (Index >= Sections.size())
0536 return createError("invalid section index: " + Twine(Index));
0537 return &Sections[Index];
0538 }
0539
0540 template <class ELFT>
0541 inline Expected<uint32_t>
0542 getExtendedSymbolTableIndex(const typename ELFT::Sym &Sym, unsigned SymIndex,
0543 DataRegion<typename ELFT::Word> ShndxTable) {
0544 assert(Sym.st_shndx == ELF::SHN_XINDEX);
0545 if (!ShndxTable.First)
0546 return createError(
0547 "found an extended symbol index (" + Twine(SymIndex) +
0548 "), but unable to locate the extended symbol index table");
0549
0550 Expected<typename ELFT::Word> TableOrErr = ShndxTable[SymIndex];
0551 if (!TableOrErr)
0552 return createError("unable to read an extended symbol table at index " +
0553 Twine(SymIndex) + ": " +
0554 toString(TableOrErr.takeError()));
0555 return *TableOrErr;
0556 }
0557
0558 template <class ELFT>
0559 Expected<uint32_t>
0560 ELFFile<ELFT>::getSectionIndex(const Elf_Sym &Sym, Elf_Sym_Range Syms,
0561 DataRegion<Elf_Word> ShndxTable) const {
0562 uint32_t Index = Sym.st_shndx;
0563 if (Index == ELF::SHN_XINDEX) {
0564 Expected<uint32_t> ErrorOrIndex =
0565 getExtendedSymbolTableIndex<ELFT>(Sym, &Sym - Syms.begin(), ShndxTable);
0566 if (!ErrorOrIndex)
0567 return ErrorOrIndex.takeError();
0568 return *ErrorOrIndex;
0569 }
0570 if (Index == ELF::SHN_UNDEF || Index >= ELF::SHN_LORESERVE)
0571 return 0;
0572 return Index;
0573 }
0574
0575 template <class ELFT>
0576 Expected<const typename ELFT::Shdr *>
0577 ELFFile<ELFT>::getSection(const Elf_Sym &Sym, const Elf_Shdr *SymTab,
0578 DataRegion<Elf_Word> ShndxTable) const {
0579 auto SymsOrErr = symbols(SymTab);
0580 if (!SymsOrErr)
0581 return SymsOrErr.takeError();
0582 return getSection(Sym, *SymsOrErr, ShndxTable);
0583 }
0584
0585 template <class ELFT>
0586 Expected<const typename ELFT::Shdr *>
0587 ELFFile<ELFT>::getSection(const Elf_Sym &Sym, Elf_Sym_Range Symbols,
0588 DataRegion<Elf_Word> ShndxTable) const {
0589 auto IndexOrErr = getSectionIndex(Sym, Symbols, ShndxTable);
0590 if (!IndexOrErr)
0591 return IndexOrErr.takeError();
0592 uint32_t Index = *IndexOrErr;
0593 if (Index == 0)
0594 return nullptr;
0595 return getSection(Index);
0596 }
0597
0598 template <class ELFT>
0599 Expected<const typename ELFT::Sym *>
0600 ELFFile<ELFT>::getSymbol(const Elf_Shdr *Sec, uint32_t Index) const {
0601 auto SymsOrErr = symbols(Sec);
0602 if (!SymsOrErr)
0603 return SymsOrErr.takeError();
0604
0605 Elf_Sym_Range Symbols = *SymsOrErr;
0606 if (Index >= Symbols.size())
0607 return createError("unable to get symbol from section " +
0608 getSecIndexForError(*this, *Sec) +
0609 ": invalid symbol index (" + Twine(Index) + ")");
0610 return &Symbols[Index];
0611 }
0612
0613 template <class ELFT>
0614 template <typename T>
0615 Expected<ArrayRef<T>>
0616 ELFFile<ELFT>::getSectionContentsAsArray(const Elf_Shdr &Sec) const {
0617 if (Sec.sh_entsize != sizeof(T) && sizeof(T) != 1)
0618 return createError("section " + getSecIndexForError(*this, Sec) +
0619 " has invalid sh_entsize: expected " + Twine(sizeof(T)) +
0620 ", but got " + Twine(Sec.sh_entsize));
0621
0622 uintX_t Offset = Sec.sh_offset;
0623 uintX_t Size = Sec.sh_size;
0624
0625 if (Size % sizeof(T))
0626 return createError("section " + getSecIndexForError(*this, Sec) +
0627 " has an invalid sh_size (" + Twine(Size) +
0628 ") which is not a multiple of its sh_entsize (" +
0629 Twine(Sec.sh_entsize) + ")");
0630 if (std::numeric_limits<uintX_t>::max() - Offset < Size)
0631 return createError("section " + getSecIndexForError(*this, Sec) +
0632 " has a sh_offset (0x" + Twine::utohexstr(Offset) +
0633 ") + sh_size (0x" + Twine::utohexstr(Size) +
0634 ") that cannot be represented");
0635 if (Offset + Size > Buf.size())
0636 return createError("section " + getSecIndexForError(*this, Sec) +
0637 " has a sh_offset (0x" + Twine::utohexstr(Offset) +
0638 ") + sh_size (0x" + Twine::utohexstr(Size) +
0639 ") that is greater than the file size (0x" +
0640 Twine::utohexstr(Buf.size()) + ")");
0641
0642 if (Offset % alignof(T))
0643
0644 return createError("unaligned data");
0645
0646 const T *Start = reinterpret_cast<const T *>(base() + Offset);
0647 return ArrayRef(Start, Size / sizeof(T));
0648 }
0649
0650 template <class ELFT>
0651 Expected<ArrayRef<uint8_t>>
0652 ELFFile<ELFT>::getSegmentContents(const Elf_Phdr &Phdr) const {
0653 uintX_t Offset = Phdr.p_offset;
0654 uintX_t Size = Phdr.p_filesz;
0655
0656 if (std::numeric_limits<uintX_t>::max() - Offset < Size)
0657 return createError("program header " + getPhdrIndexForError(*this, Phdr) +
0658 " has a p_offset (0x" + Twine::utohexstr(Offset) +
0659 ") + p_filesz (0x" + Twine::utohexstr(Size) +
0660 ") that cannot be represented");
0661 if (Offset + Size > Buf.size())
0662 return createError("program header " + getPhdrIndexForError(*this, Phdr) +
0663 " has a p_offset (0x" + Twine::utohexstr(Offset) +
0664 ") + p_filesz (0x" + Twine::utohexstr(Size) +
0665 ") that is greater than the file size (0x" +
0666 Twine::utohexstr(Buf.size()) + ")");
0667 return ArrayRef(base() + Offset, Size);
0668 }
0669
0670 template <class ELFT>
0671 Expected<ArrayRef<uint8_t>>
0672 ELFFile<ELFT>::getSectionContents(const Elf_Shdr &Sec) const {
0673 return getSectionContentsAsArray<uint8_t>(Sec);
0674 }
0675
0676 template <class ELFT>
0677 StringRef ELFFile<ELFT>::getRelocationTypeName(uint32_t Type) const {
0678 return getELFRelocationTypeName(getHeader().e_machine, Type);
0679 }
0680
0681 template <class ELFT>
0682 void ELFFile<ELFT>::getRelocationTypeName(uint32_t Type,
0683 SmallVectorImpl<char> &Result) const {
0684 if (!isMipsELF64()) {
0685 StringRef Name = getRelocationTypeName(Type);
0686 Result.append(Name.begin(), Name.end());
0687 } else {
0688
0689
0690
0691
0692
0693
0694 uint8_t Type1 = (Type >> 0) & 0xFF;
0695 uint8_t Type2 = (Type >> 8) & 0xFF;
0696 uint8_t Type3 = (Type >> 16) & 0xFF;
0697
0698
0699 StringRef Name = getRelocationTypeName(Type1);
0700 Result.append(Name.begin(), Name.end());
0701
0702 Name = getRelocationTypeName(Type2);
0703 Result.append(1, '/');
0704 Result.append(Name.begin(), Name.end());
0705
0706 Name = getRelocationTypeName(Type3);
0707 Result.append(1, '/');
0708 Result.append(Name.begin(), Name.end());
0709 }
0710 }
0711
0712 template <class ELFT>
0713 uint32_t ELFFile<ELFT>::getRelativeRelocationType() const {
0714 return getELFRelativeRelocationType(getHeader().e_machine);
0715 }
0716
0717 template <class ELFT>
0718 Expected<SmallVector<std::optional<VersionEntry>, 0>>
0719 ELFFile<ELFT>::loadVersionMap(const Elf_Shdr *VerNeedSec,
0720 const Elf_Shdr *VerDefSec) const {
0721 SmallVector<std::optional<VersionEntry>, 0> VersionMap;
0722
0723
0724
0725 VersionMap.push_back(VersionEntry());
0726 VersionMap.push_back(VersionEntry());
0727
0728 auto InsertEntry = [&](unsigned N, StringRef Version, bool IsVerdef) {
0729 if (N >= VersionMap.size())
0730 VersionMap.resize(N + 1);
0731 VersionMap[N] = {std::string(Version), IsVerdef};
0732 };
0733
0734 if (VerDefSec) {
0735 Expected<std::vector<VerDef>> Defs = getVersionDefinitions(*VerDefSec);
0736 if (!Defs)
0737 return Defs.takeError();
0738 for (const VerDef &Def : *Defs)
0739 InsertEntry(Def.Ndx & ELF::VERSYM_VERSION, Def.Name, true);
0740 }
0741
0742 if (VerNeedSec) {
0743 Expected<std::vector<VerNeed>> Deps = getVersionDependencies(*VerNeedSec);
0744 if (!Deps)
0745 return Deps.takeError();
0746 for (const VerNeed &Dep : *Deps)
0747 for (const VernAux &Aux : Dep.AuxV)
0748 InsertEntry(Aux.Other & ELF::VERSYM_VERSION, Aux.Name, false);
0749 }
0750
0751 return VersionMap;
0752 }
0753
0754 template <class ELFT>
0755 Expected<const typename ELFT::Sym *>
0756 ELFFile<ELFT>::getRelocationSymbol(const Elf_Rel &Rel,
0757 const Elf_Shdr *SymTab) const {
0758 uint32_t Index = Rel.getSymbol(isMips64EL());
0759 if (Index == 0)
0760 return nullptr;
0761 return getEntry<Elf_Sym>(*SymTab, Index);
0762 }
0763
0764 template <class ELFT>
0765 Expected<StringRef>
0766 ELFFile<ELFT>::getSectionStringTable(Elf_Shdr_Range Sections,
0767 WarningHandler WarnHandler) const {
0768 uint32_t Index = getHeader().e_shstrndx;
0769 if (Index == ELF::SHN_XINDEX) {
0770
0771
0772
0773
0774 if (Sections.empty())
0775 return createError(
0776 "e_shstrndx == SHN_XINDEX, but the section header table is empty");
0777
0778 Index = Sections[0].sh_link;
0779 }
0780
0781
0782
0783 if (!Index)
0784 return FakeSectionStrings;
0785
0786 if (Index >= Sections.size())
0787 return createError("section header string table index " + Twine(Index) +
0788 " does not exist");
0789 return getStringTable(Sections[Index], WarnHandler);
0790 }
0791
0792
0793
0794
0795 template <class ELFT>
0796 static Expected<uint64_t>
0797 getDynSymtabSizeFromGnuHash(const typename ELFT::GnuHash &Table,
0798 const void *BufEnd) {
0799 using Elf_Word = typename ELFT::Word;
0800 if (Table.nbuckets == 0)
0801 return Table.symndx + 1;
0802 uint64_t LastSymIdx = 0;
0803
0804 for (Elf_Word Val : Table.buckets())
0805 LastSymIdx = std::max(LastSymIdx, (uint64_t)Val);
0806 const Elf_Word *It =
0807 reinterpret_cast<const Elf_Word *>(Table.values(LastSymIdx).end());
0808
0809 while (It < BufEnd && (*It & 1) == 0) {
0810 ++LastSymIdx;
0811 ++It;
0812 }
0813 if (It >= BufEnd) {
0814 return createStringError(
0815 object_error::parse_failed,
0816 "no terminator found for GNU hash section before buffer end");
0817 }
0818 return LastSymIdx + 1;
0819 }
0820
0821
0822
0823
0824 template <class ELFT>
0825 Expected<uint64_t> ELFFile<ELFT>::getDynSymtabSize() const {
0826
0827 Expected<Elf_Shdr_Range> SectionsOrError = sections();
0828 if (!SectionsOrError)
0829 return SectionsOrError.takeError();
0830 for (const Elf_Shdr &Sec : *SectionsOrError) {
0831 if (Sec.sh_type == ELF::SHT_DYNSYM) {
0832 if (Sec.sh_size % Sec.sh_entsize != 0) {
0833 return createStringError(object_error::parse_failed,
0834 "SHT_DYNSYM section has sh_size (" +
0835 Twine(Sec.sh_size) + ") % sh_entsize (" +
0836 Twine(Sec.sh_entsize) + ") that is not 0");
0837 }
0838 return Sec.sh_size / Sec.sh_entsize;
0839 }
0840 }
0841
0842 if (!SectionsOrError->empty()) {
0843
0844
0845 return 0;
0846 }
0847
0848
0849
0850 Expected<Elf_Dyn_Range> DynTable = dynamicEntries();
0851 if (!DynTable)
0852 return DynTable.takeError();
0853 std::optional<uint64_t> ElfHash;
0854 std::optional<uint64_t> ElfGnuHash;
0855 for (const Elf_Dyn &Entry : *DynTable) {
0856 switch (Entry.d_tag) {
0857 case ELF::DT_HASH:
0858 ElfHash = Entry.d_un.d_ptr;
0859 break;
0860 case ELF::DT_GNU_HASH:
0861 ElfGnuHash = Entry.d_un.d_ptr;
0862 break;
0863 }
0864 }
0865 if (ElfGnuHash) {
0866 Expected<const uint8_t *> TablePtr = toMappedAddr(*ElfGnuHash);
0867 if (!TablePtr)
0868 return TablePtr.takeError();
0869 const Elf_GnuHash *Table =
0870 reinterpret_cast<const Elf_GnuHash *>(TablePtr.get());
0871 return getDynSymtabSizeFromGnuHash<ELFT>(*Table, this->Buf.bytes_end());
0872 }
0873
0874
0875 if (ElfHash) {
0876 Expected<const uint8_t *> TablePtr = toMappedAddr(*ElfHash);
0877 if (!TablePtr)
0878 return TablePtr.takeError();
0879 const Elf_Hash *Table = reinterpret_cast<const Elf_Hash *>(TablePtr.get());
0880 return Table->nchain;
0881 }
0882 return 0;
0883 }
0884
0885 template <class ELFT> ELFFile<ELFT>::ELFFile(StringRef Object) : Buf(Object) {}
0886
0887 template <class ELFT>
0888 Expected<ELFFile<ELFT>> ELFFile<ELFT>::create(StringRef Object) {
0889 if (sizeof(Elf_Ehdr) > Object.size())
0890 return createError("invalid buffer: the size (" + Twine(Object.size()) +
0891 ") is smaller than an ELF header (" +
0892 Twine(sizeof(Elf_Ehdr)) + ")");
0893 return ELFFile(Object);
0894 }
0895
0896
0897
0898
0899 template <class ELFT> void ELFFile<ELFT>::createFakeSections() {
0900 if (!FakeSections.empty())
0901 return;
0902 auto PhdrsOrErr = program_headers();
0903 if (!PhdrsOrErr)
0904 return;
0905
0906 FakeSectionStrings += '\0';
0907 for (auto [Idx, Phdr] : llvm::enumerate(*PhdrsOrErr)) {
0908 if (Phdr.p_type != ELF::PT_LOAD || !(Phdr.p_flags & ELF::PF_X))
0909 continue;
0910 Elf_Shdr FakeShdr = {};
0911 FakeShdr.sh_type = ELF::SHT_PROGBITS;
0912 FakeShdr.sh_flags = ELF::SHF_ALLOC | ELF::SHF_EXECINSTR;
0913 FakeShdr.sh_addr = Phdr.p_vaddr;
0914 FakeShdr.sh_size = Phdr.p_memsz;
0915 FakeShdr.sh_offset = Phdr.p_offset;
0916
0917 FakeShdr.sh_name = FakeSectionStrings.size();
0918 FakeSectionStrings += ("PT_LOAD#" + Twine(Idx)).str();
0919 FakeSectionStrings += '\0';
0920 FakeSections.push_back(FakeShdr);
0921 }
0922 }
0923
0924 template <class ELFT>
0925 Expected<typename ELFT::ShdrRange> ELFFile<ELFT>::sections() const {
0926 const uintX_t SectionTableOffset = getHeader().e_shoff;
0927 if (SectionTableOffset == 0) {
0928 if (!FakeSections.empty())
0929 return ArrayRef(FakeSections.data(), FakeSections.size());
0930 return ArrayRef<Elf_Shdr>();
0931 }
0932
0933 if (getHeader().e_shentsize != sizeof(Elf_Shdr))
0934 return createError("invalid e_shentsize in ELF header: " +
0935 Twine(getHeader().e_shentsize));
0936
0937 const uint64_t FileSize = Buf.size();
0938 if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize ||
0939 SectionTableOffset + (uintX_t)sizeof(Elf_Shdr) < SectionTableOffset)
0940 return createError(
0941 "section header table goes past the end of the file: e_shoff = 0x" +
0942 Twine::utohexstr(SectionTableOffset));
0943
0944
0945 if (SectionTableOffset & (alignof(Elf_Shdr) - 1))
0946
0947 return createError("invalid alignment of section headers");
0948
0949 const Elf_Shdr *First =
0950 reinterpret_cast<const Elf_Shdr *>(base() + SectionTableOffset);
0951
0952 uintX_t NumSections = getHeader().e_shnum;
0953 if (NumSections == 0)
0954 NumSections = First->sh_size;
0955
0956 if (NumSections > UINT64_MAX / sizeof(Elf_Shdr))
0957 return createError("invalid number of sections specified in the NULL "
0958 "section's sh_size field (" +
0959 Twine(NumSections) + ")");
0960
0961 const uint64_t SectionTableSize = NumSections * sizeof(Elf_Shdr);
0962 if (SectionTableOffset + SectionTableSize < SectionTableOffset)
0963 return createError(
0964 "invalid section header table offset (e_shoff = 0x" +
0965 Twine::utohexstr(SectionTableOffset) +
0966 ") or invalid number of sections specified in the first section "
0967 "header's sh_size field (0x" +
0968 Twine::utohexstr(NumSections) + ")");
0969
0970
0971 if (SectionTableOffset + SectionTableSize > FileSize)
0972 return createError("section table goes past the end of file");
0973 return ArrayRef(First, NumSections);
0974 }
0975
0976 template <class ELFT>
0977 template <typename T>
0978 Expected<const T *> ELFFile<ELFT>::getEntry(uint32_t Section,
0979 uint32_t Entry) const {
0980 auto SecOrErr = getSection(Section);
0981 if (!SecOrErr)
0982 return SecOrErr.takeError();
0983 return getEntry<T>(**SecOrErr, Entry);
0984 }
0985
0986 template <class ELFT>
0987 template <typename T>
0988 Expected<const T *> ELFFile<ELFT>::getEntry(const Elf_Shdr &Section,
0989 uint32_t Entry) const {
0990 Expected<ArrayRef<T>> EntriesOrErr = getSectionContentsAsArray<T>(Section);
0991 if (!EntriesOrErr)
0992 return EntriesOrErr.takeError();
0993
0994 ArrayRef<T> Arr = *EntriesOrErr;
0995 if (Entry >= Arr.size())
0996 return createError(
0997 "can't read an entry at 0x" +
0998 Twine::utohexstr(Entry * static_cast<uint64_t>(sizeof(T))) +
0999 ": it goes past the end of the section (0x" +
1000 Twine::utohexstr(Section.sh_size) + ")");
1001 return &Arr[Entry];
1002 }
1003
1004 template <typename ELFT>
1005 Expected<StringRef> ELFFile<ELFT>::getSymbolVersionByIndex(
1006 uint32_t SymbolVersionIndex, bool &IsDefault,
1007 SmallVector<std::optional<VersionEntry>, 0> &VersionMap,
1008 std::optional<bool> IsSymHidden) const {
1009 size_t VersionIndex = SymbolVersionIndex & llvm::ELF::VERSYM_VERSION;
1010
1011
1012 if (VersionIndex == llvm::ELF::VER_NDX_LOCAL ||
1013 VersionIndex == llvm::ELF::VER_NDX_GLOBAL) {
1014 IsDefault = false;
1015 return "";
1016 }
1017
1018
1019 if (VersionIndex >= VersionMap.size() || !VersionMap[VersionIndex])
1020 return createError("SHT_GNU_versym section refers to a version index " +
1021 Twine(VersionIndex) + " which is missing");
1022
1023 const VersionEntry &Entry = *VersionMap[VersionIndex];
1024
1025 if (!Entry.IsVerDef || IsSymHidden.value_or(false))
1026 IsDefault = false;
1027 else
1028 IsDefault = !(SymbolVersionIndex & llvm::ELF::VERSYM_HIDDEN);
1029 return Entry.Name.c_str();
1030 }
1031
1032 template <class ELFT>
1033 Expected<std::vector<VerDef>>
1034 ELFFile<ELFT>::getVersionDefinitions(const Elf_Shdr &Sec) const {
1035 Expected<StringRef> StrTabOrErr = getLinkAsStrtab(Sec);
1036 if (!StrTabOrErr)
1037 return StrTabOrErr.takeError();
1038
1039 Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec);
1040 if (!ContentsOrErr)
1041 return createError("cannot read content of " + describe(*this, Sec) + ": " +
1042 toString(ContentsOrErr.takeError()));
1043
1044 const uint8_t *Start = ContentsOrErr->data();
1045 const uint8_t *End = Start + ContentsOrErr->size();
1046
1047 auto ExtractNextAux = [&](const uint8_t *&VerdauxBuf,
1048 unsigned VerDefNdx) -> Expected<VerdAux> {
1049 if (VerdauxBuf + sizeof(Elf_Verdaux) > End)
1050 return createError("invalid " + describe(*this, Sec) +
1051 ": version definition " + Twine(VerDefNdx) +
1052 " refers to an auxiliary entry that goes past the end "
1053 "of the section");
1054
1055 auto *Verdaux = reinterpret_cast<const Elf_Verdaux *>(VerdauxBuf);
1056 VerdauxBuf += Verdaux->vda_next;
1057
1058 VerdAux Aux;
1059 Aux.Offset = VerdauxBuf - Start;
1060 if (Verdaux->vda_name <= StrTabOrErr->size())
1061 Aux.Name = std::string(StrTabOrErr->drop_front(Verdaux->vda_name));
1062 else
1063 Aux.Name = ("<invalid vda_name: " + Twine(Verdaux->vda_name) + ">").str();
1064 return Aux;
1065 };
1066
1067 std::vector<VerDef> Ret;
1068 const uint8_t *VerdefBuf = Start;
1069 for (unsigned I = 1; I <= Sec.sh_info; ++I) {
1070 if (VerdefBuf + sizeof(Elf_Verdef) > End)
1071 return createError("invalid " + describe(*this, Sec) +
1072 ": version definition " + Twine(I) +
1073 " goes past the end of the section");
1074
1075 if (reinterpret_cast<uintptr_t>(VerdefBuf) % sizeof(uint32_t) != 0)
1076 return createError(
1077 "invalid " + describe(*this, Sec) +
1078 ": found a misaligned version definition entry at offset 0x" +
1079 Twine::utohexstr(VerdefBuf - Start));
1080
1081 unsigned Version = *reinterpret_cast<const Elf_Half *>(VerdefBuf);
1082 if (Version != 1)
1083 return createError("unable to dump " + describe(*this, Sec) +
1084 ": version " + Twine(Version) +
1085 " is not yet supported");
1086
1087 const Elf_Verdef *D = reinterpret_cast<const Elf_Verdef *>(VerdefBuf);
1088 VerDef &VD = *Ret.emplace(Ret.end());
1089 VD.Offset = VerdefBuf - Start;
1090 VD.Version = D->vd_version;
1091 VD.Flags = D->vd_flags;
1092 VD.Ndx = D->vd_ndx;
1093 VD.Cnt = D->vd_cnt;
1094 VD.Hash = D->vd_hash;
1095
1096 const uint8_t *VerdauxBuf = VerdefBuf + D->vd_aux;
1097 for (unsigned J = 0; J < D->vd_cnt; ++J) {
1098 if (reinterpret_cast<uintptr_t>(VerdauxBuf) % sizeof(uint32_t) != 0)
1099 return createError("invalid " + describe(*this, Sec) +
1100 ": found a misaligned auxiliary entry at offset 0x" +
1101 Twine::utohexstr(VerdauxBuf - Start));
1102
1103 Expected<VerdAux> AuxOrErr = ExtractNextAux(VerdauxBuf, I);
1104 if (!AuxOrErr)
1105 return AuxOrErr.takeError();
1106
1107 if (J == 0)
1108 VD.Name = AuxOrErr->Name;
1109 else
1110 VD.AuxV.push_back(*AuxOrErr);
1111 }
1112
1113 VerdefBuf += D->vd_next;
1114 }
1115
1116 return Ret;
1117 }
1118
1119 template <class ELFT>
1120 Expected<std::vector<VerNeed>>
1121 ELFFile<ELFT>::getVersionDependencies(const Elf_Shdr &Sec,
1122 WarningHandler WarnHandler) const {
1123 StringRef StrTab;
1124 Expected<StringRef> StrTabOrErr = getLinkAsStrtab(Sec);
1125 if (!StrTabOrErr) {
1126 if (Error E = WarnHandler(toString(StrTabOrErr.takeError())))
1127 return std::move(E);
1128 } else {
1129 StrTab = *StrTabOrErr;
1130 }
1131
1132 Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec);
1133 if (!ContentsOrErr)
1134 return createError("cannot read content of " + describe(*this, Sec) + ": " +
1135 toString(ContentsOrErr.takeError()));
1136
1137 const uint8_t *Start = ContentsOrErr->data();
1138 const uint8_t *End = Start + ContentsOrErr->size();
1139 const uint8_t *VerneedBuf = Start;
1140
1141 std::vector<VerNeed> Ret;
1142 for (unsigned I = 1; I <= Sec.sh_info; ++I) {
1143 if (VerneedBuf + sizeof(Elf_Verdef) > End)
1144 return createError("invalid " + describe(*this, Sec) +
1145 ": version dependency " + Twine(I) +
1146 " goes past the end of the section");
1147
1148 if (reinterpret_cast<uintptr_t>(VerneedBuf) % sizeof(uint32_t) != 0)
1149 return createError(
1150 "invalid " + describe(*this, Sec) +
1151 ": found a misaligned version dependency entry at offset 0x" +
1152 Twine::utohexstr(VerneedBuf - Start));
1153
1154 unsigned Version = *reinterpret_cast<const Elf_Half *>(VerneedBuf);
1155 if (Version != 1)
1156 return createError("unable to dump " + describe(*this, Sec) +
1157 ": version " + Twine(Version) +
1158 " is not yet supported");
1159
1160 const Elf_Verneed *Verneed =
1161 reinterpret_cast<const Elf_Verneed *>(VerneedBuf);
1162
1163 VerNeed &VN = *Ret.emplace(Ret.end());
1164 VN.Version = Verneed->vn_version;
1165 VN.Cnt = Verneed->vn_cnt;
1166 VN.Offset = VerneedBuf - Start;
1167
1168 if (Verneed->vn_file < StrTab.size())
1169 VN.File = std::string(StrTab.data() + Verneed->vn_file);
1170 else
1171 VN.File = ("<corrupt vn_file: " + Twine(Verneed->vn_file) + ">").str();
1172
1173 const uint8_t *VernauxBuf = VerneedBuf + Verneed->vn_aux;
1174 for (unsigned J = 0; J < Verneed->vn_cnt; ++J) {
1175 if (reinterpret_cast<uintptr_t>(VernauxBuf) % sizeof(uint32_t) != 0)
1176 return createError("invalid " + describe(*this, Sec) +
1177 ": found a misaligned auxiliary entry at offset 0x" +
1178 Twine::utohexstr(VernauxBuf - Start));
1179
1180 if (VernauxBuf + sizeof(Elf_Vernaux) > End)
1181 return createError(
1182 "invalid " + describe(*this, Sec) + ": version dependency " +
1183 Twine(I) +
1184 " refers to an auxiliary entry that goes past the end "
1185 "of the section");
1186
1187 const Elf_Vernaux *Vernaux =
1188 reinterpret_cast<const Elf_Vernaux *>(VernauxBuf);
1189
1190 VernAux &Aux = *VN.AuxV.emplace(VN.AuxV.end());
1191 Aux.Hash = Vernaux->vna_hash;
1192 Aux.Flags = Vernaux->vna_flags;
1193 Aux.Other = Vernaux->vna_other;
1194 Aux.Offset = VernauxBuf - Start;
1195 if (StrTab.size() <= Vernaux->vna_name)
1196 Aux.Name = "<corrupt>";
1197 else
1198 Aux.Name = std::string(StrTab.drop_front(Vernaux->vna_name));
1199
1200 VernauxBuf += Vernaux->vna_next;
1201 }
1202 VerneedBuf += Verneed->vn_next;
1203 }
1204 return Ret;
1205 }
1206
1207 template <class ELFT>
1208 Expected<const typename ELFT::Shdr *>
1209 ELFFile<ELFT>::getSection(uint32_t Index) const {
1210 auto TableOrErr = sections();
1211 if (!TableOrErr)
1212 return TableOrErr.takeError();
1213 return object::getSection<ELFT>(*TableOrErr, Index);
1214 }
1215
1216 template <class ELFT>
1217 Expected<StringRef>
1218 ELFFile<ELFT>::getStringTable(const Elf_Shdr &Section,
1219 WarningHandler WarnHandler) const {
1220 if (Section.sh_type != ELF::SHT_STRTAB)
1221 if (Error E = WarnHandler("invalid sh_type for string table section " +
1222 getSecIndexForError(*this, Section) +
1223 ": expected SHT_STRTAB, but got " +
1224 object::getELFSectionTypeName(
1225 getHeader().e_machine, Section.sh_type)))
1226 return std::move(E);
1227
1228 auto V = getSectionContentsAsArray<char>(Section);
1229 if (!V)
1230 return V.takeError();
1231 ArrayRef<char> Data = *V;
1232 if (Data.empty())
1233 return createError("SHT_STRTAB string table section " +
1234 getSecIndexForError(*this, Section) + " is empty");
1235 if (Data.back() != '\0')
1236 return createError("SHT_STRTAB string table section " +
1237 getSecIndexForError(*this, Section) +
1238 " is non-null terminated");
1239 return StringRef(Data.begin(), Data.size());
1240 }
1241
1242 template <class ELFT>
1243 Expected<ArrayRef<typename ELFT::Word>>
1244 ELFFile<ELFT>::getSHNDXTable(const Elf_Shdr &Section) const {
1245 auto SectionsOrErr = sections();
1246 if (!SectionsOrErr)
1247 return SectionsOrErr.takeError();
1248 return getSHNDXTable(Section, *SectionsOrErr);
1249 }
1250
1251 template <class ELFT>
1252 Expected<ArrayRef<typename ELFT::Word>>
1253 ELFFile<ELFT>::getSHNDXTable(const Elf_Shdr &Section,
1254 Elf_Shdr_Range Sections) const {
1255 assert(Section.sh_type == ELF::SHT_SYMTAB_SHNDX);
1256 auto VOrErr = getSectionContentsAsArray<Elf_Word>(Section);
1257 if (!VOrErr)
1258 return VOrErr.takeError();
1259 ArrayRef<Elf_Word> V = *VOrErr;
1260 auto SymTableOrErr = object::getSection<ELFT>(Sections, Section.sh_link);
1261 if (!SymTableOrErr)
1262 return SymTableOrErr.takeError();
1263 const Elf_Shdr &SymTable = **SymTableOrErr;
1264 if (SymTable.sh_type != ELF::SHT_SYMTAB &&
1265 SymTable.sh_type != ELF::SHT_DYNSYM)
1266 return createError(
1267 "SHT_SYMTAB_SHNDX section is linked with " +
1268 object::getELFSectionTypeName(getHeader().e_machine, SymTable.sh_type) +
1269 " section (expected SHT_SYMTAB/SHT_DYNSYM)");
1270
1271 uint64_t Syms = SymTable.sh_size / sizeof(Elf_Sym);
1272 if (V.size() != Syms)
1273 return createError("SHT_SYMTAB_SHNDX has " + Twine(V.size()) +
1274 " entries, but the symbol table associated has " +
1275 Twine(Syms));
1276
1277 return V;
1278 }
1279
1280 template <class ELFT>
1281 Expected<StringRef>
1282 ELFFile<ELFT>::getStringTableForSymtab(const Elf_Shdr &Sec) const {
1283 auto SectionsOrErr = sections();
1284 if (!SectionsOrErr)
1285 return SectionsOrErr.takeError();
1286 return getStringTableForSymtab(Sec, *SectionsOrErr);
1287 }
1288
1289 template <class ELFT>
1290 Expected<StringRef>
1291 ELFFile<ELFT>::getStringTableForSymtab(const Elf_Shdr &Sec,
1292 Elf_Shdr_Range Sections) const {
1293
1294 if (Sec.sh_type != ELF::SHT_SYMTAB && Sec.sh_type != ELF::SHT_DYNSYM)
1295 return createError(
1296 "invalid sh_type for symbol table, expected SHT_SYMTAB or SHT_DYNSYM");
1297 Expected<const Elf_Shdr *> SectionOrErr =
1298 object::getSection<ELFT>(Sections, Sec.sh_link);
1299 if (!SectionOrErr)
1300 return SectionOrErr.takeError();
1301 return getStringTable(**SectionOrErr);
1302 }
1303
1304 template <class ELFT>
1305 Expected<StringRef>
1306 ELFFile<ELFT>::getLinkAsStrtab(const typename ELFT::Shdr &Sec) const {
1307 Expected<const typename ELFT::Shdr *> StrTabSecOrErr =
1308 getSection(Sec.sh_link);
1309 if (!StrTabSecOrErr)
1310 return createError("invalid section linked to " + describe(*this, Sec) +
1311 ": " + toString(StrTabSecOrErr.takeError()));
1312
1313 Expected<StringRef> StrTabOrErr = getStringTable(**StrTabSecOrErr);
1314 if (!StrTabOrErr)
1315 return createError("invalid string table linked to " +
1316 describe(*this, Sec) + ": " +
1317 toString(StrTabOrErr.takeError()));
1318 return *StrTabOrErr;
1319 }
1320
1321 template <class ELFT>
1322 Expected<StringRef>
1323 ELFFile<ELFT>::getSectionName(const Elf_Shdr &Section,
1324 WarningHandler WarnHandler) const {
1325 auto SectionsOrErr = sections();
1326 if (!SectionsOrErr)
1327 return SectionsOrErr.takeError();
1328 auto Table = getSectionStringTable(*SectionsOrErr, WarnHandler);
1329 if (!Table)
1330 return Table.takeError();
1331 return getSectionName(Section, *Table);
1332 }
1333
1334 template <class ELFT>
1335 Expected<StringRef> ELFFile<ELFT>::getSectionName(const Elf_Shdr &Section,
1336 StringRef DotShstrtab) const {
1337 uint32_t Offset = Section.sh_name;
1338 if (Offset == 0)
1339 return StringRef();
1340 if (Offset >= DotShstrtab.size())
1341 return createError("a section " + getSecIndexForError(*this, Section) +
1342 " has an invalid sh_name (0x" +
1343 Twine::utohexstr(Offset) +
1344 ") offset which goes past the end of the "
1345 "section name string table");
1346 return StringRef(DotShstrtab.data() + Offset);
1347 }
1348
1349
1350
1351
1352 inline uint32_t hashSysV(StringRef SymbolName) {
1353 uint32_t H = 0;
1354 for (uint8_t C : SymbolName) {
1355 H = (H << 4) + C;
1356 H ^= (H >> 24) & 0xf0;
1357 }
1358 return H & 0x0fffffff;
1359 }
1360
1361
1362
1363
1364 inline uint32_t hashGnu(StringRef Name) {
1365 uint32_t H = 5381;
1366 for (uint8_t C : Name)
1367 H = (H << 5) + H + C;
1368 return H;
1369 }
1370
1371 extern template class LLVM_TEMPLATE_ABI llvm::object::ELFFile<ELF32LE>;
1372 extern template class LLVM_TEMPLATE_ABI llvm::object::ELFFile<ELF32BE>;
1373 extern template class LLVM_TEMPLATE_ABI llvm::object::ELFFile<ELF64LE>;
1374 extern template class LLVM_TEMPLATE_ABI llvm::object::ELFFile<ELF64BE>;
1375
1376 }
1377 }
1378
1379 #endif