//===- 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/Support/DataTypes.h>
#include <mcld/Support/Allocators.h>
#include <mcld/Config/Config.h>
#include <mcld/LD/LDFileFormat.h>
#include <string>

namespace mcld {

class SectionData;
class RelocData;
class EhFrame;

/** \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
{
private:
  friend class Chunk<LDSection, MCLD_SECTIONS_PER_INPUT>;

  LDSection();

  LDSection(const std::string& pName,
            LDFileFormat::Kind pKind,
            uint32_t pType,
            uint32_t pFlag,
            uint64_t pSize = 0,
            uint64_t pAddr = 0);

public:
  ~LDSection();

  static LDSection* Create(const std::string& pName,
                           LDFileFormat::Kind pKind,
                           uint32_t pType,
                           uint32_t pFlag,
                           uint64_t pSize = 0,
                           uint64_t pAddr = 0);

  static void Destroy(LDSection*& pSection);

  static void Clear();

  bool hasOffset() const;

  /// 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  ----- //
  const SectionData* getSectionData() const { return m_Data.sect_data; }
  SectionData*       getSectionData()       { return m_Data.sect_data; }

  void setSectionData(SectionData* pSD) { m_Data.sect_data = pSD; }

  bool hasSectionData() const;

  // ------  RelocData  ------ //
  const RelocData* getRelocData() const { return m_Data.reloc_data; }
  RelocData*       getRelocData()       { return m_Data.reloc_data; }

  void setRelocData(RelocData* pRD) { m_Data.reloc_data = pRD; }

  bool hasRelocData() const;

  // ------  EhFrame  ------ //
  const EhFrame* getEhFrame() const { return m_Data.eh_frame; }
  EhFrame*       getEhFrame()       { return m_Data.eh_frame; }

  void setEhFrame(EhFrame* pEhFrame) { m_Data.eh_frame = pEhFrame; }

  bool hasEhFrame() const;

  /// 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:
  union SectOrRelocData
  {
    SectionData* sect_data;
    RelocData*   reloc_data;
    EhFrame*     eh_frame;
  };

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;

  /// m_Data - the SectionData or RelocData of this section
  SectOrRelocData m_Data;

  /// m_Index - the index of the file
  size_t m_Index;

}; // end of LDSection

} // end namespace mcld

#endif

