[yaml2obj][obj2yaml] - Add support for dumping/parsing .dynamic sections.

This teaches the tools to parse and dump
the .dynamic section and its dynamic tags.

Differential revision: https://reviews.llvm.org/D57691

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@353606 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/llvm/ObjectYAML/ELFYAML.h b/include/llvm/ObjectYAML/ELFYAML.h
index 110d399..5eff7fc 100644
--- a/include/llvm/ObjectYAML/ELFYAML.h
+++ b/include/llvm/ObjectYAML/ELFYAML.h
@@ -43,6 +43,8 @@
 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFOSABI)
 // Just use 64, since it can hold 32-bit values too.
 LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_EF)
+// Just use 64, since it can hold 32-bit values too.
+LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_DYNTAG)
 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_PF)
 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_SHT)
 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_REL)
@@ -107,8 +109,14 @@
   StringRef sectionNameOrType;
 };
 
+struct DynamicEntry {
+  ELF_DYNTAG Tag;
+  llvm::yaml::Hex64 Val;
+};
+
 struct Section {
   enum class SectionKind {
+    Dynamic,
     Group,
     RawContent,
     Relocation,
@@ -128,6 +136,17 @@
   Section(SectionKind Kind) : Kind(Kind) {}
   virtual ~Section();
 };
+
+struct DynamicSection : Section {
+  std::vector<DynamicEntry> Entries;
+
+  DynamicSection() : Section(SectionKind::Dynamic) {}
+
+  static bool classof(const Section *S) {
+    return S->Kind == SectionKind::Dynamic;
+  }
+};
+
 struct RawContentSection : Section {
   yaml::BinaryRef Content;
   llvm::yaml::Hex64 Size;
@@ -214,6 +233,7 @@
 } // end namespace ELFYAML
 } // end namespace llvm
 
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::DynamicEntry)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ProgramHeader)
 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::ELFYAML::Section>)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol)
@@ -297,6 +317,11 @@
 };
 
 template <>
+struct ScalarEnumerationTraits<ELFYAML::ELF_DYNTAG> {
+  static void enumeration(IO &IO, ELFYAML::ELF_DYNTAG &Value);
+};
+
+template <>
 struct ScalarEnumerationTraits<ELFYAML::ELF_RSS> {
   static void enumeration(IO &IO, ELFYAML::ELF_RSS &Value);
 };
@@ -351,6 +376,10 @@
   static void mapping(IO &IO, ELFYAML::LocalGlobalWeakSymbols &Symbols);
 };
 
+template <> struct MappingTraits<ELFYAML::DynamicEntry> {
+  static void mapping(IO &IO, ELFYAML::DynamicEntry &Rel);
+};
+
 template <> struct MappingTraits<ELFYAML::Relocation> {
   static void mapping(IO &IO, ELFYAML::Relocation &Rel);
 };
diff --git a/lib/ObjectYAML/ELFYAML.cpp b/lib/ObjectYAML/ELFYAML.cpp
index a89180d..4707a44 100644
--- a/lib/ObjectYAML/ELFYAML.cpp
+++ b/lib/ObjectYAML/ELFYAML.cpp
@@ -661,6 +661,33 @@
   IO.enumFallback<Hex32>(Value);
 }
 
+void ScalarEnumerationTraits<ELFYAML::ELF_DYNTAG>::enumeration(
+    IO &IO, ELFYAML::ELF_DYNTAG &Value) {
+  const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
+  assert(Object && "The IO context is not initialized");
+
+// TODO: For simplicity we do not handle target specific flags. They are
+// still supported and will be shown as a raw numeric values in the output.
+#define MIPS_DYNAMIC_TAG(name, value)
+#define HEXAGON_DYNAMIC_TAG(name, value)
+#define PPC64_DYNAMIC_TAG(name, value)
+// Also ignore marker tags such as DT_HIOS (maps to DT_VERNEEDNUM), etc.
+#define DYNAMIC_TAG_MARKER(name, value)
+
+#define STRINGIFY(X) (#X)
+#define DYNAMIC_TAG(X, Y) IO.enumCase(Value, STRINGIFY(DT_##X), ELF::DT_##X);
+#include "llvm/BinaryFormat/DynamicTags.def"
+
+#undef MIPS_DYNAMIC_TAG
+#undef HEXAGON_DYNAMIC_TAG
+#undef PPC64_DYNAMIC_TAG
+#undef DYNAMIC_TAG_MARKER
+#undef STRINGIFY
+#undef DYNAMIC_TAG
+
+  IO.enumFallback<Hex64>(Value);
+}
+
 void ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG>::enumeration(
     IO &IO, ELFYAML::MIPS_AFL_REG &Value) {
 #define ECase(X) IO.enumCase(Value, #X, Mips::AFL_##X)
@@ -831,6 +858,11 @@
   IO.mapOptional("Info", Section.Info, StringRef());
 }
 
+static void sectionMapping(IO &IO, ELFYAML::DynamicSection &Section) {
+  commonSectionMapping(IO, Section);
+  IO.mapOptional("Entries", Section.Entries);
+}
+
 static void sectionMapping(IO &IO, ELFYAML::RawContentSection &Section) {
   commonSectionMapping(IO, Section);
   IO.mapOptional("Content", Section.Content);
@@ -891,6 +923,11 @@
     IO.mapRequired("Type", sectionType);
 
   switch (sectionType) {
+  case ELF::SHT_DYNAMIC:
+    if (!IO.outputting())
+      Section.reset(new ELFYAML::DynamicSection());
+    sectionMapping(IO, *cast<ELFYAML::DynamicSection>(Section.get()));
+    break;
   case ELF::SHT_REL:
   case ELF::SHT_RELA:
     if (!IO.outputting())
@@ -952,6 +989,15 @@
 
 } // end anonymous namespace
 
+void MappingTraits<ELFYAML::DynamicEntry>::mapping(IO &IO,
+                                                   ELFYAML::DynamicEntry &Rel) {
+  const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
+  assert(Object && "The IO context is not initialized");
+
+  IO.mapRequired("Tag", Rel.Tag);
+  IO.mapRequired("Value", Rel.Val);
+}
+
 void MappingTraits<ELFYAML::Relocation>::mapping(IO &IO,
                                                  ELFYAML::Relocation &Rel) {
   const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
diff --git a/test/tools/llvm-elfabi/binary-read-add-soname.test b/test/tools/llvm-elfabi/binary-read-add-soname.test
index 49c37ef..744fa51 100644
--- a/test/tools/llvm-elfabi/binary-read-add-soname.test
+++ b/test/tools/llvm-elfabi/binary-read-add-soname.test
@@ -16,15 +16,19 @@
   - Name:            .dynamic
     Type:            SHT_DYNAMIC
     Flags:           [ SHF_ALLOC ]
-    Address:         0x0008
-    AddressAlign:    8
-    Content:         "0a000000000000000100000000000000050000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000"
-      # DT_STRSZ      1 (0x1)
-      # DT_STRTAB     0x0
-      # DT_SYMTAB     0x0
-      # DT_NULL       0x0
-    Size:            64
+    Address:         0x0000000000000008
     Link:            .dynstr
+    AddressAlign:    0x0000000000000008
+    EntSize:         0x0000000000000010
+    Entries:
+      - Tag:             DT_STRSZ
+        Value:           0x0000000000000001
+      - Tag:             DT_STRTAB
+        Value:           0x0000000000000000
+      - Tag:             DT_SYMTAB
+        Value:           0x0000000000000000
+      - Tag:             DT_NULL
+        Value:           0x0000000000000000
 ProgramHeaders:
   - Type: PT_LOAD
     Flags: [ PF_R ]
diff --git a/test/tools/llvm-elfabi/binary-read-arch.test b/test/tools/llvm-elfabi/binary-read-arch.test
index 23f99a3..918a0c6 100644
--- a/test/tools/llvm-elfabi/binary-read-arch.test
+++ b/test/tools/llvm-elfabi/binary-read-arch.test
@@ -16,15 +16,19 @@
   - Name:            .dynamic
     Type:            SHT_DYNAMIC
     Flags:           [ SHF_ALLOC ]
-    Address:         0x0008
-    AddressAlign:    8
-    Content:         "0a000000000000000100000000000000050000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000"
-      # DT_STRSZ      1 (0x1)
-      # DT_STRTAB     0x0
-      # DT_SYMTAB     0x0
-      # DT_NULL       0x0
-    Size:            64
+    Address:         0x0000000000000008
     Link:            .dynstr
+    AddressAlign:    0x0000000000000008
+    EntSize:         0x0000000000000010
+    Entries:
+      - Tag:             DT_STRSZ
+        Value:           0x0000000000000001
+      - Tag:             DT_STRTAB
+        Value:           0x0000000000000000
+      - Tag:             DT_SYMTAB
+        Value:           0x0000000000000000
+      - Tag:             DT_NULL
+        Value:           0x0000000000000000
 ProgramHeaders:
   - Type: PT_LOAD
     Flags: [ PF_R ]
diff --git a/test/tools/llvm-elfabi/binary-read-bad-soname.test b/test/tools/llvm-elfabi/binary-read-bad-soname.test
index e0e6ac2..a92d61e 100644
--- a/test/tools/llvm-elfabi/binary-read-bad-soname.test
+++ b/test/tools/llvm-elfabi/binary-read-bad-soname.test
@@ -16,16 +16,21 @@
   - Name:            .dynamic
     Type:            SHT_DYNAMIC
     Flags:           [ SHF_ALLOC ]
-    Address:         0x0008
-    AddressAlign:    8
-    Content:         "0e000000000000000d000000000000000a000000000000000100000000000000050000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000"
-      # DT_SONAME     13 (0x0d)
-      # DT_STRSZ      1 (0x01)
-      # DT_STRTAB     0x0
-      # DT_SYMTAB     0x0
-      # DT_NULL       0x0
-    Size:            80
+    Address:         0x0000000000000008
     Link:            .dynstr
+    AddressAlign:    0x0000000000000008
+    EntSize:         0x0000000000000010
+    Entries:
+      - Tag:             DT_SONAME
+        Value:           0x000000000000000D
+      - Tag:             DT_STRSZ
+        Value:           0x0000000000000001
+      - Tag:             DT_STRTAB
+        Value:           0x0000000000000000
+      - Tag:             DT_SYMTAB
+        Value:           0x0000000000000000
+      - Tag:             DT_NULL
+        Value:           0x0000000000000000
 ProgramHeaders:
   - Type: PT_LOAD
     Flags: [ PF_R ]
diff --git a/test/tools/llvm-elfabi/binary-read-bad-vaddr.test b/test/tools/llvm-elfabi/binary-read-bad-vaddr.test
index 03d453c..b8918b9 100644
--- a/test/tools/llvm-elfabi/binary-read-bad-vaddr.test
+++ b/test/tools/llvm-elfabi/binary-read-bad-vaddr.test
@@ -16,16 +16,21 @@
   - Name:            .dynamic
     Type:            SHT_DYNAMIC
     Flags:           [ SHF_ALLOC ]
-    Address:         0x1008
-    AddressAlign:    8
-    Content:         "0e0000000000000000000000000000000a000000000000000100000000000000050000000000000060020000000000000600000000000000001000000000000000000000000000000000000000000000"
-      # DT_SONAME     0
-      # DT_STRSZ      1
-      # DT_STRTAB     0x0260 # Bad vaddr (no PT_LOAD for 0x0000 to 0x0FFF)
-      # DT_SYMTAB     0x1000
-      # DT_NULL       0x0
-    Size:            80
+    Address:         0x0000000000001008
     Link:            .dynstr
+    AddressAlign:    0x0000000000000008
+    EntSize:         0x0000000000000010
+    Entries:
+      - Tag:             DT_SONAME
+        Value:           0x0000000000000000
+      - Tag:             DT_STRSZ
+        Value:           0x0000000000000001
+      - Tag:             DT_STRTAB
+        Value:           0x0000000000000260 # Bad vaddr (no PT_LOAD for 0x0000 to 0x0FFF)
+      - Tag:             DT_SYMTAB
+        Value:           0x0000000000001000
+      - Tag:             DT_NULL
+        Value:           0x0000000000000000
 ProgramHeaders:
   - Type: PT_LOAD
     Flags: [ PF_R ]
diff --git a/test/tools/llvm-elfabi/binary-read-neededlibs-bad-offset.test b/test/tools/llvm-elfabi/binary-read-neededlibs-bad-offset.test
index e76aa5d..6b7ba8b 100644
--- a/test/tools/llvm-elfabi/binary-read-neededlibs-bad-offset.test
+++ b/test/tools/llvm-elfabi/binary-read-neededlibs-bad-offset.test
@@ -17,17 +17,24 @@
   - Name:            .dynamic
     Type:            SHT_DYNAMIC
     Flags:           [ SHF_ALLOC ]
-    Address:         0x1024
-    Content:         "010000000000000001000000000000000e0000000000000015000000000000000100000000000000ffff0000000000000a000000000000002400000000000000050000000000000000100000000000000600000000000000001000000000000000000000000000000000000000000000"
-      # DT_NEEDED     1 (0x01)
-      # DT_SONAME     21 (0x15)
+    Address:         0x0000000000001024
+    EntSize:         0x0000000000000010
+    Entries:
+      - Tag:             DT_NEEDED
+        Value:           0x0000000000000001
+      - Tag:             DT_SONAME
+        Value:           0x0000000000000015
       # Bad DT_NEEDED entry (offset outside string table):
-      # DT_NEEDED     65535 (0xffff)
-      # DT_STRSZ      36 (0x24)
-      # DT_STRTAB     0x1000
-      # DT_SYMTAB     0x1000
-      # DT_NULL       0x0
-    Size:            112
+      - Tag:             DT_NEEDED
+        Value:           0x000000000000FFFF
+      - Tag:             DT_STRSZ
+        Value:           0x0000000000000024
+      - Tag:             DT_STRTAB
+        Value:           0x0000000000001000
+      - Tag:             DT_SYMTAB
+        Value:           0x0000000000001000
+      - Tag:             DT_NULL
+        Value:           0x0000000000000000
 ProgramHeaders:
   - Type: PT_LOAD
     Flags: [ PF_R ]
diff --git a/test/tools/llvm-elfabi/binary-read-neededlibs.test b/test/tools/llvm-elfabi/binary-read-neededlibs.test
index 4814995..09567e0 100644
--- a/test/tools/llvm-elfabi/binary-read-neededlibs.test
+++ b/test/tools/llvm-elfabi/binary-read-neededlibs.test
@@ -17,16 +17,23 @@
   - Name:            .dynamic
     Type:            SHT_DYNAMIC
     Flags:           [ SHF_ALLOC ]
-    Address:         0x1024
-    Content:         "010000000000000001000000000000000e00000000000000150000000000000001000000000000000b000000000000000a000000000000002400000000000000050000000000000000100000000000000600000000000000001000000000000000000000000000000000000000000000"
-      # DT_NEEDED     1 (0x01)
-      # DT_SONAME     21 (0x15)
-      # DT_NEEDED     11 (0x0b)
-      # DT_STRSZ      36 (0x24)
-      # DT_STRTAB     0x1000
-      # DT_SYMTAB     0x1000
-      # DT_NULL       0x0
-    Size:            112
+    Address:         0x0000000000001024
+    EntSize:         0x0000000000000010
+    Entries:
+      - Tag:             DT_NEEDED
+        Value:           0x0000000000000001
+      - Tag:             DT_SONAME
+        Value:           0x0000000000000015
+      - Tag:             DT_NEEDED
+        Value:           0x000000000000000B
+      - Tag:             DT_STRSZ
+        Value:           0x0000000000000024
+      - Tag:             DT_STRTAB
+        Value:           0x0000000000001000
+      - Tag:             DT_SYMTAB
+        Value:           0x0000000000001000
+      - Tag:             DT_NULL
+        Value:           0x0000000000000000
 ProgramHeaders:
   - Type: PT_LOAD
     Flags: [ PF_R ]
diff --git a/test/tools/llvm-elfabi/binary-read-no-dt-strsz.test b/test/tools/llvm-elfabi/binary-read-no-dt-strsz.test
index 09e514a..99e06b2 100644
--- a/test/tools/llvm-elfabi/binary-read-no-dt-strsz.test
+++ b/test/tools/llvm-elfabi/binary-read-no-dt-strsz.test
@@ -17,13 +17,15 @@
   - Name:            .dynamic
     Type:            SHT_DYNAMIC
     Flags:           [ SHF_ALLOC ]
-    Address:         0x0008
-    AddressAlign:    8
-    Content:         "0500000000000000000000000000000000000000000000000000000000000000"
-      # DT_STRTAB     0x0
-      # DT_NULL       0x0
-    Size:            32
+    Address:         0x0000000000000008
     Link:            .dynstr
+    AddressAlign:    0x0000000000000008
+    EntSize:         0x0000000000000010
+    Entries:
+      - Tag:             DT_STRTAB
+        Value:           0x0000000000000000
+      - Tag:             DT_NULL
+        Value:           0x0000000000000000
 ProgramHeaders:
   - Type: PT_LOAD
     Flags: [ PF_R ]
diff --git a/test/tools/llvm-elfabi/binary-read-no-dt-strtab.test b/test/tools/llvm-elfabi/binary-read-no-dt-strtab.test
index 25fcbdc..79f4496 100644
--- a/test/tools/llvm-elfabi/binary-read-no-dt-strtab.test
+++ b/test/tools/llvm-elfabi/binary-read-no-dt-strtab.test
@@ -16,13 +16,15 @@
   - Name:            .dynamic
     Type:            SHT_DYNAMIC
     Flags:           [ SHF_ALLOC ]
-    Address:         0x0008
-    AddressAlign:    8
-    Content:         "0a00000000000000010000000000000000000000000000000000000000000000"
-      # DT_STRSZ      1 (0x1)
-      # DT_NULL       0x0
-    Size:            32
+    Address:         0x0000000000000008
     Link:            .dynstr
+    AddressAlign:    0x0000000000000008
+    EntSize:         0x0000000000000010
+    Entries:
+      - Tag:             DT_STRSZ
+        Value:           0x0000000000000001
+      - Tag:             DT_NULL
+        Value:           0x0000000000000000
 ProgramHeaders:
   - Type: PT_LOAD
     Flags: [ PF_R ]
diff --git a/test/tools/llvm-elfabi/binary-read-replace-soname.test b/test/tools/llvm-elfabi/binary-read-replace-soname.test
index da3427d..762dcbb 100644
--- a/test/tools/llvm-elfabi/binary-read-replace-soname.test
+++ b/test/tools/llvm-elfabi/binary-read-replace-soname.test
@@ -18,16 +18,21 @@
   - Name:            .dynamic
     Type:            SHT_DYNAMIC
     Flags:           [ SHF_ALLOC ]
-    Address:         0x1018
-    AddressAlign:    8
-    Content:         "0e0000000000000005000000000000000a000000000000001400000000000000050000000000000000100000000000000600000000000000001000000000000000000000000000000000000000000000"
-      # DT_SONAME     5 (0x05)
-      # DT_STRSZ      20 (0x14)
-      # DT_STRTAB     0x1000
-      # DT_SYMTAB     0x1000
-      # DT_NULL       0x0
-    Size:            80
+    Address:         0x0000000000001018
     Link:            .dynstr
+    AddressAlign:    0x0000000000000008
+    EntSize:         0x0000000000000010
+    Entries:
+      - Tag:             DT_SONAME
+        Value:           0x0000000000000005
+      - Tag:             DT_STRSZ
+        Value:           0x0000000000000014
+      - Tag:             DT_STRTAB
+        Value:           0x0000000000001000
+      - Tag:             DT_SYMTAB
+        Value:           0x0000000000001000
+      - Tag:             DT_NULL
+        Value:           0x0000000000000000
 ProgramHeaders:
   - Type: PT_LOAD
     Flags: [ PF_R ]
diff --git a/test/tools/llvm-elfabi/binary-read-soname-no-null.test b/test/tools/llvm-elfabi/binary-read-soname-no-null.test
index f474878..30aa679 100644
--- a/test/tools/llvm-elfabi/binary-read-soname-no-null.test
+++ b/test/tools/llvm-elfabi/binary-read-soname-no-null.test
@@ -17,16 +17,21 @@
   - Name:            .dynamic
     Type:            SHT_DYNAMIC
     Flags:           [ SHF_ALLOC ]
-    Address:         0x1018
-    AddressAlign:    8
-    Content:         "0e0000000000000005000000000000000a000000000000000f00000000000000050000000000000000100000000000000600000000000000001000000000000000000000000000000000000000000000"
-      # DT_SONAME     5 (0x05)
-      # DT_STRSZ      15 (0x0F)
-      # DT_STRTAB     0x1000
-      # DT_SYMTAB     0x1000
-      # DT_NULL       0x0
-    Size:            80
+    Address:         0x0000000000001018
     Link:            .dynstr
+    AddressAlign:    0x0000000000000008
+    EntSize:         0x0000000000000010
+    Entries:
+      - Tag:             DT_SONAME
+        Value:           0x0000000000000005
+      - Tag:             DT_STRSZ
+        Value:           0x000000000000000F
+      - Tag:             DT_STRTAB
+        Value:           0x0000000000001000
+      - Tag:             DT_SYMTAB
+        Value:           0x0000000000001000
+      - Tag:             DT_NULL
+        Value:           0x0000000000000000
 ProgramHeaders:
   - Type: PT_LOAD
     Flags: [ PF_R ]
diff --git a/test/tools/llvm-elfabi/binary-read-soname.test b/test/tools/llvm-elfabi/binary-read-soname.test
index 61e8fcf..ef35b89 100644
--- a/test/tools/llvm-elfabi/binary-read-soname.test
+++ b/test/tools/llvm-elfabi/binary-read-soname.test
@@ -17,16 +17,21 @@
   - Name:            .dynamic
     Type:            SHT_DYNAMIC
     Flags:           [ SHF_ALLOC ]
-    Address:         0x1018
-    AddressAlign:    8
-    Content:         "0e0000000000000005000000000000000a000000000000001400000000000000050000000000000000100000000000000600000000000000001000000000000000000000000000000000000000000000"
-      # DT_SONAME     5 (0x05)
-      # DT_STRSZ      20 (0x14)
-      # DT_STRTAB     0x1000
-      # DT_SYMTAB     0x1000
-      # DT_NULL       0x0
-    Size:            80
+    Address:         0x0000000000001018
     Link:            .dynstr
+    AddressAlign:    0x0000000000000008
+    EntSize:         0x0000000000000010
+    Entries:
+      - Tag:             DT_SONAME
+        Value:           0x0000000000000005
+      - Tag:             DT_STRSZ
+        Value:           0x0000000000000014
+      - Tag:             DT_STRTAB
+        Value:           0x0000000000001000
+      - Tag:             DT_SYMTAB
+        Value:           0x0000000000001000
+      - Tag:             DT_NULL
+        Value:           0x0000000000000000
 ProgramHeaders:
   - Type: PT_LOAD
     Flags: [ PF_R ]
diff --git a/test/tools/llvm-objdump/private-headers-no-dynamic-segment.test b/test/tools/llvm-objdump/private-headers-no-dynamic-segment.test
index 0aec1fe..c3f5925 100644
--- a/test/tools/llvm-objdump/private-headers-no-dynamic-segment.test
+++ b/test/tools/llvm-objdump/private-headers-no-dynamic-segment.test
@@ -10,8 +10,65 @@
 Sections:
   - Name:            .dynamic
     Type:            SHT_DYNAMIC
-    Flags:           [ SHF_ALLOC, SHF_WRITE ]
-    Content: 0c00000000000000a0060000000000000d0000000000000024090000000000001900000000000000a80d2000000000001b0000000000000010000000000000001a00000000000000b80d2000000000001c000000000000000800000000000000f5feff6f0000000098020000000000000500000000000000c8030000000000000600000000000000c0020000000000000a000000000000002f010000000000000b0000000000000018000000000000001500000000000000000000000000000003000000000000000010200000000000020000000000000048000000000000001400000000000000070000000000000017000000000000005806000000000000070000000000000050050000000000000800000000000000080100000000000009000000000000001800000000000000fbffff6f000000000000000800000000feffff6f000000001005000000000000ffffff6f000000000200000000000000f0ffff6f00000000f804000000000000f9ffff6f0000000004000000000000002300000000000000140000000000000024000000000000002143658700000000250000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    EntSize:         0x0000000000000010
+    Entries:
+      - Tag:             DT_INIT
+        Value:           0x00000000000006A0
+      - Tag:             DT_FINI
+        Value:           0x0000000000000924
+      - Tag:             DT_INIT_ARRAY
+        Value:           0x0000000000200DA8
+      - Tag:             DT_INIT_ARRAYSZ
+        Value:           0x0000000000000010
+      - Tag:             DT_FINI_ARRAY
+        Value:           0x0000000000200DB8
+      - Tag:             DT_FINI_ARRAYSZ
+        Value:           0x0000000000000008
+      - Tag:             DT_GNU_HASH
+        Value:           0x0000000000000298
+      - Tag:             DT_STRTAB
+        Value:           0x00000000000003C8
+      - Tag:             DT_SYMTAB
+        Value:           0x00000000000002C0
+      - Tag:             DT_STRSZ
+        Value:           0x000000000000012F
+      - Tag:             DT_SYMENT
+        Value:           0x0000000000000018
+      - Tag:             DT_DEBUG
+        Value:           0x0000000000000000
+      - Tag:             DT_PLTGOT
+        Value:           0x0000000000201000
+      - Tag:             DT_PLTRELSZ
+        Value:           0x0000000000000048
+      - Tag:             DT_PLTREL
+        Value:           0x0000000000000007
+      - Tag:             DT_JMPREL
+        Value:           0x0000000000000658
+      - Tag:             DT_RELA
+        Value:           0x0000000000000550
+      - Tag:             DT_RELASZ
+        Value:           0x0000000000000108
+      - Tag:             DT_RELAENT
+        Value:           0x0000000000000018
+      - Tag:             DT_FLAGS_1
+        Value:           0x0000000008000000
+      - Tag:             DT_VERNEED
+        Value:           0x0000000000000510
+      - Tag:             DT_VERNEEDNUM
+        Value:           0x0000000000000002
+      - Tag:             DT_VERSYM
+        Value:           0x00000000000004F8
+      - Tag:             DT_RELACOUNT
+        Value:           0x0000000000000004
+      - Tag:             DT_RELRSZ
+        Value:           0x0000000000000014
+      - Tag:             DT_RELR
+        Value:           0x0000000087654321
+      - Tag:             DT_RELRENT
+        Value:           0x0000000000000010
+      - Tag:             DT_NULL
+        Value:           0x0000000000000000
 
 # CHECK:  INIT                 0x00000000000006a0
 # CHECK:  FINI                 0x0000000000000924
diff --git a/test/tools/llvm-readobj/demangle.test b/test/tools/llvm-readobj/demangle.test
index 615cf77..edac38e 100644
--- a/test/tools/llvm-readobj/demangle.test
+++ b/test/tools/llvm-readobj/demangle.test
@@ -156,21 +156,30 @@
         Symbol: _Z3fooc
         Type:   R_X86_64_PC32
         Addend: 0x4
-  - Name:         .dynamic
-    Type:         SHT_DYNAMIC
-    Flags:        [ SHF_ALLOC ]
-    Link:         .dynstr
-    Address:      0x1000
-    AddressAlign: 0x1000
-    ## DT_STRTAB  - 0x0
-    ## DT_STRSZ   - 0x9
-    ## DT_SYMTAB  - 0x100
-    ## DT_SYMENT  - 0x18
-    ## DT_RELA    - 0x200
-    ## DT_RELASZ  - 0x18
-    ## DT_RELAENT - 0x18
-    ## DT_NULL    - 0x0
-    Content: "050000000000000000000000000000000a000000000000000900000000000000060000000000000000010000000000000b00000000000000180000000000000007000000000000000002000000000000080000000000000018000000000000000900000000000000180000000000000000000000000000000000000000000000"
+  - Name:            .dynamic
+    Type:            SHT_DYNAMIC
+    Flags:           [ SHF_ALLOC ]
+    Address:         0x0000000000001000
+    Link:            .dynstr
+    AddressAlign:    0x0000000000001000
+    EntSize:         0x0000000000000010
+    Entries:
+      - Tag:             DT_STRTAB
+        Value:           0x0000000000000000
+      - Tag:             DT_STRSZ
+        Value:           0x0000000000000009
+      - Tag:             DT_SYMTAB
+        Value:           0x0000000000000100
+      - Tag:             DT_SYMENT
+        Value:           0x0000000000000018
+      - Tag:             DT_RELA
+        Value:           0x0000000000000200
+      - Tag:             DT_RELASZ
+        Value:           0x0000000000000018
+      - Tag:             DT_RELAENT
+        Value:           0x0000000000000018
+      - Tag:             DT_NULL
+        Value:           0x0000000000000000
   - Name:  .text.foo
     Type:  SHT_PROGBITS
     Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ]
diff --git a/test/tools/llvm-readobj/gnu-hash-symbols.test b/test/tools/llvm-readobj/gnu-hash-symbols.test
index 28ec34d..79e58a9 100644
--- a/test/tools/llvm-readobj/gnu-hash-symbols.test
+++ b/test/tools/llvm-readobj/gnu-hash-symbols.test
@@ -71,18 +71,24 @@
     ## st_name: 1; st_info: Global | Func; st_other: 0;
     ##   st_shndx: .text.foo; st_value: 0x2000; st_size: 0
     Content: "000000000000000000000000000000000000000000000000010000001200040000200000000000000000000000000000"
-  - Name:         .dynamic
-    Type:         SHT_DYNAMIC
-    Flags:        [ SHF_ALLOC ]
-    Link:         .dynstr
-    Address:      0x1000
-    AddressAlign: 0x1000
-    ## DT_STRTAB  - 0x0
-    ## DT_STRSZ   - 0x9
-    ## DT_SYMTAB  - 0x100
-    ## DT_SYMENT  - 0x18
-    ## DT_NULL    - 0x0
-    Content: "050000000000000000000000000000000a000000000000000900000000000000060000000000000000010000000000000b00000000000000180000000000000000000000000000000000000000000000"
+  - Name:            .dynamic
+    Type:            SHT_DYNAMIC
+    Flags:           [ SHF_ALLOC ]
+    Address:         0x0000000000001000
+    Link:            .dynstr
+    AddressAlign:    0x0000000000001000
+    EntSize:         0x0000000000000010
+    Entries:
+      - Tag:             DT_STRTAB
+        Value:           0x0000000000000000
+      - Tag:             DT_STRSZ
+        Value:           0x0000000000000009
+      - Tag:             DT_SYMTAB
+        Value:           0x0000000000000100
+      - Tag:             DT_SYMENT
+        Value:           0x0000000000000018
+      - Tag:             DT_NULL
+        Value:           0x0000000000000000
   - Name:  .text.foo
     Type:  SHT_PROGBITS
     Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ]
diff --git a/test/tools/obj2yaml/dynamic-section.test b/test/tools/obj2yaml/dynamic-section.test
new file mode 100644
index 0000000..d8fb7e9
--- /dev/null
+++ b/test/tools/obj2yaml/dynamic-section.test
@@ -0,0 +1,248 @@
+# RUN: yaml2obj %s -o %t
+# RUN: obj2yaml %t | FileCheck %s
+
+## Check we can use obj2yaml to yamalize the object containing
+## .dynamic section. Check that resulting section has the
+## proper attributes and dynamic tags.
+
+# CHECK:       Sections:
+# CHECK-NEXT:  - Name:            .dynamic
+# CHECK-NEXT:    Type:            SHT_DYNAMIC
+# CHECK-NEXT:    Address:         0x0000000000001000
+# CHECK-NEXT:    AddressAlign:    0x0000000000002000
+# CHECK-NEXT:    EntSize:         0x0000000000000010
+# CHECK-NEXT:    Entries:
+# CHECK-NEXT:      - Tag:             DT_NULL
+# CHECK-NEXT:        Value:           0x0000000000000000
+# CHECK-NEXT:      - Tag:             DT_NEEDED
+# CHECK-NEXT:        Value:           0x0000000000000001
+# CHECK-NEXT:      - Tag:             DT_PLTRELSZ
+# CHECK-NEXT:        Value:           0x0000000000000002
+# CHECK-NEXT:      - Tag:             DT_PLTGOT
+# CHECK-NEXT:        Value:           0x0000000000000003
+# CHECK-NEXT:      - Tag:             DT_HASH
+# CHECK-NEXT:        Value:           0x0000000000000004
+# CHECK-NEXT:      - Tag:             DT_STRTAB
+# CHECK-NEXT:        Value:           0x0000000000000005
+# CHECK-NEXT:      - Tag:             DT_SYMTAB
+# CHECK-NEXT:        Value:           0x0000000000000006
+# CHECK-NEXT:      - Tag:             DT_RELA
+# CHECK-NEXT:        Value:           0x0000000000000007
+# CHECK-NEXT:      - Tag:             DT_RELASZ
+# CHECK-NEXT:        Value:           0x0000000000000008
+# CHECK-NEXT:      - Tag:             DT_RELAENT
+# CHECK-NEXT:        Value:           0x0000000000000009
+# CHECK-NEXT:      - Tag:             DT_STRSZ
+# CHECK-NEXT:        Value:           0x000000000000000A
+# CHECK-NEXT:      - Tag:             DT_SYMENT
+# CHECK-NEXT:        Value:           0x000000000000000B
+# CHECK-NEXT:      - Tag:             DT_INIT
+# CHECK-NEXT:        Value:           0x000000000000000C
+# CHECK-NEXT:      - Tag:             DT_FINI
+# CHECK-NEXT:        Value:           0x000000000000000D
+# CHECK-NEXT:      - Tag:             DT_SONAME
+# CHECK-NEXT:        Value:           0x000000000000000E
+# CHECK-NEXT:      - Tag:             DT_RPATH
+# CHECK-NEXT:        Value:           0x000000000000000F
+# CHECK-NEXT:      - Tag:             DT_SYMBOLIC
+# CHECK-NEXT:        Value:           0x0000000000000010
+# CHECK-NEXT:      - Tag:             DT_REL
+# CHECK-NEXT:        Value:           0x0000000000000011
+# CHECK-NEXT:      - Tag:             DT_RELSZ
+# CHECK-NEXT:        Value:           0x0000000000000012
+# CHECK-NEXT:      - Tag:             DT_RELENT
+# CHECK-NEXT:        Value:           0x0000000000000013
+# CHECK-NEXT:      - Tag:             DT_PLTREL
+# CHECK-NEXT:        Value:           0x0000000000000014
+# CHECK-NEXT:      - Tag:             DT_DEBUG
+# CHECK-NEXT:        Value:           0x0000000000000015
+# CHECK-NEXT:      - Tag:             DT_TEXTREL
+# CHECK-NEXT:        Value:           0x0000000000000016
+# CHECK-NEXT:      - Tag:             DT_JMPREL
+# CHECK-NEXT:        Value:           0x0000000000000017
+# CHECK-NEXT:      - Tag:             DT_BIND_NOW
+# CHECK-NEXT:        Value:           0x0000000000000018
+# CHECK-NEXT:      - Tag:             DT_INIT_ARRAY
+# CHECK-NEXT:        Value:           0x0000000000000019
+# CHECK-NEXT:      - Tag:             DT_FINI_ARRAY
+# CHECK-NEXT:        Value:           0x000000000000001A
+# CHECK-NEXT:      - Tag:             DT_INIT_ARRAYSZ
+# CHECK-NEXT:        Value:           0x000000000000001B
+# CHECK-NEXT:      - Tag:             DT_FINI_ARRAYSZ
+# CHECK-NEXT:        Value:           0x000000000000001C
+# CHECK-NEXT:      - Tag:             DT_RUNPATH
+# CHECK-NEXT:        Value:           0x000000000000001D
+# CHECK-NEXT:      - Tag:             DT_FLAGS
+# CHECK-NEXT:        Value:           0x000000000000001E
+# CHECK-NEXT:      - Tag:             DT_PREINIT_ARRAY
+# CHECK-NEXT:        Value:           0x000000000000001F
+# CHECK-NEXT:      - Tag:             DT_PREINIT_ARRAYSZ
+# CHECK-NEXT:        Value:           0x0000000000000020
+# CHECK-NEXT:      - Tag:             DT_SYMTAB_SHNDX
+# CHECK-NEXT:        Value:           0x0000000000000021
+# CHECK-NEXT:      - Tag:             DT_RELRSZ
+# CHECK-NEXT:        Value:           0x0000000000000022
+# CHECK-NEXT:      - Tag:             DT_RELR
+# CHECK-NEXT:        Value:           0x0000000000000023
+# CHECK-NEXT:      - Tag:             DT_RELRENT
+# CHECK-NEXT:        Value:           0x0000000000000024
+# CHECK-NEXT:      - Tag:             DT_ANDROID_REL
+# CHECK-NEXT:        Value:           0x0000000000000025
+# CHECK-NEXT:      - Tag:             DT_ANDROID_RELSZ
+# CHECK-NEXT:        Value:           0x0000000000000026
+# CHECK-NEXT:      - Tag:             DT_ANDROID_RELA
+# CHECK-NEXT:        Value:           0x0000000000000027
+# CHECK-NEXT:      - Tag:             DT_ANDROID_RELASZ
+# CHECK-NEXT:        Value:           0x0000000000000028
+# CHECK-NEXT:      - Tag:             DT_ANDROID_RELR
+# CHECK-NEXT:        Value:           0x0000000000000029
+# CHECK-NEXT:      - Tag:             DT_ANDROID_RELRSZ
+# CHECK-NEXT:        Value:           0x000000000000002A
+# CHECK-NEXT:      - Tag:             DT_ANDROID_RELRENT
+# CHECK-NEXT:        Value:           0x000000000000002B
+# CHECK-NEXT:      - Tag:             DT_GNU_HASH
+# CHECK-NEXT:        Value:           0x000000000000002C
+# CHECK-NEXT:      - Tag:             DT_TLSDESC_PLT
+# CHECK-NEXT:        Value:           0x000000000000002D
+# CHECK-NEXT:      - Tag:             DT_TLSDESC_GOT
+# CHECK-NEXT:        Value:           0x000000000000002E
+# CHECK-NEXT:      - Tag:             DT_RELACOUNT
+# CHECK-NEXT:        Value:           0x000000000000002F
+# CHECK-NEXT:      - Tag:             DT_RELCOUNT
+# CHECK-NEXT:        Value:           0x0000000000000030
+# CHECK-NEXT:      - Tag:             DT_FLAGS_1
+# CHECK-NEXT:        Value:           0x0000000000000031
+# CHECK-NEXT:      - Tag:             DT_VERSYM
+# CHECK-NEXT:        Value:           0x0000000000000032
+# CHECK-NEXT:      - Tag:             DT_VERDEF
+# CHECK-NEXT:        Value:           0x0000000000000033
+# CHECK-NEXT:      - Tag:             DT_VERDEFNUM
+# CHECK-NEXT:        Value:           0x0000000000000034
+# CHECK-NEXT:      - Tag:             DT_VERNEED
+# CHECK-NEXT:        Value:           0x0000000000000035
+# CHECK-NEXT:      - Tag:             DT_VERNEEDNUM
+# CHECK-NEXT:        Value:           0x0000000000000036
+
+!ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_DYN
+  Machine:         EM_X86_64
+Sections:
+  - Name:            .dynamic
+    Type:            SHT_DYNAMIC
+    Address:         0x0000000000001000
+    AddressAlign:    0x0000000000002000
+    EntSize:         0x0000000000000010
+    Entries:
+      - Tag:             DT_NULL
+        Value:           0x0000000000000000
+      - Tag:             DT_NEEDED
+        Value:           0x0000000000000001
+      - Tag:             DT_PLTRELSZ
+        Value:           0x0000000000000002
+      - Tag:             DT_PLTGOT
+        Value:           0x0000000000000003
+      - Tag:             DT_HASH
+        Value:           0x0000000000000004
+      - Tag:             DT_STRTAB
+        Value:           0x0000000000000005
+      - Tag:             DT_SYMTAB
+        Value:           0x0000000000000006
+      - Tag:             DT_RELA
+        Value:           0x0000000000000007
+      - Tag:             DT_RELASZ
+        Value:           0x0000000000000008
+      - Tag:             DT_RELAENT
+        Value:           0x0000000000000009
+      - Tag:             DT_STRSZ
+        Value:           0x000000000000000A
+      - Tag:             DT_SYMENT
+        Value:           0x000000000000000B
+      - Tag:             DT_INIT
+        Value:           0x000000000000000C
+      - Tag:             DT_FINI
+        Value:           0x000000000000000D
+      - Tag:             DT_SONAME
+        Value:           0x000000000000000E
+      - Tag:             DT_RPATH
+        Value:           0x000000000000000F
+      - Tag:             DT_SYMBOLIC
+        Value:           0x0000000000000010
+      - Tag:             DT_REL
+        Value:           0x0000000000000011
+      - Tag:             DT_RELSZ
+        Value:           0x0000000000000012
+      - Tag:             DT_RELENT
+        Value:           0x0000000000000013
+      - Tag:             DT_PLTREL
+        Value:           0x0000000000000014
+      - Tag:             DT_DEBUG
+        Value:           0x0000000000000015
+      - Tag:             DT_TEXTREL
+        Value:           0x0000000000000016
+      - Tag:             DT_JMPREL
+        Value:           0x0000000000000017
+      - Tag:             DT_BIND_NOW
+        Value:           0x0000000000000018
+      - Tag:             DT_INIT_ARRAY
+        Value:           0x0000000000000019
+      - Tag:             DT_FINI_ARRAY
+        Value:           0x000000000000001A
+      - Tag:             DT_INIT_ARRAYSZ
+        Value:           0x000000000000001B
+      - Tag:             DT_FINI_ARRAYSZ
+        Value:           0x000000000000001C
+      - Tag:             DT_RUNPATH
+        Value:           0x000000000000001D
+      - Tag:             DT_FLAGS
+        Value:           0x000000000000001E
+      - Tag:             DT_PREINIT_ARRAY
+        Value:           0x000000000000001F
+      - Tag:             DT_PREINIT_ARRAYSZ
+        Value:           0x0000000000000020
+      - Tag:             DT_SYMTAB_SHNDX
+        Value:           0x0000000000000021
+      - Tag:             DT_RELRSZ
+        Value:           0x0000000000000022
+      - Tag:             DT_RELR
+        Value:           0x0000000000000023
+      - Tag:             DT_RELRENT
+        Value:           0x0000000000000024
+      - Tag:             DT_ANDROID_REL
+        Value:           0x0000000000000025
+      - Tag:             DT_ANDROID_RELSZ
+        Value:           0x0000000000000026
+      - Tag:             DT_ANDROID_RELA
+        Value:           0x0000000000000027
+      - Tag:             DT_ANDROID_RELASZ
+        Value:           0x0000000000000028
+      - Tag:             DT_ANDROID_RELR
+        Value:           0x0000000000000029
+      - Tag:             DT_ANDROID_RELRSZ
+        Value:           0x000000000000002A
+      - Tag:             DT_ANDROID_RELRENT
+        Value:           0x000000000000002B
+      - Tag:             DT_GNU_HASH
+        Value:           0x000000000000002C
+      - Tag:             DT_TLSDESC_PLT
+        Value:           0x000000000000002D
+      - Tag:             DT_TLSDESC_GOT
+        Value:           0x000000000000002E
+      - Tag:             DT_RELACOUNT
+        Value:           0x000000000000002F
+      - Tag:             DT_RELCOUNT
+        Value:           0x0000000000000030
+      - Tag:             DT_FLAGS_1
+        Value:           0x0000000000000031
+      - Tag:             DT_VERSYM
+        Value:           0x0000000000000032
+      - Tag:             DT_VERDEF
+        Value:           0x0000000000000033
+      - Tag:             DT_VERDEFNUM
+        Value:           0x0000000000000034
+      - Tag:             DT_VERNEED
+        Value:           0x0000000000000035
+      - Tag:             DT_VERNEEDNUM
+        Value:           0x0000000000000036
diff --git a/tools/obj2yaml/elf2yaml.cpp b/tools/obj2yaml/elf2yaml.cpp
index e2fb463..a089890 100644
--- a/tools/obj2yaml/elf2yaml.cpp
+++ b/tools/obj2yaml/elf2yaml.cpp
@@ -21,6 +21,7 @@
 template <class ELFT>
 class ELFDumper {
   typedef object::Elf_Sym_Impl<ELFT> Elf_Sym;
+  typedef typename ELFT::Dyn Elf_Dyn;
   typedef typename ELFT::Shdr Elf_Shdr;
   typedef typename ELFT::Word Elf_Word;
   typedef typename ELFT::Rel Elf_Rel;
@@ -50,7 +51,8 @@
   template <class RelT>
   std::error_code dumpRelocation(const RelT *Rel, const Elf_Shdr *SymTab,
                                  ELFYAML::Relocation &R);
-
+  
+  ErrorOr<ELFYAML::DynamicSection *> dumpDynamicSection(const Elf_Shdr *Shdr);
   ErrorOr<ELFYAML::RelocationSection *> dumpRelocSection(const Elf_Shdr *Shdr);
   ErrorOr<ELFYAML::RawContentSection *>
   dumpContentSection(const Elf_Shdr *Shdr);
@@ -129,6 +131,13 @@
   SectionNames.resize(Sections.size());
   for (const Elf_Shdr &Sec : Sections) {
     switch (Sec.sh_type) {
+    case ELF::SHT_DYNAMIC: {
+      ErrorOr<ELFYAML::DynamicSection *> S = dumpDynamicSection(&Sec);
+      if (std::error_code EC = S.getError())
+        return EC;
+      Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get()));
+      break;
+    }
     case ELF::SHT_NULL:
     case ELF::SHT_STRTAB:
       // Do not dump these sections.
@@ -351,6 +360,23 @@
 }
 
 template <class ELFT>
+ErrorOr<ELFYAML::DynamicSection *>
+ELFDumper<ELFT>::dumpDynamicSection(const Elf_Shdr *Shdr) {
+  auto S = make_unique<ELFYAML::DynamicSection>();
+  if (std::error_code EC = dumpCommonSection(Shdr, *S))
+    return EC;
+
+  auto DynTagsOrErr = Obj.template getSectionContentsAsArray<Elf_Dyn>(Shdr);
+  if (!DynTagsOrErr)
+    return errorToErrorCode(DynTagsOrErr.takeError());
+
+  for (const Elf_Dyn &Dyn : *DynTagsOrErr)
+    S->Entries.push_back({(ELFYAML::ELF_DYNTAG)Dyn.getTag(), Dyn.getVal()});
+
+  return S.release();
+}
+
+template <class ELFT>
 ErrorOr<ELFYAML::RelocationSection *>
 ELFDumper<ELFT>::dumpRelocSection(const Elf_Shdr *Shdr) {
   auto S = make_unique<ELFYAML::RelocationSection>();
diff --git a/tools/yaml2obj/yaml2elf.cpp b/tools/yaml2obj/yaml2elf.cpp
index 0b2c99c..4e3a1d7 100644
--- a/tools/yaml2obj/yaml2elf.cpp
+++ b/tools/yaml2obj/yaml2elf.cpp
@@ -159,6 +159,9 @@
   bool writeSectionContent(Elf_Shdr &SHeader,
                            const ELFYAML::MipsABIFlags &Section,
                            ContiguousBlobAccumulator &CBA);
+  void writeSectionContent(Elf_Shdr &SHeader,
+                           const ELFYAML::DynamicSection &Section,
+                           ContiguousBlobAccumulator &CBA);
   bool hasDynamicSymbols() const;
   SmallVector<const char *, 5> implicitSectionNames() const;
 
@@ -291,6 +294,8 @@
       // SHT_NOBITS section does not have content
       // so just to setup the section offset.
       CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
+    } else if (auto S = dyn_cast<ELFYAML::DynamicSection>(Sec.get())) {
+      writeSectionContent(SHeader, *S, CBA);
     } else
       llvm_unreachable("Unknown section type");
 
@@ -465,8 +470,6 @@
     SHeader.sh_entsize = *Section.EntSize;
   else if (Section.Type == llvm::ELF::SHT_RELR)
     SHeader.sh_entsize = sizeof(Elf_Relr);
-  else if (Section.Type == llvm::ELF::SHT_DYNAMIC)
-    SHeader.sh_entsize = sizeof(Elf_Dyn);
   else
     SHeader.sh_entsize = 0;
   SHeader.sh_size = Section.Size;
@@ -575,6 +578,29 @@
   return true;
 }
 
+template <class ELFT>
+void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
+                                         const ELFYAML::DynamicSection &Section,
+                                         ContiguousBlobAccumulator &CBA) {
+  typedef typename ELFT::uint uintX_t;
+  assert(Section.Type == llvm::ELF::SHT_DYNAMIC &&
+         "Section type is not SHT_DYNAMIC");
+
+  SHeader.sh_size = 2 * sizeof(uintX_t) * Section.Entries.size();
+  if (Section.EntSize)
+    SHeader.sh_entsize = *Section.EntSize;
+  else
+    SHeader.sh_entsize = sizeof(Elf_Dyn);
+
+  auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
+  for (const ELFYAML::DynamicEntry &DE : Section.Entries) {
+    uintX_t Tag = DE.Tag;
+    OS.write((const char *)&Tag, sizeof(uintX_t));
+    uintX_t Val = DE.Val;
+    OS.write((const char *)&Val, sizeof(uintX_t));
+  }
+}
+
 template <class ELFT> bool ELFState<ELFT>::buildSectionIndex() {
   for (unsigned i = 0, e = Doc.Sections.size(); i != e; ++i) {
     StringRef Name = Doc.Sections[i]->Name;