| 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 /// \file | 10 /// \file |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 // Choice of RELA vs REL is actually separate from elf64 vs elf32, but in | 108 // Choice of RELA vs REL is actually separate from elf64 vs elf32, but in |
| 109 // practice we've only had .rela for elf64 (x86-64). In the future, the two | 109 // practice we've only had .rela for elf64 (x86-64). In the future, the two |
| 110 // properties may need to be decoupled and the ShEntSize can vary more. | 110 // properties may need to be decoupled and the ShEntSize can vary more. |
| 111 const Elf64_Word ShType = ELF64 ? SHT_RELA : SHT_REL; | 111 const Elf64_Word ShType = ELF64 ? SHT_RELA : SHT_REL; |
| 112 IceString RelPrefix = ELF64 ? ".rela" : ".rel"; | 112 IceString RelPrefix = ELF64 ? ".rela" : ".rel"; |
| 113 IceString RelSectionName = RelPrefix + RelatedSection->getName(); | 113 IceString RelSectionName = RelPrefix + RelatedSection->getName(); |
| 114 const Elf64_Xword ShAlign = ELF64 ? 8 : 4; | 114 const Elf64_Xword ShAlign = ELF64 ? 8 : 4; |
| 115 const Elf64_Xword ShEntSize = ELF64 ? sizeof(Elf64_Rela) : sizeof(Elf32_Rel); | 115 const Elf64_Xword ShEntSize = ELF64 ? sizeof(Elf64_Rela) : sizeof(Elf32_Rel); |
| 116 static_assert(sizeof(Elf64_Rela) == 24 && sizeof(Elf32_Rel) == 8, | 116 static_assert(sizeof(Elf64_Rela) == 24 && sizeof(Elf32_Rel) == 8, |
| 117 "Elf_Rel/Rela sizes cannot be derived from sizeof"); | 117 "Elf_Rel/Rela sizes cannot be derived from sizeof"); |
| 118 const Elf64_Xword ShFlags = 0; | 118 constexpr Elf64_Xword ShFlags = 0; |
| 119 ELFRelocationSection *RelSection = createSection<ELFRelocationSection>( | 119 ELFRelocationSection *RelSection = createSection<ELFRelocationSection>( |
| 120 RelSectionName, ShType, ShFlags, ShAlign, ShEntSize); | 120 RelSectionName, ShType, ShFlags, ShAlign, ShEntSize); |
| 121 RelSection->setRelatedSection(RelatedSection); | 121 RelSection->setRelatedSection(RelatedSection); |
| 122 return RelSection; | 122 return RelSection; |
| 123 } | 123 } |
| 124 | 124 |
| 125 template <typename UserSectionList> | 125 template <typename UserSectionList> |
| 126 void ELFObjectWriter::assignRelSectionNumInPairs(SizeT &CurSectionNumber, | 126 void ELFObjectWriter::assignRelSectionNumInPairs(SizeT &CurSectionNumber, |
| 127 UserSectionList &UserSections, | 127 UserSectionList &UserSections, |
| 128 RelSectionList &RelSections, | 128 RelSectionList &RelSections, |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 211 void ELFObjectWriter::writeFunctionCode(const IceString &FuncName, | 211 void ELFObjectWriter::writeFunctionCode(const IceString &FuncName, |
| 212 bool IsInternal, const Assembler *Asm) { | 212 bool IsInternal, const Assembler *Asm) { |
| 213 assert(!SectionNumbersAssigned); | 213 assert(!SectionNumbersAssigned); |
| 214 ELFTextSection *Section = nullptr; | 214 ELFTextSection *Section = nullptr; |
| 215 ELFRelocationSection *RelSection = nullptr; | 215 ELFRelocationSection *RelSection = nullptr; |
| 216 const bool FunctionSections = Ctx.getFlags().getFunctionSections(); | 216 const bool FunctionSections = Ctx.getFlags().getFunctionSections(); |
| 217 if (TextSections.empty() || FunctionSections) { | 217 if (TextSections.empty() || FunctionSections) { |
| 218 IceString SectionName = ".text"; | 218 IceString SectionName = ".text"; |
| 219 if (FunctionSections) | 219 if (FunctionSections) |
| 220 SectionName += "." + FuncName; | 220 SectionName += "." + FuncName; |
| 221 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_EXECINSTR; | 221 constexpr Elf64_Xword ShFlags = SHF_ALLOC | SHF_EXECINSTR; |
| 222 const Elf64_Xword ShAlign = 1 << Asm->getBundleAlignLog2Bytes(); | 222 const Elf64_Xword ShAlign = 1 << Asm->getBundleAlignLog2Bytes(); |
| 223 Section = createSection<ELFTextSection>(SectionName, SHT_PROGBITS, ShFlags, | 223 Section = createSection<ELFTextSection>(SectionName, SHT_PROGBITS, ShFlags, |
| 224 ShAlign, 0); | 224 ShAlign, 0); |
| 225 Elf64_Off OffsetInFile = alignFileOffset(Section->getSectionAlign()); | 225 Elf64_Off OffsetInFile = alignFileOffset(Section->getSectionAlign()); |
| 226 Section->setFileOffset(OffsetInFile); | 226 Section->setFileOffset(OffsetInFile); |
| 227 TextSections.push_back(Section); | 227 TextSections.push_back(Section); |
| 228 RelSection = createRelocationSection(Section); | 228 RelSection = createRelocationSection(Section); |
| 229 RelTextSections.push_back(RelSection); | 229 RelTextSections.push_back(RelSection); |
| 230 } else { | 230 } else { |
| 231 Section = TextSections[0]; | 231 Section = TextSections[0]; |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 if (Vars.empty()) | 315 if (Vars.empty()) |
| 316 return; | 316 return; |
| 317 ELFDataSection *Section; | 317 ELFDataSection *Section; |
| 318 ELFRelocationSection *RelSection; | 318 ELFRelocationSection *RelSection; |
| 319 IceString SectionName; | 319 IceString SectionName; |
| 320 Elf64_Xword ShAddralign = 1; | 320 Elf64_Xword ShAddralign = 1; |
| 321 for (VariableDeclaration *Var : Vars) { | 321 for (VariableDeclaration *Var : Vars) { |
| 322 Elf64_Xword Align = Var->getAlignment(); | 322 Elf64_Xword Align = Var->getAlignment(); |
| 323 ShAddralign = std::max(ShAddralign, Align); | 323 ShAddralign = std::max(ShAddralign, Align); |
| 324 } | 324 } |
| 325 const Elf64_Xword ShEntsize = 0; // non-uniform data element size. | 325 constexpr Elf64_Xword ShEntsize = 0; // non-uniform data element size. |
| 326 // Lift this out, so it can be re-used if we do fdata-sections? | 326 // Lift this out, so it can be re-used if we do fdata-sections? |
| 327 switch (ST) { | 327 switch (ST) { |
| 328 case ROData: { | 328 case ROData: { |
| 329 const IceString SectionName = MangleSectionName(".rodata", SectionSuffix); | 329 const IceString SectionName = MangleSectionName(".rodata", SectionSuffix); |
| 330 const Elf64_Xword ShFlags = SHF_ALLOC; | 330 constexpr Elf64_Xword ShFlags = SHF_ALLOC; |
| 331 Section = createSection<ELFDataSection>(SectionName, SHT_PROGBITS, ShFlags, | 331 Section = createSection<ELFDataSection>(SectionName, SHT_PROGBITS, ShFlags, |
| 332 ShAddralign, ShEntsize); | 332 ShAddralign, ShEntsize); |
| 333 Section->setFileOffset(alignFileOffset(ShAddralign)); | 333 Section->setFileOffset(alignFileOffset(ShAddralign)); |
| 334 RODataSections.push_back(Section); | 334 RODataSections.push_back(Section); |
| 335 RelSection = createRelocationSection(Section); | 335 RelSection = createRelocationSection(Section); |
| 336 RelRODataSections.push_back(RelSection); | 336 RelRODataSections.push_back(RelSection); |
| 337 break; | 337 break; |
| 338 } | 338 } |
| 339 case Data: { | 339 case Data: { |
| 340 const IceString SectionName = MangleSectionName(".data", SectionSuffix); | 340 const IceString SectionName = MangleSectionName(".data", SectionSuffix); |
| 341 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_WRITE; | 341 constexpr Elf64_Xword ShFlags = SHF_ALLOC | SHF_WRITE; |
| 342 Section = createSection<ELFDataSection>(SectionName, SHT_PROGBITS, ShFlags, | 342 Section = createSection<ELFDataSection>(SectionName, SHT_PROGBITS, ShFlags, |
| 343 ShAddralign, ShEntsize); | 343 ShAddralign, ShEntsize); |
| 344 Section->setFileOffset(alignFileOffset(ShAddralign)); | 344 Section->setFileOffset(alignFileOffset(ShAddralign)); |
| 345 DataSections.push_back(Section); | 345 DataSections.push_back(Section); |
| 346 RelSection = createRelocationSection(Section); | 346 RelSection = createRelocationSection(Section); |
| 347 RelDataSections.push_back(RelSection); | 347 RelDataSections.push_back(RelSection); |
| 348 break; | 348 break; |
| 349 } | 349 } |
| 350 case BSS: { | 350 case BSS: { |
| 351 const IceString SectionName = MangleSectionName(".bss", SectionSuffix); | 351 const IceString SectionName = MangleSectionName(".bss", SectionSuffix); |
| 352 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_WRITE; | 352 constexpr Elf64_Xword ShFlags = SHF_ALLOC | SHF_WRITE; |
| 353 Section = createSection<ELFDataSection>(SectionName, SHT_NOBITS, ShFlags, | 353 Section = createSection<ELFDataSection>(SectionName, SHT_NOBITS, ShFlags, |
| 354 ShAddralign, ShEntsize); | 354 ShAddralign, ShEntsize); |
| 355 Section->setFileOffset(alignFileOffset(ShAddralign)); | 355 Section->setFileOffset(alignFileOffset(ShAddralign)); |
| 356 BSSSections.push_back(Section); | 356 BSSSections.push_back(Section); |
| 357 break; | 357 break; |
| 358 } | 358 } |
| 359 case NumSectionTypes: | 359 case NumSectionTypes: |
| 360 llvm::report_fatal_error("Unknown SectionType"); | 360 llvm::report_fatal_error("Unknown SectionType"); |
| 361 break; | 361 break; |
| 362 } | 362 } |
| 363 | 363 |
| 364 const uint8_t SymbolType = STT_OBJECT; | 364 constexpr uint8_t SymbolType = STT_OBJECT; |
| 365 for (VariableDeclaration *Var : Vars) { | 365 for (VariableDeclaration *Var : Vars) { |
| 366 // If the variable declaration does not have an initializer, its symtab | 366 // If the variable declaration does not have an initializer, its symtab |
| 367 // entry will be created separately. | 367 // entry will be created separately. |
| 368 if (!Var->hasInitializer()) | 368 if (!Var->hasInitializer()) |
| 369 continue; | 369 continue; |
| 370 Elf64_Xword Align = Var->getAlignment(); | 370 Elf64_Xword Align = Var->getAlignment(); |
| 371 const Elf64_Xword MinAlign = 1; | 371 constexpr Elf64_Xword MinAlign = 1; |
| 372 Align = std::max(Align, MinAlign); | 372 Align = std::max(Align, MinAlign); |
| 373 Section->padToAlignment(Str, Align); | 373 Section->padToAlignment(Str, Align); |
| 374 SizeT SymbolSize = Var->getNumBytes(); | 374 SizeT SymbolSize = Var->getNumBytes(); |
| 375 bool IsExternal = Var->isExternal() || Ctx.getFlags().getDisableInternal(); | 375 bool IsExternal = Var->isExternal() || Ctx.getFlags().getDisableInternal(); |
| 376 const uint8_t SymbolBinding = IsExternal ? STB_GLOBAL : STB_LOCAL; | 376 const uint8_t SymbolBinding = IsExternal ? STB_GLOBAL : STB_LOCAL; |
| 377 IceString MangledName = Var->mangleName(&Ctx); | 377 IceString MangledName = Var->mangleName(&Ctx); |
| 378 SymTab->createDefinedSym(MangledName, SymbolType, SymbolBinding, Section, | 378 SymTab->createDefinedSym(MangledName, SymbolType, SymbolBinding, Section, |
| 379 Section->getCurrentSize(), SymbolSize); | 379 Section->getCurrentSize(), SymbolSize); |
| 380 StrTab->add(MangledName); | 380 StrTab->add(MangledName); |
| 381 if (!Var->hasNonzeroInitializer()) { | 381 if (!Var->hasNonzeroInitializer()) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 398 } | 398 } |
| 399 case VariableDeclaration::Initializer::ZeroInitializerKind: | 399 case VariableDeclaration::Initializer::ZeroInitializerKind: |
| 400 Section->appendZeros(Str, Init->getNumBytes()); | 400 Section->appendZeros(Str, Init->getNumBytes()); |
| 401 break; | 401 break; |
| 402 case VariableDeclaration::Initializer::RelocInitializerKind: { | 402 case VariableDeclaration::Initializer::RelocInitializerKind: { |
| 403 const auto Reloc = | 403 const auto Reloc = |
| 404 llvm::cast<VariableDeclaration::RelocInitializer>(Init.get()); | 404 llvm::cast<VariableDeclaration::RelocInitializer>(Init.get()); |
| 405 AssemblerFixup NewFixup; | 405 AssemblerFixup NewFixup; |
| 406 NewFixup.set_position(Section->getCurrentSize()); | 406 NewFixup.set_position(Section->getCurrentSize()); |
| 407 NewFixup.set_kind(RelocationKind); | 407 NewFixup.set_kind(RelocationKind); |
| 408 const bool SuppressMangling = true; | 408 constexpr bool SuppressMangling = true; |
| 409 NewFixup.set_value(Ctx.getConstantSym( | 409 NewFixup.set_value(Ctx.getConstantSym( |
| 410 Reloc->getOffset(), Reloc->getDeclaration()->mangleName(&Ctx), | 410 Reloc->getOffset(), Reloc->getDeclaration()->mangleName(&Ctx), |
| 411 SuppressMangling)); | 411 SuppressMangling)); |
| 412 RelSection->addRelocation(NewFixup); | 412 RelSection->addRelocation(NewFixup); |
| 413 Section->appendRelocationOffset(Str, RelSection->isRela(), | 413 Section->appendRelocationOffset(Str, RelSection->isRela(), |
| 414 Reloc->getOffset()); | 414 Reloc->getOffset()); |
| 415 break; | 415 break; |
| 416 } | 416 } |
| 417 } | 417 } |
| 418 } | 418 } |
| 419 } | 419 } |
| 420 } | 420 } |
| 421 } | 421 } |
| 422 | 422 |
| 423 void ELFObjectWriter::writeInitialELFHeader() { | 423 void ELFObjectWriter::writeInitialELFHeader() { |
| 424 assert(!SectionNumbersAssigned); | 424 assert(!SectionNumbersAssigned); |
| 425 const Elf64_Off DummySHOffset = 0; | 425 constexpr Elf64_Off DummySHOffset = 0; |
| 426 const SizeT DummySHStrIndex = 0; | 426 constexpr SizeT DummySHStrIndex = 0; |
| 427 const SizeT DummyNumSections = 0; | 427 constexpr SizeT DummyNumSections = 0; |
| 428 if (ELF64) { | 428 if (ELF64) { |
| 429 writeELFHeaderInternal<true>(DummySHOffset, DummySHStrIndex, | 429 writeELFHeaderInternal<true>(DummySHOffset, DummySHStrIndex, |
| 430 DummyNumSections); | 430 DummyNumSections); |
| 431 } else { | 431 } else { |
| 432 writeELFHeaderInternal<false>(DummySHOffset, DummySHStrIndex, | 432 writeELFHeaderInternal<false>(DummySHOffset, DummySHStrIndex, |
| 433 DummyNumSections); | 433 DummyNumSections); |
| 434 } | 434 } |
| 435 } | 435 } |
| 436 | 436 |
| 437 template <bool IsELF64> | 437 template <bool IsELF64> |
| 438 void ELFObjectWriter::writeELFHeaderInternal(Elf64_Off SectionHeaderOffset, | 438 void ELFObjectWriter::writeELFHeaderInternal(Elf64_Off SectionHeaderOffset, |
| 439 SizeT SectHeaderStrIndex, | 439 SizeT SectHeaderStrIndex, |
| 440 SizeT NumSections) { | 440 SizeT NumSections) { |
| 441 // Write the e_ident: magic number, class, etc. The e_ident is byte order and | 441 // Write the e_ident: magic number, class, etc. The e_ident is byte order and |
| 442 // ELF class independent. | 442 // ELF class independent. |
| 443 Str.writeBytes(llvm::StringRef(ElfMagic, strlen(ElfMagic))); | 443 Str.writeBytes(llvm::StringRef(ElfMagic, strlen(ElfMagic))); |
| 444 Str.write8(IsELF64 ? ELFCLASS64 : ELFCLASS32); | 444 Str.write8(IsELF64 ? ELFCLASS64 : ELFCLASS32); |
| 445 Str.write8(ELFDATA2LSB); | 445 Str.write8(ELFDATA2LSB); |
| 446 Str.write8(EV_CURRENT); | 446 Str.write8(EV_CURRENT); |
| 447 Str.write8(ELFOSABI_NONE); | 447 Str.write8(ELFOSABI_NONE); |
| 448 const uint8_t ELF_ABIVersion = 0; | 448 constexpr uint8_t ELF_ABIVersion = 0; |
| 449 Str.write8(ELF_ABIVersion); | 449 Str.write8(ELF_ABIVersion); |
| 450 Str.writeZeroPadding(EI_NIDENT - EI_PAD); | 450 Str.writeZeroPadding(EI_NIDENT - EI_PAD); |
| 451 | 451 |
| 452 // TODO(jvoung): Handle and test > 64K sections. See the generic ABI doc: | 452 // TODO(jvoung): Handle and test > 64K sections. See the generic ABI doc: |
| 453 // https://refspecs.linuxbase.org/elf/gabi4+/ch4.eheader.html e_shnum should | 453 // https://refspecs.linuxbase.org/elf/gabi4+/ch4.eheader.html e_shnum should |
| 454 // be 0 and then actual number of sections is stored in the sh_size member of | 454 // be 0 and then actual number of sections is stored in the sh_size member of |
| 455 // the 0th section. | 455 // the 0th section. |
| 456 assert(NumSections < SHN_LORESERVE); | 456 assert(NumSections < SHN_LORESERVE); |
| 457 assert(SectHeaderStrIndex < SHN_LORESERVE); | 457 assert(SectHeaderStrIndex < SHN_LORESERVE); |
| 458 | 458 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 488 } | 488 } |
| 489 SizeT Align = typeAlignInBytes(Ty); | 489 SizeT Align = typeAlignInBytes(Ty); |
| 490 size_t EntSize = typeWidthInBytes(Ty); | 490 size_t EntSize = typeWidthInBytes(Ty); |
| 491 char Buf[20]; | 491 char Buf[20]; |
| 492 SizeT WriteAmt = std::min(EntSize, llvm::array_lengthof(Buf)); | 492 SizeT WriteAmt = std::min(EntSize, llvm::array_lengthof(Buf)); |
| 493 // Check that we write the full PrimType. | 493 // Check that we write the full PrimType. |
| 494 assert(WriteAmt == EntSize); | 494 assert(WriteAmt == EntSize); |
| 495 // Assume that writing WriteAmt bytes at a time allows us to avoid aligning | 495 // Assume that writing WriteAmt bytes at a time allows us to avoid aligning |
| 496 // between entries. | 496 // between entries. |
| 497 assert(WriteAmt % Align == 0); | 497 assert(WriteAmt % Align == 0); |
| 498 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_MERGE; | 498 constexpr Elf64_Xword ShFlags = SHF_ALLOC | SHF_MERGE; |
| 499 std::string SecBuffer; | 499 std::string SecBuffer; |
| 500 llvm::raw_string_ostream SecStrBuf(SecBuffer); | 500 llvm::raw_string_ostream SecStrBuf(SecBuffer); |
| 501 SecStrBuf << ".rodata.cst" << WriteAmt; | 501 SecStrBuf << ".rodata.cst" << WriteAmt; |
| 502 ELFDataSection *Section = createSection<ELFDataSection>( | 502 ELFDataSection *Section = createSection<ELFDataSection>( |
| 503 SecStrBuf.str(), SHT_PROGBITS, ShFlags, Align, WriteAmt); | 503 SecStrBuf.str(), SHT_PROGBITS, ShFlags, Align, WriteAmt); |
| 504 RODataSections.push_back(Section); | 504 RODataSections.push_back(Section); |
| 505 SizeT OffsetInSection = 0; | 505 SizeT OffsetInSection = 0; |
| 506 // The symbol table entry doesn't need to know the defined symbol's size | 506 // The symbol table entry doesn't need to know the defined symbol's size |
| 507 // since this is in a section with a fixed Entry Size. | 507 // since this is in a section with a fixed Entry Size. |
| 508 const SizeT SymbolSize = 0; | 508 constexpr SizeT SymbolSize = 0; |
| 509 Section->setFileOffset(alignFileOffset(Align)); | 509 Section->setFileOffset(alignFileOffset(Align)); |
| 510 | 510 |
| 511 // If the -reorder-pooled-constant option is set to true, we should shuffle | 511 // If the -reorder-pooled-constant option is set to true, we should shuffle |
| 512 // the constants before we emit them. | 512 // the constants before we emit them. |
| 513 if (Ctx.getFlags().shouldReorderPooledConstants() && !Pool.empty()) { | 513 if (Ctx.getFlags().shouldReorderPooledConstants() && !Pool.empty()) { |
| 514 // Use the constant's kind value as the salt for creating random number | 514 // Use the constant's kind value as the salt for creating random number |
| 515 // generator. | 515 // generator. |
| 516 Operand::OperandKind K = (*Pool.begin())->getKind(); | 516 Operand::OperandKind K = (*Pool.begin())->getKind(); |
| 517 RandomNumberGenerator RNG(Ctx.getFlags().getRandomSeed(), | 517 RandomNumberGenerator RNG(Ctx.getFlags().getRandomSeed(), |
| 518 RPE_PooledConstantReordering, K); | 518 RPE_PooledConstantReordering, K); |
| 519 RandomShuffle(Pool.begin(), Pool.end(), | 519 RandomShuffle(Pool.begin(), Pool.end(), |
| 520 [&RNG](uint64_t N) { return (uint32_t)RNG.next(N); }); | 520 [&RNG](uint64_t N) { return (uint32_t)RNG.next(N); }); |
| 521 } | 521 } |
| 522 // Write the data. | 522 // Write the data. |
| 523 for (Constant *C : Pool) { | 523 for (Constant *C : Pool) { |
| 524 if (!C->getShouldBePooled()) | 524 if (!C->getShouldBePooled()) |
| 525 continue; | 525 continue; |
| 526 auto Const = llvm::cast<ConstType>(C); | 526 auto *Const = llvm::cast<ConstType>(C); |
| 527 std::string SymBuffer; | 527 std::string SymBuffer; |
| 528 llvm::raw_string_ostream SymStrBuf(SymBuffer); | 528 llvm::raw_string_ostream SymStrBuf(SymBuffer); |
| 529 Const->emitPoolLabel(SymStrBuf, &Ctx); | 529 Const->emitPoolLabel(SymStrBuf, &Ctx); |
| 530 std::string &SymName = SymStrBuf.str(); | 530 std::string &SymName = SymStrBuf.str(); |
| 531 SymTab->createDefinedSym(SymName, STT_NOTYPE, STB_LOCAL, Section, | 531 SymTab->createDefinedSym(SymName, STT_NOTYPE, STB_LOCAL, Section, |
| 532 OffsetInSection, SymbolSize); | 532 OffsetInSection, SymbolSize); |
| 533 StrTab->add(SymName); | 533 StrTab->add(SymName); |
| 534 typename ConstType::PrimType Value = Const->getValue(); | 534 typename ConstType::PrimType Value = Const->getValue(); |
| 535 memcpy(Buf, &Value, WriteAmt); | 535 memcpy(Buf, &Value, WriteAmt); |
| 536 Str.writeBytes(llvm::StringRef(Buf, WriteAmt)); | 536 Str.writeBytes(llvm::StringRef(Buf, WriteAmt)); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 565 const Elf64_Xword ShEntsize = PointerSize; | 565 const Elf64_Xword ShEntsize = PointerSize; |
| 566 const IceString SectionName = | 566 const IceString SectionName = |
| 567 MangleSectionName(".rodata", JT.getFunctionName() + "$jumptable"); | 567 MangleSectionName(".rodata", JT.getFunctionName() + "$jumptable"); |
| 568 Section = createSection<ELFDataSection>(SectionName, SHT_PROGBITS, SHF_ALLOC, | 568 Section = createSection<ELFDataSection>(SectionName, SHT_PROGBITS, SHF_ALLOC, |
| 569 ShAddralign, ShEntsize); | 569 ShAddralign, ShEntsize); |
| 570 Section->setFileOffset(alignFileOffset(ShAddralign)); | 570 Section->setFileOffset(alignFileOffset(ShAddralign)); |
| 571 RODataSections.push_back(Section); | 571 RODataSections.push_back(Section); |
| 572 RelSection = createRelocationSection(Section); | 572 RelSection = createRelocationSection(Section); |
| 573 RelRODataSections.push_back(RelSection); | 573 RelRODataSections.push_back(RelSection); |
| 574 | 574 |
| 575 const uint8_t SymbolType = STT_OBJECT; | 575 constexpr uint8_t SymbolType = STT_OBJECT; |
| 576 Section->padToAlignment(Str, PointerSize); | 576 Section->padToAlignment(Str, PointerSize); |
| 577 bool IsExternal = Ctx.getFlags().getDisableInternal(); | 577 bool IsExternal = Ctx.getFlags().getDisableInternal(); |
| 578 const uint8_t SymbolBinding = IsExternal ? STB_GLOBAL : STB_LOCAL; | 578 const uint8_t SymbolBinding = IsExternal ? STB_GLOBAL : STB_LOCAL; |
| 579 IceString JumpTableName = | 579 IceString JumpTableName = |
| 580 InstJumpTable::makeName(JT.getFunctionName(), JT.getId()); | 580 InstJumpTable::makeName(JT.getFunctionName(), JT.getId()); |
| 581 SymTab->createDefinedSym(JumpTableName, SymbolType, SymbolBinding, Section, | 581 SymTab->createDefinedSym(JumpTableName, SymbolType, SymbolBinding, Section, |
| 582 Section->getCurrentSize(), PointerSize); | 582 Section->getCurrentSize(), PointerSize); |
| 583 StrTab->add(JumpTableName); | 583 StrTab->add(JumpTableName); |
| 584 | 584 |
| 585 for (intptr_t TargetOffset : JT.getTargetOffsets()) { | 585 for (intptr_t TargetOffset : JT.getTargetOffsets()) { |
| 586 AssemblerFixup NewFixup; | 586 AssemblerFixup NewFixup; |
| 587 NewFixup.set_position(Section->getCurrentSize()); | 587 NewFixup.set_position(Section->getCurrentSize()); |
| 588 NewFixup.set_kind(RelocationKind); | 588 NewFixup.set_kind(RelocationKind); |
| 589 constexpr bool SuppressMangling = true; | 589 constexpr bool SuppressMangling = true; |
| 590 NewFixup.set_value(Ctx.getConstantSym(TargetOffset, JT.getFunctionName(), | 590 NewFixup.set_value(Ctx.getConstantSym(TargetOffset, JT.getFunctionName(), |
| 591 SuppressMangling)); | 591 SuppressMangling)); |
| 592 RelSection->addRelocation(NewFixup); | 592 RelSection->addRelocation(NewFixup); |
| 593 Section->appendRelocationOffset(Str, RelSection->isRela(), TargetOffset); | 593 Section->appendRelocationOffset(Str, RelSection->isRela(), TargetOffset); |
| 594 } | 594 } |
| 595 } | 595 } |
| 596 | 596 |
| 597 void ELFObjectWriter::setUndefinedSyms(const ConstantList &UndefSyms) { | 597 void ELFObjectWriter::setUndefinedSyms(const ConstantList &UndefSyms) { |
| 598 for (const Constant *S : UndefSyms) { | 598 for (const Constant *S : UndefSyms) { |
| 599 const auto Sym = llvm::cast<ConstantRelocatable>(S); | 599 const auto *Sym = llvm::cast<ConstantRelocatable>(S); |
| 600 const IceString &Name = Sym->getName(); | 600 const IceString &Name = Sym->getName(); |
| 601 bool BadIntrinsic; | 601 bool BadIntrinsic; |
| 602 const Intrinsics::FullIntrinsicInfo *Info = | 602 const Intrinsics::FullIntrinsicInfo *Info = |
| 603 Ctx.getIntrinsicsInfo().find(Name, BadIntrinsic); | 603 Ctx.getIntrinsicsInfo().find(Name, BadIntrinsic); |
| 604 if (Info) | 604 if (Info) |
| 605 continue; | 605 continue; |
| 606 // Ignore BadIntrinsic, which is set if the name begins with "llvm." but | 606 // Ignore BadIntrinsic, which is set if the name begins with "llvm." but |
| 607 // doesn't match a known intrinsic. If we want this to turn into an error, | 607 // doesn't match a known intrinsic. If we want this to turn into an error, |
| 608 // we should catch it early on. | 608 // we should catch it early on. |
| 609 assert(Sym->getOffset() == 0); | 609 assert(Sym->getOffset() == 0); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 669 if (ELF64) { | 669 if (ELF64) { |
| 670 writeELFHeaderInternal<true>(ShOffset, ShStrTab->getNumber(), | 670 writeELFHeaderInternal<true>(ShOffset, ShStrTab->getNumber(), |
| 671 AllSections.size()); | 671 AllSections.size()); |
| 672 } else { | 672 } else { |
| 673 writeELFHeaderInternal<false>(ShOffset, ShStrTab->getNumber(), | 673 writeELFHeaderInternal<false>(ShOffset, ShStrTab->getNumber(), |
| 674 AllSections.size()); | 674 AllSections.size()); |
| 675 } | 675 } |
| 676 } | 676 } |
| 677 | 677 |
| 678 } // end of namespace Ice | 678 } // end of namespace Ice |
| OLD | NEW |