1//===- LDSection.h --------------------------------------------------------===//
2//
3//                     The MCLinker Project
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9#ifndef MCLD_LD_LDSECTION_H_
10#define MCLD_LD_LDSECTION_H_
11
12#include "mcld/Config/Config.h"
13#include "mcld/LD/LDFileFormat.h"
14#include "mcld/Support/Allocators.h"
15
16#include <llvm/Support/DataTypes.h>
17
18#include <string>
19
20namespace mcld {
21
22class DebugString;
23class EhFrame;
24class RelocData;
25class SectionData;
26
27/** \class LDSection
28 *  \brief LDSection represents a section header entry. It is a unified
29 *  abstraction of a section header entry for various file formats.
30 */
31class LDSection {
32 private:
33  friend class Chunk<LDSection, MCLD_SECTIONS_PER_INPUT>;
34
35  LDSection();
36
37  LDSection(const std::string& pName,
38            LDFileFormat::Kind pKind,
39            uint32_t pType,
40            uint32_t pFlag,
41            uint64_t pSize = 0,
42            uint64_t pAddr = 0);
43
44 public:
45  ~LDSection();
46
47  static LDSection* Create(const std::string& pName,
48                           LDFileFormat::Kind pKind,
49                           uint32_t pType,
50                           uint32_t pFlag,
51                           uint64_t pSize = 0,
52                           uint64_t pAddr = 0);
53
54  static void Destroy(LDSection*& pSection);
55
56  static void Clear();
57
58  bool hasOffset() const;
59
60  /// name - the name of this section.
61  const std::string& name() const { return m_Name; }
62
63  /// kind - the kind of this section, such as Text, BSS, GOT, and so on.
64  /// from LDFileFormat::Kind
65  LDFileFormat::Kind kind() const { return m_Kind; }
66
67  /// type - The categorizes the section's contents and semantics. It's
68  /// different from llvm::SectionKind. Type is format-dependent, but
69  /// llvm::SectionKind is format independent and is used for bit-code.
70  ///   In ELF, it is sh_type
71  ///   In MachO, it's type field of struct section::flags
72  uint32_t type() const { return m_Type; }
73
74  /// flag - An integer describes miscellaneous attributes.
75  ///   In ELF, it is sh_flags.
76  ///   In MachO, it's attribute field of struct section::flags
77  uint32_t flag() const { return m_Flag; }
78
79  /// size - An integer specifying the size in bytes of the virtual memory
80  /// occupied by this section.
81  ///   In ELF, if the type() is SHT_NOBITS, this function return zero.
82  ///   Before layouting, output's LDSection::size() should return zero.
83  uint64_t size() const { return m_Size; }
84
85  /// offset - An integer specifying the offset of this section in the file.
86  ///   Before layouting, output's LDSection::offset() should return zero.
87  uint64_t offset() const { return m_Offset; }
88
89  /// addr - An integer specifying the virtual address of this section in the
90  /// virtual image.
91  ///   Before layouting, output's LDSection::offset() should return zero.
92  ///   ELF uses sh_addralign to set alignment constraints. In LLVM, alignment
93  ///   constraint is set in SectionData::setAlignment. addr() contains the
94  ///   original ELF::sh_addr. Modulo sh_addr by sh_addralign is not necessary.
95  ///   MachO uses the same scenario.
96  ///
97  ///   Because addr() in output is changing during linking, MCLinker does not
98  ///   store the address of the output here. The address is in Layout
99  uint64_t addr() const { return m_Addr; }
100
101  /// align - An integer specifying the align of this section in the file.
102  ///   Before layouting, output's LDSection::align() should return zero.
103  uint32_t align() const { return m_Align; }
104
105  size_t index() const { return m_Index; }
106
107  /// getLink - return the Link. When a section A needs the other section B
108  /// during linking or loading, we say B is A's Link section.
109  /// In ELF, InfoLink section control the ElfNN_Shdr::sh_link and sh_info.
110  ///
111  /// @return if the section needs no other sections, return NULL
112  LDSection* getLink() { return m_pLink; }
113
114  const LDSection* getLink() const { return m_pLink; }
115
116  size_t getInfo() const { return m_Info; }
117
118  void setKind(LDFileFormat::Kind pKind) { m_Kind = pKind; }
119
120  void setSize(uint64_t size) { m_Size = size; }
121
122  void setOffset(uint64_t Offset) { m_Offset = Offset; }
123
124  void setAddr(uint64_t addr) { m_Addr = addr; }
125
126  void setAlign(uint32_t align) { m_Align = align; }
127
128  void setFlag(uint32_t flag) { m_Flag = flag; }
129
130  void setType(uint32_t type) { m_Type = type; }
131
132  // -----  SectionData  ----- //
133  const SectionData* getSectionData() const { return m_Data.sect_data; }
134  SectionData* getSectionData() { return m_Data.sect_data; }
135
136  void setSectionData(SectionData* pSD) { m_Data.sect_data = pSD; }
137
138  bool hasSectionData() const;
139
140  // ------  RelocData  ------ //
141  const RelocData* getRelocData() const { return m_Data.reloc_data; }
142  RelocData* getRelocData() { return m_Data.reloc_data; }
143
144  void setRelocData(RelocData* pRD) { m_Data.reloc_data = pRD; }
145
146  bool hasRelocData() const;
147
148  // ------  EhFrame  ------ //
149  const EhFrame* getEhFrame() const { return m_Data.eh_frame; }
150  EhFrame* getEhFrame() { return m_Data.eh_frame; }
151
152  void setEhFrame(EhFrame* pEhFrame) { m_Data.eh_frame = pEhFrame; }
153
154  bool hasEhFrame() const;
155
156  // ------  DebugString  ------ //
157  const DebugString* getDebugString() const { return m_Data.debug_string; }
158  DebugString*       getDebugString()       { return m_Data.debug_string; }
159
160  void setDebugString(DebugString* pDebugString)
161  { m_Data.debug_string = pDebugString; }
162
163  bool hasDebugString() const;
164
165  /// setLink - set the sections should link with.
166  /// if pLink is NULL, no Link section is set.
167  void setLink(LDSection* pLink) { m_pLink = pLink; }
168
169  void setInfo(size_t pInfo) { m_Info = pInfo; }
170
171  void setIndex(size_t pIndex) { m_Index = pIndex; }
172
173 private:
174  union Data {
175    SectionData* sect_data;
176    RelocData*   reloc_data;
177    EhFrame*     eh_frame;
178    DebugString* debug_string;
179  };
180
181 private:
182  std::string m_Name;
183
184  LDFileFormat::Kind m_Kind;
185  uint32_t m_Type;
186  uint32_t m_Flag;
187
188  uint64_t m_Size;
189  uint64_t m_Offset;
190  uint64_t m_Addr;
191  uint32_t m_Align;
192
193  size_t m_Info;
194  LDSection* m_pLink;
195
196  /// m_Data - the SectionData or RelocData of this section
197  Data m_Data;
198
199  /// m_Index - the index of the file
200  size_t m_Index;
201};  // end of LDSection
202
203}  // namespace mcld
204
205#endif  // MCLD_LD_LDSECTION_H_
206