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
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
- Name: .gnu.version_r
Type: SHT_GNU_verneed
Flags: [ SHF_ALLOC ]
- Info: 1
- Link: .dynstr
Dependencies:
- Version: 1
File: foo
Type: SHT_GNU_verneed
Flags: [ SHF_ALLOC ]
Info: 1
- Link: .dynstr
Content: "[[VERNEED]]"
DynamicSymbols:
- Name: foo
struct VerneedSection : Section {
Optional<std::vector<VerneedEntry>> VerneedV;
- llvm::yaml::Hex64 Info;
+ Optional<llvm::yaml::Hex64> Info;
VerneedSection() : Section(ChunkKind::Verneed) {}
struct VerdefSection : Section {
Optional<std::vector<VerdefEntry>> Entries;
-
- llvm::yaml::Hex64 Info;
+ Optional<llvm::yaml::Hex64> Info;
VerdefSection() : Section(ChunkKind::Verdef) {}
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;
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;
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;
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);
}
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);
}
Type: SHT_GNU_versym
EntSize: 0x0000000000000003
Entries: [ ]
- Link: .dynsym
## Needed to trigger creation of .dynsym.
DynamicSymbols:
- Name: foo
Type: SHT_GNU_verdef
Flags: [ SHF_ALLOC ]
Address: 0x0000000000000230
- Link: .dynstr
AddressAlign: 0x0000000000000004
- Info: 0x0000000000000003
Entries:
- Version: 1
Flags: 1
Address: 0x0000000000200250
Link: .dynstr
AddressAlign: 0x0000000000000004
- Info: 0x0000000000000002
Dependencies:
- Version: 1
File: dso.so.0
- 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
- Name: .gnu.version_d
Type: SHT_GNU_verdef
Flags: [ SHF_ALLOC ]
- Link: .dynstr
AddressAlign: 0x4
- Info: 0x2
Entries:
- VersionNdx: 2
Names:
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
- Name: .gnu.version
Type: SHT_GNU_versym
Flags: [ SHF_ALLOC ]
- Link: .dynsym
Entries: [ 0, 1 ]
DynamicSymbols:
- Name: foo
- Name: .gnu.version_r
Type: SHT_GNU_verneed
Flags: [ SHF_ALLOC ]
- Link: .dynstr
AddressAlign: 0x0000000000000004
- Info: 0x0000000000000002
Dependencies:
- Version: 1
File: verneed1.so.0
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
- 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.
Sections:
- Name: .gnu.version_d
Type: SHT_GNU_verdef
- Link: .dynstr
- Info: 0x0
Entries: []
ShOffset: [[SHOFFSET=<none>]]
ShName: [[SHNAME=<none>]]
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
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
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
- 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: []
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
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
- 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
- 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"
- Name: .gnu.version_r
Type: SHT_GNU_verneed
Flags: [ SHF_ALLOC ]
- Info: 1
Link: .mystrtab
AddressAlign: 4
Dependencies:
- Name: .gnu.version_r
Type: SHT_GNU_verneed
Flags: [ SHF_ALLOC ]
- Info: 1
Link: .mystrtab
AddressAlign: 4
Dependencies:
- Name: .gnu.version_r
Type: SHT_GNU_verneed
Flags: [ SHF_ALLOC ]
- Info: 1
Link: [[LINK=.dynstr]]
ShName: [[SHNAME=<none>]]
Dependencies:
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:
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
- Name: .gnu.version_r
Type: SHT_GNU_verneed
Flags: [ SHF_ALLOC ]
- Info: 1
Link: .dynstr
Dependencies:
- Version: 1
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
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:
- Name: .gnu.version_r
Type: SHT_GNU_verneed
Flags: [ SHF_ALLOC ]
- Info: 1
- Link: .dynstr
Dependencies:
- Version: 0xfefe
File: foo
- 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
- 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
- Name: .gnu.version_r
Type: SHT_GNU_verneed
Flags: [ SHF_ALLOC ]
- Link: .dynstr
AddressAlign: 0x0000000000000004
- Info: 0x0000000000000002
Dependencies:
- Version: 1
File: verneed1.so.0
Sections:
- Name: .gnu.version
Type: SHT_GNU_versym
- Link: .dynsym
Entries: [ 0 ]
- Name: .dynstr
Type: SHT_NULL
- Name: .gnu.version
Type: SHT_GNU_versym
Entries: [ 0 ]
- Link: .dynsym
ShOffset: [[SHOFFSET=<none>]]
ShName: [[SHNAME=<none>]]
- Name: .dynsym
# 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 [
- Name: .gnu.version
Type: SHT_GNU_versym
Entries: [ 0, 1 ]
- Link: .dynsym
DynamicSymbols:
- Name: foo
- Name: bar
## 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
# 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
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.
## 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.
+## 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
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
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
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
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
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
Type: SHT_GNU_verneed
Flags: [ SHF_ALLOC ]
ShType: [[TYPE=SHT_GNU_verneed]]
- Info: 0
Dependencies:
- Version: 1
File: dso.so.0
## 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 {
- 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
- 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.
# 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
# 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 (
- 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.
# 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:
- 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.
Sections:
- Name: .gnu.version_d
Type: SHT_GNU_verdef
- Info: 0x1
Size: [[SIZE=<none>]]
Content: [[CONTENT=<none>]]
Entries: [[ENTRIES=<none>]]
# 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
-## 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 {
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
- 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:
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>]]
# 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
Type: SHT_GNU_versym
Flags: [ SHF_ALLOC ]
Address: 0x0000000000200210
- Link: .dynsym
AddressAlign: 0x0000000000000002
EntSize: 0x0000000000000002
Entries: [ 0, 3, 4 ]
Type: SHT_GNU_verneed
Flags: [ SHF_ALLOC ]
Address: 0x0000000000200250
- Link: .dynstr
AddressAlign: 0x0000000000000004
- Info: 0x0000000000000001
Dependencies:
- Version: 1
File: dso.so.0
...
## 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:
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
# 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: )
# 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
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();
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();
}
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();
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();
}