Chromium Code Reviews| 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...) Expand 10 before | Expand all | Expand 10 after 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...) Expand 10 before | Expand all | Expand 10 after 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 |