1 //===- ELFFileFormat.cpp --------------------------------------------------===//
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 #include "mcld/LD/ELFFileFormat.h"
10 #include "mcld/Object/ObjectBuilder.h"
11 #include "mcld/Target/GNULDBackend.h"
12
13 #include <llvm/Support/ELF.h>
14
15 namespace mcld {
16
ELFFileFormat()17 ELFFileFormat::ELFFileFormat()
18 : f_pNULLSection(NULL),
19 f_pGOT(NULL),
20 f_pPLT(NULL),
21 f_pRelDyn(NULL),
22 f_pRelPlt(NULL),
23 f_pRelaDyn(NULL),
24 f_pRelaPlt(NULL),
25 f_pComment(NULL),
26 f_pData1(NULL),
27 f_pDebug(NULL),
28 f_pDynamic(NULL),
29 f_pDynStrTab(NULL),
30 f_pDynSymTab(NULL),
31 f_pFini(NULL),
32 f_pFiniArray(NULL),
33 f_pHashTab(NULL),
34 f_pInit(NULL),
35 f_pInitArray(NULL),
36 f_pInterp(NULL),
37 f_pLine(NULL),
38 f_pNote(NULL),
39 f_pPreInitArray(NULL),
40 f_pROData1(NULL),
41 f_pShStrTab(NULL),
42 f_pStrTab(NULL),
43 f_pSymTab(NULL),
44 f_pTBSS(NULL),
45 f_pTData(NULL),
46 f_pCtors(NULL),
47 f_pDataRelRo(NULL),
48 f_pDtors(NULL),
49 f_pEhFrame(NULL),
50 f_pEhFrameHdr(NULL),
51 f_pGCCExceptTable(NULL),
52 f_pGNUVersion(NULL),
53 f_pGNUVersionD(NULL),
54 f_pGNUVersionR(NULL),
55 f_pGOTPLT(NULL),
56 f_pJCR(NULL),
57 f_pNoteABITag(NULL),
58 f_pStab(NULL),
59 f_pStabStr(NULL),
60 f_pStack(NULL),
61 f_pStackNote(NULL),
62 f_pDataRelRoLocal(NULL),
63 f_pGNUHashTab(NULL) {
64 }
65
initStdSections(ObjectBuilder & pBuilder,unsigned int pBitClass)66 void ELFFileFormat::initStdSections(ObjectBuilder& pBuilder,
67 unsigned int pBitClass) {
68 f_pTextSection =
69 pBuilder.CreateSection(".text",
70 LDFileFormat::TEXT,
71 llvm::ELF::SHT_PROGBITS,
72 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR,
73 0x1);
74 f_pNULLSection =
75 pBuilder.CreateSection("", LDFileFormat::Null, llvm::ELF::SHT_NULL, 0x0);
76 f_pReadOnlySection = pBuilder.CreateSection(".rodata",
77 LDFileFormat::TEXT,
78 llvm::ELF::SHT_PROGBITS,
79 llvm::ELF::SHF_ALLOC,
80 0x1);
81
82 f_pBSSSection =
83 pBuilder.CreateSection(".bss",
84 LDFileFormat::BSS,
85 llvm::ELF::SHT_NOBITS,
86 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
87 0x1);
88 f_pComment = pBuilder.CreateSection(
89 ".comment", LDFileFormat::MetaData, llvm::ELF::SHT_PROGBITS, 0x0, 0x1);
90 f_pDataSection =
91 pBuilder.CreateSection(".data",
92 LDFileFormat::DATA,
93 llvm::ELF::SHT_PROGBITS,
94 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
95 0x1);
96 f_pData1 = pBuilder.CreateSection(".data1",
97 LDFileFormat::DATA,
98 llvm::ELF::SHT_PROGBITS,
99 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
100 0x1);
101 f_pDebug = pBuilder.CreateSection(
102 ".debug", LDFileFormat::Debug, llvm::ELF::SHT_PROGBITS, 0x0, 0x1);
103 f_pInit =
104 pBuilder.CreateSection(".init",
105 LDFileFormat::TEXT,
106 llvm::ELF::SHT_PROGBITS,
107 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR,
108 0x1);
109 f_pInitArray =
110 pBuilder.CreateSection(".init_array",
111 LDFileFormat::DATA,
112 llvm::ELF::SHT_INIT_ARRAY,
113 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
114 0x1);
115 f_pFini =
116 pBuilder.CreateSection(".fini",
117 LDFileFormat::TEXT,
118 llvm::ELF::SHT_PROGBITS,
119 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR,
120 0x1);
121 f_pFiniArray =
122 pBuilder.CreateSection(".fini_array",
123 LDFileFormat::DATA,
124 llvm::ELF::SHT_FINI_ARRAY,
125 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
126 0x1);
127 f_pLine = pBuilder.CreateSection(
128 ".line", LDFileFormat::Debug, llvm::ELF::SHT_PROGBITS, 0x0, 0x1);
129 f_pPreInitArray =
130 pBuilder.CreateSection(".preinit_array",
131 LDFileFormat::DATA,
132 llvm::ELF::SHT_PREINIT_ARRAY,
133 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
134 0x1);
135 // the definition of SHF_XXX attributes of rodata in Linux Standard Base
136 // conflicts with System V standard. We follow System V standard.
137 f_pROData1 = pBuilder.CreateSection(".rodata1",
138 LDFileFormat::TEXT,
139 llvm::ELF::SHT_PROGBITS,
140 llvm::ELF::SHF_ALLOC,
141 0x1);
142 f_pShStrTab = pBuilder.CreateSection(
143 ".shstrtab", LDFileFormat::NamePool, llvm::ELF::SHT_STRTAB, 0x0, 0x1);
144 // In ELF Spec Book I, p1-16. If symbol table and string table are in
145 // loadable segments, set the attribute to SHF_ALLOC bit. But in the
146 // real world, this bit always turn off.
147 f_pSymTab = pBuilder.CreateSection(".symtab",
148 LDFileFormat::NamePool,
149 llvm::ELF::SHT_SYMTAB,
150 0x0,
151 pBitClass / 8);
152
153 f_pStrTab = pBuilder.CreateSection(
154 ".strtab", LDFileFormat::NamePool, llvm::ELF::SHT_STRTAB, 0x0, 0x1);
155 f_pTBSS = pBuilder.CreateSection(
156 ".tbss",
157 LDFileFormat::BSS,
158 llvm::ELF::SHT_NOBITS,
159 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE | llvm::ELF::SHF_TLS,
160 0x1);
161 f_pTData = pBuilder.CreateSection(
162 ".tdata",
163 LDFileFormat::DATA,
164 llvm::ELF::SHT_PROGBITS,
165 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE | llvm::ELF::SHF_TLS,
166 0x1);
167
168 /// @ref 10.3.1.2, ISO/IEC 23360, Part 1:2010(E), p. 24.
169 f_pCtors = pBuilder.CreateSection(".ctors",
170 LDFileFormat::DATA,
171 llvm::ELF::SHT_PROGBITS,
172 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
173 0x1);
174 f_pDataRelRo =
175 pBuilder.CreateSection(".data.rel.ro",
176 LDFileFormat::DATA,
177 llvm::ELF::SHT_PROGBITS,
178 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
179 0x1);
180 f_pDtors = pBuilder.CreateSection(".dtors",
181 LDFileFormat::DATA,
182 llvm::ELF::SHT_PROGBITS,
183 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
184 0x1);
185 f_pEhFrame = pBuilder.CreateSection(".eh_frame",
186 LDFileFormat::EhFrame,
187 llvm::ELF::SHT_PROGBITS,
188 llvm::ELF::SHF_ALLOC,
189 0x4);
190 f_pGCCExceptTable = pBuilder.CreateSection(".gcc_except_table",
191 LDFileFormat::GCCExceptTable,
192 llvm::ELF::SHT_PROGBITS,
193 llvm::ELF::SHF_ALLOC,
194 0x4);
195 f_pGNUVersion = pBuilder.CreateSection(".gnu.version",
196 LDFileFormat::Version,
197 llvm::ELF::SHT_GNU_versym,
198 llvm::ELF::SHF_ALLOC,
199 0x1);
200 f_pGNUVersionD = pBuilder.CreateSection(".gnu.version_d",
201 LDFileFormat::Version,
202 llvm::ELF::SHT_GNU_verdef,
203 llvm::ELF::SHF_ALLOC,
204 0x1);
205 f_pGNUVersionR = pBuilder.CreateSection(".gnu.version_r",
206 LDFileFormat::Version,
207 llvm::ELF::SHT_GNU_verneed,
208 llvm::ELF::SHF_ALLOC,
209 0x1);
210 f_pJCR = pBuilder.CreateSection(".jcr",
211 LDFileFormat::DATA,
212 llvm::ELF::SHT_PROGBITS,
213 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
214 0x1);
215 f_pStab = pBuilder.CreateSection(
216 ".stab", LDFileFormat::Debug, llvm::ELF::SHT_PROGBITS, 0x0, 0x1);
217 f_pStabStr = pBuilder.CreateSection(
218 ".stabstr", LDFileFormat::Debug, llvm::ELF::SHT_STRTAB, 0x0, 0x1);
219 f_pStackNote = pBuilder.CreateSection(".note.GNU-stack",
220 LDFileFormat::StackNote,
221 llvm::ELF::SHT_PROGBITS,
222 0x0,
223 0x1);
224
225 /// @ref GCC convention, see http://www.airs.com/blog/archives/189
226 f_pDataRelRoLocal =
227 pBuilder.CreateSection(".data.rel.ro.local",
228 LDFileFormat::DATA,
229 llvm::ELF::SHT_PROGBITS,
230 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
231 0x1);
232 /// Initialize format dependent sections. (sections for executable and shared
233 /// objects)
234 initObjectFormat(pBuilder, pBitClass);
235 }
236
237 } // namespace mcld
238