OLD | NEW |
---|---|
1 //===- subzero/src/IceELFObjectWriter.cpp - ELF object file writer --------===// | 1 //===- subzero/src/IceELFObjectWriter.cpp - ELF object file writer --------===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file defines the writer for ELF relocatable object files. | 10 // This file defines the writer for ELF relocatable object files. |
11 // | 11 // |
12 //===----------------------------------------------------------------------===// | 12 //===----------------------------------------------------------------------===// |
13 | 13 |
14 #include "llvm/Support/MathExtras.h" | |
15 | |
14 #include "assembler.h" | 16 #include "assembler.h" |
15 #include "IceDefs.h" | 17 #include "IceDefs.h" |
16 #include "IceELFObjectWriter.h" | 18 #include "IceELFObjectWriter.h" |
17 #include "IceELFSection.h" | 19 #include "IceELFSection.h" |
18 #include "IceELFStreamer.h" | 20 #include "IceELFStreamer.h" |
19 #include "IceGlobalContext.h" | 21 #include "IceGlobalContext.h" |
20 #include "IceGlobalInits.h" | 22 #include "IceGlobalInits.h" |
21 #include "IceOperand.h" | 23 #include "IceOperand.h" |
22 | 24 |
23 using namespace llvm::ELF; | 25 using namespace llvm::ELF; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
96 T *ELFObjectWriter::createSection(const IceString &Name, Elf64_Word ShType, | 98 T *ELFObjectWriter::createSection(const IceString &Name, Elf64_Word ShType, |
97 Elf64_Xword ShFlags, Elf64_Xword ShAddralign, | 99 Elf64_Xword ShFlags, Elf64_Xword ShAddralign, |
98 Elf64_Xword ShEntsize) { | 100 Elf64_Xword ShEntsize) { |
99 assert(!SectionNumbersAssigned); | 101 assert(!SectionNumbersAssigned); |
100 T *NewSection = | 102 T *NewSection = |
101 new (Ctx.allocate<T>()) T(Name, ShType, ShFlags, ShAddralign, ShEntsize); | 103 new (Ctx.allocate<T>()) T(Name, ShType, ShFlags, ShAddralign, ShEntsize); |
102 ShStrTab->add(Name); | 104 ShStrTab->add(Name); |
103 return NewSection; | 105 return NewSection; |
104 } | 106 } |
105 | 107 |
108 ELFRelocationSection * | |
109 ELFObjectWriter::createRelocationSection(bool IsELF64, | |
110 const ELFSection *RelatedSection) { | |
111 // Choice of RELA vs REL is actually separate from elf64 vs elf32, | |
112 // but in practice we've only had .rela for elf64 (x86-64). | |
113 // In the future, the two properties may need to be decoupled | |
114 // and the ShEntSize can vary more. | |
115 const Elf64_Word ShType = IsELF64 ? SHT_RELA : SHT_REL; | |
116 IceString RelPrefix = IsELF64 ? ".rela" : ".rel"; | |
117 IceString RelSectionName = RelPrefix + RelatedSection->getName(); | |
118 const Elf64_Xword ShAlign = IsELF64 ? 8 : 4; | |
119 const Elf64_Xword ShEntSize = | |
120 IsELF64 ? sizeof(Elf64_Rela) : sizeof(Elf32_Rel); | |
121 static_assert(sizeof(Elf64_Rela) == 24 && sizeof(Elf32_Rel) == 8, | |
122 "Elf_Rel/Rela sizes cannot be derived from sizeof"); | |
123 const Elf64_Xword ShFlags = 0; | |
124 ELFRelocationSection *RelSection = createSection<ELFRelocationSection>( | |
125 RelSectionName, ShType, ShFlags, ShAlign, ShEntSize); | |
126 RelSection->setRelatedSection(RelatedSection); | |
127 return RelSection; | |
128 } | |
129 | |
106 template <typename UserSectionList> | 130 template <typename UserSectionList> |
107 void ELFObjectWriter::assignRelSectionNumInPairs(SizeT &CurSectionNumber, | 131 void ELFObjectWriter::assignRelSectionNumInPairs(SizeT &CurSectionNumber, |
108 UserSectionList &UserSections, | 132 UserSectionList &UserSections, |
109 RelSectionList &RelSections, | 133 RelSectionList &RelSections, |
110 SectionList &AllSections) { | 134 SectionList &AllSections) { |
111 RelSectionList::iterator RelIt = RelSections.begin(); | 135 RelSectionList::iterator RelIt = RelSections.begin(); |
112 RelSectionList::iterator RelE = RelSections.end(); | 136 RelSectionList::iterator RelE = RelSections.end(); |
113 for (ELFSection *UserSection : UserSections) { | 137 for (ELFSection *UserSection : UserSections) { |
114 UserSection->setNumber(CurSectionNumber++); | 138 UserSection->setNumber(CurSectionNumber++); |
115 UserSection->setNameStrIndex(ShStrTab->getIndex(UserSection->getName())); | 139 UserSection->setNameStrIndex(ShStrTab->getIndex(UserSection->getName())); |
(...skipping 27 matching lines...) Expand all Loading... | |
143 assert(!SectionNumbersAssigned); | 167 assert(!SectionNumbersAssigned); |
144 SizeT CurSectionNumber = 0; | 168 SizeT CurSectionNumber = 0; |
145 NullSection->setNumber(CurSectionNumber++); | 169 NullSection->setNumber(CurSectionNumber++); |
146 // The rest of the fields are initialized to 0, and stay that way. | 170 // The rest of the fields are initialized to 0, and stay that way. |
147 AllSections.push_back(NullSection); | 171 AllSections.push_back(NullSection); |
148 | 172 |
149 assignRelSectionNumInPairs<TextSectionList>(CurSectionNumber, TextSections, | 173 assignRelSectionNumInPairs<TextSectionList>(CurSectionNumber, TextSections, |
150 RelTextSections, AllSections); | 174 RelTextSections, AllSections); |
151 assignRelSectionNumInPairs<DataSectionList>(CurSectionNumber, DataSections, | 175 assignRelSectionNumInPairs<DataSectionList>(CurSectionNumber, DataSections, |
152 RelDataSections, AllSections); | 176 RelDataSections, AllSections); |
153 assignRelSectionNumInPairs<DataSectionList>(CurSectionNumber, RoDataSections, | 177 for (ELFSection *BSSSection : BSSSections) { |
154 RelRoDataSections, AllSections); | 178 BSSSection->setNumber(CurSectionNumber++); |
179 BSSSection->setNameStrIndex(ShStrTab->getIndex(BSSSection->getName())); | |
180 AllSections.push_back(BSSSection); | |
181 } | |
182 assignRelSectionNumInPairs<DataSectionList>(CurSectionNumber, RODataSections, | |
183 RelRODataSections, AllSections); | |
155 | 184 |
156 ShStrTab->setNumber(CurSectionNumber++); | 185 ShStrTab->setNumber(CurSectionNumber++); |
157 ShStrTab->setNameStrIndex(ShStrTab->getIndex(ShStrTab->getName())); | 186 ShStrTab->setNameStrIndex(ShStrTab->getIndex(ShStrTab->getName())); |
158 AllSections.push_back(ShStrTab); | 187 AllSections.push_back(ShStrTab); |
159 | 188 |
160 SymTab->setNumber(CurSectionNumber++); | 189 SymTab->setNumber(CurSectionNumber++); |
161 SymTab->setNameStrIndex(ShStrTab->getIndex(SymTab->getName())); | 190 SymTab->setNameStrIndex(ShStrTab->getIndex(SymTab->getName())); |
162 AllSections.push_back(SymTab); | 191 AllSections.push_back(SymTab); |
163 | 192 |
164 StrTab->setNumber(CurSectionNumber++); | 193 StrTab->setNumber(CurSectionNumber++); |
165 StrTab->setNameStrIndex(ShStrTab->getIndex(StrTab->getName())); | 194 StrTab->setNameStrIndex(ShStrTab->getIndex(StrTab->getName())); |
166 AllSections.push_back(StrTab); | 195 AllSections.push_back(StrTab); |
167 | 196 |
168 SymTab->setLinkNum(StrTab->getNumber()); | 197 SymTab->setLinkNum(StrTab->getNumber()); |
169 SymTab->setInfoNum(SymTab->getNumLocals()); | 198 SymTab->setInfoNum(SymTab->getNumLocals()); |
170 | 199 |
171 assignRelLinkNum(SymTab->getNumber(), RelTextSections); | 200 assignRelLinkNum(SymTab->getNumber(), RelTextSections); |
172 assignRelLinkNum(SymTab->getNumber(), RelDataSections); | 201 assignRelLinkNum(SymTab->getNumber(), RelDataSections); |
173 assignRelLinkNum(SymTab->getNumber(), RelRoDataSections); | 202 assignRelLinkNum(SymTab->getNumber(), RelRODataSections); |
174 SectionNumbersAssigned = true; | 203 SectionNumbersAssigned = true; |
175 } | 204 } |
176 | 205 |
177 Elf64_Off ELFObjectWriter::alignFileOffset(Elf64_Xword Align) { | 206 Elf64_Off ELFObjectWriter::alignFileOffset(Elf64_Xword Align) { |
178 assert(llvm::isPowerOf2_32(Align)); | 207 assert(llvm::isPowerOf2_32(Align)); |
179 Elf64_Off OffsetInFile = Str.tell(); | 208 Elf64_Off OffsetInFile = Str.tell(); |
180 Elf64_Xword Mod = OffsetInFile & (Align - 1); | 209 Elf64_Xword Mod = OffsetInFile & (Align - 1); |
181 if (Mod == 0) | 210 if (Mod == 0) |
182 return OffsetInFile; | 211 return OffsetInFile; |
183 Elf64_Xword AlignDiff = Align - Mod; | 212 Elf64_Xword AlignDiff = Align - Mod; |
184 Str.writeZeroPadding(AlignDiff); | 213 Str.writeZeroPadding(AlignDiff); |
185 OffsetInFile += AlignDiff; | 214 OffsetInFile += AlignDiff; |
186 assert((OffsetInFile & (Align - 1)) == 0); | 215 assert((OffsetInFile & (Align - 1)) == 0); |
187 return OffsetInFile; | 216 return OffsetInFile; |
188 } | 217 } |
189 | 218 |
190 void ELFObjectWriter::writeFunctionCode(const IceString &FuncName, | 219 void ELFObjectWriter::writeFunctionCode(const IceString &FuncName, |
191 bool IsInternal, const Assembler *Asm) { | 220 bool IsInternal, const Assembler *Asm) { |
192 assert(!SectionNumbersAssigned); | 221 assert(!SectionNumbersAssigned); |
193 ELFTextSection *Section = nullptr; | 222 ELFTextSection *Section = nullptr; |
223 ELFRelocationSection *RelSection = nullptr; | |
194 // TODO(jvoung): handle ffunction-sections. | 224 // TODO(jvoung): handle ffunction-sections. |
195 IceString SectionName = ".text"; | 225 IceString SectionName = ".text"; |
196 if (TextSections.size() == 0) { | 226 bool IsELF64 = isELF64(Ctx.getTargetArch()); |
Jim Stichnoth
2015/01/27 16:44:55
Move this into the if() block? Maybe SectionName
jvoung (off chromium)
2015/01/28 17:46:22
Done.
| |
227 if (TextSections.empty()) { | |
197 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_EXECINSTR; | 228 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_EXECINSTR; |
198 // TODO(jvoung): Should be bundle size. Grab it from that target? | 229 // TODO(jvoung): Should be bundle size. Grab it from that target? |
199 const Elf64_Xword ShAlign = 32; | 230 const Elf64_Xword ShAlign = 32; |
200 Section = createSection<ELFTextSection>(SectionName, SHT_PROGBITS, ShFlags, | 231 Section = createSection<ELFTextSection>(SectionName, SHT_PROGBITS, ShFlags, |
201 ShAlign, 0); | 232 ShAlign, 0); |
202 Elf64_Off OffsetInFile = alignFileOffset(Section->getSectionAlign()); | 233 Elf64_Off OffsetInFile = alignFileOffset(Section->getSectionAlign()); |
203 Section->setFileOffset(OffsetInFile); | 234 Section->setFileOffset(OffsetInFile); |
204 TextSections.push_back(Section); | 235 TextSections.push_back(Section); |
236 RelSection = createRelocationSection(IsELF64, Section); | |
237 RelTextSections.push_back(RelSection); | |
205 } else { | 238 } else { |
206 Section = TextSections[0]; | 239 Section = TextSections[0]; |
240 RelSection = RelTextSections[0]; | |
207 } | 241 } |
208 RelocOffsetT OffsetInSection = Section->getCurrentSize(); | 242 RelocOffsetT OffsetInSection = Section->getCurrentSize(); |
209 // Function symbols are set to 0 size in the symbol table, | 243 // Function symbols are set to 0 size in the symbol table, |
210 // in contrast to data symbols which have a proper size. | 244 // in contrast to data symbols which have a proper size. |
211 SizeT SymbolSize = 0; | 245 SizeT SymbolSize = 0; |
212 Section->appendData(Str, Asm->getBufferView()); | 246 Section->appendData(Str, Asm->getBufferView()); |
213 uint8_t SymbolType; | 247 uint8_t SymbolType; |
214 uint8_t SymbolBinding; | 248 uint8_t SymbolBinding; |
215 if (IsInternal) { | 249 if (IsInternal) { |
216 SymbolType = STT_NOTYPE; | 250 SymbolType = STT_NOTYPE; |
217 SymbolBinding = STB_LOCAL; | 251 SymbolBinding = STB_LOCAL; |
218 } else { | 252 } else { |
219 SymbolType = STT_FUNC; | 253 SymbolType = STT_FUNC; |
220 SymbolBinding = STB_GLOBAL; | 254 SymbolBinding = STB_GLOBAL; |
221 } | 255 } |
222 SymTab->createDefinedSym(FuncName, SymbolType, SymbolBinding, Section, | 256 SymTab->createDefinedSym(FuncName, SymbolType, SymbolBinding, Section, |
223 OffsetInSection, SymbolSize); | 257 OffsetInSection, SymbolSize); |
224 StrTab->add(FuncName); | 258 StrTab->add(FuncName); |
225 | 259 |
226 // Create a relocation section for the text section if needed, and copy the | 260 // Create a relocation section for the text section if needed, and copy the |
227 // fixup information from per-function Assembler memory to the object | 261 // fixup information from per-function Assembler memory to the object |
228 // writer's memory, for writing later. | 262 // writer's memory, for writing later. |
229 if (!Asm->fixups().empty()) { | 263 if (!Asm->fixups().empty()) { |
230 bool IsELF64 = isELF64(Ctx.getTargetArch()); | |
231 IceString RelSectionName = IsELF64 ? ".rela" : ".rel"; | |
232 RelSectionName += SectionName; | |
233 ELFRelocationSection *RelSection = nullptr; | |
234 // TODO(jvoung): Make this more efficient if -ffunction-sections | |
235 // efficiency becomes a problem. | |
236 auto RSI = | |
237 std::find_if(RelTextSections.begin(), RelTextSections.end(), | |
238 [&RelSectionName](const ELFRelocationSection *S) | |
239 -> bool { return S->getName() == RelSectionName; }); | |
240 if (RSI != RelTextSections.end()) { | |
241 RelSection = *RSI; | |
242 } else { | |
243 const Elf64_Word ShType = IsELF64 ? SHT_RELA : SHT_REL; | |
244 const Elf64_Xword ShAlign = IsELF64 ? 8 : 4; | |
245 const Elf64_Xword ShEntSize = | |
246 IsELF64 ? sizeof(Elf64_Rela) : sizeof(Elf32_Rel); | |
247 static_assert(sizeof(Elf64_Rela) == 24 && sizeof(Elf32_Rel) == 8, | |
248 "Elf_Rel/Rela sizes cannot be derived from sizeof"); | |
249 const Elf64_Xword ShFlags = 0; | |
250 RelSection = createSection<ELFRelocationSection>( | |
251 RelSectionName, ShType, ShFlags, ShAlign, ShEntSize); | |
252 RelSection->setRelatedSection(Section); | |
253 RelTextSections.push_back(RelSection); | |
254 } | |
255 RelSection->addRelocations(OffsetInSection, Asm->fixups()); | 264 RelSection->addRelocations(OffsetInSection, Asm->fixups()); |
256 } | 265 } |
257 } | 266 } |
258 | 267 |
259 void ELFObjectWriter::writeDataInitializer(const IceString &VarName, | 268 namespace { |
260 const llvm::StringRef Data) { | 269 |
270 ELFObjectWriter::SectionType | |
271 classifyGlobalSection(const VariableDeclaration *Var) { | |
272 if (Var->getIsConstant()) | |
273 return ELFObjectWriter::ROData; | |
274 if (Var->hasNonzeroInitializer()) | |
275 return ELFObjectWriter::Data; | |
276 return ELFObjectWriter::BSS; | |
277 } | |
278 | |
279 // TODO(jvoung): dedupe, use the GlobalContext version | |
Jim Stichnoth
2015/01/27 16:44:55
Should be possible now. :)
jvoung (off chromium)
2015/01/28 17:46:22
Sweet -- Done.
| |
280 // https://codereview.chromium.org/870653002/diff/200001/src/IceGlobalContext.h | |
281 bool matchSymbolName(const IceString &SymbolName, const IceString &Match) { | |
282 return Match.empty() || Match == SymbolName; | |
283 } | |
284 | |
285 // Partition the Vars list by SectionType into VarsBySection. | |
286 // If TranslateOnly is non-empty, then only the TranslateOnly variable | |
287 // is kept for emission. | |
288 void partitionGlobalsBySection(const VariableDeclarationList &Vars, | |
289 VariableDeclarationList VarsBySection[], | |
290 const IceString &TranslateOnly) { | |
291 for (auto Var : Vars) { | |
Jim Stichnoth
2015/01/27 16:44:55
I think you should use VariableDeclaration *Var in
jvoung (off chromium)
2015/01/28 17:46:22
Done -- still getting used to this fancy new "auto
| |
292 if (matchSymbolName(Var->getName(), TranslateOnly)) { | |
293 size_t Section = classifyGlobalSection(Var); | |
294 assert(Section < ELFObjectWriter::SectionType::NumSectionTypes); | |
295 VarsBySection[Section].push_back(Var); | |
296 } | |
297 } | |
298 } | |
299 | |
300 } // end of anonymous namespace | |
301 | |
302 void ELFObjectWriter::writeDataSection(const VariableDeclarationList &Vars, | |
303 FixupKind RelocationKind) { | |
261 assert(!SectionNumbersAssigned); | 304 assert(!SectionNumbersAssigned); |
262 (void)Data; | 305 VariableDeclarationList VarsBySection[ELFObjectWriter::NumSectionTypes]; |
263 llvm_unreachable("TODO"); | 306 for (auto &SectionList : VarsBySection) |
Jim Stichnoth
2015/01/27 16:44:55
Yay! :)
| |
264 StrTab->add(VarName); | 307 SectionList.reserve(Vars.size()); |
Jim Stichnoth
2015/01/27 16:44:55
Could you document relevant functions as to whethe
jvoung (off chromium)
2015/01/28 17:46:22
Good point -- I've added some comments in the .h f
| |
308 partitionGlobalsBySection(Vars, VarsBySection, Ctx.getFlags().TranslateOnly); | |
309 bool IsELF64 = isELF64(Ctx.getTargetArch()); | |
310 for (size_t I = ELFObjectWriter::BaseSectionType; | |
311 I < ELFObjectWriter::NumSectionTypes; ++I) { | |
312 writeDataOfType(static_cast<SectionType>(I), VarsBySection[I], | |
313 RelocationKind, IsELF64); | |
314 } | |
315 } | |
316 | |
317 void ELFObjectWriter::writeDataOfType(SectionType SectionType, | |
318 const VariableDeclarationList &Vars, | |
319 FixupKind RelocationKind, bool IsELF64) { | |
320 ELFDataSection *Section; | |
321 ELFRelocationSection *RelSection; | |
322 // TODO(jvoung): Handle fdata-sections. | |
323 IceString SectionName; | |
324 Elf64_Xword ShAddralign = 0; | |
325 for (auto *Var : Vars) { | |
326 Elf64_Xword Align = Var->getAlignment(); | |
327 ShAddralign = std::max(ShAddralign, Align); | |
328 } | |
329 const Elf64_Xword ShEntsize = 0; // non-uniform data element size. | |
330 // Lift this out, so it can be re-used if we do fdata-sections? | |
331 switch (SectionType) { | |
332 case SectionType::ROData: { | |
333 SectionName = ".rodata"; | |
334 // Only expecting to write the data sections all in one shot for now. | |
335 assert(RODataSections.empty()); | |
336 const Elf64_Xword ShFlags = SHF_ALLOC; | |
337 Section = createSection<ELFDataSection>(SectionName, SHT_PROGBITS, ShFlags, | |
338 ShAddralign, ShEntsize); | |
339 Section->setFileOffset(alignFileOffset(ShAddralign)); | |
340 RODataSections.push_back(Section); | |
341 RelSection = createRelocationSection(IsELF64, Section); | |
342 RelRODataSections.push_back(RelSection); | |
343 break; | |
344 } | |
345 case SectionType::Data: { | |
346 SectionName = ".data"; | |
347 assert(DataSections.empty()); | |
348 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_WRITE; | |
349 Section = createSection<ELFDataSection>(SectionName, SHT_PROGBITS, ShFlags, | |
350 ShAddralign, ShEntsize); | |
351 Section->setFileOffset(alignFileOffset(ShAddralign)); | |
352 DataSections.push_back(Section); | |
353 RelSection = createRelocationSection(IsELF64, Section); | |
354 RelDataSections.push_back(RelSection); | |
355 break; | |
356 } | |
357 case SectionType::BSS: { | |
358 SectionName = ".bss"; | |
359 assert(BSSSections.empty()); | |
360 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_WRITE; | |
361 Section = createSection<ELFDataSection>(SectionName, SHT_NOBITS, ShFlags, | |
362 ShAddralign, ShEntsize); | |
363 Section->setFileOffset(alignFileOffset(ShAddralign)); | |
364 BSSSections.push_back(Section); | |
365 break; | |
366 } | |
367 case SectionType::NumSectionTypes: | |
368 llvm_unreachable("Unknown SectionType"); | |
Jim Stichnoth
2015/01/27 16:44:55
llvm::report_fatal_error()?
jvoung (off chromium)
2015/01/28 17:46:22
Done.
| |
369 break; | |
370 } | |
371 | |
372 const uint8_t SymbolType = STT_OBJECT; | |
373 for (auto *Var : Vars) { | |
374 Elf64_Xword Align = Var->getAlignment(); | |
375 Section->padToAlignment(Str, Align); | |
376 SizeT SymbolSize = Var->getNumBytes(); | |
377 bool IsExternal = Var->isExternal() || Ctx.getFlags().DisableInternal; | |
378 const uint8_t SymbolBinding = IsExternal ? STB_GLOBAL : STB_LOCAL; | |
379 IceString MangledName = Var->mangleName(&Ctx); | |
380 SymTab->createDefinedSym(MangledName, SymbolType, SymbolBinding, Section, | |
381 Section->getCurrentSize(), SymbolSize); | |
382 StrTab->add(MangledName); | |
383 if (!Var->hasNonzeroInitializer()) { | |
384 assert(SectionType == SectionType::BSS || | |
385 SectionType == SectionType::ROData); | |
386 if (SectionType == SectionType::ROData) | |
387 Section->appendZeros(Str, SymbolSize); | |
388 else | |
389 Section->setSize(Section->getCurrentSize() + SymbolSize); | |
390 } else { | |
391 assert(SectionType != SectionType::BSS); | |
392 for (VariableDeclaration::Initializer *Init : Var->getInitializers()) { | |
393 switch (Init->getKind()) { | |
394 case VariableDeclaration::Initializer::DataInitializerKind: { | |
395 const auto Data = llvm::cast<VariableDeclaration::DataInitializer>( | |
396 Init)->getContents(); | |
397 Section->appendData(Str, llvm::StringRef(Data.data(), Data.size())); | |
398 break; | |
399 } | |
400 case VariableDeclaration::Initializer::ZeroInitializerKind: | |
401 Section->appendZeros(Str, Init->getNumBytes()); | |
402 break; | |
403 case VariableDeclaration::Initializer::RelocInitializerKind: { | |
404 const auto Reloc = | |
405 llvm::cast<VariableDeclaration::RelocInitializer>(Init); | |
406 AssemblerFixup NewFixup; | |
407 NewFixup.set_position(Section->getCurrentSize()); | |
408 NewFixup.set_kind(RelocationKind); | |
409 const bool SuppressMangling = true; | |
410 NewFixup.set_value(Ctx.getConstantSym( | |
411 Reloc->getOffset(), Reloc->getDeclaration()->mangleName(&Ctx), | |
412 SuppressMangling)); | |
413 RelSection->addRelocation(NewFixup); | |
414 Section->appendRelocationOffset(Str, RelSection->isRela(), | |
415 Reloc->getOffset()); | |
416 break; | |
417 } | |
418 } | |
419 } | |
420 } | |
421 } | |
265 } | 422 } |
266 | 423 |
267 void ELFObjectWriter::writeInitialELFHeader() { | 424 void ELFObjectWriter::writeInitialELFHeader() { |
268 assert(!SectionNumbersAssigned); | 425 assert(!SectionNumbersAssigned); |
269 const Elf64_Off DummySHOffset = 0; | 426 const Elf64_Off DummySHOffset = 0; |
270 const SizeT DummySHStrIndex = 0; | 427 const SizeT DummySHStrIndex = 0; |
271 const SizeT DummyNumSections = 0; | 428 const SizeT DummyNumSections = 0; |
272 if (isELF64(Ctx.getTargetArch())) { | 429 if (isELF64(Ctx.getTargetArch())) { |
273 writeELFHeaderInternal<true>(DummySHOffset, DummySHStrIndex, | 430 writeELFHeaderInternal<true>(DummySHOffset, DummySHStrIndex, |
274 DummyNumSections); | 431 DummyNumSections); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
338 // between entries. | 495 // between entries. |
339 assert(WriteAmt % Align == 0); | 496 assert(WriteAmt % Align == 0); |
340 // Check that we write the full PrimType. | 497 // Check that we write the full PrimType. |
341 assert(WriteAmt == sizeof(typename ConstType::PrimType)); | 498 assert(WriteAmt == sizeof(typename ConstType::PrimType)); |
342 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_MERGE; | 499 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_MERGE; |
343 std::string SecBuffer; | 500 std::string SecBuffer; |
344 llvm::raw_string_ostream SecStrBuf(SecBuffer); | 501 llvm::raw_string_ostream SecStrBuf(SecBuffer); |
345 SecStrBuf << ".rodata.cst" << WriteAmt; | 502 SecStrBuf << ".rodata.cst" << WriteAmt; |
346 ELFDataSection *Section = createSection<ELFDataSection>( | 503 ELFDataSection *Section = createSection<ELFDataSection>( |
347 SecStrBuf.str(), SHT_PROGBITS, ShFlags, Align, WriteAmt); | 504 SecStrBuf.str(), SHT_PROGBITS, ShFlags, Align, WriteAmt); |
348 RoDataSections.push_back(Section); | 505 RODataSections.push_back(Section); |
349 SizeT OffsetInSection = 0; | 506 SizeT OffsetInSection = 0; |
350 // The symbol table entry doesn't need to know the defined symbol's | 507 // The symbol table entry doesn't need to know the defined symbol's |
351 // size since this is in a section with a fixed Entry Size. | 508 // size since this is in a section with a fixed Entry Size. |
352 const SizeT SymbolSize = 0; | 509 const SizeT SymbolSize = 0; |
353 Section->setFileOffset(alignFileOffset(Align)); | 510 Section->setFileOffset(alignFileOffset(Align)); |
354 | 511 |
355 // Write the data. | 512 // Write the data. |
356 for (Constant *C : Pool) { | 513 for (Constant *C : Pool) { |
357 auto Const = llvm::cast<ConstType>(C); | 514 auto Const = llvm::cast<ConstType>(C); |
358 std::string SymBuffer; | 515 std::string SymBuffer; |
(...skipping 16 matching lines...) Expand all Loading... | |
375 // We may need to instantiate constant pools for integers as well | 532 // We may need to instantiate constant pools for integers as well |
376 // if we do constant-pooling of large integers to remove them | 533 // if we do constant-pooling of large integers to remove them |
377 // from the instruction stream (fewer bytes controlled by an attacker). | 534 // from the instruction stream (fewer bytes controlled by an attacker). |
378 template void ELFObjectWriter::writeConstantPool<ConstantFloat>(Type Ty); | 535 template void ELFObjectWriter::writeConstantPool<ConstantFloat>(Type Ty); |
379 | 536 |
380 template void ELFObjectWriter::writeConstantPool<ConstantDouble>(Type Ty); | 537 template void ELFObjectWriter::writeConstantPool<ConstantDouble>(Type Ty); |
381 | 538 |
382 void ELFObjectWriter::writeAllRelocationSections(bool IsELF64) { | 539 void ELFObjectWriter::writeAllRelocationSections(bool IsELF64) { |
383 writeRelocationSections(IsELF64, RelTextSections); | 540 writeRelocationSections(IsELF64, RelTextSections); |
384 writeRelocationSections(IsELF64, RelDataSections); | 541 writeRelocationSections(IsELF64, RelDataSections); |
385 writeRelocationSections(IsELF64, RelRoDataSections); | 542 writeRelocationSections(IsELF64, RelRODataSections); |
386 } | 543 } |
387 | 544 |
388 void ELFObjectWriter::writeRelocationSections(bool IsELF64, | 545 void ELFObjectWriter::writeRelocationSections(bool IsELF64, |
389 RelSectionList &RelSections) { | 546 RelSectionList &RelSections) { |
390 for (ELFRelocationSection *RelSec : RelSections) { | 547 for (ELFRelocationSection *RelSec : RelSections) { |
391 Elf64_Off Offset = alignFileOffset(RelSec->getSectionAlign()); | 548 Elf64_Off Offset = alignFileOffset(RelSec->getSectionAlign()); |
392 RelSec->setFileOffset(Offset); | 549 RelSec->setFileOffset(Offset); |
393 RelSec->setSize(RelSec->getSectionDataSize(Ctx, SymTab)); | 550 RelSec->setSize(RelSec->getSectionDataSize(Ctx, SymTab)); |
394 if (IsELF64) { | 551 if (IsELF64) { |
395 RelSec->writeData<true>(Ctx, Str, SymTab); | 552 RelSec->writeData<true>(Ctx, Str, SymTab); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
444 if (IsELF64) { | 601 if (IsELF64) { |
445 writeELFHeaderInternal<true>(ShOffset, ShStrTab->getNumber(), | 602 writeELFHeaderInternal<true>(ShOffset, ShStrTab->getNumber(), |
446 AllSections.size()); | 603 AllSections.size()); |
447 } else { | 604 } else { |
448 writeELFHeaderInternal<false>(ShOffset, ShStrTab->getNumber(), | 605 writeELFHeaderInternal<false>(ShOffset, ShStrTab->getNumber(), |
449 AllSections.size()); | 606 AllSections.size()); |
450 } | 607 } |
451 } | 608 } |
452 | 609 |
453 } // end of namespace Ice | 610 } // end of namespace Ice |
OLD | NEW |