[yaml2obj] - Allow overriding sh_name fields of the sections.

This is in line with the previous changes which allowed to
override the sh_offset/sh_size and useful for writing test cases.

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

llvm-svn: 370633
This commit is contained in:
George Rimar 2019-09-02 09:47:17 +00:00
parent 5c6b82a756
commit 86cc736df1
4 changed files with 112 additions and 12 deletions

View File

@ -139,14 +139,6 @@ struct Section {
llvm::yaml::Hex64 AddressAlign;
Optional<llvm::yaml::Hex64> EntSize;
// This can be used to override the sh_offset field. It does not place the
// section data at the offset specified. Useful for creating invalid objects.
Optional<llvm::yaml::Hex64> ShOffset;
// This can be used to override the sh_size field. It does not affect the
// content written.
Optional<llvm::yaml::Hex64> ShSize;
// Usually sections are not created implicitly, but loaded from YAML.
// When they are, this flag is used to signal about that.
bool IsImplicit;
@ -154,6 +146,21 @@ struct Section {
Section(SectionKind Kind, bool IsImplicit = false)
: Kind(Kind), IsImplicit(IsImplicit) {}
virtual ~Section();
// The following members are used to override section fields which is
// useful for creating invalid objects.
// This can be used to override the offset stored in the sh_name field.
// It does not affect the name stored in the string table.
Optional<llvm::yaml::Hex64> ShName;
// This can be used to override the sh_offset field. It does not place the
// section data at the offset specified.
Optional<llvm::yaml::Hex64> ShOffset;
// This can be used to override the sh_size field. It does not affect the
// content written.
Optional<llvm::yaml::Hex64> ShSize;
};
struct DynamicSection : Section {

View File

@ -292,8 +292,10 @@ bool ELFState<ELFT>::initImplicitHeader(ELFState<ELFT> &State,
else
return false;
// Override the sh_offset/sh_size fields if requested.
// Override the fields if requested.
if (YAMLSec) {
if (YAMLSec->ShName)
Header.sh_name = *YAMLSec->ShName;
if (YAMLSec->ShOffset)
Header.sh_offset = *YAMLSec->ShOffset;
if (YAMLSec->ShSize)
@ -395,8 +397,10 @@ bool ELFState<ELFT>::initSectionHeaders(ELFState<ELFT> &State,
} else
llvm_unreachable("Unknown section type");
// Override the sh_offset/sh_size fields if requested.
// Override the fields if requested.
if (Sec) {
if (Sec->ShName)
SHeader.sh_name = *Sec->ShName;
if (Sec->ShOffset)
SHeader.sh_offset = *Sec->ShOffset;
if (Sec->ShSize)

View File

@ -986,10 +986,11 @@ static void commonSectionMapping(IO &IO, ELFYAML::Section &Section) {
IO.mapOptional("EntSize", Section.EntSize);
// obj2yaml does not dump these fields. They are expected to be empty when we
// are producing YAML, because yaml2obj sets appropriate values for sh_offset
// and sh_size automatically when they are not explicitly defined.
// are producing YAML, because yaml2obj sets appropriate values for them
// automatically when they are not explicitly defined.
assert(!IO.outputting() ||
(!Section.ShOffset.hasValue() && !Section.ShSize.hasValue()));
IO.mapOptional("ShName", Section.ShName);
IO.mapOptional("ShOffset", Section.ShOffset);
IO.mapOptional("ShSize", Section.ShSize);
}

View File

@ -0,0 +1,88 @@
## Check we are able to set a custom sh_name field for different sections
## and that doing this does not affect the names stored in the string table.
# RUN: yaml2obj %s -o %t1
# RUN: llvm-readobj --sections --section-data %t1 | FileCheck %s
# CHECK: Index: 1
# CHECK-NEXT: Name:{{.* }}(1)
# CHECK: Index: 2
# CHECK-NEXT: Name:{{.* }}(2)
# CHECK: Index: 3
# CHECK-NEXT: Name:{{.* }}(3)
# CHECK: Index: 4
# CHECK-NEXT: Name:{{.* }}(4)
# CHECK: Index: 5
# CHECK-NEXT: Name:{{.* }}(5)
# CHECK: Index: 6
# CHECK-NEXT: Name:{{.* }}(6)
# CHECK: Index: 7
# CHECK-NEXT: Name:{{.* }}(7)
# CHECK: Index: 8
# CHECK-NEXT: Name:{{.* }}(8)
# CHECK: Index: 9
# CHECK-NEXT: Name:{{.* }}(9)
# CHECK: Index: 10
# CHECK-NEXT: Name:{{.* }}(10)
# CHECK: Index: 11
# CHECK-NEXT: Name:{{.* }}(11)
# CHECK: Name: .shstrtab
# CHECK: SectionData (
# CHECK-NEXT: |..nobits..regula|
# CHECK-NEXT: |r..gnu.version_r|
# CHECK-NEXT: |..group..gnu.ver|
# CHECK-NEXT: |sion..dynsym..gn|
# CHECK-NEXT: |u.version_d..dyn|
# CHECK-NEXT: |amic..shstrtab..|
# CHECK-NEXT: |strtab..symtab..|
# CHECK-NEXT: |rela.|
# CHECK-NEXT: )
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_X86_64
Sections:
- Name: .dynsym
Type: SHT_DYNSYM
ShName: 0x000000001
- Name: .symtab
Type: SHT_SYMTAB
ShName: 0x000000002
- Name: .dynamic
Type: SHT_DYNAMIC
ShName: 0x000000003
- Name: .rela
Type: SHT_RELA
ShName: 0x000000004
- Name: .nobits
Type: SHT_NOBITS
ShName: 0x000000005
- Name: .group
Type: SHT_GROUP
Info: 0
ShName: 0x000000006
Members:
- Name: .gnu.version
Type: SHT_GNU_versym
Entries: [ ]
ShName: 0x000000007
- Name: .gnu.version_r
Type: SHT_GNU_verneed
Info: 0x0000000000000001
ShName: 0x000000008
Dependencies:
- Name: .gnu.version_d
Type: SHT_GNU_verdef
Info: 0x0000000000000001
ShName: 0x000000009
Entries:
- Name: .regular
Type: SHT_PROGBITS
ShName: 0x00000000A
- Name: .strtab
Type: SHT_STRTAB
ShName: 0x00000000B