[llvm] 400103f - [yaml2obj/obj2yaml] - Add support of 'Size' and 'Content' keys for all sections.
Georgii Rymar via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 15 01:12:11 PDT 2020
Author: Georgii Rymar
Date: 2020-10-15T11:11:41+03:00
New Revision: 400103f3d5f1f1d3e7dd02531f9db71a049ac507
URL: https://github.com/llvm/llvm-project/commit/400103f3d5f1f1d3e7dd02531f9db71a049ac507
DIFF: https://github.com/llvm/llvm-project/commit/400103f3d5f1f1d3e7dd02531f9db71a049ac507.diff
LOG: [yaml2obj/obj2yaml] - Add support of 'Size' and 'Content' keys for all sections.
Many sections either do not have a support of `Size`/`Content` or support just a
one of them, e.g only `Content`.
`Section` is the base class for sections. This patch adds `Content` and `Size` members
to it and removes similar members from derived classes. This allows to cleanup and
generalize the code and adds a support of these keys for all sections (`SHT_MIPS_ABIFLAGS`
is a only exception, it requires unrelated specific changes to be done).
I had to update/add many tests to test the new functionality properly.
Differential revision: https://reviews.llvm.org/D89039
Added:
llvm/test/tools/yaml2obj/ELF/group.yaml
llvm/test/tools/yaml2obj/ELF/nobits.yaml
llvm/test/tools/yaml2obj/ELF/reloc-sec.yaml
Modified:
llvm/include/llvm/ObjectYAML/ELFYAML.h
llvm/lib/ObjectYAML/ELFEmitter.cpp
llvm/lib/ObjectYAML/ELFYAML.cpp
llvm/test/tools/yaml2obj/ELF/arm-exidx-section.yaml
llvm/test/tools/yaml2obj/ELF/call-graph-profile-section.yaml
llvm/test/tools/yaml2obj/ELF/dynamic-section-raw-content.yaml
llvm/test/tools/yaml2obj/ELF/gnu-hash-section.yaml
llvm/test/tools/yaml2obj/ELF/hash-section.yaml
llvm/test/tools/yaml2obj/ELF/linker-options.yaml
llvm/test/tools/yaml2obj/ELF/llvm-addrsig-section.yaml
llvm/test/tools/yaml2obj/ELF/llvm-deplibs-section.yaml
llvm/test/tools/yaml2obj/ELF/mips-abi-flags.yaml
llvm/test/tools/yaml2obj/ELF/note-section.yaml
llvm/test/tools/yaml2obj/ELF/relr-section.yaml
llvm/test/tools/yaml2obj/ELF/sht-symtab-shndx.yaml
llvm/test/tools/yaml2obj/ELF/stack-sizes.yaml
llvm/test/tools/yaml2obj/ELF/verdef-section.yaml
llvm/test/tools/yaml2obj/ELF/verneed-section.yaml
llvm/test/tools/yaml2obj/ELF/versym-section.yaml
llvm/tools/obj2yaml/elf2yaml.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/ObjectYAML/ELFYAML.h b/llvm/include/llvm/ObjectYAML/ELFYAML.h
index 0581b0b28b68..af6d934d611e 100644
--- a/llvm/include/llvm/ObjectYAML/ELFYAML.h
+++ b/llvm/include/llvm/ObjectYAML/ELFYAML.h
@@ -178,6 +178,9 @@ struct Section : public Chunk {
llvm::yaml::Hex64 AddressAlign;
Optional<llvm::yaml::Hex64> EntSize;
+ Optional<yaml::BinaryRef> Content;
+ Optional<llvm::yaml::Hex64> Size;
+
// Usually sections are not created implicitly, but loaded from YAML.
// When they are, this flag is used to signal about that.
bool IsImplicit;
@@ -228,8 +231,6 @@ struct Fill : Chunk {
};
struct StackSizesSection : Section {
- Optional<yaml::BinaryRef> Content;
- Optional<llvm::yaml::Hex64> Size;
Optional<std::vector<StackSizeEntry>> Entries;
StackSizesSection() : Section(ChunkKind::StackSizes) {}
@@ -244,8 +245,7 @@ struct StackSizesSection : Section {
};
struct DynamicSection : Section {
- std::vector<DynamicEntry> Entries;
- Optional<yaml::BinaryRef> Content;
+ Optional<std::vector<DynamicEntry>> Entries;
DynamicSection() : Section(ChunkKind::Dynamic) {}
@@ -253,8 +253,6 @@ struct DynamicSection : Section {
};
struct RawContentSection : Section {
- Optional<yaml::BinaryRef> Content;
- Optional<llvm::yaml::Hex64> Size;
Optional<llvm::yaml::Hex64> Info;
RawContentSection() : Section(ChunkKind::RawContent) {}
@@ -268,16 +266,12 @@ struct RawContentSection : Section {
};
struct NoBitsSection : Section {
- llvm::yaml::Hex64 Size;
-
NoBitsSection() : Section(ChunkKind::NoBits) {}
static bool classof(const Chunk *S) { return S->Kind == ChunkKind::NoBits; }
};
struct NoteSection : Section {
- Optional<yaml::BinaryRef> Content;
- Optional<llvm::yaml::Hex64> Size;
Optional<std::vector<ELFYAML::NoteEntry>> Notes;
NoteSection() : Section(ChunkKind::Note) {}
@@ -286,8 +280,6 @@ struct NoteSection : Section {
};
struct HashSection : Section {
- Optional<yaml::BinaryRef> Content;
- Optional<llvm::yaml::Hex64> Size;
Optional<std::vector<uint32_t>> Bucket;
Optional<std::vector<uint32_t>> Chain;
@@ -322,8 +314,6 @@ struct GnuHashHeader {
};
struct GnuHashSection : Section {
- Optional<yaml::BinaryRef> Content;
-
Optional<GnuHashHeader> Header;
Optional<std::vector<llvm::yaml::Hex64>> BloomFilter;
Optional<std::vector<llvm::yaml::Hex32>> HashBuckets;
@@ -348,7 +338,6 @@ struct VerneedEntry {
};
struct VerneedSection : Section {
- Optional<yaml::BinaryRef> Content;
Optional<std::vector<VerneedEntry>> VerneedV;
llvm::yaml::Hex64 Info;
@@ -360,8 +349,6 @@ struct VerneedSection : Section {
};
struct AddrsigSection : Section {
- Optional<yaml::BinaryRef> Content;
- Optional<llvm::yaml::Hex64> Size;
Optional<std::vector<YAMLFlowString>> Symbols;
AddrsigSection() : Section(ChunkKind::Addrsig) {}
@@ -376,7 +363,6 @@ struct LinkerOption {
struct LinkerOptionsSection : Section {
Optional<std::vector<LinkerOption>> Options;
- Optional<yaml::BinaryRef> Content;
LinkerOptionsSection() : Section(ChunkKind::LinkerOptions) {}
@@ -387,7 +373,6 @@ struct LinkerOptionsSection : Section {
struct DependentLibrariesSection : Section {
Optional<std::vector<YAMLFlowString>> Libs;
- Optional<yaml::BinaryRef> Content;
DependentLibrariesSection() : Section(ChunkKind::DependentLibraries) {}
@@ -408,7 +393,6 @@ struct CallGraphEntry {
struct CallGraphProfileSection : Section {
Optional<std::vector<CallGraphEntry>> Entries;
- Optional<yaml::BinaryRef> Content;
CallGraphProfileSection() : Section(ChunkKind::CallGraphProfile) {}
@@ -418,7 +402,7 @@ struct CallGraphProfileSection : Section {
};
struct SymverSection : Section {
- std::vector<uint16_t> Entries;
+ Optional<std::vector<uint16_t>> Entries;
SymverSection() : Section(ChunkKind::Symver) {}
@@ -435,7 +419,6 @@ struct VerdefEntry {
struct VerdefSection : Section {
Optional<std::vector<VerdefEntry>> Entries;
- Optional<yaml::BinaryRef> Content;
llvm::yaml::Hex64 Info;
@@ -447,7 +430,7 @@ struct VerdefSection : Section {
struct GroupSection : Section {
// Members of a group contain a flag and a list of section indices
// that are part of the group.
- std::vector<SectionOrType> Members;
+ Optional<std::vector<SectionOrType>> Members;
Optional<StringRef> Signature; /* Info */
GroupSection() : Section(ChunkKind::Group) {}
@@ -463,7 +446,7 @@ struct Relocation {
};
struct RelocationSection : Section {
- std::vector<Relocation> Relocations;
+ Optional<std::vector<Relocation>> Relocations;
StringRef RelocatableSec; /* Info */
RelocationSection() : Section(ChunkKind::Relocation) {}
@@ -475,7 +458,6 @@ struct RelocationSection : Section {
struct RelrSection : Section {
Optional<std::vector<llvm::yaml::Hex64>> Entries;
- Optional<yaml::BinaryRef> Content;
RelrSection() : Section(ChunkKind::Relr) {}
@@ -485,7 +467,7 @@ struct RelrSection : Section {
};
struct SymtabShndxSection : Section {
- std::vector<uint32_t> Entries;
+ Optional<std::vector<uint32_t>> Entries;
SymtabShndxSection() : Section(ChunkKind::SymtabShndxSection) {}
@@ -501,8 +483,6 @@ struct ARMIndexTableEntry {
struct ARMIndexTableSection : Section {
Optional<std::vector<ARMIndexTableEntry>> Entries;
- Optional<yaml::BinaryRef> Content;
- Optional<llvm::yaml::Hex64> Size;
ARMIndexTableSection() : Section(ChunkKind::ARMIndexTable) {}
diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp
index 559c45a56d71..33c4836d0883 100644
--- a/llvm/lib/ObjectYAML/ELFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp
@@ -1126,13 +1126,17 @@ void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
ContiguousBlobAccumulator &CBA) {
// SHT_NOBITS sections do not have any content to write.
SHeader.sh_entsize = 0;
- SHeader.sh_size = S.Size;
+
+ if (!S.Size)
+ return;
+
+ SHeader.sh_size = *S.Size;
// When a nobits section is followed by a non-nobits section or fill
// in the same segment, we allocate the file space for it. This behavior
// matches linkers.
if (shouldAllocateFileSpace(Doc.ProgramHeaders, S))
- CBA.writeZeros(S.Size);
+ CBA.writeZeros(*S.Size);
}
template <class ELFT>
@@ -1167,8 +1171,6 @@ void ELFState<ELFT>::writeSectionContent(
SHeader.sh_entsize = *Section.EntSize;
else
SHeader.sh_entsize = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
- SHeader.sh_size = (IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel)) *
- Section.Relocations.size();
// For relocation section set link to .symtab by default.
unsigned Link = 0;
@@ -1179,7 +1181,15 @@ void ELFState<ELFT>::writeSectionContent(
if (!Section.RelocatableSec.empty())
SHeader.sh_info = toSectionIndex(Section.RelocatableSec, Section.Name);
- for (const auto &Rel : Section.Relocations) {
+ if (Section.Content || Section.Size) {
+ SHeader.sh_size = writeContent(CBA, Section.Content, Section.Size);
+ return;
+ }
+
+ if (!Section.Relocations)
+ return;
+
+ for (const ELFYAML::Relocation &Rel : *Section.Relocations) {
unsigned SymIdx = Rel.Symbol ? toSymbolIndex(*Rel.Symbol, Section.Name,
Section.Link == ".dynsym")
: 0;
@@ -1198,6 +1208,9 @@ void ELFState<ELFT>::writeSectionContent(
CBA.write((const char *)&REntry, sizeof(REntry));
}
}
+
+ SHeader.sh_size = (IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel)) *
+ Section.Relocations->size();
}
template <class ELFT>
@@ -1207,8 +1220,8 @@ void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
SHeader.sh_entsize =
Section.EntSize ? uint64_t(*Section.EntSize) : sizeof(Elf_Relr);
- if (Section.Content) {
- SHeader.sh_size = writeContent(CBA, Section.Content, None);
+ if (Section.Content || Section.Size) {
+ SHeader.sh_size = writeContent(CBA, Section.Content, Section.Size);
return;
}
@@ -1229,11 +1242,19 @@ template <class ELFT>
void ELFState<ELFT>::writeSectionContent(
Elf_Shdr &SHeader, const ELFYAML::SymtabShndxSection &Shndx,
ContiguousBlobAccumulator &CBA) {
- for (uint32_t E : Shndx.Entries)
- CBA.write<uint32_t>(E, ELFT::TargetEndianness);
-
SHeader.sh_entsize = Shndx.EntSize ? (uint64_t)*Shndx.EntSize : 4;
- SHeader.sh_size = Shndx.Entries.size() * SHeader.sh_entsize;
+
+ if (Shndx.Content || Shndx.Size) {
+ SHeader.sh_size = writeContent(CBA, Shndx.Content, Shndx.Size);
+ return;
+ }
+
+ if (!Shndx.Entries)
+ return;
+
+ for (uint32_t E : *Shndx.Entries)
+ CBA.write<uint32_t>(E, ELFT::TargetEndianness);
+ SHeader.sh_size = Shndx.Entries->size() * SHeader.sh_entsize;
}
template <class ELFT>
@@ -1249,13 +1270,20 @@ void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
SHeader.sh_link = Link;
SHeader.sh_entsize = 4;
- SHeader.sh_size = SHeader.sh_entsize * Section.Members.size();
if (Section.Signature)
SHeader.sh_info =
toSymbolIndex(*Section.Signature, Section.Name, /*IsDynamic=*/false);
- for (const ELFYAML::SectionOrType &Member : Section.Members) {
+ if (Section.Content || Section.Size) {
+ SHeader.sh_size = writeContent(CBA, Section.Content, Section.Size);
+ return;
+ }
+
+ if (!Section.Members)
+ return;
+
+ for (const ELFYAML::SectionOrType &Member : *Section.Members) {
unsigned int SectionIndex = 0;
if (Member.sectionNameOrType == "GRP_COMDAT")
SectionIndex = llvm::ELF::GRP_COMDAT;
@@ -1263,17 +1291,26 @@ void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
SectionIndex = toSectionIndex(Member.sectionNameOrType, Section.Name);
CBA.write<uint32_t>(SectionIndex, ELFT::TargetEndianness);
}
+ SHeader.sh_size = SHeader.sh_entsize * Section.Members->size();
}
template <class ELFT>
void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
const ELFYAML::SymverSection &Section,
ContiguousBlobAccumulator &CBA) {
- for (uint16_t Version : Section.Entries)
- CBA.write<uint16_t>(Version, ELFT::TargetEndianness);
-
SHeader.sh_entsize = Section.EntSize ? (uint64_t)*Section.EntSize : 2;
- SHeader.sh_size = Section.Entries.size() * SHeader.sh_entsize;
+
+ if (Section.Content || Section.Size) {
+ SHeader.sh_size = writeContent(CBA, Section.Content, Section.Size);
+ return;
+ }
+
+ if (!Section.Entries)
+ return;
+
+ for (uint16_t Version : *Section.Entries)
+ CBA.write<uint16_t>(Version, ELFT::TargetEndianness);
+ SHeader.sh_size = Section.Entries->size() * SHeader.sh_entsize;
}
template <class ELFT>
@@ -1295,8 +1332,8 @@ template <class ELFT>
void ELFState<ELFT>::writeSectionContent(
Elf_Shdr &SHeader, const ELFYAML::LinkerOptionsSection &Section,
ContiguousBlobAccumulator &CBA) {
- if (Section.Content) {
- SHeader.sh_size = writeContent(CBA, Section.Content, None);
+ if (Section.Content || Section.Size) {
+ SHeader.sh_size = writeContent(CBA, Section.Content, Section.Size);
return;
}
@@ -1316,8 +1353,8 @@ template <class ELFT>
void ELFState<ELFT>::writeSectionContent(
Elf_Shdr &SHeader, const ELFYAML::DependentLibrariesSection &Section,
ContiguousBlobAccumulator &CBA) {
- if (Section.Content) {
- SHeader.sh_size = writeContent(CBA, Section.Content, None);
+ if (Section.Content || Section.Size) {
+ SHeader.sh_size = writeContent(CBA, Section.Content, Section.Size);
return;
}
@@ -1369,8 +1406,8 @@ void ELFState<ELFT>::writeSectionContent(
SN2I.lookup(".symtab", Link))
SHeader.sh_link = Link;
- if (Section.Content) {
- SHeader.sh_size = writeContent(CBA, Section.Content, None);
+ if (Section.Content || Section.Size) {
+ SHeader.sh_size = writeContent(CBA, Section.Content, Section.Size);
return;
}
@@ -1431,8 +1468,8 @@ void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
SHeader.sh_info = Section.Info;
- if (Section.Content) {
- SHeader.sh_size = writeContent(CBA, Section.Content, None);
+ if (Section.Content || Section.Size) {
+ SHeader.sh_size = writeContent(CBA, Section.Content, Section.Size);
return;
}
@@ -1481,8 +1518,8 @@ void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
SHeader.sh_info = Section.Info;
- if (Section.Content) {
- SHeader.sh_size = writeContent(CBA, Section.Content, None);
+ if (Section.Content || Section.Size) {
+ SHeader.sh_size = writeContent(CBA, Section.Content, Section.Size);
return;
}
@@ -1577,26 +1614,24 @@ void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
assert(Section.Type == llvm::ELF::SHT_DYNAMIC &&
"Section type is not SHT_DYNAMIC");
- if (!Section.Entries.empty() && Section.Content)
- reportError("cannot specify both raw content and explicit entries "
- "for dynamic section '" +
- Section.Name + "'");
-
- 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
- SHeader.sh_entsize = sizeof(Elf_Dyn);
+ SHeader.sh_entsize = 2 * sizeof(uintX_t);
+
+ if (Section.Content || Section.Size) {
+ SHeader.sh_size = writeContent(CBA, Section.Content, Section.Size);
+ return;
+ }
+
+ if (!Section.Entries)
+ return;
- for (const ELFYAML::DynamicEntry &DE : Section.Entries) {
+ for (const ELFYAML::DynamicEntry &DE : *Section.Entries) {
CBA.write<uintX_t>(DE.Tag, ELFT::TargetEndianness);
CBA.write<uintX_t>(DE.Val, ELFT::TargetEndianness);
}
- if (Section.Content)
- CBA.writeAsBinary(*Section.Content);
+ SHeader.sh_size = 2 * sizeof(uintX_t) * Section.Entries->size();
}
template <class ELFT>
@@ -1670,8 +1705,8 @@ void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
SN2I.lookup(".dynsym", Link))
SHeader.sh_link = Link;
- if (Section.Content) {
- SHeader.sh_size = writeContent(CBA, Section.Content, None);
+ if (Section.Content || Section.Size) {
+ SHeader.sh_size = writeContent(CBA, Section.Content, Section.Size);
return;
}
diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp
index fe4c2746f063..c66ead0dfea7 100644
--- a/llvm/lib/ObjectYAML/ELFYAML.cpp
+++ b/llvm/lib/ObjectYAML/ELFYAML.cpp
@@ -1105,6 +1105,9 @@ static void commonSectionMapping(IO &IO, ELFYAML::Section &Section) {
IO.mapOptional("EntSize", Section.EntSize);
IO.mapOptional("Offset", Section.Offset);
+ IO.mapOptional("Content", Section.Content);
+ IO.mapOptional("Size", Section.Size);
+
// obj2yaml does not dump these fields. They are expected to be empty when we
// are producing YAML, because yaml2obj sets appropriate values for them
// automatically when they are not explicitly defined.
@@ -1122,12 +1125,10 @@ static void commonSectionMapping(IO &IO, ELFYAML::Section &Section) {
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) {
commonSectionMapping(IO, Section);
- IO.mapOptional("Content", Section.Content);
// We also support reading a content as array of bytes using the ContentArray
// key. obj2yaml never prints this field.
@@ -1139,23 +1140,18 @@ static void sectionMapping(IO &IO, ELFYAML::RawContentSection &Section) {
Section.Content = yaml::BinaryRef(*Section.ContentBuf);
}
- IO.mapOptional("Size", Section.Size);
IO.mapOptional("Info", Section.Info);
}
static void sectionMapping(IO &IO, ELFYAML::StackSizesSection &Section) {
commonSectionMapping(IO, Section);
- IO.mapOptional("Content", Section.Content);
- IO.mapOptional("Size", Section.Size);
IO.mapOptional("Entries", Section.Entries);
}
static void sectionMapping(IO &IO, ELFYAML::HashSection &Section) {
commonSectionMapping(IO, Section);
- IO.mapOptional("Content", Section.Content);
IO.mapOptional("Bucket", Section.Bucket);
IO.mapOptional("Chain", Section.Chain);
- IO.mapOptional("Size", Section.Size);
// obj2yaml does not dump these fields. They can be used to override nchain
// and nbucket values for creating broken sections.
@@ -1167,15 +1163,12 @@ static void sectionMapping(IO &IO, ELFYAML::HashSection &Section) {
static void sectionMapping(IO &IO, ELFYAML::NoteSection &Section) {
commonSectionMapping(IO, Section);
- IO.mapOptional("Content", Section.Content);
- IO.mapOptional("Size", Section.Size);
IO.mapOptional("Notes", Section.Notes);
}
static void sectionMapping(IO &IO, ELFYAML::GnuHashSection &Section) {
commonSectionMapping(IO, Section);
- IO.mapOptional("Content", Section.Content);
IO.mapOptional("Header", Section.Header);
IO.mapOptional("BloomFilter", Section.BloomFilter);
IO.mapOptional("HashBuckets", Section.HashBuckets);
@@ -1183,26 +1176,23 @@ static void sectionMapping(IO &IO, ELFYAML::GnuHashSection &Section) {
}
static void sectionMapping(IO &IO, ELFYAML::NoBitsSection &Section) {
commonSectionMapping(IO, Section);
- IO.mapOptional("Size", Section.Size, Hex64(0));
}
static void sectionMapping(IO &IO, ELFYAML::VerdefSection &Section) {
commonSectionMapping(IO, Section);
IO.mapRequired("Info", Section.Info);
IO.mapOptional("Entries", Section.Entries);
- IO.mapOptional("Content", Section.Content);
}
static void sectionMapping(IO &IO, ELFYAML::SymverSection &Section) {
commonSectionMapping(IO, Section);
- IO.mapRequired("Entries", Section.Entries);
+ IO.mapOptional("Entries", Section.Entries);
}
static void sectionMapping(IO &IO, ELFYAML::VerneedSection &Section) {
commonSectionMapping(IO, Section);
IO.mapRequired("Info", Section.Info);
IO.mapOptional("Dependencies", Section.VerneedV);
- IO.mapOptional("Content", Section.Content);
}
static void sectionMapping(IO &IO, ELFYAML::RelocationSection &Section) {
@@ -1214,24 +1204,21 @@ static void sectionMapping(IO &IO, ELFYAML::RelocationSection &Section) {
static void sectionMapping(IO &IO, ELFYAML::RelrSection &Section) {
commonSectionMapping(IO, Section);
IO.mapOptional("Entries", Section.Entries);
- IO.mapOptional("Content", Section.Content);
}
static void groupSectionMapping(IO &IO, ELFYAML::GroupSection &Group) {
commonSectionMapping(IO, Group);
IO.mapOptional("Info", Group.Signature);
- IO.mapRequired("Members", Group.Members);
+ IO.mapOptional("Members", Group.Members);
}
static void sectionMapping(IO &IO, ELFYAML::SymtabShndxSection &Section) {
commonSectionMapping(IO, Section);
- IO.mapRequired("Entries", Section.Entries);
+ IO.mapOptional("Entries", Section.Entries);
}
static void sectionMapping(IO &IO, ELFYAML::AddrsigSection &Section) {
commonSectionMapping(IO, Section);
- IO.mapOptional("Content", Section.Content);
- IO.mapOptional("Size", Section.Size);
IO.mapOptional("Symbols", Section.Symbols);
}
@@ -1245,20 +1232,17 @@ static void fillMapping(IO &IO, ELFYAML::Fill &Fill) {
static void sectionMapping(IO &IO, ELFYAML::LinkerOptionsSection &Section) {
commonSectionMapping(IO, Section);
IO.mapOptional("Options", Section.Options);
- IO.mapOptional("Content", Section.Content);
}
static void sectionMapping(IO &IO,
ELFYAML::DependentLibrariesSection &Section) {
commonSectionMapping(IO, Section);
IO.mapOptional("Libraries", Section.Libs);
- IO.mapOptional("Content", Section.Content);
}
static void sectionMapping(IO &IO, ELFYAML::CallGraphProfileSection &Section) {
commonSectionMapping(IO, Section);
IO.mapOptional("Entries", Section.Entries);
- IO.mapOptional("Content", Section.Content);
}
void MappingTraits<ELFYAML::SectionOrType>::mapping(
@@ -1273,8 +1257,6 @@ void MappingTraits<ELFYAML::SectionName>::mapping(
static void sectionMapping(IO &IO, ELFYAML::ARMIndexTableSection &Section) {
commonSectionMapping(IO, Section);
- IO.mapOptional("Content", Section.Content);
- IO.mapOptional("Size", Section.Size);
IO.mapOptional("Entries", Section.Entries);
}
@@ -1441,10 +1423,18 @@ void MappingTraits<std::unique_ptr<ELFYAML::Chunk>>::mapping(
StringRef MappingTraits<std::unique_ptr<ELFYAML::Chunk>>::validate(
IO &io, std::unique_ptr<ELFYAML::Chunk> &C) {
+ if (const auto *F = dyn_cast<ELFYAML::Fill>(C.get())) {
+ if (F->Pattern && F->Pattern->binary_size() != 0 && !F->Size)
+ return "\"Size\" can't be 0 when \"Pattern\" is not empty";
+ return {};
+ }
+
+ const ELFYAML::Section &Sec = *cast<ELFYAML::Section>(C.get());
+ if (Sec.Size && Sec.Content &&
+ (uint64_t)(*Sec.Size) < Sec.Content->binary_size())
+ return "Section size must be greater than or equal to the content size";
+
if (const auto *RawSection = dyn_cast<ELFYAML::RawContentSection>(C.get())) {
- if (RawSection->Size && RawSection->Content &&
- (uint64_t)(*RawSection->Size) < RawSection->Content->binary_size())
- return "Section size must be greater than or equal to the content size";
if (RawSection->Flags && RawSection->ShFlags)
return "ShFlags and Flags cannot be used together";
return {};
@@ -1454,11 +1444,6 @@ StringRef MappingTraits<std::unique_ptr<ELFYAML::Chunk>>::validate(
if (!SS->Entries && !SS->Content && !SS->Size)
return ".stack_sizes: one of Content, Entries and Size must be specified";
- if (SS->Size && SS->Content &&
- (uint64_t)(*SS->Size) < SS->Content->binary_size())
- return ".stack_sizes: Size must be greater than or equal to the content "
- "size";
-
// We accept Content, Size or both together when there are no Entries.
if (!SS->Entries)
return {};
@@ -1476,11 +1461,6 @@ StringRef MappingTraits<std::unique_ptr<ELFYAML::Chunk>>::validate(
"specified";
if (HS->Content || HS->Size) {
- if (HS->Size && HS->Content &&
- (uint64_t)*HS->Size < HS->Content->binary_size())
- return "\"Size\" must be greater than or equal to the content "
- "size";
-
if (HS->Bucket)
return "\"Bucket\" cannot be used with \"Content\" or \"Size\"";
if (HS->Chain)
@@ -1497,19 +1477,8 @@ StringRef MappingTraits<std::unique_ptr<ELFYAML::Chunk>>::validate(
if (!Sec->Symbols && !Sec->Content && !Sec->Size)
return "one of \"Content\", \"Size\" or \"Symbols\" must be specified";
- if (Sec->Content || Sec->Size) {
- if (Sec->Size && Sec->Content &&
- (uint64_t)*Sec->Size < Sec->Content->binary_size())
- return "\"Size\" must be greater than or equal to the content "
- "size";
-
- if (Sec->Symbols)
- return "\"Symbols\" cannot be used with \"Content\" or \"Size\"";
- return {};
- }
-
- if (!Sec->Symbols)
- return {};
+ if ((Sec->Content || Sec->Size) && Sec->Symbols)
+ return "\"Symbols\" cannot be used with \"Content\" or \"Size\"";
return {};
}
@@ -1518,23 +1487,15 @@ StringRef MappingTraits<std::unique_ptr<ELFYAML::Chunk>>::validate(
return "one of \"Content\", \"Size\" or \"Notes\" must be "
"specified";
- if (!NS->Content && !NS->Size)
- return {};
-
- if (NS->Size && NS->Content &&
- (uint64_t)*NS->Size < NS->Content->binary_size())
- return "\"Size\" must be greater than or equal to the content "
- "size";
-
- if (NS->Notes)
+ if ((NS->Content || NS->Size) && NS->Notes)
return "\"Notes\" cannot be used with \"Content\" or \"Size\"";
return {};
}
if (const auto *Sec = dyn_cast<ELFYAML::GnuHashSection>(C.get())) {
- if (!Sec->Content && !Sec->Header && !Sec->BloomFilter &&
+ if (!Sec->Content && !Sec->Size && !Sec->Header && !Sec->BloomFilter &&
!Sec->HashBuckets && !Sec->HashValues)
- return "either \"Content\" or \"Header\", \"BloomFilter\", "
+ return "either \"Content\", \"Size\" or \"Header\", \"BloomFilter\", "
"\"HashBuckets\" and \"HashBuckets\" must be specified";
if (Sec->Header || Sec->BloomFilter || Sec->HashBuckets ||
@@ -1543,10 +1504,10 @@ StringRef MappingTraits<std::unique_ptr<ELFYAML::Chunk>>::validate(
!Sec->HashValues)
return "\"Header\", \"BloomFilter\", "
"\"HashBuckets\" and \"HashValues\" must be used together";
- if (Sec->Content)
+ if (Sec->Content || Sec->Size)
return "\"Header\", \"BloomFilter\", "
"\"HashBuckets\" and \"HashValues\" can't be used together with "
- "\"Content\"";
+ "\"Content\" or \"Size\"";
return {};
}
@@ -1555,65 +1516,89 @@ StringRef MappingTraits<std::unique_ptr<ELFYAML::Chunk>>::validate(
}
if (const auto *Sec = dyn_cast<ELFYAML::LinkerOptionsSection>(C.get())) {
- if (Sec->Options && Sec->Content)
- return "\"Options\" and \"Content\" can't be used together";
+ if ((Sec->Content || Sec->Size) && Sec->Options)
+ return "\"Options\" cannot be used with \"Content\" or \"Size\"";
return {};
}
if (const auto *Sec = dyn_cast<ELFYAML::DependentLibrariesSection>(C.get())) {
- if (Sec->Libs && Sec->Content)
- return "SHT_LLVM_DEPENDENT_LIBRARIES: \"Libraries\" and \"Content\" "
- "can't "
- "be used together";
+ if ((Sec->Content || Sec->Size) && Sec->Libs)
+ return "\"Libraries\" cannot be used with \"Content\" or \"Size\"";
return {};
}
- if (const auto *F = dyn_cast<ELFYAML::Fill>(C.get())) {
- if (!F->Pattern)
- return {};
- if (F->Pattern->binary_size() != 0 && !F->Size)
- return "\"Size\" can't be 0 when \"Pattern\" is not empty";
+ if (const auto *VD = dyn_cast<ELFYAML::VerdefSection>(C.get())) {
+ if ((VD->Content || VD->Size) && VD->Entries)
+ return "\"Entries\" cannot be used with \"Content\" or \"Size\"";
return {};
}
- if (const auto *VD = dyn_cast<ELFYAML::VerdefSection>(C.get())) {
- if (VD->Entries && VD->Content)
- return "SHT_GNU_verdef: \"Entries\" and \"Content\" can't be used "
- "together";
+ if (const auto *VN = dyn_cast<ELFYAML::VerneedSection>(C.get())) {
+ if ((VN->Content || VN->Size) && VN->VerneedV)
+ return "\"Dependencies\" cannot be used with \"Content\" or \"Size\"";
return {};
}
- if (const auto *VD = dyn_cast<ELFYAML::VerneedSection>(C.get())) {
- if (VD->VerneedV && VD->Content)
- return "SHT_GNU_verneed: \"Dependencies\" and \"Content\" can't be used "
- "together";
+ if (const auto *SV = dyn_cast<ELFYAML::SymverSection>(C.get())) {
+ if ((SV->Content || SV->Size) && SV->Entries)
+ return "\"Entries\" cannot be used with \"Content\" or \"Size\"";
return {};
}
if (const auto *RS = dyn_cast<ELFYAML::RelrSection>(C.get())) {
- if (RS->Entries && RS->Content)
- return "\"Entries\" and \"Content\" can't be used together";
+ if ((RS->Content || RS->Size) && RS->Entries)
+ return "\"Entries\" cannot be used with \"Content\" or \"Size\"";
return {};
}
if (const auto *CGP = dyn_cast<ELFYAML::CallGraphProfileSection>(C.get())) {
- if (CGP->Entries && CGP->Content)
- return "\"Entries\" and \"Content\" can't be used together";
+ if ((CGP->Content || CGP->Size) && CGP->Entries)
+ return "\"Entries\" cannot be used with \"Content\" or \"Size\"";
return {};
}
if (const auto *IT = dyn_cast<ELFYAML::ARMIndexTableSection>(C.get())) {
- if (IT->Content || IT->Size) {
- if (IT->Size && IT->Content &&
- (uint64_t)*IT->Size < IT->Content->binary_size())
- return "\"Size\" must be greater than or equal to the content "
- "size";
-
- if (IT->Entries)
- return "\"Entries\" cannot be used with \"Content\" or \"Size\"";
- return {};
- }
+ if ((IT->Content || IT->Size) && IT->Entries)
+ return "\"Entries\" cannot be used with \"Content\" or \"Size\"";
+ return {};
+ }
+
+ if (const auto *RS = dyn_cast<ELFYAML::RelocationSection>(C.get())) {
+ if ((RS->Content || RS->Size) && RS->Relocations)
+ return "\"Relocations\" cannot be used with \"Content\" or \"Size\"";
+ return {};
+ }
+
+ if (const auto *SS = dyn_cast<ELFYAML::SymtabShndxSection>(C.get())) {
+ if ((SS->Content || SS->Size) && SS->Entries)
+ return "\"Entries\" cannot be used with \"Content\" or \"Size\"";
+ return {};
+ }
+
+ if (const auto *GS = dyn_cast<ELFYAML::GroupSection>(C.get())) {
+ if ((GS->Content || GS->Size) && GS->Members)
+ return "\"Members\" cannot be used with \"Content\" or \"Size\"";
+ return {};
+ }
+
+ if (const auto *NB = dyn_cast<ELFYAML::NoBitsSection>(C.get())) {
+ if (NB->Content)
+ return "SHT_NOBITS section cannot have \"Content\"";
+ return {};
+ }
+
+ if (const auto *DS = dyn_cast<ELFYAML::DynamicSection>(C.get())) {
+ if ((DS->Content || DS->Size) && DS->Entries)
+ return "\"Entries\" cannot be used with \"Content\" or \"Size\"";
+ return {};
+ }
+ if (const auto *MF = dyn_cast<ELFYAML::MipsABIFlags>(C.get())) {
+ if (MF->Content)
+ return "\"Content\" key is not implemented for SHT_MIPS_ABIFLAGS "
+ "sections";
+ if (MF->Size)
+ return "\"Size\" key is not implemented for SHT_MIPS_ABIFLAGS sections";
return {};
}
diff --git a/llvm/test/tools/yaml2obj/ELF/arm-exidx-section.yaml b/llvm/test/tools/yaml2obj/ELF/arm-exidx-section.yaml
index 4b3d96caa23e..b78a77dd32e6 100644
--- a/llvm/test/tools/yaml2obj/ELF/arm-exidx-section.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/arm-exidx-section.yaml
@@ -73,7 +73,7 @@ Sections:
AddressAlign: 0x55
EntSize: 0x66
-## Check we can't use "Entries" key together with "Content" or "Size" keys.
+## Check we can't use the "Entries" key together with the "Content" or "Size" keys.
# RUN: not yaml2obj --docnum=3 -DSIZE=0 -DENT="[]" %s 2>&1 | \
# RUN: FileCheck %s --check-prefix=ENTRIES-ERR
@@ -95,13 +95,13 @@ Sections:
Content: [[CONTENT=<none>]]
Entries: [[ENT=<none>]]
-## Check we can use "Content" key with "Size" key when the size is greater
+## Check we can use the "Content" key with the "Size" key when the size is greater
## than or equal to the content size.
# RUN: not yaml2obj --docnum=3 -DCONTENT="'00'" -DSIZE=0 %s 2>&1 | \
# RUN: FileCheck %s --check-prefix=CONTENT-SIZE-ERR
-# CONTENT-SIZE-ERR: error: "Size" must be greater than or equal to the content size
+# CONTENT-SIZE-ERR: error: Section size must be greater than or equal to the content size
# RUN: yaml2obj --docnum=3 -DCONTENT="'00'" -DSIZE=1 %s -o %t.cont.size.eq.o
# RUN: llvm-readobj --sections --section-data %t.cont.size.eq.o | \
diff --git a/llvm/test/tools/yaml2obj/ELF/call-graph-profile-section.yaml b/llvm/test/tools/yaml2obj/ELF/call-graph-profile-section.yaml
index f911103ac06f..c52add3a0217 100644
--- a/llvm/test/tools/yaml2obj/ELF/call-graph-profile-section.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/call-graph-profile-section.yaml
@@ -68,7 +68,7 @@ Symbols:
- Name: bar
## Check we can set arbitrary sh_link and sh_entsize values.
-## Check we can specify neither "Content" nor "Entries" tags.
+## Check we can specify none of "Content", "Entries", and "Size" tags.
# RUN: yaml2obj --docnum=2 %s -o %t.link
# RUN: llvm-readelf --sections %t.link | FileCheck %s --check-prefix=LINK
@@ -91,23 +91,8 @@ Sections:
Link: 0xFF
EntSize: 0xFF
-## Check we can't specify both "Content" and "Entries" tags.
-# RUN: not yaml2obj --docnum=3 %s 2>&1 | FileCheck %s --check-prefix=BOTH
-# BOTH: error: "Entries" and "Content" can't be used together
-
---- !ELF
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_DYN
-Sections:
- - Name: .llvm.foo
- Type: SHT_LLVM_CALL_GRAPH_PROFILE
- Content: ""
- Entries: []
-
## Check we can refer to symbols by name.
-# RUN: yaml2obj --docnum=4 %s -o %t.sym
+# RUN: yaml2obj --docnum=3 %s -o %t.sym
# RUN: llvm-readobj --cg-profile %t.sym | FileCheck %s --check-prefix=SYMBOL-NAMES
# SYMBOL-NAMES: CGProfile [
@@ -146,7 +131,7 @@ Symbols:
- Name: 'foo (1)'
## Check we can describe SHT_LLVM_CALL_GRAPH_PROFILE sections using the "Content" tag.
-# RUN: yaml2obj --docnum=5 %s -o %t.content
+# RUN: yaml2obj --docnum=4 %s -o %t.content
# RUN: llvm-readobj --sections --section-data %t.content | FileCheck %s --check-prefix=CONTENT
# CONTENT: Name: .llvm.call-graph-profile
@@ -165,8 +150,8 @@ Sections:
Content: "11223344"
## Check we can't reference unknown symbols by name.
+# RUN: not yaml2obj --docnum=5 %s 2>&1 | FileCheck %s --check-prefix=UNKNOWN-NAME
# RUN: not yaml2obj --docnum=6 %s 2>&1 | FileCheck %s --check-prefix=UNKNOWN-NAME
-# RUN: not yaml2obj --docnum=7 %s 2>&1 | FileCheck %s --check-prefix=UNKNOWN-NAME
# UNKNOWN-NAME: error: unknown symbol referenced: 'bar' by YAML section '.llvm.call-graph-profile'
--- !ELF
@@ -202,7 +187,7 @@ Symbols:
- Name: foo
## Check we can specify arbitrary symbol indexes for an SHT_LLVM_CALL_GRAPH_PROFILE section entry.
-# RUN: yaml2obj --docnum=8 %s -o %t.unk
+# RUN: yaml2obj --docnum=7 %s -o %t.unk
# RUN: llvm-readobj --sections --section-data %t.unk | FileCheck %s --check-prefix=UNKNOWN-INDEX
# UNKNOWN-INDEX: Name: .llvm.call-graph-profile
@@ -222,3 +207,69 @@ Sections:
- From: 1
To: 2
Weight: 3
+
+## Check we can use the "Content" key with the "Size" key when the size is greater
+## than or equal to the content size.
+
+# RUN: not yaml2obj --docnum=8 -DSIZE=1 -DCONTENT="'0011'" %s 2>&1 | \
+# RUN: FileCheck %s --check-prefix=CONTENT-SIZE-ERR
+
+# CONTENT-SIZE-ERR: error: Section size must be greater than or equal to the content size
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_DYN
+Sections:
+ - Name: .llvm.foo
+ Type: SHT_LLVM_CALL_GRAPH_PROFILE
+ Link: 0x1
+ EntSize: 0x2
+ Size: [[SIZE=<none>]]
+ Content: [[CONTENT=<none>]]
+ Entries: [[ENTRIES=<none>]]
+
+# RUN: yaml2obj --docnum=8 -DSIZE=2 -DCONTENT="'0011'" %s -o %t.cont.size.eq.o
+# RUN: llvm-readobj --sections --section-data %t.cont.size.eq.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="0011"
+
+# RUN: yaml2obj --docnum=8 -DSIZE=3 -DCONTENT="'0011'" %s -o %t.cont.size.gr.o
+# RUN: llvm-readobj --sections --section-data %t.cont.size.gr.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="001100"
+
+# CHECK-CONTENT: Name: .llvm.foo
+# CHECK-CONTENT-NEXT: Type: SHT_LLVM_CALL_GRAPH_PROFILE
+# CHECK-CONTENT-NEXT: Flags [
+# CHECK-CONTENT-NEXT: ]
+# CHECK-CONTENT-NEXT: Address:
+# CHECK-CONTENT-NEXT: Offset:
+# CHECK-CONTENT-NEXT: Size:
+# CHECK-CONTENT-NEXT: Link: 1
+# CHECK-CONTENT-NEXT: Info:
+# CHECK-CONTENT-NEXT: AddressAlignment:
+# CHECK-CONTENT-NEXT: EntrySize: 2
+# CHECK-CONTENT-NEXT: SectionData (
+# CHECK-CONTENT-NEXT: 0000: [[DATA]] |
+# CHECK-CONTENT-NEXT: )
+
+## Check we can use the "Size" key alone to create the section.
+
+# RUN: yaml2obj --docnum=8 -DSIZE=3 %s -o %t.size.o
+# RUN: llvm-readobj --sections --section-data %t.size.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="000000"
+
+## Check we can use the "Content" key alone to create the section.
+
+# RUN: yaml2obj --docnum=8 -DCONTENT="'112233'" %s -o %t.content.o
+# RUN: llvm-readobj --sections --section-data %t.content.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="112233"
+
+## Check we can't use the "Entries" key together with the "Content" or "Size" keys.
+
+# RUN: not yaml2obj --docnum=8 -DSIZE=0 -DENTRIES="[]" %s 2>&1 | \
+# RUN: FileCheck %s --check-prefix=ENTRIES-ERR
+# RUN: not yaml2obj --docnum=8 -DCONTENT="'00'" -DENTRIES="[]" %s 2>&1 | \
+# RUN: FileCheck %s --check-prefix=ENTRIES-ERR
+
+# ENTRIES-ERR: error: "Entries" cannot be used with "Content" or "Size"
diff --git a/llvm/test/tools/yaml2obj/ELF/dynamic-section-raw-content.yaml b/llvm/test/tools/yaml2obj/ELF/dynamic-section-raw-content.yaml
index 7c4edf4c4ce3..06354f4946d9 100644
--- a/llvm/test/tools/yaml2obj/ELF/dynamic-section-raw-content.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/dynamic-section-raw-content.yaml
@@ -1,19 +1,18 @@
-## 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.
+## Check how "Content", "Size" and "Entries" keys can be used to
+## describe a content for relocations sections.
-# RUN: yaml2obj --docnum=1 %s -o %t1
-# RUN: llvm-readobj -x .dynamic --sections %t1 | FileCheck %s --check-prefix=RAW
+## Check we can use the "Content" key alone.
-# RAW: Name: .dynamic
-# RAW-NEXT: Type: SHT_DYNAMIC
-# RAW-NEXT: Flags [
-# RAW-NEXT: ]
-# RAW-NEXT: Address:
-# RAW-NEXT: Offset:
-# RAW-NEXT: Size: 16
+# RUN: yaml2obj -DCONTENT="01234567" %s -o %t1.content
+# RUN: llvm-readobj --sections --section-data %t1.content | \
+# RUN: FileCheck %s --check-prefix=RAW -DDATA="01234567"
-# RAW: Hex dump of section '.dynamic':
-# RAW-NEXT: 0x00000000 01234567 89012345 67890000 00000000 {{.*}}
+# RAW: Name: .dynamic
+# RAW: EntrySize:
+# RAW-SAME: 255{{$}}
+# RAW: SectionData (
+# RAW-NEXT: 0000: [[DATA]] |
+# RAW-NEXT: )
--- !ELF
FileHeader:
@@ -21,30 +20,49 @@ FileHeader:
Data: ELFDATA2LSB
Type: ET_EXEC
Sections:
- - Name: .dynamic
- Type: SHT_DYNAMIC
- Content: "01234567890123456789000000000000"
+ - Name: .dynamic
+ Type: SHT_DYNAMIC
+ EntSize: 0xff
+ Content: [[CONTENT=<none>]]
+ Size: [[SIZE=<none>]]
+ Entries: [[ENTRIES=<none>]]
-# RUN: not yaml2obj --docnum=2 %s 2>&1 | FileCheck %s --check-prefix=ERR
+## Check we can use the "Size" key alone.
-# ERR: cannot specify both raw content and explicit entries for dynamic section '.dynamic1'
-# ERR: cannot specify both raw content and explicit entries for dynamic section '.dynamic2'
+# RUN: yaml2obj -DSIZE=3 %s -o %t1.size
+# RUN: llvm-readobj --sections --section-data %t1.size | \
+# RUN: FileCheck %s --check-prefix=RAW -DDATA="000000"
---- !ELF
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_EXEC
-Sections:
- - Name: .dynamic1
- Type: SHT_DYNAMIC
- Content: "0123456789"
- Entries:
- - Tag: DT_STRSZ
- Value: 0
- - Name: .dynamic2
- Type: SHT_DYNAMIC
- Content: "0123456789"
- Entries:
- - Tag: DT_STRSZ
- Value: 0
+## Check we can use the "Content" key with the "Size" key when the size is greater
+## than or equal to the content size.
+
+# RUN: not yaml2obj -DSIZE=1 -DCONTENT="'0011'" %s 2>&1 | \
+# RUN: FileCheck %s --check-prefix=CONTENT-SIZE-ERR
+
+# CONTENT-SIZE-ERR: error: Section size must be greater than or equal to the content size
+
+# RUN: yaml2obj -DSIZE=2 -DCONTENT="'0011'" %s -o %t.cont.size.eq.o
+# RUN: llvm-readobj --sections --section-data %t.cont.size.eq.o | \
+# RUN: FileCheck %s --check-prefix=RAW -DDATA="0011"
+
+# RUN: yaml2obj -DSIZE=3 -DCONTENT="'0011'" %s -o %t.cont.size.gr.o
+# RUN: llvm-readobj --sections --section-data %t.cont.size.gr.o | \
+# RUN: FileCheck %s --check-prefix=RAW -DDATA="001100"
+
+## Check we can't use the "Entries" key together with the "Content" or "Size" keys.
+
+# RUN: not yaml2obj -DSIZE=0 -DENTRIES="[]" %s 2>&1 | \
+# RUN: FileCheck %s --check-prefix=ENT-ERR
+# RUN: not yaml2obj -DCONTENT="'00'" -DENTRIES="[]" %s 2>&1 | \
+# RUN: FileCheck %s --check-prefix=ENT-ERR
+
+# ENT-ERR: error: "Entries" cannot be used with "Content" or "Size"
+
+## Check we create an empty section when none of "Size", "Content" or "Entries" are specified.
+
+# RUN: yaml2obj %s -o %t.empty.o
+# RUN: llvm-readelf --sections --section-data %t.empty.o | \
+# RUN: FileCheck %s --check-prefix=EMPTY-SEC
+
+# EMPTY-SEC: [Nr] Name Type Address Off Size
+# EMPTY-SEC: [ 1] .dynamic DYNAMIC 0000000000000000 000040 000000
diff --git a/llvm/test/tools/yaml2obj/ELF/gnu-hash-section.yaml b/llvm/test/tools/yaml2obj/ELF/gnu-hash-section.yaml
index ae0791051dd5..846e40519624 100644
--- a/llvm/test/tools/yaml2obj/ELF/gnu-hash-section.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/gnu-hash-section.yaml
@@ -213,7 +213,7 @@ Sections:
# RUN: not yaml2obj --docnum=10 %s -o %t10 2>&1 | FileCheck %s --check-prefix=NOKEYS
-# NOKEYS: error: either "Content" or "Header", "BloomFilter", "HashBuckets" and "HashBuckets" must be specified
+# NOKEYS: error: either "Content", "Size" or "Header", "BloomFilter", "HashBuckets" and "HashBuckets" must be specified
--- !ELF
FileHeader:
@@ -224,11 +224,11 @@ Sections:
- Name: .gnu.hash
Type: SHT_GNU_HASH
-## Test that "Header", "BloomFilter", "HashBuckets" and "HashValues" can't be used together with "Content".
+## Test that "Header", "BloomFilter", "HashBuckets" and "HashValues" can't be used together with the "Content" or "Size"
-# RUN: not yaml2obj --docnum=11 %s -o %t11 2>&1 | FileCheck %s --check-prefix=TOGETHER
-
-# TOGETHER: error: "Header", "BloomFilter", "HashBuckets" and "HashValues" can't be used together with "Content"
+# RUN: not yaml2obj --docnum=11 -DCONTENT="" %s 2>&1 | FileCheck %s --check-prefix=TOGETHER
+# RUN: not yaml2obj --docnum=11 -DSIZE=0 %s 2>&1 | FileCheck %s --check-prefix=TOGETHER
+# TOGETHER: error: "Header", "BloomFilter", "HashBuckets" and "HashValues" can't be used together with "Content" or "Size"
--- !ELF
FileHeader:
@@ -236,9 +236,10 @@ FileHeader:
Data: ELFDATA2LSB
Type: ET_DYN
Sections:
- - Name: .gnu.hash
- Type: SHT_GNU_HASH
- Content: ""
+ - Name: .gnu.hash
+ Type: SHT_GNU_HASH
+ Content: [[CONTENT=<none>]]
+ Size: [[SIZE=<none>]]
Header:
SymNdx: 0x0
Shift2: 0x0
@@ -273,3 +274,47 @@ Sections:
BloomFilter: []
HashBuckets: []
HashValues: []
+
+## Check we can use the "Content" key with the "Size" key when the size is greater
+## than or equal to the content size.
+
+# RUN: not yaml2obj --docnum=13 -DSIZE=1 -DCONTENT="'0011'" %s 2>&1 | \
+# RUN: FileCheck %s --check-prefix=CONTENT-SIZE-ERR
+
+# CONTENT-SIZE-ERR: error: Section size must be greater than or equal to the content size
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_DYN
+Sections:
+ - Name: .gnu.hash
+ Type: SHT_GNU_HASH
+ Size: [[SIZE=<none>]]
+ Content: [[CONTENT=<none>]]
+
+# RUN: yaml2obj --docnum=13 -DSIZE=2 -DCONTENT="'0011'" %s -o %t.cont.size.eq.o
+# RUN: llvm-readobj --sections --section-data %t.cont.size.eq.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="0011"
+
+# RUN: yaml2obj --docnum=13 -DSIZE=3 -DCONTENT="'0011'" %s -o %t.cont.size.gr.o
+# RUN: llvm-readobj --sections --section-data %t.cont.size.gr.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="001100"
+
+# CHECK-CONTENT: Name: .gnu.hash
+# CHECK-CONTENT: SectionData (
+# CHECK-CONTENT-NEXT: 0000: [[DATA]] |
+# CHECK-CONTENT-NEXT: )
+
+## Check we can use the "Size" key alone to create the section.
+
+# RUN: yaml2obj --docnum=13 -DSIZE=3 %s -o %t.size.o
+# RUN: llvm-readobj --sections --section-data %t.size.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="000000"
+
+## Check we can use the "Content" key alone to create the section.
+
+# RUN: yaml2obj --docnum=13 -DCONTENT="'112233'" %s -o %t.content.o
+# RUN: llvm-readobj --sections --section-data %t.content.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="112233"
diff --git a/llvm/test/tools/yaml2obj/ELF/group.yaml b/llvm/test/tools/yaml2obj/ELF/group.yaml
new file mode 100644
index 000000000000..56794d9f14d7
--- /dev/null
+++ b/llvm/test/tools/yaml2obj/ELF/group.yaml
@@ -0,0 +1,77 @@
+## Check how the "Content", "Size" and "Members" keys can be used to
+## describe the content for group sections.
+
+## Check we can use the "Content" key with the "Size" key when the size is greater
+## than or equal to the content size.
+
+# RUN: not yaml2obj -DSIZE=1 -DCONTENT="'0011'" %s 2>&1 | \
+# RUN: FileCheck %s --check-prefix=CONTENT-SIZE-ERR
+
+# CONTENT-SIZE-ERR: error: Section size must be greater than or equal to the content size
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_DYN
+Sections:
+ - Name: .group
+ Type: SHT_GROUP
+ Link: 0x1
+ Info: 0x2
+ Size: [[SIZE=<none>]]
+ Content: [[CONTENT=<none>]]
+ Members: [[MEMBERS=<none>]]
+
+# RUN: yaml2obj -DSIZE=2 -DCONTENT="'0011'" %s -o %t.cont.size.eq.o
+# RUN: llvm-readobj --sections --section-data %t.cont.size.eq.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="0011"
+
+# RUN: yaml2obj -DSIZE=3 -DCONTENT="'0011'" %s -o %t.cont.size.gr.o
+# RUN: llvm-readobj --sections --section-data %t.cont.size.gr.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="001100"
+
+# CHECK-CONTENT: Name: .group
+# CHECK-CONTENT-NEXT: Type: SHT_GROUP
+# CHECK-CONTENT-NEXT: Flags [
+# CHECK-CONTENT-NEXT: ]
+# CHECK-CONTENT-NEXT: Address:
+# CHECK-CONTENT-NEXT: Offset:
+# CHECK-CONTENT-NEXT: Size:
+# CHECK-CONTENT-NEXT: Link: 1
+# CHECK-CONTENT-NEXT: Info: 2
+# CHECK-CONTENT-NEXT: AddressAlignment:
+# CHECK-CONTENT-NEXT: EntrySize: 4
+# CHECK-CONTENT-NEXT: SectionData (
+# CHECK-CONTENT-NEXT: 0000: [[DATA]] |
+# CHECK-CONTENT-NEXT: )
+
+## Check we can use the "Size" key alone to create the section.
+
+# RUN: yaml2obj -DSIZE=3 %s -o %t.size.o
+# RUN: llvm-readobj --sections --section-data %t.size.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="000000"
+
+## Check we can use the "Content" key alone to create the section.
+
+# RUN: yaml2obj -DCONTENT="'112233'" %s -o %t.content.o
+# RUN: llvm-readobj --sections --section-data %t.content.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="112233"
+
+## Check we can't use the "Members" key together with the "Content" or "Size" keys.
+
+# RUN: not yaml2obj -DSIZE=0 -DMEMBERS="[]" %s 2>&1 | \
+# RUN: FileCheck %s --check-prefix=MEMBERS-ERR
+# RUN: not yaml2obj -DCONTENT="'00'" -DMEMBERS="[]" %s 2>&1 | \
+# RUN: FileCheck %s --check-prefix=MEMBERS-ERR
+
+# MEMBERS-ERR: error: "Members" cannot be used with "Content" or "Size"
+
+## Check we create an empty section when none of "Size", "Content" or "Members" are specified.
+
+# RUN: yaml2obj %s -o %t.empty.o
+# RUN: llvm-readelf --sections --section-data %t.empty.o | \
+# RUN: FileCheck %s --check-prefix=EMPTY-SEC
+
+# EMPTY-SEC: [Nr] Name Type Address Off Size
+# EMPTY-SEC: [ 1] .group GROUP 0000000000000000 000040 000000
diff --git a/llvm/test/tools/yaml2obj/ELF/hash-section.yaml b/llvm/test/tools/yaml2obj/ELF/hash-section.yaml
index 35e086a49bd3..4ec461d10612 100644
--- a/llvm/test/tools/yaml2obj/ELF/hash-section.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/hash-section.yaml
@@ -230,7 +230,7 @@ Sections:
# RUN: not yaml2obj --docnum=11 %s 2>&1 | FileCheck %s --check-prefix=SIZE-CONTENT-ERR
-# SIZE-CONTENT-ERR: error: "Size" must be greater than or equal to the content size
+# SIZE-CONTENT-ERR: error: Section size must be greater than or equal to the content size
--- !ELF
FileHeader:
diff --git a/llvm/test/tools/yaml2obj/ELF/linker-options.yaml b/llvm/test/tools/yaml2obj/ELF/linker-options.yaml
index 5af4fa70e52a..29d0a4b6d235 100644
--- a/llvm/test/tools/yaml2obj/ELF/linker-options.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/linker-options.yaml
@@ -1,7 +1,7 @@
## Check we are able to produce a valid SHT_LLVM_LINKER_OPTIONS
## section from its description.
-## Check we can use either "Options" or "Content" to describe the data.
+## Check we can use "Options", "Size" and "Content" alone to describe the data.
# RUN: yaml2obj --docnum=1 %s -o %t1
# RUN: llvm-readobj --string-dump .linker-options1 --sections --section-data %t1 \
@@ -25,6 +25,12 @@
# OPTIONS-NEXT: 0000: 00112233 |
# OPTIONS-NEXT: )
+# OPTIONS: Name: .linker-options3
+# OPTIONS-NEXT: Type: SHT_LLVM_LINKER_OPTIONS
+# OPTIONS: SectionData (
+# OPTIONS-NEXT: 0000: 00000000 |
+# OPTIONS-NEXT: )
+
# OPTIONS: String dump of section '.linker-options1':
# OPTIONS-NEXT: [ 0] option 0
# OPTIONS-NEXT: [ 9] value 0
@@ -47,6 +53,9 @@ Sections:
- Name: .linker-options2
Type: SHT_LLVM_LINKER_OPTIONS
Content: "00112233"
+ - Name: .linker-options3
+ Type: SHT_LLVM_LINKER_OPTIONS
+ Size: 4
## Check that "Value" and "Name" fields are mandatory when using "Options" key.
@@ -78,11 +87,15 @@ Sections:
Options:
- Value: value
-## Check we can't use both "Options" and "Content" together.
+## Check we can't use "Options" or "Size" keys together with the "Content" key.
+
+# RUN: not yaml2obj %s -DOPTIONS="[]" -DCONTENT="''" --docnum=4 2>&1 | \
+# RUN: FileCheck %s --check-prefix=TOGETHER
-# RUN: not yaml2obj %s --docnum=4 2>&1 | FileCheck %s --check-prefix=BOTH
+# RUN: not yaml2obj %s -DOPTIONS="[]" -DSIZE="0" --docnum=4 2>&1 | \
+# RUN: FileCheck %s --check-prefix=TOGETHER
-# BOTH: error: "Options" and "Content" can't be used together
+# TOGETHER: error: "Options" cannot be used with "Content" or "Size"
--- !ELF
FileHeader:
@@ -90,26 +103,37 @@ FileHeader:
Data: ELFDATA2LSB
Type: ET_REL
Sections:
- - Name: .linker-options
- Type: SHT_LLVM_LINKER_OPTIONS
- Options:
- - Name: name
- Value: value
- Content: "00112233"
+ - Name: .linker-options
+ Type: SHT_LLVM_LINKER_OPTIONS
+ Options: [[OPTIONS=<none>]]
+ Content: [[CONTENT=<none>]]
+ Size: [[SIZE=<none>]]
-## Check we can omit both "Options" and "Content". This produces an empty section.
+## Check we can omit "Options", "Content" and "Size" keys. This produces an empty section.
-# RUN: yaml2obj %s --docnum=5 2>&1 -o %t5
+# RUN: yaml2obj %s --docnum=4 2>&1 -o %t5
# RUN: llvm-readelf --sections %t5 | FileCheck %s --check-prefix=NONE
# NONE: [Nr] Name Type Address Off Size
# NONE: [ 1] .linker-options LLVM_LINKER_OPTIONS 0000000000000000 000040 000000
---- !ELF
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_REL
-Sections:
- - Name: .linker-options
- Type: SHT_LLVM_LINKER_OPTIONS
+## Check we can use the "Content" key with the "Size" key when the size is greater
+## than or equal to the content size.
+
+# RUN: not yaml2obj --docnum=4 -DSIZE=1 -DCONTENT="'0011'" %s 2>&1 | \
+# RUN: FileCheck %s --check-prefix=CONTENT-SIZE-ERR
+
+# CONTENT-SIZE-ERR: error: Section size must be greater than or equal to the content size
+
+# RUN: yaml2obj --docnum=4 -DSIZE=2 -DCONTENT="'0011'" %s -o %t.cont.size.eq.o
+# RUN: llvm-readobj --sections --section-data %t.cont.size.eq.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="0011"
+
+# CHECK-CONTENT: Name: .linker-options (1)
+# CHECK-CONTENT: SectionData (
+# CHECK-CONTENT-NEXT: 0000: [[DATA]] |
+# CHECK-CONTENT-NEXT: )
+
+# RUN: yaml2obj --docnum=4 -DSIZE=3 -DCONTENT="'0011'" %s -o %t.cont.size.gr.o
+# RUN: llvm-readobj --sections --section-data %t.cont.size.gr.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="001100"
diff --git a/llvm/test/tools/yaml2obj/ELF/llvm-addrsig-section.yaml b/llvm/test/tools/yaml2obj/ELF/llvm-addrsig-section.yaml
index 3cbd939b4b99..6cc0fedd8a37 100644
--- a/llvm/test/tools/yaml2obj/ELF/llvm-addrsig-section.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/llvm-addrsig-section.yaml
@@ -232,7 +232,7 @@ Sections:
# RUN: not yaml2obj --docnum=11 %s 2>&1 | FileCheck %s --check-prefix=SIZE-CONTENT-ERR
-# SIZE-CONTENT-ERR: error: "Size" must be greater than or equal to the content size
+# SIZE-CONTENT-ERR: error: Section size must be greater than or equal to the content size
--- !ELF
FileHeader:
diff --git a/llvm/test/tools/yaml2obj/ELF/llvm-deplibs-section.yaml b/llvm/test/tools/yaml2obj/ELF/llvm-deplibs-section.yaml
index 531a71db4e97..1a1a12d84b39 100644
--- a/llvm/test/tools/yaml2obj/ELF/llvm-deplibs-section.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/llvm-deplibs-section.yaml
@@ -1,7 +1,7 @@
## Check how yaml2obj produces SHT_LLVM_DEPENDENT_LIBRARIES sections.
## Check we can describe SHT_LLVM_DEPENDENT_LIBRARIES using
-## "Libraries" and "Content" properies.
+## "Libraries", "Size" and "Content" properies.
# RUN: yaml2obj --docnum=1 %s -o %t1
# RUN: llvm-readobj --sections --section-data %t1 | FileCheck %s --check-prefix=LIBRARIES
@@ -36,6 +36,21 @@
# LIBRARIES-NEXT: 0000: 112233
# LIBRARIES-NEXT: )
+# LIBRARIES: Name: .deplibs.size
+# LIBRARIES-NEXT: Type: SHT_LLVM_DEPENDENT_LIBRARIES
+# LIBRARIES-NEXT: Flags [ (0x0)
+# LIBRARIES-NEXT: ]
+# LIBRARIES-NEXT: Address: 0x0
+# LIBRARIES-NEXT: Offset: 0x4F
+# LIBRARIES-NEXT: Size: 3
+# LIBRARIES-NEXT: Link: 0
+# LIBRARIES-NEXT: Info: 0
+# LIBRARIES-NEXT: AddressAlignment: 0
+# LIBRARIES-NEXT: EntrySize: 0
+# LIBRARIES-NEXT: SectionData (
+# LIBRARIES-NEXT: 0000: 000000 |
+# LIBRARIES-NEXT: )
+
--- !ELF
FileHeader:
Class: ELFCLASS64
@@ -48,12 +63,16 @@ Sections:
- Name: .deplibs.content
Type: SHT_LLVM_DEPENDENT_LIBRARIES
Content: "112233"
+ - Name: .deplibs.size
+ Type: SHT_LLVM_DEPENDENT_LIBRARIES
+ Size: 0x3
-## Check we report an error when "Libraries" and "Content" are used together.
+## Check we report an error when "Libraries" and "Content"/"Size" keys are used together.
-# RUN: not yaml2obj --docnum=2 %s 2>&1 | FileCheck %s --check-prefix=LIBS-CONTENT
+# RUN: not yaml2obj --docnum=2 -DCONTENT="FF" -DLIBS="[]" %s 2>&1 | FileCheck %s --check-prefix=LIBS-ERR
+# RUN: not yaml2obj --docnum=2 -DSIZE=0 -DLIBS="[]" %s 2>&1 | FileCheck %s --check-prefix=LIBS-ERR
-# LIBS-CONTENT: error: SHT_LLVM_DEPENDENT_LIBRARIES: "Libraries" and "Content" can't be used together
+# LIBS-ERR: error: "Libraries" cannot be used with "Content" or "Size"
--- !ELF
FileHeader:
@@ -63,22 +82,35 @@ FileHeader:
Sections:
- Name: .deplibs
Type: SHT_LLVM_DEPENDENT_LIBRARIES
- Content: "FF"
- Libraries: [ foo ]
+ Content: [[CONTENT=<none>]]
+ Size: [[SIZE=<none>]]
+ Libraries: [[LIBS=<none>]]
-## Check we create an empty section when neither "Libraries" nor "Content" are specified.
+## Check we create an empty section when none of "Libraries", "Size" or "Content" are specified.
-# RUN: yaml2obj --docnum=3 %s -o %t3
-# RUN: llvm-readelf --sections %t3 | FileCheck %s --check-prefix=NOPROPS
+# RUN: yaml2obj --docnum=2 %s -o %t2.empty
+# RUN: llvm-readelf --sections %t2.empty | FileCheck %s --check-prefix=EMPTY
-# NOPROPS: [Nr] Name Type Address Off Size
-# NOPROPS: [ 1] .deplibs LLVM_DEPENDENT_LIBRARIES 0000000000000000 000040 000000
-
---- !ELF
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_REL
-Sections:
- - Name: .deplibs
- Type: SHT_LLVM_DEPENDENT_LIBRARIES
+# EMPTY: [Nr] Name Type Address Off Size
+# EMPTY: [ 1] .deplibs LLVM_DEPENDENT_LIBRARIES 0000000000000000 000040 000000
+
+## Check we can use the "Content" key with the "Size" key when the size is greater
+## than or equal to the content size.
+
+# RUN: not yaml2obj --docnum=2 -DSIZE=1 -DCONTENT="'0011'" %s 2>&1 | \
+# RUN: FileCheck %s --check-prefix=CONTENT-SIZE-ERR
+
+# CONTENT-SIZE-ERR: error: Section size must be greater than or equal to the content size
+
+# RUN: yaml2obj --docnum=2 -DSIZE=2 -DCONTENT="'0011'" %s -o %t.cont.size.eq.o
+# RUN: llvm-readobj --sections --section-data %t.cont.size.eq.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="0011"
+
+# RUN: yaml2obj --docnum=2 -DSIZE=3 -DCONTENT="'0011'" %s -o %t.cont.size.gr.o
+# RUN: llvm-readobj --sections --section-data %t.cont.size.gr.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="001100"
+
+# CHECK-CONTENT: Name: .deplibs
+# CHECK-CONTENT: SectionData (
+# CHECK-CONTENT-NEXT: 0000: [[DATA]] |
+# CHECK-CONTENT-NEXT: )
diff --git a/llvm/test/tools/yaml2obj/ELF/mips-abi-flags.yaml b/llvm/test/tools/yaml2obj/ELF/mips-abi-flags.yaml
index 749914b5d8de..df68fc5f684a 100644
--- a/llvm/test/tools/yaml2obj/ELF/mips-abi-flags.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/mips-abi-flags.yaml
@@ -43,6 +43,8 @@ Sections:
CPR2Size: REG_NONE
Flags1: [ ODDSPREG ]
Flags2: 0x0
+ Content: [[CONTENT=<none>]]
+ Size: [[SIZE=<none>]]
## Check we don't recognize the SHT_MIPS_ABIFLAGS section for non-MIPS targets.
@@ -50,3 +52,15 @@ Sections:
# ERR: error: invalid hex32 number
# ERR-NEXT: Type: SHT_MIPS_ABIFLAGS
+
+## Document we don't support the "Content" key yet.
+
+# RUN: not yaml2obj %s -DCONTENT="'00'" 2>&1 | FileCheck %s --check-prefix=ERR-CONTENT
+
+# ERR-CONTENT: error: "Content" key is not implemented for SHT_MIPS_ABIFLAGS section
+
+## Document we don't support the "Size" key yet.
+
+# RUN: not yaml2obj %s -DSIZE=0 2>&1 | FileCheck %s --check-prefix=ERR-SIZE
+
+# ERR-SIZE: error: "Size" key is not implemented for SHT_MIPS_ABIFLAGS section
diff --git a/llvm/test/tools/yaml2obj/ELF/nobits.yaml b/llvm/test/tools/yaml2obj/ELF/nobits.yaml
new file mode 100644
index 000000000000..36fcfda032d2
--- /dev/null
+++ b/llvm/test/tools/yaml2obj/ELF/nobits.yaml
@@ -0,0 +1,36 @@
+## Check how SHT_NOBITS sections are created.
+
+## Check we can use the "Size" key alone to create the section.
+
+# RUN: yaml2obj -DSIZE=3 %s -o %t.size.o
+# RUN: llvm-readelf --sections --section-data %t.size.o | FileCheck %s
+
+# CHECK: [Nr] Name Type Address Off Size ES Flg Lk Inf Al
+# CHECK: [ 1] .nobits NOBITS 0000000000000000 000040 000003 00 0 0 0
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_DYN
+Sections:
+ - Name: .nobits
+ Type: SHT_NOBITS
+ Size: [[SIZE=<none>]]
+ Content: [[CONTENT=<none>]]
+
+## Check we can't use the "Content" key.
+
+# RUN: not yaml2obj -DCONTENT="'112233'" %s 2>&1 | \
+# RUN: FileCheck %s --check-prefix=CONTENT-ERR
+
+# CONTENT-ERR: error: SHT_NOBITS section cannot have "Content"
+
+## Check we create an empty section when neither of "Size" nor "Content" are specified.
+
+# RUN: yaml2obj %s -o %t.empty.o
+# RUN: llvm-readelf --sections --section-data %t.empty.o | \
+# RUN: FileCheck %s --check-prefix=EMPTY-SEC
+
+# EMPTY-SEC: [Nr] Name Type Address Off Size
+# EMPTY-SEC: [ 1] .nobits NOBITS 0000000000000000 000040 000000
diff --git a/llvm/test/tools/yaml2obj/ELF/note-section.yaml b/llvm/test/tools/yaml2obj/ELF/note-section.yaml
index 524f8f859619..af5d8675af68 100644
--- a/llvm/test/tools/yaml2obj/ELF/note-section.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/note-section.yaml
@@ -274,7 +274,7 @@ Sections:
## must be greater than or equal to the content size.
# RUN: not yaml2obj --docnum=13 %s 2>&1 | FileCheck %s --check-prefix=SIZE-CONTENT-ERR
-# SIZE-CONTENT-ERR: error: "Size" must be greater than or equal to the content size
+# SIZE-CONTENT-ERR: error: Section size must be greater than or equal to the content size
--- !ELF
FileHeader:
diff --git a/llvm/test/tools/yaml2obj/ELF/reloc-sec.yaml b/llvm/test/tools/yaml2obj/ELF/reloc-sec.yaml
new file mode 100644
index 000000000000..fe92b464de89
--- /dev/null
+++ b/llvm/test/tools/yaml2obj/ELF/reloc-sec.yaml
@@ -0,0 +1,78 @@
+## Check how "Content", "Size" and "Entries" keys can be used to
+## describe a content for relocations sections.
+
+## Check we can use the "Content" key with the "Size" key when the size is greater
+## than or equal to the content size.
+
+# RUN: not yaml2obj -DSIZE=1 -DCONTENT="'0011'" %s 2>&1 | \
+# RUN: FileCheck %s --check-prefix=CONTENT-SIZE-ERR
+
+# CONTENT-SIZE-ERR: error: Section size must be greater than or equal to the content size
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_DYN
+Sections:
+ - Name: .rela
+ Type: SHT_RELA
+ Link: 0x1
+ Info: 0x2
+ EntSize: 0x3
+ Size: [[SIZE=<none>]]
+ Content: [[CONTENT=<none>]]
+ Relocations: [[RELS=<none>]]
+
+# RUN: yaml2obj -DSIZE=2 -DCONTENT="'0011'" %s -o %t.cont.size.eq.o
+# RUN: llvm-readobj --sections --section-data %t.cont.size.eq.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="0011"
+
+# RUN: yaml2obj -DSIZE=3 -DCONTENT="'0011'" %s -o %t.cont.size.gr.o
+# RUN: llvm-readobj --sections --section-data %t.cont.size.gr.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="001100"
+
+# CHECK-CONTENT: Name: .rela
+# CHECK-CONTENT-NEXT: Type: SHT_RELA
+# CHECK-CONTENT-NEXT: Flags [
+# CHECK-CONTENT-NEXT: ]
+# CHECK-CONTENT-NEXT: Address:
+# CHECK-CONTENT-NEXT: Offset:
+# CHECK-CONTENT-NEXT: Size:
+# CHECK-CONTENT-NEXT: Link: 1
+# CHECK-CONTENT-NEXT: Info: 2
+# CHECK-CONTENT-NEXT: AddressAlignment:
+# CHECK-CONTENT-NEXT: EntrySize: 3
+# CHECK-CONTENT-NEXT: SectionData (
+# CHECK-CONTENT-NEXT: 0000: [[DATA]] |
+# CHECK-CONTENT-NEXT: )
+
+## Check we can use the "Size" key alone to create the section.
+
+# RUN: yaml2obj -DSIZE=3 %s -o %t.size.o
+# RUN: llvm-readobj --sections --section-data %t.size.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="000000"
+
+## Check we can use the "Content" key alone to create the section.
+
+# RUN: yaml2obj -DCONTENT="'112233'" %s -o %t.content.o
+# RUN: llvm-readobj --sections --section-data %t.content.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="112233"
+
+## Check we can't use the "Relocations" key together with the "Content" or "Size" keys.
+
+# RUN: not yaml2obj -DSIZE=0 -DRELS="[]" %s 2>&1 | \
+# RUN: FileCheck %s --check-prefix=REL-ERR
+# RUN: not yaml2obj -DCONTENT="'00'" -DRELS="[]" %s 2>&1 | \
+# RUN: FileCheck %s --check-prefix=REL-ERR
+
+# REL-ERR: error: "Relocations" cannot be used with "Content" or "Size"
+
+## Check we create an empty section when none of "Size", "Content" or "Relocations" are specified.
+
+# RUN: yaml2obj %s -o %t.empty.o
+# RUN: llvm-readelf --sections --section-data %t.empty.o | \
+# RUN: FileCheck %s --check-prefix=EMPTY-SEC
+
+# EMPTY-SEC: [Nr] Name Type Address Off Size
+# EMPTY-SEC: [ 1] .rela RELA 0000000000000000 000040 000000
diff --git a/llvm/test/tools/yaml2obj/ELF/relr-section.yaml b/llvm/test/tools/yaml2obj/ELF/relr-section.yaml
index 0010bc657115..3b975d8ab10d 100644
--- a/llvm/test/tools/yaml2obj/ELF/relr-section.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/relr-section.yaml
@@ -1,172 +1,211 @@
-## Test how we create SHT_RELR sections.
-
-## Test that the content of SHT_RELR sections for 64-bit little endian targets is correct.
-# RUN: yaml2obj --docnum=1 -D ENCODE=LSB %s -o %t.le64
-# RUN: llvm-readobj --sections --section-data %t.le64 | FileCheck %s --check-prefix=LE64
-
-# LE64: Name: .relr.dyn
-# LE64-NEXT: Type: SHT_RELR
-# LE64-NEXT: Flags [
-# LE64-NEXT: SHF_ALLOC
-# LE64-NEXT: ]
-# LE64-NEXT: Address: 0x0
-# LE64-NEXT: Offset: 0x40
-# LE64-NEXT: Size: 32
-# LE64-NEXT: Link: 0
-# LE64-NEXT: Info: 0
-# LE64-NEXT: AddressAlignment: 0
-# LE64-NEXT: EntrySize: 8
-# LE64-NEXT: SectionData (
-# LE64-NEXT: 0000: DDCCBBAA 00000000 2211FFEE 00000000
-# LE64-NEXT: 0010: 66554433 00000010 AA998877 00000010
-# LE64-NEXT: )
-
-## Test that the content of SHT_RELR sections for 64-bit big endian targets is correct.
-# RUN: yaml2obj --docnum=1 -D ENCODE=MSB %s -o %t.be64
-# RUN: llvm-readobj --sections --section-data %t.be64 | FileCheck %s --check-prefix=BE64
-
-# BE64: Name: .relr.dyn
-# BE64: SectionData (
-# BE64-NEXT: 0000: 00000000 AABBCCDD 00000000 EEFF1122
-# BE64-NEXT: 0010: 10000000 33445566 10000000 778899AA
-# BE64-NEXT: )
-
---- !ELF
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2[[ENCODE]]
- Type: ET_DYN
-Sections:
- - Name: .relr.dyn
- Type: SHT_RELR
-## Set an arbitrary flag to demonstrate flags are set when requested.
- Flags: [ SHF_ALLOC ]
- Entries: [ 0x00000000AABBCCDD, 0x00000000EEFF1122,
- 0x1000000033445566, 0x10000000778899AA ]
-
-## Test that the content of SHT_RELR sections for 32-bit little endian targets is correct.
-# RUN: yaml2obj --docnum=2 -D ENCODE=LSB %s -o %t.le32
-# RUN: llvm-readobj --sections --section-data %t.le32 | FileCheck %s --check-prefix=LE32
-
-# LE32: Name: .relr.dyn
-# LE32-NEXT: Type: SHT_RELR
-# LE32-NEXT: Flags [
-# LE32-NEXT: SHF_ALLOC
-# LE32-NEXT: ]
-# LE32-NEXT: Address: 0x0
-# LE32-NEXT: Offset: 0x34
-# LE32-NEXT: Size: 16
-# LE32-NEXT: Link: 0
-# LE32-NEXT: Info: 0
-# LE32-NEXT: AddressAlignment: 0
-# LE32-NEXT: EntrySize: 4
-# LE32-NEXT: SectionData (
-# LE32-NEXT: 0000: DDCCBBAA BBAAFFEE BBAAFFEE BCAAFFEE
-# LE32-NEXT: )
-
-## Test that the content of SHT_RELR sections for 32-bit big endian targets is correct.
-# RUN: yaml2obj --docnum=2 -D ENCODE=MSB %s -o %t.be32
-# RUN: llvm-readobj --sections --section-data %t.be32 | FileCheck %s --check-prefix=BE32
-
-# BE32: Name: .relr.dyn
-# BE32: SectionData (
-# BE32-NEXT: 0000: AABBCCDD EEFFAABB EEFFAABB EEFFAABC |
-# BE32-NEXT: )
-
---- !ELF
-FileHeader:
- Class: ELFCLASS32
- Data: ELFDATA2[[ENCODE]]
- Type: ET_DYN
-Sections:
- - Name: .relr.dyn
- Type: SHT_RELR
-## Set an arbitrary flag to demonstrate flags are set when requested.
- Flags: [ SHF_ALLOC ]
- Entries: [ 0xAABBCCDD, 0xEEFFAABB,
- 0xEEFFAABB, 0xEEFFAABC ]
-
-## Test we can use "Content" to describe SHT_RELR section.
-# RUN: yaml2obj --docnum=3 %s -o %t.content
-# RUN: llvm-readobj --sections --section-data %t.content | FileCheck %s --check-prefix=CONTENT
-
-# CONTENT: Name: .relr.dyn
-# CONTENT: SectionData (
-# CONTENT-NEXT: 0000: 112233 |
-# CONTENT-NEXT: )
-
---- !ELF
-FileHeader:
- Class: ELFCLASS32
- Data: ELFDATA2LSB
- Type: ET_DYN
-Sections:
- - Name: .relr.dyn
- Type: SHT_RELR
- Content: "112233"
-
-## Check we are able to set an arbitrary sh_entsize.
-# RUN: yaml2obj --docnum=4 %s -o %t.entsize
-# RUN: llvm-readelf --sections %t.entsize | FileCheck %s --check-prefix=ENTSIZE
-
-# ENTSIZE: [Nr] Name Type Address Off Size ES
-# ENTSIZE: [ 1] .relr.dyn RELR 00000000 000034 000001 34
-
---- !ELF
-FileHeader:
- Class: ELFCLASS32
- Data: ELFDATA2LSB
- Type: ET_DYN
-Sections:
- - Name: .relr.dyn
- Type: SHT_RELR
- EntSize: 0x34
- Content: "12"
-
-## Test we can't use 64-bit offsets/bitmaps when creating a 32-bit object.
-# RUN: yaml2obj --docnum=5 %s -o %t.nottoolarge
-# RUN: llvm-readobj --sections --section-data %t.nottoolarge | FileCheck %s --check-prefix=NOT-TOO-LARGE
-
-# NOT-TOO-LARGE: Name: .relr.dyn
-# NOT-TOO-LARGE: SectionData (
-# NOT-TOO-LARGE-NEXT: 0000: FFFFFFFF
-# NOT-TOO-LARGE-NEXT: )
-
-# RUN: not yaml2obj --docnum=6 %s 2>&1 | FileCheck %s --check-prefix=TOO-LARGE
-# TOO-LARGE: error: .relr.dyn: the value is too large for 32-bits: 0x100000000
-
---- !ELF
-FileHeader:
- Class: ELFCLASS32
- Data: ELFDATA2LSB
- Type: ET_DYN
-Sections:
- - Name: .relr.dyn
- Type: SHT_RELR
- Entries: [ 0x00000000FFFFFFFF ]
-
---- !ELF
-FileHeader:
- Class: ELFCLASS32
- Data: ELFDATA2LSB
- Type: ET_DYN
-Sections:
- - Name: .relr.dyn
- Type: SHT_RELR
- Entries: [ 0x0000000100000000 ]
-
-## Test we can't specify "Entries" and "Content" properties at the same time.
-# RUN: not yaml2obj --docnum=7 %s 2>&1 | FileCheck %s --check-prefix=BOTH
-
-# BOTH: error: "Entries" and "Content" can't be used together
-
---- !ELF
-FileHeader:
- Class: ELFCLASS32
- Data: ELFDATA2LSB
- Type: ET_DYN
-Sections:
- - Name: .relr.dyn
- Type: SHT_RELR
- Entries: [ 0x0 ]
- Content: "00"
+## Test how we create SHT_RELR sections.
+
+## Test that the content of SHT_RELR sections for 64-bit little endian targets is correct.
+# RUN: yaml2obj --docnum=1 -D ENCODE=LSB %s -o %t.le64
+# RUN: llvm-readobj --sections --section-data %t.le64 | FileCheck %s --check-prefix=LE64
+
+# LE64: Name: .relr.dyn
+# LE64-NEXT: Type: SHT_RELR
+# LE64-NEXT: Flags [
+# LE64-NEXT: SHF_ALLOC
+# LE64-NEXT: ]
+# LE64-NEXT: Address: 0x0
+# LE64-NEXT: Offset: 0x40
+# LE64-NEXT: Size: 32
+# LE64-NEXT: Link: 0
+# LE64-NEXT: Info: 0
+# LE64-NEXT: AddressAlignment: 0
+# LE64-NEXT: EntrySize: 8
+# LE64-NEXT: SectionData (
+# LE64-NEXT: 0000: DDCCBBAA 00000000 2211FFEE 00000000
+# LE64-NEXT: 0010: 66554433 00000010 AA998877 00000010
+# LE64-NEXT: )
+
+## Test that the content of SHT_RELR sections for 64-bit big endian targets is correct.
+# RUN: yaml2obj --docnum=1 -D ENCODE=MSB %s -o %t.be64
+# RUN: llvm-readobj --sections --section-data %t.be64 | FileCheck %s --check-prefix=BE64
+
+# BE64: Name: .relr.dyn
+# BE64: SectionData (
+# BE64-NEXT: 0000: 00000000 AABBCCDD 00000000 EEFF1122
+# BE64-NEXT: 0010: 10000000 33445566 10000000 778899AA
+# BE64-NEXT: )
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2[[ENCODE]]
+ Type: ET_DYN
+Sections:
+ - Name: .relr.dyn
+ Type: SHT_RELR
+## Set an arbitrary flag to demonstrate flags are set when requested.
+ Flags: [ SHF_ALLOC ]
+ Entries: [ 0x00000000AABBCCDD, 0x00000000EEFF1122,
+ 0x1000000033445566, 0x10000000778899AA ]
+
+## Test that the content of SHT_RELR sections for 32-bit little endian targets is correct.
+# RUN: yaml2obj --docnum=2 -D ENCODE=LSB %s -o %t.le32
+# RUN: llvm-readobj --sections --section-data %t.le32 | FileCheck %s --check-prefix=LE32
+
+# LE32: Name: .relr.dyn
+# LE32-NEXT: Type: SHT_RELR
+# LE32-NEXT: Flags [
+# LE32-NEXT: SHF_ALLOC
+# LE32-NEXT: ]
+# LE32-NEXT: Address: 0x0
+# LE32-NEXT: Offset: 0x34
+# LE32-NEXT: Size: 16
+# LE32-NEXT: Link: 0
+# LE32-NEXT: Info: 0
+# LE32-NEXT: AddressAlignment: 0
+# LE32-NEXT: EntrySize: 4
+# LE32-NEXT: SectionData (
+# LE32-NEXT: 0000: DDCCBBAA BBAAFFEE BBAAFFEE BCAAFFEE
+# LE32-NEXT: )
+
+## Test that the content of SHT_RELR sections for 32-bit big endian targets is correct.
+# RUN: yaml2obj --docnum=2 -D ENCODE=MSB %s -o %t.be32
+# RUN: llvm-readobj --sections --section-data %t.be32 | FileCheck %s --check-prefix=BE32
+
+# BE32: Name: .relr.dyn
+# BE32: SectionData (
+# BE32-NEXT: 0000: AABBCCDD EEFFAABB EEFFAABB EEFFAABC |
+# BE32-NEXT: )
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2[[ENCODE]]
+ Type: ET_DYN
+Sections:
+ - Name: .relr.dyn
+ Type: SHT_RELR
+## Set an arbitrary flag to demonstrate flags are set when requested.
+ Flags: [ SHF_ALLOC ]
+ Entries: [ 0xAABBCCDD, 0xEEFFAABB,
+ 0xEEFFAABB, 0xEEFFAABC ]
+
+## Check we are able to set an arbitrary sh_entsize.
+# RUN: yaml2obj --docnum=3 %s -o %t.entsize
+# RUN: llvm-readelf --sections %t.entsize | FileCheck %s --check-prefix=ENTSIZE
+
+# ENTSIZE: [Nr] Name Type Address Off Size ES
+# ENTSIZE: [ 1] .relr.dyn RELR 00000000 000034 000001 34
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_DYN
+Sections:
+ - Name: .relr.dyn
+ Type: SHT_RELR
+ EntSize: 0x34
+ Content: "12"
+
+## Test we can't use 64-bit offsets/bitmaps when creating a 32-bit object.
+# RUN: yaml2obj --docnum=4 %s -o %t.nottoolarge
+# RUN: llvm-readobj --sections --section-data %t.nottoolarge | FileCheck %s --check-prefix=NOT-TOO-LARGE
+
+# NOT-TOO-LARGE: Name: .relr.dyn
+# NOT-TOO-LARGE: SectionData (
+# NOT-TOO-LARGE-NEXT: 0000: FFFFFFFF
+# NOT-TOO-LARGE-NEXT: )
+
+# RUN: not yaml2obj --docnum=5 %s 2>&1 | FileCheck %s --check-prefix=TOO-LARGE
+# TOO-LARGE: error: .relr.dyn: the value is too large for 32-bits: 0x100000000
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_DYN
+Sections:
+ - Name: .relr.dyn
+ Type: SHT_RELR
+ Entries: [ 0x00000000FFFFFFFF ]
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_DYN
+Sections:
+ - Name: .relr.dyn
+ Type: SHT_RELR
+ Entries: [ 0x0000000100000000 ]
+
+## Check we can use the "Content" key with the "Size" key when the size is greater
+## than or equal to the content size.
+
+# RUN: not yaml2obj --docnum=6 -DSIZE=1 -DCONTENT="'0011'" %s 2>&1 | \
+# RUN: FileCheck %s --check-prefix=CONTENT-SIZE-ERR
+
+# CONTENT-SIZE-ERR: error: Section size must be greater than or equal to the content size
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_DYN
+Sections:
+ - Name: .relr.dyn
+ Type: SHT_RELR
+ EntSize: 0xff
+ Size: [[SIZE=<none>]]
+ Content: [[CONTENT=<none>]]
+ Entries: [[ENTRIES=<none>]]
+
+# RUN: yaml2obj --docnum=6 -DSIZE=2 -DCONTENT="'0011'" %s -o %t.cont.size.eq.o
+# RUN: llvm-readobj --sections --section-data %t.cont.size.eq.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="0011"
+
+# RUN: yaml2obj --docnum=6 -DSIZE=3 -DCONTENT="'0011'" %s -o %t.cont.size.gr.o
+# RUN: llvm-readobj --sections --section-data %t.cont.size.gr.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="001100"
+
+# CHECK-CONTENT: Name: .relr.dyn
+# CHECK-CONTENT-NEXT: Type: SHT_RELR
+# CHECK-CONTENT-NEXT: Flags [
+# CHECK-CONTENT-NEXT: ]
+# CHECK-CONTENT-NEXT: Address:
+# CHECK-CONTENT-NEXT: Offset:
+# CHECK-CONTENT-NEXT: Size:
+# CHECK-CONTENT-NEXT: Link:
+# CHECK-CONTENT-NEXT: Info:
+# CHECK-CONTENT-NEXT: AddressAlignment:
+# CHECK-CONTENT-NEXT: EntrySize: 255
+# CHECK-CONTENT-NEXT: SectionData (
+# CHECK-CONTENT-NEXT: 0000: [[DATA]] |
+# CHECK-CONTENT-NEXT: )
+
+## Check we can use the "Size" key alone to create the section.
+
+# RUN: yaml2obj --docnum=6 -DSIZE=3 %s -o %t.size.o
+# RUN: llvm-readobj --sections --section-data %t.size.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="000000"
+
+## Check we can use the "Content" key alone to create the section.
+
+# RUN: yaml2obj --docnum=6 -DCONTENT="'112233'" %s -o %t.content.o
+# RUN: llvm-readobj --sections --section-data %t.content.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="112233"
+
+## Check we can't use the "Entries" key together with the "Content" or "Size" keys.
+
+# RUN: not yaml2obj --docnum=6 -DSIZE=0 -DENTRIES="[]" %s 2>&1 | \
+# RUN: FileCheck %s --check-prefix=ENTRIES-ERR
+# RUN: not yaml2obj --docnum=6 -DCONTENT="'00'" -DENTRIES="[]" %s 2>&1 | \
+# RUN: FileCheck %s --check-prefix=ENTRIES-ERR
+
+# ENTRIES-ERR: error: "Entries" cannot be used with "Content" or "Size"
+
+## Check we create an empty section when none of "Size", "Content" or "Entries" are specified.
+
+# RUN: yaml2obj %s --docnum=6 -o %t.empty.o
+# RUN: llvm-readelf --sections --section-data %t.empty.o | \
+# RUN: FileCheck %s --check-prefix=EMPTY-SEC
+
+# EMPTY-SEC: [Nr] Name Type Address Off Size
+# EMPTY-SEC: [ 1] .relr.dyn RELR 0000000000000000 000040 000000
diff --git a/llvm/test/tools/yaml2obj/ELF/sht-symtab-shndx.yaml b/llvm/test/tools/yaml2obj/ELF/sht-symtab-shndx.yaml
index 157530f341ec..a442c24522e7 100644
--- a/llvm/test/tools/yaml2obj/ELF/sht-symtab-shndx.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/sht-symtab-shndx.yaml
@@ -121,3 +121,71 @@ Sections:
Type: SHT_SYMTAB_SHNDX
Entries: [ 0 ]
EntSize: 2
+
+## Check we can use the "Content" key with the "Size" key when the size is greater
+## than or equal to the content size.
+
+# RUN: not yaml2obj --docnum=6 -DSIZE=1 -DCONTENT="'0011'" %s 2>&1 | \
+# RUN: FileCheck %s --check-prefix=CONTENT-SIZE-ERR
+
+# CONTENT-SIZE-ERR: error: Section size must be greater than or equal to the content size
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_DYN
+Sections:
+ - Name: .symtab_shndx
+ Type: SHT_SYMTAB_SHNDX
+ Link: .symtab
+ Size: [[SIZE=<none>]]
+ Content: [[CONTENT=<none>]]
+ Entries: [[ENTRIES=<none>]]
+ - Name: .symtab
+ Type: SHT_SYMTAB
+## llvm-readobj validates that SHT_SYMTAB_SHNDX section has the same number
+## of entries that the symbol table associated has.
+ Size: [[SYMTAB=0x24]]
+
+# RUN: yaml2obj --docnum=6 -DSIZE=4 -DCONTENT="'00112233'" %s -o %t.cont.size.eq.o
+# RUN: llvm-readobj --sections --section-data %t.cont.size.eq.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="00112233"
+
+# RUN: yaml2obj --docnum=6 -DSIZE=8 -DSYMTAB=0x36 -DCONTENT="'00112233'" %s -o %t.cont.size.gr.o
+# RUN: llvm-readobj --sections --section-data %t.cont.size.gr.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="00112233 00000000"
+
+# CHECK-CONTENT: Name: .symtab_shndx
+# CHECK-CONTENT: SectionData (
+# CHECK-CONTENT-NEXT: 0000: [[DATA]] |
+# CHECK-CONTENT-NEXT: )
+
+## Check we can use the "Size" key alone to create the section.
+
+# RUN: yaml2obj --docnum=6 -DSIZE=4 %s -o %t.size.o
+# RUN: llvm-readobj --sections --section-data %t.size.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="00000000"
+
+## Check we can use the "Content" key alone to create the section.
+
+# RUN: yaml2obj --docnum=6 -DCONTENT="'11223344'" %s -o %t.content.o
+# RUN: llvm-readobj --sections --section-data %t.content.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="11223344"
+
+## Check we can't use the "Entries" key together with the "Content" or "Size" keys.
+
+# RUN: not yaml2obj --docnum=6 -DSIZE=0 -DENTRIES="[]" %s 2>&1 | \
+# RUN: FileCheck %s --check-prefix=ENTRIES-ERR
+# RUN: not yaml2obj --docnum=6 -DCONTENT="'00'" -DENTRIES="[]" %s 2>&1 | \
+# RUN: FileCheck %s --check-prefix=ENTRIES-ERR
+
+# ENTRIES-ERR: error: "Entries" cannot be used with "Content" or "Size"
+
+## Check we create an empty section when none of "Size", "Entries" or "Content" are specified.
+
+# RUN: yaml2obj --docnum=6 -DSYMTAB=0x0 %s -o %t.empty
+# RUN: llvm-readelf --sections %t.empty | FileCheck %s --check-prefix=EMPTY
+
+# EMPTY: [Nr] Name Type Address Off Size
+# EMPTY: [ 1] .symtab_shndx SYMTAB SECTION INDICES 0000000000000000 000040 000000
diff --git a/llvm/test/tools/yaml2obj/ELF/stack-sizes.yaml b/llvm/test/tools/yaml2obj/ELF/stack-sizes.yaml
index b8384103007a..d2e77aeaa56e 100644
--- a/llvm/test/tools/yaml2obj/ELF/stack-sizes.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/stack-sizes.yaml
@@ -244,7 +244,7 @@ Sections:
# RUN: not yaml2obj --docnum=10 %s 2>&1 | FileCheck %s --check-prefix=SIZE-CONTENT-ERR
-# SIZE-CONTENT-ERR: error: .stack_sizes: Size must be greater than or equal to the content size
+# SIZE-CONTENT-ERR: error: Section size must be greater than or equal to the content size
--- !ELF
FileHeader:
diff --git a/llvm/test/tools/yaml2obj/ELF/verdef-section.yaml b/llvm/test/tools/yaml2obj/ELF/verdef-section.yaml
index fe7d7f89eac4..376a2531a200 100644
--- a/llvm/test/tools/yaml2obj/ELF/verdef-section.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/verdef-section.yaml
@@ -127,11 +127,13 @@ Sections:
Flags: [ SHF_ALLOC ]
Info: 0x0000000000000001
-## Check we can't use both "Entries" and "Content" together.
+## Check we can use the "Content" key with the "Size" key when the size is greater
+## than or equal to the content size.
-# RUN: not yaml2obj --docnum=4 %s -o %t4 2>&1 | FileCheck %s --check-prefix=BOTH
+# RUN: not yaml2obj --docnum=4 -DSIZE=1 -DCONTENT="'0011'" %s 2>&1 | \
+# RUN: FileCheck %s --check-prefix=CONTENT-SIZE-ERR
-# BOTH: error: SHT_GNU_verdef: "Entries" and "Content" can't be used together
+# CONTENT-SIZE-ERR: error: Section size must be greater than or equal to the content size
--- !ELF
FileHeader:
@@ -141,13 +143,41 @@ FileHeader:
Sections:
- Name: .gnu.version_d
Type: SHT_GNU_verdef
- Flags: [ SHF_ALLOC ]
- Info: 0x0000000000000001
- Content: "112233"
- Entries:
- - Version: 0
- Flags: 0
- VersionNdx: 0
- Hash: 0
- Names:
- - foo
+ Info: 0x1
+ Size: [[SIZE=<none>]]
+ Content: [[CONTENT=<none>]]
+ Entries: [[ENTRIES=<none>]]
+
+# RUN: yaml2obj --docnum=4 -DSIZE=2 -DCONTENT="'0011'" %s -o %t.cont.size.eq.o
+# RUN: llvm-readobj --sections --section-data %t.cont.size.eq.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="0011"
+
+# RUN: yaml2obj --docnum=4 -DSIZE=3 -DCONTENT="'0011'" %s -o %t.cont.size.gr.o
+# RUN: llvm-readobj --sections --section-data %t.cont.size.gr.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="001100"
+
+# CHECK-CONTENT: Name: .gnu.version_d
+# CHECK-CONTENT: SectionData (
+# CHECK-CONTENT-NEXT: 0000: [[DATA]] |
+# CHECK-CONTENT-NEXT: )
+
+## Check we can use the "Size" key alone to create the section.
+
+# RUN: yaml2obj --docnum=4 -DSIZE=3 %s -o %t.size.o
+# RUN: llvm-readobj --sections --section-data %t.size.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="000000"
+
+## Check we can use the "Content" key alone to create the section.
+
+# RUN: yaml2obj --docnum=4 -DCONTENT="'112233'" %s -o %t.content.o
+# RUN: llvm-readobj --sections --section-data %t.content.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="112233"
+
+## Check we can't use the "Entries" key together with the "Content" or "Size" keys.
+
+# RUN: not yaml2obj --docnum=4 -DSIZE=0 -DENTRIES="[]" %s 2>&1 | \
+# RUN: FileCheck %s --check-prefix=ENTRIES-ERR
+# RUN: not yaml2obj --docnum=4 -DCONTENT="'00'" -DENTRIES="[]" %s 2>&1 | \
+# RUN: FileCheck %s --check-prefix=ENTRIES-ERR
+
+# ENTRIES-ERR: error: "Entries" cannot be used with "Content" or "Size"
diff --git a/llvm/test/tools/yaml2obj/ELF/verneed-section.yaml b/llvm/test/tools/yaml2obj/ELF/verneed-section.yaml
index 96e21fea578c..fad54c27bfca 100644
--- a/llvm/test/tools/yaml2obj/ELF/verneed-section.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/verneed-section.yaml
@@ -82,42 +82,10 @@ DynamicSymbols:
- Name: f1
Binding: STB_GLOBAL
-## Check we can use "Content" to describe the content.
-
-# RUN: yaml2obj --docnum=2 %s -o %t2
-# RUN: llvm-readobj --sections --section-data %t2 | FileCheck %s --check-prefix=CONTENT
-
-# CONTENT: Name: .gnu.version_r
-# CONTENT-NEXT: Type: SHT_GNU_verneed
-# CONTENT-NEXT: Flags [ (0x2)
-# CONTENT-NEXT: SHF_ALLOC (0x2)
-# CONTENT-NEXT: ]
-# CONTENT-NEXT: Address: 0x0
-# CONTENT-NEXT: Offset: 0x40
-# CONTENT-NEXT: Size: 3
-# CONTENT-NEXT: Link: 0
-# CONTENT-NEXT: Info: 1
-# CONTENT-NEXT: AddressAlignment: 0
-# CONTENT-NEXT: EntrySize: 0
-# CONTENT-NEXT: SectionData (
-# CONTENT-NEXT: 0000: 112233
-# CONTENT-NEXT: )
+## Check we can omit "Content", "Size" and "Dependencies" fields to
+## produce an empty SHT_GNU_verneed section.
---- !ELF
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_EXEC
-Sections:
- - Name: .gnu.version_r
- Type: SHT_GNU_verneed
- Flags: [ SHF_ALLOC ]
- Info: 0x1
- Content: "112233"
-
-## Check we can omit "Content" and "Dependencies" fields to produce an empty SHT_GNU_verneed section.
-
-# RUN: yaml2obj --docnum=3 %s -o %t3
+# RUN: yaml2obj --docnum=2 %s -o %t3
# RUN: llvm-readelf --sections %t3 | FileCheck %s --check-prefix=NO-PROPS
# NO-PROPS: [Nr] Name Type Address Off Size
@@ -133,22 +101,48 @@ Sections:
Type: SHT_GNU_verneed
Flags: [ SHF_ALLOC ]
Info: 0x0
+ Size: [[SIZE=<none>]]
+ Content: [[CONTENT=<none>]]
+ Dependencies: [[DEPS=<none>]]
-## Check we can't use both "Dependencies" and "Content" together.
+## Check we can use the "Content" key with the "Size" key when the size is greater
+## than or equal to the content size.
-# RUN: not yaml2obj --docnum=4 %s 2>&1 | FileCheck %s --check-prefix=BOTH
+# RUN: not yaml2obj --docnum=2 -DCONTENT="'00'" -DSIZE=0 %s 2>&1 | \
+# RUN: FileCheck %s --check-prefix=CONTENT-SIZE-ERR
-# BOTH: error: SHT_GNU_verneed: "Dependencies" and "Content" can't be used together
+# CONTENT-SIZE-ERR: error: Section size must be greater than or equal to the content size
---- !ELF
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_EXEC
-Sections:
- - Name: .gnu.version_r
- Type: SHT_GNU_verneed
- Flags: [ SHF_ALLOC ]
- Info: 0x0
- Content: ""
- Dependencies: []
+# RUN: yaml2obj --docnum=2 -DCONTENT="'00'" -DSIZE=1 %s -o %t.cont.size.eq.o
+# RUN: llvm-readobj --sections --section-data %t.cont.size.eq.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="00"
+
+# RUN: yaml2obj --docnum=2 -DCONTENT="'00'" -DSIZE=2 %s -o %t.cont.size.gr.o
+# RUN: llvm-readobj --sections --section-data %t.cont.size.gr.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="0000"
+
+# CHECK-CONTENT: Name: .gnu.version_r
+# CHECK-CONTENT: SectionData (
+# CHECK-CONTENT-NEXT: 0000: [[DATA]] |
+# CHECK-CONTENT-NEXT: )
+
+## Check we can use the "Size" key alone to create the section.
+
+# RUN: yaml2obj --docnum=2 -DSIZE=3 %s -o %t.size.o
+# RUN: llvm-readobj --sections --section-data %t.size.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="000000"
+
+## Check we can use the "Content" key alone to create the section.
+
+# RUN: yaml2obj --docnum=2 -DCONTENT="'112233'" %s -o %t.content.o
+# RUN: llvm-readobj --sections --section-data %t.content.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="112233"
+
+## Check we can't use the "Dependencies" key together with the "Content" or "Size" keys.
+
+# RUN: not yaml2obj --docnum=2 -DSIZE=0 -DDEPS="[]" %s 2>&1 | \
+# RUN: FileCheck %s --check-prefix=DEPS-ERR
+# RUN: not yaml2obj --docnum=2 -DCONTENT="'00'" -DDEPS="[]" %s 2>&1 | \
+# RUN: FileCheck %s --check-prefix=DEPS-ERR
+
+# DEPS-ERR: error: "Dependencies" cannot be used with "Content" or "Size"
diff --git a/llvm/test/tools/yaml2obj/ELF/versym-section.yaml b/llvm/test/tools/yaml2obj/ELF/versym-section.yaml
index 0d43fd1cab5e..7f9fc713356e 100644
--- a/llvm/test/tools/yaml2obj/ELF/versym-section.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/versym-section.yaml
@@ -105,3 +105,57 @@ Sections:
Type: SHT_GNU_versym
EntSize: 0x0000000000000003
Entries: [ ]
+
+## Check we can use the "Content" key with the "Size" key when the size is greater
+## than or equal to the content size.
+
+# RUN: not yaml2obj --docnum=3 -DSIZE=1 -DCONTENT="'0011'" %s 2>&1 | \
+# RUN: FileCheck %s --check-prefix=CONTENT-SIZE-ERR
+
+# CONTENT-SIZE-ERR: error: Section size must be greater than or equal to the content size
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_DYN
+Sections:
+ - Name: .gnu.version
+ Type: SHT_GNU_versym
+ Size: [[SIZE=<none>]]
+ Content: [[CONTENT=<none>]]
+ Entries: [[ENTRIES=<none>]]
+
+# RUN: yaml2obj --docnum=3 -DSIZE=2 -DCONTENT="'0011'" %s -o %t.cont.size.eq.o
+# RUN: llvm-readobj --sections --section-data %t.cont.size.eq.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="0011"
+
+# RUN: yaml2obj --docnum=3 -DSIZE=3 -DCONTENT="'0011'" %s -o %t.cont.size.gr.o
+# RUN: llvm-readobj --sections --section-data %t.cont.size.gr.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="001100"
+
+# CHECK-CONTENT: Name: .gnu.version
+# CHECK-CONTENT: SectionData (
+# CHECK-CONTENT-NEXT: 0000: [[DATA]] |
+# CHECK-CONTENT-NEXT: )
+
+## Check we can use the "Size" key alone to create the section.
+
+# RUN: yaml2obj --docnum=3 -DSIZE=3 %s -o %t.size.o
+# RUN: llvm-readobj --sections --section-data %t.size.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="000000"
+
+## Check we can use the "Content" key alone to create the section.
+
+# RUN: yaml2obj --docnum=3 -DCONTENT="'112233'" %s -o %t.content.o
+# RUN: llvm-readobj --sections --section-data %t.content.o | \
+# RUN: FileCheck %s --check-prefix=CHECK-CONTENT -DDATA="112233"
+
+## Check we can't use the "Entries" key together with the "Content" or "Size" keys.
+
+# RUN: not yaml2obj --docnum=3 -DSIZE=0 -DENTRIES="[]" %s 2>&1 | \
+# RUN: FileCheck %s --check-prefix=ENTRIES-ERR
+# RUN: not yaml2obj --docnum=3 -DCONTENT="'00'" -DENTRIES="[]" %s 2>&1 | \
+# RUN: FileCheck %s --check-prefix=ENTRIES-ERR
+
+# ENTRIES-ERR: error: "Entries" cannot be used with "Content" or "Size"
diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp
index 2d09c34c093f..fb62f4739b1a 100644
--- a/llvm/tools/obj2yaml/elf2yaml.cpp
+++ b/llvm/tools/obj2yaml/elf2yaml.cpp
@@ -929,8 +929,9 @@ ELFDumper<ELFT>::dumpDynamicSection(const Elf_Shdr *Shdr) {
if (!DynTagsOrErr)
return DynTagsOrErr.takeError();
+ S->Entries.emplace();
for (const Elf_Dyn &Dyn : *DynTagsOrErr)
- S->Entries.push_back({(ELFYAML::ELF_DYNTAG)Dyn.getTag(), Dyn.getVal()});
+ S->Entries->push_back({(ELFYAML::ELF_DYNTAG)Dyn.getTag(), Dyn.getVal()});
return S.release();
}
@@ -945,7 +946,9 @@ ELFDumper<ELFT>::dumpRelocSection(const Elf_Shdr *Shdr) {
auto SymTabOrErr = Obj.getSection(Shdr->sh_link);
if (!SymTabOrErr)
return SymTabOrErr.takeError();
- const Elf_Shdr *SymTab = *SymTabOrErr;
+
+ if (Shdr->sh_size != 0)
+ S->Relocations.emplace();
if (Shdr->sh_type == ELF::SHT_REL) {
auto Rels = Obj.rels(*Shdr);
@@ -953,9 +956,9 @@ ELFDumper<ELFT>::dumpRelocSection(const Elf_Shdr *Shdr) {
return Rels.takeError();
for (const Elf_Rel &Rel : *Rels) {
ELFYAML::Relocation R;
- if (Error E = dumpRelocation(&Rel, SymTab, R))
+ if (Error E = dumpRelocation(&Rel, *SymTabOrErr, R))
return std::move(E);
- S->Relocations.push_back(R);
+ S->Relocations->push_back(R);
}
} else {
auto Rels = Obj.relas(*Shdr);
@@ -963,10 +966,10 @@ ELFDumper<ELFT>::dumpRelocSection(const Elf_Shdr *Shdr) {
return Rels.takeError();
for (const Elf_Rela &Rel : *Rels) {
ELFYAML::Relocation R;
- if (Error E = dumpRelocation(&Rel, SymTab, R))
+ if (Error E = dumpRelocation(&Rel, *SymTabOrErr, R))
return std::move(E);
R.Addend = Rel.r_addend;
- S->Relocations.push_back(R);
+ S->Relocations->push_back(R);
}
}
@@ -1031,8 +1034,10 @@ ELFDumper<ELFT>::dumpSymtabShndxSection(const Elf_Shdr *Shdr) {
auto EntriesOrErr = Obj.template getSectionContentsAsArray<Elf_Word>(*Shdr);
if (!EntriesOrErr)
return EntriesOrErr.takeError();
+
+ S->Entries.emplace();
for (const Elf_Word &E : *EntriesOrErr)
- S->Entries.push_back(E);
+ S->Entries->push_back(E);
return S.release();
}
@@ -1042,8 +1047,8 @@ ELFDumper<ELFT>::dumpNoBitsSection(const Elf_Shdr *Shdr) {
auto S = std::make_unique<ELFYAML::NoBitsSection>();
if (Error E = dumpCommonSection(Shdr, *S))
return std::move(E);
- S->Size = Shdr->sh_size;
-
+ if (Shdr->sh_size)
+ S->Size = static_cast<llvm::yaml::Hex64>(Shdr->sh_size);
return S.release();
}
@@ -1239,8 +1244,10 @@ ELFDumper<ELFT>::dumpSymverSection(const Elf_Shdr *Shdr) {
auto VersionsOrErr = Obj.template getSectionContentsAsArray<Elf_Half>(*Shdr);
if (!VersionsOrErr)
return VersionsOrErr.takeError();
+
+ S->Entries.emplace();
for (const Elf_Half &E : *VersionsOrErr)
- S->Entries.push_back(E);
+ S->Entries->push_back(E);
return S.release();
}
@@ -1339,9 +1346,10 @@ ELFDumper<ELFT>::dumpGroupSection(const Elf_Shdr *Shdr) {
if (!MembersOrErr)
return MembersOrErr.takeError();
+ S->Members.emplace();
for (Elf_Word Member : *MembersOrErr) {
if (Member == llvm::ELF::GRP_COMDAT) {
- S->Members.push_back({"GRP_COMDAT"});
+ S->Members->push_back({"GRP_COMDAT"});
continue;
}
@@ -1351,7 +1359,7 @@ ELFDumper<ELFT>::dumpGroupSection(const Elf_Shdr *Shdr) {
auto NameOrErr = getUniquedSectionName(*SHdrOrErr);
if (!NameOrErr)
return NameOrErr.takeError();
- S->Members.push_back({*NameOrErr});
+ S->Members->push_back({*NameOrErr});
}
return S.release();
}
More information about the llvm-commits
mailing list