//===--- XCOFFObjectFile.cpp - XCOFF 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
//
//===----------------------------------------------------------------------===//
//
// This file defines the XCOFFObjectFile class.
//
//===----------------------------------------------------------------------===//

#include "llvm/Object/XCOFFObjectFile.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/DataExtractor.h"
#include "llvm/TargetParser/SubtargetFeature.h"
#include <cstddef>
#include <cstring>

namespace llvm {

using namespace XCOFF;

namespace object {

static const uint8_t FunctionSym = 0x20;
static const uint16_t NoRelMask = 0x0001;
static const size_t SymbolAuxTypeOffset = 17;

// Checks that [Ptr, Ptr + Size) bytes fall inside the memory buffer
// 'M'. Returns a pointer to the underlying object on success.
template <typename T>
static Expected<const T *> getObject(MemoryBufferRef M, const void *Ptr,
                                     const uint64_t Size = sizeof(T)) {
  uintptr_t Addr = reinterpret_cast<uintptr_t>(Ptr);
  if (Error E = Binary::checkOffset(M, Addr, Size))
    return std::move(E);
  return reinterpret_cast<const T *>(Addr);
}

static uintptr_t getWithOffset(uintptr_t Base, ptrdiff_t Offset) {
  return reinterpret_cast<uintptr_t>(reinterpret_cast<const char *>(Base) +
                                     Offset);
}

template <typename T> static const T *viewAs(uintptr_t in) {
  return reinterpret_cast<const T *>(in);
}

static StringRef generateXCOFFFixedNameStringRef(const char *Name) {
  auto NulCharPtr =
      static_cast<const char *>(memchr(Name, '\0', XCOFF::NameSize));
  return NulCharPtr ? StringRef(Name, NulCharPtr - Name)
                    : StringRef(Name, XCOFF::NameSize);
}

template <typename T> StringRef XCOFFSectionHeader<T>::getName() const {
  const T &DerivedXCOFFSectionHeader = static_cast<const T &>(*this);
  return generateXCOFFFixedNameStringRef(DerivedXCOFFSectionHeader.Name);
}

template <typename T> uint16_t XCOFFSectionHeader<T>::getSectionType() const {
  const T &DerivedXCOFFSectionHeader = static_cast<const T &>(*this);
  return DerivedXCOFFSectionHeader.Flags & SectionFlagsTypeMask;
}

template <typename T>
bool XCOFFSectionHeader<T>::isReservedSectionType() const {
  return getSectionType() & SectionFlagsReservedMask;
}

template <typename AddressType>
bool XCOFFRelocation<AddressType>::isRelocationSigned() const {
  return Info & XR_SIGN_INDICATOR_MASK;
}

template <typename AddressType>
bool XCOFFRelocation<AddressType>::isFixupIndicated() const {
  return Info & XR_FIXUP_INDICATOR_MASK;
}

template <typename AddressType>
uint8_t XCOFFRelocation<AddressType>::getRelocatedLength() const {
  // The relocation encodes the bit length being relocated minus 1. Add back
  // the 1 to get the actual length being relocated.
  return (Info & XR_BIASED_LENGTH_MASK) + 1;
}

template struct ExceptionSectionEntry<support::ubig32_t>;
template struct ExceptionSectionEntry<support::ubig64_t>;

template <typename T>
Expected<StringRef> getLoaderSecSymNameInStrTbl(const T *LoaderSecHeader,
                                                uint64_t Offset) {
  if (LoaderSecHeader->LengthOfStrTbl > Offset)
    return (reinterpret_cast<const char *>(LoaderSecHeader) +
            LoaderSecHeader->OffsetToStrTbl + Offset);

  return createError("entry with offset 0x" + Twine::utohexstr(Offset) +
                     " in the loader section's string table with size 0x" +
                     Twine::utohexstr(LoaderSecHeader->LengthOfStrTbl) +
                     " is invalid");
}

Expected<StringRef> LoaderSectionSymbolEntry32::getSymbolName(
    const LoaderSectionHeader32 *LoaderSecHeader32) const {
  const NameOffsetInStrTbl *NameInStrTbl =
      reinterpret_cast<const NameOffsetInStrTbl *>(SymbolName);
  if (NameInStrTbl->IsNameInStrTbl != XCOFFSymbolRef::NAME_IN_STR_TBL_MAGIC)
    return generateXCOFFFixedNameStringRef(SymbolName);

  return getLoaderSecSymNameInStrTbl(LoaderSecHeader32, NameInStrTbl->Offset);
}

Expected<StringRef> LoaderSectionSymbolEntry64::getSymbolName(
    const LoaderSectionHeader64 *LoaderSecHeader64) const {
  return getLoaderSecSymNameInStrTbl(LoaderSecHeader64, Offset);
}

uintptr_t
XCOFFObjectFile::getAdvancedSymbolEntryAddress(uintptr_t CurrentAddress,
                                               uint32_t Distance) {
  return getWithOffset(CurrentAddress, Distance * XCOFF::SymbolTableEntrySize);
}

const XCOFF::SymbolAuxType *
XCOFFObjectFile::getSymbolAuxType(uintptr_t AuxEntryAddress) const {
  assert(is64Bit() && "64-bit interface called on a 32-bit object file.");
  return viewAs<XCOFF::SymbolAuxType>(
      getWithOffset(AuxEntryAddress, SymbolAuxTypeOffset));
}

void XCOFFObjectFile::checkSectionAddress(uintptr_t Addr,
                                          uintptr_t TableAddress) const {
  if (Addr < TableAddress)
    report_fatal_error("Section header outside of section header table.");

  uintptr_t Offset = Addr - TableAddress;
  if (Offset >= getSectionHeaderSize() * getNumberOfSections())
    report_fatal_error("Section header outside of section header table.");

  if (Offset % getSectionHeaderSize() != 0)
    report_fatal_error(
        "Section header pointer does not point to a valid section header.");
}

const XCOFFSectionHeader32 *
XCOFFObjectFile::toSection32(DataRefImpl Ref) const {
  assert(!is64Bit() && "32-bit interface called on 64-bit object file.");
#ifndef NDEBUG
  checkSectionAddress(Ref.p, getSectionHeaderTableAddress());
#endif
  return viewAs<XCOFFSectionHeader32>(Ref.p);
}

const XCOFFSectionHeader64 *
XCOFFObjectFile::toSection64(DataRefImpl Ref) const {
  assert(is64Bit() && "64-bit interface called on a 32-bit object file.");
#ifndef NDEBUG
  checkSectionAddress(Ref.p, getSectionHeaderTableAddress());
#endif
  return viewAs<XCOFFSectionHeader64>(Ref.p);
}

XCOFFSymbolRef XCOFFObjectFile::toSymbolRef(DataRefImpl Ref) const {
  assert(Ref.p != 0 && "Symbol table pointer can not be nullptr!");
#ifndef NDEBUG
  checkSymbolEntryPointer(Ref.p);
#endif
  return XCOFFSymbolRef(Ref, this);
}

const XCOFFFileHeader32 *XCOFFObjectFile::fileHeader32() const {
  assert(!is64Bit() && "32-bit interface called on 64-bit object file.");
  return static_cast<const XCOFFFileHeader32 *>(FileHeader);
}

const XCOFFFileHeader64 *XCOFFObjectFile::fileHeader64() const {
  assert(is64Bit() && "64-bit interface called on a 32-bit object file.");
  return static_cast<const XCOFFFileHeader64 *>(FileHeader);
}

const XCOFFAuxiliaryHeader32 *XCOFFObjectFile::auxiliaryHeader32() const {
  assert(!is64Bit() && "32-bit interface called on 64-bit object file.");
  return static_cast<const XCOFFAuxiliaryHeader32 *>(AuxiliaryHeader);
}

const XCOFFAuxiliaryHeader64 *XCOFFObjectFile::auxiliaryHeader64() const {
  assert(is64Bit() && "64-bit interface called on a 32-bit object file.");
  return static_cast<const XCOFFAuxiliaryHeader64 *>(AuxiliaryHeader);
}

template <typename T> const T *XCOFFObjectFile::sectionHeaderTable() const {
  return static_cast<const T *>(SectionHeaderTable);
}

const XCOFFSectionHeader32 *
XCOFFObjectFile::sectionHeaderTable32() const {
  assert(!is64Bit() && "32-bit interface called on 64-bit object file.");
  return static_cast<const XCOFFSectionHeader32 *>(SectionHeaderTable);
}

const XCOFFSectionHeader64 *
XCOFFObjectFile::sectionHeaderTable64() const {
  assert(is64Bit() && "64-bit interface called on a 32-bit object file.");
  return static_cast<const XCOFFSectionHeader64 *>(SectionHeaderTable);
}

void XCOFFObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
  uintptr_t NextSymbolAddr = getAdvancedSymbolEntryAddress(
      Symb.p, toSymbolRef(Symb).getNumberOfAuxEntries() + 1);
#ifndef NDEBUG
  // This function is used by basic_symbol_iterator, which allows to
  // point to the end-of-symbol-table address.
  if (NextSymbolAddr != getEndOfSymbolTableAddress())
    checkSymbolEntryPointer(NextSymbolAddr);
#endif
  Symb.p = NextSymbolAddr;
}

Expected<StringRef>
XCOFFObjectFile::getStringTableEntry(uint32_t Offset) const {
  // The byte offset is relative to the start of the string table.
  // A byte offset value of 0 is a null or zero-length symbol
  // name. A byte offset in the range 1 to 3 (inclusive) points into the length
  // field; as a soft-error recovery mechanism, we treat such cases as having an
  // offset of 0.
  if (Offset < 4)
    return StringRef(nullptr, 0);

  if (StringTable.Data != nullptr && StringTable.Size > Offset)
    return (StringTable.Data + Offset);

  return createError("entry with offset 0x" + Twine::utohexstr(Offset) +
                     " in a string table with size 0x" +
                     Twine::utohexstr(StringTable.Size) + " is invalid");
}

StringRef XCOFFObjectFile::getStringTable() const {
  // If the size is less than or equal to 4, then the string table contains no
  // string data.
  return StringRef(StringTable.Data,
                   StringTable.Size <= 4 ? 0 : StringTable.Size);
}

Expected<StringRef>
XCOFFObjectFile::getCFileName(const XCOFFFileAuxEnt *CFileEntPtr) const {
  if (CFileEntPtr->NameInStrTbl.Magic != XCOFFSymbolRef::NAME_IN_STR_TBL_MAGIC)
    return generateXCOFFFixedNameStringRef(CFileEntPtr->Name);
  return getStringTableEntry(CFileEntPtr->NameInStrTbl.Offset);
}

Expected<StringRef> XCOFFObjectFile::getSymbolName(DataRefImpl Symb) const {
  return toSymbolRef(Symb).getName();
}

Expected<uint64_t> XCOFFObjectFile::getSymbolAddress(DataRefImpl Symb) const {
  return toSymbolRef(Symb).getValue();
}

uint64_t XCOFFObjectFile::getSymbolValueImpl(DataRefImpl Symb) const {
  return toSymbolRef(Symb).getValue();
}

uint32_t XCOFFObjectFile::getSymbolAlignment(DataRefImpl Symb) const {
  uint64_t Result = 0;
  XCOFFSymbolRef XCOFFSym = toSymbolRef(Symb);
  if (XCOFFSym.isCsectSymbol()) {
    Expected<XCOFFCsectAuxRef> CsectAuxRefOrError =
        XCOFFSym.getXCOFFCsectAuxRef();
    if (!CsectAuxRefOrError)
      // TODO: report the error up the stack.
      consumeError(CsectAuxRefOrError.takeError());
    else
      Result = 1ULL << CsectAuxRefOrError.get().getAlignmentLog2();
  }
  return Result;
}

uint64_t XCOFFObjectFile::getCommonSymbolSizeImpl(DataRefImpl Symb) const {
  uint64_t Result = 0;
  XCOFFSymbolRef XCOFFSym = toSymbolRef(Symb);
  if (XCOFFSym.isCsectSymbol()) {
    Expected<XCOFFCsectAuxRef> CsectAuxRefOrError =
        XCOFFSym.getXCOFFCsectAuxRef();
    if (!CsectAuxRefOrError)
      // TODO: report the error up the stack.
      consumeError(CsectAuxRefOrError.takeError());
    else {
      XCOFFCsectAuxRef CsectAuxRef = CsectAuxRefOrError.get();
      assert(CsectAuxRef.getSymbolType() == XCOFF::XTY_CM);
      Result = CsectAuxRef.getSectionOrLength();
    }
  }
  return Result;
}

Expected<SymbolRef::Type>
XCOFFObjectFile::getSymbolType(DataRefImpl Symb) const {
  XCOFFSymbolRef XCOFFSym = toSymbolRef(Symb);

  if (XCOFFSym.isFunction())
    return SymbolRef::ST_Function;

  if (XCOFF::C_FILE == XCOFFSym.getStorageClass())
    return SymbolRef::ST_File;

  int16_t SecNum = XCOFFSym.getSectionNumber();
  if (SecNum <= 0)
    return SymbolRef::ST_Other;

  Expected<DataRefImpl> SecDRIOrErr =
      getSectionByNum(XCOFFSym.getSectionNumber());

  if (!SecDRIOrErr)
    return SecDRIOrErr.takeError();

  DataRefImpl SecDRI = SecDRIOrErr.get();

  Expected<StringRef> SymNameOrError = XCOFFSym.getName();
  if (SymNameOrError) {
    // The "TOC" symbol is treated as SymbolRef::ST_Other.
    if (SymNameOrError.get() == "TOC")
      return SymbolRef::ST_Other;

    // The symbol for a section name is treated as SymbolRef::ST_Other.
    StringRef SecName;
    if (is64Bit())
      SecName = XCOFFObjectFile::toSection64(SecDRIOrErr.get())->getName();
    else
      SecName = XCOFFObjectFile::toSection32(SecDRIOrErr.get())->getName();

    if (SecName == SymNameOrError.get())
      return SymbolRef::ST_Other;
  } else
    return SymNameOrError.takeError();

  if (isSectionData(SecDRI) || isSectionBSS(SecDRI))
    return SymbolRef::ST_Data;

  if (isDebugSection(SecDRI))
    return SymbolRef::ST_Debug;

  return SymbolRef::ST_Other;
}

Expected<section_iterator>
XCOFFObjectFile::getSymbolSection(DataRefImpl Symb) const {
  const int16_t SectNum = toSymbolRef(Symb).getSectionNumber();

  if (isReservedSectionNumber(SectNum))
    return section_end();

  Expected<DataRefImpl> ExpSec = getSectionByNum(SectNum);
  if (!ExpSec)
    return ExpSec.takeError();

  return section_iterator(SectionRef(ExpSec.get(), this));
}

void XCOFFObjectFile::moveSectionNext(DataRefImpl &Sec) const {
  const char *Ptr = reinterpret_cast<const char *>(Sec.p);
  Sec.p = reinterpret_cast<uintptr_t>(Ptr + getSectionHeaderSize());
}

Expected<StringRef> XCOFFObjectFile::getSectionName(DataRefImpl Sec) const {
  return generateXCOFFFixedNameStringRef(getSectionNameInternal(Sec));
}

uint64_t XCOFFObjectFile::getSectionAddress(DataRefImpl Sec) const {
  // Avoid ternary due to failure to convert the ubig32_t value to a unit64_t
  // with MSVC.
  if (is64Bit())
    return toSection64(Sec)->VirtualAddress;

  return toSection32(Sec)->VirtualAddress;
}

uint64_t XCOFFObjectFile::getSectionIndex(DataRefImpl Sec) const {
  // Section numbers in XCOFF are numbered beginning at 1. A section number of
  // zero is used to indicate that a symbol is being imported or is undefined.
  if (is64Bit())
    return toSection64(Sec) - sectionHeaderTable64() + 1;
  else
    return toSection32(Sec) - sectionHeaderTable32() + 1;
}

uint64_t XCOFFObjectFile::getSectionSize(DataRefImpl Sec) const {
  // Avoid ternary due to failure to convert the ubig32_t value to a unit64_t
  // with MSVC.
  if (is64Bit())
    return toSection64(Sec)->SectionSize;

  return toSection32(Sec)->SectionSize;
}

Expected<ArrayRef<uint8_t>>
XCOFFObjectFile::getSectionContents(DataRefImpl Sec) const {
  if (isSectionVirtual(Sec))
    return ArrayRef<uint8_t>();

  uint64_t OffsetToRaw;
  if (is64Bit())
    OffsetToRaw = toSection64(Sec)->FileOffsetToRawData;
  else
    OffsetToRaw = toSection32(Sec)->FileOffsetToRawData;

  const uint8_t * ContentStart = base() + OffsetToRaw;
  uint64_t SectionSize = getSectionSize(Sec);
  if (Error E = Binary::checkOffset(
          Data, reinterpret_cast<uintptr_t>(ContentStart), SectionSize))
    return createError(
        toString(std::move(E)) + ": section data with offset 0x" +
        Twine::utohexstr(OffsetToRaw) + " and size 0x" +
        Twine::utohexstr(SectionSize) + " goes past the end of the file");

  return ArrayRef(ContentStart, SectionSize);
}

uint64_t XCOFFObjectFile::getSectionAlignment(DataRefImpl Sec) const {
  uint64_t Result = 0;
  llvm_unreachable("Not yet implemented!");
  return Result;
}

uint64_t XCOFFObjectFile::getSectionFileOffsetToRawData(DataRefImpl Sec) const {
  if (is64Bit())
    return toSection64(Sec)->FileOffsetToRawData;

  return toSection32(Sec)->FileOffsetToRawData;
}

Expected<uintptr_t> XCOFFObjectFile::getSectionFileOffsetToRawData(
    XCOFF::SectionTypeFlags SectType) const {
  DataRefImpl DRI = getSectionByType(SectType);

  if (DRI.p == 0) // No section is not an error.
    return 0;

  uint64_t SectionOffset = getSectionFileOffsetToRawData(DRI);
  uint64_t SizeOfSection = getSectionSize(DRI);

  uintptr_t SectionStart = reinterpret_cast<uintptr_t>(base() + SectionOffset);
  if (Error E = Binary::checkOffset(Data, SectionStart, SizeOfSection)) {
    SmallString<32> UnknownType;
    Twine(("<Unknown:") + Twine::utohexstr(SectType) + ">")
        .toVector(UnknownType);
    const char *SectionName = UnknownType.c_str();

    switch (SectType) {
#define ECASE(Value, String)                                                   \
  case XCOFF::Value:                                                           \
    SectionName = String;                                                      \
    break

      ECASE(STYP_PAD, "pad");
      ECASE(STYP_DWARF, "dwarf");
      ECASE(STYP_TEXT, "text");
      ECASE(STYP_DATA, "data");
      ECASE(STYP_BSS, "bss");
      ECASE(STYP_EXCEPT, "expect");
      ECASE(STYP_INFO, "info");
      ECASE(STYP_TDATA, "tdata");
      ECASE(STYP_TBSS, "tbss");
      ECASE(STYP_LOADER, "loader");
      ECASE(STYP_DEBUG, "debug");
      ECASE(STYP_TYPCHK, "typchk");
      ECASE(STYP_OVRFLO, "ovrflo");
#undef ECASE
    }
    return createError(toString(std::move(E)) + ": " + SectionName +
                       " section with offset 0x" +
                       Twine::utohexstr(SectionOffset) + " and size 0x" +
                       Twine::utohexstr(SizeOfSection) +
                       " goes past the end of the file");
  }
  return SectionStart;
}

bool XCOFFObjectFile::isSectionCompressed(DataRefImpl Sec) const {
  return false;
}

bool XCOFFObjectFile::isSectionText(DataRefImpl Sec) const {
  return getSectionFlags(Sec) & XCOFF::STYP_TEXT;
}

bool XCOFFObjectFile::isSectionData(DataRefImpl Sec) const {
  uint32_t Flags = getSectionFlags(Sec);
  return Flags & (XCOFF::STYP_DATA | XCOFF::STYP_TDATA);
}

bool XCOFFObjectFile::isSectionBSS(DataRefImpl Sec) const {
  uint32_t Flags = getSectionFlags(Sec);
  return Flags & (XCOFF::STYP_BSS | XCOFF::STYP_TBSS);
}

bool XCOFFObjectFile::isDebugSection(DataRefImpl Sec) const {
  uint32_t Flags = getSectionFlags(Sec);
  return Flags & (XCOFF::STYP_DEBUG | XCOFF::STYP_DWARF);
}

bool XCOFFObjectFile::isSectionVirtual(DataRefImpl Sec) const {
  return is64Bit() ? toSection64(Sec)->FileOffsetToRawData == 0
                   : toSection32(Sec)->FileOffsetToRawData == 0;
}

relocation_iterator XCOFFObjectFile::section_rel_begin(DataRefImpl Sec) const {
  DataRefImpl Ret;
  if (is64Bit()) {
    const XCOFFSectionHeader64 *SectionEntPtr = toSection64(Sec);
    auto RelocationsOrErr =
        relocations<XCOFFSectionHeader64, XCOFFRelocation64>(*SectionEntPtr);
    if (Error E = RelocationsOrErr.takeError()) {
      // TODO: report the error up the stack.
      consumeError(std::move(E));
      return relocation_iterator(RelocationRef());
    }
    Ret.p = reinterpret_cast<uintptr_t>(&*RelocationsOrErr.get().begin());
  } else {
    const XCOFFSectionHeader32 *SectionEntPtr = toSection32(Sec);
    auto RelocationsOrErr =
        relocations<XCOFFSectionHeader32, XCOFFRelocation32>(*SectionEntPtr);
    if (Error E = RelocationsOrErr.takeError()) {
      // TODO: report the error up the stack.
      consumeError(std::move(E));
      return relocation_iterator(RelocationRef());
    }
    Ret.p = reinterpret_cast<uintptr_t>(&*RelocationsOrErr.get().begin());
  }
  return relocation_iterator(RelocationRef(Ret, this));
}

relocation_iterator XCOFFObjectFile::section_rel_end(DataRefImpl Sec) const {
  DataRefImpl Ret;
  if (is64Bit()) {
    const XCOFFSectionHeader64 *SectionEntPtr = toSection64(Sec);
    auto RelocationsOrErr =
        relocations<XCOFFSectionHeader64, XCOFFRelocation64>(*SectionEntPtr);
    if (Error E = RelocationsOrErr.takeError()) {
      // TODO: report the error up the stack.
      consumeError(std::move(E));
      return relocation_iterator(RelocationRef());
    }
    Ret.p = reinterpret_cast<uintptr_t>(&*RelocationsOrErr.get().end());
  } else {
    const XCOFFSectionHeader32 *SectionEntPtr = toSection32(Sec);
    auto RelocationsOrErr =
        relocations<XCOFFSectionHeader32, XCOFFRelocation32>(*SectionEntPtr);
    if (Error E = RelocationsOrErr.takeError()) {
      // TODO: report the error up the stack.
      consumeError(std::move(E));
      return relocation_iterator(RelocationRef());
    }
    Ret.p = reinterpret_cast<uintptr_t>(&*RelocationsOrErr.get().end());
  }
  return relocation_iterator(RelocationRef(Ret, this));
}

void XCOFFObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
  if (is64Bit())
    Rel.p = reinterpret_cast<uintptr_t>(viewAs<XCOFFRelocation64>(Rel.p) + 1);
  else
    Rel.p = reinterpret_cast<uintptr_t>(viewAs<XCOFFRelocation32>(Rel.p) + 1);
}

uint64_t XCOFFObjectFile::getRelocationOffset(DataRefImpl Rel) const {
  if (is64Bit()) {
    const XCOFFRelocation64 *Reloc = viewAs<XCOFFRelocation64>(Rel.p);
    const XCOFFSectionHeader64 *Sec64 = sectionHeaderTable64();
    const uint64_t RelocAddress = Reloc->VirtualAddress;
    const uint16_t NumberOfSections = getNumberOfSections();
    for (uint16_t I = 0; I < NumberOfSections; ++I) {
      // Find which section this relocation belongs to, and get the
      // relocation offset relative to the start of the section.
      if (Sec64->VirtualAddress <= RelocAddress &&
          RelocAddress < Sec64->VirtualAddress + Sec64->SectionSize) {
        return RelocAddress - Sec64->VirtualAddress;
      }
      ++Sec64;
    }
  } else {
    const XCOFFRelocation32 *Reloc = viewAs<XCOFFRelocation32>(Rel.p);
    const XCOFFSectionHeader32 *Sec32 = sectionHeaderTable32();
    const uint32_t RelocAddress = Reloc->VirtualAddress;
    const uint16_t NumberOfSections = getNumberOfSections();
    for (uint16_t I = 0; I < NumberOfSections; ++I) {
      // Find which section this relocation belongs to, and get the
      // relocation offset relative to the start of the section.
      if (Sec32->VirtualAddress <= RelocAddress &&
          RelocAddress < Sec32->VirtualAddress + Sec32->SectionSize) {
        return RelocAddress - Sec32->VirtualAddress;
      }
      ++Sec32;
    }
  }
  return InvalidRelocOffset;
}

symbol_iterator XCOFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
  uint32_t Index;
  if (is64Bit()) {
    const XCOFFRelocation64 *Reloc = viewAs<XCOFFRelocation64>(Rel.p);
    Index = Reloc->SymbolIndex;

    if (Index >= getNumberOfSymbolTableEntries64())
      return symbol_end();
  } else {
    const XCOFFRelocation32 *Reloc = viewAs<XCOFFRelocation32>(Rel.p);
    Index = Reloc->SymbolIndex;

    if (Index >= getLogicalNumberOfSymbolTableEntries32())
      return symbol_end();
  }
  DataRefImpl SymDRI;
  SymDRI.p = getSymbolEntryAddressByIndex(Index);
  return symbol_iterator(SymbolRef(SymDRI, this));
}

uint64_t XCOFFObjectFile::getRelocationType(DataRefImpl Rel) const {
  if (is64Bit())
    return viewAs<XCOFFRelocation64>(Rel.p)->Type;
  return viewAs<XCOFFRelocation32>(Rel.p)->Type;
}

void XCOFFObjectFile::getRelocationTypeName(
    DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
  StringRef Res;
  if (is64Bit()) {
    const XCOFFRelocation64 *Reloc = viewAs<XCOFFRelocation64>(Rel.p);
    Res = XCOFF::getRelocationTypeString(Reloc->Type);
  } else {
    const XCOFFRelocation32 *Reloc = viewAs<XCOFFRelocation32>(Rel.p);
    Res = XCOFF::getRelocationTypeString(Reloc->Type);
  }
  Result.append(Res.begin(), Res.end());
}

Expected<uint32_t> XCOFFObjectFile::getSymbolFlags(DataRefImpl Symb) const {
  XCOFFSymbolRef XCOFFSym = toSymbolRef(Symb);
  uint32_t Result = SymbolRef::SF_None;

  if (XCOFFSym.getSectionNumber() == XCOFF::N_ABS)
    Result |= SymbolRef::SF_Absolute;

  XCOFF::StorageClass SC = XCOFFSym.getStorageClass();
  if (XCOFF::C_EXT == SC || XCOFF::C_WEAKEXT == SC)
    Result |= SymbolRef::SF_Global;

  if (XCOFF::C_WEAKEXT == SC)
    Result |= SymbolRef::SF_Weak;

  if (XCOFFSym.isCsectSymbol()) {
    Expected<XCOFFCsectAuxRef> CsectAuxEntOrErr =
        XCOFFSym.getXCOFFCsectAuxRef();
    if (CsectAuxEntOrErr) {
      if (CsectAuxEntOrErr.get().getSymbolType() == XCOFF::XTY_CM)
        Result |= SymbolRef::SF_Common;
    } else
      return CsectAuxEntOrErr.takeError();
  }

  if (XCOFFSym.getSectionNumber() == XCOFF::N_UNDEF)
    Result |= SymbolRef::SF_Undefined;

  // There is no visibility in old 32 bit XCOFF object file interpret.
  if (is64Bit() || (auxiliaryHeader32() && (auxiliaryHeader32()->getVersion() ==
                                            NEW_XCOFF_INTERPRET))) {
    uint16_t SymType = XCOFFSym.getSymbolType();
    if ((SymType & VISIBILITY_MASK) == SYM_V_HIDDEN)
      Result |= SymbolRef::SF_Hidden;

    if ((SymType & VISIBILITY_MASK) == SYM_V_EXPORTED)
      Result |= SymbolRef::SF_Exported;
  }
  return Result;
}

basic_symbol_iterator XCOFFObjectFile::symbol_begin() const {
  DataRefImpl SymDRI;
  SymDRI.p = reinterpret_cast<uintptr_t>(SymbolTblPtr);
  return basic_symbol_iterator(SymbolRef(SymDRI, this));
}

basic_symbol_iterator XCOFFObjectFile::symbol_end() const {
  DataRefImpl SymDRI;
  const uint32_t NumberOfSymbolTableEntries = getNumberOfSymbolTableEntries();
  SymDRI.p = getSymbolEntryAddressByIndex(NumberOfSymbolTableEntries);
  return basic_symbol_iterator(SymbolRef(SymDRI, this));
}

section_iterator XCOFFObjectFile::section_begin() const {
  DataRefImpl DRI;
  DRI.p = getSectionHeaderTableAddress();
  return section_iterator(SectionRef(DRI, this));
}

section_iterator XCOFFObjectFile::section_end() const {
  DataRefImpl DRI;
  DRI.p = getWithOffset(getSectionHeaderTableAddress(),
                        getNumberOfSections() * getSectionHeaderSize());
  return section_iterator(SectionRef(DRI, this));
}

uint8_t XCOFFObjectFile::getBytesInAddress() const { return is64Bit() ? 8 : 4; }

StringRef XCOFFObjectFile::getFileFormatName() const {
  return is64Bit() ? "aix5coff64-rs6000" : "aixcoff-rs6000";
}

Triple::ArchType XCOFFObjectFile::getArch() const {
  return is64Bit() ? Triple::ppc64 : Triple::ppc;
}

Expected<SubtargetFeatures> XCOFFObjectFile::getFeatures() const {
  return SubtargetFeatures();
}

bool XCOFFObjectFile::isRelocatableObject() const {
  if (is64Bit())
    return !(fileHeader64()->Flags & NoRelMask);
  return !(fileHeader32()->Flags & NoRelMask);
}

Expected<uint64_t> XCOFFObjectFile::getStartAddress() const {
  // TODO FIXME Should get from auxiliary_header->o_entry when support for the
  // auxiliary_header is added.
  return 0;
}

StringRef XCOFFObjectFile::mapDebugSectionName(StringRef Name) const {
  return StringSwitch<StringRef>(Name)
      .Case("dwinfo", "debug_info")
      .Case("dwline", "debug_line")
      .Case("dwpbnms", "debug_pubnames")
      .Case("dwpbtyp", "debug_pubtypes")
      .Case("dwarnge", "debug_aranges")
      .Case("dwabrev", "debug_abbrev")
      .Case("dwstr", "debug_str")
      .Case("dwrnges", "debug_ranges")
      .Case("dwloc", "debug_loc")
      .Case("dwframe", "debug_frame")
      .Case("dwmac", "debug_macinfo")
      .Default(Name);
}

size_t XCOFFObjectFile::getFileHeaderSize() const {
  return is64Bit() ? sizeof(XCOFFFileHeader64) : sizeof(XCOFFFileHeader32);
}

size_t XCOFFObjectFile::getSectionHeaderSize() const {
  return is64Bit() ? sizeof(XCOFFSectionHeader64) :
                     sizeof(XCOFFSectionHeader32);
}

bool XCOFFObjectFile::is64Bit() const {
  return Binary::ID_XCOFF64 == getType();
}

Expected<StringRef> XCOFFObjectFile::getRawData(const char *Start,
                                                uint64_t Size,
                                                StringRef Name) const {
  uintptr_t StartPtr = reinterpret_cast<uintptr_t>(Start);
  // TODO: this path is untested.
  if (Error E = Binary::checkOffset(Data, StartPtr, Size))
    return createError(toString(std::move(E)) + ": " + Name.data() +
                       " data with offset 0x" + Twine::utohexstr(StartPtr) +
                       " and size 0x" + Twine::utohexstr(Size) +
                       " goes past the end of the file");
  return StringRef(Start, Size);
}

uint16_t XCOFFObjectFile::getMagic() const {
  return is64Bit() ? fileHeader64()->Magic : fileHeader32()->Magic;
}

Expected<DataRefImpl> XCOFFObjectFile::getSectionByNum(int16_t Num) const {
  if (Num <= 0 || Num > getNumberOfSections())
    return createStringError(object_error::invalid_section_index,
                             "the section index (" + Twine(Num) +
                                 ") is invalid");

  DataRefImpl DRI;
  DRI.p = getWithOffset(getSectionHeaderTableAddress(),
                        getSectionHeaderSize() * (Num - 1));
  return DRI;
}

DataRefImpl
XCOFFObjectFile::getSectionByType(XCOFF::SectionTypeFlags SectType) const {
  DataRefImpl DRI;
  auto GetSectionAddr = [&](const auto &Sections) -> uintptr_t {
    for (const auto &Sec : Sections)
      if (Sec.getSectionType() == SectType)
        return reinterpret_cast<uintptr_t>(&Sec);
    return uintptr_t(0);
  };
  if (is64Bit())
    DRI.p = GetSectionAddr(sections64());
  else
    DRI.p = GetSectionAddr(sections32());
  return DRI;
}

Expected<StringRef>
XCOFFObjectFile::getSymbolSectionName(XCOFFSymbolRef SymEntPtr) const {
  const int16_t SectionNum = SymEntPtr.getSectionNumber();

  switch (SectionNum) {
  case XCOFF::N_DEBUG:
    return "N_DEBUG";
  case XCOFF::N_ABS:
    return "N_ABS";
  case XCOFF::N_UNDEF:
    return "N_UNDEF";
  default:
    Expected<DataRefImpl> SecRef = getSectionByNum(SectionNum);
    if (SecRef)
      return generateXCOFFFixedNameStringRef(
          getSectionNameInternal(SecRef.get()));
    return SecRef.takeError();
  }
}

unsigned XCOFFObjectFile::getSymbolSectionID(SymbolRef Sym) const {
  XCOFFSymbolRef XCOFFSymRef(Sym.getRawDataRefImpl(), this);
  return XCOFFSymRef.getSectionNumber();
}

bool XCOFFObjectFile::isReservedSectionNumber(int16_t SectionNumber) {
  return (SectionNumber <= 0 && SectionNumber >= -2);
}

uint16_t XCOFFObjectFile::getNumberOfSections() const {
  return is64Bit() ? fileHeader64()->NumberOfSections
                   : fileHeader32()->NumberOfSections;
}

int32_t XCOFFObjectFile::getTimeStamp() const {
  return is64Bit() ? fileHeader64()->TimeStamp : fileHeader32()->TimeStamp;
}

uint16_t XCOFFObjectFile::getOptionalHeaderSize() const {
  return is64Bit() ? fileHeader64()->AuxHeaderSize
                   : fileHeader32()->AuxHeaderSize;
}

uint32_t XCOFFObjectFile::getSymbolTableOffset32() const {
  return fileHeader32()->SymbolTableOffset;
}

int32_t XCOFFObjectFile::getRawNumberOfSymbolTableEntries32() const {
  // As far as symbol table size is concerned, if this field is negative it is
  // to be treated as a 0. However since this field is also used for printing we
  // don't want to truncate any negative values.
  return fileHeader32()->NumberOfSymTableEntries;
}

uint32_t XCOFFObjectFile::getLogicalNumberOfSymbolTableEntries32() const {
  return (fileHeader32()->NumberOfSymTableEntries >= 0
              ? fileHeader32()->NumberOfSymTableEntries
              : 0);
}

uint64_t XCOFFObjectFile::getSymbolTableOffset64() const {
  return fileHeader64()->SymbolTableOffset;
}

uint32_t XCOFFObjectFile::getNumberOfSymbolTableEntries64() const {
  return fileHeader64()->NumberOfSymTableEntries;
}

uint32_t XCOFFObjectFile::getNumberOfSymbolTableEntries() const {
  return is64Bit() ? getNumberOfSymbolTableEntries64()
                   : getLogicalNumberOfSymbolTableEntries32();
}

uintptr_t XCOFFObjectFile::getEndOfSymbolTableAddress() const {
  const uint32_t NumberOfSymTableEntries = getNumberOfSymbolTableEntries();
  return getWithOffset(reinterpret_cast<uintptr_t>(SymbolTblPtr),
                       XCOFF::SymbolTableEntrySize * NumberOfSymTableEntries);
}

void XCOFFObjectFile::checkSymbolEntryPointer(uintptr_t SymbolEntPtr) const {
  if (SymbolEntPtr < reinterpret_cast<uintptr_t>(SymbolTblPtr))
    report_fatal_error("Symbol table entry is outside of symbol table.");

  if (SymbolEntPtr >= getEndOfSymbolTableAddress())
    report_fatal_error("Symbol table entry is outside of symbol table.");

  ptrdiff_t Offset = reinterpret_cast<const char *>(SymbolEntPtr) -
                     reinterpret_cast<const char *>(SymbolTblPtr);

  if (Offset % XCOFF::SymbolTableEntrySize != 0)
    report_fatal_error(
        "Symbol table entry position is not valid inside of symbol table.");
}

uint32_t XCOFFObjectFile::getSymbolIndex(uintptr_t SymbolEntPtr) const {
  return (reinterpret_cast<const char *>(SymbolEntPtr) -
          reinterpret_cast<const char *>(SymbolTblPtr)) /
         XCOFF::SymbolTableEntrySize;
}

uint64_t XCOFFObjectFile::getSymbolSize(DataRefImpl Symb) const {
  uint64_t Result = 0;
  XCOFFSymbolRef XCOFFSym = toSymbolRef(Symb);
  if (XCOFFSym.isCsectSymbol()) {
    Expected<XCOFFCsectAuxRef> CsectAuxRefOrError =
        XCOFFSym.getXCOFFCsectAuxRef();
    if (!CsectAuxRefOrError)
      // TODO: report the error up the stack.
      consumeError(CsectAuxRefOrError.takeError());
    else {
      XCOFFCsectAuxRef CsectAuxRef = CsectAuxRefOrError.get();
      uint8_t SymType = CsectAuxRef.getSymbolType();
      if (SymType == XCOFF::XTY_SD || SymType == XCOFF::XTY_CM)
        Result = CsectAuxRef.getSectionOrLength();
    }
  }
  return Result;
}

uintptr_t XCOFFObjectFile::getSymbolEntryAddressByIndex(uint32_t Index) const {
  return getAdvancedSymbolEntryAddress(
      reinterpret_cast<uintptr_t>(getPointerToSymbolTable()), Index);
}

Expected<StringRef>
XCOFFObjectFile::getSymbolNameByIndex(uint32_t Index) const {
  const uint32_t NumberOfSymTableEntries = getNumberOfSymbolTableEntries();

  if (Index >= NumberOfSymTableEntries)
    return createError("symbol index " + Twine(Index) +
                       " exceeds symbol count " +
                       Twine(NumberOfSymTableEntries));

  DataRefImpl SymDRI;
  SymDRI.p = getSymbolEntryAddressByIndex(Index);
  return getSymbolName(SymDRI);
}

uint16_t XCOFFObjectFile::getFlags() const {
  return is64Bit() ? fileHeader64()->Flags : fileHeader32()->Flags;
}

const char *XCOFFObjectFile::getSectionNameInternal(DataRefImpl Sec) const {
  return is64Bit() ? toSection64(Sec)->Name : toSection32(Sec)->Name;
}

uintptr_t XCOFFObjectFile::getSectionHeaderTableAddress() const {
  return reinterpret_cast<uintptr_t>(SectionHeaderTable);
}

int32_t XCOFFObjectFile::getSectionFlags(DataRefImpl Sec) const {
  return is64Bit() ? toSection64(Sec)->Flags : toSection32(Sec)->Flags;
}

XCOFFObjectFile::XCOFFObjectFile(unsigned int Type, MemoryBufferRef Object)
    : ObjectFile(Type, Object) {
  assert(Type == Binary::ID_XCOFF32 || Type == Binary::ID_XCOFF64);
}

ArrayRef<XCOFFSectionHeader64> XCOFFObjectFile::sections64() const {
  assert(is64Bit() && "64-bit interface called for non 64-bit file.");
  const XCOFFSectionHeader64 *TablePtr = sectionHeaderTable64();
  return ArrayRef<XCOFFSectionHeader64>(TablePtr,
                                        TablePtr + getNumberOfSections());
}

ArrayRef<XCOFFSectionHeader32> XCOFFObjectFile::sections32() const {
  assert(!is64Bit() && "32-bit interface called for non 32-bit file.");
  const XCOFFSectionHeader32 *TablePtr = sectionHeaderTable32();
  return ArrayRef<XCOFFSectionHeader32>(TablePtr,
                                        TablePtr + getNumberOfSections());
}

// In an XCOFF32 file, when the field value is 65535, then an STYP_OVRFLO
// section header contains the actual count of relocation entries in the s_paddr
// field. STYP_OVRFLO headers contain the section index of their corresponding
// sections as their raw "NumberOfRelocations" field value.
template <typename T>
Expected<uint32_t> XCOFFObjectFile::getNumberOfRelocationEntries(
    const XCOFFSectionHeader<T> &Sec) const {
  const T &Section = static_cast<const T &>(Sec);
  if (is64Bit())
    return Section.NumberOfRelocations;

  uint16_t SectionIndex = &Section - sectionHeaderTable<T>() + 1;
  if (Section.NumberOfRelocations < XCOFF::RelocOverflow)
    return Section.NumberOfRelocations;
  for (const auto &Sec : sections32()) {
    if (Sec.Flags == XCOFF::STYP_OVRFLO &&
        Sec.NumberOfRelocations == SectionIndex)
      return Sec.PhysicalAddress;
  }
  return errorCodeToError(object_error::parse_failed);
}

template <typename Shdr, typename Reloc>
Expected<ArrayRef<Reloc>> XCOFFObjectFile::relocations(const Shdr &Sec) const {
  uintptr_t RelocAddr = getWithOffset(reinterpret_cast<uintptr_t>(FileHeader),
                                      Sec.FileOffsetToRelocationInfo);
  auto NumRelocEntriesOrErr = getNumberOfRelocationEntries(Sec);
  if (Error E = NumRelocEntriesOrErr.takeError())
    return std::move(E);

  uint32_t NumRelocEntries = NumRelocEntriesOrErr.get();
  static_assert((sizeof(Reloc) == XCOFF::RelocationSerializationSize64 ||
                 sizeof(Reloc) == XCOFF::RelocationSerializationSize32),
                "Relocation structure is incorrect");
  auto RelocationOrErr =
      getObject<Reloc>(Data, reinterpret_cast<void *>(RelocAddr),
                       NumRelocEntries * sizeof(Reloc));
  if (!RelocationOrErr)
    return createError(
        toString(RelocationOrErr.takeError()) + ": relocations with offset 0x" +
        Twine::utohexstr(Sec.FileOffsetToRelocationInfo) + " and size 0x" +
        Twine::utohexstr(NumRelocEntries * sizeof(Reloc)) +
        " go past the end of the file");

  const Reloc *StartReloc = RelocationOrErr.get();

  return ArrayRef<Reloc>(StartReloc, StartReloc + NumRelocEntries);
}

template <typename ExceptEnt>
Expected<ArrayRef<ExceptEnt>> XCOFFObjectFile::getExceptionEntries() const {
  assert((is64Bit() && sizeof(ExceptEnt) == sizeof(ExceptionSectionEntry64)) ||
         (!is64Bit() && sizeof(ExceptEnt) == sizeof(ExceptionSectionEntry32)));

  Expected<uintptr_t> ExceptionSectOrErr =
      getSectionFileOffsetToRawData(XCOFF::STYP_EXCEPT);
  if (!ExceptionSectOrErr)
    return ExceptionSectOrErr.takeError();

  DataRefImpl DRI = getSectionByType(XCOFF::STYP_EXCEPT);
  if (DRI.p == 0)
    return ArrayRef<ExceptEnt>();

  ExceptEnt *ExceptEntStart =
      reinterpret_cast<ExceptEnt *>(*ExceptionSectOrErr);
  return ArrayRef<ExceptEnt>(
      ExceptEntStart, ExceptEntStart + getSectionSize(DRI) / sizeof(ExceptEnt));
}

template Expected<ArrayRef<ExceptionSectionEntry32>>
XCOFFObjectFile::getExceptionEntries() const;
template Expected<ArrayRef<ExceptionSectionEntry64>>
XCOFFObjectFile::getExceptionEntries() const;

Expected<XCOFFStringTable>
XCOFFObjectFile::parseStringTable(const XCOFFObjectFile *Obj, uint64_t Offset) {
  // If there is a string table, then the buffer must contain at least 4 bytes
  // for the string table's size. Not having a string table is not an error.
  if (Error E = Binary::checkOffset(
          Obj->Data, reinterpret_cast<uintptr_t>(Obj->base() + Offset), 4)) {
    consumeError(std::move(E));
    return XCOFFStringTable{0, nullptr};
  }

  // Read the size out of the buffer.
  uint32_t Size = support::endian::read32be(Obj->base() + Offset);

  // If the size is less then 4, then the string table is just a size and no
  // string data.
  if (Size <= 4)
    return XCOFFStringTable{4, nullptr};

  auto StringTableOrErr =
      getObject<char>(Obj->Data, Obj->base() + Offset, Size);
  if (!StringTableOrErr)
    return createError(toString(StringTableOrErr.takeError()) +
                       ": string table with offset 0x" +
                       Twine::utohexstr(Offset) + " and size 0x" +
                       Twine::utohexstr(Size) +
                       " goes past the end of the file");

  const char *StringTablePtr = StringTableOrErr.get();
  if (StringTablePtr[Size - 1] != '\0')
    return errorCodeToError(object_error::string_table_non_null_end);

  return XCOFFStringTable{Size, StringTablePtr};
}

// This function returns the import file table. Each entry in the import file
// table consists of: "path_name\0base_name\0archive_member_name\0".
Expected<StringRef> XCOFFObjectFile::getImportFileTable() const {
  Expected<uintptr_t> LoaderSectionAddrOrError =
      getSectionFileOffsetToRawData(XCOFF::STYP_LOADER);
  if (!LoaderSectionAddrOrError)
    return LoaderSectionAddrOrError.takeError();

  uintptr_t LoaderSectionAddr = LoaderSectionAddrOrError.get();
  if (!LoaderSectionAddr)
    return StringRef();

  uint64_t OffsetToImportFileTable = 0;
  uint64_t LengthOfImportFileTable = 0;
  if (is64Bit()) {
    const LoaderSectionHeader64 *LoaderSec64 =
        viewAs<LoaderSectionHeader64>(LoaderSectionAddr);
    OffsetToImportFileTable = LoaderSec64->OffsetToImpid;
    LengthOfImportFileTable = LoaderSec64->LengthOfImpidStrTbl;
  } else {
    const LoaderSectionHeader32 *LoaderSec32 =
        viewAs<LoaderSectionHeader32>(LoaderSectionAddr);
    OffsetToImportFileTable = LoaderSec32->OffsetToImpid;
    LengthOfImportFileTable = LoaderSec32->LengthOfImpidStrTbl;
  }

  auto ImportTableOrErr = getObject<char>(
      Data,
      reinterpret_cast<void *>(LoaderSectionAddr + OffsetToImportFileTable),
      LengthOfImportFileTable);
  if (!ImportTableOrErr)
    return createError(
        toString(ImportTableOrErr.takeError()) +
        ": import file table with offset 0x" +
        Twine::utohexstr(LoaderSectionAddr + OffsetToImportFileTable) +
        " and size 0x" + Twine::utohexstr(LengthOfImportFileTable) +
        " goes past the end of the file");

  const char *ImportTablePtr = ImportTableOrErr.get();
  if (ImportTablePtr[LengthOfImportFileTable - 1] != '\0')
    return createError(
        ": import file name table with offset 0x" +
        Twine::utohexstr(LoaderSectionAddr + OffsetToImportFileTable) +
        " and size 0x" + Twine::utohexstr(LengthOfImportFileTable) +
        " must end with a null terminator");

  return StringRef(ImportTablePtr, LengthOfImportFileTable);
}

Expected<std::unique_ptr<XCOFFObjectFile>>
XCOFFObjectFile::create(unsigned Type, MemoryBufferRef MBR) {
  // Can't use std::make_unique because of the private constructor.
  std::unique_ptr<XCOFFObjectFile> Obj;
  Obj.reset(new XCOFFObjectFile(Type, MBR));

  uint64_t CurOffset = 0;
  const auto *Base = Obj->base();
  MemoryBufferRef Data = Obj->Data;

  // Parse file header.
  auto FileHeaderOrErr =
      getObject<void>(Data, Base + CurOffset, Obj->getFileHeaderSize());
  if (Error E = FileHeaderOrErr.takeError())
    return std::move(E);
  Obj->FileHeader = FileHeaderOrErr.get();

  CurOffset += Obj->getFileHeaderSize();

  if (Obj->getOptionalHeaderSize()) {
    auto AuxiliaryHeaderOrErr =
        getObject<void>(Data, Base + CurOffset, Obj->getOptionalHeaderSize());
    if (Error E = AuxiliaryHeaderOrErr.takeError())
      return std::move(E);
    Obj->AuxiliaryHeader = AuxiliaryHeaderOrErr.get();
  }

  CurOffset += Obj->getOptionalHeaderSize();

  // Parse the section header table if it is present.
  if (Obj->getNumberOfSections()) {
    uint64_t SectionHeadersSize =
        Obj->getNumberOfSections() * Obj->getSectionHeaderSize();
    auto SecHeadersOrErr =
        getObject<void>(Data, Base + CurOffset, SectionHeadersSize);
    if (!SecHeadersOrErr)
      return createError(toString(SecHeadersOrErr.takeError()) +
                         ": section headers with offset 0x" +
                         Twine::utohexstr(CurOffset) + " and size 0x" +
                         Twine::utohexstr(SectionHeadersSize) +
                         " go past the end of the file");

    Obj->SectionHeaderTable = SecHeadersOrErr.get();
  }

  const uint32_t NumberOfSymbolTableEntries =
      Obj->getNumberOfSymbolTableEntries();

  // If there is no symbol table we are done parsing the memory buffer.
  if (NumberOfSymbolTableEntries == 0)
    return std::move(Obj);

  // Parse symbol table.
  CurOffset = Obj->is64Bit() ? Obj->getSymbolTableOffset64()
                             : Obj->getSymbolTableOffset32();
  const uint64_t SymbolTableSize =
      static_cast<uint64_t>(XCOFF::SymbolTableEntrySize) *
      NumberOfSymbolTableEntries;
  auto SymTableOrErr =
      getObject<void *>(Data, Base + CurOffset, SymbolTableSize);
  if (!SymTableOrErr)
    return createError(
        toString(SymTableOrErr.takeError()) + ": symbol table with offset 0x" +
        Twine::utohexstr(CurOffset) + " and size 0x" +
        Twine::utohexstr(SymbolTableSize) + " goes past the end of the file");

  Obj->SymbolTblPtr = SymTableOrErr.get();
  CurOffset += SymbolTableSize;

  // Parse String table.
  Expected<XCOFFStringTable> StringTableOrErr =
      parseStringTable(Obj.get(), CurOffset);
  if (Error E = StringTableOrErr.takeError())
    return std::move(E);
  Obj->StringTable = StringTableOrErr.get();

  return std::move(Obj);
}

Expected<std::unique_ptr<ObjectFile>>
ObjectFile::createXCOFFObjectFile(MemoryBufferRef MemBufRef,
                                  unsigned FileType) {
  return XCOFFObjectFile::create(FileType, MemBufRef);
}

std::optional<StringRef> XCOFFObjectFile::tryGetCPUName() const {
  return StringRef("future");
}

bool XCOFFSymbolRef::isFunction() const {
  if (!isCsectSymbol())
    return false;

  if (getSymbolType() & FunctionSym)
    return true;

  Expected<XCOFFCsectAuxRef> ExpCsectAuxEnt = getXCOFFCsectAuxRef();
  if (!ExpCsectAuxEnt) {
    // If we could not get the CSECT auxiliary entry, then treat this symbol as
    // if it isn't a function. Consume the error and return `false` to move on.
    consumeError(ExpCsectAuxEnt.takeError());
    return false;
  }

  const XCOFFCsectAuxRef CsectAuxRef = ExpCsectAuxEnt.get();

  // A function definition should be a label definition.
  // FIXME: This is not necessarily the case when -ffunction-sections is
  // enabled.
  if (!CsectAuxRef.isLabel())
    return false;

  if (CsectAuxRef.getStorageMappingClass() != XCOFF::XMC_PR)
    return false;

  const int16_t SectNum = getSectionNumber();
  Expected<DataRefImpl> SI = OwningObjectPtr->getSectionByNum(SectNum);
  if (!SI) {
    // If we could not get the section, then this symbol should not be
    // a function. So consume the error and return `false` to move on.
    consumeError(SI.takeError());
    return false;
  }

  return (OwningObjectPtr->getSectionFlags(SI.get()) & XCOFF::STYP_TEXT);
}

bool XCOFFSymbolRef::isCsectSymbol() const {
  XCOFF::StorageClass SC = getStorageClass();
  return (SC == XCOFF::C_EXT || SC == XCOFF::C_WEAKEXT ||
          SC == XCOFF::C_HIDEXT);
}

Expected<XCOFFCsectAuxRef> XCOFFSymbolRef::getXCOFFCsectAuxRef() const {
  assert(isCsectSymbol() &&
         "Calling csect symbol interface with a non-csect symbol.");

  uint8_t NumberOfAuxEntries = getNumberOfAuxEntries();

  Expected<StringRef> NameOrErr = getName();
  if (auto Err = NameOrErr.takeError())
    return std::move(Err);

  uint32_t SymbolIdx = OwningObjectPtr->getSymbolIndex(getEntryAddress());
  if (!NumberOfAuxEntries) {
    return createError("csect symbol \"" + *NameOrErr + "\" with index " +
                       Twine(SymbolIdx) + " contains no auxiliary entry");
  }

  if (!OwningObjectPtr->is64Bit()) {
    // In XCOFF32, the csect auxilliary entry is always the last auxiliary
    // entry for the symbol.
    uintptr_t AuxAddr = XCOFFObjectFile::getAdvancedSymbolEntryAddress(
        getEntryAddress(), NumberOfAuxEntries);
    return XCOFFCsectAuxRef(viewAs<XCOFFCsectAuxEnt32>(AuxAddr));
  }

  // XCOFF64 uses SymbolAuxType to identify the auxiliary entry type.
  // We need to iterate through all the auxiliary entries to find it.
  for (uint8_t Index = NumberOfAuxEntries; Index > 0; --Index) {
    uintptr_t AuxAddr = XCOFFObjectFile::getAdvancedSymbolEntryAddress(
        getEntryAddress(), Index);
    if (*OwningObjectPtr->getSymbolAuxType(AuxAddr) ==
        XCOFF::SymbolAuxType::AUX_CSECT) {
#ifndef NDEBUG
      OwningObjectPtr->checkSymbolEntryPointer(AuxAddr);
#endif
      return XCOFFCsectAuxRef(viewAs<XCOFFCsectAuxEnt64>(AuxAddr));
    }
  }

  return createError(
      "a csect auxiliary entry has not been found for symbol \"" + *NameOrErr +
      "\" with index " + Twine(SymbolIdx));
}

Expected<StringRef> XCOFFSymbolRef::getName() const {
  // A storage class value with the high-order bit on indicates that the name is
  // a symbolic debugger stabstring.
  if (getStorageClass() & 0x80)
    return StringRef("Unimplemented Debug Name");

  if (Entry32) {
    if (Entry32->NameInStrTbl.Magic != XCOFFSymbolRef::NAME_IN_STR_TBL_MAGIC)
      return generateXCOFFFixedNameStringRef(Entry32->SymbolName);

    return OwningObjectPtr->getStringTableEntry(Entry32->NameInStrTbl.Offset);
  }

  return OwningObjectPtr->getStringTableEntry(Entry64->Offset);
}

// Explictly instantiate template classes.
template struct XCOFFSectionHeader<XCOFFSectionHeader32>;
template struct XCOFFSectionHeader<XCOFFSectionHeader64>;

template struct XCOFFRelocation<llvm::support::ubig32_t>;
template struct XCOFFRelocation<llvm::support::ubig64_t>;

template llvm::Expected<llvm::ArrayRef<llvm::object::XCOFFRelocation64>>
llvm::object::XCOFFObjectFile::relocations<llvm::object::XCOFFSectionHeader64,
                                           llvm::object::XCOFFRelocation64>(
    llvm::object::XCOFFSectionHeader64 const &) const;
template llvm::Expected<llvm::ArrayRef<llvm::object::XCOFFRelocation32>>
llvm::object::XCOFFObjectFile::relocations<llvm::object::XCOFFSectionHeader32,
                                           llvm::object::XCOFFRelocation32>(
    llvm::object::XCOFFSectionHeader32 const &) const;

bool doesXCOFFTracebackTableBegin(ArrayRef<uint8_t> Bytes) {
  if (Bytes.size() < 4)
    return false;

  return support::endian::read32be(Bytes.data()) == 0;
}

#define GETVALUEWITHMASK(X) (Data & (TracebackTable::X))
#define GETVALUEWITHMASKSHIFT(X, S)                                            \
  ((Data & (TracebackTable::X)) >> (TracebackTable::S))

Expected<TBVectorExt> TBVectorExt::create(StringRef TBvectorStrRef) {
  Error Err = Error::success();
  TBVectorExt TBTVecExt(TBvectorStrRef, Err);
  if (Err)
    return std::move(Err);
  return TBTVecExt;
}

TBVectorExt::TBVectorExt(StringRef TBvectorStrRef, Error &Err) {
  const uint8_t *Ptr = reinterpret_cast<const uint8_t *>(TBvectorStrRef.data());
  Data = support::endian::read16be(Ptr);
  uint32_t VecParmsTypeValue = support::endian::read32be(Ptr + 2);
  unsigned ParmsNum =
      GETVALUEWITHMASKSHIFT(NumberOfVectorParmsMask, NumberOfVectorParmsShift);

  ErrorAsOutParameter EAO(&Err);
  Expected<SmallString<32>> VecParmsTypeOrError =
      parseVectorParmsType(VecParmsTypeValue, ParmsNum);
  if (!VecParmsTypeOrError)
    Err = VecParmsTypeOrError.takeError();
  else
    VecParmsInfo = VecParmsTypeOrError.get();
}

uint8_t TBVectorExt::getNumberOfVRSaved() const {
  return GETVALUEWITHMASKSHIFT(NumberOfVRSavedMask, NumberOfVRSavedShift);
}

bool TBVectorExt::isVRSavedOnStack() const {
  return GETVALUEWITHMASK(IsVRSavedOnStackMask);
}

bool TBVectorExt::hasVarArgs() const {
  return GETVALUEWITHMASK(HasVarArgsMask);
}

uint8_t TBVectorExt::getNumberOfVectorParms() const {
  return GETVALUEWITHMASKSHIFT(NumberOfVectorParmsMask,
                               NumberOfVectorParmsShift);
}

bool TBVectorExt::hasVMXInstruction() const {
  return GETVALUEWITHMASK(HasVMXInstructionMask);
}
#undef GETVALUEWITHMASK
#undef GETVALUEWITHMASKSHIFT

Expected<XCOFFTracebackTable>
XCOFFTracebackTable::create(const uint8_t *Ptr, uint64_t &Size, bool Is64Bit) {
  Error Err = Error::success();
  XCOFFTracebackTable TBT(Ptr, Size, Err, Is64Bit);
  if (Err)
    return std::move(Err);
  return TBT;
}

XCOFFTracebackTable::XCOFFTracebackTable(const uint8_t *Ptr, uint64_t &Size,
                                         Error &Err, bool Is64Bit)
    : TBPtr(Ptr), Is64BitObj(Is64Bit) {
  ErrorAsOutParameter EAO(&Err);
  DataExtractor DE(ArrayRef<uint8_t>(Ptr, Size), /*IsLittleEndian=*/false,
                   /*AddressSize=*/0);
  DataExtractor::Cursor Cur(/*Offset=*/0);

  // Skip 8 bytes of mandatory fields.
  DE.getU64(Cur);

  unsigned FixedParmsNum = getNumberOfFixedParms();
  unsigned FloatingParmsNum = getNumberOfFPParms();
  uint32_t ParamsTypeValue = 0;

  // Begin to parse optional fields.
  if (Cur && (FixedParmsNum + FloatingParmsNum) > 0)
    ParamsTypeValue = DE.getU32(Cur);

  if (Cur && hasTraceBackTableOffset())
    TraceBackTableOffset = DE.getU32(Cur);

  if (Cur && isInterruptHandler())
    HandlerMask = DE.getU32(Cur);

  if (Cur && hasControlledStorage()) {
    NumOfCtlAnchors = DE.getU32(Cur);
    if (Cur && NumOfCtlAnchors) {
      SmallVector<uint32_t, 8> Disp;
      Disp.reserve(*NumOfCtlAnchors);
      for (uint32_t I = 0; I < NumOfCtlAnchors && Cur; ++I)
        Disp.push_back(DE.getU32(Cur));
      if (Cur)
        ControlledStorageInfoDisp = std::move(Disp);
    }
  }

  if (Cur && isFuncNamePresent()) {
    uint16_t FunctionNameLen = DE.getU16(Cur);
    if (Cur)
      FunctionName = DE.getBytes(Cur, FunctionNameLen);
  }

  if (Cur && isAllocaUsed())
    AllocaRegister = DE.getU8(Cur);

  unsigned VectorParmsNum = 0;
  if (Cur && hasVectorInfo()) {
    StringRef VectorExtRef = DE.getBytes(Cur, 6);
    if (Cur) {
      Expected<TBVectorExt> TBVecExtOrErr = TBVectorExt::create(VectorExtRef);
      if (!TBVecExtOrErr) {
        Err = TBVecExtOrErr.takeError();
        return;
      }
      VecExt = TBVecExtOrErr.get();
      VectorParmsNum = VecExt->getNumberOfVectorParms();
      // Skip two bytes of padding after vector info.
      DE.skip(Cur, 2);
    }
  }

  // As long as there is no fixed-point or floating-point parameter, this
  // field remains not present even when hasVectorInfo gives true and
  // indicates the presence of vector parameters.
  if (Cur && (FixedParmsNum + FloatingParmsNum) > 0) {
    Expected<SmallString<32>> ParmsTypeOrError =
        hasVectorInfo()
            ? parseParmsTypeWithVecInfo(ParamsTypeValue, FixedParmsNum,
                                        FloatingParmsNum, VectorParmsNum)
            : parseParmsType(ParamsTypeValue, FixedParmsNum, FloatingParmsNum);

    if (!ParmsTypeOrError) {
      Err = ParmsTypeOrError.takeError();
      return;
    }
    ParmsType = ParmsTypeOrError.get();
  }

  if (Cur && hasExtensionTable()) {
    ExtensionTable = DE.getU8(Cur);

    if (*ExtensionTable & ExtendedTBTableFlag::TB_EH_INFO) {
      // eh_info displacement must be 4-byte aligned.
      Cur.seek(alignTo(Cur.tell(), 4));
      EhInfoDisp = Is64BitObj ? DE.getU64(Cur) : DE.getU32(Cur);
    }
  }
  if (!Cur)
    Err = Cur.takeError();

  Size = Cur.tell();
}

#define GETBITWITHMASK(P, X)                                                   \
  (support::endian::read32be(TBPtr + (P)) & (TracebackTable::X))
#define GETBITWITHMASKSHIFT(P, X, S)                                           \
  ((support::endian::read32be(TBPtr + (P)) & (TracebackTable::X)) >>           \
   (TracebackTable::S))

uint8_t XCOFFTracebackTable::getVersion() const {
  return GETBITWITHMASKSHIFT(0, VersionMask, VersionShift);
}

uint8_t XCOFFTracebackTable::getLanguageID() const {
  return GETBITWITHMASKSHIFT(0, LanguageIdMask, LanguageIdShift);
}

bool XCOFFTracebackTable::isGlobalLinkage() const {
  return GETBITWITHMASK(0, IsGlobaLinkageMask);
}

bool XCOFFTracebackTable::isOutOfLineEpilogOrPrologue() const {
  return GETBITWITHMASK(0, IsOutOfLineEpilogOrPrologueMask);
}

bool XCOFFTracebackTable::hasTraceBackTableOffset() const {
  return GETBITWITHMASK(0, HasTraceBackTableOffsetMask);
}

bool XCOFFTracebackTable::isInternalProcedure() const {
  return GETBITWITHMASK(0, IsInternalProcedureMask);
}

bool XCOFFTracebackTable::hasControlledStorage() const {
  return GETBITWITHMASK(0, HasControlledStorageMask);
}

bool XCOFFTracebackTable::isTOCless() const {
  return GETBITWITHMASK(0, IsTOClessMask);
}

bool XCOFFTracebackTable::isFloatingPointPresent() const {
  return GETBITWITHMASK(0, IsFloatingPointPresentMask);
}

bool XCOFFTracebackTable::isFloatingPointOperationLogOrAbortEnabled() const {
  return GETBITWITHMASK(0, IsFloatingPointOperationLogOrAbortEnabledMask);
}

bool XCOFFTracebackTable::isInterruptHandler() const {
  return GETBITWITHMASK(0, IsInterruptHandlerMask);
}

bool XCOFFTracebackTable::isFuncNamePresent() const {
  return GETBITWITHMASK(0, IsFunctionNamePresentMask);
}

bool XCOFFTracebackTable::isAllocaUsed() const {
  return GETBITWITHMASK(0, IsAllocaUsedMask);
}

uint8_t XCOFFTracebackTable::getOnConditionDirective() const {
  return GETBITWITHMASKSHIFT(0, OnConditionDirectiveMask,
                             OnConditionDirectiveShift);
}

bool XCOFFTracebackTable::isCRSaved() const {
  return GETBITWITHMASK(0, IsCRSavedMask);
}

bool XCOFFTracebackTable::isLRSaved() const {
  return GETBITWITHMASK(0, IsLRSavedMask);
}

bool XCOFFTracebackTable::isBackChainStored() const {
  return GETBITWITHMASK(4, IsBackChainStoredMask);
}

bool XCOFFTracebackTable::isFixup() const {
  return GETBITWITHMASK(4, IsFixupMask);
}

uint8_t XCOFFTracebackTable::getNumOfFPRsSaved() const {
  return GETBITWITHMASKSHIFT(4, FPRSavedMask, FPRSavedShift);
}

bool XCOFFTracebackTable::hasExtensionTable() const {
  return GETBITWITHMASK(4, HasExtensionTableMask);
}

bool XCOFFTracebackTable::hasVectorInfo() const {
  return GETBITWITHMASK(4, HasVectorInfoMask);
}

uint8_t XCOFFTracebackTable::getNumOfGPRsSaved() const {
  return GETBITWITHMASKSHIFT(4, GPRSavedMask, GPRSavedShift);
}

uint8_t XCOFFTracebackTable::getNumberOfFixedParms() const {
  return GETBITWITHMASKSHIFT(4, NumberOfFixedParmsMask,
                             NumberOfFixedParmsShift);
}

uint8_t XCOFFTracebackTable::getNumberOfFPParms() const {
  return GETBITWITHMASKSHIFT(4, NumberOfFloatingPointParmsMask,
                             NumberOfFloatingPointParmsShift);
}

bool XCOFFTracebackTable::hasParmsOnStack() const {
  return GETBITWITHMASK(4, HasParmsOnStackMask);
}

#undef GETBITWITHMASK
#undef GETBITWITHMASKSHIFT
} // namespace object
} // namespace llvm
