| 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 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 return ELFTargetInfo[Arch].ELFFlags; | 69 return ELFTargetInfo[Arch].ELFFlags; |
| 70 llvm_unreachable("Invalid target arch for getELFFlags"); | 70 llvm_unreachable("Invalid target arch for getELFFlags"); |
| 71 return 0; | 71 return 0; |
| 72 } | 72 } |
| 73 | 73 |
| 74 } // end of anonymous namespace | 74 } // end of anonymous namespace |
| 75 | 75 |
| 76 ELFObjectWriter::ELFObjectWriter(GlobalContext &Ctx, ELFStreamer &Out) | 76 ELFObjectWriter::ELFObjectWriter(GlobalContext &Ctx, ELFStreamer &Out) |
| 77 : Ctx(Ctx), Str(Out), ELF64(isELF64(Ctx.getFlags())) { | 77 : Ctx(Ctx), Str(Out), ELF64(isELF64(Ctx.getFlags())) { |
| 78 // Create the special bookkeeping sections now. | 78 // Create the special bookkeeping sections now. |
| 79 const IceString NullSectionName(""); | 79 constexpr char NullSectionName[] = ""; |
| 80 NullSection = new (Ctx.allocate<ELFSection>()) | 80 NullSection = new (Ctx.allocate<ELFSection>()) |
| 81 ELFSection(NullSectionName, SHT_NULL, 0, 0, 0); | 81 ELFSection(NullSectionName, SHT_NULL, 0, 0, 0); |
| 82 | 82 |
| 83 const IceString ShStrTabName(".shstrtab"); | 83 constexpr char ShStrTabName[] = ".shstrtab"; |
| 84 ShStrTab = new (Ctx.allocate<ELFStringTableSection>()) | 84 ShStrTab = new (Ctx.allocate<ELFStringTableSection>()) |
| 85 ELFStringTableSection(ShStrTabName, SHT_STRTAB, 0, 1, 0); | 85 ELFStringTableSection(ShStrTabName, SHT_STRTAB, 0, 1, 0); |
| 86 ShStrTab->add(ShStrTabName); | 86 ShStrTab->add(ShStrTabName); |
| 87 | 87 |
| 88 const IceString SymTabName(".symtab"); | 88 constexpr char SymTabName[] = ".symtab"; |
| 89 const Elf64_Xword SymTabAlign = ELF64 ? 8 : 4; | 89 const Elf64_Xword SymTabAlign = ELF64 ? 8 : 4; |
| 90 const Elf64_Xword SymTabEntSize = | 90 const Elf64_Xword SymTabEntSize = |
| 91 ELF64 ? sizeof(Elf64_Sym) : sizeof(Elf32_Sym); | 91 ELF64 ? sizeof(Elf64_Sym) : sizeof(Elf32_Sym); |
| 92 static_assert(sizeof(Elf64_Sym) == 24 && sizeof(Elf32_Sym) == 16, | 92 static_assert(sizeof(Elf64_Sym) == 24 && sizeof(Elf32_Sym) == 16, |
| 93 "Elf_Sym sizes cannot be derived from sizeof"); | 93 "Elf_Sym sizes cannot be derived from sizeof"); |
| 94 SymTab = createSection<ELFSymbolTableSection>(SymTabName, SHT_SYMTAB, 0, | 94 SymTab = createSection<ELFSymbolTableSection>(SymTabName, SHT_SYMTAB, 0, |
| 95 SymTabAlign, SymTabEntSize); | 95 SymTabAlign, SymTabEntSize); |
| 96 SymTab->createNullSymbol(NullSection); | 96 SymTab->createNullSymbol(NullSection, &Ctx); |
| 97 | 97 |
| 98 const IceString StrTabName(".strtab"); | 98 constexpr char StrTabName[] = ".strtab"; |
| 99 StrTab = | 99 StrTab = |
| 100 createSection<ELFStringTableSection>(StrTabName, SHT_STRTAB, 0, 1, 0); | 100 createSection<ELFStringTableSection>(StrTabName, SHT_STRTAB, 0, 1, 0); |
| 101 } | 101 } |
| 102 | 102 |
| 103 template <typename T> | 103 template <typename T> |
| 104 T *ELFObjectWriter::createSection(const IceString &Name, Elf64_Word ShType, | 104 T *ELFObjectWriter::createSection(const std::string &Name, Elf64_Word ShType, |
| 105 Elf64_Xword ShFlags, Elf64_Xword ShAddralign, | 105 Elf64_Xword ShFlags, Elf64_Xword ShAddralign, |
| 106 Elf64_Xword ShEntsize) { | 106 Elf64_Xword ShEntsize) { |
| 107 assert(!SectionNumbersAssigned); | 107 assert(!SectionNumbersAssigned); |
| 108 T *NewSection = | 108 T *NewSection = |
| 109 new (Ctx.allocate<T>()) T(Name, ShType, ShFlags, ShAddralign, ShEntsize); | 109 new (Ctx.allocate<T>()) T(Name, ShType, ShFlags, ShAddralign, ShEntsize); |
| 110 ShStrTab->add(Name); | 110 ShStrTab->add(Name); |
| 111 return NewSection; | 111 return NewSection; |
| 112 } | 112 } |
| 113 | 113 |
| 114 ELFRelocationSection * | 114 ELFRelocationSection * |
| 115 ELFObjectWriter::createRelocationSection(const ELFSection *RelatedSection) { | 115 ELFObjectWriter::createRelocationSection(const ELFSection *RelatedSection) { |
| 116 // Choice of RELA vs REL is actually separate from elf64 vs elf32, but in | 116 // Choice of RELA vs REL is actually separate from elf64 vs elf32, but in |
| 117 // practice we've only had .rela for elf64 (x86-64). In the future, the two | 117 // practice we've only had .rela for elf64 (x86-64). In the future, the two |
| 118 // properties may need to be decoupled and the ShEntSize can vary more. | 118 // properties may need to be decoupled and the ShEntSize can vary more. |
| 119 const Elf64_Word ShType = ELF64 ? SHT_RELA : SHT_REL; | 119 const Elf64_Word ShType = ELF64 ? SHT_RELA : SHT_REL; |
| 120 const IceString RelPrefix = ELF64 ? ".rela" : ".rel"; | 120 const std::string RelPrefix = ELF64 ? ".rela" : ".rel"; |
| 121 const IceString RelSectionName = RelPrefix + RelatedSection->getName(); | 121 const std::string RelSectionName = RelPrefix + RelatedSection->getName(); |
| 122 const Elf64_Xword ShAlign = ELF64 ? 8 : 4; | 122 const Elf64_Xword ShAlign = ELF64 ? 8 : 4; |
| 123 const Elf64_Xword ShEntSize = ELF64 ? sizeof(Elf64_Rela) : sizeof(Elf32_Rel); | 123 const Elf64_Xword ShEntSize = ELF64 ? sizeof(Elf64_Rela) : sizeof(Elf32_Rel); |
| 124 static_assert(sizeof(Elf64_Rela) == 24 && sizeof(Elf32_Rel) == 8, | 124 static_assert(sizeof(Elf64_Rela) == 24 && sizeof(Elf32_Rel) == 8, |
| 125 "Elf_Rel/Rela sizes cannot be derived from sizeof"); | 125 "Elf_Rel/Rela sizes cannot be derived from sizeof"); |
| 126 constexpr Elf64_Xword ShFlags = 0; | 126 constexpr Elf64_Xword ShFlags = 0; |
| 127 ELFRelocationSection *RelSection = createSection<ELFRelocationSection>( | 127 ELFRelocationSection *RelSection = createSection<ELFRelocationSection>( |
| 128 RelSectionName, ShType, ShFlags, ShAlign, ShEntSize); | 128 RelSectionName, ShType, ShFlags, ShAlign, ShEntSize); |
| 129 RelSection->setRelatedSection(RelatedSection); | 129 RelSection->setRelatedSection(RelatedSection); |
| 130 return RelSection; | 130 return RelSection; |
| 131 } | 131 } |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 Elf64_Off ELFObjectWriter::alignFileOffset(Elf64_Xword Align) { | 209 Elf64_Off ELFObjectWriter::alignFileOffset(Elf64_Xword Align) { |
| 210 Elf64_Off OffsetInFile = Str.tell(); | 210 Elf64_Off OffsetInFile = Str.tell(); |
| 211 Elf64_Xword AlignDiff = Utils::OffsetToAlignment(OffsetInFile, Align); | 211 Elf64_Xword AlignDiff = Utils::OffsetToAlignment(OffsetInFile, Align); |
| 212 if (AlignDiff == 0) | 212 if (AlignDiff == 0) |
| 213 return OffsetInFile; | 213 return OffsetInFile; |
| 214 Str.writeZeroPadding(AlignDiff); | 214 Str.writeZeroPadding(AlignDiff); |
| 215 OffsetInFile += AlignDiff; | 215 OffsetInFile += AlignDiff; |
| 216 return OffsetInFile; | 216 return OffsetInFile; |
| 217 } | 217 } |
| 218 | 218 |
| 219 void ELFObjectWriter::writeFunctionCode(const IceString &FuncName, | 219 void ELFObjectWriter::writeFunctionCode(GlobalString FuncName, bool IsInternal, |
| 220 bool IsInternal, Assembler *Asm) { | 220 Assembler *Asm) { |
| 221 assert(!SectionNumbersAssigned); | 221 assert(!SectionNumbersAssigned); |
| 222 TimerMarker T_func(&Ctx, FuncName); | 222 TimerMarker T_func(&Ctx, FuncName.toStringOrEmpty()); |
| 223 TimerMarker Timer(TimerStack::TT_writeELF, &Ctx); | 223 TimerMarker Timer(TimerStack::TT_writeELF, &Ctx); |
| 224 ELFTextSection *Section = nullptr; | 224 ELFTextSection *Section = nullptr; |
| 225 ELFRelocationSection *RelSection = nullptr; | 225 ELFRelocationSection *RelSection = nullptr; |
| 226 const bool FunctionSections = Ctx.getFlags().getFunctionSections(); | 226 const bool FunctionSections = Ctx.getFlags().getFunctionSections(); |
| 227 if (TextSections.empty() || FunctionSections) { | 227 if (TextSections.empty() || FunctionSections) { |
| 228 IceString SectionName = ".text"; | 228 std::string SectionName = ".text"; |
| 229 if (FunctionSections) | 229 if (FunctionSections) |
| 230 SectionName += "." + FuncName; | 230 SectionName += "." + FuncName; |
| 231 constexpr Elf64_Xword ShFlags = SHF_ALLOC | SHF_EXECINSTR; | 231 constexpr Elf64_Xword ShFlags = SHF_ALLOC | SHF_EXECINSTR; |
| 232 const Elf64_Xword ShAlign = 1 << Asm->getBundleAlignLog2Bytes(); | 232 const Elf64_Xword ShAlign = 1 << Asm->getBundleAlignLog2Bytes(); |
| 233 Section = createSection<ELFTextSection>(SectionName, SHT_PROGBITS, ShFlags, | 233 Section = createSection<ELFTextSection>(SectionName, SHT_PROGBITS, ShFlags, |
| 234 ShAlign, 0); | 234 ShAlign, 0); |
| 235 Elf64_Off OffsetInFile = alignFileOffset(Section->getSectionAlign()); | 235 Elf64_Off OffsetInFile = alignFileOffset(Section->getSectionAlign()); |
| 236 Section->setFileOffset(OffsetInFile); | 236 Section->setFileOffset(OffsetInFile); |
| 237 TextSections.push_back(Section); | 237 TextSections.push_back(Section); |
| 238 RelSection = createRelocationSection(Section); | 238 RelSection = createRelocationSection(Section); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 return ELFObjectWriter::ROData; | 282 return ELFObjectWriter::ROData; |
| 283 if (Var->hasNonzeroInitializer()) | 283 if (Var->hasNonzeroInitializer()) |
| 284 return ELFObjectWriter::Data; | 284 return ELFObjectWriter::Data; |
| 285 return ELFObjectWriter::BSS; | 285 return ELFObjectWriter::BSS; |
| 286 } | 286 } |
| 287 | 287 |
| 288 // Partition the Vars list by SectionType into VarsBySection. If TranslateOnly | 288 // Partition the Vars list by SectionType into VarsBySection. If TranslateOnly |
| 289 // is non-empty, then only the TranslateOnly variable is kept for emission. | 289 // is non-empty, then only the TranslateOnly variable is kept for emission. |
| 290 void partitionGlobalsBySection(const VariableDeclarationList &Vars, | 290 void partitionGlobalsBySection(const VariableDeclarationList &Vars, |
| 291 VariableDeclarationPartition VarsBySection[], | 291 VariableDeclarationPartition VarsBySection[], |
| 292 const IceString &TranslateOnly) { | 292 const std::string &TranslateOnly) { |
| 293 for (VariableDeclaration *Var : Vars) { | 293 for (VariableDeclaration *Var : Vars) { |
| 294 if (GlobalContext::matchSymbolName(Var->getName(), TranslateOnly)) { | 294 if (GlobalContext::matchSymbolName(Var->getName(), TranslateOnly)) { |
| 295 size_t Section = classifyGlobalSection(Var); | 295 size_t Section = classifyGlobalSection(Var); |
| 296 assert(Section < ELFObjectWriter::NumSectionTypes); | 296 assert(Section < ELFObjectWriter::NumSectionTypes); |
| 297 VarsBySection[Section].push_back(Var); | 297 VarsBySection[Section].push_back(Var); |
| 298 } | 298 } |
| 299 } | 299 } |
| 300 } | 300 } |
| 301 | 301 |
| 302 } // end of anonymous namespace | 302 } // end of anonymous namespace |
| 303 | 303 |
| 304 void ELFObjectWriter::writeDataSection(const VariableDeclarationList &Vars, | 304 void ELFObjectWriter::writeDataSection(const VariableDeclarationList &Vars, |
| 305 FixupKind RelocationKind, | 305 FixupKind RelocationKind, |
| 306 const IceString &SectionSuffix, | 306 const std::string &SectionSuffix, |
| 307 bool IsPIC) { | 307 bool IsPIC) { |
| 308 TimerMarker Timer(TimerStack::TT_writeELF, &Ctx); | 308 TimerMarker Timer(TimerStack::TT_writeELF, &Ctx); |
| 309 assert(!SectionNumbersAssigned); | 309 assert(!SectionNumbersAssigned); |
| 310 VariableDeclarationPartition VarsBySection[ELFObjectWriter::NumSectionTypes]; | 310 VariableDeclarationPartition VarsBySection[ELFObjectWriter::NumSectionTypes]; |
| 311 for (auto &SectionList : VarsBySection) | 311 for (auto &SectionList : VarsBySection) |
| 312 SectionList.reserve(Vars.size()); | 312 SectionList.reserve(Vars.size()); |
| 313 partitionGlobalsBySection(Vars, VarsBySection, | 313 partitionGlobalsBySection(Vars, VarsBySection, |
| 314 Ctx.getFlags().getTranslateOnly()); | 314 Ctx.getFlags().getTranslateOnly()); |
| 315 size_t I = 0; | 315 size_t I = 0; |
| 316 for (auto &SectionList : VarsBySection) { | 316 for (auto &SectionList : VarsBySection) { |
| 317 writeDataOfType(static_cast<SectionType>(I++), SectionList, RelocationKind, | 317 writeDataOfType(static_cast<SectionType>(I++), SectionList, RelocationKind, |
| 318 SectionSuffix, IsPIC); | 318 SectionSuffix, IsPIC); |
| 319 } | 319 } |
| 320 } | 320 } |
| 321 | 321 |
| 322 namespace { | 322 namespace { |
| 323 IceString MangleSectionName(const char Base[], const IceString &Suffix) { | 323 std::string MangleSectionName(const char Base[], const std::string &Suffix) { |
| 324 if (Suffix.empty()) | 324 if (Suffix.empty()) |
| 325 return Base; | 325 return Base; |
| 326 return Base + ("." + Suffix); | 326 return Base + ("." + Suffix); |
| 327 } | 327 } |
| 328 } // end of anonymous namespace | 328 } // end of anonymous namespace |
| 329 | 329 |
| 330 // TODO(jvoung): Handle fdata-sections. | 330 // TODO(jvoung): Handle fdata-sections. |
| 331 void ELFObjectWriter::writeDataOfType(SectionType ST, | 331 void ELFObjectWriter::writeDataOfType(SectionType ST, |
| 332 const VariableDeclarationPartition &Vars, | 332 const VariableDeclarationPartition &Vars, |
| 333 FixupKind RelocationKind, | 333 FixupKind RelocationKind, |
| 334 const IceString &SectionSuffix, | 334 const std::string &SectionSuffix, |
| 335 bool IsPIC) { | 335 bool IsPIC) { |
| 336 if (Vars.empty()) | 336 if (Vars.empty()) |
| 337 return; | 337 return; |
| 338 ELFDataSection *Section; | 338 ELFDataSection *Section; |
| 339 ELFRelocationSection *RelSection; | 339 ELFRelocationSection *RelSection; |
| 340 Elf64_Xword ShAddralign = 1; | 340 Elf64_Xword ShAddralign = 1; |
| 341 for (VariableDeclaration *Var : Vars) { | 341 for (VariableDeclaration *Var : Vars) { |
| 342 Elf64_Xword Align = Var->getAlignment(); | 342 Elf64_Xword Align = Var->getAlignment(); |
| 343 ShAddralign = std::max(ShAddralign, Align); | 343 ShAddralign = std::max(ShAddralign, Align); |
| 344 } | 344 } |
| 345 constexpr Elf64_Xword ShEntsize = 0; // non-uniform data element size. | 345 constexpr Elf64_Xword ShEntsize = 0; // non-uniform data element size. |
| 346 // Lift this out, so it can be re-used if we do fdata-sections? | 346 // Lift this out, so it can be re-used if we do fdata-sections? |
| 347 switch (ST) { | 347 switch (ST) { |
| 348 case ROData: { | 348 case ROData: { |
| 349 const IceString SectionName = | 349 const std::string SectionName = |
| 350 MangleSectionName(IsPIC ? ".data.rel.ro" : ".rodata", SectionSuffix); | 350 MangleSectionName(IsPIC ? ".data.rel.ro" : ".rodata", SectionSuffix); |
| 351 const Elf64_Xword ShFlags = IsPIC ? (SHF_ALLOC | SHF_WRITE) : SHF_ALLOC; | 351 const Elf64_Xword ShFlags = IsPIC ? (SHF_ALLOC | SHF_WRITE) : SHF_ALLOC; |
| 352 Section = createSection<ELFDataSection>(SectionName, SHT_PROGBITS, ShFlags, | 352 Section = createSection<ELFDataSection>(SectionName, SHT_PROGBITS, ShFlags, |
| 353 ShAddralign, ShEntsize); | 353 ShAddralign, ShEntsize); |
| 354 Section->setFileOffset(alignFileOffset(ShAddralign)); | 354 Section->setFileOffset(alignFileOffset(ShAddralign)); |
| 355 RODataSections.push_back(Section); | 355 RODataSections.push_back(Section); |
| 356 RelSection = createRelocationSection(Section); | 356 RelSection = createRelocationSection(Section); |
| 357 RelRODataSections.push_back(RelSection); | 357 RelRODataSections.push_back(RelSection); |
| 358 break; | 358 break; |
| 359 } | 359 } |
| 360 case Data: { | 360 case Data: { |
| 361 const IceString SectionName = MangleSectionName(".data", SectionSuffix); | 361 const std::string SectionName = MangleSectionName(".data", SectionSuffix); |
| 362 constexpr Elf64_Xword ShFlags = SHF_ALLOC | SHF_WRITE; | 362 constexpr Elf64_Xword ShFlags = SHF_ALLOC | SHF_WRITE; |
| 363 Section = createSection<ELFDataSection>(SectionName, SHT_PROGBITS, ShFlags, | 363 Section = createSection<ELFDataSection>(SectionName, SHT_PROGBITS, ShFlags, |
| 364 ShAddralign, ShEntsize); | 364 ShAddralign, ShEntsize); |
| 365 Section->setFileOffset(alignFileOffset(ShAddralign)); | 365 Section->setFileOffset(alignFileOffset(ShAddralign)); |
| 366 DataSections.push_back(Section); | 366 DataSections.push_back(Section); |
| 367 RelSection = createRelocationSection(Section); | 367 RelSection = createRelocationSection(Section); |
| 368 RelDataSections.push_back(RelSection); | 368 RelDataSections.push_back(RelSection); |
| 369 break; | 369 break; |
| 370 } | 370 } |
| 371 case BSS: { | 371 case BSS: { |
| 372 const IceString SectionName = MangleSectionName(".bss", SectionSuffix); | 372 const std::string SectionName = MangleSectionName(".bss", SectionSuffix); |
| 373 constexpr Elf64_Xword ShFlags = SHF_ALLOC | SHF_WRITE; | 373 constexpr Elf64_Xword ShFlags = SHF_ALLOC | SHF_WRITE; |
| 374 Section = createSection<ELFDataSection>(SectionName, SHT_NOBITS, ShFlags, | 374 Section = createSection<ELFDataSection>(SectionName, SHT_NOBITS, ShFlags, |
| 375 ShAddralign, ShEntsize); | 375 ShAddralign, ShEntsize); |
| 376 Section->setFileOffset(alignFileOffset(ShAddralign)); | 376 Section->setFileOffset(alignFileOffset(ShAddralign)); |
| 377 BSSSections.push_back(Section); | 377 BSSSections.push_back(Section); |
| 378 break; | 378 break; |
| 379 } | 379 } |
| 380 case NumSectionTypes: | 380 case NumSectionTypes: |
| 381 llvm::report_fatal_error("Unknown SectionType"); | 381 llvm::report_fatal_error("Unknown SectionType"); |
| 382 break; | 382 break; |
| 383 } | 383 } |
| 384 | 384 |
| 385 constexpr uint8_t SymbolType = STT_OBJECT; | 385 constexpr uint8_t SymbolType = STT_OBJECT; |
| 386 for (VariableDeclaration *Var : Vars) { | 386 for (VariableDeclaration *Var : Vars) { |
| 387 // If the variable declaration does not have an initializer, its symtab | 387 // If the variable declaration does not have an initializer, its symtab |
| 388 // entry will be created separately. | 388 // entry will be created separately. |
| 389 if (!Var->hasInitializer()) | 389 if (!Var->hasInitializer()) |
| 390 continue; | 390 continue; |
| 391 Elf64_Xword Align = Var->getAlignment(); | 391 Elf64_Xword Align = Var->getAlignment(); |
| 392 constexpr Elf64_Xword MinAlign = 1; | 392 constexpr Elf64_Xword MinAlign = 1; |
| 393 Align = std::max(Align, MinAlign); | 393 Align = std::max(Align, MinAlign); |
| 394 Section->padToAlignment(Str, Align); | 394 Section->padToAlignment(Str, Align); |
| 395 SizeT SymbolSize = Var->getNumBytes(); | 395 SizeT SymbolSize = Var->getNumBytes(); |
| 396 bool IsExternal = Var->isExternal() || Ctx.getFlags().getDisableInternal(); | 396 bool IsExternal = Var->isExternal() || Ctx.getFlags().getDisableInternal(); |
| 397 const uint8_t SymbolBinding = IsExternal ? STB_GLOBAL : STB_LOCAL; | 397 const uint8_t SymbolBinding = IsExternal ? STB_GLOBAL : STB_LOCAL; |
| 398 const IceString &Name = Var->getName(); | 398 GlobalString Name = Var->getName(); |
| 399 SymTab->createDefinedSym(Name, SymbolType, SymbolBinding, Section, | 399 SymTab->createDefinedSym(Name, SymbolType, SymbolBinding, Section, |
| 400 Section->getCurrentSize(), SymbolSize); | 400 Section->getCurrentSize(), SymbolSize); |
| 401 StrTab->add(Name); | 401 StrTab->add(Name); |
| 402 if (!Var->hasNonzeroInitializer()) { | 402 if (!Var->hasNonzeroInitializer()) { |
| 403 assert(ST == BSS || ST == ROData); | 403 assert(ST == BSS || ST == ROData); |
| 404 if (ST == ROData) | 404 if (ST == ROData) |
| 405 Section->appendZeros(Str, SymbolSize); | 405 Section->appendZeros(Str, SymbolSize); |
| 406 else | 406 else |
| 407 Section->setSize(Section->getCurrentSize() + SymbolSize); | 407 Section->setSize(Section->getCurrentSize() + SymbolSize); |
| 408 } else { | 408 } else { |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 539 RandomNumberGenerator RNG(Ctx.getFlags().getRandomSeed(), | 539 RandomNumberGenerator RNG(Ctx.getFlags().getRandomSeed(), |
| 540 RPE_PooledConstantReordering, K); | 540 RPE_PooledConstantReordering, K); |
| 541 RandomShuffle(Pool.begin(), Pool.end(), | 541 RandomShuffle(Pool.begin(), Pool.end(), |
| 542 [&RNG](uint64_t N) { return (uint32_t)RNG.next(N); }); | 542 [&RNG](uint64_t N) { return (uint32_t)RNG.next(N); }); |
| 543 } | 543 } |
| 544 // Write the data. | 544 // Write the data. |
| 545 for (Constant *C : Pool) { | 545 for (Constant *C : Pool) { |
| 546 if (!C->getShouldBePooled()) | 546 if (!C->getShouldBePooled()) |
| 547 continue; | 547 continue; |
| 548 auto *Const = llvm::cast<ConstType>(C); | 548 auto *Const = llvm::cast<ConstType>(C); |
| 549 std::string SymBuffer; | 549 GlobalString SymName = Const->getLabelName(); |
| 550 llvm::raw_string_ostream SymStrBuf(SymBuffer); | |
| 551 Const->emitPoolLabel(SymStrBuf); | |
| 552 std::string &SymName = SymStrBuf.str(); | |
| 553 SymTab->createDefinedSym(SymName, STT_NOTYPE, STB_LOCAL, Section, | 550 SymTab->createDefinedSym(SymName, STT_NOTYPE, STB_LOCAL, Section, |
| 554 OffsetInSection, SymbolSize); | 551 OffsetInSection, SymbolSize); |
| 555 StrTab->add(SymName); | 552 StrTab->add(SymName); |
| 556 typename ConstType::PrimType Value = Const->getValue(); | 553 typename ConstType::PrimType Value = Const->getValue(); |
| 557 memcpy(Buf, &Value, WriteAmt); | 554 memcpy(Buf, &Value, WriteAmt); |
| 558 Str.writeBytes(llvm::StringRef(Buf, WriteAmt)); | 555 Str.writeBytes(llvm::StringRef(Buf, WriteAmt)); |
| 559 OffsetInSection += WriteAmt; | 556 OffsetInSection += WriteAmt; |
| 560 } | 557 } |
| 561 Section->setSize(OffsetInSection); | 558 Section->setSize(OffsetInSection); |
| 562 } | 559 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 579 } | 576 } |
| 580 | 577 |
| 581 void ELFObjectWriter::writeJumpTable(const JumpTableData &JT, | 578 void ELFObjectWriter::writeJumpTable(const JumpTableData &JT, |
| 582 FixupKind RelocationKind, bool IsPIC) { | 579 FixupKind RelocationKind, bool IsPIC) { |
| 583 TimerMarker Timer(TimerStack::TT_writeELF, &Ctx); | 580 TimerMarker Timer(TimerStack::TT_writeELF, &Ctx); |
| 584 ELFDataSection *Section; | 581 ELFDataSection *Section; |
| 585 ELFRelocationSection *RelSection; | 582 ELFRelocationSection *RelSection; |
| 586 const Elf64_Xword PointerSize = typeWidthInBytes(getPointerType()); | 583 const Elf64_Xword PointerSize = typeWidthInBytes(getPointerType()); |
| 587 const Elf64_Xword ShAddralign = PointerSize; | 584 const Elf64_Xword ShAddralign = PointerSize; |
| 588 const Elf64_Xword ShEntsize = PointerSize; | 585 const Elf64_Xword ShEntsize = PointerSize; |
| 589 const IceString SectionName = MangleSectionName( | 586 const GlobalString JTName = JT.getFunctionName(); |
| 590 IsPIC ? ".data.rel.ro" : ".rodata", JT.getFunctionName() + "$jumptable"); | 587 const std::string SectionName = MangleSectionName( |
| 588 IsPIC ? ".data.rel.ro" : ".rodata", |
| 589 (JTName.hasStdString() ? JTName.toString() |
| 590 : std::to_string(JTName.getID())) + |
| 591 "$jumptable"); |
| 591 Section = createSection<ELFDataSection>(SectionName, SHT_PROGBITS, SHF_ALLOC, | 592 Section = createSection<ELFDataSection>(SectionName, SHT_PROGBITS, SHF_ALLOC, |
| 592 ShAddralign, ShEntsize); | 593 ShAddralign, ShEntsize); |
| 593 Section->setFileOffset(alignFileOffset(ShAddralign)); | 594 Section->setFileOffset(alignFileOffset(ShAddralign)); |
| 594 RODataSections.push_back(Section); | 595 RODataSections.push_back(Section); |
| 595 RelSection = createRelocationSection(Section); | 596 RelSection = createRelocationSection(Section); |
| 596 RelRODataSections.push_back(RelSection); | 597 RelRODataSections.push_back(RelSection); |
| 597 | 598 |
| 598 constexpr uint8_t SymbolType = STT_OBJECT; | 599 constexpr uint8_t SymbolType = STT_OBJECT; |
| 599 Section->padToAlignment(Str, PointerSize); | 600 Section->padToAlignment(Str, PointerSize); |
| 600 const bool IsExternal = Ctx.getFlags().getDisableInternal(); | 601 const bool IsExternal = Ctx.getFlags().getDisableInternal(); |
| 601 const uint8_t SymbolBinding = IsExternal ? STB_GLOBAL : STB_LOCAL; | 602 const uint8_t SymbolBinding = IsExternal ? STB_GLOBAL : STB_LOCAL; |
| 602 const IceString JumpTableName = | 603 GlobalString JumpTableName = Ctx.getGlobalString( |
| 603 InstJumpTable::makeName(JT.getFunctionName(), JT.getId()); | 604 InstJumpTable::makeName(JT.getFunctionName(), JT.getId())); |
| 604 SymTab->createDefinedSym(JumpTableName, SymbolType, SymbolBinding, Section, | 605 SymTab->createDefinedSym(JumpTableName, SymbolType, SymbolBinding, Section, |
| 605 Section->getCurrentSize(), PointerSize); | 606 Section->getCurrentSize(), PointerSize); |
| 606 StrTab->add(JumpTableName); | 607 StrTab->add(JumpTableName); |
| 607 | 608 |
| 608 for (intptr_t TargetOffset : JT.getTargetOffsets()) { | 609 for (intptr_t TargetOffset : JT.getTargetOffsets()) { |
| 609 AssemblerFixup NewFixup; | 610 AssemblerFixup NewFixup; |
| 610 NewFixup.set_position(Section->getCurrentSize()); | 611 NewFixup.set_position(Section->getCurrentSize()); |
| 611 NewFixup.set_kind(RelocationKind); | 612 NewFixup.set_kind(RelocationKind); |
| 612 NewFixup.set_value(Ctx.getConstantSym(TargetOffset, JT.getFunctionName())); | 613 NewFixup.set_value(Ctx.getConstantSym(TargetOffset, JT.getFunctionName())); |
| 613 RelSection->addRelocation(NewFixup); | 614 RelSection->addRelocation(NewFixup); |
| 614 Section->appendRelocationOffset(Str, RelSection->isRela(), TargetOffset); | 615 Section->appendRelocationOffset(Str, RelSection->isRela(), TargetOffset); |
| 615 } | 616 } |
| 616 } | 617 } |
| 617 | 618 |
| 618 void ELFObjectWriter::setUndefinedSyms(const ConstantList &UndefSyms) { | 619 void ELFObjectWriter::setUndefinedSyms(const ConstantList &UndefSyms) { |
| 619 TimerMarker Timer(TimerStack::TT_writeELF, &Ctx); | 620 TimerMarker Timer(TimerStack::TT_writeELF, &Ctx); |
| 620 for (const Constant *S : UndefSyms) { | 621 for (const Constant *S : UndefSyms) { |
| 621 const auto *Sym = llvm::cast<ConstantRelocatable>(S); | 622 const auto *Sym = llvm::cast<ConstantRelocatable>(S); |
| 622 const IceString &Name = Sym->getName(); | 623 GlobalString Name = Sym->getName(); |
| 624 assert(Name.hasStdString()); |
| 623 bool BadIntrinsic; | 625 bool BadIntrinsic; |
| 624 const Intrinsics::FullIntrinsicInfo *Info = | 626 const Intrinsics::FullIntrinsicInfo *Info = |
| 625 Ctx.getIntrinsicsInfo().find(Name, BadIntrinsic); | 627 Ctx.getIntrinsicsInfo().find(Name, BadIntrinsic); |
| 626 if (Info) | 628 if (Info) |
| 627 continue; | 629 continue; |
| 628 // Ignore BadIntrinsic, which is set if the name begins with "llvm." but | 630 // Ignore BadIntrinsic, which is set if the name begins with "llvm." but |
| 629 // doesn't match a known intrinsic. If we want this to turn into an error, | 631 // doesn't match a known intrinsic. If we want this to turn into an error, |
| 630 // we should catch it early on. | 632 // we should catch it early on. |
| 631 assert(Sym->getOffset() == 0); | 633 assert(Sym->getOffset() == 0); |
| 632 SymTab->noteUndefinedSym(Name, NullSection); | 634 SymTab->noteUndefinedSym(Name, NullSection); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 692 if (ELF64) { | 694 if (ELF64) { |
| 693 writeELFHeaderInternal<true>(ShOffset, ShStrTab->getNumber(), | 695 writeELFHeaderInternal<true>(ShOffset, ShStrTab->getNumber(), |
| 694 AllSections.size()); | 696 AllSections.size()); |
| 695 } else { | 697 } else { |
| 696 writeELFHeaderInternal<false>(ShOffset, ShStrTab->getNumber(), | 698 writeELFHeaderInternal<false>(ShOffset, ShStrTab->getNumber(), |
| 697 AllSections.size()); | 699 AllSections.size()); |
| 698 } | 700 } |
| 699 } | 701 } |
| 700 | 702 |
| 701 } // end of namespace Ice | 703 } // end of namespace Ice |
| OLD | NEW |