diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2021-06-13 19:31:46 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2021-06-13 19:37:19 +0000 |
commit | e8d8bef961a50d4dc22501cde4fb9fb0be1b2532 (patch) | |
tree | 94f04805f47bb7c59ae29690d8952b6074fff602 /contrib/llvm-project/llvm/lib/Object/ELF.cpp | |
parent | bb130ff39747b94592cb26d71b7cb097b9a4ea6b (diff) | |
parent | b60736ec1405bb0a8dd40989f67ef4c93da068ab (diff) |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Object/ELF.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Object/ELF.cpp | 58 |
1 files changed, 39 insertions, 19 deletions
diff --git a/contrib/llvm-project/llvm/lib/Object/ELF.cpp b/contrib/llvm-project/llvm/lib/Object/ELF.cpp index 2515695095a1..264f115ddbb5 100644 --- a/contrib/llvm-project/llvm/lib/Object/ELF.cpp +++ b/contrib/llvm-project/llvm/lib/Object/ELF.cpp @@ -152,6 +152,13 @@ StringRef llvm::object::getELFRelocationTypeName(uint32_t Machine, break; } break; + case ELF::EM_CSKY: + switch (Type) { +#include "llvm/BinaryFormat/ELFRelocs/CSKY.def" + default: + break; + } + break; default: break; } @@ -194,6 +201,8 @@ uint32_t llvm::object::getELFRelativeRelocationType(uint32_t Machine) { case ELF::EM_SPARC32PLUS: case ELF::EM_SPARCV9: return ELF::R_SPARC_RELATIVE; + case ELF::EM_CSKY: + return ELF::R_CKCORE_RELATIVE; case ELF::EM_AMDGPU: break; case ELF::EM_BPF: @@ -267,6 +276,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); STRINGIFY_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES); STRINGIFY_ENUM_CASE(ELF, SHT_GNU_HASH); STRINGIFY_ENUM_CASE(ELF, SHT_GNU_verdef); @@ -278,7 +288,7 @@ StringRef llvm::object::getELFSectionTypeName(uint32_t Machine, unsigned Type) { } template <class ELFT> -Expected<std::vector<typename ELFT::Rela>> +std::vector<typename ELFT::Rel> ELFFile<ELFT>::decode_relrs(Elf_Relr_Range relrs) const { // This function decodes the contents of an SHT_RELR packed relocation // section. @@ -310,11 +320,10 @@ ELFFile<ELFT>::decode_relrs(Elf_Relr_Range relrs) const { // even means address, odd means bitmap. // 2. Just a simple list of addresses is a valid encoding. - Elf_Rela Rela; - Rela.r_info = 0; - Rela.r_addend = 0; - Rela.setType(getRelativeRelocationType(), false); - std::vector<Elf_Rela> Relocs; + Elf_Rel Rel; + Rel.r_info = 0; + Rel.setType(getRelativeRelocationType(), false); + std::vector<Elf_Rel> Relocs; // Word type: uint32_t for Elf32, and uint64_t for Elf64. typedef typename ELFT::uint Word; @@ -331,8 +340,8 @@ ELFFile<ELFT>::decode_relrs(Elf_Relr_Range relrs) const { Word Entry = R; if ((Entry&1) == 0) { // Even entry: encodes the offset for next relocation. - Rela.r_offset = Entry; - Relocs.push_back(Rela); + Rel.r_offset = Entry; + Relocs.push_back(Rel); // Set base offset for subsequent bitmap entries. Base = Entry + WordSize; continue; @@ -343,8 +352,8 @@ ELFFile<ELFT>::decode_relrs(Elf_Relr_Range relrs) const { while (Entry != 0) { Entry >>= 1; if ((Entry&1) != 0) { - Rela.r_offset = Offset; - Relocs.push_back(Rela); + Rel.r_offset = Offset; + Relocs.push_back(Rel); } Offset += WordSize; } @@ -358,7 +367,7 @@ ELFFile<ELFT>::decode_relrs(Elf_Relr_Range relrs) const { template <class ELFT> Expected<std::vector<typename ELFT::Rela>> -ELFFile<ELFT>::android_relas(const Elf_Shdr *Sec) const { +ELFFile<ELFT>::android_relas(const Elf_Shdr &Sec) const { // This function reads relocations in Android's packed relocation format, // which is based on SLEB128 and delta encoding. Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec); @@ -503,7 +512,7 @@ std::string ELFFile<ELFT>::getDynamicTagAsString(unsigned Arch, template <class ELFT> std::string ELFFile<ELFT>::getDynamicTagAsString(uint64_t Type) const { - return getDynamicTagAsString(getHeader()->e_machine, Type); + return getDynamicTagAsString(getHeader().e_machine, Type); } template <class ELFT> @@ -533,7 +542,7 @@ Expected<typename ELFT::DynRange> ELFFile<ELFT>::dynamicEntries() const { for (const Elf_Shdr &Sec : *SectionsOrError) { if (Sec.sh_type == ELF::SHT_DYNAMIC) { Expected<ArrayRef<Elf_Dyn>> DynOrError = - getSectionContentsAsArray<Elf_Dyn>(&Sec); + getSectionContentsAsArray<Elf_Dyn>(Sec); if (!DynOrError) return DynOrError.takeError(); Dyn = *DynOrError; @@ -557,7 +566,8 @@ Expected<typename ELFT::DynRange> ELFFile<ELFT>::dynamicEntries() const { } template <class ELFT> -Expected<const uint8_t *> ELFFile<ELFT>::toMappedAddr(uint64_t VAddr) const { +Expected<const uint8_t *> +ELFFile<ELFT>::toMappedAddr(uint64_t VAddr, WarningHandler WarnHandler) const { auto ProgramHeadersOrError = program_headers(); if (!ProgramHeadersOrError) return ProgramHeadersOrError.takeError(); @@ -568,11 +578,21 @@ Expected<const uint8_t *> ELFFile<ELFT>::toMappedAddr(uint64_t VAddr) const { if (Phdr.p_type == ELF::PT_LOAD) LoadSegments.push_back(const_cast<Elf_Phdr *>(&Phdr)); - const Elf_Phdr *const *I = - std::upper_bound(LoadSegments.begin(), LoadSegments.end(), VAddr, - [](uint64_t VAddr, const Elf_Phdr_Impl<ELFT> *Phdr) { - return VAddr < Phdr->p_vaddr; - }); + auto SortPred = [](const Elf_Phdr_Impl<ELFT> *A, + const Elf_Phdr_Impl<ELFT> *B) { + return A->p_vaddr < B->p_vaddr; + }; + if (!llvm::is_sorted(LoadSegments, SortPred)) { + if (Error E = + WarnHandler("loadable segments are unsorted by virtual address")) + return std::move(E); + llvm::stable_sort(LoadSegments, SortPred); + } + + const Elf_Phdr *const *I = llvm::upper_bound( + LoadSegments, VAddr, [](uint64_t VAddr, const Elf_Phdr_Impl<ELFT> *Phdr) { + return VAddr < Phdr->p_vaddr; + }); if (I == LoadSegments.begin()) return createError("virtual address is not in any segment: 0x" + |