[yaml2obj]Re-allow dynamic sections to have raw content

Recently, support was added to yaml2obj to allow dynamic sections to
have a list of entries, to make it easier to write tests with dynamic
sections. However, this change also removed the ability to provide
custom contents to the dynamic section, making it hard to test
malformed contents (e.g. because the section is not a valid size to
contain an array of entries). This change reinstates this. An error is
emitted if raw content and dynamic entries are both specified.

Reviewed by: grimar, ruiu

Differential Review: https://reviews.llvm.org/D58543

llvm-svn: 354770
This commit is contained in:
James Henderson 2019-02-25 11:02:24 +00:00
parent 777e1cfdc3
commit fd99780c09
4 changed files with 66 additions and 4 deletions

View File

@ -141,6 +141,7 @@ struct Section {
struct DynamicSection : Section { struct DynamicSection : Section {
std::vector<DynamicEntry> Entries; std::vector<DynamicEntry> Entries;
Optional<yaml::BinaryRef> Content;
DynamicSection() : Section(SectionKind::Dynamic) {} DynamicSection() : Section(SectionKind::Dynamic) {}

View File

@ -855,6 +855,7 @@ static void commonSectionMapping(IO &IO, ELFYAML::Section &Section) {
static void sectionMapping(IO &IO, ELFYAML::DynamicSection &Section) { static void sectionMapping(IO &IO, ELFYAML::DynamicSection &Section) {
commonSectionMapping(IO, Section); commonSectionMapping(IO, Section);
IO.mapOptional("Entries", Section.Entries); IO.mapOptional("Entries", Section.Entries);
IO.mapOptional("Content", Section.Content);
} }
static void sectionMapping(IO &IO, ELFYAML::RawContentSection &Section) { static void sectionMapping(IO &IO, ELFYAML::RawContentSection &Section) {

View File

@ -0,0 +1,44 @@
# 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
# 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 {{.*}}
# RUN: not yaml2obj --docnum=2 %s -o %t2 2>&1 | FileCheck %s --check-prefix=ERR
# 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

View File

@ -169,7 +169,7 @@ class ELFState {
bool writeSectionContent(Elf_Shdr &SHeader, bool writeSectionContent(Elf_Shdr &SHeader,
const ELFYAML::MipsABIFlags &Section, const ELFYAML::MipsABIFlags &Section,
ContiguousBlobAccumulator &CBA); ContiguousBlobAccumulator &CBA);
void writeSectionContent(Elf_Shdr &SHeader, bool writeSectionContent(Elf_Shdr &SHeader,
const ELFYAML::DynamicSection &Section, const ELFYAML::DynamicSection &Section,
ContiguousBlobAccumulator &CBA); ContiguousBlobAccumulator &CBA);
bool hasDynamicSymbols() const; bool hasDynamicSymbols() const;
@ -309,7 +309,8 @@ bool ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,
// so just to setup the section offset. // so just to setup the section offset.
CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
} else if (auto S = dyn_cast<ELFYAML::DynamicSection>(Sec.get())) { } else if (auto S = dyn_cast<ELFYAML::DynamicSection>(Sec.get())) {
writeSectionContent(SHeader, *S, CBA); if (!writeSectionContent(SHeader, *S, CBA))
return false;
} else if (auto S = dyn_cast<ELFYAML::SymverSection>(Sec.get())) { } else if (auto S = dyn_cast<ELFYAML::SymverSection>(Sec.get())) {
writeSectionContent(SHeader, *S, CBA); writeSectionContent(SHeader, *S, CBA);
} else if (auto S = dyn_cast<ELFYAML::VerneedSection>(Sec.get())) { } else if (auto S = dyn_cast<ELFYAML::VerneedSection>(Sec.get())) {
@ -713,7 +714,7 @@ bool ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
} }
template <class ELFT> template <class ELFT>
void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, bool ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
const ELFYAML::DynamicSection &Section, const ELFYAML::DynamicSection &Section,
ContiguousBlobAccumulator &CBA) { ContiguousBlobAccumulator &CBA) {
typedef typename ELFT::uint uintX_t; typedef typename ELFT::uint uintX_t;
@ -721,7 +722,18 @@ void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
assert(Section.Type == llvm::ELF::SHT_DYNAMIC && assert(Section.Type == llvm::ELF::SHT_DYNAMIC &&
"Section type is not 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) if (Section.EntSize)
SHeader.sh_entsize = *Section.EntSize; SHeader.sh_entsize = *Section.EntSize;
else else
@ -732,6 +744,10 @@ void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
support::endian::write<uintX_t>(OS, DE.Tag, ELFT::TargetEndianness); support::endian::write<uintX_t>(OS, DE.Tag, ELFT::TargetEndianness);
support::endian::write<uintX_t>(OS, DE.Val, ELFT::TargetEndianness); support::endian::write<uintX_t>(OS, DE.Val, ELFT::TargetEndianness);
} }
if (Section.Content)
Section.Content->writeAsBinary(OS);
return true;
} }
template <class ELFT> bool ELFState<ELFT>::buildSectionIndex() { template <class ELFT> bool ELFState<ELFT>::buildSectionIndex() {