//===- subzero/src/IceELFObjectWriter.cpp - ELF object file writer --------===//
//
//                        The Subzero Code Generator
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Defines the writer for ELF relocatable object files.
///
//===----------------------------------------------------------------------===//

#include "IceELFObjectWriter.h"

#include "IceAssembler.h"
#include "IceDefs.h"
#include "IceELFSection.h"
#include "IceELFStreamer.h"
#include "IceGlobalContext.h"
#include "IceGlobalInits.h"
#include "IceInst.h"
#include "IceOperand.h"

#include "llvm/Support/ELF.h"
#include "llvm/Support/MathExtras.h"

namespace Ice {

namespace {

constexpr struct {
  bool IsELF64;
  uint16_t ELFMachine;
  uint32_t ELFFlags;
} ELFTargetInfo[TargetArch_NUM] = {
#define X(tag, str, is_elf64, e_machine, e_flags)                              \
  { is_elf64, e_machine, e_flags }                                             \
  ,
    TARGETARCH_TABLE
#undef X
};

bool isELF64(const ClFlags &Flags) {
  const TargetArch Arch = Flags.getTargetArch();
  if (Arch >= TargetArch_NUM) {
    llvm_unreachable("Invalid target arch for isELF64");
    return false;
  }

  if (!Flags.getUseSandboxing()) {
    // Unsandboxed code is always ELF32 (pexes are ILP32.)
    return false;
  }

  return ELFTargetInfo[Arch].IsELF64;
}

uint16_t getELFMachine(TargetArch Arch) {
  if (Arch < TargetArch_NUM)
    return ELFTargetInfo[Arch].ELFMachine;
  llvm_unreachable("Invalid target arch for getELFMachine");
  return EM_NONE;
}

uint32_t getELFFlags(TargetArch Arch) {
  if (Arch < TargetArch_NUM)
    return ELFTargetInfo[Arch].ELFFlags;
  llvm_unreachable("Invalid target arch for getELFFlags");
  return 0;
}

} // end of anonymous namespace

ELFObjectWriter::ELFObjectWriter(GlobalContext &Ctx, ELFStreamer &Out)
    : Ctx(Ctx), Str(Out), ELF64(isELF64(getFlags())) {
  // Create the special bookkeeping sections now.
  constexpr char NullSectionName[] = "";
  NullSection = new (Ctx.allocate<ELFSection>())
      ELFSection(NullSectionName, SHT_NULL, 0, 0, 0);

  constexpr char ShStrTabName[] = ".shstrtab";
  ShStrTab = new (Ctx.allocate<ELFStringTableSection>())
      ELFStringTableSection(ShStrTabName, SHT_STRTAB, 0, 1, 0);
  ShStrTab->add(ShStrTabName);

  constexpr char SymTabName[] = ".symtab";
  const Elf64_Xword SymTabAlign = ELF64 ? 8 : 4;
  const Elf64_Xword SymTabEntSize =
      ELF64 ? sizeof(Elf64_Sym) : sizeof(Elf32_Sym);
  static_assert(sizeof(Elf64_Sym) == 24 && sizeof(Elf32_Sym) == 16,
                "Elf_Sym sizes cannot be derived from sizeof");
  SymTab = createSection<ELFSymbolTableSection>(SymTabName, SHT_SYMTAB, 0,
                                                SymTabAlign, SymTabEntSize);
  SymTab->createNullSymbol(NullSection, &Ctx);

  constexpr char StrTabName[] = ".strtab";
  StrTab =
      createSection<ELFStringTableSection>(StrTabName, SHT_STRTAB, 0, 1, 0);
}

template <typename T>
T *ELFObjectWriter::createSection(const std::string &Name, Elf64_Word ShType,
                                  Elf64_Xword ShFlags, Elf64_Xword ShAddralign,
                                  Elf64_Xword ShEntsize) {
  assert(!SectionNumbersAssigned);
  T *NewSection =
      new (Ctx.allocate<T>()) T(Name, ShType, ShFlags, ShAddralign, ShEntsize);
  ShStrTab->add(Name);
  return NewSection;
}

ELFRelocationSection *
ELFObjectWriter::createRelocationSection(const ELFSection *RelatedSection) {
  // Choice of RELA vs REL is actually separate from elf64 vs elf32, but in
  // practice we've only had .rela for elf64 (x86-64). In the future, the two
  // properties may need to be decoupled and the ShEntSize can vary more.
  const Elf64_Word ShType = ELF64 ? SHT_RELA : SHT_REL;
  const std::string RelPrefix = ELF64 ? ".rela" : ".rel";
  const std::string RelSectionName = RelPrefix + RelatedSection->getName();
  const Elf64_Xword ShAlign = ELF64 ? 8 : 4;
  const Elf64_Xword ShEntSize = ELF64 ? sizeof(Elf64_Rela) : sizeof(Elf32_Rel);
  static_assert(sizeof(Elf64_Rela) == 24 && sizeof(Elf32_Rel) == 8,
                "Elf_Rel/Rela sizes cannot be derived from sizeof");
  constexpr Elf64_Xword ShFlags = 0;
  ELFRelocationSection *RelSection = createSection<ELFRelocationSection>(
      RelSectionName, ShType, ShFlags, ShAlign, ShEntSize);
  RelSection->setRelatedSection(RelatedSection);
  return RelSection;
}

template <typename UserSectionList>
void ELFObjectWriter::assignRelSectionNumInPairs(SizeT &CurSectionNumber,
                                                 UserSectionList &UserSections,
                                                 RelSectionList &RelSections,
                                                 SectionList &AllSections) {
  RelSectionList::iterator RelIt = RelSections.begin();
  RelSectionList::iterator RelE = RelSections.end();
  for (ELFSection *UserSection : UserSections) {
    UserSection->setNumber(CurSectionNumber++);
    UserSection->setNameStrIndex(ShStrTab->getIndex(UserSection->getName()));
    AllSections.push_back(UserSection);
    if (RelIt != RelE) {
      ELFRelocationSection *RelSection = *RelIt;
      if (RelSection->getRelatedSection() == UserSection) {
        RelSection->setInfoNum(UserSection->getNumber());
        RelSection->setNumber(CurSectionNumber++);
        RelSection->setNameStrIndex(ShStrTab->getIndex(RelSection->getName()));
        AllSections.push_back(RelSection);
        ++RelIt;
      }
    }
  }
  // Should finish with UserIt at the same time as RelIt.
  assert(RelIt == RelE);
  return;
}

void ELFObjectWriter::assignRelLinkNum(SizeT SymTabNumber,
                                       RelSectionList &RelSections) {
  for (ELFRelocationSection *S : RelSections) {
    S->setLinkNum(SymTabNumber);
  }
}

void ELFObjectWriter::assignSectionNumbersInfo(SectionList &AllSections) {
  // Go through each section, assigning them section numbers and and fill in
  // the size for sections that aren't incrementally updated.
  assert(!SectionNumbersAssigned);
  SizeT CurSectionNumber = 0;
  NullSection->setNumber(CurSectionNumber++);
  // The rest of the fields are initialized to 0, and stay that way.
  AllSections.push_back(NullSection);

  assignRelSectionNumInPairs<TextSectionList>(CurSectionNumber, TextSections,
                                              RelTextSections, AllSections);
  assignRelSectionNumInPairs<DataSectionList>(CurSectionNumber, DataSections,
                                              RelDataSections, AllSections);
  for (ELFSection *BSSSection : BSSSections) {
    BSSSection->setNumber(CurSectionNumber++);
    BSSSection->setNameStrIndex(ShStrTab->getIndex(BSSSection->getName()));
    AllSections.push_back(BSSSection);
  }
  assignRelSectionNumInPairs<DataSectionList>(CurSectionNumber, RODataSections,
                                              RelRODataSections, AllSections);

  ShStrTab->setNumber(CurSectionNumber++);
  ShStrTab->setNameStrIndex(ShStrTab->getIndex(ShStrTab->getName()));
  AllSections.push_back(ShStrTab);

  SymTab->setNumber(CurSectionNumber++);
  SymTab->setNameStrIndex(ShStrTab->getIndex(SymTab->getName()));
  AllSections.push_back(SymTab);

  StrTab->setNumber(CurSectionNumber++);
  StrTab->setNameStrIndex(ShStrTab->getIndex(StrTab->getName()));
  AllSections.push_back(StrTab);

  SymTab->setLinkNum(StrTab->getNumber());
  SymTab->setInfoNum(SymTab->getNumLocals());

  assignRelLinkNum(SymTab->getNumber(), RelTextSections);
  assignRelLinkNum(SymTab->getNumber(), RelDataSections);
  assignRelLinkNum(SymTab->getNumber(), RelRODataSections);
  SectionNumbersAssigned = true;
}

Elf64_Off ELFObjectWriter::alignFileOffset(Elf64_Xword Align) {
  Elf64_Off OffsetInFile = Str.tell();
  Elf64_Xword AlignDiff = Utils::OffsetToAlignment(OffsetInFile, Align);
  if (AlignDiff == 0)
    return OffsetInFile;
  Str.writeZeroPadding(AlignDiff);
  OffsetInFile += AlignDiff;
  return OffsetInFile;
}

void ELFObjectWriter::writeFunctionCode(GlobalString FuncName, bool IsInternal,
                                        Assembler *Asm) {
  assert(!SectionNumbersAssigned);
  TimerMarker T_func(&Ctx, FuncName.toStringOrEmpty());
  TimerMarker Timer(TimerStack::TT_writeELF, &Ctx);
  ELFTextSection *Section = nullptr;
  ELFRelocationSection *RelSection = nullptr;
  const bool FunctionSections = getFlags().getFunctionSections();
  if (TextSections.empty() || FunctionSections) {
    std::string SectionName = ".text";
    if (FunctionSections)
      SectionName += "." + FuncName;
    constexpr Elf64_Xword ShFlags = SHF_ALLOC | SHF_EXECINSTR;
    const Elf64_Xword ShAlign = 1 << Asm->getBundleAlignLog2Bytes();
    Section = createSection<ELFTextSection>(SectionName, SHT_PROGBITS, ShFlags,
                                            ShAlign, 0);
    Elf64_Off OffsetInFile = alignFileOffset(Section->getSectionAlign());
    Section->setFileOffset(OffsetInFile);
    TextSections.push_back(Section);
    RelSection = createRelocationSection(Section);
    RelTextSections.push_back(RelSection);
  } else {
    Section = TextSections[0];
    RelSection = RelTextSections[0];
  }
  const RelocOffsetT OffsetInSection = Section->getCurrentSize();
  // Function symbols are set to 0 size in the symbol table, in contrast to
  // data symbols which have a proper size.
  constexpr SizeT SymbolSize = 0;
  uint8_t SymbolType;
  uint8_t SymbolBinding;
  if (IsInternal && !getFlags().getDisableInternal()) {
    SymbolType = STT_NOTYPE;
    SymbolBinding = STB_LOCAL;
  } else {
    SymbolType = STT_FUNC;
    SymbolBinding = STB_GLOBAL;
  }
  SymTab->createDefinedSym(FuncName, SymbolType, SymbolBinding, Section,
                           OffsetInSection, SymbolSize);
  StrTab->add(FuncName);

  // Copy the fixup information from per-function Assembler memory to the
  // object writer's memory, for writing later.
  const auto &Fixups = Asm->fixups();
  if (!Fixups.empty()) {
    if (!RelSection->isRela()) {
      // This is a non-rela section, so we need to update the instruction stream
      // with the relocation addends.
      for (const auto *Fixup : Fixups) {
        Fixup->emitOffset(Asm);
      }
    }
    RelSection->addRelocations(OffsetInSection, Asm->fixups(), SymTab);
  }
  Section->appendData(Str, Asm->getBufferView());
}

namespace {

ELFObjectWriter::SectionType
classifyGlobalSection(const VariableDeclaration *Var) {
  if (Var->getIsConstant())
    return ELFObjectWriter::ROData;
  if (Var->hasNonzeroInitializer())
    return ELFObjectWriter::Data;
  return ELFObjectWriter::BSS;
}

// Partition the Vars list by SectionType into VarsBySection. If TranslateOnly
// is non-empty, then only the TranslateOnly variable is kept for emission.
void partitionGlobalsBySection(const VariableDeclarationList &Vars,
                               VariableDeclarationPartition VarsBySection[],
                               const std::string &TranslateOnly) {
  for (VariableDeclaration *Var : Vars) {
    if (GlobalContext::matchSymbolName(Var->getName(), TranslateOnly)) {
      size_t Section = classifyGlobalSection(Var);
      assert(Section < ELFObjectWriter::NumSectionTypes);
      VarsBySection[Section].push_back(Var);
    }
  }
}

} // end of anonymous namespace

void ELFObjectWriter::writeDataSection(const VariableDeclarationList &Vars,
                                       FixupKind RelocationKind,
                                       const std::string &SectionSuffix,
                                       bool IsPIC) {
  TimerMarker Timer(TimerStack::TT_writeELF, &Ctx);
  assert(!SectionNumbersAssigned);
  VariableDeclarationPartition VarsBySection[ELFObjectWriter::NumSectionTypes];
  for (auto &SectionList : VarsBySection)
    SectionList.reserve(Vars.size());
  partitionGlobalsBySection(Vars, VarsBySection, getFlags().getTranslateOnly());
  size_t I = 0;
  for (auto &SectionList : VarsBySection) {
    writeDataOfType(static_cast<SectionType>(I++), SectionList, RelocationKind,
                    SectionSuffix, IsPIC);
  }
}

namespace {
std::string MangleSectionName(const char Base[], const std::string &Suffix) {
  if (Suffix.empty())
    return Base;
  return Base + ("." + Suffix);
}
} // end of anonymous namespace

// TODO(jvoung): Handle fdata-sections.
void ELFObjectWriter::writeDataOfType(SectionType ST,
                                      const VariableDeclarationPartition &Vars,
                                      FixupKind RelocationKind,
                                      const std::string &SectionSuffix,
                                      bool IsPIC) {
  if (Vars.empty())
    return;
  ELFDataSection *Section;
  ELFRelocationSection *RelSection;
  Elf64_Xword ShAddralign = 1;
  for (VariableDeclaration *Var : Vars) {
    Elf64_Xword Align = Var->getAlignment();
    ShAddralign = std::max(ShAddralign, Align);
  }
  constexpr Elf64_Xword ShEntsize = 0; // non-uniform data element size.
  // Lift this out, so it can be re-used if we do fdata-sections?
  switch (ST) {
  case ROData: {
    const std::string SectionName =
        MangleSectionName(IsPIC ? ".data.rel.ro" : ".rodata", SectionSuffix);
    const Elf64_Xword ShFlags = IsPIC ? (SHF_ALLOC | SHF_WRITE) : SHF_ALLOC;
    Section = createSection<ELFDataSection>(SectionName, SHT_PROGBITS, ShFlags,
                                            ShAddralign, ShEntsize);
    Section->setFileOffset(alignFileOffset(ShAddralign));
    RODataSections.push_back(Section);
    RelSection = createRelocationSection(Section);
    RelRODataSections.push_back(RelSection);
    break;
  }
  case Data: {
    const std::string SectionName = MangleSectionName(".data", SectionSuffix);
    constexpr Elf64_Xword ShFlags = SHF_ALLOC | SHF_WRITE;
    Section = createSection<ELFDataSection>(SectionName, SHT_PROGBITS, ShFlags,
                                            ShAddralign, ShEntsize);
    Section->setFileOffset(alignFileOffset(ShAddralign));
    DataSections.push_back(Section);
    RelSection = createRelocationSection(Section);
    RelDataSections.push_back(RelSection);
    break;
  }
  case BSS: {
    const std::string SectionName = MangleSectionName(".bss", SectionSuffix);
    constexpr Elf64_Xword ShFlags = SHF_ALLOC | SHF_WRITE;
    Section = createSection<ELFDataSection>(SectionName, SHT_NOBITS, ShFlags,
                                            ShAddralign, ShEntsize);
    Section->setFileOffset(alignFileOffset(ShAddralign));
    BSSSections.push_back(Section);
    break;
  }
  case NumSectionTypes:
    llvm::report_fatal_error("Unknown SectionType");
    break;
  }

  constexpr uint8_t SymbolType = STT_OBJECT;
  for (VariableDeclaration *Var : Vars) {
    // If the variable declaration does not have an initializer, its symtab
    // entry will be created separately.
    if (!Var->hasInitializer())
      continue;
    constexpr Elf64_Xword MinAlign = 1;
    const auto Align = std::max<Elf64_Xword>(MinAlign, Var->getAlignment());
    Section->padToAlignment(Str, Align);
    SizeT SymbolSize = Var->getNumBytes();
    bool IsExternal = Var->isExternal() || getFlags().getDisableInternal();
    const uint8_t SymbolBinding = IsExternal ? STB_GLOBAL : STB_LOCAL;
    GlobalString Name = Var->getName();
    SymTab->createDefinedSym(Name, SymbolType, SymbolBinding, Section,
                             Section->getCurrentSize(), SymbolSize);
    StrTab->add(Name);
    if (!Var->hasNonzeroInitializer()) {
      assert(ST == BSS || ST == ROData);
      if (ST == ROData)
        Section->appendZeros(Str, SymbolSize);
      else
        Section->setSize(Section->getCurrentSize() + SymbolSize);
    } else {
      assert(ST != BSS);
      for (const auto *Init : Var->getInitializers()) {
        switch (Init->getKind()) {
        case VariableDeclaration::Initializer::DataInitializerKind: {
          const auto &Data =
              llvm::cast<VariableDeclaration::DataInitializer>(Init)
                  ->getContents();
          Section->appendData(Str, llvm::StringRef(Data.data(), Data.size()));
          break;
        }
        case VariableDeclaration::Initializer::ZeroInitializerKind:
          Section->appendZeros(Str, Init->getNumBytes());
          break;
        case VariableDeclaration::Initializer::RelocInitializerKind: {
          const auto *Reloc =
              llvm::cast<VariableDeclaration::RelocInitializer>(Init);
          AssemblerFixup NewFixup;
          NewFixup.set_position(Section->getCurrentSize());
          NewFixup.set_kind(Reloc->hasFixup() ? Reloc->getFixup()
                                              : RelocationKind);
          assert(NewFixup.kind() != llvm::ELF::R_ARM_NONE);
          NewFixup.set_value(Ctx.getConstantSym(
              Reloc->getOffset(), Reloc->getDeclaration()->getName()));
          RelSection->addRelocation(NewFixup);
          Section->appendRelocationOffset(Str, RelSection->isRela(),
                                          Reloc->getOffset());
          break;
        }
        }
      }
    }
  }
}

void ELFObjectWriter::writeInitialELFHeader() {
  TimerMarker Timer(TimerStack::TT_writeELF, &Ctx);
  assert(!SectionNumbersAssigned);
  constexpr Elf64_Off DummySHOffset = 0;
  constexpr SizeT DummySHStrIndex = 0;
  constexpr SizeT DummyNumSections = 0;
  if (ELF64) {
    writeELFHeaderInternal<true>(DummySHOffset, DummySHStrIndex,
                                 DummyNumSections);
  } else {
    writeELFHeaderInternal<false>(DummySHOffset, DummySHStrIndex,
                                  DummyNumSections);
  }
}

template <bool IsELF64>
void ELFObjectWriter::writeELFHeaderInternal(Elf64_Off SectionHeaderOffset,
                                             SizeT SectHeaderStrIndex,
                                             SizeT NumSections) {
  // Write the e_ident: magic number, class, etc. The e_ident is byte order and
  // ELF class independent.
  Str.writeBytes(llvm::StringRef(ElfMagic, strlen(ElfMagic)));
  Str.write8(IsELF64 ? ELFCLASS64 : ELFCLASS32);
  Str.write8(ELFDATA2LSB);
  Str.write8(EV_CURRENT);
  Str.write8(ELFOSABI_NONE);
  constexpr uint8_t ELF_ABIVersion = 0;
  Str.write8(ELF_ABIVersion);
  Str.writeZeroPadding(EI_NIDENT - EI_PAD);

  // TODO(jvoung): Handle and test > 64K sections. See the generic ABI doc:
  // https://refspecs.linuxbase.org/elf/gabi4+/ch4.eheader.html e_shnum should
  // be 0 and then actual number of sections is stored in the sh_size member of
  // the 0th section.
  assert(NumSections < SHN_LORESERVE);
  assert(SectHeaderStrIndex < SHN_LORESERVE);

  const TargetArch Arch = getFlags().getTargetArch();
  // Write the rest of the file header, which does depend on byte order and ELF
  // class.
  Str.writeLE16(ET_REL);                                    // e_type
  Str.writeLE16(getELFMachine(getFlags().getTargetArch())); // e_machine
  Str.writeELFWord<IsELF64>(1);                             // e_version
  // Since this is for a relocatable object, there is no entry point, and no
  // program headers.
  Str.writeAddrOrOffset<IsELF64>(0);                                // e_entry
  Str.writeAddrOrOffset<IsELF64>(0);                                // e_phoff
  Str.writeAddrOrOffset<IsELF64>(SectionHeaderOffset);              // e_shoff
  Str.writeELFWord<IsELF64>(getELFFlags(Arch));                     // e_flags
  Str.writeLE16(IsELF64 ? sizeof(Elf64_Ehdr) : sizeof(Elf32_Ehdr)); // e_ehsize
  static_assert(sizeof(Elf64_Ehdr) == 64 && sizeof(Elf32_Ehdr) == 52,
                "Elf_Ehdr sizes cannot be derived from sizeof");
  Str.writeLE16(0); // e_phentsize
  Str.writeLE16(0); // e_phnum
  Str.writeLE16(IsELF64 ? sizeof(Elf64_Shdr)
                        : sizeof(Elf32_Shdr)); // e_shentsize
  static_assert(sizeof(Elf64_Shdr) == 64 && sizeof(Elf32_Shdr) == 40,
                "Elf_Shdr sizes cannot be derived from sizeof");
  Str.writeLE16(static_cast<Elf64_Half>(NumSections));        // e_shnum
  Str.writeLE16(static_cast<Elf64_Half>(SectHeaderStrIndex)); // e_shstrndx
}

template <typename ConstType> void ELFObjectWriter::writeConstantPool(Type Ty) {
  TimerMarker Timer(TimerStack::TT_writeELF, &Ctx);
  ConstantList Pool = Ctx.getConstantPool(Ty);
  if (Pool.empty()) {
    return;
  }
  SizeT Align = typeAlignInBytes(Ty);
  size_t EntSize = typeWidthInBytes(Ty);
  char Buf[20];
  SizeT WriteAmt = std::min(EntSize, llvm::array_lengthof(Buf));
  // Check that we write the full PrimType.
  assert(WriteAmt == EntSize);
  // Assume that writing WriteAmt bytes at a time allows us to avoid aligning
  // between entries.
  assert(WriteAmt % Align == 0);
  constexpr Elf64_Xword ShFlags = SHF_ALLOC | SHF_MERGE;
  std::string SecBuffer;
  llvm::raw_string_ostream SecStrBuf(SecBuffer);
  SecStrBuf << ".rodata.cst" << WriteAmt;
  ELFDataSection *Section = createSection<ELFDataSection>(
      SecStrBuf.str(), SHT_PROGBITS, ShFlags, Align, WriteAmt);
  RODataSections.push_back(Section);
  SizeT OffsetInSection = 0;
  // The symbol table entry doesn't need to know the defined symbol's size
  // since this is in a section with a fixed Entry Size.
  constexpr SizeT SymbolSize = 0;
  Section->setFileOffset(alignFileOffset(Align));

  // If the -reorder-pooled-constant option is set to true, we should shuffle
  // the constants before we emit them.
  if (getFlags().getReorderPooledConstants() && !Pool.empty()) {
    // Use the constant's kind value as the salt for creating random number
    // generator.
    Operand::OperandKind K = (*Pool.begin())->getKind();
    RandomNumberGenerator RNG(getFlags().getRandomSeed(),
                              RPE_PooledConstantReordering, K);
    RandomShuffle(Pool.begin(), Pool.end(),
                  [&RNG](uint64_t N) { return (uint32_t)RNG.next(N); });
  }
  // Write the data.
  for (Constant *C : Pool) {
    if (!C->getShouldBePooled())
      continue;
    auto *Const = llvm::cast<ConstType>(C);
    GlobalString SymName = Const->getLabelName();
    SymTab->createDefinedSym(SymName, STT_NOTYPE, STB_LOCAL, Section,
                             OffsetInSection, SymbolSize);
    StrTab->add(SymName);
    typename ConstType::PrimType Value = Const->getValue();
    memcpy(Buf, &Value, WriteAmt);
    Str.writeBytes(llvm::StringRef(Buf, WriteAmt));
    OffsetInSection += WriteAmt;
  }
  Section->setSize(OffsetInSection);
}

// Instantiate known needed versions of the template, since we are defining the
// function in the .cpp file instead of the .h file. We may need to instantiate
// constant pools for integers as well if we do constant-pooling of large
// integers to remove them from the instruction stream (fewer bytes controlled
// by an attacker).
template void ELFObjectWriter::writeConstantPool<ConstantFloat>(Type Ty);

template void ELFObjectWriter::writeConstantPool<ConstantDouble>(Type Ty);

template void ELFObjectWriter::writeConstantPool<ConstantInteger32>(Type Ty);

void ELFObjectWriter::writeAllRelocationSections() {
  writeRelocationSections(RelTextSections);
  writeRelocationSections(RelDataSections);
  writeRelocationSections(RelRODataSections);
}

void ELFObjectWriter::writeJumpTable(const JumpTableData &JT,
                                     FixupKind RelocationKind, bool IsPIC) {
  TimerMarker Timer(TimerStack::TT_writeELF, &Ctx);
  ELFDataSection *Section;
  ELFRelocationSection *RelSection;
  const Elf64_Xword PointerSize = typeWidthInBytes(getPointerType());
  const Elf64_Xword ShAddralign = PointerSize;
  const Elf64_Xword ShEntsize = PointerSize;
  const GlobalString JTName = JT.getFunctionName();
  const std::string SectionName = MangleSectionName(
      IsPIC ? ".data.rel.ro" : ".rodata",
      (JTName.hasStdString() ? JTName.toString()
                             : std::to_string(JTName.getID())) +
          "$jumptable");
  Section = createSection<ELFDataSection>(SectionName, SHT_PROGBITS, SHF_ALLOC,
                                          ShAddralign, ShEntsize);
  Section->setFileOffset(alignFileOffset(ShAddralign));
  RODataSections.push_back(Section);
  RelSection = createRelocationSection(Section);
  RelRODataSections.push_back(RelSection);

  constexpr uint8_t SymbolType = STT_OBJECT;
  Section->padToAlignment(Str, PointerSize);
  const bool IsExternal = getFlags().getDisableInternal();
  const uint8_t SymbolBinding = IsExternal ? STB_GLOBAL : STB_LOCAL;
  GlobalString JumpTableName = Ctx.getGlobalString(
      InstJumpTable::makeName(JT.getFunctionName(), JT.getId()));
  SymTab->createDefinedSym(JumpTableName, SymbolType, SymbolBinding, Section,
                           Section->getCurrentSize(), PointerSize);
  StrTab->add(JumpTableName);

  for (intptr_t TargetOffset : JT.getTargetOffsets()) {
    AssemblerFixup NewFixup;
    NewFixup.set_position(Section->getCurrentSize());
    NewFixup.set_kind(RelocationKind);
    NewFixup.set_value(Ctx.getConstantSym(TargetOffset, JT.getFunctionName()));
    RelSection->addRelocation(NewFixup);
    Section->appendRelocationOffset(Str, RelSection->isRela(), TargetOffset);
  }
}

void ELFObjectWriter::setUndefinedSyms(const ConstantList &UndefSyms) {
  TimerMarker Timer(TimerStack::TT_writeELF, &Ctx);
  for (const Constant *S : UndefSyms) {
    const auto *Sym = llvm::cast<ConstantRelocatable>(S);
    GlobalString Name = Sym->getName();
    assert(Name.hasStdString());
    bool BadIntrinsic;
    const Intrinsics::FullIntrinsicInfo *Info =
        Ctx.getIntrinsicsInfo().find(Name, BadIntrinsic);
    if (Info)
      continue;
    // Ignore BadIntrinsic, which is set if the name begins with "llvm." but
    // doesn't match a known intrinsic.  If we want this to turn into an error,
    // we should catch it early on.
    assert(Sym->getOffset() == 0);
    SymTab->noteUndefinedSym(Name, NullSection);
    StrTab->add(Name);
  }
}

void ELFObjectWriter::writeRelocationSections(RelSectionList &RelSections) {
  for (ELFRelocationSection *RelSec : RelSections) {
    Elf64_Off Offset = alignFileOffset(RelSec->getSectionAlign());
    RelSec->setFileOffset(Offset);
    RelSec->setSize(RelSec->getSectionDataSize());
    if (ELF64) {
      RelSec->writeData<true>(Str, SymTab);
    } else {
      RelSec->writeData<false>(Str, SymTab);
    }
  }
}

void ELFObjectWriter::writeNonUserSections() {
  TimerMarker Timer(TimerStack::TT_writeELF, &Ctx);

  // Write out the shstrtab now that all sections are known.
  ShStrTab->doLayout();
  ShStrTab->setSize(ShStrTab->getSectionDataSize());
  Elf64_Off ShStrTabOffset = alignFileOffset(ShStrTab->getSectionAlign());
  ShStrTab->setFileOffset(ShStrTabOffset);
  Str.writeBytes(ShStrTab->getSectionData());

  SectionList AllSections;
  assignSectionNumbersInfo(AllSections);

  // Finalize the regular StrTab and fix up references in the SymTab.
  StrTab->doLayout();
  StrTab->setSize(StrTab->getSectionDataSize());

  SymTab->updateIndices(StrTab);

  Elf64_Off SymTabOffset = alignFileOffset(SymTab->getSectionAlign());
  SymTab->setFileOffset(SymTabOffset);
  SymTab->setSize(SymTab->getSectionDataSize());
  SymTab->writeData(Str, ELF64);

  Elf64_Off StrTabOffset = alignFileOffset(StrTab->getSectionAlign());
  StrTab->setFileOffset(StrTabOffset);
  Str.writeBytes(StrTab->getSectionData());

  writeAllRelocationSections();

  // Write out the section headers.
  const size_t ShdrAlign = ELF64 ? 8 : 4;
  Elf64_Off ShOffset = alignFileOffset(ShdrAlign);
  for (const auto S : AllSections) {
    if (ELF64)
      S->writeHeader<true>(Str);
    else
      S->writeHeader<false>(Str);
  }

  // Finally write the updated ELF header w/ the correct number of sections.
  Str.seek(0);
  if (ELF64) {
    writeELFHeaderInternal<true>(ShOffset, ShStrTab->getNumber(),
                                 AllSections.size());
  } else {
    writeELFHeaderInternal<false>(ShOffset, ShStrTab->getNumber(),
                                  AllSections.size());
  }
}

} // end of namespace Ice
