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 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
289 if (Var->getIsConstant()) | 289 if (Var->getIsConstant()) |
290 return ELFObjectWriter::ROData; | 290 return ELFObjectWriter::ROData; |
291 if (Var->hasNonzeroInitializer()) | 291 if (Var->hasNonzeroInitializer()) |
292 return ELFObjectWriter::Data; | 292 return ELFObjectWriter::Data; |
293 return ELFObjectWriter::BSS; | 293 return ELFObjectWriter::BSS; |
294 } | 294 } |
295 | 295 |
296 // Partition the Vars list by SectionType into VarsBySection. If TranslateOnly | 296 // Partition the Vars list by SectionType into VarsBySection. If TranslateOnly |
297 // is non-empty, then only the TranslateOnly variable is kept for emission. | 297 // is non-empty, then only the TranslateOnly variable is kept for emission. |
298 void partitionGlobalsBySection(const VariableDeclarationList &Vars, | 298 void partitionGlobalsBySection(const VariableDeclarationList &Vars, |
299 VariableDeclarationList VarsBySection[], | 299 VariableDeclarationPartition VarsBySection[], |
300 const IceString &TranslateOnly) { | 300 const IceString &TranslateOnly) { |
301 for (VariableDeclaration *Var : Vars) { | 301 for (VariableDeclaration *Var : Vars) { |
302 if (GlobalContext::matchSymbolName(Var->getName(), TranslateOnly)) { | 302 if (GlobalContext::matchSymbolName(Var->getName(), TranslateOnly)) { |
303 size_t Section = classifyGlobalSection(Var); | 303 size_t Section = classifyGlobalSection(Var); |
304 assert(Section < ELFObjectWriter::NumSectionTypes); | 304 assert(Section < ELFObjectWriter::NumSectionTypes); |
305 VarsBySection[Section].push_back(Var); | 305 VarsBySection[Section].push_back(Var); |
306 } | 306 } |
307 } | 307 } |
308 } | 308 } |
309 | 309 |
310 } // end of anonymous namespace | 310 } // end of anonymous namespace |
311 | 311 |
312 void ELFObjectWriter::writeDataSection(const VariableDeclarationList &Vars, | 312 void ELFObjectWriter::writeDataSection(const VariableDeclarationList &Vars, |
313 FixupKind RelocationKind, | 313 FixupKind RelocationKind, |
314 const IceString &SectionSuffix, | 314 const IceString &SectionSuffix, |
315 bool IsPIC) { | 315 bool IsPIC) { |
316 TimerMarker Timer(TimerStack::TT_writeELF, &Ctx); | 316 TimerMarker Timer(TimerStack::TT_writeELF, &Ctx); |
317 assert(!SectionNumbersAssigned); | 317 assert(!SectionNumbersAssigned); |
318 VariableDeclarationList VarsBySection[ELFObjectWriter::NumSectionTypes]; | 318 VariableDeclarationPartition VarsBySection[ELFObjectWriter::NumSectionTypes]; |
319 for (auto &SectionList : VarsBySection) | 319 for (auto &SectionList : VarsBySection) |
320 SectionList.reserve(Vars.size()); | 320 SectionList.reserve(Vars.size()); |
321 partitionGlobalsBySection(Vars, VarsBySection, | 321 partitionGlobalsBySection(Vars, VarsBySection, |
322 Ctx.getFlags().getTranslateOnly()); | 322 Ctx.getFlags().getTranslateOnly()); |
323 size_t I = 0; | 323 size_t I = 0; |
324 for (auto &SectionList : VarsBySection) { | 324 for (auto &SectionList : VarsBySection) { |
325 writeDataOfType(static_cast<SectionType>(I++), SectionList, RelocationKind, | 325 writeDataOfType(static_cast<SectionType>(I++), SectionList, RelocationKind, |
326 SectionSuffix, IsPIC); | 326 SectionSuffix, IsPIC); |
327 } | 327 } |
328 } | 328 } |
329 | 329 |
330 namespace { | 330 namespace { |
331 IceString MangleSectionName(const char Base[], const IceString &Suffix) { | 331 IceString MangleSectionName(const char Base[], const IceString &Suffix) { |
332 if (Suffix.empty()) | 332 if (Suffix.empty()) |
333 return Base; | 333 return Base; |
334 return Base + ("." + Suffix); | 334 return Base + ("." + Suffix); |
335 } | 335 } |
336 } // end of anonymous namespace | 336 } // end of anonymous namespace |
337 | 337 |
338 // TODO(jvoung): Handle fdata-sections. | 338 // TODO(jvoung): Handle fdata-sections. |
339 void ELFObjectWriter::writeDataOfType(SectionType ST, | 339 void ELFObjectWriter::writeDataOfType(SectionType ST, |
340 const VariableDeclarationList &Vars, | 340 const VariableDeclarationPartition &Vars, |
341 FixupKind RelocationKind, | 341 FixupKind RelocationKind, |
342 const IceString &SectionSuffix, | 342 const IceString &SectionSuffix, |
343 bool IsPIC) { | 343 bool IsPIC) { |
344 if (Vars.empty()) | 344 if (Vars.empty()) |
345 return; | 345 return; |
346 ELFDataSection *Section; | 346 ELFDataSection *Section; |
347 ELFRelocationSection *RelSection; | 347 ELFRelocationSection *RelSection; |
348 Elf64_Xword ShAddralign = 1; | 348 Elf64_Xword ShAddralign = 1; |
349 for (VariableDeclaration *Var : Vars) { | 349 for (VariableDeclaration *Var : Vars) { |
350 Elf64_Xword Align = Var->getAlignment(); | 350 Elf64_Xword Align = Var->getAlignment(); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 Section->getCurrentSize(), SymbolSize); | 408 Section->getCurrentSize(), SymbolSize); |
409 StrTab->add(Name); | 409 StrTab->add(Name); |
410 if (!Var->hasNonzeroInitializer()) { | 410 if (!Var->hasNonzeroInitializer()) { |
411 assert(ST == BSS || ST == ROData); | 411 assert(ST == BSS || ST == ROData); |
412 if (ST == ROData) | 412 if (ST == ROData) |
413 Section->appendZeros(Str, SymbolSize); | 413 Section->appendZeros(Str, SymbolSize); |
414 else | 414 else |
415 Section->setSize(Section->getCurrentSize() + SymbolSize); | 415 Section->setSize(Section->getCurrentSize() + SymbolSize); |
416 } else { | 416 } else { |
417 assert(ST != BSS); | 417 assert(ST != BSS); |
418 for (const std::unique_ptr<VariableDeclaration::Initializer> &Init : | 418 for (const auto *Init : Var->getInitializers()) { |
419 Var->getInitializers()) { | |
420 switch (Init->getKind()) { | 419 switch (Init->getKind()) { |
421 case VariableDeclaration::Initializer::DataInitializerKind: { | 420 case VariableDeclaration::Initializer::DataInitializerKind: { |
422 const auto &Data = | 421 const auto &Data = |
423 llvm::cast<VariableDeclaration::DataInitializer>(Init.get()) | 422 llvm::cast<VariableDeclaration::DataInitializer>(Init) |
424 ->getContents(); | 423 ->getContents(); |
425 Section->appendData(Str, llvm::StringRef(Data.data(), Data.size())); | 424 Section->appendData(Str, llvm::StringRef(Data.data(), Data.size())); |
426 break; | 425 break; |
427 } | 426 } |
428 case VariableDeclaration::Initializer::ZeroInitializerKind: | 427 case VariableDeclaration::Initializer::ZeroInitializerKind: |
429 Section->appendZeros(Str, Init->getNumBytes()); | 428 Section->appendZeros(Str, Init->getNumBytes()); |
430 break; | 429 break; |
431 case VariableDeclaration::Initializer::RelocInitializerKind: { | 430 case VariableDeclaration::Initializer::RelocInitializerKind: { |
432 const auto *Reloc = | 431 const auto *Reloc = |
433 llvm::cast<VariableDeclaration::RelocInitializer>(Init.get()); | 432 llvm::cast<VariableDeclaration::RelocInitializer>(Init); |
434 AssemblerFixup NewFixup; | 433 AssemblerFixup NewFixup; |
435 NewFixup.set_position(Section->getCurrentSize()); | 434 NewFixup.set_position(Section->getCurrentSize()); |
436 NewFixup.set_kind(Reloc->hasFixup() ? Reloc->getFixup() | 435 NewFixup.set_kind(Reloc->hasFixup() ? Reloc->getFixup() |
437 : RelocationKind); | 436 : RelocationKind); |
438 assert(NewFixup.kind() != llvm::ELF::R_ARM_NONE); | 437 assert(NewFixup.kind() != llvm::ELF::R_ARM_NONE); |
439 NewFixup.set_value(Ctx.getConstantSym( | 438 NewFixup.set_value(Ctx.getConstantSym( |
440 Reloc->getOffset(), Reloc->getDeclaration()->getName())); | 439 Reloc->getOffset(), Reloc->getDeclaration()->getName())); |
441 RelSection->addRelocation(NewFixup); | 440 RelSection->addRelocation(NewFixup); |
442 Section->appendRelocationOffset(Str, RelSection->isRela(), | 441 Section->appendRelocationOffset(Str, RelSection->isRela(), |
443 Reloc->getOffset()); | 442 Reloc->getOffset()); |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
701 if (ELF64) { | 700 if (ELF64) { |
702 writeELFHeaderInternal<true>(ShOffset, ShStrTab->getNumber(), | 701 writeELFHeaderInternal<true>(ShOffset, ShStrTab->getNumber(), |
703 AllSections.size()); | 702 AllSections.size()); |
704 } else { | 703 } else { |
705 writeELFHeaderInternal<false>(ShOffset, ShStrTab->getNumber(), | 704 writeELFHeaderInternal<false>(ShOffset, ShStrTab->getNumber(), |
706 AllSections.size()); | 705 AllSections.size()); |
707 } | 706 } |
708 } | 707 } |
709 | 708 |
710 } // end of namespace Ice | 709 } // end of namespace Ice |
OLD | NEW |