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 "IceDefs.h" | 14 #include "IceDefs.h" |
15 #include "IceELFObjectWriter.h" | 15 #include "IceELFObjectWriter.h" |
16 #include "IceELFSection.h" | 16 #include "IceELFSection.h" |
17 #include "IceELFStreamer.h" | 17 #include "IceELFStreamer.h" |
18 #include "IceGlobalContext.h" | 18 #include "IceGlobalContext.h" |
19 #include "IceGlobalInits.h" | 19 #include "IceGlobalInits.h" |
20 #include "IceOperand.h" | |
20 | 21 |
21 using namespace llvm::ELF; | 22 using namespace llvm::ELF; |
22 | 23 |
23 namespace Ice { | 24 namespace Ice { |
24 | 25 |
25 namespace { | 26 namespace { |
26 | 27 |
27 struct { | 28 struct { |
28 bool IsELF64; | 29 bool IsELF64; |
29 uint16_t ELFMachine; | 30 uint16_t ELFMachine; |
(...skipping 254 matching lines...) Loading... | |
284 Str.writeLE16(0); // e_phentsize | 285 Str.writeLE16(0); // e_phentsize |
285 Str.writeLE16(0); // e_phnum | 286 Str.writeLE16(0); // e_phnum |
286 Str.writeLE16(IsELF64 ? sizeof(Elf64_Shdr) | 287 Str.writeLE16(IsELF64 ? sizeof(Elf64_Shdr) |
287 : sizeof(Elf32_Shdr)); // e_shentsize | 288 : sizeof(Elf32_Shdr)); // e_shentsize |
288 static_assert(sizeof(Elf64_Shdr) == 64 && sizeof(Elf32_Shdr) == 40, | 289 static_assert(sizeof(Elf64_Shdr) == 64 && sizeof(Elf32_Shdr) == 40, |
289 "Elf_Shdr sizes cannot be derived from sizeof"); | 290 "Elf_Shdr sizes cannot be derived from sizeof"); |
290 Str.writeLE16(static_cast<Elf64_Half>(NumSections)); // e_shnum | 291 Str.writeLE16(static_cast<Elf64_Half>(NumSections)); // e_shnum |
291 Str.writeLE16(static_cast<Elf64_Half>(SectHeaderStrIndex)); // e_shstrndx | 292 Str.writeLE16(static_cast<Elf64_Half>(SectHeaderStrIndex)); // e_shstrndx |
292 } | 293 } |
293 | 294 |
295 template <typename ConstType> void ELFObjectWriter::writeConstantPool(Type Ty) { | |
296 ConstantList Pool = Ctx.getConstantPool(Ty); | |
297 if (Pool.size() == 0) { | |
Jim Stichnoth
2015/01/09 19:23:45
Pool.empty()
jvoung (off chromium)
2015/01/09 19:52:16
Done.
| |
298 return; | |
299 } | |
300 SizeT Align = typeAlignInBytes(Ty); | |
301 SizeT EntSize = typeWidthInBytes(Ty); | |
302 // Assume that writing EntSize bytes at a time allows us to avoid aligning | |
303 // between entries. | |
304 assert(EntSize % Align == 0); | |
305 assert(EntSize == sizeof(typename ConstType::PrimType)); | |
306 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_MERGE; | |
307 std::string SecBuffer; | |
308 llvm::raw_string_ostream SecStrBuf(SecBuffer); | |
309 SecStrBuf << ".rodata.cst" << EntSize; | |
310 ELFDataSection *Section = createSection<ELFDataSection>( | |
311 SecStrBuf.str(), SHT_PROGBITS, ShFlags, Align, EntSize); | |
312 RoDataSections.push_back(Section); | |
313 SizeT OffsetInSection = 0; | |
314 // The symbol table entry doesn't need to know the defined symbol's | |
315 // size since this is in a section with a fixed Entry Size. | |
316 const SizeT SymbolSize = 0; | |
317 Section->setFileOffset(alignFileOffset(Align)); | |
318 | |
319 // Write the data. | |
320 for (Constant *C : Pool) { | |
321 ConstType *Const = llvm::cast<ConstType>(C); | |
Jim Stichnoth
2015/01/09 19:23:45
Could use "auto Const" here.
jvoung (off chromium)
2015/01/09 19:52:16
Done.
| |
322 std::string SymBuffer; | |
323 llvm::raw_string_ostream SymStrBuf(SymBuffer); | |
324 SymStrBuf << ".L$" << Ty << "$" << Const->getPoolEntryID(); | |
325 std::string &SymName = SymStrBuf.str(); | |
326 SymTab->createDefinedSym(SymName, STT_NOTYPE, STB_LOCAL, Section, | |
327 OffsetInSection, SymbolSize); | |
328 StrTab->add(SymName); | |
329 typename ConstType::PrimType Value = Const->getValue(); | |
330 char Buf[20]; | |
331 assert(EntSize < llvm::array_lengthof(Buf)); | |
332 memcpy(Buf, &Value, EntSize); | |
Jim Stichnoth
2015/01/09 19:23:45
Can you make this safer in the NDEBUG build by usi
jvoung (off chromium)
2015/01/09 19:52:16
Done.
| |
333 Str.writeBytes(llvm::StringRef(Buf, EntSize)); | |
334 OffsetInSection += EntSize; | |
335 } | |
336 Section->setSize(OffsetInSection); | |
337 } | |
338 | |
339 // Instantiate known needed versions of the template, since we are | |
340 // defining the function in the .cpp file instead of the .h file. | |
jvoung (off chromium)
2015/01/09 02:05:50
Wasn't sure of a better way =/
I think on ARM we'
Jim Stichnoth
2015/01/09 19:23:45
I think this is the usual way...
jvoung (off chromium)
2015/01/09 19:52:16
Done.
| |
341 template void ELFObjectWriter::writeConstantPool<ConstantFloat>(Type Ty); | |
342 | |
343 template void ELFObjectWriter::writeConstantPool<ConstantDouble>(Type Ty); | |
344 | |
294 void ELFObjectWriter::writeNonUserSections() { | 345 void ELFObjectWriter::writeNonUserSections() { |
295 bool IsELF64 = isELF64(Ctx.getTargetArch()); | 346 bool IsELF64 = isELF64(Ctx.getTargetArch()); |
296 | 347 |
297 // Write out the shstrtab now that all sections are known. | 348 // Write out the shstrtab now that all sections are known. |
298 ShStrTab->doLayout(); | 349 ShStrTab->doLayout(); |
299 ShStrTab->setSize(ShStrTab->getSectionDataSize()); | 350 ShStrTab->setSize(ShStrTab->getSectionDataSize()); |
300 Elf64_Off ShStrTabOffset = alignFileOffset(ShStrTab->getSectionAlign()); | 351 Elf64_Off ShStrTabOffset = alignFileOffset(ShStrTab->getSectionAlign()); |
301 ShStrTab->setFileOffset(ShStrTabOffset); | 352 ShStrTab->setFileOffset(ShStrTabOffset); |
302 Str.writeBytes(ShStrTab->getSectionData()); | 353 Str.writeBytes(ShStrTab->getSectionData()); |
303 | 354 |
(...skipping 34 matching lines...) Loading... | |
338 if (IsELF64) { | 389 if (IsELF64) { |
339 writeELFHeaderInternal<true>(ShOffset, ShStrTab->getNumber(), | 390 writeELFHeaderInternal<true>(ShOffset, ShStrTab->getNumber(), |
340 AllSections.size()); | 391 AllSections.size()); |
341 } else { | 392 } else { |
342 writeELFHeaderInternal<false>(ShOffset, ShStrTab->getNumber(), | 393 writeELFHeaderInternal<false>(ShOffset, ShStrTab->getNumber(), |
343 AllSections.size()); | 394 AllSections.size()); |
344 } | 395 } |
345 } | 396 } |
346 | 397 |
347 } // end of namespace Ice | 398 } // end of namespace Ice |
OLD | NEW |