[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