[llvm-branch-commits] [llvm] d9afe85 - [yaml2obj/obj2yaml] - Refine handling of SHT_GNU_verdef sections.
Georgii Rymar via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Jan 15 01:47:45 PST 2021
Author: Georgii Rymar
Date: 2021-01-15T12:40:42+03:00
New Revision: d9afe8588e49f1a2779ab1fe7ff2ec39e8d080fd
URL: https://github.com/llvm/llvm-project/commit/d9afe8588e49f1a2779ab1fe7ff2ec39e8d080fd
DIFF: https://github.com/llvm/llvm-project/commit/d9afe8588e49f1a2779ab1fe7ff2ec39e8d080fd.diff
LOG: [yaml2obj/obj2yaml] - Refine handling of SHT_GNU_verdef sections.
This patch:
1) Makes `Version`, `Flags`, `VersionNdx` and `Hash` fields to be `Optional<>`.
2) Disallows dumping version definitions that have `vd_version != 1`.
`vd_version` identifies the version of the structure itself.
(https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/symversion.html,
https://docs.oracle.com/cd/E19683-01/816-7777/chapter6-80869/index.html)
3) Stops dumping default values for `Version`, `Flags`, `VersionNdx` and `Hash` fields.
4) Refines testing.
Differential revision: https://reviews.llvm.org/D94659
Added:
Modified:
llvm/include/llvm/ObjectYAML/ELFYAML.h
llvm/lib/ObjectYAML/ELFEmitter.cpp
llvm/lib/ObjectYAML/ELFYAML.cpp
llvm/test/tools/obj2yaml/ELF/verdef-section.yaml
llvm/test/tools/yaml2obj/ELF/verdef-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 a289aab05b2c..c9e90527380e 100644
--- a/llvm/include/llvm/ObjectYAML/ELFYAML.h
+++ b/llvm/include/llvm/ObjectYAML/ELFYAML.h
@@ -522,10 +522,10 @@ struct SymverSection : Section {
};
struct VerdefEntry {
- uint16_t Version;
- uint16_t Flags;
- uint16_t VersionNdx;
- uint32_t Hash;
+ Optional<uint16_t> Version;
+ Optional<uint16_t> Flags;
+ Optional<uint16_t> VersionNdx;
+ Optional<uint32_t> Hash;
std::vector<StringRef> VerNames;
};
diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp
index ba0525c4a675..d4d61b22f1e1 100644
--- a/llvm/lib/ObjectYAML/ELFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp
@@ -1456,10 +1456,10 @@ void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
const ELFYAML::VerdefEntry &E = (*Section.Entries)[I];
Elf_Verdef VerDef;
- VerDef.vd_version = E.Version;
- VerDef.vd_flags = E.Flags;
- VerDef.vd_ndx = E.VersionNdx;
- VerDef.vd_hash = E.Hash;
+ VerDef.vd_version = E.Version.getValueOr(1);
+ VerDef.vd_flags = E.Flags.getValueOr(0);
+ VerDef.vd_ndx = E.VersionNdx.getValueOr(0);
+ VerDef.vd_hash = E.Hash.getValueOr(0);
VerDef.vd_aux = sizeof(Elf_Verdef);
VerDef.vd_cnt = E.VerNames.size();
if (I == Section.Entries->size() - 1)
diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp
index 3a280b06336d..20b52723b1e8 100644
--- a/llvm/lib/ObjectYAML/ELFYAML.cpp
+++ b/llvm/lib/ObjectYAML/ELFYAML.cpp
@@ -1584,10 +1584,10 @@ void MappingTraits<ELFYAML::VerdefEntry>::mapping(IO &IO,
ELFYAML::VerdefEntry &E) {
assert(IO.getContext() && "The IO context is not initialized");
- IO.mapRequired("Version", E.Version);
- IO.mapRequired("Flags", E.Flags);
- IO.mapRequired("VersionNdx", E.VersionNdx);
- IO.mapRequired("Hash", E.Hash);
+ IO.mapOptional("Version", E.Version);
+ IO.mapOptional("Flags", E.Flags);
+ IO.mapOptional("VersionNdx", E.VersionNdx);
+ IO.mapOptional("Hash", E.Hash);
IO.mapRequired("Names", E.VerNames);
}
diff --git a/llvm/test/tools/obj2yaml/ELF/verdef-section.yaml b/llvm/test/tools/obj2yaml/ELF/verdef-section.yaml
index 762b797ceb2b..cd6981c25df1 100644
--- a/llvm/test/tools/obj2yaml/ELF/verdef-section.yaml
+++ b/llvm/test/tools/obj2yaml/ELF/verdef-section.yaml
@@ -1,42 +1,37 @@
+## Check how we dump SHT_GNU_verdef sections.
+
# RUN: yaml2obj %s -o %t
# RUN: obj2yaml %t | FileCheck %s
-## Check we are able to yamalize SHT_GNU_verdef section.
-
-# CHECK: - Name: .gnu.version_d
-# CHECK-NEXT: Type: SHT_GNU_verdef
-# CHECK-NEXT: Flags: [ SHF_ALLOC ]
-# CHECK-NEXT: Address: 0x230
-# CHECK-NEXT: Link: .dynstr
-# CHECK-NEXT: AddressAlign: 0x4
-# CHECK-NEXT: Info: 0x4
-# CHECK-NEXT: Entries:
-# CHECK-NEXT: - Version: 1
-# CHECK-NEXT: Flags: 1
-# CHECK-NEXT: VersionNdx: 1
-# CHECK-NEXT: Hash: 170240160
-# CHECK-NEXT: Names:
-# CHECK-NEXT: - dso.so.0
-# CHECK-NEXT: - Version: 1
-# CHECK-NEXT: Flags: 2
-# CHECK-NEXT: VersionNdx: 2
-# CHECK-NEXT: Hash: 108387921
-# CHECK-NEXT: Names:
-# CHECK-NEXT: - VERSION_1
-# CHECK-NEXT: - Version: 1
-# CHECK-NEXT: Flags: 3
-# CHECK-NEXT: VersionNdx: 3
-# CHECK-NEXT: Hash: 108387922
-# CHECK-NEXT: Names:
-# CHECK-NEXT: - VERSION_2
-# CHECK-NEXT: - VERSION_3
+# CHECK: - Name: .gnu.version_d
+# CHECK-NEXT: Type: SHT_GNU_verdef
+# CHECK-NEXT: Flags: [ SHF_ALLOC ]
+# CHECK-NEXT: Address: 0x230
+# CHECK-NEXT: Link: .dynstr
+# CHECK-NEXT: AddressAlign: 0x4
+# CHECK-NEXT: Info: 0x4
+# CHECK-NEXT: Entries:
+# CHECK-NEXT: - Names:
+# CHECK-NEXT: - VERSION_0
+# CHECK-NEXT: - Flags: 2
+# CHECK-NEXT: VersionNdx: 2
+# CHECK-NEXT: Hash: 108387921
+# CHECK-NEXT: Names:
+# CHECK-NEXT: - VERSION_1
+# CHECK-NEXT: - Flags: 3
+# CHECK-NEXT: VersionNdx: 3
+# CHECK-NEXT: Hash: 108387922
+# CHECK-NEXT: Names:
+# CHECK-NEXT: - VERSION_2
+# CHECK-NEXT: - VERSION_3
+# CHECK-NEXT: - VERSION_4
+# CHECK-NEXT: - Name:
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_DYN
- Entry: 0x1000
Sections:
- Name: .gnu.version_d
Type: SHT_GNU_verdef
@@ -46,26 +41,36 @@ Sections:
AddressAlign: 0x4
Info: 0x4
Entries:
- - Version: 1
- Flags: 1
- VersionNdx: 1
- Hash: 170240160
+## An entry that has all fields explicitly set to their default values.
+## Used to check that we don't dump them.
+ - Version: [[VERSION=1]]
+ Flags: 0
+ VersionNdx: 0
+ Hash: 0
Names:
- - dso.so.0
- - Version: 1
- Flags: 2
- VersionNdx: 2
- Hash: 108387921
+ - VERSION_0
+## An entry with arbitrary values.
+ - Flags: 2
+ VersionNdx: 2
+ Hash: 108387921
Names:
- VERSION_1
- - Version: 1
- Flags: 3
- VersionNdx: 3
- Hash: 108387922
+## Another entry with arbitrary values and version predecessors.
+ - Flags: 3
+ VersionNdx: 3
+ Hash: 108387922
Names:
- VERSION_2
- VERSION_3
-DynamicSymbols:
- - Name: foo
- Binding: STB_GLOBAL
-...
+ - VERSION_4
+## Needed to emit the .dynstr section.
+DynamicSymbols: []
+
+## Document that we are not able to dump a version definition which
+## has a version revision (vd_version) that is not equal to 1.
+
+# RUN: yaml2obj %s -DVERSION=2 -o %t.version
+# RUN: not obj2yaml %t.version 2>&1 | \
+# RUN: FileCheck %s -DFILE=%t.version --check-prefix=VERSION-ERR
+
+# VERSION-ERR: Error reading file: [[FILE]]: invalid SHT_GNU_verdef section version: 2
diff --git a/llvm/test/tools/yaml2obj/ELF/verdef-section.yaml b/llvm/test/tools/yaml2obj/ELF/verdef-section.yaml
index 376a2531a200..f7dae449b67f 100644
--- a/llvm/test/tools/yaml2obj/ELF/verdef-section.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/verdef-section.yaml
@@ -1,4 +1,4 @@
-## Check we are able to handle SHT_GNU_verdef sections.
+## Test how we create SHT_GNU_verdef sections.
# RUN: yaml2obj --docnum=1 %s -o %t1
# RUN: llvm-readobj -V %t1 | FileCheck %s
@@ -6,6 +6,15 @@
# CHECK: VersionDefinitions [
# CHECK-NEXT: Definition {
# CHECK-NEXT: Version: 1
+# CHECK-NEXT: Flags [ (0x0)
+# CHECK-NEXT: ]
+# CHECK-NEXT: Index: 0
+# CHECK-NEXT: Hash: 0
+# CHECK-NEXT: Name:
+# CHECK-NEXT: Predecessors: []
+# CHECK-NEXT: }
+# CHECK-NEXT: Definition {
+# CHECK-NEXT: Version: 1
# CHECK-NEXT: Flags [ (0x1)
# CHECK-NEXT: Base (0x1)
# CHECK-NEXT: ]
@@ -26,14 +35,15 @@
# CHECK-NEXT: }
# CHECK-NEXT: Definition {
# CHECK-NEXT: Version: 1
-# CHECK-NEXT: Flags [ (0x3)
+# CHECK-NEXT: Flags [ (0xFFFF)
# CHECK-NEXT: Base (0x1)
+# CHECK-NEXT: Info (0x4)
# CHECK-NEXT: Weak (0x2)
# CHECK-NEXT: ]
# CHECK-NEXT: Index: 3
# CHECK-NEXT: Hash: 108387922
# CHECK-NEXT: Name: VERSION_2
-# CHECK-NEXT: Predecessors: [VERSION_3]
+# CHECK-NEXT: Predecessors: [VERSION_3, VERSION_4]
# CHECK-NEXT: }
# CHECK-NEXT: ]
@@ -42,39 +52,54 @@ FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_DYN
- Entry: 0x0000000000001000
Sections:
- - Name: .gnu.version_d
- Type: SHT_GNU_verdef
- Flags: [ SHF_ALLOC ]
- Address: 0x0000000000000230
- Link: .dynstr
- AddressAlign: 0x0000000000000004
- Info: 0x0000000000000003
+ - Name: .gnu.version_d
+ Type: SHT_GNU_verdef
+ Flags: [ SHF_ALLOC ]
+ Link: .dynstr
+ Info: 0x4
Entries:
- - Version: 1
- Flags: 1
- VersionNdx: 1
- Hash: 170240160
+## 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
+## that we are able to use the "=<none>" syntax for these fields.
+ - Version: [[VERSION=<none>]]
+ Flags: [[FLAGS=<none>]]
+ VersionNdx: [[VERNDX=<none>]]
+ Hash: [[HASH=<none>]]
+ Names: []
+## Case 2: an arbitrary entry.
+ - Flags: 1
+ VersionNdx: 1
+ Hash: 170240160
Names:
- dso.so.0
- - Version: 1
- Flags: 2
- VersionNdx: 2
- Hash: 108387921
+## Case 3: one more arbitrary entry with
diff erent values.
+ - Flags: 2
+ VersionNdx: 2
+ Hash: 108387921
Names:
- VERSION_1
- - Version: 1
- Flags: 3
- VersionNdx: 3
- Hash: 108387922
+## Case 4: an entry that has version predecessors. Also, it sets
+## all known flags as well as few unknown.
+ - Flags: 0xffff
+ VersionNdx: 3
+ Hash: 108387922
Names:
- VERSION_2
- VERSION_3
+ - VERSION_4
DynamicSymbols:
- Name: foo
Binding: STB_GLOBAL
+## Check we are able to emit a version definition which has a version revision
+## (vd_version) field value that is not equal to 1.
+
+# RUN: yaml2obj --docnum=1 -DVERSION=2 %s -o %t.version
+# RUN: llvm-readobj -V %t.version 2>&1 | FileCheck %s --check-prefix=VERSION-ERR
+
+# 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.
# RUN: yaml2obj --docnum=2 %s -o %t2
diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp
index 494aa5b17b13..320c0aa36c65 100644
--- a/llvm/tools/obj2yaml/elf2yaml.cpp
+++ b/llvm/tools/obj2yaml/elf2yaml.cpp
@@ -1315,10 +1315,19 @@ ELFDumper<ELFT>::dumpVerdefSection(const Elf_Shdr *Shdr) {
while (Buf) {
const Elf_Verdef *Verdef = reinterpret_cast<const Elf_Verdef *>(Buf);
ELFYAML::VerdefEntry Entry;
- Entry.Version = Verdef->vd_version;
- Entry.Flags = Verdef->vd_flags;
- Entry.VersionNdx = Verdef->vd_ndx;
- Entry.Hash = Verdef->vd_hash;
+ if (Verdef->vd_version != 1)
+ return createStringError(errc::invalid_argument,
+ "invalid SHT_GNU_verdef section version: " +
+ Twine(Verdef->vd_version));
+
+ if (Verdef->vd_flags != 0)
+ Entry.Flags = Verdef->vd_flags;
+
+ if (Verdef->vd_ndx != 0)
+ Entry.VersionNdx = Verdef->vd_ndx;
+
+ if (Verdef->vd_hash != 0)
+ Entry.Hash = Verdef->vd_hash;
const uint8_t *BufAux = Buf + Verdef->vd_aux;
while (BufAux) {
More information about the llvm-branch-commits
mailing list