diff --git a/llvm/include/llvm/ObjectYAML/ELFYAML.h b/llvm/include/llvm/ObjectYAML/ELFYAML.h index 2fd18fcd2957c..22ed82289ca8c 100644 --- a/llvm/include/llvm/ObjectYAML/ELFYAML.h +++ b/llvm/include/llvm/ObjectYAML/ELFYAML.h @@ -90,18 +90,6 @@ struct SectionName { StringRef Section; }; -struct ProgramHeader { - ELF_PT Type; - ELF_PF Flags; - llvm::yaml::Hex64 VAddr; - llvm::yaml::Hex64 PAddr; - Optional Align; - Optional FileSize; - Optional MemSize; - Optional Offset; - std::vector Sections; -}; - struct Symbol { StringRef Name; ELF_STT Type; @@ -503,6 +491,21 @@ struct MipsABIFlags : Section { } }; +struct ProgramHeader { + ELF_PT Type; + ELF_PF Flags; + llvm::yaml::Hex64 VAddr; + llvm::yaml::Hex64 PAddr; + Optional Align; + Optional FileSize; + Optional MemSize; + Optional Offset; + + std::vector Sections; + // This vector is parallel to Sections and contains corresponding chunks. + std::vector Chunks; +}; + struct Object { FileHeader Header; std::vector ProgramHeaders; diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp index 95d74eeeb6e6e..78093491704be 100644 --- a/llvm/lib/ObjectYAML/ELFEmitter.cpp +++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp @@ -330,7 +330,13 @@ void ELFState::writeELFHeader(ContiguousBlobAccumulator &CBA, raw_ostream template void ELFState::initProgramHeaders(std::vector &PHeaders) { - for (const auto &YamlPhdr : Doc.ProgramHeaders) { + DenseMap NameToFill; + for (const std::unique_ptr &D : Doc.Chunks) + if (auto S = dyn_cast(D.get())) + NameToFill[S->Name] = S; + + std::vector Sections = Doc.getSections(); + for (ELFYAML::ProgramHeader &YamlPhdr : Doc.ProgramHeaders) { Elf_Phdr Phdr; zero(Phdr); Phdr.p_type = YamlPhdr.Type; @@ -338,6 +344,23 @@ void ELFState::initProgramHeaders(std::vector &PHeaders) { Phdr.p_vaddr = YamlPhdr.VAddr; Phdr.p_paddr = YamlPhdr.PAddr; PHeaders.push_back(Phdr); + + // Map Sections list to corresponding chunks. + for (const ELFYAML::SectionName &SecName : YamlPhdr.Sections) { + if (ELFYAML::Fill *Fill = NameToFill.lookup(SecName.Section)) { + YamlPhdr.Chunks.push_back(Fill); + continue; + } + + unsigned Index; + if (SN2I.lookup(SecName.Section, Index)) { + YamlPhdr.Chunks.push_back(Sections[Index]); + continue; + } + + reportError("unknown section or fill referenced: '" + SecName.Section + + "' by program header"); + } } } @@ -757,31 +780,19 @@ template void ELFState::reportError(const Twine &Msg) { template std::vector ELFState::getPhdrFragments(const ELFYAML::ProgramHeader &Phdr, - ArrayRef SHeaders) { - DenseMap NameToFill; - for (const std::unique_ptr &D : Doc.Chunks) - if (auto S = dyn_cast(D.get())) - NameToFill[S->Name] = S; - + ArrayRef SHeaders) { std::vector Ret; - for (const ELFYAML::SectionName &SecName : Phdr.Sections) { - unsigned Index; - if (SN2I.lookup(SecName.Section, Index)) { - const typename ELFT::Shdr &H = SHeaders[Index]; - Ret.push_back({H.sh_offset, H.sh_size, H.sh_type, H.sh_addralign}); - continue; - } - - if (ELFYAML::Fill *Fill = NameToFill.lookup(SecName.Section)) { - Ret.push_back({*Fill->Offset, Fill->Size, llvm::ELF::SHT_PROGBITS, + for (const ELFYAML::Chunk *C : Phdr.Chunks) { + if (const ELFYAML::Fill *F = dyn_cast(C)) { + Ret.push_back({*F->Offset, F->Size, llvm::ELF::SHT_PROGBITS, /*ShAddrAlign=*/1}); continue; } - reportError("unknown section or fill referenced: '" + SecName.Section + - "' by program header"); + const ELFYAML::Section *S = cast(C); + const Elf_Shdr &H = SHeaders[SN2I.get(S->Name)]; + Ret.push_back({H.sh_offset, H.sh_size, H.sh_type, H.sh_addralign}); } - return Ret; }