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. |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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> |
|
jvoung (off chromium)
2015/03/20 20:47:10
I removed all the local "bool IsELF64 = isELF64(Ct
| |
| 435 void ELFObjectWriter::writeELFHeaderInternal(Elf64_Off SectionHeaderOffset, | 430 void ELFObjectWriter::writeELFHeaderInternal(Elf64_Off SectionHeaderOffset, |
| 436 SizeT SectHeaderStrIndex, | 431 SizeT SectHeaderStrIndex, |
| 437 SizeT NumSections) { | 432 SizeT NumSections) { |
| 438 // Write the e_ident: magic number, class, etc. | 433 // Write the e_ident: magic number, class, etc. |
| 439 // The e_ident is byte order and ELF class independent. | 434 // The e_ident is byte order and ELF class independent. |
| 440 Str.writeBytes(llvm::StringRef(ElfMagic, strlen(ElfMagic))); | 435 Str.writeBytes(llvm::StringRef(ElfMagic, strlen(ElfMagic))); |
| 441 Str.write8(IsELF64 ? ELFCLASS64 : ELFCLASS32); | 436 Str.write8(IsELF64 ? ELFCLASS64 : ELFCLASS32); |
| 442 Str.write8(ELFDATA2LSB); | 437 Str.write8(ELFDATA2LSB); |
| 443 Str.write8(EV_CURRENT); | 438 Str.write8(EV_CURRENT); |
| 444 Str.write8(ELFOSABI_NONE); | 439 Str.write8(ELFOSABI_NONE); |
| 445 const uint8_t ELF_ABIVersion = 0; | 440 const uint8_t ELF_ABIVersion = 0; |
| 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 |
| 456 // Write the rest of the file header, which does depend on byte order | 451 // Write the rest of the file header, which does depend on byte order |
| 457 // and ELF class. | 452 // and ELF class. |
| 458 Str.writeLE16(ET_REL); // e_type | 453 Str.writeLE16(ET_REL); // e_type |
| 459 Str.writeLE16(getELFMachine(Ctx.getTargetArch())); // e_machine | 454 Str.writeLE16(getELFMachine(Ctx.getFlags().getTargetArch())); // e_machine |
| 460 Str.writeELFWord<IsELF64>(1); // e_version | 455 Str.writeELFWord<IsELF64>(1); // e_version |
| 461 // Since this is for a relocatable object, there is no entry point, | 456 // Since this is for a relocatable object, there is no entry point, |
| 462 // and no program headers. | 457 // and no program headers. |
| 463 Str.writeAddrOrOffset<IsELF64>(0); // e_entry | 458 Str.writeAddrOrOffset<IsELF64>(0); // e_entry |
| 464 Str.writeAddrOrOffset<IsELF64>(0); // e_phoff | 459 Str.writeAddrOrOffset<IsELF64>(0); // e_phoff |
| 465 Str.writeAddrOrOffset<IsELF64>(SectionHeaderOffset); // e_shoff | 460 Str.writeAddrOrOffset<IsELF64>(SectionHeaderOffset); // e_shoff |
| 466 Str.writeELFWord<IsELF64>(getELFFlags(Ctx.getTargetArch())); // e_flags | 461 // e_flags |
| 462 Str.writeELFWord<IsELF64>(getELFFlags(Ctx.getFlags().getTargetArch())); | |
| 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 Loading... | |
| 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 |
| OLD | NEW |