1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 10:42:39 +01:00

[yaml2obj] - Add a way to override sh_type section field.

This adds the `ShType` key similar to others `Sh*` keys we have.

My use case is the following. Imagine we have a `SHT_SYMTAB_SHNDX`
section and want to hide it from a dumper. The natural way would be to
do something like:

```
  - Name:    .symtab_shndx
    Type:    [[TYPE=SHT_SYMTAB_SHNDX]]
    Entries: [ 0, 1 ]

```

and then change the TYPE from `SHT_SYMTAB_SHNDX` to something else,
for example to `SHT_PROGBITS`.

But we have a problem: regular sections does not have `Entries` key,
so yaml2obj will be unable to produce a section.

The solution is to introduce a `ShType` key to override the final type.

This is not the first time I am facing the need to change the type. I
was able to invent workarounds or solved issues differently in the past,
but finally came to conclusion that we just should support the `ShType`.

Differential revision: https://reviews.llvm.org/D84738
This commit is contained in:
Georgii Rymar 2020-07-28 12:53:06 +03:00
parent 7532dd9434
commit 9db223cc66
4 changed files with 55 additions and 1 deletions

View File

@ -206,6 +206,12 @@ struct Section : public Chunk {
// This can be used to override the sh_flags field.
Optional<llvm::yaml::Hex64> ShFlags;
// This can be used to override the sh_type field. It is useful when we
// want to use specific YAML keys for a section of a particular type to
// describe the content, but still want to have a different final type
// for the section.
Optional<ELF_SHT> ShType;
};
// Fill is a block of data which is placed outside of sections. It is

View File

@ -551,6 +551,8 @@ static void overrideFields(ELFYAML::Section *From, typename ELFT::Shdr &To) {
To.sh_offset = *From->ShOffset;
if (From->ShSize)
To.sh_size = *From->ShSize;
if (From->ShType)
To.sh_type = *From->ShType;
}
template <class ELFT>

View File

@ -1094,11 +1094,13 @@ static void commonSectionMapping(IO &IO, ELFYAML::Section &Section) {
// automatically when they are not explicitly defined.
assert(!IO.outputting() ||
(!Section.ShOffset.hasValue() && !Section.ShSize.hasValue() &&
!Section.ShName.hasValue() && !Section.ShFlags.hasValue()));
!Section.ShName.hasValue() && !Section.ShFlags.hasValue() &&
!Section.ShType.hasValue()));
IO.mapOptional("ShName", Section.ShName);
IO.mapOptional("ShOffset", Section.ShOffset);
IO.mapOptional("ShSize", Section.ShSize);
IO.mapOptional("ShFlags", Section.ShFlags);
IO.mapOptional("ShType", Section.ShType);
}
static void sectionMapping(IO &IO, ELFYAML::DynamicSection &Section) {

View File

@ -0,0 +1,44 @@
## Check we are able to override the sh_type field for different sections.
## When doing this we are still able to use YAML keys that can be normally used
## to describe a section with the original type specified with the Type key.
# RUN: yaml2obj %s -o %t1
# RUN: llvm-readobj --sections --section-data %t1 | FileCheck %s --check-prefixes=COMMON,ORIGINAL
## Check we can use a hex value for the ShType. SHT_PROGBITS == 0x1.
# RUN: yaml2obj -DTYPE=0x1 %s -o %t2
# RUN: llvm-readobj --sections --section-data %t2 | FileCheck %s --check-prefixes=COMMON,OVERRIDE
# COMMON: Name: .gnu.version_r
# ORIGINAL-NEXT: Type: SHT_GNU_verneed
# OVERRIDE-NEXT: Type: SHT_PROGBITS
# COMMON: SectionData (
# COMMON-NEXT: 0000: 01000100 04000000 10000000 00000000 |
# COMMON-NEXT: 0010: 91070000 00000300 01000000 00000000 |
# COMMON-NEXT: )
## Check we can use a string type name for the ShType.
# RUN: yaml2obj -DTYPE=SHT_PROGBITS %s -o %t3
# RUN: cmp %t2 %t3
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_EXEC
Machine: EM_X86_64
Sections:
- Name: .gnu.version_r
Type: SHT_GNU_verneed
Flags: [ SHF_ALLOC ]
ShType: [[TYPE=SHT_GNU_verneed]]
Info: 0
Dependencies:
- Version: 1
File: dso.so.0
Entries:
- Name: v1
Hash: 1937
Flags: 0
Other: 3
DynamicSymbols: []