Index: include/llvm/ObjectYAML/ELFYAML.h =================================================================== --- include/llvm/ObjectYAML/ELFYAML.h +++ include/llvm/ObjectYAML/ELFYAML.h @@ -129,7 +129,7 @@ SectionKind Kind; StringRef Name; ELF_SHT Type; - ELF_SHF Flags; + Optional Flags; llvm::yaml::Hex64 Address; StringRef Link; llvm::yaml::Hex64 AddressAlign; Index: lib/ObjectYAML/ELFYAML.cpp =================================================================== --- lib/ObjectYAML/ELFYAML.cpp +++ lib/ObjectYAML/ELFYAML.cpp @@ -898,7 +898,7 @@ 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)); Index: test/tools/yaml2obj/strtab-implicit-sections-flags.yaml =================================================================== --- /dev/null +++ test/tools/yaml2obj/strtab-implicit-sections-flags.yaml @@ -0,0 +1,62 @@ +## For implicit string table sections, `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 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 and make +## .strtab to be allocatable and .dynstr to be not allocatable. + +# 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 ] Index: test/tools/yaml2obj/symtab-implicit-sections-flags.yaml =================================================================== --- /dev/null +++ test/tools/yaml2obj/symtab-implicit-sections-flags.yaml @@ -0,0 +1,62 @@ +## For implicit symbol table sections, `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 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 and make +## .symtab to be allocatable and .dynsym to be not allocatable. + +# 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 ] Index: tools/obj2yaml/elf2yaml.cpp =================================================================== --- tools/obj2yaml/elf2yaml.cpp +++ tools/obj2yaml/elf2yaml.cpp @@ -329,7 +329,8 @@ std::error_code ELFDumper::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(Shdr->sh_flags); S.Address = Shdr->sh_addr; S.AddressAlign = Shdr->sh_addralign; if (Shdr->sh_entsize) Index: tools/yaml2obj/yaml2elf.cpp =================================================================== --- tools/yaml2obj/yaml2elf.cpp +++ tools/yaml2obj/yaml2elf.cpp @@ -303,7 +303,8 @@ 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; @@ -424,8 +425,10 @@ 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. @@ -481,14 +484,16 @@ 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