Skip to content

Commit

Permalink
[yaml2obj] - Add NBucket and NChain fields for the SHT_HASH section.
Browse files Browse the repository at this point in the history
These fields allows to override nchain and nbucket fields of a SHT_HASH section.

Differential revision: https://reviews.llvm.org/D76834
  • Loading branch information
Georgii Rymar committed Apr 1, 2020
1 parent 0ec88d0 commit 93fc0ba
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 4 deletions.
5 changes: 5 additions & 0 deletions llvm/include/llvm/ObjectYAML/ELFYAML.h
Expand Up @@ -282,6 +282,11 @@ struct HashSection : Section {
Optional<std::vector<uint32_t>> Bucket;
Optional<std::vector<uint32_t>> Chain;

// The following members are used to override section fields.
// This is useful for creating invalid objects.
Optional<llvm::yaml::Hex64> NBucket;
Optional<llvm::yaml::Hex64> NChain;

HashSection() : Section(ChunkKind::Hash) {}

static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Hash; }
Expand Down
11 changes: 7 additions & 4 deletions llvm/lib/ObjectYAML/ELFEmitter.cpp
Expand Up @@ -1065,10 +1065,13 @@ void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
return;
}

support::endian::write<uint32_t>(OS, Section.Bucket->size(),
ELFT::TargetEndianness);
support::endian::write<uint32_t>(OS, Section.Chain->size(),
ELFT::TargetEndianness);
support::endian::write<uint32_t>(
OS, Section.NBucket.getValueOr(llvm::yaml::Hex64(Section.Bucket->size())),
ELFT::TargetEndianness);
support::endian::write<uint32_t>(
OS, Section.NChain.getValueOr(llvm::yaml::Hex64(Section.Chain->size())),
ELFT::TargetEndianness);

for (uint32_t Val : *Section.Bucket)
support::endian::write<uint32_t>(OS, Val, ELFT::TargetEndianness);
for (uint32_t Val : *Section.Chain)
Expand Down
7 changes: 7 additions & 0 deletions llvm/lib/ObjectYAML/ELFYAML.cpp
Expand Up @@ -1091,6 +1091,13 @@ static void sectionMapping(IO &IO, ELFYAML::HashSection &Section) {
IO.mapOptional("Bucket", Section.Bucket);
IO.mapOptional("Chain", Section.Chain);
IO.mapOptional("Size", Section.Size);

// obj2yaml does not dump these fields. They can be used to override nchain
// and nbucket values for creating broken sections.
assert(!IO.outputting() ||
(!Section.NBucket.hasValue() && !Section.NChain.hasValue()));
IO.mapOptional("NChain", Section.NChain);
IO.mapOptional("NBucket", Section.NBucket);
}

static void sectionMapping(IO &IO, ELFYAML::NoteSection &Section) {
Expand Down
36 changes: 36 additions & 0 deletions llvm/test/tools/yaml2obj/ELF/hash-section.yaml
Expand Up @@ -276,3 +276,39 @@ Sections:
Type: SHT_HASH
Size: 0x1
Chain: [ 1 ]

## Check we can override "nbucket" and "nchain" values of a SHT_HASH section using "NBucket"
## and "NChain" tags. Check that the section size is unaffected when we do this.

# RUN: yaml2obj --docnum=14 %s -o %t14
# RUN: llvm-readobj --sections --section-data %t14 | FileCheck %s --check-prefix=OVERRIDE

# OVERRIDE: Name: .hash
# OVERRIDE-NEXT: Type: SHT_HASH
# OVERRIDE-NEXT: Flags [
# OVERRIDE-NEXT: ]
# OVERRIDE-NEXT: Address: 0x0
# OVERRIDE-NEXT: Offset: 0x34
# OVERRIDE-NEXT: Size: 28
# OVERRIDE-NEXT: Link: 0
# OVERRIDE-NEXT: Info: 0
# OVERRIDE-NEXT: AddressAlignment: 0
# OVERRIDE-NEXT: EntrySize: 0
# OVERRIDE-NEXT: SectionData (
# OVERRIDE-NEXT: 0000: AA000000 BB000000 01000000 02000000
# OVERRIDE-NEXT: 0010: 03000000 04000000 05000000
# OVERRIDE-NEXT: )

--- !ELF
FileHeader:
Class: ELFCLASS32
Data: ELFDATA2LSB
Type: ET_DYN
Machine: EM_386
Sections:
- Name: .hash
Type: SHT_HASH
Bucket: [ 1, 2 ]
Chain: [ 3, 4, 5 ]
NBucket: 0xAA
NChain: 0xBB

0 comments on commit 93fc0ba

Please sign in to comment.