[llvm] 51f4958 - [yaml2obj/obj2yaml] - Improve dumping/creating of ELF versioning sections.

Georgii Rymar via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 20 23:51:34 PST 2021


Author: Georgii Rymar
Date: 2021-01-21T10:36:48+03:00
New Revision: 51f4958057d6c246e85c3fbc65353bc0d7c1049b

URL: https://github.com/llvm/llvm-project/commit/51f4958057d6c246e85c3fbc65353bc0d7c1049b
DIFF: https://github.com/llvm/llvm-project/commit/51f4958057d6c246e85c3fbc65353bc0d7c1049b.diff

LOG: [yaml2obj/obj2yaml] - Improve dumping/creating of ELF versioning sections.

This makes the following improvements.

For `SHT_GNU_versym`:
 * yaml2obj: set `sh_link` to index of `.dynsym` section automatically.
For `SHT_GNU_verdef`:
 * yaml2obj: set `sh_link` to index of `.dynstr` section automatically.
 * yaml2obj: set `sh_info` field automatically.
 * obj2yaml: don't dump the `Info` field when its value matches the number of version definitions.
For `SHT_GNU_verneed`:
 * yaml2obj: set `sh_link` to index of `.dynstr` section automatically.
 * yaml2obj: set `sh_info` field automatically.
 * obj2yaml: don't dump the `Info` field when its value matches the number of version dependencies.

Also, simplifies few test cases.

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

Added: 
    

Modified: 
    lld/test/ELF/invalid/verneed-shared.test
    llvm/include/llvm/ObjectYAML/ELFYAML.h
    llvm/lib/ObjectYAML/ELFEmitter.cpp
    llvm/lib/ObjectYAML/ELFYAML.cpp
    llvm/test/Object/invalid.test
    llvm/test/tools/llvm-objdump/ELF/verdef.test
    llvm/test/tools/llvm-objdump/ELF/verneed.test
    llvm/test/tools/llvm-readobj/ELF/all.test
    llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test
    llvm/test/tools/llvm-readobj/ELF/hidden-versym.test
    llvm/test/tools/llvm-readobj/ELF/merged.test
    llvm/test/tools/llvm-readobj/ELF/reloc-symbol-with-versioning.test
    llvm/test/tools/llvm-readobj/ELF/section-types.test
    llvm/test/tools/llvm-readobj/ELF/verdef-invalid.test
    llvm/test/tools/llvm-readobj/ELF/verneed-flags.yaml
    llvm/test/tools/llvm-readobj/ELF/verneed-invalid.test
    llvm/test/tools/llvm-readobj/ELF/versioninfo.test
    llvm/test/tools/llvm-readobj/ELF/versym-invalid.test
    llvm/test/tools/obj2yaml/ELF/verdef-section.yaml
    llvm/test/tools/obj2yaml/ELF/verneed-section.yaml
    llvm/test/tools/yaml2obj/ELF/override-shname.yaml
    llvm/test/tools/yaml2obj/ELF/override-shoffset.yaml
    llvm/test/tools/yaml2obj/ELF/override-shsize.yaml
    llvm/test/tools/yaml2obj/ELF/override-shtype.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/lld/test/ELF/invalid/verneed-shared.test b/lld/test/ELF/invalid/verneed-shared.test
index 916b8c1a5d95..2e2ff494fb58 100644
--- a/lld/test/ELF/invalid/verneed-shared.test
+++ b/lld/test/ELF/invalid/verneed-shared.test
@@ -14,10 +14,9 @@ FileHeader:
   Type:    ET_DYN
   Machine: EM_X86_64
 Sections:
-  - Name:  .gnu.version_r
-    Type:  SHT_GNU_verneed
-    Flags: [ SHF_ALLOC ]
-    Info:  1
+  - Name:     .gnu.version_r
+    Type:     SHT_GNU_verneed
+    Flags:    [ SHF_ALLOC ]
     ShOffset: 0xFFFFFFFF
 
 ## A Verneed entry is misaligned (not a multiple of 4). This may happen
@@ -37,8 +36,6 @@ Sections:
   - Name:  .gnu.version_r
     Type:  SHT_GNU_verneed
     Flags: [ SHF_ALLOC ]
-    Info:  1
-    Link:  .dynstr
     Dependencies:
       - Version: 1
         File:    foo
@@ -65,7 +62,6 @@ Sections:
     Type:  SHT_GNU_verneed
     Flags: [ SHF_ALLOC ]
     Info:  1
-    Link:  .dynstr
     Content: "[[VERNEED]]"
 DynamicSymbols:
   - Name: foo

diff  --git a/llvm/include/llvm/ObjectYAML/ELFYAML.h b/llvm/include/llvm/ObjectYAML/ELFYAML.h
index c9e90527380e..98ba8cda372b 100644
--- a/llvm/include/llvm/ObjectYAML/ELFYAML.h
+++ b/llvm/include/llvm/ObjectYAML/ELFYAML.h
@@ -427,7 +427,7 @@ struct VerneedEntry {
 
 struct VerneedSection : Section {
   Optional<std::vector<VerneedEntry>> VerneedV;
-  llvm::yaml::Hex64 Info;
+  Optional<llvm::yaml::Hex64> Info;
 
   VerneedSection() : Section(ChunkKind::Verneed) {}
 
@@ -531,8 +531,7 @@ struct VerdefEntry {
 
 struct VerdefSection : Section {
   Optional<std::vector<VerdefEntry>> Entries;
-
-  llvm::yaml::Hex64 Info;
+  Optional<llvm::yaml::Hex64> Info;
 
   VerdefSection() : Section(ChunkKind::Verdef) {}
 

diff  --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp
index d4d61b22f1e1..752a037d61b1 100644
--- a/llvm/lib/ObjectYAML/ELFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp
@@ -1288,6 +1288,11 @@ template <class ELFT>
 void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
                                          const ELFYAML::SymverSection &Section,
                                          ContiguousBlobAccumulator &CBA) {
+  unsigned Link = 0;
+  if (!Section.Link && !ExcludedSectionHeaders.count(".dynsym") &&
+      SN2I.lookup(".dynsym", Link))
+    SHeader.sh_link = Link;
+
   if (!Section.Entries)
     return;
 
@@ -1446,7 +1451,16 @@ template <class ELFT>
 void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
                                          const ELFYAML::VerdefSection &Section,
                                          ContiguousBlobAccumulator &CBA) {
-  SHeader.sh_info = Section.Info;
+
+  if (Section.Info)
+    SHeader.sh_info = *Section.Info;
+  else if (Section.Entries)
+    SHeader.sh_info = Section.Entries->size();
+
+  unsigned Link = 0;
+  if (!Section.Link && !ExcludedSectionHeaders.count(".dynstr") &&
+      SN2I.lookup(".dynstr", Link))
+    SHeader.sh_link = Link;
 
   if (!Section.Entries)
     return;
@@ -1488,7 +1502,15 @@ template <class ELFT>
 void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
                                          const ELFYAML::VerneedSection &Section,
                                          ContiguousBlobAccumulator &CBA) {
-  SHeader.sh_info = Section.Info;
+  if (Section.Info)
+    SHeader.sh_info = *Section.Info;
+  else if (Section.VerneedV)
+    SHeader.sh_info = Section.VerneedV->size();
+
+  unsigned Link = 0;
+  if (!Section.Link && !ExcludedSectionHeaders.count(".dynstr") &&
+      SN2I.lookup(".dynstr", Link))
+    SHeader.sh_link = Link;
 
   if (!Section.VerneedV)
     return;

diff  --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp
index 20b52723b1e8..84022cf6b416 100644
--- a/llvm/lib/ObjectYAML/ELFYAML.cpp
+++ b/llvm/lib/ObjectYAML/ELFYAML.cpp
@@ -1203,7 +1203,7 @@ static void sectionMapping(IO &IO, ELFYAML::NoBitsSection &Section) {
 
 static void sectionMapping(IO &IO, ELFYAML::VerdefSection &Section) {
   commonSectionMapping(IO, Section);
-  IO.mapRequired("Info", Section.Info);
+  IO.mapOptional("Info", Section.Info);
   IO.mapOptional("Entries", Section.Entries);
 }
 
@@ -1214,7 +1214,7 @@ static void sectionMapping(IO &IO, ELFYAML::SymverSection &Section) {
 
 static void sectionMapping(IO &IO, ELFYAML::VerneedSection &Section) {
   commonSectionMapping(IO, Section);
-  IO.mapRequired("Info", Section.Info);
+  IO.mapOptional("Info", Section.Info);
   IO.mapOptional("Dependencies", Section.VerneedV);
 }
 

diff  --git a/llvm/test/Object/invalid.test b/llvm/test/Object/invalid.test
index 89bb4b5c5a62..1e0629efc0f7 100644
--- a/llvm/test/Object/invalid.test
+++ b/llvm/test/Object/invalid.test
@@ -644,7 +644,6 @@ Sections:
     Type:    SHT_GNU_versym
     EntSize: 0x0000000000000003
     Entries: [ ]
-    Link:    .dynsym
 ## Needed to trigger creation of .dynsym.
 DynamicSymbols:
   - Name:    foo

diff  --git a/llvm/test/tools/llvm-objdump/ELF/verdef.test b/llvm/test/tools/llvm-objdump/ELF/verdef.test
index 254328f877c5..034afe8d166e 100644
--- a/llvm/test/tools/llvm-objdump/ELF/verdef.test
+++ b/llvm/test/tools/llvm-objdump/ELF/verdef.test
@@ -18,9 +18,7 @@ Sections:
     Type:            SHT_GNU_verdef
     Flags:           [ SHF_ALLOC ]
     Address:         0x0000000000000230
-    Link:            .dynstr
     AddressAlign:    0x0000000000000004
-    Info:            0x0000000000000003
     Entries:
       - Version:         1
         Flags:           1

diff  --git a/llvm/test/tools/llvm-objdump/ELF/verneed.test b/llvm/test/tools/llvm-objdump/ELF/verneed.test
index b9130dcbb11c..66ac837bfbf6 100644
--- a/llvm/test/tools/llvm-objdump/ELF/verneed.test
+++ b/llvm/test/tools/llvm-objdump/ELF/verneed.test
@@ -22,7 +22,6 @@ Sections:
     Address:         0x0000000000200250
     Link:            .dynstr
     AddressAlign:    0x0000000000000004
-    Info:            0x0000000000000002
     Dependencies:
       - Version:         1
         File:            dso.so.0

diff  --git a/llvm/test/tools/llvm-readobj/ELF/all.test b/llvm/test/tools/llvm-readobj/ELF/all.test
index 3d452d8b60f8..f3de10fda806 100644
--- a/llvm/test/tools/llvm-readobj/ELF/all.test
+++ b/llvm/test/tools/llvm-readobj/ELF/all.test
@@ -53,14 +53,11 @@ Sections:
   - Name:    .gnu.version
     Type:    SHT_GNU_versym
     Entries: [ 0 ]
-    Link:    .dynsym
   - Name:    .gnu.version_d
     Type:    SHT_GNU_verdef
-    Info:    0x0
     Entries: []
   - Name: .gnu.version_r
     Type: SHT_GNU_verneed
-    Info: 0x0
     Dependencies:
       - Version: 1
         File:    verneed1.so.0

diff  --git a/llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test b/llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test
index edb12d861862..9ab2e8508f32 100644
--- a/llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test
+++ b/llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test
@@ -304,9 +304,7 @@ Sections:
   - Name:         .gnu.version_d
     Type:         SHT_GNU_verdef
     Flags:        [ SHF_ALLOC ]
-    Link:         .dynstr
     AddressAlign: 0x4
-    Info:         0x2
     Entries:
       - VersionNdx: 2
         Names:

diff  --git a/llvm/test/tools/llvm-readobj/ELF/hidden-versym.test b/llvm/test/tools/llvm-readobj/ELF/hidden-versym.test
index bc1904f0c535..8bbd7b614549 100644
--- a/llvm/test/tools/llvm-readobj/ELF/hidden-versym.test
+++ b/llvm/test/tools/llvm-readobj/ELF/hidden-versym.test
@@ -15,13 +15,10 @@ Sections:
     Type:    SHT_GNU_versym
     Flags:   [ SHF_ALLOC ]
     Address: 0x0000000000200210
-    Link:    .dynsym
     Entries: [ 0, 0x8003 ]
   - Name:  .gnu.version_r
     Type:  SHT_GNU_verneed
     Flags: [ SHF_ALLOC ]
-    Link:  .dynstr
-    Info:  0x0000000000000001
     Dependencies:
       - Version: 1
         File:    somefile

diff  --git a/llvm/test/tools/llvm-readobj/ELF/merged.test b/llvm/test/tools/llvm-readobj/ELF/merged.test
index 0892a174c58a..5b464ebbdce7 100644
--- a/llvm/test/tools/llvm-readobj/ELF/merged.test
+++ b/llvm/test/tools/llvm-readobj/ELF/merged.test
@@ -44,7 +44,6 @@ Sections:
   - Name:    .gnu.version
     Type:    SHT_GNU_versym
     Flags:   [ SHF_ALLOC ]
-    Link:    .dynsym
     Entries: [ 0, 1 ]
 DynamicSymbols:
   - Name:    foo

diff  --git a/llvm/test/tools/llvm-readobj/ELF/reloc-symbol-with-versioning.test b/llvm/test/tools/llvm-readobj/ELF/reloc-symbol-with-versioning.test
index 1034f0f7c933..76974d0dd427 100644
--- a/llvm/test/tools/llvm-readobj/ELF/reloc-symbol-with-versioning.test
+++ b/llvm/test/tools/llvm-readobj/ELF/reloc-symbol-with-versioning.test
@@ -36,9 +36,7 @@ Sections:
   - Name:         .gnu.version_r
     Type:         SHT_GNU_verneed
     Flags:        [ SHF_ALLOC ]
-    Link:         .dynstr
     AddressAlign: 0x0000000000000004
-    Info:         0x0000000000000002
     Dependencies:
       - Version: 1
         File:    verneed1.so.0

diff  --git a/llvm/test/tools/llvm-readobj/ELF/section-types.test b/llvm/test/tools/llvm-readobj/ELF/section-types.test
index 2453a85c732f..ee220982eeef 100644
--- a/llvm/test/tools/llvm-readobj/ELF/section-types.test
+++ b/llvm/test/tools/llvm-readobj/ELF/section-types.test
@@ -212,11 +212,9 @@ Sections:
     Content: ""
   - Name: gnu_verdef
     Type: SHT_GNU_verdef
-    Info: 0
     Entries:
   - Name: gnu_verneed
     Type: SHT_GNU_verneed
-    Info: 0
     Dependencies:
   - Name: unknown
     Type: 0x1000

diff  --git a/llvm/test/tools/llvm-readobj/ELF/verdef-invalid.test b/llvm/test/tools/llvm-readobj/ELF/verdef-invalid.test
index 17e0fb1dda63..e8bd4d21f742 100644
--- a/llvm/test/tools/llvm-readobj/ELF/verdef-invalid.test
+++ b/llvm/test/tools/llvm-readobj/ELF/verdef-invalid.test
@@ -21,7 +21,6 @@ Sections:
   - Name:    .gnu.version_d
     Type:    SHT_GNU_verdef
     Link:    [[LINK]]
-    Info:    0x0
     Entries: []
 
 ## Check that we report a warning when the sh_link field of a SHT_GNU_verdef section references a non-string table section.
@@ -48,8 +47,6 @@ FileHeader:
 Sections:
   - Name:     .gnu.version_d
     Type:     SHT_GNU_verdef
-    Link:     .dynstr
-    Info:     0x0
     Entries:  []
     ShOffset: [[SHOFFSET=<none>]]
     ShName:   [[SHNAME=<none>]]
@@ -102,10 +99,8 @@ FileHeader:
   Data:  ELFDATA2LSB
   Type:  ET_DYN
 Sections:
-  - Name:    .gnu.version_d
-    Type:    SHT_GNU_verdef
-    Link:    .dynstr
-    Info:    0x1
+  - Name: .gnu.version_d
+    Type: SHT_GNU_verdef
     Entries:
       - Names:
           - FOO
@@ -128,10 +123,8 @@ FileHeader:
   Data:  ELFDATA2LSB
   Type:  ET_DYN
 Sections:
-  - Name:    .gnu.version_d
-    Type:    SHT_GNU_verdef
-    Link:    .dynstr
-    Info:    0x1
+  - Name: .gnu.version_d
+    Type: SHT_GNU_verdef
     Entries:
       - Names:
           - FOO
@@ -168,10 +161,9 @@ FileHeader:
   Data:  ELFDATA2LSB
   Type:  ET_DYN
 Sections:
-  - Name:    .gnu.version_d
-    Type:    SHT_GNU_verdef
-    Link:    .strtab
-    Info:    0x1
+  - Name: .gnu.version_d
+    Type: SHT_GNU_verdef
+    Link: .strtab
     Entries:
       - Names:
           - FOO
@@ -286,14 +278,12 @@ Sections:
   - Name:         .gnu.version
     Type:         SHT_GNU_versym
     Flags:        [ SHF_ALLOC ]
-    Link:         .dynsym
     AddressAlign: 0x0000000000000002
     EntSize:      0x0000000000000002
     Entries:      [ 0, 2 ]
   - Name:         .gnu.version_d
     Type:         SHT_GNU_verdef
     Flags:        [ SHF_ALLOC ]
-    Link:         .dynstr
     AddressAlign: 0x4
     Info:         0x1
     Entries: []

diff  --git a/llvm/test/tools/llvm-readobj/ELF/verneed-flags.yaml b/llvm/test/tools/llvm-readobj/ELF/verneed-flags.yaml
index 2399efe3b176..f1f2be0cb194 100644
--- a/llvm/test/tools/llvm-readobj/ELF/verneed-flags.yaml
+++ b/llvm/test/tools/llvm-readobj/ELF/verneed-flags.yaml
@@ -83,10 +83,8 @@ FileHeader:
   Type:  ET_EXEC
   Entry: 0x0000000000201000
 Sections:
-  - Name:            .gnu.version_r
-    Type:            SHT_GNU_verneed
-    Link:            .dynstr
-    Info:            0x0000000000000001
+  - Name: .gnu.version_r
+    Type: SHT_GNU_verneed
     Dependencies:
       - Version:         1
         File:            dso.so.0

diff  --git a/llvm/test/tools/llvm-readobj/ELF/verneed-invalid.test b/llvm/test/tools/llvm-readobj/ELF/verneed-invalid.test
index 2d4e32a8b163..548920838bca 100644
--- a/llvm/test/tools/llvm-readobj/ELF/verneed-invalid.test
+++ b/llvm/test/tools/llvm-readobj/ELF/verneed-invalid.test
@@ -55,13 +55,10 @@ Sections:
     Type:    SHT_GNU_versym
     Flags:   [ SHF_ALLOC ]
     Address: 0x200210
-    Link:    .dynsym
     Entries: [ 0, 2 ]
   - Name:  .gnu.version_r
     Type:  SHT_GNU_verneed
     Flags: [ SHF_ALLOC ]
-    Link:  .dynstr
-    Info:  1
     AddressAlign: 4
     Dependencies:
       - Version:   1
@@ -130,13 +127,11 @@ Sections:
   - Name:    .gnu.version
     Type:    SHT_GNU_versym
     Flags:   [ SHF_ALLOC ]
-    Link:    .dynsym
     Entries: [ 0, 2 ]
   - Name:  .gnu.version_r
     Type:  SHT_GNU_verneed
     Flags: [ SHF_ALLOC ]
     Link:  0
-    Info:  1
     AddressAlign: 4
     Dependencies:
       - Version: 1
@@ -178,13 +173,11 @@ Sections:
   - Name:    .gnu.version
     Type:    SHT_GNU_versym
     Flags:   [ SHF_ALLOC ]
-    Link:    .dynsym
     Entries: [ 2 ]
   - Name:         .gnu.version_r
     Type:         SHT_GNU_verneed
     Flags:        [ SHF_ALLOC ]
     Info:         1
-    Link:         .dynstr
     AddressAlign: 4
 ## The byte offset to the auxiliary entry is 0x11, i.e. it is not correctly aligned in memory.
     Content: "0100010001000000110000000000000000000000"
@@ -244,7 +237,6 @@ Sections:
   - Name:  .gnu.version_r
     Type:  SHT_GNU_verneed
     Flags: [ SHF_ALLOC ]
-    Info:  1
     Link:  .mystrtab
     AddressAlign: 4
     Dependencies:
@@ -299,7 +291,6 @@ Sections:
   - Name:  .gnu.version_r
     Type:  SHT_GNU_verneed
     Flags: [ SHF_ALLOC ]
-    Info:  1
     Link:  .mystrtab
     AddressAlign: 4
     Dependencies:
@@ -352,7 +343,6 @@ Sections:
   - Name:   .gnu.version_r
     Type:   SHT_GNU_verneed
     Flags:  [ SHF_ALLOC ]
-    Info:   1
     Link:   [[LINK=.dynstr]]
     ShName: [[SHNAME=<none>]]
     Dependencies:
@@ -429,11 +419,9 @@ FileHeader:
   Data:  ELFDATA2LSB
   Type:  ET_EXEC
 Sections:
-  - Name:  .gnu.version_r
-    Type:  SHT_GNU_verneed
-    Flags: [ SHF_ALLOC ]
-    Info:  1
-    Link:  .dynstr
+  - Name:     .gnu.version_r
+    Type:     SHT_GNU_verneed
+    Flags:    [ SHF_ALLOC ]
     ShOffset: 0xFFFFFFFF
 ## Triggers creation of the .dynstr.
 DynamicSymbols:
@@ -454,11 +442,9 @@ FileHeader:
   Data:  ELFDATA2LSB
   Type:  ET_EXEC
 Sections:
-  - Name:  .gnu.version_r
-    Type:  SHT_GNU_verneed
-    Flags: [ SHF_ALLOC ]
-    Info:  1
-    Link:  .dynstr
+  - Name:   .gnu.version_r
+    Type:   SHT_GNU_verneed
+    Flags:  [ SHF_ALLOC ]
     ShSize: 0x1
     Dependencies:
       - Version: 1
@@ -490,7 +476,6 @@ Sections:
   - Name:  .gnu.version_r
     Type:  SHT_GNU_verneed
     Flags: [ SHF_ALLOC ]
-    Info:  1
     Link:  .dynstr
     Dependencies:
       - Version: 1
@@ -518,11 +503,9 @@ FileHeader:
   Data:  ELFDATA2LSB
   Type:  ET_EXEC
 Sections:
-  - Name:  .gnu.version_r
-    Type:  SHT_GNU_verneed
-    Flags: [ SHF_ALLOC ]
-    Info:  1
-    Link:  .dynstr
+  - Name:   .gnu.version_r
+    Type:   SHT_GNU_verneed
+    Flags:  [ SHF_ALLOC ]
     ShSize: 21
     Dependencies:
       - Version: 1
@@ -553,7 +536,6 @@ Sections:
     Type:  SHT_GNU_verneed
     Flags: [ SHF_ALLOC ]
     Info:  1
-    Link:  .dynstr
 ## The byte offset to the auxiliary entry is 0x11, i.e. it is not correctly aligned in memory.
     Content: "0100010001000000110000000000000000000000"
 DynamicSymbols:
@@ -576,8 +558,6 @@ Sections:
   - Name:  .gnu.version_r
     Type:  SHT_GNU_verneed
     Flags: [ SHF_ALLOC ]
-    Info:  1
-    Link:  .dynstr
     Dependencies:
       - Version: 0xfefe
         File:    foo
@@ -625,13 +605,11 @@ Sections:
   - Name:    .gnu.version
     Type:    SHT_GNU_versym
     Flags:   [ SHF_ALLOC ]
-    Link:    .dynsym
     Entries: [ 0, 2 ]
-  - Name:         .gnu.version_r
-    Type:         SHT_GNU_verneed
-    Flags:        [ SHF_ALLOC ]
-    Link:         .custom.dynstr
-    Info:         1
+  - Name:  .gnu.version_r
+    Type:  SHT_GNU_verneed
+    Flags: [ SHF_ALLOC ]
+    Link:  .custom.dynstr
     AddressAlign: 4
     Dependencies:
       - Version: 1

diff  --git a/llvm/test/tools/llvm-readobj/ELF/versioninfo.test b/llvm/test/tools/llvm-readobj/ELF/versioninfo.test
index 38f1c6a02973..a7125bedea02 100644
--- a/llvm/test/tools/llvm-readobj/ELF/versioninfo.test
+++ b/llvm/test/tools/llvm-readobj/ELF/versioninfo.test
@@ -16,16 +16,12 @@ Sections:
   - Name:         .gnu.version
     Type:         SHT_GNU_versym
     Flags:        [ SHF_ALLOC ]
-    Link:         .dynsym
     AddressAlign: 0x0000000000000002
-    EntSize:      0x0000000000000002
     Entries:      [ 0, 2, 3, 4, 5, 6]
   - Name:         .gnu.version_d
     Type:         SHT_GNU_verdef
     Flags:        [ SHF_ALLOC ]
-    Link:         .dynstr
     AddressAlign: 0x0000000000000004
-    Info:         0x0000000000000006
     Entries:
       - Names:
           - VERSION1
@@ -53,9 +49,7 @@ Sections:
   - Name:         .gnu.version_r
     Type:         SHT_GNU_verneed
     Flags:        [ SHF_ALLOC ]
-    Link:         .dynstr
     AddressAlign: 0x0000000000000004
-    Info:         0x0000000000000002
     Dependencies:
       - Version: 1
         File:    verneed1.so.0

diff  --git a/llvm/test/tools/llvm-readobj/ELF/versym-invalid.test b/llvm/test/tools/llvm-readobj/ELF/versym-invalid.test
index 9c7cc376322c..0c4ce6b98816 100644
--- a/llvm/test/tools/llvm-readobj/ELF/versym-invalid.test
+++ b/llvm/test/tools/llvm-readobj/ELF/versym-invalid.test
@@ -66,7 +66,6 @@ FileHeader:
 Sections:
   - Name:    .gnu.version
     Type:    SHT_GNU_versym
-    Link:    .dynsym
     Entries: [ 0 ]
   - Name:    .dynstr
     Type:    SHT_NULL
@@ -95,7 +94,6 @@ Sections:
   - Name:     .gnu.version
     Type:     SHT_GNU_versym
     Entries:  [ 0 ]
-    Link:     .dynsym
     ShOffset: [[SHOFFSET=<none>]]
     ShName:   [[SHNAME=<none>]]
   - Name:   .dynsym
@@ -149,7 +147,7 @@ DynamicSymbols: []
 # INVALID-ENT-SIZE-GNU-NEXT:      0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT   UND @<corrupt>
 # INVALID-ENT-SIZE-GNU-NEXT:      1: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT   UND foo@<corrupt>
 # INVALID-ENT-SIZE-GNU:      Version symbols section '.gnu.version' contains 1 entries:
-# INVALID-ENT-SIZE-GNU-NEXT:  Addr: 0000000000000000  Offset: 0x000040  Link: 0 ()
+# INVALID-ENT-SIZE-GNU-NEXT:  Addr: 0000000000000000  Offset: 0x000040  Link: 2 (.dynsym)
 # INVALID-ENT-SIZE-GNU-NEXT: warning: '[[FILE]]': cannot read content of SHT_GNU_versym section with index 1: section [index 1] has invalid sh_entsize: expected 2, but got 3
 
 # INVALID-ENT-SIZE-LLVM:      DynamicSymbols [
@@ -214,7 +212,6 @@ Sections:
   - Name:    .gnu.version
     Type:    SHT_GNU_versym
     Entries: [ 0, 1 ]
-    Link:   .dynsym
 DynamicSymbols:
   - Name: foo
   - Name: bar

diff  --git a/llvm/test/tools/obj2yaml/ELF/verdef-section.yaml b/llvm/test/tools/obj2yaml/ELF/verdef-section.yaml
index cd6981c25df1..fc3e0f7ae22d 100644
--- a/llvm/test/tools/obj2yaml/ELF/verdef-section.yaml
+++ b/llvm/test/tools/obj2yaml/ELF/verdef-section.yaml
@@ -1,4 +1,6 @@
 ## Check how we dump SHT_GNU_verdef sections.
+## Check we don't dump the `Info` field when its value is equal
+## to the number of version definitions.
 
 # RUN: yaml2obj %s -o %t
 # RUN: obj2yaml %t | FileCheck %s
@@ -9,7 +11,7 @@
 # CHECK-NEXT:    Address:      0x230
 # CHECK-NEXT:    Link:         .dynstr
 # CHECK-NEXT:    AddressAlign: 0x4
-# CHECK-NEXT:    Info:         0x4
+# INFO-NEXT:     Info:         0x4
 # CHECK-NEXT:    Entries:
 # CHECK-NEXT:      - Names:
 # CHECK-NEXT:          - VERSION_0
@@ -37,9 +39,8 @@ Sections:
     Type:            SHT_GNU_verdef
     Flags:           [ SHF_ALLOC ]
     Address:         0x230
-    Link:            .dynstr
     AddressAlign:    0x4
-    Info:            0x4
+    Info:            [[INFO=<none>]]
     Entries:
 ## An entry that has all fields explicitly set to their default values.
 ## Used to check that we don't dump them.
@@ -66,6 +67,12 @@ Sections:
 ## Needed to emit the .dynstr section.
 DynamicSymbols: []
 
+## Check we dump the `Info` field when its value is not equal
+## to the number of version definitions.
+
+# RUN: yaml2obj %s -DINFO=0x4 -o %t.info
+# RUN: obj2yaml %t.info | FileCheck %s --check-prefixes=CHECK,INFO
+
 ## Document that we are not able to dump a version definition which
 ## has a version revision (vd_version) that is not equal to 1.
 

diff  --git a/llvm/test/tools/obj2yaml/ELF/verneed-section.yaml b/llvm/test/tools/obj2yaml/ELF/verneed-section.yaml
index acd997c3ebff..dbc507794ca8 100644
--- a/llvm/test/tools/obj2yaml/ELF/verneed-section.yaml
+++ b/llvm/test/tools/obj2yaml/ELF/verneed-section.yaml
@@ -1,15 +1,17 @@
+## Check that we are able to yamalize the SHT_GNU_verneed section.
+## Check we don't dump the `Info` field when its value
+## is equal to the number of version dependencies.
+
 # RUN: yaml2obj %s -o %t
 # RUN: obj2yaml %t | FileCheck %s
 
-## Check we are able to yamalize SHT_GNU_verneed section.
-
 # CHECK:      - Name:            .gnu.version_r
 # CHECK-NEXT:   Type:            SHT_GNU_verneed
 # CHECK-NEXT:   Flags:           [ SHF_ALLOC ]
 # CHECK-NEXT:   Address:         0x200250
 # CHECK-NEXT:   Link:            .dynstr
 # CHECK-NEXT:   AddressAlign:    0x4
-# CHECK-NEXT:   Info:            0x2
+# INFO-NEXT:    Info:            0x3
 # CHECK-NEXT:   Dependencies:
 # CHECK-NEXT:     - Version:         1
 # CHECK-NEXT:       File:            dso.so.0
@@ -37,13 +39,12 @@ FileHeader:
   Type:  ET_EXEC
   Entry: 0x0000000000201000
 Sections:
-  - Name:            .gnu.version_r
-    Type:            SHT_GNU_verneed
-    Flags:           [ SHF_ALLOC ]
-    Address:         0x200250
-    Link:            .dynstr
-    AddressAlign:    4
-    Info:            2
+  - Name:         .gnu.version_r
+    Type:         SHT_GNU_verneed
+    Flags:        [ SHF_ALLOC ]
+    Address:      0x200250
+    AddressAlign: 4
+    Info:         [[INFO=<none>]]
     Dependencies:
       - Version:         1
         File:            dso.so.0
@@ -66,3 +67,9 @@ Sections:
 DynamicSymbols:
   - Name:    f1
     Binding: STB_GLOBAL
+
+## Check we dump the `Info` field when its value
+## is not equal to the number of version dependencies.
+
+# RUN: yaml2obj %s -DINFO=0x3 -o %t.info
+# RUN: obj2yaml %t.info | FileCheck %s --check-prefixes=CHECK,INFO

diff  --git a/llvm/test/tools/yaml2obj/ELF/override-shname.yaml b/llvm/test/tools/yaml2obj/ELF/override-shname.yaml
index 702e65b93da2..ab73a6a5345f 100644
--- a/llvm/test/tools/yaml2obj/ELF/override-shname.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/override-shname.yaml
@@ -68,14 +68,12 @@ Sections:
     Type: SHT_GNU_versym
     Entries: [ ]
     ShName: 0x000000007
-  - Name: .gnu.version_r
-    Type: SHT_GNU_verneed
-    Info: 0x0000000000000001
+  - Name:   .gnu.version_r
+    Type:   SHT_GNU_verneed
     ShName: 0x000000008
     Dependencies:
   - Name: .gnu.version_d
     Type: SHT_GNU_verdef
-    Info: 0x0000000000000001
     ShName: 0x000000009
     Entries:
   - Name: .regular

diff  --git a/llvm/test/tools/yaml2obj/ELF/override-shoffset.yaml b/llvm/test/tools/yaml2obj/ELF/override-shoffset.yaml
index 91f8cad31da5..48c60d518c22 100644
--- a/llvm/test/tools/yaml2obj/ELF/override-shoffset.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/override-shoffset.yaml
@@ -48,14 +48,12 @@ Sections:
     Type: SHT_GNU_versym
     Entries: [ ]
     ShOffset: 0x000000007
-  - Name: .gnu.version_r
-    Type: SHT_GNU_verneed
-    Info: 0x0000000000000001
+  - Name:     .gnu.version_r
+    Type:     SHT_GNU_verneed
     ShOffset: 0x000000008
     Dependencies:
   - Name: .gnu.version_d
     Type: SHT_GNU_verdef
-    Info: 0x0000000000000001
     ShOffset: 0x000000009
     Entries:
   - Name: .regular

diff  --git a/llvm/test/tools/yaml2obj/ELF/override-shsize.yaml b/llvm/test/tools/yaml2obj/ELF/override-shsize.yaml
index aec6b4cdef3e..c7e218e12410 100644
--- a/llvm/test/tools/yaml2obj/ELF/override-shsize.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/override-shsize.yaml
@@ -48,14 +48,12 @@ Sections:
     Type: SHT_GNU_versym
     Entries: [ ]
     ShSize: 0x000000007
-  - Name: .gnu.version_r
-    Type: SHT_GNU_verneed
-    Info: 0x0000000000000001
+  - Name:   .gnu.version_r
+    Type:   SHT_GNU_verneed
     ShSize: 0x000000008
     Dependencies:
   - Name: .gnu.version_d
     Type: SHT_GNU_verdef
-    Info: 0x0000000000000001
     ShSize: 0x000000009
     Entries:
   - Name: .regular

diff  --git a/llvm/test/tools/yaml2obj/ELF/override-shtype.yaml b/llvm/test/tools/yaml2obj/ELF/override-shtype.yaml
index e35983e30ade..b7545597bbec 100644
--- a/llvm/test/tools/yaml2obj/ELF/override-shtype.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/override-shtype.yaml
@@ -31,7 +31,6 @@ Sections:
     Type:   SHT_GNU_verneed
     Flags:  [ SHF_ALLOC ]
     ShType: [[TYPE=SHT_GNU_verneed]]
-    Info:   0
     Dependencies:
       - Version: 1
         File:    dso.so.0

diff  --git a/llvm/test/tools/yaml2obj/ELF/verdef-section.yaml b/llvm/test/tools/yaml2obj/ELF/verdef-section.yaml
index f7dae449b67f..65490da101c6 100644
--- a/llvm/test/tools/yaml2obj/ELF/verdef-section.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/verdef-section.yaml
@@ -1,7 +1,18 @@
 ## Test how we create SHT_GNU_verdef sections.
 
+## Check that we link the SHT_GNU_verdef section to
+## the `.dynstr` section by default.
+## Check that we set the value of `sh_info` field to the
+## number of version definitions by default.
+
 # RUN: yaml2obj --docnum=1 %s -o %t1
 # RUN: llvm-readobj -V %t1 | FileCheck %s
+# RUN: llvm-readelf --sections %t1 | \
+# RUN:   FileCheck %s -DLINK=3 -DINFO=4 --check-prefix=FIELDS
+
+# FIELDS: [Nr] Name              Type   {{.*}} Flg Lk       Inf
+# FIELDS: [ 1] .gnu.version_d    VERDEF {{.*}}   A [[LINK]] [[INFO]]
+# FIELDS: [ 3] .dynstr
 
 # CHECK:      VersionDefinitions [
 # CHECK-NEXT:   Definition {
@@ -56,8 +67,8 @@ Sections:
   - Name:  .gnu.version_d
     Type:  SHT_GNU_verdef
     Flags: [ SHF_ALLOC ]
-    Link:  .dynstr
-    Info:  0x4
+    Info:  [[INFO=<none>]]
+    Link:  [[LINK=<none>]]
     Entries:
 ## Case 1: an entry that has no Version, Flags, VersionNdx or Hash fields set.
 ##         Used to check values that are written by default. Also shows
@@ -92,6 +103,12 @@ DynamicSymbols:
   - Name:    foo
     Binding: STB_GLOBAL
 
+## Check that we are able to set sh_info and sh_link fields to arbitrary values.
+
+# RUN: yaml2obj --docnum=1 -DINFO=123 -DLINK=234 %s -o %t1.fields
+# RUN: llvm-readelf --sections %t1.fields | \
+# RUN:   FileCheck %s -DINFO=123 -DLINK=234 --check-prefix=FIELDS
+
 ## Check we are able to emit a version definition which has a version revision
 ## (vd_version) field value that is not equal to 1.
 
@@ -101,6 +118,7 @@ DynamicSymbols:
 # VERSION-ERR: unable to dump SHT_GNU_verdef section with index 1: version 2 is not yet supported
 
 ## Check we can use "Content" to describe the content.
+## Check we set the sh_link field to 0 when there is no .dynstr section.
 
 # RUN: yaml2obj --docnum=2 %s -o %t2
 # RUN: llvm-readobj --sections --section-data %t2 | FileCheck %s --check-prefix=CONTENT
@@ -114,7 +132,7 @@ DynamicSymbols:
 # CONTENT-NEXT: Offset: 0x40
 # CONTENT-NEXT: Size: 3
 # CONTENT-NEXT: Link: 0
-# CONTENT-NEXT: Info: 1
+# CONTENT-NEXT: Info: 0
 # CONTENT-NEXT: AddressAlignment:
 # CONTENT-NEXT: EntrySize:
 # CONTENT-NEXT: SectionData (
@@ -130,7 +148,6 @@ Sections:
   - Name:    .gnu.version_d
     Type:    SHT_GNU_verdef
     Flags:   [ SHF_ALLOC ]
-    Info:    0x0000000000000001
     Content: "112233"
 
 ## Check we can omit "Content" and "Entries" fields to produce an empty SHT_GNU_verdef section.
@@ -139,7 +156,7 @@ Sections:
 # RUN: llvm-readelf --sections %t3 | FileCheck %s --check-prefix=NO-PROPS
 
 # NO-PROPS: [Nr] Name           Type   Address          Off    Size   ES Flg Lk Inf Al
-# NO-PROPS: [ 1] .gnu.version_d VERDEF 0000000000000000 000040 000000 00   A 0   1  0
+# NO-PROPS: [ 1] .gnu.version_d VERDEF 0000000000000000 000040 000000 00   A 0   0  0
 
 --- !ELF
 FileHeader:
@@ -150,7 +167,6 @@ Sections:
   - Name:  .gnu.version_d
     Type:  SHT_GNU_verdef
     Flags: [ SHF_ALLOC ]
-    Info:  0x0000000000000001
 
 ## Check we can use the "Content" key with the "Size" key when the size is greater
 ## than or equal to the content size.
@@ -168,7 +184,6 @@ FileHeader:
 Sections:
   - Name:    .gnu.version_d
     Type:    SHT_GNU_verdef
-    Info:    0x1
     Size:    [[SIZE=<none>]]
     Content: [[CONTENT=<none>]]
     Entries: [[ENTRIES=<none>]]
@@ -206,3 +221,30 @@ Sections:
 # RUN:   FileCheck %s --check-prefix=ENTRIES-ERR
 
 # ENTRIES-ERR: error: "Entries" cannot be used with "Content" or "Size"
+
+## Check we set the sh_link field to 0 when the .dynstr section is excluded
+## from the section header table.
+
+# RUN: yaml2obj --docnum=5 %s -o %t5
+# RUN: llvm-readelf --sections %t5 | FileCheck %s --check-prefix=EXCLUDED
+
+# EXCLUDED: [Nr] Name           {{.*}} ES Flg Lk Inf
+# EXCLUDED: [ 1] .gnu.version_d {{.*}} 00     0   0
+
+--- !ELF
+FileHeader:
+  Class: ELFCLASS64
+  Data:  ELFDATA2LSB
+  Type:  ET_DYN
+Sections:
+  - Name: .gnu.version_d
+    Type: SHT_GNU_verdef
+  - Name: .dynstr
+    Type: SHT_STRTAB
+SectionHeaderTable:
+  Sections:
+    - Name: .gnu.version_d
+    - Name: .strtab
+    - Name: .shstrtab
+  Excluded:
+    - Name: .dynstr

diff  --git a/llvm/test/tools/yaml2obj/ELF/verneed-section.yaml b/llvm/test/tools/yaml2obj/ELF/verneed-section.yaml
index fad54c27bfca..2fbf83a69b4e 100644
--- a/llvm/test/tools/yaml2obj/ELF/verneed-section.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/verneed-section.yaml
@@ -1,7 +1,17 @@
-## Check we are able to handle SHT_GNU_verneed sections.
+## Check we are able to dump SHT_GNU_verneed sections properly.
+## Check that we link the SHT_GNU_verneed section to
+## the `.dynstr` section by default.
+## Check that we set the value of `sh_info` field to the number
+## of version dependencies by default.
 
 # RUN: yaml2obj --docnum=1 %s -o %t1
 # RUN: llvm-readobj -V %t1 | FileCheck %s
+# RUN: llvm-readelf --sections %t1 | \
+# RUN:   FileCheck %s -DLINK=3 -DINFO=2 --check-prefix=FIELDS
+
+# FIELDS: [Nr] Name           Type    {{.*}} Flg Lk       Inf      Al
+# FIELDS: [ 1] .gnu.version_r VERNEED {{.*}}   A [[LINK]] [[INFO]] 4
+# FIELDS: [ 3] .dynstr
 
 # CHECK:      VersionRequirements [
 # CHECK-NEXT:   Dependency {
@@ -52,13 +62,13 @@ FileHeader:
   Type:  ET_EXEC
   Entry: 0x0000000000201000
 Sections:
-  - Name:            .gnu.version_r
-    Type:            SHT_GNU_verneed
-    Flags:           [ SHF_ALLOC ]
-    Address:         0x0000000000200250
-    Link:            .dynstr
-    AddressAlign:    0x0000000000000004
-    Info:            0x0000000000000002
+  - Name:         .gnu.version_r
+    Type:         SHT_GNU_verneed
+    Flags:        [ SHF_ALLOC ]
+    Address:      0x0000000000200250
+    AddressAlign: 0x0000000000000004
+    Info:         [[INFO=<none>]]
+    Link:         [[LINK=<none>]]
     Dependencies:
       - Version:         1
         File:            dso.so.0
@@ -82,14 +92,21 @@ DynamicSymbols:
   - Name:    f1
     Binding: STB_GLOBAL
 
+## Check that we are able to set sh_info and sh_link fields to arbitrary values.
+
+# RUN: yaml2obj --docnum=1 -DINFO=123 -DLINK=234 %s -o %t1.fields
+# RUN: llvm-readelf --sections %t1.fields | \
+# RUN:   FileCheck %s -DINFO=123 -DLINK=234 --check-prefix=FIELDS
+
 ## Check we can omit "Content", "Size" and "Dependencies" fields to
 ## produce an empty SHT_GNU_verneed section.
+## Check we set the sh_link field to 0 when there is no .dynstr section.
 
 # 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
-# NO-PROPS: [ 1] .gnu.version_r VERNEED 0000000000000000 000040 000000
+# NO-PROPS: [Nr] Name           Type    Address          Off    Size   ES Flg Lk Inf
+# NO-PROPS: [ 1] .gnu.version_r VERNEED 0000000000000000 000040 000000 00   A 0  0
 
 --- !ELF
 FileHeader:
@@ -97,10 +114,9 @@ FileHeader:
   Data:  ELFDATA2LSB
   Type:  ET_EXEC
 Sections:
-  - Name:  .gnu.version_r
-    Type:  SHT_GNU_verneed
-    Flags: [ SHF_ALLOC ]
-    Info:  0x0
+  - Name:         .gnu.version_r
+    Type:         SHT_GNU_verneed
+    Flags:        [ SHF_ALLOC ]
     Size:         [[SIZE=<none>]]
     Content:      [[CONTENT=<none>]]
     Dependencies: [[DEPS=<none>]]
@@ -146,3 +162,30 @@ Sections:
 # RUN:   FileCheck %s --check-prefix=DEPS-ERR
 
 # DEPS-ERR: error: "Dependencies" cannot be used with "Content" or "Size"
+
+## Check we set the sh_link field to 0 when the .dynstr section is excluded
+## from the section header table.
+
+# RUN: yaml2obj --docnum=3 %s -o %t3
+# RUN: llvm-readelf --sections %t3 | FileCheck %s --check-prefix=EXCLUDED
+
+# EXCLUDED: [Nr] Name           {{.*}} ES Flg Lk Inf
+# EXCLUDED: [ 1] .gnu.version_r {{.*}} 00     0   0
+
+--- !ELF
+FileHeader:
+  Class: ELFCLASS64
+  Data:  ELFDATA2LSB
+  Type:  ET_DYN
+Sections:
+  - Name: .gnu.version_r
+    Type: SHT_GNU_verneed
+  - Name: .dynstr
+    Type: SHT_STRTAB
+SectionHeaderTable:
+  Sections:
+    - Name: .gnu.version_r
+    - Name: .strtab
+    - Name: .shstrtab
+  Excluded:
+    - Name: .dynstr

diff  --git a/llvm/test/tools/yaml2obj/ELF/versym-section.yaml b/llvm/test/tools/yaml2obj/ELF/versym-section.yaml
index 7f9fc713356e..24a0916a0ef8 100644
--- a/llvm/test/tools/yaml2obj/ELF/versym-section.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/versym-section.yaml
@@ -55,7 +55,6 @@ Sections:
     Type:            SHT_GNU_versym
     Flags:           [ SHF_ALLOC ]
     Address:         0x0000000000200210
-    Link:            .dynsym
     AddressAlign:    0x0000000000000002
     EntSize:         0x0000000000000002
     Entries:         [ 0, 3, 4 ]
@@ -63,9 +62,7 @@ Sections:
     Type:            SHT_GNU_verneed
     Flags:           [ SHF_ALLOC ]
     Address:         0x0000000000200250
-    Link:            .dynstr
     AddressAlign:    0x0000000000000004
-    Info:            0x0000000000000001
     Dependencies:
       - Version:         1
         File:            dso.so.0
@@ -86,13 +83,15 @@ DynamicSymbols:
 ...
 
 ## Check we are able to set custom sh_entsize field for SHT_GNU_versym section.
+## Check we link the SHT_GNU_versym section to the .dynsym section by default.
 
 # RUN: yaml2obj --docnum=2 %s -o %t2
-# RUN: llvm-readelf -S %t2 | FileCheck %s --check-prefix=ENTSIZE
+# RUN: llvm-readelf -S %t2 | FileCheck %s -DLINK=2 --check-prefix=FIELDS
 
-# ENTSIZE: Section Headers:
-# ENTSIZE:   [Nr] Name         Type   Address          Off    Size   ES
-# ENTSIZE:   [ 1] .gnu.version VERSYM 0000000000000000 000040 000000 03
+# FIELDS: Section Headers:
+# FIELDS:   [Nr] Name         Type   Address          Off    Size   ES Flg Lk
+# FIELDS:   [ 1] .gnu.version VERSYM 0000000000000000 000040 000000 03     [[LINK]]
+# FIELDS:   [ 2] .dynsym      DYNSYM 0000000000000000 000040 000018 18   A 3
 
 --- !ELF
 FileHeader:
@@ -105,9 +104,18 @@ Sections:
     Type:    SHT_GNU_versym
     EntSize: 0x0000000000000003
     Entries: [ ]
+    Link:    [[LINK=<none>]]
+## Needed to emit the .dynsym section.
+DynamicSymbols: []
+
+## Check we are able to set the sh_link field to an arbitrary value.
+
+# RUN: yaml2obj --docnum=2 -DLINK=0xff %s -o %t2.link
+# RUN: llvm-readelf -S %t2.link | FileCheck %s -DLINK=255 --check-prefix=FIELDS
 
 ## Check we can use the "Content" key with the "Size" key when the size is greater
 ## than or equal to the content size.
+## Also, check that we set the sh_link field to 0 when there is no .dynsym section.
 
 # RUN: not yaml2obj --docnum=3 -DSIZE=1 -DCONTENT="'0011'" %s 2>&1 | \
 # RUN:   FileCheck %s --check-prefix=CONTENT-SIZE-ERR
@@ -134,8 +142,15 @@ Sections:
 # 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:        Name: .gnu.version
+# CHECK-CONTENT-NEXT:   Type: SHT_GNU_versym (0x6FFFFFFF)
+# CHECK-CONTENT-NEXT:   Flags [ (0x0)
+# CHECK-CONTENT-NEXT:   ]
+# CHECK-CONTENT-NEXT:   Address:
+# CHECK-CONTENT-NEXT:   Offset:
+# CHECK-CONTENT-NEXT:   Size:
+# CHECK-CONTENT-NEXT:   Link: 0
+# CHECK-CONTENT:        SectionData (
 # CHECK-CONTENT-NEXT:   0000: [[DATA]] |
 # CHECK-CONTENT-NEXT: )
 
@@ -159,3 +174,30 @@ Sections:
 # RUN:   FileCheck %s --check-prefix=ENTRIES-ERR
 
 # ENTRIES-ERR: error: "Entries" cannot be used with "Content" or "Size"
+
+## Check we set the sh_link field to 0 when the .dynsym section is excluded
+## from the section header table.
+
+# RUN: yaml2obj --docnum=4 %s -o %t4
+# RUN: llvm-readelf --sections %t4 | FileCheck %s --check-prefix=EXCLUDED
+
+# EXCLUDED: [Nr] Name         {{.*}} ES Flg Lk Inf
+# EXCLUDED: [ 1] .gnu.version {{.*}} 02     0   0
+
+--- !ELF
+FileHeader:
+  Class: ELFCLASS64
+  Data:  ELFDATA2LSB
+  Type:  ET_DYN
+Sections:
+  - Name: .gnu.version
+    Type: SHT_GNU_versym
+  - Name: .dynsym
+    Type: SHT_DYNSYM
+SectionHeaderTable:
+  Sections:
+    - Name: .gnu.version
+    - Name: .strtab
+    - Name: .shstrtab
+  Excluded:
+    - Name: .dynsym

diff  --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp
index 320c0aa36c65..d92e2254d9b3 100644
--- a/llvm/tools/obj2yaml/elf2yaml.cpp
+++ b/llvm/tools/obj2yaml/elf2yaml.cpp
@@ -1294,8 +1294,6 @@ ELFDumper<ELFT>::dumpVerdefSection(const Elf_Shdr *Shdr) {
   if (Error E = dumpCommonSection(Shdr, *S))
     return std::move(E);
 
-  S->Info = Shdr->sh_info;
-
   auto StringTableShdrOrErr = Obj.getSection(Shdr->sh_link);
   if (!StringTableShdrOrErr)
     return StringTableShdrOrErr.takeError();
@@ -1342,6 +1340,9 @@ ELFDumper<ELFT>::dumpVerdefSection(const Elf_Shdr *Shdr) {
     Buf = Verdef->vd_next ? Buf + Verdef->vd_next : nullptr;
   }
 
+  if (Shdr->sh_info != S->Entries->size())
+    S->Info = (llvm::yaml::Hex64)Shdr->sh_info;
+
   return S.release();
 }
 
@@ -1370,8 +1371,6 @@ ELFDumper<ELFT>::dumpVerneedSection(const Elf_Shdr *Shdr) {
   if (Error E = dumpCommonSection(Shdr, *S))
     return std::move(E);
 
-  S->Info = Shdr->sh_info;
-
   auto Contents = Obj.getSectionContents(*Shdr);
   if (!Contents)
     return Contents.takeError();
@@ -1416,6 +1415,9 @@ ELFDumper<ELFT>::dumpVerneedSection(const Elf_Shdr *Shdr) {
     Buf = Verneed->vn_next ? Buf + Verneed->vn_next : nullptr;
   }
 
+  if (Shdr->sh_info != S->VerneedV->size())
+    S->Info = (llvm::yaml::Hex64)Shdr->sh_info;
+
   return S.release();
 }
 


        


More information about the llvm-commits mailing list