diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2022-07-03 14:10:23 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2022-07-03 14:10:23 +0000 |
commit | 145449b1e420787bb99721a429341fa6be3adfb6 (patch) | |
tree | 1d56ae694a6de602e348dd80165cf881a36600ed /llvm/lib/Object/ELF.cpp | |
parent | ecbca9f5fb7d7613d2b94982c4825eb0d33d6842 (diff) |
Diffstat (limited to 'llvm/lib/Object/ELF.cpp')
-rw-r--r-- | llvm/lib/Object/ELF.cpp | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/llvm/lib/Object/ELF.cpp b/llvm/lib/Object/ELF.cpp index 6e56da1a31f3..6acf4543be5a 100644 --- a/llvm/lib/Object/ELF.cpp +++ b/llvm/lib/Object/ELF.cpp @@ -166,6 +166,13 @@ StringRef llvm::object::getELFRelocationTypeName(uint32_t Machine, break; } break; + case ELF::EM_LOONGARCH: + switch (Type) { +#include "llvm/BinaryFormat/ELFRelocs/LoongArch.def" + default: + break; + } + break; default: break; } @@ -288,6 +295,7 @@ StringRef llvm::object::getELFSectionTypeName(uint32_t Machine, unsigned Type) { STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_SYMPART); STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_PART_EHDR); STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_PART_PHDR); + STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_BB_ADDR_MAP_V0); STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_BB_ADDR_MAP); STRINGIFY_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES); STRINGIFY_ENUM_CASE(ELF, SHT_GNU_HASH); @@ -561,11 +569,9 @@ Expected<typename ELFT::DynRange> ELFFile<ELFT>::dynamicEntries() const { } if (Dyn.empty()) - // TODO: this error is untested. return createError("invalid empty dynamic section"); if (Dyn.back().d_tag != ELF::DT_NULL) - // TODO: this error is untested. return createError("dynamic sections must be DT_NULL terminated"); return Dyn; @@ -635,7 +641,6 @@ ELFFile<ELFT>::decodeBBAddrMap(const Elf_Shdr &Sec) const { DataExtractor::Cursor Cur(0); Error ULEBSizeErr = Error::success(); - // Helper to extract and decode the next ULEB128 value as uint32_t. // Returns zero and sets ULEBSizeErr if the ULEB128 value exceeds the uint32_t // limit. @@ -655,18 +660,34 @@ ELFFile<ELFT>::decodeBBAddrMap(const Elf_Shdr &Sec) const { return static_cast<uint32_t>(Value); }; + uint8_t Version = 0; while (!ULEBSizeErr && Cur && Cur.tell() < Content.size()) { + if (Sec.sh_type == ELF::SHT_LLVM_BB_ADDR_MAP) { + Version = Data.getU8(Cur); + if (!Cur) + break; + if (Version > 1) + return createError("unsupported SHT_LLVM_BB_ADDR_MAP version: " + + Twine(static_cast<int>(Version))); + Data.getU8(Cur); // Feature byte + } uintX_t Address = static_cast<uintX_t>(Data.getAddress(Cur)); uint32_t NumBlocks = ReadULEB128AsUInt32(); std::vector<BBAddrMap::BBEntry> BBEntries; + uint32_t PrevBBEndOffset = 0; for (uint32_t BlockID = 0; !ULEBSizeErr && Cur && (BlockID < NumBlocks); ++BlockID) { uint32_t Offset = ReadULEB128AsUInt32(); uint32_t Size = ReadULEB128AsUInt32(); uint32_t Metadata = ReadULEB128AsUInt32(); + if (Version >= 1) { + // Offset is calculated relative to the end of the previous BB. + Offset += PrevBBEndOffset; + PrevBBEndOffset = Offset + Size; + } BBEntries.push_back({Offset, Size, Metadata}); } - FunctionEntries.push_back({Address, BBEntries}); + FunctionEntries.push_back({Address, std::move(BBEntries)}); } // Either Cur is in the error state, or ULEBSizeError is set (not both), but // we join the two errors here to be safe. |