Skip to content

Commit

Permalink
[yaml2obj] - Allow overriding sh_name fields of the sections.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
George Rimar committed Sep 2, 2019
1 parent 5c6b82a commit 86cc736
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 12 deletions.
23 changes: 15 additions & 8 deletions llvm/include/llvm/ObjectYAML/ELFYAML.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,21 +139,28 @@ 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;

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 {
Expand Down
8 changes: 6 additions & 2 deletions llvm/lib/ObjectYAML/ELFEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
5 changes: 3 additions & 2 deletions llvm/lib/ObjectYAML/ELFYAML.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
88 changes: 88 additions & 0 deletions llvm/test/tools/yaml2obj/elf-override-shname.yaml
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 86cc736

Please sign in to comment.