Index: include/llvm/ObjectYAML/ELFYAML.h =================================================================== --- include/llvm/ObjectYAML/ELFYAML.h +++ include/llvm/ObjectYAML/ELFYAML.h @@ -141,6 +141,7 @@ struct DynamicSection : Section { std::vector Entries; + Optional Content; DynamicSection() : Section(SectionKind::Dynamic) {} Index: lib/ObjectYAML/ELFYAML.cpp =================================================================== --- lib/ObjectYAML/ELFYAML.cpp +++ lib/ObjectYAML/ELFYAML.cpp @@ -855,6 +855,7 @@ static void sectionMapping(IO &IO, ELFYAML::DynamicSection &Section) { commonSectionMapping(IO, Section); IO.mapOptional("Entries", Section.Entries); + IO.mapOptional("Content", Section.Content); } static void sectionMapping(IO &IO, ELFYAML::RawContentSection &Section) { Index: test/tools/yaml2obj/dynamic-section-raw-content.yaml =================================================================== --- test/tools/yaml2obj/dynamic-section-raw-content.yaml +++ test/tools/yaml2obj/dynamic-section-raw-content.yaml @@ -0,0 +1,45 @@ +# Show that yaml2obj can handle a dynamic section with raw content instead of +# entries. Also show that it rejects raw content when entries are also provided. + +# RUN: yaml2obj --docnum=1 %s -o %t1 +# RUN: llvm-readobj -x .dynamic --sections %t1 | FileCheck %s --check-prefix=RAW + +# RUN: not yaml2obj --docnum=2 %s -o %t2 2>&1 | FileCheck %s --check-prefix=ERR + +# RAW: Name: .dynamic +# RAW-NEXT: Type: SHT_DYNAMIC +# RAW-NEXT: Flags [ +# RAW-NEXT: ] +# RAW-NEXT: Address: +# RAW-NEXT: Offset: +# RAW-NEXT: Size: 5 + +# RAW: Hex dump of section '.dynamic': +# RAW-NEXT: 0x00000000 01234567 89 {{.*}} + +# ERR: Cannot specify both raw content and explicit entries for dynamic section '.dynamic'. + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +Sections: + - Name: .dynamic + Type: SHT_DYNAMIC + Content: "0123456789" + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +Sections: + - Name: .dynamic + Type: SHT_DYNAMIC + Content: "0123456789" + Entries: + - Tag: DT_STRSZ + Value: 0 Index: tools/yaml2obj/yaml2elf.cpp =================================================================== --- tools/yaml2obj/yaml2elf.cpp +++ tools/yaml2obj/yaml2elf.cpp @@ -169,7 +169,7 @@ bool writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::MipsABIFlags &Section, ContiguousBlobAccumulator &CBA); - void writeSectionContent(Elf_Shdr &SHeader, + bool writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::DynamicSection &Section, ContiguousBlobAccumulator &CBA); bool hasDynamicSymbols() const; @@ -309,7 +309,8 @@ // so just to setup the section offset. CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); } else if (auto S = dyn_cast(Sec.get())) { - writeSectionContent(SHeader, *S, CBA); + if (!writeSectionContent(SHeader, *S, CBA)) + return false; } else if (auto S = dyn_cast(Sec.get())) { writeSectionContent(SHeader, *S, CBA); } else if (auto S = dyn_cast(Sec.get())) { @@ -713,7 +714,7 @@ } template -void ELFState::writeSectionContent(Elf_Shdr &SHeader, +bool ELFState::writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::DynamicSection &Section, ContiguousBlobAccumulator &CBA) { typedef typename ELFT::uint uintX_t; @@ -721,7 +722,18 @@ assert(Section.Type == llvm::ELF::SHT_DYNAMIC && "Section type is not SHT_DYNAMIC"); - SHeader.sh_size = 2 * sizeof(uintX_t) * Section.Entries.size(); + if (!Section.Entries.empty() && Section.Content) { + WithColor::error() + << "Cannot specify both raw content and explicit entries " + "for dynamic section '" + << Section.Name << "'.\n"; + return false; + } + + if (Section.Content) + SHeader.sh_size = Section.Content->binary_size(); + else + SHeader.sh_size = 2 * sizeof(uintX_t) * Section.Entries.size(); if (Section.EntSize) SHeader.sh_entsize = *Section.EntSize; else @@ -732,6 +744,10 @@ support::endian::write(OS, DE.Tag, ELFT::TargetEndianness); support::endian::write(OS, DE.Val, ELFT::TargetEndianness); } + if (Section.Content) + Section.Content->writeAsBinary(OS); + + return true; } template bool ELFState::buildSectionIndex() {