Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(977)

Side by Side Diff: src/IceELFObjectWriter.cpp

Issue 1024203002: Move some flag-like props from GlobalContext and TargetLowering to ClFlags. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: review / clean up formatting Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceELFObjectWriter.h ('k') | src/IceGlobalContext.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 uint32_t getELFFlags(TargetArch Arch) { 57 uint32_t getELFFlags(TargetArch Arch) {
58 if (Arch < TargetArch_NUM) 58 if (Arch < TargetArch_NUM)
59 return ELFTargetInfo[Arch].ELFFlags; 59 return ELFTargetInfo[Arch].ELFFlags;
60 llvm_unreachable("Invalid target arch for getELFFlags"); 60 llvm_unreachable("Invalid target arch for getELFFlags");
61 return 0; 61 return 0;
62 } 62 }
63 63
64 } // end of anonymous namespace 64 } // end of anonymous namespace
65 65
66 ELFObjectWriter::ELFObjectWriter(GlobalContext &Ctx, ELFStreamer &Out) 66 ELFObjectWriter::ELFObjectWriter(GlobalContext &Ctx, ELFStreamer &Out)
67 : Ctx(Ctx), Str(Out), SectionNumbersAssigned(false) { 67 : Ctx(Ctx), Str(Out), SectionNumbersAssigned(false),
68 ELF64(isELF64(Ctx.getFlags().getTargetArch())) {
68 // Create the special bookkeeping sections now. 69 // Create the special bookkeeping sections now.
69 const IceString NullSectionName(""); 70 const IceString NullSectionName("");
70 NullSection = new (Ctx.allocate<ELFSection>()) 71 NullSection = new (Ctx.allocate<ELFSection>())
71 ELFSection(NullSectionName, SHT_NULL, 0, 0, 0); 72 ELFSection(NullSectionName, SHT_NULL, 0, 0, 0);
72 73
73 const IceString ShStrTabName(".shstrtab"); 74 const IceString ShStrTabName(".shstrtab");
74 ShStrTab = new (Ctx.allocate<ELFStringTableSection>()) 75 ShStrTab = new (Ctx.allocate<ELFStringTableSection>())
75 ELFStringTableSection(ShStrTabName, SHT_STRTAB, 0, 1, 0); 76 ELFStringTableSection(ShStrTabName, SHT_STRTAB, 0, 1, 0);
76 ShStrTab->add(ShStrTabName); 77 ShStrTab->add(ShStrTabName);
77 78
78 const IceString SymTabName(".symtab"); 79 const IceString SymTabName(".symtab");
79 bool IsELF64 = isELF64(Ctx.getTargetArch()); 80 const Elf64_Xword SymTabAlign = ELF64 ? 8 : 4;
80 const Elf64_Xword SymTabAlign = IsELF64 ? 8 : 4;
81 const Elf64_Xword SymTabEntSize = 81 const Elf64_Xword SymTabEntSize =
82 IsELF64 ? sizeof(Elf64_Sym) : sizeof(Elf32_Sym); 82 ELF64 ? sizeof(Elf64_Sym) : sizeof(Elf32_Sym);
83 static_assert(sizeof(Elf64_Sym) == 24 && sizeof(Elf32_Sym) == 16, 83 static_assert(sizeof(Elf64_Sym) == 24 && sizeof(Elf32_Sym) == 16,
84 "Elf_Sym sizes cannot be derived from sizeof"); 84 "Elf_Sym sizes cannot be derived from sizeof");
85 SymTab = createSection<ELFSymbolTableSection>(SymTabName, SHT_SYMTAB, 0, 85 SymTab = createSection<ELFSymbolTableSection>(SymTabName, SHT_SYMTAB, 0,
86 SymTabAlign, SymTabEntSize); 86 SymTabAlign, SymTabEntSize);
87 SymTab->createNullSymbol(NullSection); 87 SymTab->createNullSymbol(NullSection);
88 88
89 const IceString StrTabName(".strtab"); 89 const IceString StrTabName(".strtab");
90 StrTab = 90 StrTab =
91 createSection<ELFStringTableSection>(StrTabName, SHT_STRTAB, 0, 1, 0); 91 createSection<ELFStringTableSection>(StrTabName, SHT_STRTAB, 0, 1, 0);
92 } 92 }
93 93
94 template <typename T> 94 template <typename T>
95 T *ELFObjectWriter::createSection(const IceString &Name, Elf64_Word ShType, 95 T *ELFObjectWriter::createSection(const IceString &Name, Elf64_Word ShType,
96 Elf64_Xword ShFlags, Elf64_Xword ShAddralign, 96 Elf64_Xword ShFlags, Elf64_Xword ShAddralign,
97 Elf64_Xword ShEntsize) { 97 Elf64_Xword ShEntsize) {
98 assert(!SectionNumbersAssigned); 98 assert(!SectionNumbersAssigned);
99 T *NewSection = 99 T *NewSection =
100 new (Ctx.allocate<T>()) T(Name, ShType, ShFlags, ShAddralign, ShEntsize); 100 new (Ctx.allocate<T>()) T(Name, ShType, ShFlags, ShAddralign, ShEntsize);
101 ShStrTab->add(Name); 101 ShStrTab->add(Name);
102 return NewSection; 102 return NewSection;
103 } 103 }
104 104
105 ELFRelocationSection * 105 ELFRelocationSection *
106 ELFObjectWriter::createRelocationSection(bool IsELF64, 106 ELFObjectWriter::createRelocationSection(const ELFSection *RelatedSection) {
107 const ELFSection *RelatedSection) {
108 // Choice of RELA vs REL is actually separate from elf64 vs elf32, 107 // Choice of RELA vs REL is actually separate from elf64 vs elf32,
109 // but in practice we've only had .rela for elf64 (x86-64). 108 // but in practice we've only had .rela for elf64 (x86-64).
110 // In the future, the two properties may need to be decoupled 109 // In the future, the two properties may need to be decoupled
111 // and the ShEntSize can vary more. 110 // and the ShEntSize can vary more.
112 const Elf64_Word ShType = IsELF64 ? SHT_RELA : SHT_REL; 111 const Elf64_Word ShType = ELF64 ? SHT_RELA : SHT_REL;
113 IceString RelPrefix = IsELF64 ? ".rela" : ".rel"; 112 IceString RelPrefix = ELF64 ? ".rela" : ".rel";
114 IceString RelSectionName = RelPrefix + RelatedSection->getName(); 113 IceString RelSectionName = RelPrefix + RelatedSection->getName();
115 const Elf64_Xword ShAlign = IsELF64 ? 8 : 4; 114 const Elf64_Xword ShAlign = ELF64 ? 8 : 4;
116 const Elf64_Xword ShEntSize = 115 const Elf64_Xword ShEntSize = ELF64 ? sizeof(Elf64_Rela) : sizeof(Elf32_Rel);
117 IsELF64 ? sizeof(Elf64_Rela) : sizeof(Elf32_Rel);
118 static_assert(sizeof(Elf64_Rela) == 24 && sizeof(Elf32_Rel) == 8, 116 static_assert(sizeof(Elf64_Rela) == 24 && sizeof(Elf32_Rel) == 8,
119 "Elf_Rel/Rela sizes cannot be derived from sizeof"); 117 "Elf_Rel/Rela sizes cannot be derived from sizeof");
120 const Elf64_Xword ShFlags = 0; 118 const Elf64_Xword ShFlags = 0;
121 ELFRelocationSection *RelSection = createSection<ELFRelocationSection>( 119 ELFRelocationSection *RelSection = createSection<ELFRelocationSection>(
122 RelSectionName, ShType, ShFlags, ShAlign, ShEntSize); 120 RelSectionName, ShType, ShFlags, ShAlign, ShEntSize);
123 RelSection->setRelatedSection(RelatedSection); 121 RelSection->setRelatedSection(RelatedSection);
124 return RelSection; 122 return RelSection;
125 } 123 }
126 124
127 template <typename UserSectionList> 125 template <typename UserSectionList>
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 void ELFObjectWriter::writeFunctionCode(const IceString &FuncName, 211 void ELFObjectWriter::writeFunctionCode(const IceString &FuncName,
214 bool IsInternal, const Assembler *Asm) { 212 bool IsInternal, const Assembler *Asm) {
215 assert(!SectionNumbersAssigned); 213 assert(!SectionNumbersAssigned);
216 ELFTextSection *Section = nullptr; 214 ELFTextSection *Section = nullptr;
217 ELFRelocationSection *RelSection = nullptr; 215 ELFRelocationSection *RelSection = nullptr;
218 const bool FunctionSections = Ctx.getFlags().getFunctionSections(); 216 const bool FunctionSections = Ctx.getFlags().getFunctionSections();
219 if (TextSections.empty() || FunctionSections) { 217 if (TextSections.empty() || FunctionSections) {
220 IceString SectionName = ".text"; 218 IceString SectionName = ".text";
221 if (FunctionSections) 219 if (FunctionSections)
222 SectionName += "." + FuncName; 220 SectionName += "." + FuncName;
223 bool IsELF64 = isELF64(Ctx.getTargetArch());
224 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_EXECINSTR; 221 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_EXECINSTR;
225 const Elf64_Xword ShAlign = 1 << Asm->getBundleAlignLog2Bytes(); 222 const Elf64_Xword ShAlign = 1 << Asm->getBundleAlignLog2Bytes();
226 Section = createSection<ELFTextSection>(SectionName, SHT_PROGBITS, ShFlags, 223 Section = createSection<ELFTextSection>(SectionName, SHT_PROGBITS, ShFlags,
227 ShAlign, 0); 224 ShAlign, 0);
228 Elf64_Off OffsetInFile = alignFileOffset(Section->getSectionAlign()); 225 Elf64_Off OffsetInFile = alignFileOffset(Section->getSectionAlign());
229 Section->setFileOffset(OffsetInFile); 226 Section->setFileOffset(OffsetInFile);
230 TextSections.push_back(Section); 227 TextSections.push_back(Section);
231 RelSection = createRelocationSection(IsELF64, Section); 228 RelSection = createRelocationSection(Section);
232 RelTextSections.push_back(RelSection); 229 RelTextSections.push_back(RelSection);
233 } else { 230 } else {
234 Section = TextSections[0]; 231 Section = TextSections[0];
235 RelSection = RelTextSections[0]; 232 RelSection = RelTextSections[0];
236 } 233 }
237 RelocOffsetT OffsetInSection = Section->getCurrentSize(); 234 RelocOffsetT OffsetInSection = Section->getCurrentSize();
238 // Function symbols are set to 0 size in the symbol table, 235 // Function symbols are set to 0 size in the symbol table,
239 // in contrast to data symbols which have a proper size. 236 // in contrast to data symbols which have a proper size.
240 SizeT SymbolSize = 0; 237 SizeT SymbolSize = 0;
241 Section->appendData(Str, Asm->getBufferView()); 238 Section->appendData(Str, Asm->getBufferView());
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 } // end of anonymous namespace 285 } // end of anonymous namespace
289 286
290 void ELFObjectWriter::writeDataSection(const VariableDeclarationList &Vars, 287 void ELFObjectWriter::writeDataSection(const VariableDeclarationList &Vars,
291 FixupKind RelocationKind) { 288 FixupKind RelocationKind) {
292 assert(!SectionNumbersAssigned); 289 assert(!SectionNumbersAssigned);
293 VariableDeclarationList VarsBySection[ELFObjectWriter::NumSectionTypes]; 290 VariableDeclarationList VarsBySection[ELFObjectWriter::NumSectionTypes];
294 for (auto &SectionList : VarsBySection) 291 for (auto &SectionList : VarsBySection)
295 SectionList.reserve(Vars.size()); 292 SectionList.reserve(Vars.size());
296 partitionGlobalsBySection(Vars, VarsBySection, 293 partitionGlobalsBySection(Vars, VarsBySection,
297 Ctx.getFlags().getTranslateOnly()); 294 Ctx.getFlags().getTranslateOnly());
298 bool IsELF64 = isELF64(Ctx.getTargetArch());
299 size_t I = 0; 295 size_t I = 0;
300 for (auto &SectionList : VarsBySection) { 296 for (auto &SectionList : VarsBySection) {
301 writeDataOfType(static_cast<SectionType>(I++), SectionList, RelocationKind, 297 writeDataOfType(static_cast<SectionType>(I++), SectionList, RelocationKind);
302 IsELF64);
303 } 298 }
304 } 299 }
305 300
306 void ELFObjectWriter::writeDataOfType(SectionType ST, 301 void ELFObjectWriter::writeDataOfType(SectionType ST,
307 const VariableDeclarationList &Vars, 302 const VariableDeclarationList &Vars,
308 FixupKind RelocationKind, bool IsELF64) { 303 FixupKind RelocationKind) {
309 if (Vars.empty()) 304 if (Vars.empty())
310 return; 305 return;
311 ELFDataSection *Section; 306 ELFDataSection *Section;
312 ELFRelocationSection *RelSection; 307 ELFRelocationSection *RelSection;
313 // TODO(jvoung): Handle fdata-sections. 308 // TODO(jvoung): Handle fdata-sections.
314 IceString SectionName; 309 IceString SectionName;
315 Elf64_Xword ShAddralign = 1; 310 Elf64_Xword ShAddralign = 1;
316 for (VariableDeclaration *Var : Vars) { 311 for (VariableDeclaration *Var : Vars) {
317 Elf64_Xword Align = Var->getAlignment(); 312 Elf64_Xword Align = Var->getAlignment();
318 ShAddralign = std::max(ShAddralign, Align); 313 ShAddralign = std::max(ShAddralign, Align);
319 } 314 }
320 const Elf64_Xword ShEntsize = 0; // non-uniform data element size. 315 const Elf64_Xword ShEntsize = 0; // non-uniform data element size.
321 // Lift this out, so it can be re-used if we do fdata-sections? 316 // Lift this out, so it can be re-used if we do fdata-sections?
322 switch (ST) { 317 switch (ST) {
323 case ROData: { 318 case ROData: {
324 SectionName = ".rodata"; 319 SectionName = ".rodata";
325 // Only expecting to write the data sections all in one shot for now. 320 // Only expecting to write the data sections all in one shot for now.
326 assert(RODataSections.empty()); 321 assert(RODataSections.empty());
327 const Elf64_Xword ShFlags = SHF_ALLOC; 322 const Elf64_Xword ShFlags = SHF_ALLOC;
328 Section = createSection<ELFDataSection>(SectionName, SHT_PROGBITS, ShFlags, 323 Section = createSection<ELFDataSection>(SectionName, SHT_PROGBITS, ShFlags,
329 ShAddralign, ShEntsize); 324 ShAddralign, ShEntsize);
330 Section->setFileOffset(alignFileOffset(ShAddralign)); 325 Section->setFileOffset(alignFileOffset(ShAddralign));
331 RODataSections.push_back(Section); 326 RODataSections.push_back(Section);
332 RelSection = createRelocationSection(IsELF64, Section); 327 RelSection = createRelocationSection(Section);
333 RelRODataSections.push_back(RelSection); 328 RelRODataSections.push_back(RelSection);
334 break; 329 break;
335 } 330 }
336 case Data: { 331 case Data: {
337 SectionName = ".data"; 332 SectionName = ".data";
338 assert(DataSections.empty()); 333 assert(DataSections.empty());
339 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_WRITE; 334 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_WRITE;
340 Section = createSection<ELFDataSection>(SectionName, SHT_PROGBITS, ShFlags, 335 Section = createSection<ELFDataSection>(SectionName, SHT_PROGBITS, ShFlags,
341 ShAddralign, ShEntsize); 336 ShAddralign, ShEntsize);
342 Section->setFileOffset(alignFileOffset(ShAddralign)); 337 Section->setFileOffset(alignFileOffset(ShAddralign));
343 DataSections.push_back(Section); 338 DataSections.push_back(Section);
344 RelSection = createRelocationSection(IsELF64, Section); 339 RelSection = createRelocationSection(Section);
345 RelDataSections.push_back(RelSection); 340 RelDataSections.push_back(RelSection);
346 break; 341 break;
347 } 342 }
348 case BSS: { 343 case BSS: {
349 SectionName = ".bss"; 344 SectionName = ".bss";
350 assert(BSSSections.empty()); 345 assert(BSSSections.empty());
351 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_WRITE; 346 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_WRITE;
352 Section = createSection<ELFDataSection>(SectionName, SHT_NOBITS, ShFlags, 347 Section = createSection<ELFDataSection>(SectionName, SHT_NOBITS, ShFlags,
353 ShAddralign, ShEntsize); 348 ShAddralign, ShEntsize);
354 Section->setFileOffset(alignFileOffset(ShAddralign)); 349 Section->setFileOffset(alignFileOffset(ShAddralign));
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
415 } 410 }
416 } 411 }
417 } 412 }
418 } 413 }
419 414
420 void ELFObjectWriter::writeInitialELFHeader() { 415 void ELFObjectWriter::writeInitialELFHeader() {
421 assert(!SectionNumbersAssigned); 416 assert(!SectionNumbersAssigned);
422 const Elf64_Off DummySHOffset = 0; 417 const Elf64_Off DummySHOffset = 0;
423 const SizeT DummySHStrIndex = 0; 418 const SizeT DummySHStrIndex = 0;
424 const SizeT DummyNumSections = 0; 419 const SizeT DummyNumSections = 0;
425 if (isELF64(Ctx.getTargetArch())) { 420 if (ELF64) {
426 writeELFHeaderInternal<true>(DummySHOffset, DummySHStrIndex, 421 writeELFHeaderInternal<true>(DummySHOffset, DummySHStrIndex,
427 DummyNumSections); 422 DummyNumSections);
428 } else { 423 } else {
429 writeELFHeaderInternal<false>(DummySHOffset, DummySHStrIndex, 424 writeELFHeaderInternal<false>(DummySHOffset, DummySHStrIndex,
430 DummyNumSections); 425 DummyNumSections);
431 } 426 }
432 } 427 }
433 428
434 template <bool IsELF64> 429 template <bool IsELF64>
435 void ELFObjectWriter::writeELFHeaderInternal(Elf64_Off SectionHeaderOffset, 430 void ELFObjectWriter::writeELFHeaderInternal(Elf64_Off SectionHeaderOffset,
(...skipping 10 matching lines...) Expand all
446 Str.write8(ELF_ABIVersion); 441 Str.write8(ELF_ABIVersion);
447 Str.writeZeroPadding(EI_NIDENT - EI_PAD); 442 Str.writeZeroPadding(EI_NIDENT - EI_PAD);
448 443
449 // TODO(jvoung): Handle and test > 64K sections. See the generic ABI doc: 444 // TODO(jvoung): Handle and test > 64K sections. See the generic ABI doc:
450 // https://refspecs.linuxbase.org/elf/gabi4+/ch4.eheader.html 445 // https://refspecs.linuxbase.org/elf/gabi4+/ch4.eheader.html
451 // e_shnum should be 0 and then actual number of sections is 446 // e_shnum should be 0 and then actual number of sections is
452 // stored in the sh_size member of the 0th section. 447 // stored in the sh_size member of the 0th section.
453 assert(NumSections < SHN_LORESERVE); 448 assert(NumSections < SHN_LORESERVE);
454 assert(SectHeaderStrIndex < SHN_LORESERVE); 449 assert(SectHeaderStrIndex < SHN_LORESERVE);
455 450
451 const TargetArch Arch = Ctx.getFlags().getTargetArch();
456 // Write the rest of the file header, which does depend on byte order 452 // Write the rest of the file header, which does depend on byte order
457 // and ELF class. 453 // and ELF class.
458 Str.writeLE16(ET_REL); // e_type 454 Str.writeLE16(ET_REL); // e_type
459 Str.writeLE16(getELFMachine(Ctx.getTargetArch())); // e_machine 455 Str.writeLE16(getELFMachine(Ctx.getFlags().getTargetArch())); // e_machine
460 Str.writeELFWord<IsELF64>(1); // e_version 456 Str.writeELFWord<IsELF64>(1); // e_version
461 // Since this is for a relocatable object, there is no entry point, 457 // Since this is for a relocatable object, there is no entry point,
462 // and no program headers. 458 // and no program headers.
463 Str.writeAddrOrOffset<IsELF64>(0); // e_entry 459 Str.writeAddrOrOffset<IsELF64>(0); // e_entry
464 Str.writeAddrOrOffset<IsELF64>(0); // e_phoff 460 Str.writeAddrOrOffset<IsELF64>(0); // e_phoff
465 Str.writeAddrOrOffset<IsELF64>(SectionHeaderOffset); // e_shoff 461 Str.writeAddrOrOffset<IsELF64>(SectionHeaderOffset); // e_shoff
466 Str.writeELFWord<IsELF64>(getELFFlags(Ctx.getTargetArch())); // e_flags 462 Str.writeELFWord<IsELF64>(getELFFlags(Arch)); // e_flags
467 Str.writeLE16(IsELF64 ? sizeof(Elf64_Ehdr) : sizeof(Elf32_Ehdr)); // e_ehsize 463 Str.writeLE16(IsELF64 ? sizeof(Elf64_Ehdr) : sizeof(Elf32_Ehdr)); // e_ehsize
468 static_assert(sizeof(Elf64_Ehdr) == 64 && sizeof(Elf32_Ehdr) == 52, 464 static_assert(sizeof(Elf64_Ehdr) == 64 && sizeof(Elf32_Ehdr) == 52,
469 "Elf_Ehdr sizes cannot be derived from sizeof"); 465 "Elf_Ehdr sizes cannot be derived from sizeof");
470 Str.writeLE16(0); // e_phentsize 466 Str.writeLE16(0); // e_phentsize
471 Str.writeLE16(0); // e_phnum 467 Str.writeLE16(0); // e_phnum
472 Str.writeLE16(IsELF64 ? sizeof(Elf64_Shdr) 468 Str.writeLE16(IsELF64 ? sizeof(Elf64_Shdr)
473 : sizeof(Elf32_Shdr)); // e_shentsize 469 : sizeof(Elf32_Shdr)); // e_shentsize
474 static_assert(sizeof(Elf64_Shdr) == 64 && sizeof(Elf32_Shdr) == 40, 470 static_assert(sizeof(Elf64_Shdr) == 64 && sizeof(Elf32_Shdr) == 40,
475 "Elf_Shdr sizes cannot be derived from sizeof"); 471 "Elf_Shdr sizes cannot be derived from sizeof");
476 Str.writeLE16(static_cast<Elf64_Half>(NumSections)); // e_shnum 472 Str.writeLE16(static_cast<Elf64_Half>(NumSections)); // e_shnum
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
525 521
526 // Instantiate known needed versions of the template, since we are 522 // Instantiate known needed versions of the template, since we are
527 // defining the function in the .cpp file instead of the .h file. 523 // defining the function in the .cpp file instead of the .h file.
528 // We may need to instantiate constant pools for integers as well 524 // We may need to instantiate constant pools for integers as well
529 // if we do constant-pooling of large integers to remove them 525 // if we do constant-pooling of large integers to remove them
530 // from the instruction stream (fewer bytes controlled by an attacker). 526 // from the instruction stream (fewer bytes controlled by an attacker).
531 template void ELFObjectWriter::writeConstantPool<ConstantFloat>(Type Ty); 527 template void ELFObjectWriter::writeConstantPool<ConstantFloat>(Type Ty);
532 528
533 template void ELFObjectWriter::writeConstantPool<ConstantDouble>(Type Ty); 529 template void ELFObjectWriter::writeConstantPool<ConstantDouble>(Type Ty);
534 530
535 void ELFObjectWriter::writeAllRelocationSections(bool IsELF64) { 531 void ELFObjectWriter::writeAllRelocationSections() {
536 writeRelocationSections(IsELF64, RelTextSections); 532 writeRelocationSections(RelTextSections);
537 writeRelocationSections(IsELF64, RelDataSections); 533 writeRelocationSections(RelDataSections);
538 writeRelocationSections(IsELF64, RelRODataSections); 534 writeRelocationSections(RelRODataSections);
539 } 535 }
540 536
541 void ELFObjectWriter::setUndefinedSyms(const ConstantList &UndefSyms) { 537 void ELFObjectWriter::setUndefinedSyms(const ConstantList &UndefSyms) {
542 for (const Constant *S : UndefSyms) { 538 for (const Constant *S : UndefSyms) {
543 const auto Sym = llvm::cast<ConstantRelocatable>(S); 539 const auto Sym = llvm::cast<ConstantRelocatable>(S);
544 const IceString &Name = Sym->getName(); 540 const IceString &Name = Sym->getName();
545 bool BadIntrinsic; 541 bool BadIntrinsic;
546 const Intrinsics::FullIntrinsicInfo *Info = 542 const Intrinsics::FullIntrinsicInfo *Info =
547 Ctx.getIntrinsicsInfo().find(Name, BadIntrinsic); 543 Ctx.getIntrinsicsInfo().find(Name, BadIntrinsic);
548 if (Info) 544 if (Info)
549 continue; 545 continue;
550 assert(!BadIntrinsic); 546 assert(!BadIntrinsic);
551 assert(Sym->getOffset() == 0); 547 assert(Sym->getOffset() == 0);
552 assert(Sym->getSuppressMangling()); 548 assert(Sym->getSuppressMangling());
553 SymTab->noteUndefinedSym(Name, NullSection); 549 SymTab->noteUndefinedSym(Name, NullSection);
554 StrTab->add(Name); 550 StrTab->add(Name);
555 } 551 }
556 } 552 }
557 553
558 void ELFObjectWriter::writeRelocationSections(bool IsELF64, 554 void ELFObjectWriter::writeRelocationSections(RelSectionList &RelSections) {
559 RelSectionList &RelSections) {
560 for (ELFRelocationSection *RelSec : RelSections) { 555 for (ELFRelocationSection *RelSec : RelSections) {
561 Elf64_Off Offset = alignFileOffset(RelSec->getSectionAlign()); 556 Elf64_Off Offset = alignFileOffset(RelSec->getSectionAlign());
562 RelSec->setFileOffset(Offset); 557 RelSec->setFileOffset(Offset);
563 RelSec->setSize(RelSec->getSectionDataSize()); 558 RelSec->setSize(RelSec->getSectionDataSize());
564 if (IsELF64) { 559 if (ELF64) {
565 RelSec->writeData<true>(Ctx, Str, SymTab); 560 RelSec->writeData<true>(Ctx, Str, SymTab);
566 } else { 561 } else {
567 RelSec->writeData<false>(Ctx, Str, SymTab); 562 RelSec->writeData<false>(Ctx, Str, SymTab);
568 } 563 }
569 } 564 }
570 } 565 }
571 566
572 void ELFObjectWriter::writeNonUserSections() { 567 void ELFObjectWriter::writeNonUserSections() {
573 bool IsELF64 = isELF64(Ctx.getTargetArch());
574
575 // Write out the shstrtab now that all sections are known. 568 // Write out the shstrtab now that all sections are known.
576 ShStrTab->doLayout(); 569 ShStrTab->doLayout();
577 ShStrTab->setSize(ShStrTab->getSectionDataSize()); 570 ShStrTab->setSize(ShStrTab->getSectionDataSize());
578 Elf64_Off ShStrTabOffset = alignFileOffset(ShStrTab->getSectionAlign()); 571 Elf64_Off ShStrTabOffset = alignFileOffset(ShStrTab->getSectionAlign());
579 ShStrTab->setFileOffset(ShStrTabOffset); 572 ShStrTab->setFileOffset(ShStrTabOffset);
580 Str.writeBytes(ShStrTab->getSectionData()); 573 Str.writeBytes(ShStrTab->getSectionData());
581 574
582 SectionList AllSections; 575 SectionList AllSections;
583 assignSectionNumbersInfo(AllSections); 576 assignSectionNumbersInfo(AllSections);
584 577
585 // Finalize the regular StrTab and fix up references in the SymTab. 578 // Finalize the regular StrTab and fix up references in the SymTab.
586 StrTab->doLayout(); 579 StrTab->doLayout();
587 StrTab->setSize(StrTab->getSectionDataSize()); 580 StrTab->setSize(StrTab->getSectionDataSize());
588 581
589 SymTab->updateIndices(StrTab); 582 SymTab->updateIndices(StrTab);
590 583
591 Elf64_Off SymTabOffset = alignFileOffset(SymTab->getSectionAlign()); 584 Elf64_Off SymTabOffset = alignFileOffset(SymTab->getSectionAlign());
592 SymTab->setFileOffset(SymTabOffset); 585 SymTab->setFileOffset(SymTabOffset);
593 SymTab->setSize(SymTab->getSectionDataSize()); 586 SymTab->setSize(SymTab->getSectionDataSize());
594 SymTab->writeData(Str, IsELF64); 587 SymTab->writeData(Str, ELF64);
595 588
596 Elf64_Off StrTabOffset = alignFileOffset(StrTab->getSectionAlign()); 589 Elf64_Off StrTabOffset = alignFileOffset(StrTab->getSectionAlign());
597 StrTab->setFileOffset(StrTabOffset); 590 StrTab->setFileOffset(StrTabOffset);
598 Str.writeBytes(StrTab->getSectionData()); 591 Str.writeBytes(StrTab->getSectionData());
599 592
600 writeAllRelocationSections(IsELF64); 593 writeAllRelocationSections();
601 594
602 // Write out the section headers. 595 // Write out the section headers.
603 const size_t ShdrAlign = IsELF64 ? 8 : 4; 596 const size_t ShdrAlign = ELF64 ? 8 : 4;
604 Elf64_Off ShOffset = alignFileOffset(ShdrAlign); 597 Elf64_Off ShOffset = alignFileOffset(ShdrAlign);
605 for (const auto S : AllSections) { 598 for (const auto S : AllSections) {
606 if (IsELF64) 599 if (ELF64)
607 S->writeHeader<true>(Str); 600 S->writeHeader<true>(Str);
608 else 601 else
609 S->writeHeader<false>(Str); 602 S->writeHeader<false>(Str);
610 } 603 }
611 604
612 // Finally write the updated ELF header w/ the correct number of sections. 605 // Finally write the updated ELF header w/ the correct number of sections.
613 Str.seek(0); 606 Str.seek(0);
614 if (IsELF64) { 607 if (ELF64) {
615 writeELFHeaderInternal<true>(ShOffset, ShStrTab->getNumber(), 608 writeELFHeaderInternal<true>(ShOffset, ShStrTab->getNumber(),
616 AllSections.size()); 609 AllSections.size());
617 } else { 610 } else {
618 writeELFHeaderInternal<false>(ShOffset, ShStrTab->getNumber(), 611 writeELFHeaderInternal<false>(ShOffset, ShStrTab->getNumber(),
619 AllSections.size()); 612 AllSections.size());
620 } 613 }
621 } 614 }
622 615
623 } // end of namespace Ice 616 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceELFObjectWriter.h ('k') | src/IceGlobalContext.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698