//===- LDSection.h --------------------------------------------------------===//
//
//                     The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef MCLD_LD_LDSECTION_H
#define MCLD_LD_LDSECTION_H
#ifdef ENABLE_UNITTEST
#include <gtest.h>
#endif

#include <llvm/ADT/StringRef.h>
#include <llvm/Support/DataTypes.h>
#include <mcld/LD/LDFileFormat.h>
#include <string>

namespace mcld {

class SectionData;

/** \class LDSection
 *  \brief LDSection represents a section header entry. It is a unified
 *  abstraction of a section header entry for various file formats.
 */
class LDSection
{
public:
  LDSection(const std::string& pName,
            LDFileFormat::Kind pKind,
            uint32_t pType,
            uint32_t pFlag,
            uint64_t pSize = 0,
            uint64_t pOffset = 0,
            uint64_t pAddr = 0);

  /// name - the name of this section.
  const std::string& name() const
  { return m_Name; }

  /// kind - the kind of this section, such as Text, BSS, GOT, and so on.
  /// from LDFileFormat::Kind
  LDFileFormat::Kind kind() const
  { return m_Kind; }

  /// type - The categorizes the section's contents and semantics. It's
  /// different from llvm::SectionKind. Type is format-dependent, but
  /// llvm::SectionKind is format independent and is used for bit-code.
  ///   In ELF, it is sh_type
  ///   In MachO, it's type field of struct section::flags
  uint32_t type() const
  { return m_Type; }

  /// flag - An integer describes miscellaneous attributes.
  ///   In ELF, it is sh_flags.
  ///   In MachO, it's attribute field of struct section::flags
  uint32_t flag() const
  { return m_Flag; }

  /// size - An integer specifying the size in bytes of the virtual memory
  /// occupied by this section.
  ///   In ELF, if the type() is SHT_NOBITS, this function return zero.
  ///   Before layouting, output's LDSection::size() should return zero.
  uint64_t size() const
  { return m_Size; }

  /// offset - An integer specifying the offset of this section in the file.
  ///   Before layouting, output's LDSection::offset() should return zero.
  uint64_t offset() const
  { return m_Offset; }

  /// addr - An integer specifying the virtual address of this section in the
  /// virtual image.
  ///   Before layouting, output's LDSection::offset() should return zero.
  ///   ELF uses sh_addralign to set alignment constraints. In LLVM, alignment
  ///   constraint is set in SectionData::setAlignment. addr() contains the
  ///   original ELF::sh_addr. Modulo sh_addr by sh_addralign is not necessary.
  ///   MachO uses the same scenario.
  ///
  ///   Because addr() in output is changing during linking, MCLinker does not
  ///   store the address of the output here. The address is in Layout
  uint64_t addr() const
  { return m_Addr; }

  /// align - An integer specifying the align of this section in the file.
  ///   Before layouting, output's LDSection::align() should return zero.
  uint32_t align() const
  { return m_Align; }

  size_t index() const
  { return m_Index; }

  /// getLink - return the Link. When a section A needs the other section B
  /// during linking or loading, we say B is A's Link section.
  /// In ELF, InfoLink section control the ElfNN_Shdr::sh_link and sh_info.
  ///
  /// @return if the section needs no other sections, return NULL
  LDSection* getLink()
  { return m_pLink; }

  const LDSection* getLink() const
  { return m_pLink; }

  size_t getInfo() const
  { return m_Info; }

  void setKind(LDFileFormat::Kind pKind)
  { m_Kind = pKind; }

  void setSize(uint64_t size)
  { m_Size = size; }

  void setOffset(uint64_t Offset)
  { m_Offset = Offset; }

  void setAddr(uint64_t addr)
  { m_Addr = addr; }

  void setAlign(uint32_t align)
  { m_Align = align; }

  void setFlag(uint32_t flag)
  { m_Flag = flag; }

  void setType(uint32_t type)
  { m_Type = type; }

  SectionData* getSectionData()
  { return m_pSectionData; }

  const SectionData* getSectionData() const
  { return m_pSectionData; }

  void setSectionData(SectionData* pSD)
  { m_pSectionData = pSD; }

  bool hasSectionData() const
  { return (NULL != m_pSectionData); }

  /// setLink - set the sections should link with.
  /// if pLink is NULL, no Link section is set.
  void setLink(LDSection* pLink)
  { m_pLink = pLink; }

  void setInfo(size_t pInfo)
  { m_Info = pInfo; }

  void setIndex(size_t pIndex)
  { m_Index = pIndex; }

private:
  std::string m_Name;
  LDFileFormat::Kind m_Kind;
  uint32_t m_Type;
  uint32_t m_Flag;

  uint64_t m_Size;
  uint64_t m_Offset;
  uint64_t m_Addr;
  uint32_t m_Align;

  size_t m_Info;
  LDSection* m_pLink;

  SectionData* m_pSectionData;

  // the index of the file
  size_t m_Index;

}; // end of LDSection

} // end namespace mcld

#endif

