From: George Rimar Date: Fri, 1 Mar 2019 10:18:16 +0000 (+0000) Subject: [yaml2obj] - Allow setting custom sh_info for RawContentSection sections. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5f896ac2501016fe5339a77df780aa978ed75db6;p=llvm [yaml2obj] - Allow setting custom sh_info for RawContentSection sections. This is for tweaking SHT_SYMTAB sections. Their sh_info contains the (number of symbols + 1) usually. But for creating invalid inputs for test cases it would be convenient to allow explicitly override this field from YAML. Differential revision: https://reviews.llvm.org/D58779 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@355193 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/ObjectYAML/ELFYAML.h b/include/llvm/ObjectYAML/ELFYAML.h index 91c37ece0d8..c7bcfcbb4f4 100644 --- a/include/llvm/ObjectYAML/ELFYAML.h +++ b/include/llvm/ObjectYAML/ELFYAML.h @@ -153,6 +153,7 @@ struct DynamicSection : Section { struct RawContentSection : Section { yaml::BinaryRef Content; llvm::yaml::Hex64 Size; + llvm::yaml::Hex64 Info; RawContentSection() : Section(SectionKind::RawContent) {} diff --git a/lib/ObjectYAML/ELFYAML.cpp b/lib/ObjectYAML/ELFYAML.cpp index 352048b8de8..c374cc2a9e1 100644 --- a/lib/ObjectYAML/ELFYAML.cpp +++ b/lib/ObjectYAML/ELFYAML.cpp @@ -887,6 +887,7 @@ static void sectionMapping(IO &IO, ELFYAML::RawContentSection &Section) { commonSectionMapping(IO, Section); IO.mapOptional("Content", Section.Content); IO.mapOptional("Size", Section.Size, Hex64(Section.Content.binary_size())); + IO.mapOptional("Info", Section.Info, Hex64(0)); } static void sectionMapping(IO &IO, ELFYAML::NoBitsSection &Section) { diff --git a/test/tools/obj2yaml/elf-shinfo.yaml b/test/tools/obj2yaml/elf-shinfo.yaml new file mode 100644 index 00000000000..e77fc62e9d0 --- /dev/null +++ b/test/tools/obj2yaml/elf-shinfo.yaml @@ -0,0 +1,20 @@ +# RUN: yaml2obj %s -o %t +# RUN: obj2yaml %t | FileCheck %s + +## Check obj2yaml is able to dump sh_info field of a section. + +# CHECK: - Name: .test +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Content: '' +# CHECK-NEXT: Info: 0x000000000000002A + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .test + Type: SHT_PROGBITS + Info: 42 diff --git a/test/tools/yaml2obj/elf-symtab-shinfo.yaml b/test/tools/yaml2obj/elf-symtab-shinfo.yaml new file mode 100644 index 00000000000..649e5684f63 --- /dev/null +++ b/test/tools/yaml2obj/elf-symtab-shinfo.yaml @@ -0,0 +1,43 @@ +## Check we are able to set sh_info field for SHT_SYMTAB sections. +# RUN: yaml2obj %s -o %t +# RUN: llvm-readobj -sections %t | FileCheck %s + +# CHECK: Name: .symtab +# CHECK-NEXT: Type: SHT_SYMTAB +# CHECK-NEXT: Flags [ +# CHECK-NEXT: ] +# CHECK-NEXT: Address: +# CHECK-NEXT: Offset: +# CHECK-NEXT: Size: +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: 42 +# CHECK: Name: .dynsym +# CHECK-NEXT: Type: SHT_DYNSYM +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: ] +# CHECK-NEXT: Address: +# CHECK-NEXT: Offset: +# CHECK-NEXT: Size: +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: 26 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .symtab + Info: 42 + Type: SHT_SYMTAB + - Name: .dynsym + Info: 26 + Type: SHT_SYMTAB +Symbols: + Global: + - Name: foo +DynamicSymbols: + Global: + - Name: bar diff --git a/test/tools/yaml2obj/elf-symtab-shtype.yaml b/test/tools/yaml2obj/elf-symtab-shtype.yaml new file mode 100644 index 00000000000..cfa5cf427b7 --- /dev/null +++ b/test/tools/yaml2obj/elf-symtab-shtype.yaml @@ -0,0 +1,21 @@ +## Check we dont crash when .symtab has type different from SHT_SYMTAB. +# RUN: yaml2obj %s -o %t +# RUN: llvm-readobj -sections %t | FileCheck %s + +## TODO: the output is still SHT_SYMTAB because we do not yet +## support changing it. +# CHECK: Name: .symtab +# CHECK-NEXT: Type: SHT_SYMTAB + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .symtab + Type: SHT_DYNAMIC +Symbols: + Global: + - Name: foo diff --git a/tools/obj2yaml/elf2yaml.cpp b/tools/obj2yaml/elf2yaml.cpp index 7f5e9a28d72..4d94b4bea79 100644 --- a/tools/obj2yaml/elf2yaml.cpp +++ b/tools/obj2yaml/elf2yaml.cpp @@ -458,6 +458,7 @@ ELFDumper::dumpContentSection(const Elf_Shdr *Shdr) { return errorToErrorCode(ContentOrErr.takeError()); S->Content = yaml::BinaryRef(ContentOrErr.get()); S->Size = S->Content.binary_size(); + S->Info = Shdr->sh_info; return S.release(); } diff --git a/tools/yaml2obj/yaml2elf.cpp b/tools/yaml2obj/yaml2elf.cpp index d651c92dd65..7b5841b5d3d 100644 --- a/tools/yaml2obj/yaml2elf.cpp +++ b/tools/yaml2obj/yaml2elf.cpp @@ -341,13 +341,16 @@ void ELFState::initSymtabSectionHeader(Elf_Shdr &SHeader, SHeader.sh_entsize = sizeof(Elf_Sym); SHeader.sh_addralign = 8; - // If .dynsym section is explicitly described in the YAML - // then we want to use its section address. - if (!IsStatic) { - // Take section index and ignore the SHT_NULL section. - unsigned SecNdx = getDotDynSymSecNo() - 1; - if (SecNdx < Doc.Sections.size()) - SHeader.sh_addr = Doc.Sections[SecNdx]->Address; + // Get the section index ignoring the SHT_NULL section. + unsigned SecNdx = + IsStatic ? getDotSymTabSecNo() - 1 : getDotDynSymSecNo() - 1; + // If the symbol table section is explicitly described in the YAML + // then we should set the fields requested. + if (SecNdx < Doc.Sections.size()) { + ELFYAML::Section *Sec = Doc.Sections[SecNdx].get(); + SHeader.sh_addr = Sec->Address; + if (auto S = dyn_cast(Sec)) + SHeader.sh_info = S->Info; } std::vector Syms; @@ -503,6 +506,7 @@ ELFState::writeSectionContent(Elf_Shdr &SHeader, else SHeader.sh_entsize = 0; SHeader.sh_size = Section.Size; + SHeader.sh_info = Section.Info; } static bool isMips64EL(const ELFYAML::Object &Doc) {