//===- lib/ReaderWriter/ELF/SegmentChunks.h -------------------------------===//
//
//                             The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "SegmentChunks.h"
#include "TargetLayout.h"

namespace lld {
namespace elf {

template <class ELFT>
bool SegmentSlice<ELFT>::compare_slices(SegmentSlice<ELFT> *a,
                                        SegmentSlice<ELFT> *b) {
  return a->startSection() < b->startSection();
}

template <class ELFT>
Segment<ELFT>::Segment(const ELFLinkingContext &ctx, StringRef name,
                       const typename TargetLayout<ELFT>::SegmentType type)
    : Chunk<ELFT>(name, Chunk<ELFT>::Kind::ELFSegment, ctx), _segmentType(type),
      _flags(0), _atomflags(0), _segmentFlags(false) {
  this->_alignment = 1;
  this->_fsize = 0;
  _outputMagic = ctx.getOutputMagic();
}

// This function actually is used, but not in all instantiations of Segment.
LLVM_ATTRIBUTE_UNUSED
static DefinedAtom::ContentPermissions toAtomPerms(uint64_t flags) {
  switch (flags & (SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR)) {
  case SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR:
    return DefinedAtom::permRWX;
  case SHF_ALLOC | SHF_EXECINSTR:
    return DefinedAtom::permR_X;
  case SHF_ALLOC:
    return DefinedAtom::permR__;
  case SHF_ALLOC | SHF_WRITE:
    return DefinedAtom::permRW_;
  default:
    return DefinedAtom::permUnknown;
  }
}

// This function actually is used, but not in all instantiations of Segment.
LLVM_ATTRIBUTE_UNUSED
static DefinedAtom::ContentPermissions toAtomPermsSegment(uint64_t flags) {
  switch (flags & (llvm::ELF::PF_R | llvm::ELF::PF_W | llvm::ELF::PF_X)) {
  case llvm::ELF::PF_R | llvm::ELF::PF_W | llvm::ELF::PF_X:
    return DefinedAtom::permRWX;
  case llvm::ELF::PF_R | llvm::ELF::PF_X:
    return DefinedAtom::permR_X;
  case llvm::ELF::PF_R:
    return DefinedAtom::permR__;
  case llvm::ELF::PF_R | llvm::ELF::PF_W:
    return DefinedAtom::permRW_;
  default:
    return DefinedAtom::permUnknown;
  }
}

template <class ELFT> void Segment<ELFT>::append(Chunk<ELFT> *chunk) {
  _sections.push_back(chunk);
  Section<ELFT> *section = dyn_cast<Section<ELFT>>(chunk);
  if (!section)
    return;
  if (this->_alignment < section->alignment())
    this->_alignment = section->alignment();

  if (_segmentFlags)
    return;
  if (_flags < section->getFlags())
    _flags |= section->getFlags();
  if (_atomflags < toAtomPerms(_flags))
    _atomflags = toAtomPerms(_flags);
}

template <class ELFT>
bool Segment<ELFT>::compareSegments(Segment<ELFT> *sega, Segment<ELFT> *segb) {
  int64_t type1 = sega->segmentType();
  int64_t type2 = segb->segmentType();

  if (type1 == type2)
    return sega->atomflags() < segb->atomflags();

  // The single PT_PHDR segment is required to precede any loadable
  // segment.  We simply make it always first.
  if (type1 == llvm::ELF::PT_PHDR)
    return true;
  if (type2 == llvm::ELF::PT_PHDR)
    return false;

  // The single PT_INTERP segment is required to precede any loadable
  // segment.  We simply make it always second.
  if (type1 == llvm::ELF::PT_INTERP)
    return true;
  if (type2 == llvm::ELF::PT_INTERP)
    return false;

  // We then put PT_LOAD segments before any other segments.
  if (type1 == llvm::ELF::PT_LOAD)
    return true;
  if (type2 == llvm::ELF::PT_LOAD)
    return false;

  // We put the PT_GNU_RELRO segment last, because that is where the
  // dynamic linker expects to find it
  if (type1 == llvm::ELF::PT_GNU_RELRO)
    return false;
  if (type2 == llvm::ELF::PT_GNU_RELRO)
    return true;

  // We put the PT_TLS segment last except for the PT_GNU_RELRO
  // segment, because that is where the dynamic linker expects to find
  if (type1 == llvm::ELF::PT_TLS)
    return false;
  if (type2 == llvm::ELF::PT_TLS)
    return true;

  // Otherwise compare the types to establish an arbitrary ordering.
  // FIXME: Should figure out if we should just make all other types compare
  // equal, but if so, we should probably do the same for atom flags and change
  // users of this to use stable_sort.
  return type1 < type2;
}

template <class ELFT>
void Segment<ELFT>::assignFileOffsets(uint64_t startOffset) {
  uint64_t fileOffset = startOffset;
  uint64_t curSliceFileOffset = fileOffset;
  bool isDataPageAlignedForNMagic = false;
  bool alignSegments = this->_ctx.alignSegments();
  uint64_t p_align = this->_ctx.getPageSize();
  uint64_t lastVirtualAddress = 0;

  this->setFileOffset(startOffset);
  bool changeOffset = false;
  uint64_t newOffset = 0;
  for (auto &slice : slices()) {
    bool isFirstSection = true;
    for (auto section : slice->sections()) {
      // Handle linker script expressions, which may change the offset
      if (auto expr = dyn_cast<ExpressionChunk<ELFT>>(section)) {
        if (!isFirstSection) {
          changeOffset = true;
          newOffset = fileOffset + expr->virtualAddr() - lastVirtualAddress;
        }
        continue;
      }
      if (changeOffset) {
        changeOffset = false;
        fileOffset = newOffset;
      }
      // Align fileoffset to the alignment of the section.
      fileOffset = llvm::RoundUpToAlignment(fileOffset, section->alignment());
      // If the linker outputmagic is set to OutputMagic::NMAGIC, align the Data
      // to a page boundary
      if (isFirstSection &&
          _outputMagic != ELFLinkingContext::OutputMagic::NMAGIC &&
          _outputMagic != ELFLinkingContext::OutputMagic::OMAGIC) {
        // Align to a page only if the output is not
        // OutputMagic::NMAGIC/OutputMagic::OMAGIC
        if (alignSegments)
          fileOffset = llvm::RoundUpToAlignment(fileOffset, p_align);
        // Align according to ELF spec.
        // in p75, http://www.sco.com/developers/devspecs/gabi41.pdf
        uint64_t virtualAddress = slice->virtualAddr();
        Section<ELFT> *sect = dyn_cast<Section<ELFT>>(section);
        if (sect && sect->isLoadableSection() &&
            ((virtualAddress & (p_align - 1)) != (fileOffset & (p_align - 1))))
          fileOffset = llvm::RoundUpToAlignment(fileOffset, p_align) +
                       (virtualAddress % p_align);
      } else if (!isDataPageAlignedForNMagic && needAlign(section)) {
        fileOffset =
            llvm::RoundUpToAlignment(fileOffset, this->_ctx.getPageSize());
        isDataPageAlignedForNMagic = true;
      }
      if (isFirstSection) {
        slice->setFileOffset(fileOffset);
        isFirstSection = false;
        curSliceFileOffset = fileOffset;
      }
      section->setFileOffset(fileOffset);
      fileOffset += section->fileSize();
      lastVirtualAddress = section->virtualAddr() + section->memSize();
    }
    changeOffset = false;
    slice->setFileSize(fileOffset - curSliceFileOffset);
  }
  this->setFileSize(fileOffset - startOffset);
}

/// \brief Assign virtual addresses to the slices
template <class ELFT> void Segment<ELFT>::assignVirtualAddress(uint64_t addr) {
  int startSection = 0;
  int currSection = 0;
  SectionIter startSectionIter;

  // slice align is set to the max alignment of the chunks that are
  // contained in the slice
  uint64_t sliceAlign = 0;
  // Current slice size
  uint64_t curSliceSize = 0;
  // Current Slice File Offset
  uint64_t curSliceAddress = 0;

  startSectionIter = _sections.begin();
  startSection = 0;
  bool isDataPageAlignedForNMagic = false;
  uint64_t startAddr = addr;
  SegmentSlice<ELFT> *slice = nullptr;
  uint64_t tlsStartAddr = 0;
  bool alignSegments = this->_ctx.alignSegments();
  StringRef prevOutputSectionName = StringRef();
  uint64_t tbssMemsize = 0;

  // If this is first section in the segment, page align the section start
  // address. The linker needs to align the data section to a page boundary
  // only if NMAGIC is set.
  auto si = _sections.begin();
  if (si != _sections.end()) {
    if (alignSegments &&
        _outputMagic != ELFLinkingContext::OutputMagic::NMAGIC &&
        _outputMagic != ELFLinkingContext::OutputMagic::OMAGIC) {
      // Align to a page only if the output is not
      // OutputMagic::NMAGIC/OutputMagic::OMAGIC
      startAddr = llvm::RoundUpToAlignment(startAddr, this->_ctx.getPageSize());
    } else if (needAlign(*si)) {
      // If the linker outputmagic is set to OutputMagic::NMAGIC, align the
      // Data to a page boundary.
      startAddr = llvm::RoundUpToAlignment(startAddr, this->_ctx.getPageSize());
      isDataPageAlignedForNMagic = true;
    }
    // align the startOffset to the section alignment
    uint64_t newAddr = llvm::RoundUpToAlignment(startAddr, (*si)->alignment());
    // Handle linker script expressions, which *may update newAddr* if the
    // expression assigns to "."
    if (auto expr = dyn_cast<ExpressionChunk<ELFT>>(*si))
      expr->evalExpr(newAddr);
    curSliceAddress = newAddr;
    sliceAlign = (*si)->alignment();
    (*si)->setVirtualAddr(curSliceAddress);

    // Handle TLS.
    if (auto section = dyn_cast<Section<ELFT>>(*si)) {
      if (section->getSegmentType() == llvm::ELF::PT_TLS) {
        tlsStartAddr =
            llvm::RoundUpToAlignment(tlsStartAddr, (*si)->alignment());
        section->assignVirtualAddress(tlsStartAddr);
        tlsStartAddr += (*si)->memSize();
      } else {
        section->assignVirtualAddress(newAddr);
      }
    }
    // TBSS section is special in that it doesn't contribute to memory of any
    // segment. If we see a tbss section, don't add memory size to addr The
    // fileOffset is automatically taken care of since TBSS section does not
    // end up using file size
    if ((*si)->order() != TargetLayout<ELFT>::ORDER_TBSS) {
      curSliceSize = (*si)->memSize();
      tbssMemsize = 0;
    } else {
      tbssMemsize = (*si)->memSize();
    }
    ++currSection;
    ++si;
  }

  uint64_t scriptAddr = 0;
  bool forceScriptAddr = false;
  for (auto e = _sections.end(); si != e; ++si) {
    uint64_t curAddr = curSliceAddress + curSliceSize;
    if (!isDataPageAlignedForNMagic && needAlign(*si)) {
      // If the linker outputmagic is set to OutputMagic::NMAGIC, align the
      // Data
      // to a page boundary
      curAddr = llvm::RoundUpToAlignment(curAddr, this->_ctx.getPageSize());
      isDataPageAlignedForNMagic = true;
    }
    uint64_t newAddr = llvm::RoundUpToAlignment(
        forceScriptAddr ? scriptAddr : curAddr, (*si)->alignment());
    forceScriptAddr = false;

    // Handle linker script expressions, which may force an address change if
    // the expression assigns to "."
    if (auto expr = dyn_cast<ExpressionChunk<ELFT>>(*si)) {
      uint64_t oldAddr = newAddr;
      expr->evalExpr(newAddr);
      if (oldAddr != newAddr) {
        forceScriptAddr = true;
        scriptAddr = newAddr;
      }
      (*si)->setVirtualAddr(newAddr);
      continue;
    }
    Section<ELFT> *sec = dyn_cast<Section<ELFT>>(*si);
    StringRef curOutputSectionName =
        sec ? sec->outputSectionName() : (*si)->name();
    bool autoCreateSlice = true;
    if (curOutputSectionName == prevOutputSectionName)
      autoCreateSlice = false;
    // If the newAddress computed is more than a page away, let's create
    // a separate segment, so that memory is not used up while running.
    // Dont create a slice, if the new section falls in the same output
    // section as the previous section.
    if (autoCreateSlice && ((newAddr - curAddr) > this->_ctx.getPageSize()) &&
        (_outputMagic != ELFLinkingContext::OutputMagic::NMAGIC &&
         _outputMagic != ELFLinkingContext::OutputMagic::OMAGIC)) {
      auto sliceIter =
          std::find_if(_segmentSlices.begin(), _segmentSlices.end(),
                       [startSection](SegmentSlice<ELFT> *s) -> bool {
                         return s->startSection() == startSection;
                       });
      if (sliceIter == _segmentSlices.end()) {
        slice = new (_segmentAllocate.Allocate<SegmentSlice<ELFT>>())
            SegmentSlice<ELFT>();
        _segmentSlices.push_back(slice);
      } else {
        slice = *sliceIter;
      }
      slice->setStart(startSection);
      slice->setSections(make_range(startSectionIter, si));
      slice->setMemSize(curSliceSize);
      slice->setAlign(sliceAlign);
      slice->setVirtualAddr(curSliceAddress);
      // Start new slice
      curSliceAddress = newAddr;
      if ((*si)->order() == TargetLayout<ELFT>::ORDER_TBSS)
        curSliceAddress += tbssMemsize;
      (*si)->setVirtualAddr(curSliceAddress);
      startSectionIter = si;
      startSection = currSection;
      if (auto section = dyn_cast<Section<ELFT>>(*si))
        section->assignVirtualAddress(newAddr);
      curSliceSize = newAddr - curSliceAddress + (*si)->memSize();
      sliceAlign = (*si)->alignment();
    } else {
      if (sliceAlign < (*si)->alignment())
        sliceAlign = (*si)->alignment();
      if ((*si)->order() == TargetLayout<ELFT>::ORDER_TBSS)
        newAddr += tbssMemsize;
      (*si)->setVirtualAddr(newAddr);
      // Handle TLS.
      if (auto section = dyn_cast<Section<ELFT>>(*si)) {
        if (section->getSegmentType() == llvm::ELF::PT_TLS) {
          tlsStartAddr =
              llvm::RoundUpToAlignment(tlsStartAddr, (*si)->alignment());
          section->assignVirtualAddress(tlsStartAddr);
          tlsStartAddr += (*si)->memSize();
        } else {
          section->assignVirtualAddress(newAddr);
        }
      }
      // TBSS section is special in that it doesn't contribute to memory of
      // any segment. If we see a tbss section, don't add memory size to addr
      // The fileOffset is automatically taken care of since TBSS section does
      // not end up using file size.
      if ((*si)->order() != TargetLayout<ELFT>::ORDER_TBSS) {
        curSliceSize = newAddr - curSliceAddress + (*si)->memSize();
        tbssMemsize = 0;
      } else {
        // Although TBSS section does not contribute to memory of any segment,
        // we still need to keep track its total size to correct write it
        // down.  Since it is done based on curSliceAddress, we need to add
        // add it to virtual address.
        tbssMemsize = (*si)->memSize();
      }
    }
    prevOutputSectionName = curOutputSectionName;
    ++currSection;
  }

  auto sliceIter = std::find_if(_segmentSlices.begin(), _segmentSlices.end(),
                                [startSection](SegmentSlice<ELFT> *s) -> bool {
                                  return s->startSection() == startSection;
                                });
  if (sliceIter == _segmentSlices.end()) {
    slice = new (_segmentAllocate.Allocate<SegmentSlice<ELFT>>())
        SegmentSlice<ELFT>();
    _segmentSlices.push_back(slice);
  } else {
    slice = *sliceIter;
  }

  slice->setStart(startSection);
  slice->setVirtualAddr(curSliceAddress);
  slice->setMemSize(curSliceSize);
  slice->setSections(make_range(startSectionIter, _sections.end()));
  slice->setAlign(sliceAlign);

  // Set the segment memory size and the virtual address.
  this->setMemSize(curSliceAddress - startAddr + curSliceSize);
  this->setVirtualAddr(startAddr);
  std::stable_sort(_segmentSlices.begin(), _segmentSlices.end(),
                   SegmentSlice<ELFT>::compare_slices);
}

// Write the Segment
template <class ELFT>
void Segment<ELFT>::write(ELFWriter *writer, TargetLayout<ELFT> &layout,
                          llvm::FileOutputBuffer &buffer) {
  for (auto slice : slices())
    for (auto section : slice->sections())
      section->write(writer, layout, buffer);
}

template <class ELFT> int64_t Segment<ELFT>::flags() const {
  if (_segmentFlags)
    return (int64_t)_flags;

  int64_t fl = 0;
  if (_flags & llvm::ELF::SHF_ALLOC)
    fl |= llvm::ELF::PF_R;
  if (_flags & llvm::ELF::SHF_WRITE)
    fl |= llvm::ELF::PF_W;
  if (_flags & llvm::ELF::SHF_EXECINSTR)
    fl |= llvm::ELF::PF_X;
  return fl;
}

template <class ELFT> void Segment<ELFT>::setSegmentFlags(uint64_t flags) {
  assert(!_segmentFlags && "Segment flags have already been set");
  _segmentFlags = true;
  _flags = flags;
  _atomflags = toAtomPermsSegment(flags);
}

template <class ELFT> void Segment<ELFT>::finalize() {
  // We want to finalize the segment values for now only for non loadable
  // segments, since those values are not set in the Layout
  if (_segmentType == llvm::ELF::PT_LOAD)
    return;
  // The size is the difference of the
  // last section to the first section, especially for TLS because
  // the TLS segment contains both .tdata/.tbss
  this->setFileOffset(_sections.front()->fileOffset());
  this->setVirtualAddr(_sections.front()->virtualAddr());
  size_t startFileOffset = _sections.front()->fileOffset();
  size_t startAddr = _sections.front()->virtualAddr();
  for (auto ai : _sections) {
    this->_fsize = ai->fileOffset() + ai->fileSize() - startFileOffset;
    this->_msize = ai->virtualAddr() + ai->memSize() - startAddr;
  }
}

template <class ELFT> int Segment<ELFT>::getContentType() const {
  int64_t fl = flags();
  switch (_segmentType) {
  case llvm::ELF::PT_LOAD: {
    if (fl && llvm::ELF::PF_X)
      return Chunk<ELFT>::ContentType::Code;
    if (fl && llvm::ELF::PF_W)
      return Chunk<ELFT>::ContentType::Data;
  }
  case llvm::ELF::PT_TLS:
    return Chunk<ELFT>::ContentType::TLS;
  case llvm::ELF::PT_NOTE:
    return Chunk<ELFT>::ContentType::Note;
  default:
    return Chunk<ELFT>::ContentType::Unknown;
  }
}

template <class ELFT> int64_t Segment<ELFT>::atomflags() const {
  switch (_atomflags) {
  case DefinedAtom::permUnknown:
    return permUnknown;
  case DefinedAtom::permRWX:
    return permRWX;
  case DefinedAtom::permR_X:
    return permRX;
  case DefinedAtom::permR__:
    return permR;
  case DefinedAtom::permRW_L:
    return permRWL;
  case DefinedAtom::permRW_:
    return permRW;
  case DefinedAtom::perm___:
  default:
    return permNonAccess;
  }
}

/// \brief Check if the chunk needs to be aligned
template <class ELFT> bool Segment<ELFT>::needAlign(Chunk<ELFT> *chunk) const {
  if (chunk->getContentType() == Chunk<ELFT>::ContentType::Data &&
      _outputMagic == ELFLinkingContext::OutputMagic::NMAGIC)
    return true;
  return false;
}

template <class ELFT> void ProgramHeaderSegment<ELFT>::finalize() {
  // If the segment is of type Program Header, then the values fileOffset
  // and the fileSize need to be picked up from the last section, the first
  // section points to the ELF header and the second chunk points to the
  // actual program headers
  this->setFileOffset(this->_sections.back()->fileOffset());
  this->setVirtualAddr(this->_sections.back()->virtualAddr());
  this->_fsize = this->_sections.back()->fileSize();
  this->_msize = this->_sections.back()->memSize();
}

#define INSTANTIATE(klass)        \
  template class klass<ELF32LE>;  \
  template class klass<ELF32BE>;  \
  template class klass<ELF64LE>;  \
  template class klass<ELF64BE>

INSTANTIATE(ExpressionChunk);
INSTANTIATE(ProgramHeaderSegment);
INSTANTIATE(Segment);
INSTANTIATE(SegmentSlice);

} // end namespace elf
} // end namespace lld
