diff --git a/llvm/include/llvm/ObjectYAML/ELFYAML.h b/llvm/include/llvm/ObjectYAML/ELFYAML.h --- a/llvm/include/llvm/ObjectYAML/ELFYAML.h +++ b/llvm/include/llvm/ObjectYAML/ELFYAML.h @@ -687,6 +687,10 @@ // This vector contains all chunks from [FirstSec, LastSec]. std::vector Chunks; + + // This contains optional content when no sections are used. + // It should NOT be used with Chunks or other section contents. + Optional Content; }; struct Object { diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp --- a/llvm/lib/ObjectYAML/ELFEmitter.cpp +++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp @@ -232,7 +232,8 @@ ContiguousBlobAccumulator &CBA, ELFYAML::Section *YAMLSec); void setProgramHeaderLayout(std::vector &PHeaders, - std::vector &SHeaders); + std::vector &SHeaders, + ContiguousBlobAccumulator &CBA); std::vector getPhdrFragments(const ELFYAML::ProgramHeader &Phdr, @@ -1162,7 +1163,8 @@ template void ELFState::setProgramHeaderLayout(std::vector &PHeaders, - std::vector &SHeaders) { + std::vector &SHeaders, + ContiguousBlobAccumulator &CBA) { uint32_t PhdrIdx = 0; for (auto &YamlPhdr : Doc.ProgramHeaders) { Elf_Phdr &PHeader = PHeaders[PhdrIdx++]; @@ -1215,6 +1217,12 @@ for (const Fragment &F : Fragments) PHeader.p_align = std::max((uint64_t)PHeader.p_align, F.AddrAlign); } + + if (YamlPhdr.Content) { + alignToOffset(CBA, PHeader.p_align, + yaml::Hex64(PHeader.p_paddr + PHeader.p_offset)); + CBA.writeAsBinary(*YamlPhdr.Content); + } } } @@ -1938,7 +1946,7 @@ State.initSectionHeaders(SHeaders, CBA); // Now we can decide segment offsets. - State.setProgramHeaderLayout(PHeaders, SHeaders); + State.setProgramHeaderLayout(PHeaders, SHeaders, CBA); bool ReachedLimit = CBA.getOffset() > MaxSize; if (Error E = CBA.takeLimitError()) { diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp --- a/llvm/lib/ObjectYAML/ELFYAML.cpp +++ b/llvm/lib/ObjectYAML/ELFYAML.cpp @@ -1096,6 +1096,7 @@ IO.mapOptional("FileSize", Phdr.FileSize); IO.mapOptional("MemSize", Phdr.MemSize); IO.mapOptional("Offset", Phdr.Offset); + IO.mapOptional("Content", Phdr.Content); } std::string MappingTraits::validate( @@ -1104,6 +1105,8 @@ return "the \"LastSec\" key can't be used without the \"FirstSec\" key"; if (FileHdr.FirstSec && !FileHdr.LastSec) return "the \"FirstSec\" key can't be used without the \"LastSec\" key"; + if (FileHdr.FirstSec && FileHdr.Content) + return "the \"FirstSec\" key can't be used with \"Content\" key"; return ""; }