You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
206 lines
6.3 KiB
206 lines
6.3 KiB
//===- 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_
|