mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 02:33:06 +01:00
[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
This commit is contained in:
parent
ec64cb3a8e
commit
fc516b0eae
@ -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) {}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -644,7 +644,6 @@ Sections:
|
||||
Type: SHT_GNU_versym
|
||||
EntSize: 0x0000000000000003
|
||||
Entries: [ ]
|
||||
Link: .dynsym
|
||||
## Needed to trigger creation of .dynsym.
|
||||
DynamicSymbols:
|
||||
- Name: foo
|
||||
|
@ -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
|
||||
|
@ -22,7 +22,6 @@ Sections:
|
||||
Address: 0x0000000000200250
|
||||
Link: .dynstr
|
||||
AddressAlign: 0x0000000000000004
|
||||
Info: 0x0000000000000002
|
||||
Dependencies:
|
||||
- Version: 1
|
||||
File: dso.so.0
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -44,7 +44,6 @@ Sections:
|
||||
- Name: .gnu.version
|
||||
Type: SHT_GNU_versym
|
||||
Flags: [ SHF_ALLOC ]
|
||||
Link: .dynsym
|
||||
Entries: [ 0, 1 ]
|
||||
DynamicSymbols:
|
||||
- Name: foo
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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: []
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user