//===- ELFObjectFile.cpp - ELF object file implementation -----------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Part of the ELFObjectFile class implementation.
//
//===----------------------------------------------------------------------===//

#include "llvm/Object/ELFObjectFile.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/MC/MCInstrAnalysis.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Object/ELF.h"
#include "llvm/Object/ELFTypes.h"
#include "llvm/Object/Error.h"
#include "llvm/Support/ARMAttributeParser.h"
#include "llvm/Support/ARMBuildAttributes.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/HexagonAttributeParser.h"
#include "llvm/Support/RISCVAttributeParser.h"
#include "llvm/Support/RISCVAttributes.h"
#include "llvm/TargetParser/RISCVISAInfo.h"
#include "llvm/TargetParser/SubtargetFeature.h"
#include "llvm/TargetParser/Triple.h"
#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <optional>
#include <string>
#include <utility>

using namespace llvm;
using namespace object;

EnumStrings<uint8_t, 2> llvm::object::getElfSymbolTypes() {
  constexpr EnumStringDef<uint8_t, 2> ElfSymbolTypeDefs[] = {
      {{"None", "NOTYPE"}, ELF::STT_NOTYPE},
      {{"Object", "OBJECT"}, ELF::STT_OBJECT},
      {{"Function", "FUNC"}, ELF::STT_FUNC},
      {{"Section", "SECTION"}, ELF::STT_SECTION},
      {{"File", "FILE"}, ELF::STT_FILE},
      {{"Common", "COMMON"}, ELF::STT_COMMON},
      {{"TLS", "TLS"}, ELF::STT_TLS},
      {{"Unknown", "<unknown>: 7"}, 7},
      {{"Unknown", "<unknown>: 8"}, 8},
      {{"Unknown", "<unknown>: 9"}, 9},
      {{"GNU_IFunc", "IFUNC"}, ELF::STT_GNU_IFUNC},
      {{"OS Specific", "<OS specific>: 11"}, 11},
      {{"OS Specific", "<OS specific>: 12"}, 12},
      {{"Proc Specific", "<processor specific>: 13"}, 13},
      {{"Proc Specific", "<processor specific>: 14"}, 14},
      {{"Proc Specific", "<processor specific>: 15"}, 15},
  };
  static constexpr auto ElfSymbolTypes = BUILD_ENUM_STRINGS(ElfSymbolTypeDefs);
  return ElfSymbolTypes;
}

ELFObjectFileBase::ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source)
    : ObjectFile(Type, Source) {}

template <class ELFT>
static Expected<std::unique_ptr<ELFObjectFile<ELFT>>>
createPtr(MemoryBufferRef Object, bool InitContent) {
  auto Ret = ELFObjectFile<ELFT>::create(Object, InitContent);
  if (Error E = Ret.takeError())
    return std::move(E);
  return std::make_unique<ELFObjectFile<ELFT>>(std::move(*Ret));
}

Expected<std::unique_ptr<ObjectFile>>
ObjectFile::createELFObjectFile(MemoryBufferRef Obj, bool InitContent) {
  std::pair<unsigned char, unsigned char> Ident =
      getElfArchType(Obj.getBuffer());
  std::size_t MaxAlignment =
      1ULL << llvm::countr_zero(
          reinterpret_cast<uintptr_t>(Obj.getBufferStart()));

  if (MaxAlignment < 2)
    return createError("Insufficient alignment");

  if (Ident.first == ELF::ELFCLASS32) {
    if (Ident.second == ELF::ELFDATA2LSB)
      return createPtr<ELF32LE>(Obj, InitContent);
    else if (Ident.second == ELF::ELFDATA2MSB)
      return createPtr<ELF32BE>(Obj, InitContent);
    else
      return createError("Invalid ELF data");
  } else if (Ident.first == ELF::ELFCLASS64) {
    if (Ident.second == ELF::ELFDATA2LSB)
      return createPtr<ELF64LE>(Obj, InitContent);
    else if (Ident.second == ELF::ELFDATA2MSB)
      return createPtr<ELF64BE>(Obj, InitContent);
    else
      return createError("Invalid ELF data");
  }
  return createError("Invalid ELF class");
}

SubtargetFeatures ELFObjectFileBase::getMIPSFeatures() const {
  SubtargetFeatures Features;
  unsigned PlatformFlags = getPlatformFlags();

  switch (PlatformFlags & ELF::EF_MIPS_ARCH) {
  case ELF::EF_MIPS_ARCH_1:
    break;
  case ELF::EF_MIPS_ARCH_2:
    Features.AddFeature("mips2");
    break;
  case ELF::EF_MIPS_ARCH_3:
    Features.AddFeature("mips3");
    break;
  case ELF::EF_MIPS_ARCH_4:
    Features.AddFeature("mips4");
    break;
  case ELF::EF_MIPS_ARCH_5:
    Features.AddFeature("mips5");
    break;
  case ELF::EF_MIPS_ARCH_32:
    Features.AddFeature("mips32");
    break;
  case ELF::EF_MIPS_ARCH_64:
    Features.AddFeature("mips64");
    break;
  case ELF::EF_MIPS_ARCH_32R2:
    Features.AddFeature("mips32r2");
    break;
  case ELF::EF_MIPS_ARCH_64R2:
    Features.AddFeature("mips64r2");
    break;
  case ELF::EF_MIPS_ARCH_32R6:
    Features.AddFeature("mips32r6");
    break;
  case ELF::EF_MIPS_ARCH_64R6:
    Features.AddFeature("mips64r6");
    break;
  default:
    llvm_unreachable("Unknown EF_MIPS_ARCH value");
  }

  switch (PlatformFlags & ELF::EF_MIPS_MACH) {
  case ELF::EF_MIPS_MACH_NONE:
    // No feature associated with this value.
    break;
  case ELF::EF_MIPS_MACH_OCTEON:
    Features.AddFeature("cnmips");
    break;
  default:
    llvm_unreachable("Unknown EF_MIPS_ARCH value");
  }

  if (PlatformFlags & ELF::EF_MIPS_ARCH_ASE_M16)
    Features.AddFeature("mips16");
  if (PlatformFlags & ELF::EF_MIPS_MICROMIPS)
    Features.AddFeature("micromips");

  return Features;
}

SubtargetFeatures ELFObjectFileBase::getARMFeatures() const {
  SubtargetFeatures Features;
  ARMAttributeParser Attributes;
  if (Error E = getBuildAttributes(Attributes)) {
    consumeError(std::move(E));
    return SubtargetFeatures();
  }

  // both ARMv7-M and R have to support thumb hardware div
  bool isV7 = false;
  std::optional<unsigned> Attr =
      Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch);
  if (Attr)
    isV7 = *Attr == ARMBuildAttrs::v7;

  Attr = Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch_profile);
  if (Attr) {
    switch (*Attr) {
    case ARMBuildAttrs::ApplicationProfile:
      Features.AddFeature("aclass");
      break;
    case ARMBuildAttrs::RealTimeProfile:
      Features.AddFeature("rclass");
      if (isV7)
        Features.AddFeature("hwdiv");
      break;
    case ARMBuildAttrs::MicroControllerProfile:
      Features.AddFeature("mclass");
      if (isV7)
        Features.AddFeature("hwdiv");
      break;
    }
  }

  Attr = Attributes.getAttributeValue(ARMBuildAttrs::THUMB_ISA_use);
  if (Attr) {
    switch (*Attr) {
    default:
      break;
    case ARMBuildAttrs::Not_Allowed:
      Features.AddFeature("thumb", false);
      Features.AddFeature("thumb2", false);
      break;
    case ARMBuildAttrs::AllowThumb32:
      Features.AddFeature("thumb2");
      break;
    }
  }

  Attr = Attributes.getAttributeValue(ARMBuildAttrs::FP_arch);
  if (Attr) {
    switch (*Attr) {
    default:
      break;
    case ARMBuildAttrs::Not_Allowed:
      Features.AddFeature("vfp2sp", false);
      Features.AddFeature("vfp3d16sp", false);
      Features.AddFeature("vfp4d16sp", false);
      break;
    case ARMBuildAttrs::AllowFPv2:
      Features.AddFeature("vfp2");
      break;
    case ARMBuildAttrs::AllowFPv3A:
    case ARMBuildAttrs::AllowFPv3B:
      Features.AddFeature("vfp3");
      break;
    case ARMBuildAttrs::AllowFPv4A:
    case ARMBuildAttrs::AllowFPv4B:
      Features.AddFeature("vfp4");
      break;
    }
  }

  Attr = Attributes.getAttributeValue(ARMBuildAttrs::Advanced_SIMD_arch);
  if (Attr) {
    switch (*Attr) {
    default:
      break;
    case ARMBuildAttrs::Not_Allowed:
      Features.AddFeature("neon", false);
      Features.AddFeature("fp16", false);
      break;
    case ARMBuildAttrs::AllowNeon:
      Features.AddFeature("neon");
      break;
    case ARMBuildAttrs::AllowNeon2:
      Features.AddFeature("neon");
      Features.AddFeature("fp16");
      break;
    }
  }

  Attr = Attributes.getAttributeValue(ARMBuildAttrs::MVE_arch);
  if (Attr) {
    switch (*Attr) {
    default:
      break;
    case ARMBuildAttrs::Not_Allowed:
      Features.AddFeature("mve", false);
      Features.AddFeature("mve.fp", false);
      break;
    case ARMBuildAttrs::AllowMVEInteger:
      Features.AddFeature("mve.fp", false);
      Features.AddFeature("mve");
      break;
    case ARMBuildAttrs::AllowMVEIntegerAndFloat:
      Features.AddFeature("mve.fp");
      break;
    }
  }

  Attr = Attributes.getAttributeValue(ARMBuildAttrs::DIV_use);
  if (Attr) {
    switch (*Attr) {
    default:
      break;
    case ARMBuildAttrs::DisallowDIV:
      Features.AddFeature("hwdiv", false);
      Features.AddFeature("hwdiv-arm", false);
      break;
    case ARMBuildAttrs::AllowDIVExt:
      Features.AddFeature("hwdiv");
      Features.AddFeature("hwdiv-arm");
      break;
    }
  }

  return Features;
}

static std::string hexagonAttrToFeatureString(unsigned Attr) {
  return "v" + utostr(Attr);
}

SubtargetFeatures ELFObjectFileBase::getHexagonFeatures() const {
  SubtargetFeatures Features;
  HexagonAttributeParser Parser;
  if (Error E = getBuildAttributes(Parser)) {
    // Return no attributes if none can be read.
    // This behavior is important for backwards compatibility.
    consumeError(std::move(E));
    return Features;
  }
  std::optional<unsigned> Attr;

  if ((Attr = Parser.getAttributeValue(HexagonAttrs::ARCH)))
    Features.AddFeature(hexagonAttrToFeatureString(*Attr));

  if ((Attr = Parser.getAttributeValue(HexagonAttrs::HVXARCH)))
    Features.AddFeature("hvx" + hexagonAttrToFeatureString(*Attr));

  if ((Attr = Parser.getAttributeValue(HexagonAttrs::HVXIEEEFP)))
    if (*Attr)
      Features.AddFeature("hvx-ieee-fp");

  if ((Attr = Parser.getAttributeValue(HexagonAttrs::HVXQFLOAT)))
    if (*Attr)
      Features.AddFeature("hvx-qfloat");

  if ((Attr = Parser.getAttributeValue(HexagonAttrs::ZREG)))
    if (*Attr)
      Features.AddFeature("zreg");

  if ((Attr = Parser.getAttributeValue(HexagonAttrs::AUDIO)))
    if (*Attr)
      Features.AddFeature("audio");

  if ((Attr = Parser.getAttributeValue(HexagonAttrs::CABAC)))
    if (*Attr)
      Features.AddFeature("cabac");

  return Features;
}

Expected<SubtargetFeatures> ELFObjectFileBase::getRISCVFeatures() const {
  SubtargetFeatures Features;
  unsigned PlatformFlags = getPlatformFlags();

  if (PlatformFlags & ELF::EF_RISCV_RVC) {
    Features.AddFeature("zca");
  }

  RISCVAttributeParser Attributes;
  if (Error E = getBuildAttributes(Attributes)) {
    return std::move(E);
  }

  std::optional<StringRef> Attr =
      Attributes.getAttributeString(RISCVAttrs::ARCH);
  if (Attr) {
    auto ParseResult = RISCVISAInfo::parseNormalizedArchString(*Attr);
    if (!ParseResult)
      return ParseResult.takeError();
    auto &ISAInfo = *ParseResult;

    if (ISAInfo->getXLen() == 32)
      Features.AddFeature("64bit", false);
    else if (ISAInfo->getXLen() == 64)
      Features.AddFeature("64bit");
    else
      llvm_unreachable("XLEN should be 32 or 64.");

    Features.addFeaturesVector(ISAInfo->toFeatures());
  }

  return Features;
}

SubtargetFeatures ELFObjectFileBase::getLoongArchFeatures() const {
  SubtargetFeatures Features;

  switch (getPlatformFlags() & ELF::EF_LOONGARCH_ABI_MODIFIER_MASK) {
  case ELF::EF_LOONGARCH_ABI_SOFT_FLOAT:
    break;
  case ELF::EF_LOONGARCH_ABI_DOUBLE_FLOAT:
    Features.AddFeature("d");
    // D implies F according to LoongArch ISA spec.
    [[fallthrough]];
  case ELF::EF_LOONGARCH_ABI_SINGLE_FLOAT:
    Features.AddFeature("f");
    break;
  }

  return Features;
}

Expected<SubtargetFeatures> ELFObjectFileBase::getFeatures() const {
  switch (getEMachine()) {
  case ELF::EM_MIPS:
    return getMIPSFeatures();
  case ELF::EM_ARM:
    return getARMFeatures();
  case ELF::EM_RISCV:
    return getRISCVFeatures();
  case ELF::EM_LOONGARCH:
    return getLoongArchFeatures();
  case ELF::EM_HEXAGON:
    return getHexagonFeatures();
  default:
    return SubtargetFeatures();
  }
}

std::optional<StringRef> ELFObjectFileBase::tryGetCPUName() const {
  switch (getEMachine()) {
  case ELF::EM_AMDGPU:
    return getAMDGPUCPUName();
  case ELF::EM_CUDA:
    return getNVPTXCPUName();
  case ELF::EM_PPC:
  case ELF::EM_PPC64:
    return StringRef("future");
  case ELF::EM_BPF:
    return StringRef("v4");
  default:
    return std::nullopt;
  }
}

StringRef ELFObjectFileBase::getAMDGPUCPUName() const {
  assert(getEMachine() == ELF::EM_AMDGPU);
  unsigned CPU = getPlatformFlags() & ELF::EF_AMDGPU_MACH;

  switch (CPU) {
#define X(NUM, ENUM, NAME)                                                     \
  case ELF::ENUM:                                                              \
    return NAME;
    AMDGPU_MACH_LIST(X)
#undef X

  default:
    llvm_unreachable("Unknown EF_AMDGPU_MACH value");
  }
}

StringRef ELFObjectFileBase::getNVPTXCPUName() const {
  assert(getEMachine() == ELF::EM_CUDA);
  unsigned SM = getEIdentABIVersion() == ELF::ELFABIVERSION_CUDA_V1
                    ? getPlatformFlags() & ELF::EF_CUDA_SM
                    : (getPlatformFlags() & ELF::EF_CUDA_SM_MASK) >>
                          ELF::EF_CUDA_SM_OFFSET;

  switch (SM) {
  // Fermi architecture.
  case ELF::EF_CUDA_SM20:
    return "sm_20";
  case ELF::EF_CUDA_SM21:
    return "sm_21";

  // Kepler architecture.
  case ELF::EF_CUDA_SM30:
    return "sm_30";
  case ELF::EF_CUDA_SM32:
    return "sm_32";
  case ELF::EF_CUDA_SM35:
    return "sm_35";
  case ELF::EF_CUDA_SM37:
    return "sm_37";

  // Maxwell architecture.
  case ELF::EF_CUDA_SM50:
    return "sm_50";
  case ELF::EF_CUDA_SM52:
    return "sm_52";
  case ELF::EF_CUDA_SM53:
    return "sm_53";

  // Pascal architecture.
  case ELF::EF_CUDA_SM60:
    return "sm_60";
  case ELF::EF_CUDA_SM61:
    return "sm_61";
  case ELF::EF_CUDA_SM62:
    return "sm_62";

  // Volta architecture.
  case ELF::EF_CUDA_SM70:
    return "sm_70";
  case ELF::EF_CUDA_SM72:
    return "sm_72";

  // Turing architecture.
  case ELF::EF_CUDA_SM75:
    return "sm_75";

  // Ampere architecture.
  case ELF::EF_CUDA_SM80:
    return "sm_80";
  case ELF::EF_CUDA_SM86:
    return "sm_86";
  case ELF::EF_CUDA_SM87:
    return "sm_87";
  case ELF::EF_CUDA_SM88:
    return "sm_88";

  // Ada architecture.
  case ELF::EF_CUDA_SM89:
    return "sm_89";

  // Hopper architecture.
  case ELF::EF_CUDA_SM90:
    return getPlatformFlags() & ELF::EF_CUDA_ACCELERATORS_V1 ? "sm_90a"
                                                             : "sm_90";

  // Blackwell architecture.
  case ELF::EF_CUDA_SM100:
    return getPlatformFlags() & ELF::EF_CUDA_ACCELERATORS ? "sm_100a"
                                                          : "sm_100";
  case ELF::EF_CUDA_SM101:
    return getPlatformFlags() & ELF::EF_CUDA_ACCELERATORS ? "sm_101a"
                                                          : "sm_101";
  case ELF::EF_CUDA_SM103:
    return getPlatformFlags() & ELF::EF_CUDA_ACCELERATORS ? "sm_103a"
                                                          : "sm_103";
  case ELF::EF_CUDA_SM107:
    return getPlatformFlags() & ELF::EF_CUDA_ACCELERATORS ? "sm_107a"
                                                          : "sm_107";
  case ELF::EF_CUDA_SM110:
    return getPlatformFlags() & ELF::EF_CUDA_ACCELERATORS ? "sm_110a"
                                                          : "sm_110";

  // Rubin architecture.
  case ELF::EF_CUDA_SM120:
    return getPlatformFlags() & ELF::EF_CUDA_ACCELERATORS ? "sm_120a"
                                                          : "sm_120";
  case ELF::EF_CUDA_SM121:
    return getPlatformFlags() & ELF::EF_CUDA_ACCELERATORS ? "sm_121a"
                                                          : "sm_121";
  default:
    llvm_unreachable("Unknown EF_CUDA_SM value");
  }
}

// FIXME Encode from a tablegen description or target parser.
void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const {
  if (TheTriple.getSubArch() != Triple::NoSubArch)
    return;

  ARMAttributeParser Attributes;
  if (Error E = getBuildAttributes(Attributes)) {
    // TODO Propagate Error.
    consumeError(std::move(E));
    return;
  }

  std::string Triple;
  // Default to ARM, but use the triple if it's been set.
  if (TheTriple.isThumb())
    Triple = "thumb";
  else
    Triple = "arm";

  std::optional<unsigned> Attr =
      Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch);
  if (Attr) {
    switch (*Attr) {
    case ARMBuildAttrs::v4:
      Triple += "v4";
      break;
    case ARMBuildAttrs::v4T:
      Triple += "v4t";
      break;
    case ARMBuildAttrs::v5T:
      Triple += "v5t";
      break;
    case ARMBuildAttrs::v5TE:
      Triple += "v5te";
      break;
    case ARMBuildAttrs::v5TEJ:
      Triple += "v5tej";
      break;
    case ARMBuildAttrs::v6:
      Triple += "v6";
      break;
    case ARMBuildAttrs::v6KZ:
      Triple += "v6kz";
      break;
    case ARMBuildAttrs::v6T2:
      Triple += "v6t2";
      break;
    case ARMBuildAttrs::v6K:
      Triple += "v6k";
      break;
    case ARMBuildAttrs::v7: {
      std::optional<unsigned> ArchProfileAttr =
          Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch_profile);
      if (ArchProfileAttr == ARMBuildAttrs::MicroControllerProfile)
        Triple += "v7m";
      else
        Triple += "v7";
      break;
    }
    case ARMBuildAttrs::v6_M:
      Triple += "v6m";
      break;
    case ARMBuildAttrs::v6S_M:
      Triple += "v6sm";
      break;
    case ARMBuildAttrs::v7E_M:
      Triple += "v7em";
      break;
    case ARMBuildAttrs::v8_A:
      Triple += "v8a";
      break;
    case ARMBuildAttrs::v8_R:
      Triple += "v8r";
      break;
    case ARMBuildAttrs::v8_M_Base:
      Triple += "v8m.base";
      break;
    case ARMBuildAttrs::v8_M_Main:
      Triple += "v8m.main";
      break;
    case ARMBuildAttrs::v8_1_M_Main:
      Triple += "v8.1m.main";
      break;
    case ARMBuildAttrs::v9_A:
      Triple += "v9a";
      break;
    }
  }
  if (!isLittleEndian())
    Triple += "eb";

  TheTriple.setArchName(Triple);
}

std::vector<ELFPltEntry>
ELFObjectFileBase::getPltEntries(const MCSubtargetInfo &STI) const {
  std::string Err;
  const auto Triple = makeTriple();
  const auto *T = TargetRegistry::lookupTarget(Triple, Err);
  if (!T)
    return {};
  uint32_t JumpSlotReloc = 0, GlobDatReloc = 0;
  switch (Triple.getArch()) {
    case Triple::x86:
      JumpSlotReloc = ELF::R_386_JUMP_SLOT;
      GlobDatReloc = ELF::R_386_GLOB_DAT;
      break;
    case Triple::x86_64:
      JumpSlotReloc = ELF::R_X86_64_JUMP_SLOT;
      GlobDatReloc = ELF::R_X86_64_GLOB_DAT;
      break;
    case Triple::aarch64:
    case Triple::aarch64_be:
      JumpSlotReloc = ELF::R_AARCH64_JUMP_SLOT;
      break;
    case Triple::arm:
    case Triple::armeb:
    case Triple::thumb:
    case Triple::thumbeb:
      JumpSlotReloc = ELF::R_ARM_JUMP_SLOT;
      break;
    case Triple::hexagon:
      JumpSlotReloc = ELF::R_HEX_JMP_SLOT;
      GlobDatReloc = ELF::R_HEX_GLOB_DAT;
      break;
    case Triple::riscv32:
    case Triple::riscv64:
      JumpSlotReloc = ELF::R_RISCV_JUMP_SLOT;
      break;
    case Triple::loongarch32:
    case Triple::loongarch64:
      JumpSlotReloc = ELF::R_LARCH_JUMP_SLOT;
      break;
    default:
      return {};
  }
  std::unique_ptr<const MCInstrInfo> MII(T->createMCInstrInfo());
  std::unique_ptr<const MCInstrAnalysis> MIA(
      T->createMCInstrAnalysis(MII.get()));
  if (!MIA)
    return {};
  std::vector<std::pair<uint64_t, uint64_t>> PltEntries;
  std::optional<SectionRef> RelaPlt, RelaDyn;
  uint64_t GotBaseVA = 0;
  for (const SectionRef &Section : sections()) {
    Expected<StringRef> NameOrErr = Section.getName();
    if (!NameOrErr) {
      consumeError(NameOrErr.takeError());
      continue;
    }
    StringRef Name = *NameOrErr;

    if (Name == ".rela.plt" || Name == ".rel.plt") {
      RelaPlt = Section;
    } else if (Name == ".rela.dyn" || Name == ".rel.dyn") {
      RelaDyn = Section;
    } else if (Name == ".got.plt") {
      GotBaseVA = Section.getAddress();
    } else if (Name == ".plt" || Name == ".plt.got") {
      Expected<StringRef> PltContents = Section.getContents();
      if (!PltContents) {
        consumeError(PltContents.takeError());
        return {};
      }
      llvm::append_range(
          PltEntries,
          MIA->findPltEntries(Section.getAddress(),
                              arrayRefFromStringRef(*PltContents), STI));
    }
  }

  // Build a map from GOT entry virtual address to PLT entry virtual address.
  DenseMap<uint64_t, uint64_t> GotToPlt;
  for (auto [Plt, GotPlt] : PltEntries) {
    uint64_t GotPltEntry = GotPlt;
    // An x86-32 PIC PLT uses jmp DWORD PTR [ebx-offset]. Add
    // _GLOBAL_OFFSET_TABLE_ (EBX) to get the .got.plt (or .got) entry address.
    // See X86MCTargetDesc.cpp:findPltEntries for the 1 << 32 bit.
    if (GotPltEntry & (uint64_t(1) << 32) && getEMachine() == ELF::EM_386)
      GotPltEntry = static_cast<int32_t>(GotPltEntry) + GotBaseVA;
    GotToPlt.insert(std::make_pair(GotPltEntry, Plt));
  }

  // Find the relocations in the dynamic relocation table that point to
  // locations in the GOT for which we know the corresponding PLT entry.
  std::vector<ELFPltEntry> Result;
  auto handleRels = [&](iterator_range<relocation_iterator> Rels,
                        uint32_t RelType, StringRef PltSec) {
    for (const auto &R : Rels) {
      if (R.getType() != RelType)
        continue;
      auto PltEntryIter = GotToPlt.find(R.getOffset());
      if (PltEntryIter != GotToPlt.end()) {
        symbol_iterator Sym = R.getSymbol();
        if (Sym == symbol_end())
          Result.push_back(
              ELFPltEntry{PltSec, std::nullopt, PltEntryIter->second});
        else
          Result.push_back(ELFPltEntry{PltSec, Sym->getRawDataRefImpl(),
                                       PltEntryIter->second});
      }
    }
  };

  if (RelaPlt)
    handleRels(RelaPlt->relocations(), JumpSlotReloc, ".plt");

  // If a symbol needing a PLT entry also needs a GLOB_DAT relocation, GNU ld's
  // x86 port places the PLT entry in the .plt.got section.
  if (RelaDyn)
    handleRels(RelaDyn->relocations(), GlobDatReloc, ".plt.got");

  return Result;
}

template <class ELFT>
Expected<std::vector<BBAddrMap>> static readBBAddrMapImpl(
    const ELFFile<ELFT> &EF, std::optional<unsigned> TextSectionIndex,
    std::vector<PGOAnalysisMap> *PGOAnalyses) {
  using Elf_Shdr = typename ELFT::Shdr;
  bool IsRelocatable = EF.getHeader().e_type == ELF::ET_REL;
  std::vector<BBAddrMap> BBAddrMaps;
  if (PGOAnalyses)
    PGOAnalyses->clear();

  const auto &Sections = cantFail(EF.sections());
  auto IsMatch = [&](const Elf_Shdr &Sec) -> Expected<bool> {
    if (Sec.sh_type != ELF::SHT_LLVM_BB_ADDR_MAP)
      return false;
    if (!TextSectionIndex)
      return true;
    Expected<const Elf_Shdr *> TextSecOrErr = EF.getSection(Sec.sh_link);
    if (!TextSecOrErr)
      return createError("unable to get the linked-to section for " +
                         describe(EF, Sec) + ": " +
                         toString(TextSecOrErr.takeError()));
    assert(*TextSecOrErr >= Sections.begin() &&
           "Text section pointer outside of bounds");
    if (*TextSectionIndex !=
        (unsigned)std::distance(Sections.begin(), *TextSecOrErr))
      return false;
    return true;
  };

  Expected<MapVector<const Elf_Shdr *, const Elf_Shdr *>> SectionRelocMapOrErr =
      EF.getSectionAndRelocations(IsMatch);
  if (!SectionRelocMapOrErr)
    return SectionRelocMapOrErr.takeError();

  for (auto const &[Sec, RelocSec] : *SectionRelocMapOrErr) {
    if (IsRelocatable && !RelocSec)
      return createError("unable to get relocation section for " +
                         describe(EF, *Sec));
    Expected<std::vector<BBAddrMap>> BBAddrMapOrErr =
        EF.decodeBBAddrMap(*Sec, RelocSec, PGOAnalyses);
    if (!BBAddrMapOrErr) {
      if (PGOAnalyses)
        PGOAnalyses->clear();
      return createError("unable to read BB addr map section: " +
                         toString(BBAddrMapOrErr.takeError()));
    }
    std::move(BBAddrMapOrErr->begin(), BBAddrMapOrErr->end(),
              std::back_inserter(BBAddrMaps));
  }
  if (PGOAnalyses)
    assert(PGOAnalyses->size() == BBAddrMaps.size() &&
           "The same number of BBAddrMaps and PGOAnalysisMaps should be "
           "returned when PGO information is requested");
  return BBAddrMaps;
}

template <class ELFT>
static Expected<std::vector<VersionEntry>>
readDynsymVersionsImpl(const ELFFile<ELFT> &EF,
                       ELFObjectFileBase::elf_symbol_iterator_range Symbols) {
  using Elf_Shdr = typename ELFT::Shdr;
  const Elf_Shdr *VerSec = nullptr;
  const Elf_Shdr *VerNeedSec = nullptr;
  const Elf_Shdr *VerDefSec = nullptr;
  // The user should ensure sections() can't fail here.
  for (const Elf_Shdr &Sec : cantFail(EF.sections())) {
    if (Sec.sh_type == ELF::SHT_GNU_versym)
      VerSec = &Sec;
    else if (Sec.sh_type == ELF::SHT_GNU_verdef)
      VerDefSec = &Sec;
    else if (Sec.sh_type == ELF::SHT_GNU_verneed)
      VerNeedSec = &Sec;
  }
  if (!VerSec)
    return std::vector<VersionEntry>();

  Expected<SmallVector<std::optional<VersionEntry>, 0>> MapOrErr =
      EF.loadVersionMap(VerNeedSec, VerDefSec);
  if (!MapOrErr)
    return MapOrErr.takeError();

  std::vector<VersionEntry> Ret;
  size_t I = 0;
  for (const ELFSymbolRef &Sym : Symbols) {
    ++I;
    Expected<const typename ELFT::Versym *> VerEntryOrErr =
        EF.template getEntry<typename ELFT::Versym>(*VerSec, I);
    if (!VerEntryOrErr)
      return createError("unable to read an entry with index " + Twine(I) +
                         " from " + describe(EF, *VerSec) + ": " +
                         toString(VerEntryOrErr.takeError()));

    Expected<uint32_t> FlagsOrErr = Sym.getFlags();
    if (!FlagsOrErr)
      return createError("unable to read flags for symbol with index " +
                         Twine(I) + ": " + toString(FlagsOrErr.takeError()));

    bool IsDefault;
    Expected<StringRef> VerOrErr = EF.getSymbolVersionByIndex(
        (*VerEntryOrErr)->vs_index, IsDefault, *MapOrErr,
        (*FlagsOrErr) & SymbolRef::SF_Undefined);
    if (!VerOrErr)
      return createError("unable to get a version for entry " + Twine(I) +
                         " of " + describe(EF, *VerSec) + ": " +
                         toString(VerOrErr.takeError()));

    Ret.push_back({(*VerOrErr).str(), IsDefault});
  }

  return Ret;
}

Expected<std::vector<VersionEntry>>
ELFObjectFileBase::readDynsymVersions() const {
  elf_symbol_iterator_range Symbols = getDynamicSymbolIterators();
  if (const auto *Obj = dyn_cast<ELF32LEObjectFile>(this))
    return readDynsymVersionsImpl(Obj->getELFFile(), Symbols);
  if (const auto *Obj = dyn_cast<ELF32BEObjectFile>(this))
    return readDynsymVersionsImpl(Obj->getELFFile(), Symbols);
  if (const auto *Obj = dyn_cast<ELF64LEObjectFile>(this))
    return readDynsymVersionsImpl(Obj->getELFFile(), Symbols);
  return readDynsymVersionsImpl(cast<ELF64BEObjectFile>(this)->getELFFile(),
                                Symbols);
}

Expected<std::vector<BBAddrMap>> ELFObjectFileBase::readBBAddrMap(
    std::optional<unsigned> TextSectionIndex,
    std::vector<PGOAnalysisMap> *PGOAnalyses) const {
  if (const auto *Obj = dyn_cast<ELF32LEObjectFile>(this))
    return readBBAddrMapImpl(Obj->getELFFile(), TextSectionIndex, PGOAnalyses);
  if (const auto *Obj = dyn_cast<ELF64LEObjectFile>(this))
    return readBBAddrMapImpl(Obj->getELFFile(), TextSectionIndex, PGOAnalyses);
  if (const auto *Obj = dyn_cast<ELF32BEObjectFile>(this))
    return readBBAddrMapImpl(Obj->getELFFile(), TextSectionIndex, PGOAnalyses);
  return readBBAddrMapImpl(cast<ELF64BEObjectFile>(this)->getELFFile(),
                           TextSectionIndex, PGOAnalyses);
}

StringRef ELFObjectFileBase::getCrelDecodeProblem(SectionRef Sec) const {
  auto Data = Sec.getRawDataRefImpl();
  if (const auto *Obj = dyn_cast<ELF32LEObjectFile>(this))
    return Obj->getCrelDecodeProblem(Data);
  if (const auto *Obj = dyn_cast<ELF32BEObjectFile>(this))
    return Obj->getCrelDecodeProblem(Data);
  if (const auto *Obj = dyn_cast<ELF64LEObjectFile>(this))
    return Obj->getCrelDecodeProblem(Data);
  return cast<ELF64BEObjectFile>(this)->getCrelDecodeProblem(Data);
}
