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.empty()) { |
| 298 return; |
| 299 } |
| 300 SizeT Align = typeAlignInBytes(Ty); |
| 301 size_t EntSize = typeWidthInBytes(Ty); |
| 302 char Buf[20]; |
| 303 SizeT WriteAmt = std::min(EntSize, llvm::array_lengthof(Buf)); |
| 304 assert(WriteAmt == EntSize); |
| 305 // Assume that writing WriteAmt bytes at a time allows us to avoid aligning |
| 306 // between entries. |
| 307 assert(WriteAmt % Align == 0); |
| 308 // Check that we write the full PrimType. |
| 309 assert(WriteAmt == sizeof(typename ConstType::PrimType)); |
| 310 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_MERGE; |
| 311 std::string SecBuffer; |
| 312 llvm::raw_string_ostream SecStrBuf(SecBuffer); |
| 313 SecStrBuf << ".rodata.cst" << WriteAmt; |
| 314 ELFDataSection *Section = createSection<ELFDataSection>( |
| 315 SecStrBuf.str(), SHT_PROGBITS, ShFlags, Align, WriteAmt); |
| 316 RoDataSections.push_back(Section); |
| 317 SizeT OffsetInSection = 0; |
| 318 // The symbol table entry doesn't need to know the defined symbol's |
| 319 // size since this is in a section with a fixed Entry Size. |
| 320 const SizeT SymbolSize = 0; |
| 321 Section->setFileOffset(alignFileOffset(Align)); |
| 322 |
| 323 // Write the data. |
| 324 for (Constant *C : Pool) { |
| 325 auto Const = llvm::cast<ConstType>(C); |
| 326 std::string SymBuffer; |
| 327 llvm::raw_string_ostream SymStrBuf(SymBuffer); |
| 328 SymStrBuf << ".L$" << Ty << "$" << Const->getPoolEntryID(); |
| 329 std::string &SymName = SymStrBuf.str(); |
| 330 SymTab->createDefinedSym(SymName, STT_NOTYPE, STB_LOCAL, Section, |
| 331 OffsetInSection, SymbolSize); |
| 332 StrTab->add(SymName); |
| 333 typename ConstType::PrimType Value = Const->getValue(); |
| 334 memcpy(Buf, &Value, WriteAmt); |
| 335 Str.writeBytes(llvm::StringRef(Buf, WriteAmt)); |
| 336 OffsetInSection += WriteAmt; |
| 337 } |
| 338 Section->setSize(OffsetInSection); |
| 339 } |
| 340 |
| 341 // Instantiate known needed versions of the template, since we are |
| 342 // defining the function in the .cpp file instead of the .h file. |
| 343 // We may need to instantiate constant pools for integers as well |
| 344 // if we do constant-pooling of large integers to remove them |
| 345 // from the instruction stream (fewer bytes controlled by an attacker). |
| 346 template void ELFObjectWriter::writeConstantPool<ConstantFloat>(Type Ty); |
| 347 |
| 348 template void ELFObjectWriter::writeConstantPool<ConstantDouble>(Type Ty); |
| 349 |
294 void ELFObjectWriter::writeNonUserSections() { | 350 void ELFObjectWriter::writeNonUserSections() { |
295 bool IsELF64 = isELF64(Ctx.getTargetArch()); | 351 bool IsELF64 = isELF64(Ctx.getTargetArch()); |
296 | 352 |
297 // Write out the shstrtab now that all sections are known. | 353 // Write out the shstrtab now that all sections are known. |
298 ShStrTab->doLayout(); | 354 ShStrTab->doLayout(); |
299 ShStrTab->setSize(ShStrTab->getSectionDataSize()); | 355 ShStrTab->setSize(ShStrTab->getSectionDataSize()); |
300 Elf64_Off ShStrTabOffset = alignFileOffset(ShStrTab->getSectionAlign()); | 356 Elf64_Off ShStrTabOffset = alignFileOffset(ShStrTab->getSectionAlign()); |
301 ShStrTab->setFileOffset(ShStrTabOffset); | 357 ShStrTab->setFileOffset(ShStrTabOffset); |
302 Str.writeBytes(ShStrTab->getSectionData()); | 358 Str.writeBytes(ShStrTab->getSectionData()); |
303 | 359 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 if (IsELF64) { | 394 if (IsELF64) { |
339 writeELFHeaderInternal<true>(ShOffset, ShStrTab->getNumber(), | 395 writeELFHeaderInternal<true>(ShOffset, ShStrTab->getNumber(), |
340 AllSections.size()); | 396 AllSections.size()); |
341 } else { | 397 } else { |
342 writeELFHeaderInternal<false>(ShOffset, ShStrTab->getNumber(), | 398 writeELFHeaderInternal<false>(ShOffset, ShStrTab->getNumber(), |
343 AllSections.size()); | 399 AllSections.size()); |
344 } | 400 } |
345 } | 401 } |
346 | 402 |
347 } // end of namespace Ice | 403 } // end of namespace Ice |
OLD | NEW |