diff --git a/include/llvm/ObjectYAML/ELFYAML.h b/include/llvm/ObjectYAML/ELFYAML.h index 9fc86441f1a..38e19d28faf 100644 --- a/include/llvm/ObjectYAML/ELFYAML.h +++ b/include/llvm/ObjectYAML/ELFYAML.h @@ -153,7 +153,7 @@ struct DynamicSection : Section { struct RawContentSection : Section { Optional Content; Optional Size; - llvm::yaml::Hex64 Info; + Optional Info; RawContentSection() : Section(SectionKind::RawContent) {} diff --git a/lib/ObjectYAML/ELFYAML.cpp b/lib/ObjectYAML/ELFYAML.cpp index e0b52d1fc33..ac3e3e577ea 100644 --- a/lib/ObjectYAML/ELFYAML.cpp +++ b/lib/ObjectYAML/ELFYAML.cpp @@ -917,7 +917,7 @@ static void sectionMapping(IO &IO, ELFYAML::RawContentSection &Section) { commonSectionMapping(IO, Section); IO.mapOptional("Content", Section.Content); IO.mapOptional("Size", Section.Size); - IO.mapOptional("Info", Section.Info, Hex64(0)); + IO.mapOptional("Info", Section.Info); } static void sectionMapping(IO &IO, ELFYAML::NoBitsSection &Section) { diff --git a/test/tools/obj2yaml/sections-info.yaml b/test/tools/obj2yaml/sections-info.yaml new file mode 100644 index 00000000000..f7ec4f625b9 --- /dev/null +++ b/test/tools/obj2yaml/sections-info.yaml @@ -0,0 +1,25 @@ +## Check that obj2yaml does not write a section Info +## field in the case when it has a value of zero. + +# RUN: yaml2obj %s -o %t +# RUN: obj2yaml %t | FileCheck %s + +# CHECK: Sections: +# CHECK-NEXT: - Name: .foo +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: - Name: .bar +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Info: 0x0000000000000001 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .foo + Type: SHT_PROGBITS + - Name: .bar + Type: SHT_PROGBITS + Info: 1 diff --git a/test/tools/yaml2obj/dynsymtab-implicit-sections-size-content.yaml b/test/tools/yaml2obj/dynsymtab-implicit-sections-size-content.yaml index 479e5513d02..c8e583f5033 100644 --- a/test/tools/yaml2obj/dynsymtab-implicit-sections-size-content.yaml +++ b/test/tools/yaml2obj/dynsymtab-implicit-sections-size-content.yaml @@ -78,7 +78,7 @@ DynamicSymbols: # CASE4-NEXT: Offset: 0x180 # CASE4-NEXT: Size: 2 # CASE4-NEXT: Link: 0 -# CASE4-NEXT: Info: 0 +# CASE4-NEXT: Info: 1 # CASE4-NEXT: AddressAlignment: 0 # CASE4-NEXT: EntrySize: 24 # CASE4-NEXT: SectionData ( @@ -110,7 +110,7 @@ Sections: # CASE5-NEXT: Offset: 0x180 # CASE5-NEXT: Size: 5 # CASE5-NEXT: Link: 0 -# CASE5-NEXT: Info: 0 +# CASE5-NEXT: Info: 1 # CASE5-NEXT: AddressAlignment: 0 # CASE5-NEXT: EntrySize: 24 # CASE5-NEXT: SectionData ( @@ -144,7 +144,7 @@ Sections: # CASE6-NEXT: Offset: 0x180 # CASE6-NEXT: Size: 4 # CASE6-NEXT: Link: 0 -# CASE6-NEXT: Info: 0 +# CASE6-NEXT: Info: 1 # CASE6-NEXT: AddressAlignment: 0 # CASE6-NEXT: EntrySize: 24 # CASE6-NEXT: SectionData ( @@ -178,7 +178,7 @@ Sections: # CASE7-NEXT: Offset: 0x180 # CASE7-NEXT: Size: 2 # CASE7-NEXT: Link: 0 -# CASE7-NEXT: Info: 0 +# CASE7-NEXT: Info: 1 # CASE7-NEXT: AddressAlignment: 0 # CASE7-NEXT: EntrySize: 24 # CASE7-NEXT: SectionData ( diff --git a/test/tools/yaml2obj/implicit-sections-info.yaml b/test/tools/yaml2obj/implicit-sections-info.yaml new file mode 100644 index 00000000000..d7d530d3960 --- /dev/null +++ b/test/tools/yaml2obj/implicit-sections-info.yaml @@ -0,0 +1,113 @@ +## Check the values of sh_info fields set by default for +## explicitly listed .dynstr, .dynsym, .strtab and .symtab +## sections. +## +## For symbol table sections, sh_info has a value which is +## one greater than the symbol table index of the last +## local symbol. +## +## sh_info isn't set for string table sections. + +# RUN: yaml2obj --docnum=1 %s -o %t +# RUN: llvm-readobj --sections %t | FileCheck %s --check-prefix=CASE1 + +# CASE1: Name: .symtab +# CASE1: Info: +# CASE1-SAME: 2 +# CASE1: Name: .strtab +# CASE1: Info: +# CASE1-SAME: 0 +# CASE1: Name: .dynsym +# CASE1: Info: +# CASE1-SAME: 1 +# CASE1: Name: .dynstr +# CASE1: Info: +# CASE1-SAME: 0 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .symtab + Type: SHT_SYMTAB + - Name: .strtab + Type: SHT_STRTAB + - Name: .dynsym + Type: SHT_DYNSYM + - Name: .dynstr + Type: SHT_STRTAB +Symbols: + - Name: local + - Name: global1 + Binding: STB_GLOBAL +DynamicSymbols: + - Name: global2 + Binding: STB_GLOBAL + +## In the case when these sections are not defined in YAML, the +## behavior is the same as when we define them, but do not set the Info. + +# RUN: yaml2obj --docnum=2 %s -o %t +# RUN: llvm-readobj --sections %t | FileCheck %s --check-prefix=CASE1 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Symbols: + - Name: local + - Name: global1 + Binding: STB_GLOBAL +DynamicSymbols: + - Name: global2 + Binding: STB_GLOBAL + +## Check we are able to set any sh_info explicitly. + +# RUN: yaml2obj --docnum=3 %s -o %t +# RUN: llvm-readobj --sections %t | FileCheck %s --check-prefix=CASE2 + +# CASE2: Name: .dynstr +# CASE2: Info: +# CASE2-SAME: 10 +# CASE2: Name: .dynsym +# CASE2: Info: +# CASE2-SAME: 11 +# CASE2: Name: .strtab +# CASE2: Info: +# CASE2-SAME: 12 +# CASE2: Name: .symtab +# CASE2: Info: +# CASE2-SAME: 13 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .dynstr + Type: SHT_STRTAB + Info: 10 + - Name: .dynsym + Type: SHT_DYNSYM + Info: 11 + - Name: .strtab + Type: SHT_STRTAB + Info: 12 + - Name: .symtab + Type: SHT_SYMTAB + Info: 13 +Symbols: + - Name: local + - Name: global1 + Binding: STB_GLOBAL +DynamicSymbols: + - Name: global2 + Binding: STB_GLOBAL diff --git a/test/tools/yaml2obj/symtab-implicit-sections-size-content.yaml b/test/tools/yaml2obj/symtab-implicit-sections-size-content.yaml index 3dd9640c43d..4981dbd61ef 100644 --- a/test/tools/yaml2obj/symtab-implicit-sections-size-content.yaml +++ b/test/tools/yaml2obj/symtab-implicit-sections-size-content.yaml @@ -73,7 +73,7 @@ Symbols: # CASE4-NEXT: Offset: 0x140 # CASE4-NEXT: Size: 2 # CASE4-NEXT: Link: 2 -# CASE4-NEXT: Info: 0 +# CASE4-NEXT: Info: 1 # CASE4-NEXT: AddressAlignment: 0 # CASE4-NEXT: EntrySize: 24 # CASE4-NEXT: SectionData ( @@ -104,7 +104,7 @@ Sections: # CASE5-NEXT: Offset: 0x140 # CASE5-NEXT: Size: 5 # CASE5-NEXT: Link: 2 -# CASE5-NEXT: Info: 0 +# CASE5-NEXT: Info: 1 # CASE5-NEXT: AddressAlignment: 0 # CASE5-NEXT: EntrySize: 24 # CASE5-NEXT: SectionData ( @@ -137,7 +137,7 @@ Sections: # CASE6-NEXT: Offset: 0x140 # CASE6-NEXT: Size: 4 # CASE6-NEXT: Link: 2 -# CASE6-NEXT: Info: 0 +# CASE6-NEXT: Info: 1 # CASE6-NEXT: AddressAlignment: 0 # CASE6-NEXT: EntrySize: 24 # CASE6-NEXT: SectionData ( @@ -170,7 +170,7 @@ Sections: # CASE7-NEXT: Offset: 0x140 # CASE7-NEXT: Size: 2 # CASE7-NEXT: Link: 2 -# CASE7-NEXT: Info: 0 +# CASE7-NEXT: Info: 1 # CASE7-NEXT: AddressAlignment: 0 # CASE7-NEXT: EntrySize: 24 # CASE7-NEXT: SectionData ( diff --git a/tools/obj2yaml/elf2yaml.cpp b/tools/obj2yaml/elf2yaml.cpp index e84cc2f6b5e..a9ea774c452 100644 --- a/tools/obj2yaml/elf2yaml.cpp +++ b/tools/obj2yaml/elf2yaml.cpp @@ -442,7 +442,8 @@ ELFDumper::dumpContentSection(const Elf_Shdr *Shdr) { ArrayRef Content = *ContentOrErr; if (!Content.empty()) S->Content = yaml::BinaryRef(Content); - S->Info = Shdr->sh_info; + if (Shdr->sh_info) + S->Info = static_cast(Shdr->sh_info); return S.release(); } diff --git a/tools/yaml2obj/yaml2elf.cpp b/tools/yaml2obj/yaml2elf.cpp index 8e4ea786c85..6bba732f9fe 100644 --- a/tools/yaml2obj/yaml2elf.cpp +++ b/tools/yaml2obj/yaml2elf.cpp @@ -436,8 +436,8 @@ void ELFState::initSymtabSectionHeader(Elf_Shdr &SHeader, // If the symbol table section is explicitly described in the YAML // then we should set the fields requested. - SHeader.sh_info = - RawSec ? (unsigned)RawSec->Info : findFirstNonGlobal(Symbols) + 1; + SHeader.sh_info = (RawSec && RawSec->Info) ? (unsigned)(*RawSec->Info) + : findFirstNonGlobal(Symbols) + 1; SHeader.sh_entsize = (YAMLSec && YAMLSec->EntSize) ? (uint64_t)(*YAMLSec->EntSize) : sizeof(Elf_Sym); @@ -488,6 +488,9 @@ void ELFState::initStrtabSectionHeader(Elf_Shdr &SHeader, StringRef Name, if (YAMLSec && YAMLSec->EntSize) SHeader.sh_entsize = *YAMLSec->EntSize; + if (RawSec && RawSec->Info) + SHeader.sh_info = *RawSec->Info; + if (YAMLSec && YAMLSec->Flags) SHeader.sh_flags = *YAMLSec->Flags; else if (Name == ".dynstr") @@ -624,7 +627,10 @@ bool ELFState::writeSectionContent( SHeader.sh_entsize = sizeof(Elf_Relr); else SHeader.sh_entsize = 0; - SHeader.sh_info = Section.Info; + + if (Section.Info) + SHeader.sh_info = *Section.Info; + return true; }