blob: c77a31b68b962bca3025fa30e5b4bd015f075e36 [file] [log] [blame]
//===- 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_
#include <mcld/Config/Config.h>
#include <mcld/LD/LDFileFormat.h>
#include <mcld/Support/Allocators.h>
#include <llvm/Support/DataTypes.h>
#include <string>
namespace mcld {
class DebugString;
class EhFrame;
class RelocData;
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 {
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;
// ------ DebugString ------ //
const DebugString* getDebugString() const { return m_Data.debug_string; }
DebugString* getDebugString() { return m_Data.debug_string; }
void setDebugString(DebugString* pDebugString)
{ m_Data.debug_string = pDebugString; }
bool hasDebugString() 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 Data {
SectionData* sect_data;
RelocData* reloc_data;
EhFrame* eh_frame;
DebugString* debug_string;
};
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
Data m_Data;
/// m_Index - the index of the file
size_t m_Index;
}; // end of LDSection
} // namespace mcld
#endif // MCLD_LD_LDSECTION_H_