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 using 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 }
66
initStdSections(ObjectBuilder & pBuilder,unsigned int pBitClass)67 void ELFFileFormat::initStdSections(ObjectBuilder& pBuilder, unsigned int pBitClass)
68 {
69 f_pTextSection = 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 = pBuilder.CreateSection("",
75 LDFileFormat::Null,
76 llvm::ELF::SHT_NULL,
77 0x0);
78 f_pReadOnlySection = pBuilder.CreateSection(".rodata",
79 LDFileFormat::TEXT,
80 llvm::ELF::SHT_PROGBITS,
81 llvm::ELF::SHF_ALLOC,
82 0x1);
83
84 f_pBSSSection = pBuilder.CreateSection(".bss",
85 LDFileFormat::BSS,
86 llvm::ELF::SHT_NOBITS,
87 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
88 0x1);
89 f_pComment = pBuilder.CreateSection(".comment",
90 LDFileFormat::MetaData,
91 llvm::ELF::SHT_PROGBITS,
92 0x0,
93 0x1);
94 f_pDataSection = pBuilder.CreateSection(".data",
95 LDFileFormat::DATA,
96 llvm::ELF::SHT_PROGBITS,
97 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
98 0x1);
99 f_pData1 = pBuilder.CreateSection(".data1",
100 LDFileFormat::DATA,
101 llvm::ELF::SHT_PROGBITS,
102 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
103 0x1);
104 f_pDebug = pBuilder.CreateSection(".debug",
105 LDFileFormat::Debug,
106 llvm::ELF::SHT_PROGBITS,
107 0x0,
108 0x1);
109 f_pInit = pBuilder.CreateSection(".init",
110 LDFileFormat::TEXT,
111 llvm::ELF::SHT_PROGBITS,
112 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR,
113 0x1);
114 f_pInitArray = pBuilder.CreateSection(".init_array",
115 LDFileFormat::DATA,
116 llvm::ELF::SHT_INIT_ARRAY,
117 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
118 0x1);
119 f_pFini = pBuilder.CreateSection(".fini",
120 LDFileFormat::TEXT,
121 llvm::ELF::SHT_PROGBITS,
122 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR,
123 0x1);
124 f_pFiniArray = pBuilder.CreateSection(".fini_array",
125 LDFileFormat::DATA,
126 llvm::ELF::SHT_FINI_ARRAY,
127 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
128 0x1);
129 f_pLine = pBuilder.CreateSection(".line",
130 LDFileFormat::Debug,
131 llvm::ELF::SHT_PROGBITS,
132 0x0,
133 0x1);
134 f_pPreInitArray = pBuilder.CreateSection(".preinit_array",
135 LDFileFormat::DATA,
136 llvm::ELF::SHT_PREINIT_ARRAY,
137 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
138 0x1);
139 // the definition of SHF_XXX attributes of rodata in Linux Standard Base
140 // conflicts with System V standard. We follow System V standard.
141 f_pROData1 = pBuilder.CreateSection(".rodata1",
142 LDFileFormat::TEXT,
143 llvm::ELF::SHT_PROGBITS,
144 llvm::ELF::SHF_ALLOC,
145 0x1);
146 f_pShStrTab = pBuilder.CreateSection(".shstrtab",
147 LDFileFormat::NamePool,
148 llvm::ELF::SHT_STRTAB,
149 0x0,
150 0x1);
151 // In ELF Spec Book I, p1-16. If symbol table and string table are in
152 // loadable segments, set the attribute to SHF_ALLOC bit. But in the
153 // real world, this bit always turn off.
154 f_pSymTab = pBuilder.CreateSection(".symtab",
155 LDFileFormat::NamePool,
156 llvm::ELF::SHT_SYMTAB,
157 0x0,
158 pBitClass / 8);
159
160 f_pStrTab = pBuilder.CreateSection(".strtab",
161 LDFileFormat::NamePool,
162 llvm::ELF::SHT_STRTAB,
163 0x0,
164 0x1);
165 f_pTBSS = pBuilder.CreateSection(".tbss",
166 LDFileFormat::BSS,
167 llvm::ELF::SHT_NOBITS,
168 llvm::ELF::SHF_ALLOC |
169 llvm::ELF::SHF_WRITE |
170 llvm::ELF::SHF_TLS,
171 0x1);
172 f_pTData = pBuilder.CreateSection(".tdata",
173 LDFileFormat::DATA,
174 llvm::ELF::SHT_PROGBITS,
175 llvm::ELF::SHF_ALLOC |
176 llvm::ELF::SHF_WRITE |
177 llvm::ELF::SHF_TLS,
178 0x1);
179
180 /// @ref 10.3.1.2, ISO/IEC 23360, Part 1:2010(E), p. 24.
181 f_pCtors = pBuilder.CreateSection(".ctors",
182 LDFileFormat::DATA,
183 llvm::ELF::SHT_PROGBITS,
184 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
185 0x1);
186 f_pDataRelRo = pBuilder.CreateSection(".data.rel.ro",
187 LDFileFormat::DATA,
188 llvm::ELF::SHT_PROGBITS,
189 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
190 0x1);
191 f_pDtors = pBuilder.CreateSection(".dtors",
192 LDFileFormat::DATA,
193 llvm::ELF::SHT_PROGBITS,
194 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
195 0x1);
196 f_pEhFrame = pBuilder.CreateSection(".eh_frame",
197 LDFileFormat::EhFrame,
198 llvm::ELF::SHT_PROGBITS,
199 llvm::ELF::SHF_ALLOC,
200 0x4);
201 f_pGCCExceptTable = pBuilder.CreateSection(".gcc_except_table",
202 LDFileFormat::GCCExceptTable,
203 llvm::ELF::SHT_PROGBITS,
204 llvm::ELF::SHF_ALLOC,
205 0x4);
206 f_pGNUVersion = pBuilder.CreateSection(".gnu.version",
207 LDFileFormat::Version,
208 llvm::ELF::SHT_GNU_versym,
209 llvm::ELF::SHF_ALLOC,
210 0x1);
211 f_pGNUVersionD = pBuilder.CreateSection(".gnu.version_d",
212 LDFileFormat::Version,
213 llvm::ELF::SHT_GNU_verdef,
214 llvm::ELF::SHF_ALLOC,
215 0x1);
216 f_pGNUVersionR = pBuilder.CreateSection(".gnu.version_r",
217 LDFileFormat::Version,
218 llvm::ELF::SHT_GNU_verneed,
219 llvm::ELF::SHF_ALLOC,
220 0x1);
221 f_pJCR = pBuilder.CreateSection(".jcr",
222 LDFileFormat::DATA,
223 llvm::ELF::SHT_PROGBITS,
224 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
225 0x1);
226 f_pStab = pBuilder.CreateSection(".stab",
227 LDFileFormat::Debug,
228 llvm::ELF::SHT_PROGBITS,
229 0x0,
230 0x1);
231 f_pStabStr = pBuilder.CreateSection(".stabstr",
232 LDFileFormat::Debug,
233 llvm::ELF::SHT_STRTAB,
234 0x0,
235 0x1);
236 f_pStackNote = pBuilder.CreateSection(".note.GNU-stack",
237 LDFileFormat::StackNote,
238 llvm::ELF::SHT_PROGBITS,
239 0x0,
240 0x1);
241
242 /// @ref GCC convention, see http://www.airs.com/blog/archives/189
243 f_pDataRelRoLocal = pBuilder.CreateSection(".data.rel.ro.local",
244 LDFileFormat::DATA,
245 llvm::ELF::SHT_PROGBITS,
246 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
247 0x1);
248 /// Initialize format dependent sections. (sections for executable and shared
249 /// objects)
250 initObjectFormat(pBuilder, pBitClass);
251 }
252
253