Skip to content

Commit

Permalink
[yaml2obj] - Allow setting cutom Flags for implicit sections.
Browse files Browse the repository at this point in the history
With this patch we get ability to set any flags we want
for implicit sections defined in YAML.

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

llvm-svn: 363367
  • Loading branch information
George Rimar committed Jun 14, 2019
1 parent 822794e commit cfa1a62
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 12 deletions.
2 changes: 1 addition & 1 deletion llvm/include/llvm/ObjectYAML/ELFYAML.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ struct Section {
SectionKind Kind;
StringRef Name;
ELF_SHT Type;
ELF_SHF Flags;
Optional<ELF_SHF> Flags;
llvm::yaml::Hex64 Address;
StringRef Link;
llvm::yaml::Hex64 AddressAlign;
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/ObjectYAML/ELFYAML.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -900,7 +900,7 @@ StringRef MappingTraits<ELFYAML::Symbol>::validate(IO &IO,
static void commonSectionMapping(IO &IO, ELFYAML::Section &Section) {
IO.mapOptional("Name", Section.Name, StringRef());
IO.mapRequired("Type", Section.Type);
IO.mapOptional("Flags", Section.Flags, ELFYAML::ELF_SHF(0));
IO.mapOptional("Flags", Section.Flags);
IO.mapOptional("Address", Section.Address, Hex64(0));
IO.mapOptional("Link", Section.Link, StringRef());
IO.mapOptional("AddressAlign", Section.AddressAlign, Hex64(0));
Expand Down
79 changes: 79 additions & 0 deletions llvm/test/tools/yaml2obj/strtab-implicit-sections-flags.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
## For implicit string table sections, the `Flags` field can also
## be specified in YAML. Here we test the behavior in different cases.

## When flags are not explicitly specified, yaml2obj assigns no flags
## for .strtab and the SHF_ALLOC flag for .dynstr by default.

# RUN: yaml2obj --docnum=1 %s -o %t1
# RUN: llvm-readobj %t1 -S | FileCheck %s --check-prefix=CASE1

# CASE1: Name: .strtab
# CASE1-NEXT: Type: SHT_STRTAB
# CASE1-NEXT: Flags [
# CASE1-NEXT: ]
# CASE1: Name: .dynstr
# CASE1-NEXT: Type: SHT_STRTAB
# CASE1-NEXT: Flags [
# CASE1-NEXT: SHF_ALLOC
# CASE1-NEXT: ]

--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_DYN
Machine: EM_X86_64
Sections:
- Name: .strtab
Type: SHT_STRTAB
- Name: .dynstr
Type: SHT_STRTAB

## Check we can set arbitrary flags for .strtab/.dynstr.

# RUN: yaml2obj --docnum=2 %s -o %t2
# RUN: llvm-readobj %t2 -S | FileCheck %s --check-prefix=CASE2

# CASE2: Name: .strtab
# CASE2-NEXT: Type: SHT_STRTAB
# CASE2-NEXT: Flags [
# CASE2-NEXT: SHF_ALLOC
# CASE2-NEXT: SHF_STRINGS
# CASE2-NEXT: ]
# CASE2: Name: .dynstr
# CASE2-NEXT: Type: SHT_STRTAB
# CASE2-NEXT: Flags [
# CASE2-NEXT: SHF_STRINGS
# CASE2-NEXT: ]

--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_DYN
Machine: EM_X86_64
Sections:
- Name: .strtab
Type: SHT_STRTAB
Flags: [ SHF_ALLOC, SHF_STRINGS ]
- Name: .dynstr
Type: SHT_STRTAB
Flags: [ SHF_STRINGS ]

## Check no flags are set by default for .strtab when it is not
## described in the YAML.

# RUN: yaml2obj --docnum=3 %s -o %t3
# RUN: llvm-readobj %t3 -S | FileCheck %s --check-prefix=CASE3

# CASE3: Name: .strtab
# CASE3-NEXT: Type: SHT_STRTAB
# CASE3-NEXT: Flags [
# CASE3-NEXT: ]

--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_DYN
Machine: EM_X86_64
79 changes: 79 additions & 0 deletions llvm/test/tools/yaml2obj/symtab-implicit-sections-flags.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
## For implicit symbol table sections, the `Flags` field can also
## be specified in YAML. Here we test the behavior in different cases.

## When flags are not explicitly specified, yaml2obj assigns no flags
## for .symtab and the SHF_ALLOC flag for .dynsym by default.

# RUN: yaml2obj --docnum=1 %s -o %t1
# RUN: llvm-readobj %t1 -S | FileCheck %s --check-prefix=CASE1

# CASE1: Name: .symtab
# CASE1-NEXT: Type: SHT_SYMTAB
# CASE1-NEXT: Flags [
# CASE1-NEXT: ]
# CASE1: Name: .dynsym
# CASE1-NEXT: Type: SHT_DYNSYM
# CASE1-NEXT: Flags [
# CASE1-NEXT: SHF_ALLOC
# CASE1-NEXT: ]

--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_DYN
Machine: EM_X86_64
Sections:
- Name: .symtab
Type: SHT_SYMTAB
- Name: .dynsym
Type: SHT_SYMTAB

## Check we can set arbitrary flags for .symtab/.dynsym.

# RUN: yaml2obj --docnum=2 %s -o %t2
# RUN: llvm-readobj %t2 -S | FileCheck %s --check-prefix=CASE2

# CASE2: Name: .symtab
# CASE2-NEXT: Type: SHT_SYMTAB
# CASE2-NEXT: Flags [
# CASE2-NEXT: SHF_ALLOC
# CASE2-NEXT: SHF_STRINGS
# CASE2-NEXT: ]
# CASE2: Name: .dynsym
# CASE2-NEXT: Type: SHT_DYNSYM
# CASE2-NEXT: Flags [
# CASE2-NEXT: SHF_STRINGS
# CASE2-NEXT: ]

--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_DYN
Machine: EM_X86_64
Sections:
- Name: .symtab
Type: SHT_SYMTAB
Flags: [ SHF_ALLOC, SHF_STRINGS ]
- Name: .dynsym
Type: SHT_SYMTAB
Flags: [ SHF_STRINGS ]

## Check no flags are set by default for .symtab when it is not
## described in the YAML.

# RUN: yaml2obj --docnum=3 %s -o %t3
# RUN: llvm-readobj %t3 -S | FileCheck %s --check-prefix=CASE3

# CASE3: Name: .symtab
# CASE3-NEXT: Type: SHT_SYMTAB
# CASE3-NEXT: Flags [
# CASE3-NEXT: ]

--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_DYN
Machine: EM_X86_64
3 changes: 2 additions & 1 deletion llvm/tools/obj2yaml/elf2yaml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,8 @@ template <class ELFT>
std::error_code ELFDumper<ELFT>::dumpCommonSection(const Elf_Shdr *Shdr,
ELFYAML::Section &S) {
S.Type = Shdr->sh_type;
S.Flags = Shdr->sh_flags;
if (Shdr->sh_flags)
S.Flags = static_cast<ELFYAML::ELF_SHF>(Shdr->sh_flags);
S.Address = Shdr->sh_addr;
S.AddressAlign = Shdr->sh_addralign;
if (Shdr->sh_entsize)
Expand Down
23 changes: 14 additions & 9 deletions llvm/tools/yaml2obj/yaml2elf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,8 @@ bool ELFState<ELFT>::initSectionHeaders(ELFState<ELFT> &State,

SHeader.sh_name = DotShStrtab.getOffset(SecName);
SHeader.sh_type = Sec->Type;
SHeader.sh_flags = Sec->Flags;
if (Sec->Flags)
SHeader.sh_flags = *Sec->Flags;
SHeader.sh_addr = Sec->Address;
SHeader.sh_addralign = Sec->AddressAlign;

Expand Down Expand Up @@ -424,8 +425,10 @@ void ELFState<ELFT>::initSymtabSectionHeader(Elf_Shdr &SHeader,
SHeader.sh_link = Link;
}

if (!IsStatic)
SHeader.sh_flags |= ELF::SHF_ALLOC;
if (YAMLSec && YAMLSec->Flags)
SHeader.sh_flags = *YAMLSec->Flags;
else if (!IsStatic)
SHeader.sh_flags = ELF::SHF_ALLOC;

// If the symbol table section is explicitly described in the YAML
// then we should set the fields requested.
Expand Down Expand Up @@ -481,14 +484,16 @@ void ELFState<ELFT>::initStrtabSectionHeader(Elf_Shdr &SHeader, StringRef Name,
if (YAMLSec && YAMLSec->EntSize)
SHeader.sh_entsize = *YAMLSec->EntSize;

if (YAMLSec && YAMLSec->Flags)
SHeader.sh_flags = *YAMLSec->Flags;
else if (Name == ".dynstr")
SHeader.sh_flags = ELF::SHF_ALLOC;

// If .dynstr section is explicitly described in the YAML
// then we want to use its section address.
if (Name == ".dynstr") {
if (YAMLSec)
SHeader.sh_addr = YAMLSec->Address;
// We assume that .dynstr is always allocatable.
SHeader.sh_flags |= ELF::SHF_ALLOC;
}
// TODO: Allow this for any explicitly described section.
if (YAMLSec && Name == ".dynstr")
SHeader.sh_addr = YAMLSec->Address;
}

template <class ELFT>
Expand Down

0 comments on commit cfa1a62

Please sign in to comment.