brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.6 KiB · 35e2f53 Raw
114 lines · c
1//===----------------------------------------------------------------------===//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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLD_ELF_ARCH_RISCVINTERNALRELOCATIONS_H10#define LLD_ELF_ARCH_RISCVINTERNALRELOCATIONS_H11 12#include "Relocations.h"13#include "Symbols.h"14 15namespace lld::elf {16 17// Bit 8 of RelType is used to indicate linker-internal relocations that are18// not vendor-specific.19// These are internal relocation numbers for GP/X0 relaxation. They aren't part20// of the psABI spec.21constexpr uint32_t INTERNAL_R_RISCV_GPREL_I = 256;22constexpr uint32_t INTERNAL_R_RISCV_GPREL_S = 257;23constexpr uint32_t INTERNAL_R_RISCV_X0REL_I = 258;24constexpr uint32_t INTERNAL_R_RISCV_X0REL_S = 259;25 26// Bits 9 -> 31 of RelType are used to indicate vendor-specific relocations.27constexpr uint32_t INTERNAL_RISCV_VENDOR_MASK = 0xFFFFFFFF << 9;28constexpr uint32_t INTERNAL_RISCV_VENDOR_QUALCOMM = 1 << 9;29constexpr uint32_t INTERNAL_RISCV_VENDOR_ANDES = 2 << 9;30 31constexpr uint32_t INTERNAL_RISCV_QC_ABS20_U =32    INTERNAL_RISCV_VENDOR_QUALCOMM | llvm::ELF::R_RISCV_QC_ABS20_U;33constexpr uint32_t INTERNAL_RISCV_QC_E_BRANCH =34    INTERNAL_RISCV_VENDOR_QUALCOMM | llvm::ELF::R_RISCV_QC_E_BRANCH;35constexpr uint32_t INTERNAL_RISCV_QC_E_32 =36    INTERNAL_RISCV_VENDOR_QUALCOMM | llvm::ELF::R_RISCV_QC_E_32;37constexpr uint32_t INTERNAL_RISCV_QC_E_CALL_PLT =38    INTERNAL_RISCV_VENDOR_QUALCOMM | llvm::ELF::R_RISCV_QC_E_CALL_PLT;39 40constexpr uint32_t INTERNAL_RISCV_NDS_BRANCH_10 =41    INTERNAL_RISCV_VENDOR_ANDES | llvm::ELF::R_RISCV_NDS_BRANCH_10;42 43uint32_t getRISCVVendorRelMarker(llvm::StringRef rvVendor);44std::optional<llvm::StringRef> getRISCVVendorString(RelType ty);45 46class vendor_reloc_iterator {47public:48  using iterator_category = std::forward_iterator_tag;49  using value_type = Relocation;50  using difference_type = std::ptrdiff_t;51  using pointer = Relocation *;52  using reference = Relocation; // returned by value53 54  vendor_reloc_iterator(MutableArrayRef<Relocation>::iterator i,55                        MutableArrayRef<Relocation>::iterator e)56      : it(i), end(e) {}57 58  // Dereference59  Relocation operator*() const {60    Relocation r = *it;61    r.type.v |= rvVendorFlag;62    return r;63  }64 65  struct vendor_reloc_proxy {66    Relocation r;67    const Relocation *operator->() const { return &r; }68  };69 70  vendor_reloc_proxy operator->() const {71    return vendor_reloc_proxy{this->operator*()};72  }73 74  vendor_reloc_iterator &operator++() {75    ++it;76    if (it != end && it->type == llvm::ELF::R_RISCV_VENDOR) {77      rvVendorFlag = getRISCVVendorRelMarker(it->sym->getName());78      ++it;79    } else {80      rvVendorFlag = 0;81    }82    return *this;83  }84 85  vendor_reloc_iterator operator++(int) {86    vendor_reloc_iterator tmp(*this);87    ++(*this);88    return tmp;89  }90 91  bool operator==(const vendor_reloc_iterator &other) const {92    return it == other.it;93  }94  bool operator!=(const vendor_reloc_iterator &other) const {95    return it != other.it;96  }97 98  Relocation *getUnderlyingRelocation() const { return &*it; }99 100private:101  MutableArrayRef<Relocation>::iterator it;102  MutableArrayRef<Relocation>::iterator end;103  uint32_t rvVendorFlag = 0;104};105 106inline auto riscv_vendor_relocs(MutableArrayRef<Relocation> arr) {107  return llvm::make_range(vendor_reloc_iterator(arr.begin(), arr.end()),108                          vendor_reloc_iterator(arr.end(), arr.end()));109}110 111} // namespace lld::elf112 113#endif114