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 |