//===- GOFFObjectFile.cpp - GOFF object file implementation -----*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Implementation of the GOFFObjectFile class.
//
//===----------------------------------------------------------------------===//

#include "llvm/Object/GOFFObjectFile.h"
#include "llvm/BinaryFormat/GOFF.h"
#include "llvm/Object/GOFF.h"
#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/raw_ostream.h"

#ifndef DEBUG_TYPE
#define DEBUG_TYPE "goff"
#endif

using namespace llvm::object;
using namespace llvm;

// Return the type of the record.
static GOFF::RecordType getRecordType(const uint8_t *PhysicalRecord) {
  return GOFF::RecordType((PhysicalRecord[1] & 0xF0) >> 4);
}

// Return true if the record is a continuation record.
static bool isContinuation(const uint8_t *PhysicalRecord) {
  return PhysicalRecord[1] & 0x02;
}

// Return true if the record has a continuation.
static bool isContinued(const uint8_t *PhysicalRecord) {
  return PhysicalRecord[1] & 0x01;
}

// Helper function to get continuous data from a logical record
// Includes PTV header + everything from first record + continuation payloads
// Returns the number of physical records consumed (including the initial
// record)
Expected<unsigned>
GOFFObjectFile::getContinuousData(SmallVectorImpl<uint8_t> &CompleteData,
                                  int DataIndex, uint16_t DataLength,
                                  const uint8_t *Record) const {

  CompleteData.reserve(DataLength + GOFF::RecordLength - DataIndex);

  // First record - include PTV header (bytes 0-2)
  CompleteData.append(Record, Record + GOFF::RecordPrefixLength);
  // Append everything from the first record before the start of the data.
  CompleteData.append(Record + GOFF::RecordPrefixLength, Record + DataIndex);
  // Append the data.
  const uint8_t *Ptr = Record + DataIndex;
  size_t SliceLength = std::min(
      DataLength, static_cast<uint16_t>(GOFF::RecordLength - DataIndex));
  CompleteData.append(Ptr, Ptr + SliceLength);
  DataLength -= SliceLength;
  Ptr += SliceLength;

  unsigned BlocksConsumed = 1; // Count the initial record
  // Continuation records.
  while (DataLength > 0) {
    // Ptr now points to the start of the next physical record.
    // Check that this block is a Continuation.
    assert(isContinuation(Ptr) && "Continuation bit must be set");
    // Check that the last Continuation is terminated correctly.
    if (DataLength <= GOFF::PayloadLength && isContinued(Ptr))
      return createStringError(object_error::parse_failed,
                               "continued bit should not be set");

    SliceLength =
        std::min(DataLength, static_cast<uint16_t>(GOFF::PayloadLength));
    Ptr += GOFF::RecordPrefixLength; // Skip the 3-byte prefix
    CompleteData.append(Ptr, Ptr + SliceLength);
    DataLength -= SliceLength;
    // Advance to the start of the next record
    Ptr += (GOFF::RecordLength - GOFF::RecordPrefixLength);
    BlocksConsumed++;
  }
  return BlocksConsumed;
}

// Walk over the object file and populate FlattenedData.
Error GOFFObjectFile::createFlattenedData() {
  const uint8_t *It = base();
  const uint8_t *End = base() + getData().size();

  // First pass: validate continuation records.
  const uint8_t *ValidateIt = It;
  unsigned ValidateIndex = 0;
  bool PrevContinued = false;
  bool PrevWasContinuation = false;
  GOFF::RecordType PrevRecordType = GOFF::RT_HDR;

  while (ValidateIt < End) {
    bool IsCont = isContinuation(ValidateIt);
    bool IsContd = isContinued(ValidateIt);
    GOFF::RecordType CurrentType = ::getRecordType(ValidateIt);

    if (IsCont) {
      // Continuation record must be preceded by a continued record.
      if (!PrevContinued) {
        return createStringError(object_error::parse_failed,
                                 "record " + std::to_string(ValidateIndex) +
                                     " is a continuation record that is not "
                                     "preceded by a continued record");
      }
      // Continuation record type must match previous record type.
      if (CurrentType != PrevRecordType) {
        return createStringError(
            object_error::parse_failed,
            "record " + std::to_string(ValidateIndex) +
                " is a continuation record that does not match "
                "the type of the previous record");
      }
      // Update PrevContinued for continuation records.
      PrevContinued = IsContd;
    } else {
      // Check if previous non-continuation was marked as continued.
      if (PrevContinued && !PrevWasContinuation) {
        return createStringError(object_error::parse_failed,
                                 "record " + std::to_string(ValidateIndex) +
                                     " is not a continuation record but the "
                                     "preceding record is continued");
      }
      PrevRecordType = CurrentType;
      PrevContinued = IsContd;
    }

    PrevWasContinuation = IsCont;
    ValidateIt += GOFF::RecordLength;
    ValidateIndex++;
  }

  // Second pass: process records now that we know they're valid.
  while (It < End) {
    // Skip continuation records - only process first physical record of each
    // logical record.
    if (isContinuation(It)) {
      It += GOFF::RecordLength;
      continue;
    }

    GOFF::RecordType RecordType = ::getRecordType(It);

    // Call get continuous data based on record type.
    int DataIndex = 0;
    uint16_t DataLength = 0;
    ArrayRef<uint8_t> Slice(It, GOFF::RecordLength);
    DataExtractor DE(Slice, false);

    switch (RecordType) {
    case GOFF::RT_ESD: {
      DataIndex = 72;
      uint64_t Offset = 70;
      DataLength = DE.getU16(&Offset);
      break;
    }
    case GOFF::RT_TXT: {
      DataIndex = 24;
      uint64_t Offset = 22;
      DataLength = DE.getU16(&Offset);
      break;
    }
    case GOFF::RT_RLD: {
      DataIndex = 6;
      uint64_t Offset = 4;
      DataLength = DE.getU16(&Offset);
      break;
    }
    case GOFF::RT_LEN: {
      DataIndex = 8;
      uint64_t Offset = 6;
      DataLength = DE.getU16(&Offset);
      break;
    }
    case GOFF::RT_END: {
      DataIndex = 26;
      uint64_t Offset = 24;
      DataLength = DE.getU16(&Offset);
      break;
    }
    case GOFF::RT_HDR: {
      DataIndex = 60;
      uint64_t Offset = 52;
      DataLength = DE.getU16(&Offset);
      break;
    }
    }
    // Get the flattened data for this logical record (including continuations).
    SmallVector<uint8_t> CompleteData;
    Expected<unsigned> BlocksConsumed =
        getContinuousData(CompleteData, DataIndex, DataLength, It);
    if (!BlocksConsumed) {
      // Log the error but don't fail construction - errors in continuation
      // data will be caught when the data is actually accessed.
      llvm::handleAllErrors(
          BlocksConsumed.takeError(), [](const llvm::ErrorInfoBase &EIB) {
            llvm::errs() << "ERROR: " << EIB.message() << "\n";
          });
      // Skip this record and continue.
      It += GOFF::RecordLength;
      continue;
    }
    FlattenedData.push_back({RecordType, std::move(CompleteData)});

    // Move to next logical record using the number of blocks consumed.
    It += (*BlocksConsumed) * GOFF::RecordLength;
  }
  return Error::success();
}

Expected<std::unique_ptr<ObjectFile>>
ObjectFile::createGOFFObjectFile(MemoryBufferRef Object) {
  Error Err = Error::success();
  std::unique_ptr<GOFFObjectFile> Ret(new GOFFObjectFile(Object, Err));
  if (Err)
    return std::move(Err);
  return std::move(Ret);
}

GOFFObjectFile::GOFFObjectFile(MemoryBufferRef Object, Error &Err)
    : ObjectFile(Binary::ID_GOFF, Object) {
  ErrorAsOutParameter ErrAsOutParam(Err);
  // Object file isn't the right size, bail out early.
  if ((Object.getBufferSize() % GOFF::RecordLength) != 0) {
    Err = createStringError(
        object_error::unexpected_eof,
        "object file is not the right size. Must be a multiple "
        "of 80 bytes, but is " +
            std::to_string(Object.getBufferSize()) + " bytes");
    return;
  }
  // Object file doesn't start/end with HDR/END records.
  // Bail out early.
  if (Object.getBufferSize() != 0) {
    if ((base()[1] & 0xF0) >> 4 != GOFF::RT_HDR) {
      Err = createStringError(object_error::parse_failed,
                              "object file must start with HDR record");
      return;
    }
    if ((base()[Object.getBufferSize() - GOFF::RecordLength + 1] & 0xF0) >> 4 !=
        GOFF::RT_END) {
      Err = createStringError(object_error::parse_failed,
                              "object file must end with END record");
      return;
    }
  }

  if (Error E = createFlattenedData()) {
    Err = std::move(E);
    return;
  }

  SectionEntryImpl DummySection;
  SectionList.emplace_back(DummySection); // Dummy entry at index 0.

  // Dummy relocation entry at index 0.
  GOFFRelEntry DummyRelEntry;
  DummyRelEntry.PEsdId = 0;
  RelEntries.emplace_back(DummyRelEntry);

  for (const auto &[RecordType, Data] : FlattenedData) {
    const uint8_t *I = Data.data();
    switch (RecordType) {
    case GOFF::RT_ESD: {
      // Save ESD record.
      uint32_t EsdId;
      ESDRecord::getEsdId(I, EsdId);
      EsdPtrs.grow(EsdId);
      EsdPtrs[EsdId] = I;

      // Determine and save the "sections" in GOFF.
      // A section is saved as a tuple of the form
      // case (1): (ED,child PR)
      //    - where the PR must have non-zero length.
      // case (2a) (ED,0)
      //   - where the ED is of non-zero length.
      // case (2b) (ED,0)
      //   - where the ED is zero length but
      //     contains a label (LD).
      GOFF::ESDSymbolType SymbolType;
      ESDRecord::getSymbolType(I, SymbolType);
      SectionEntryImpl Section;
      uint32_t Length;
      ESDRecord::getLength(I, Length);
      if (SymbolType == GOFF::ESD_ST_ElementDefinition) {
        // case (2a)
        if (Length != 0) {
          Section.d.a = EsdId;
          SectionList.emplace_back(Section);
        }
      } else if (SymbolType == GOFF::ESD_ST_PartReference) {
        // case (1)
        if (Length != 0) {
          uint32_t SymEdId;
          ESDRecord::getParentEsdId(I, SymEdId);
          Section.d.a = SymEdId;
          Section.d.b = EsdId;
          SectionList.emplace_back(Section);
        }
      } else if (SymbolType == GOFF::ESD_ST_LabelDefinition) {
        // case (2b)
        uint32_t SymEdId;
        ESDRecord::getParentEsdId(I, SymEdId);
        const uint8_t *SymEdRecord = EsdPtrs[SymEdId];
        uint32_t EdLength;
        ESDRecord::getLength(SymEdRecord, EdLength);
        if (!EdLength) { // [ EDID, PRID ]
          // LD child of a zero length parent ED.
          // Add the section ED which was previously ignored.
          Section.d.a = SymEdId;
          SectionList.emplace_back(Section);
        }
      }
      LLVM_DEBUG(dbgs() << "  --  ESD " << EsdId << "\n");
      break;
    }
    case GOFF::RT_TXT:
      // Save TXT records.
      TextPtrs.emplace_back(I);
      LLVM_DEBUG(dbgs() << "  --  TXT\n");
      break;
    case GOFF::RT_RLD:
      setRelocationData(I);
      LLVM_DEBUG(dbgs() << "  --  RLD\n");
      break;
    case GOFF::RT_LEN:
      LLVM_DEBUG(dbgs() << "  --  LEN (GOFF record type) unhandled\n");
      break;
    case GOFF::RT_END:
      LLVM_DEBUG(dbgs() << "  --  END (GOFF record type) unhandled\n");
      break;
    case GOFF::RT_HDR:
      LLVM_DEBUG(dbgs() << "  --  HDR (GOFF record type) unhandled\n");
      break;
    }
  }
}

const uint8_t *GOFFObjectFile::getSymbolEsdRecord(DataRefImpl Symb) const {
  const uint8_t *EsdRecord = EsdPtrs[Symb.d.a];
  return EsdRecord;
}

Expected<StringRef> GOFFObjectFile::getSymbolName(DataRefImpl Symb) const {
  if (auto It = EsdNamesCache.find(Symb.d.a); It != EsdNamesCache.end()) {
    auto &StrPtr = It->second;
    return StringRef(StrPtr.second.get(), StrPtr.first);
  }

  // Get the ESD record pointer from EsdPtrs (points to FlattenedData)
  const uint8_t *EsdRecord = getSymbolEsdRecord(Symb);
  // Extract name from the flattened ESD record
  // Name length is at byte 70-71, name data starts at byte 72
  uint16_t NameLength = ESDRecord::getNameLength(EsdRecord);
  SmallString<256> SymbolName;
  if (NameLength > 0) {
    // Name starts at byte 72 in the record (already flattened, no
    // continuations)
    const uint8_t *NameStart = EsdRecord + 72;
    SymbolName.append(NameStart, NameStart + NameLength);
  }

  SmallString<256> SymbolNameConverted;
  ConverterEBCDIC::convertToUTF8(SymbolName, SymbolNameConverted);

  size_t Size = SymbolNameConverted.size();
  auto StrPtr = std::make_pair(Size, std::make_unique<char[]>(Size));
  char *Buf = StrPtr.second.get();
  memcpy(Buf, SymbolNameConverted.data(), Size);
  EsdNamesCache[Symb.d.a] = std::move(StrPtr);
  return StringRef(Buf, Size);
}

Expected<StringRef> GOFFObjectFile::getSymbolName(SymbolRef Symbol) const {
  return getSymbolName(Symbol.getRawDataRefImpl());
}

Expected<uint64_t> GOFFObjectFile::getSymbolAddress(DataRefImpl Symb) const {
  uint32_t Offset;
  const uint8_t *EsdRecord = getSymbolEsdRecord(Symb);
  ESDRecord::getOffset(EsdRecord, Offset);
  return static_cast<uint64_t>(Offset);
}

uint64_t GOFFObjectFile::getSymbolValueImpl(DataRefImpl Symb) const {
  uint32_t Offset;
  const uint8_t *EsdRecord = getSymbolEsdRecord(Symb);
  ESDRecord::getOffset(EsdRecord, Offset);
  return static_cast<uint64_t>(Offset);
}

uint64_t GOFFObjectFile::getCommonSymbolSizeImpl(DataRefImpl Symb) const {
  return 0;
}

bool GOFFObjectFile::isSymbolUnresolved(DataRefImpl Symb) const {
  const uint8_t *Record = getSymbolEsdRecord(Symb);
  GOFF::ESDSymbolType SymbolType;
  ESDRecord::getSymbolType(Record, SymbolType);

  if (SymbolType == GOFF::ESD_ST_ExternalReference)
    return true;
  if (SymbolType == GOFF::ESD_ST_PartReference) {
    uint32_t Length;
    ESDRecord::getLength(Record, Length);
    if (Length == 0)
      return true;
  }
  return false;
}

bool GOFFObjectFile::isSymbolIndirect(DataRefImpl Symb) const {
  const uint8_t *Record = getSymbolEsdRecord(Symb);
  bool Indirect;
  ESDRecord::getIndirectReference(Record, Indirect);
  return Indirect;
}

Expected<uint32_t> GOFFObjectFile::getSymbolFlags(DataRefImpl Symb) const {
  uint32_t Flags = 0;
  if (isSymbolUnresolved(Symb))
    Flags |= SymbolRef::SF_Undefined;

  const uint8_t *Record = getSymbolEsdRecord(Symb);

  GOFF::ESDBindingStrength BindingStrength;
  ESDRecord::getBindingStrength(Record, BindingStrength);
  if (BindingStrength == GOFF::ESD_BST_Weak)
    Flags |= SymbolRef::SF_Weak;

  GOFF::ESDBindingScope BindingScope;
  ESDRecord::getBindingScope(Record, BindingScope);

  GOFF::ESDSymbolType Type;
  ESDRecord::getSymbolType(Record, Type);

  if (Type != GOFF::ESD_ST_SectionDefinition &&
      Type != GOFF::ESD_ST_ElementDefinition &&
      BindingScope != GOFF::ESD_BSC_Section &&
      BindingScope != GOFF::ESD_BSC_Module) {
    Expected<StringRef> Name = getSymbolName(Symb);
    if (Name && *Name != " ") { // Blank name is local.
      Flags |= SymbolRef::SF_Global;
      if (BindingScope == GOFF::ESD_BSC_ImportExport)
        Flags |= SymbolRef::SF_Exported;
      else if (!(Flags & SymbolRef::SF_Undefined))
        Flags |= SymbolRef::SF_Hidden;
    }
  }

  return Flags;
}

Expected<SymbolRef::Type>
GOFFObjectFile::getSymbolType(DataRefImpl Symb) const {
  const uint8_t *Record = getSymbolEsdRecord(Symb);
  GOFF::ESDSymbolType SymbolType;
  ESDRecord::getSymbolType(Record, SymbolType);
  GOFF::ESDExecutable Executable;
  ESDRecord::getExecutable(Record, Executable);

  if (SymbolType != GOFF::ESD_ST_SectionDefinition &&
      SymbolType != GOFF::ESD_ST_ElementDefinition &&
      SymbolType != GOFF::ESD_ST_LabelDefinition &&
      SymbolType != GOFF::ESD_ST_PartReference &&
      SymbolType != GOFF::ESD_ST_ExternalReference) {
    uint32_t EsdId;
    ESDRecord::getEsdId(Record, EsdId);
    return createStringError(llvm::errc::invalid_argument,
                             "ESD record %" PRIu32
                             " has invalid symbol type 0x%02" PRIX8,
                             EsdId, SymbolType);
  }
  switch (SymbolType) {
  case GOFF::ESD_ST_SectionDefinition:
  case GOFF::ESD_ST_ElementDefinition:
    return SymbolRef::ST_Other;
  case GOFF::ESD_ST_LabelDefinition:
  case GOFF::ESD_ST_PartReference:
  case GOFF::ESD_ST_ExternalReference:
    if (Executable != GOFF::ESD_EXE_CODE && Executable != GOFF::ESD_EXE_DATA &&
        Executable != GOFF::ESD_EXE_Unspecified) {
      uint32_t EsdId;
      ESDRecord::getEsdId(Record, EsdId);
      return createStringError(llvm::errc::invalid_argument,
                               "ESD record %" PRIu32
                               " has unknown Executable type 0x%02X",
                               EsdId, Executable);
    }
    switch (Executable) {
    case GOFF::ESD_EXE_CODE:
      return SymbolRef::ST_Function;
    case GOFF::ESD_EXE_DATA:
      return SymbolRef::ST_Data;
    case GOFF::ESD_EXE_Unspecified:
      return SymbolRef::ST_Unknown;
    }
    llvm_unreachable("Unhandled ESDExecutable");
  }
  llvm_unreachable("Unhandled ESDSymbolType");
}

Expected<section_iterator>
GOFFObjectFile::getSymbolSection(DataRefImpl Symb) const {
  DataRefImpl Sec;

  if (isSymbolUnresolved(Symb))
    return section_iterator(SectionRef(Sec, this));

  const uint8_t *SymEsdRecord = EsdPtrs[Symb.d.a];
  uint32_t SymEdId;
  ESDRecord::getParentEsdId(SymEsdRecord, SymEdId);
  const uint8_t *SymEdRecord = EsdPtrs[SymEdId];

  for (size_t I = 0, E = SectionList.size(); I < E; ++I) {
    bool Found;
    const uint8_t *SectionPrRecord = getSectionPrEsdRecord(I);
    if (SectionPrRecord) {
      Found = SymEsdRecord == SectionPrRecord;
    } else {
      const uint8_t *SectionEdRecord = getSectionEdEsdRecord(I);
      Found = SymEdRecord == SectionEdRecord;
    }

    if (Found) {
      Sec.d.a = I;
      return section_iterator(SectionRef(Sec, this));
    }
  }
  return createStringError(llvm::errc::invalid_argument,
                           "symbol with ESD id " + std::to_string(Symb.d.a) +
                               " refers to invalid section with ESD id " +
                               std::to_string(SymEdId));
}

uint32_t GOFFObjectFile::getZOSSymbolArchiveAttributes(DataRefImpl Symb) const {
  const uint8_t *SymRecord = getSymbolEsdRecord(Symb);
  uint32_t Attrs = 0;

  // Bit 2 (0x4): 64-bit AMODE. If the child AMODE is unspecified,
  // query the parent ED.
  // TODO: The parent-walk path (child ESD_AMODE_None with a parent that has
  // ESD_AMODE_64) cannot currently be tested as GOFFObjectWriter always emits
  // ESD_AMODE_64 directly on LD/ER records and does not set AMODE on ED
  // records. Full coverage requires yaml2obj GOFF ESD record support.
  GOFF::ESDAmode Amode;
  ESDRecord::getAmode(SymRecord, Amode);
  if (Amode == GOFF::ESD_AMODE_None) {
    uint32_t ParentEsdId;
    ESDRecord::getParentEsdId(SymRecord, ParentEsdId);
    if (ParentEsdId) {
      const uint8_t *EdRecord = EsdPtrs[ParentEsdId];
      ESDRecord::getAmode(EdRecord, Amode);
    }
  }
  if (Amode == GOFF::ESD_AMODE_64)
    Attrs |= 0x4;

  // Bit 1 (0x2): XPLink — LinkageType is ESD_LT_XPLink.
  GOFF::ESDLinkageType LinkageType;
  ESDRecord::getLinkageType(SymRecord, LinkageType);
  if (LinkageType == GOFF::ESD_LT_XPLink)
    Attrs |= 0x2;

  // Bit 0 (0x1): Writable Static Area.
  GOFF::ESDNameSpaceId NameSpace;
  ESDRecord::getNameSpaceId(SymRecord, NameSpace);
  if (NameSpace == GOFF::ESD_NS_Parts)
    Attrs |= 0x1;

  return Attrs;
}

uint64_t GOFFObjectFile::getSymbolSize(DataRefImpl Symb) const {
  const uint8_t *Record = getSymbolEsdRecord(Symb);
  uint32_t Length;
  ESDRecord::getLength(Record, Length);
  return Length;
}

const uint8_t *GOFFObjectFile::getSectionEdEsdRecord(DataRefImpl &Sec) const {
  SectionEntryImpl EsdIds = SectionList[Sec.d.a];
  const uint8_t *EsdRecord = EsdPtrs[EsdIds.d.a];
  return EsdRecord;
}

const uint8_t *GOFFObjectFile::getSectionPrEsdRecord(DataRefImpl &Sec) const {
  SectionEntryImpl EsdIds = SectionList[Sec.d.a];
  const uint8_t *EsdRecord = nullptr;
  if (EsdIds.d.b)
    EsdRecord = EsdPtrs[EsdIds.d.b];
  return EsdRecord;
}

const uint8_t *
GOFFObjectFile::getSectionEdEsdRecord(uint32_t SectionIndex) const {
  DataRefImpl Sec;
  Sec.d.a = SectionIndex;
  const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
  return EsdRecord;
}

const uint8_t *
GOFFObjectFile::getSectionPrEsdRecord(uint32_t SectionIndex) const {
  DataRefImpl Sec;
  Sec.d.a = SectionIndex;
  const uint8_t *EsdRecord = getSectionPrEsdRecord(Sec);
  return EsdRecord;
}

uint32_t GOFFObjectFile::getSectionDefEsdId(DataRefImpl &Sec) const {
  const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
  uint32_t Length;
  ESDRecord::getLength(EsdRecord, Length);
  if (Length == 0) {
    const uint8_t *PrEsdRecord = getSectionPrEsdRecord(Sec);
    if (PrEsdRecord)
      EsdRecord = PrEsdRecord;
  }

  uint32_t DefEsdId;
  ESDRecord::getEsdId(EsdRecord, DefEsdId);
  LLVM_DEBUG(dbgs() << "Got def EsdId: " << DefEsdId << '\n');
  return DefEsdId;
}

void GOFFObjectFile::moveSectionNext(DataRefImpl &Sec) const {
  Sec.d.a++;
  if ((Sec.d.a) >= SectionList.size())
    Sec.d.a = 0;
}

Expected<StringRef> GOFFObjectFile::getSectionName(DataRefImpl Sec) const {
  DataRefImpl EdSym;
  SectionEntryImpl EsdIds = SectionList[Sec.d.a];
  EdSym.d.a = EsdIds.d.a;
  Expected<StringRef> Name = getSymbolName(EdSym);
  if (Name) {
    StringRef Res = *Name;
    LLVM_DEBUG(dbgs() << "Got section: " << Res << '\n');
    LLVM_DEBUG(dbgs() << "Final section name: " << Res << '\n');
    Name = Res;
  }
  return Name;
}

uint64_t GOFFObjectFile::getSectionAddress(DataRefImpl Sec) const {
  uint32_t Offset;
  const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
  ESDRecord::getOffset(EsdRecord, Offset);
  return Offset;
}

uint64_t GOFFObjectFile::getSectionSize(DataRefImpl Sec) const {
  uint32_t Length;
  uint32_t DefEsdId = getSectionDefEsdId(Sec);
  const uint8_t *EsdRecord = EsdPtrs[DefEsdId];
  ESDRecord::getLength(EsdRecord, Length);
  LLVM_DEBUG(dbgs() << "Got section size: " << Length << '\n');
  return static_cast<uint64_t>(Length);
}

// Unravel TXT records and expand fill characters to produce
// a contiguous sequence of bytes.
Expected<ArrayRef<uint8_t>>
GOFFObjectFile::getSectionContents(DataRefImpl Sec) const {
  if (auto It = SectionDataCache.find(Sec.d.a); It != SectionDataCache.end()) {
    auto &Buf = It->second;
    return ArrayRef<uint8_t>(Buf);
  }
  uint64_t SectionSize = getSectionSize(Sec);
  uint32_t DefEsdId = getSectionDefEsdId(Sec);

  const uint8_t *EdEsdRecord = getSectionEdEsdRecord(Sec);
  bool FillBytePresent;
  ESDRecord::getFillBytePresent(EdEsdRecord, FillBytePresent);
  uint8_t FillByte = '\0';
  if (FillBytePresent)
    ESDRecord::getFillByteValue(EdEsdRecord, FillByte);

  // Initialize section with fill byte.
  SmallVector<uint8_t> Data(SectionSize, FillByte);

  // Replace section with content from text records.
  for (const uint8_t *TxtRecordPtr : TextPtrs) {
    uint32_t TxtEsdId;
    TXTRecord::getElementEsdId(TxtRecordPtr, TxtEsdId);
    LLVM_DEBUG(dbgs() << "Got txt EsdId: " << TxtEsdId << '\n');

    if (TxtEsdId != DefEsdId)
      continue;

    uint32_t TxtDataOffset;
    TXTRecord::getOffset(TxtRecordPtr, TxtDataOffset);

    uint16_t TxtDataSize;
    TXTRecord::getDataLength(TxtRecordPtr, TxtDataSize);

    LLVM_DEBUG(dbgs() << "Record offset " << TxtDataOffset << ", data size "
                      << TxtDataSize << "\n");

    // Text data starts at byte 24 in the flattened record (already processed
    // continuations)
    const uint8_t *TxtData = TxtRecordPtr + 24;
    assert(TxtDataSize <= Data.size() - TxtDataOffset &&
           "Text data exceeds section size");
    std::copy(TxtData, TxtData + TxtDataSize, Data.begin() + TxtDataOffset);
  }
  auto &Cache = SectionDataCache[Sec.d.a];
  Cache = std::move(Data);
  return ArrayRef<uint8_t>(Cache);
}

uint64_t GOFFObjectFile::getSectionAlignment(DataRefImpl Sec) const {
  const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
  GOFF::ESDAlignment Pow2Alignment;
  ESDRecord::getAlignment(EsdRecord, Pow2Alignment);
  return 1ULL << static_cast<uint64_t>(Pow2Alignment);
}

bool GOFFObjectFile::isSectionText(DataRefImpl Sec) const {
  const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
  GOFF::ESDExecutable Executable;
  ESDRecord::getExecutable(EsdRecord, Executable);
  return Executable == GOFF::ESD_EXE_CODE;
}

bool GOFFObjectFile::isSectionData(DataRefImpl Sec) const {
  const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
  GOFF::ESDExecutable Executable;
  ESDRecord::getExecutable(EsdRecord, Executable);
  return Executable == GOFF::ESD_EXE_DATA;
}

bool GOFFObjectFile::isSectionNoLoad(DataRefImpl Sec) const {
  const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
  GOFF::ESDLoadingBehavior LoadingBehavior;
  ESDRecord::getLoadingBehavior(EsdRecord, LoadingBehavior);
  return LoadingBehavior == GOFF::ESD_LB_NoLoad;
}

bool GOFFObjectFile::isSectionReadOnlyData(DataRefImpl Sec) const {
  if (!isSectionData(Sec))
    return false;

  const uint8_t *EsdRecord = getSectionEdEsdRecord(Sec);
  GOFF::ESDLoadingBehavior LoadingBehavior;
  ESDRecord::getLoadingBehavior(EsdRecord, LoadingBehavior);
  return LoadingBehavior == GOFF::ESD_LB_Initial;
}

bool GOFFObjectFile::isSectionZeroInit(DataRefImpl Sec) const {
  // GOFF uses fill characters and fill characters are applied
  // on getSectionContents() - so we say false to zero init.
  return false;
}

section_iterator GOFFObjectFile::section_begin() const {
  DataRefImpl Sec;
  moveSectionNext(Sec);
  return section_iterator(SectionRef(Sec, this));
}

section_iterator GOFFObjectFile::section_end() const {
  DataRefImpl Sec;
  return section_iterator(SectionRef(Sec, this));
}

void GOFFObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
  for (uint32_t I = Symb.d.a + 1, E = EsdPtrs.size(); I < E; ++I) {
    if (const uint8_t *EsdRecord = EsdPtrs[I]) {
      GOFF::ESDSymbolType SymbolType;
      ESDRecord::getSymbolType(EsdRecord, SymbolType);
      // Skip EDs - i.e. section symbols.
      bool IgnoreSpecialGOFFSymbols = true;
      bool SkipSymbol = ((SymbolType == GOFF::ESD_ST_ElementDefinition) ||
                         (SymbolType == GOFF::ESD_ST_SectionDefinition)) &&
                        IgnoreSpecialGOFFSymbols;
      if (!SkipSymbol) {
        Symb.d.a = I;
        return;
      }
    }
  }
  Symb.d.a = 0;
}

basic_symbol_iterator GOFFObjectFile::symbol_begin() const {
  DataRefImpl Symb;
  moveSymbolNext(Symb);
  return basic_symbol_iterator(SymbolRef(Symb, this));
}

basic_symbol_iterator GOFFObjectFile::symbol_end() const {
  DataRefImpl Symb;
  return basic_symbol_iterator(SymbolRef(Symb, this));
}

inline constexpr uint8_t SAME_R_ID = 0x80;
inline constexpr uint8_t SAME_P_ID = 0x40;
inline constexpr uint8_t SAME_OFFSET = 0x20;
inline constexpr uint8_t EXT_ATTR_PRESENT = 0x04;
inline constexpr uint8_t BYTE_OFFSET_8 = 0x02;

// Populate the relocation entries.
void GOFFObjectFile::setRelocationData(const uint8_t *RldRecord) {
  SmallVector<uint8_t, 8> RelocationData;
  int DataIndex = 6;
  uint16_t DataLength;
  RLDRecord::getDataLength(RldRecord, DataLength);

  // The record is already flattened if it's continued.
  const uint8_t *RldI = RldRecord + DataIndex;
  const uint8_t *RldE = RldI + DataLength;
  uint32_t CurREsdId = 0;
  uint32_t CurPEsdId = 0;
  uint64_t CurPOffset = 0;
  for (const uint8_t *Rld = RldI; Rld < RldE;) {
    GOFFRelEntry RelEntry;
    uint8_t Flags = Rld[0];
    int32_t Length = 8;
    if (!(Flags & SAME_R_ID)) {
      CurREsdId = support::endian::read32be(&Rld[Length]);
      Length += 4;
    }
    if (!(Flags & SAME_P_ID)) {
      CurPEsdId = support::endian::read32be(&Rld[Length]);
      Length += 4;
    }
    if (!(Flags & SAME_OFFSET)) {
      if (Flags & BYTE_OFFSET_8) {
        CurPOffset = support::endian::read64be(&Rld[Length]);
        Length += 8;
      } else {
        CurPOffset = support::endian::read32be(&Rld[Length]);
        Length += 4;
      }
    }
    if (Flags & EXT_ATTR_PRESENT)
      Length += 8;

    RelEntry.PEsdId = CurPEsdId;
    RelEntry.REsdId = CurREsdId;
    RelEntry.POffset = CurPOffset;
    RelEntry.RelType = getRldType(Rld);
    RelEntries.emplace_back(RelEntry);

    Rld += Length;
    assert(Rld <= RldE && "RLD length?");
  }
}

void GOFFObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
  for (size_t I = Rel.d.b + 1, E = RelEntries.size(); I < E; ++I) {
    const GOFFRelEntry &RelEntry = RelEntries[I];
    if (Rel.d.a == RelEntry.PEsdId) {
      Rel.d.b = I;
      return;
    }
  }

  Rel.d.b = 0;
}

uint64_t GOFFObjectFile::getRelocationOffset(DataRefImpl Rel) const {
  assert(Rel.d.b > 0 && Rel.d.b < RelEntries.size() &&
         "Rel Index out of boundary");
  const GOFFRelEntry &RelEntry = RelEntries[Rel.d.b];
  return RelEntry.POffset;
}

symbol_iterator GOFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
  assert(Rel.d.b > 0 && Rel.d.b < RelEntries.size() &&
         "Rel Index out of boundary");
  const GOFFRelEntry &RelEntry = RelEntries[Rel.d.b];
  DataRefImpl RefSym;
  RefSym.d.a = RelEntry.REsdId;
  return basic_symbol_iterator(SymbolRef(RefSym, this));
}

uint64_t GOFFObjectFile::getRelocationType(DataRefImpl Rel) const {
  assert(Rel.d.b > 0 && Rel.d.b < RelEntries.size() &&
         "Rel Index out of boundary");
  const GOFFRelEntry &RelEntry = RelEntries[Rel.d.b];
  return RelEntry.RelType;
}

void GOFFObjectFile::getRelocationTypeName(
    DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
  uint64_t RelType = getRelocationType(Rel);
  std::string HexStr = formatv("R_{0:x-8}", RelType).str();
  Result.append(HexStr.begin(), HexStr.end());
}

relocation_iterator GOFFObjectFile::section_rel_begin(DataRefImpl Sec) const {
  DataRefImpl Rel;
  Rel.d.a = getSectionDefEsdId(Sec);
  Rel.d.b = 0;
  moveRelocationNext(Rel);
  return relocation_iterator(RelocationRef(Rel, this));
}

relocation_iterator GOFFObjectFile::section_rel_end(DataRefImpl Sec) const {
  DataRefImpl Rel;
  Rel.d.a = getSectionDefEsdId(Sec);
  Rel.d.b = 0;
  return relocation_iterator(RelocationRef(Rel, this));
}
