From d3963051c49037b1ce6edace90f59056d3bddffa Mon Sep 17 00:00:00 2001 From: George Rimar Date: Thu, 8 Aug 2019 09:49:05 +0000 Subject: [PATCH] [yaml2obj/obj2yaml] - Add a basic support for extended section indexes. In some cases a symbol might have section index == SHN_XINDEX. This is an escape value indicating that the actual section header index is too large to fit in the containing field. Then the SHT_SYMTAB_SHNDX section is used. It contains the 32bit values that stores section indexes. ELF gABI says that there can be multiple SHT_SYMTAB_SHNDX sections, i.e. for example one for .symtab and one for .dynsym (1) https://groups.google.com/forum/#!topic/generic-abi/-XJAV5d8PRg (2) DT_SYMTAB_SHNDX: http://www.sco.com/developers/gabi/latest/ch5.dynamic.html In this patch I am only supporting a single SHT_SYMTAB_SHNDX associated with a .symtab. This is a more or less common case which is used a few tests I saw in LLVM. I decided not to create the SHT_SYMTAB_SHNDX section as "implicit", but implement is like a kind of regular section for now. i.e. tools do not recreate this section or its content, like they do for symbol table sections, for example. That should allow to write all kind of possible broken test cases for our needs and keep the output closer to requested. Differential revision: https://reviews.llvm.org/D65446 llvm-svn: 368272 --- llvm/include/llvm/Object/ELF.h | 7 +- llvm/include/llvm/ObjectYAML/ELFYAML.h | 11 ++ llvm/lib/ObjectYAML/ELFEmitter.cpp | 21 +++ llvm/lib/ObjectYAML/ELFYAML.cpp | 14 +- llvm/test/Object/invalid.test | 5 +- .../test/tools/llvm-readobj/elf-section-types.test | 3 +- llvm/test/tools/obj2yaml/Inputs/shn_xindex.o | Bin 403 -> 0 bytes llvm/test/tools/obj2yaml/elf-sht-symtab-shndx.yaml | 189 +++++++++++++++++++++ .../tools/obj2yaml/special-symbol-indices.yaml | 7 +- llvm/test/tools/yaml2obj/elf-sht-symtab-shndx.yaml | 129 ++++++++++++++ llvm/tools/obj2yaml/elf2yaml.cpp | 71 ++++++-- 11 files changed, 428 insertions(+), 29 deletions(-) delete mode 100644 llvm/test/tools/obj2yaml/Inputs/shn_xindex.o create mode 100644 llvm/test/tools/obj2yaml/elf-sht-symtab-shndx.yaml create mode 100644 llvm/test/tools/yaml2obj/elf-sht-symtab-shndx.yaml diff --git a/llvm/include/llvm/Object/ELF.h b/llvm/include/llvm/Object/ELF.h index a9a78e9..5b7ad18 100644 --- a/llvm/include/llvm/Object/ELF.h +++ b/llvm/include/llvm/Object/ELF.h @@ -635,8 +635,11 @@ ELFFile::getSHNDXTable(const Elf_Shdr &Section, const Elf_Shdr &SymTable = **SymTableOrErr; if (SymTable.sh_type != ELF::SHT_SYMTAB && SymTable.sh_type != ELF::SHT_DYNSYM) - // TODO: this error is untested. - return createError("invalid sh_type"); + return createError("SHT_SYMTAB_SHNDX section is linked with " + + object::getELFSectionTypeName(getHeader()->e_machine, + SymTable.sh_type) + + " section (expected SHT_SYMTAB/SHT_DYNSYM)"); + if (V.size() != (SymTable.sh_size / sizeof(Elf_Sym))) return createError("SHT_SYMTAB_SHNDX section has sh_size (" + Twine(SymTable.sh_size) + diff --git a/llvm/include/llvm/ObjectYAML/ELFYAML.h b/llvm/include/llvm/ObjectYAML/ELFYAML.h index 89c0c58..a282f32 100644 --- a/llvm/include/llvm/ObjectYAML/ELFYAML.h +++ b/llvm/include/llvm/ObjectYAML/ELFYAML.h @@ -128,6 +128,7 @@ struct Section { NoBits, Verdef, Verneed, + SymtabShndxSection, Symver, MipsABIFlags }; @@ -274,6 +275,16 @@ struct RelocationSection : Section { } }; +struct SymtabShndxSection : Section { + std::vector Entries; + + SymtabShndxSection() : Section(SectionKind::SymtabShndxSection) {} + + static bool classof(const Section *S) { + return S->Kind == SectionKind::SymtabShndxSection; + } +}; + // Represents .MIPS.abiflags section struct MipsABIFlags : Section { llvm::yaml::Hex16 Version; diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp index 370d620..d2ceb40 100644 --- a/llvm/lib/ObjectYAML/ELFEmitter.cpp +++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp @@ -141,6 +141,9 @@ template class ELFState { bool writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::Group &Group, ContiguousBlobAccumulator &CBA); bool writeSectionContent(Elf_Shdr &SHeader, + const ELFYAML::SymtabShndxSection &Shndx, + ContiguousBlobAccumulator &CBA); + bool writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::SymverSection &Section, ContiguousBlobAccumulator &CBA); bool writeSectionContent(Elf_Shdr &SHeader, @@ -358,6 +361,9 @@ bool ELFState::initSectionHeaders(ELFState &State, } else if (auto S = dyn_cast(Sec)) { if (!writeSectionContent(SHeader, *S, CBA)) return false; + } else if (auto S = dyn_cast(Sec)) { + if (!writeSectionContent(SHeader, *S, CBA)) + return false; } else if (auto S = dyn_cast(Sec)) { if (!writeSectionContent(SHeader, *S, CBA)) return false; @@ -741,6 +747,21 @@ bool ELFState::writeSectionContent( } template +bool ELFState::writeSectionContent( + Elf_Shdr &SHeader, const ELFYAML::SymtabShndxSection &Shndx, + ContiguousBlobAccumulator &CBA) { + raw_ostream &OS = + CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); + + for (uint32_t E : Shndx.Entries) + support::endian::write(OS, E, ELFT::TargetEndianness); + + SHeader.sh_entsize = Shndx.EntSize ? (uint64_t)*Shndx.EntSize : 4; + SHeader.sh_size = Shndx.Entries.size() * SHeader.sh_entsize; + return true; +} + +template bool ELFState::writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::Group &Section, ContiguousBlobAccumulator &CBA) { diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp index 7497154..be19111 100644 --- a/llvm/lib/ObjectYAML/ELFYAML.cpp +++ b/llvm/lib/ObjectYAML/ELFYAML.cpp @@ -563,7 +563,7 @@ void ScalarEnumerationTraits::enumeration( ECase(SHN_HEXAGON_SCOMMON_4); ECase(SHN_HEXAGON_SCOMMON_8); #undef ECase - IO.enumFallback(Value); + IO.enumFallback(Value); } void ScalarEnumerationTraits::enumeration( @@ -897,8 +897,6 @@ StringRef MappingTraits::validate(IO &IO, ELFYAML::Symbol &Symbol) { if (Symbol.Index && Symbol.Section.data()) return "Index and Section cannot both be specified for Symbol"; - if (Symbol.Index && *Symbol.Index == ELFYAML::ELF_SHN(ELF::SHN_XINDEX)) - return "Large indexes are not supported"; if (Symbol.NameIndex && !Symbol.Name.empty()) return "Name and NameIndex cannot both be specified for Symbol"; return StringRef(); @@ -969,6 +967,11 @@ static void groupSectionMapping(IO &IO, ELFYAML::Group &Group) { IO.mapRequired("Members", Group.Members); } +static void sectionMapping(IO &IO, ELFYAML::SymtabShndxSection &Section) { + commonSectionMapping(IO, Section); + IO.mapRequired("Entries", Section.Entries); +} + void MappingTraits::mapping( IO &IO, ELFYAML::SectionOrType §ionOrType) { IO.mapRequired("SectionOrType", sectionOrType.sectionNameOrType); @@ -1049,6 +1052,11 @@ void MappingTraits>::mapping( Section.reset(new ELFYAML::VerneedSection()); sectionMapping(IO, *cast(Section.get())); break; + case ELF::SHT_SYMTAB_SHNDX: + if (!IO.outputting()) + Section.reset(new ELFYAML::SymtabShndxSection()); + sectionMapping(IO, *cast(Section.get())); + break; default: if (!IO.outputting()) Section.reset(new ELFYAML::RawContentSection()); diff --git a/llvm/test/Object/invalid.test b/llvm/test/Object/invalid.test index 05f38e9..7566ab2 100644 --- a/llvm/test/Object/invalid.test +++ b/llvm/test/Object/invalid.test @@ -207,7 +207,7 @@ Sections: # RUN: yaml2obj %s --docnum=11 -o %t11 # RUN: not llvm-readobj --symbols %t11 2>&1 | FileCheck --check-prefix=INVALID-XINDEX-SIZE %s -# INVALID-XINDEX-SIZE: error: {{.*}}: SHT_SYMTAB_SHNDX section has sh_size (24) which is not equal to the number of symbols (6) +# INVALID-XINDEX-SIZE: error: {{.*}}: SHT_SYMTAB_SHNDX section has sh_size (24) which is not equal to the number of symbols (2) --- !ELF FileHeader: @@ -218,8 +218,7 @@ FileHeader: Sections: - Name: .symtab_shndx Type: SHT_SYMTAB_SHNDX - Size: 0x18 - EntSize: 4 + Entries: [ 0, 1 ] Link: .symtab ## Check that llvm-readobj reports an error if the e_phentsize field is broken. diff --git a/llvm/test/tools/llvm-readobj/elf-section-types.test b/llvm/test/tools/llvm-readobj/elf-section-types.test index f65655a..9b3e350 100644 --- a/llvm/test/tools/llvm-readobj/elf-section-types.test +++ b/llvm/test/tools/llvm-readobj/elf-section-types.test @@ -166,8 +166,7 @@ Sections: - Name: symtab_shndx Type: SHT_SYMTAB_SHNDX Link: .symtab - EntSize: 0x4 - Content: "0000000000000000" + Entries: [ 0, 1 ] - Name: relr Type: SHT_RELR - Name: android_rel diff --git a/llvm/test/tools/obj2yaml/Inputs/shn_xindex.o b/llvm/test/tools/obj2yaml/Inputs/shn_xindex.o deleted file mode 100644 index 73e2b60ba1e24c4909d30ecf81ba3b8741cd2e5b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 403 zcmb<-^>JfjWMqH=CI&kO1doBi0V)BbL0kt03oyyTzzpJ21cZUQnXs7P0Cj``R1TyD zB*X#bOF(IEAdSrx1yKDk^-$#~eglbtlws3f0o5-J(+H)Z!f2wHT#z~ehX4ODWGXWA aQc^1z81#xWic5-05|e-|7+skQ;sXH55fWJd diff --git a/llvm/test/tools/obj2yaml/elf-sht-symtab-shndx.yaml b/llvm/test/tools/obj2yaml/elf-sht-symtab-shndx.yaml new file mode 100644 index 0000000..e926019 --- /dev/null +++ b/llvm/test/tools/obj2yaml/elf-sht-symtab-shndx.yaml @@ -0,0 +1,189 @@ +## Check that obj2yaml is able to dump a normal object which +## contains the SHT_SYMTAB_SHNDX section and symbols with +## section index == SHN_XINDEX. + +# RUN: yaml2obj --docnum=1 %s -o %t1 +# RUN: obj2yaml %t1 | FileCheck %s --check-prefix=CASE1 + +# CASE1: --- !ELF +# CASE1-NEXT: FileHeader: +# CASE1-NEXT: Class: ELFCLASS64 +# CASE1-NEXT: Data: ELFDATA2LSB +# CASE1-NEXT: Type: ET_REL +# CASE1-NEXT: Machine: EM_X86_64 +# CASE1-NEXT: Sections: +# CASE1-NEXT: - Name: bar +# CASE1-NEXT: Type: SHT_PROGBITS +# CASE1-NEXT: - Name: .symtab_shndx +# CASE1-NEXT: Type: SHT_SYMTAB_SHNDX +# CASE1-NEXT: Link: .symtab +# CASE1-NEXT: EntSize: 0x0000000000000004 +# CASE1-NEXT: Entries: [ 0, 1, 2 ] +# CASE1-NEXT: Symbols: +# CASE1-NEXT: - Name: bar +# CASE1-NEXT: Type: STT_SECTION +# CASE1-NEXT: Index: SHN_XINDEX +# CASE1-NEXT: - Name: .symtab_shndx +# CASE1-NEXT: Type: STT_SECTION +# CASE1-NEXT: Index: SHN_XINDEX +# CASE1-NEXT: ... + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: bar + Type: SHT_PROGBITS + - Name: .symtab_shndx + Type: SHT_SYMTAB_SHNDX + Entries: [ 0, 1, 2 ] + Link: .symtab +Symbols: + - Type: STT_SECTION + Index: SHN_XINDEX + - Type: STT_SECTION + Index: SHN_XINDEX + +## Check that yaml2obj is unable to dump an object, which has +## symbols with section index == SHN_XINDEX, but no SHT_SYMTAB_SHNDX section. + +# RUN: yaml2obj --docnum=2 %s -o %t2 +# RUN: not obj2yaml %t2 2>&1 | FileCheck %s -DFILE=%t2 --check-prefix=CASE2 + +# CASE2: Error reading file: [[FILE]]: extended symbol index (1) is past the end of the SHT_SYMTAB_SHNDX section of size 0 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Symbols: + - Type: STT_SECTION + Index: SHN_XINDEX + +## Check that yaml2obj is unable to dump an object, which has symbols with +## section index == SHN_XINDEX, but SHT_SYMTAB_SHNDX table contains invalid indices +## that are larger than total number of the sections. + +# RUN: yaml2obj --docnum=3 %s -o %t3 +# RUN: not obj2yaml %t3 2>&1 | FileCheck %s -DFILE=%t3 --check-prefix=CASE3 + +# CASE3: Error reading file: [[FILE]]: invalid section index: 254 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: bar + Type: SHT_PROGBITS + - Name: .symtab_shndx + Type: SHT_SYMTAB_SHNDX + Entries: [ 0, 254 ] + Link: .symtab +Symbols: + - Type: STT_SECTION + Index: SHN_XINDEX + +## Check that yaml2obj is unable to dump an object, which has symbols with +## section index == SHN_XINDEX, but SHT_SYMTAB_SHNDX table contains more +## entries than the number of symbols in .symtab. + +# RUN: yaml2obj --docnum=4 %s -o %t4 +# RUN: not obj2yaml %t4 2>&1 | FileCheck %s -DFILE=%t4 --check-prefix=CASE4 + +## FIXME: The error message below needs rewording. Size should not be equal to the number of symbols. +## CASE4: Error reading file: [[FILE]]: SHT_SYMTAB_SHNDX section has sh_size (48) which is not equal to the number of symbols (3) + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: bar + Type: SHT_PROGBITS + - Name: .symtab_shndx + Type: SHT_SYMTAB_SHNDX + Entries: [ 0, 1, 2 ] + Link: .symtab +Symbols: + - Type: STT_SECTION + Index: SHN_XINDEX + +## ELF gABI allows having multiple SHT_SYMTAB_SHNDX sections. +## We only support having one associated with .symtab now. + +# RUN: yaml2obj --docnum=5 %s -o %t5 +# RUN: not obj2yaml %t5 2>&1 | FileCheck %s -DFILE=%t5 --check-prefix=CASE5 + +# CASE5: Error reading file: [[FILE]]: multiple SHT_SYMTAB_SHNDX sections are not supported + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .symtab_shndx1 + Type: SHT_SYMTAB_SHNDX + Entries: [ 0 ] + EntSize: 4 + Link: .symtab + - Name: .symtab_shndx2 + Type: SHT_SYMTAB_SHNDX + Entries: [ 0 ] + Link: .symtab + +## Check that yaml2obj can't dump the object if SHT_SYMTAB_SHNDX is +## not associated with a SHT_SYMTAB section (this case is illegal). + +# RUN: yaml2obj --docnum=6 %s -o %t6 +# RUN: not obj2yaml %t6 2>&1 | FileCheck %s -DFILE=%t6 --check-prefix=CASE6 + +# CASE6: Error reading file: [[FILE]]: SHT_SYMTAB_SHNDX section is linked with SHT_PROGBITS section (expected SHT_SYMTAB/SHT_DYNSYM) + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .symtab_shndx + Type: SHT_SYMTAB_SHNDX + Entries: [ 0 ] + Link: .foo + - Name: .foo + Type: SHT_PROGBITS + +## Check that yaml2obj can't dump the object if SHT_SYMTAB_SHNDX is +## associated with a SHT_DYNSYM section (not implemented yet). + +# RUN: yaml2obj --docnum=7 %s -o %t7 +# RUN: not obj2yaml %t7 2>&1 | FileCheck %s -DFILE=%t7 --check-prefix=CASE7 + +# CASE7: Error reading file: [[FILE]]: only SHT_SYMTAB_SHNDX associated with SHT_SYMTAB are supported + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .symtab_shndx + Type: SHT_SYMTAB_SHNDX + Entries: [ 0, 1 ] + Link: .dynsym +DynamicSymbols: + - Type: STT_SECTION + Index: SHN_XINDEX diff --git a/llvm/test/tools/obj2yaml/special-symbol-indices.yaml b/llvm/test/tools/obj2yaml/special-symbol-indices.yaml index fcc2a70..9ba4241 100644 --- a/llvm/test/tools/obj2yaml/special-symbol-indices.yaml +++ b/llvm/test/tools/obj2yaml/special-symbol-indices.yaml @@ -18,7 +18,7 @@ # CHECK-NEXT: Index: SHN_HEXAGON_SCOMMON_1 # CHECK-NEXT: Binding: STB_GLOBAL # CHECK-NEXT: - Name: unknown_index -# CHECK-NEXT: Index: 0x0000FFFE +# CHECK-NEXT: Index: 0xFFFE # CHECK-NEXT: Binding: STB_GLOBAL !ELF @@ -47,8 +47,3 @@ Symbols: - Name: unknown_index Index: 0xfffe Binding: STB_GLOBAL - -## shn_xindex.o contains a symbol with st_shndx == SHN_XINDEX. -## We do not support it at this moment. -# RUN: not obj2yaml %S/Inputs/shn_xindex.o 2>&1 | FileCheck %s --check-prefix=ERR -# ERR: Error reading file: {{.*}}shn_xindex.o: SHN_XINDEX symbols are not supported diff --git a/llvm/test/tools/yaml2obj/elf-sht-symtab-shndx.yaml b/llvm/test/tools/yaml2obj/elf-sht-symtab-shndx.yaml new file mode 100644 index 0000000..c8d86b1 --- /dev/null +++ b/llvm/test/tools/yaml2obj/elf-sht-symtab-shndx.yaml @@ -0,0 +1,129 @@ +## Check that yaml2obj is able to produce output +## when a symbol with section index SHN_XINDEX is used, +## but no SHT_SYMTAB_SHNDX section is defined. + +# RUN: yaml2obj --docnum=1 %s -o %t1 +# RUN: not llvm-readobj --symbols 2>&1 %t1 | FileCheck %s --check-prefix=CASE1 + +# CASE1: error: extended symbol index (1) is past the end of the SHT_SYMTAB_SHNDX section of size 0 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: bar + Type: SHT_PROGBITS +Symbols: + - Type: STT_SECTION + Index: SHN_XINDEX + +## Check that yaml2obj keeps the SHT_SYMTAB_SHNDX section in the output +## even when symbol's section index value is low enough to not require the extended symtab. +## Also, check that symbols in .symtab still have the SHN_XINDEX index. + +# RUN: yaml2obj --docnum=2 %s -o %t2 +# RUN: llvm-readobj --sections --symbols --section-data 2>&1 %t2 | FileCheck %s --check-prefix=CASE2 + +# CASE2: Section { +# CASE2: Name: .symtab_shndx (1) +# CASE2-NEXT: Type: SHT_SYMTAB_SHNDX (0x12) + +# CASE2: Name: .symtab +# CASE2: SectionData ( +# CASE2-NEXT: 0000: 00000000 00000000 00000000 00000000 +# CASE2-NEXT: 0010: 00000000 00000000 00000000 0300FFFF +## ^-- 0xFFFF here is a SHN_XINDEX. +# CASE2-NEXT: 0020: 00000000 00000000 00000000 00000000 +# CASE2-NEXT: ) + +# CASE2: Symbol { +# CASE2: Name: bar (0) +# CASE2-NEXT: Value: 0x0 +# CASE2-NEXT: Size: 0 +# CASE2-NEXT: Binding: Local (0x0) +# CASE2-NEXT: Type: Section (0x3) +# CASE2-NEXT: Other: 0 +# CASE2-NEXT: Section: bar (0x1) +# CASE2-NEXT: } + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: bar + Type: SHT_PROGBITS + - Name: .symtab_shndx + Type: SHT_SYMTAB_SHNDX + Entries: [ 0, 1 ] + Link: .symtab +Symbols: + - Type: STT_SECTION + Index: SHN_XINDEX + +## Check that yaml2obj allows producing broken SHT_SYMTAB_SHNDX section +## content (in the case below it contains 0xff as an index of a section, +## which is larger than the total number of sections in the file). + +# RUN: yaml2obj --docnum=3 %s -o %t3 +# RUN: not llvm-readobj --symbols 2>&1 %t3 | FileCheck %s --check-prefix=CASE3 + +# CASE3: error: invalid section index: 255 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: bar + Type: SHT_PROGBITS + - Name: .symtab_shndx + Type: SHT_SYMTAB_SHNDX + Entries: [ 0, 255 ] + Link: .symtab +Symbols: + - Type: STT_SECTION + Index: SHN_XINDEX + +## Check that yaml2obj reports an error if a symbol index does not fit into 2 bytes. + +# RUN: not yaml2obj --docnum=4 %s -o %t4 2>&1 | FileCheck %s --check-prefix=CASE4 + +# CASE4: error: out of range hex16 number + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Symbols: + - Type: STT_SECTION + Index: 65536 + +## Check we can set a custom sh_entsize for SHT_SYMTAB_SHNDX section. + +# RUN: yaml2obj --docnum=5 %s -o %t5 +# RUN: not llvm-readelf -S 2>&1 %t5 | FileCheck %s -DFILE=%t5 --check-prefix=CASE5 + +# CASE5: error: '[[FILE]]': section [index 1] has an invalid sh_entsize: 2 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .symtab_shndx + Type: SHT_SYMTAB_SHNDX + Entries: [ 0 ] + EntSize: 2 + Link: .symtab diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp index 717b9f1..a228d39 100644 --- a/llvm/tools/obj2yaml/elf2yaml.cpp +++ b/llvm/tools/obj2yaml/elf2yaml.cpp @@ -59,6 +59,8 @@ class ELFDumper { Expected dumpRelocSection(const Elf_Shdr *Shdr); Expected dumpContentSection(const Elf_Shdr *Shdr); + Expected + dumpSymtabShndxSection(const Elf_Shdr *Shdr); Expected dumpNoBitsSection(const Elf_Shdr *Shdr); Expected dumpVerdefSection(const Elf_Shdr *Shdr); Expected dumpSymverSection(const Elf_Shdr *Shdr); @@ -158,15 +160,45 @@ template Expected ELFDumper::dump() { // Dump symbols. We need to do this early because other sections might want // to access the deduplicated symbol names that we also create here. + const Elf_Shdr *SymTab = nullptr; + const Elf_Shdr *SymTabShndx = nullptr; + const Elf_Shdr *DynSymTab = nullptr; + for (const Elf_Shdr &Sec : Sections) { - if (Sec.sh_type == ELF::SHT_SYMTAB) - if (Error E = dumpSymbols(&Sec, Y->Symbols)) - return std::move(E); - if (Sec.sh_type == ELF::SHT_DYNSYM) - if (Error E = dumpSymbols(&Sec, Y->DynamicSymbols)) - return std::move(E); + if (Sec.sh_type == ELF::SHT_SYMTAB) { + SymTab = &Sec; + } else if (Sec.sh_type == ELF::SHT_DYNSYM) { + DynSymTab = &Sec; + } else if (Sec.sh_type == ELF::SHT_SYMTAB_SHNDX) { + // ABI allows us to have one SHT_SYMTAB_SHNDX for each symbol table. + // We only support having the SHT_SYMTAB_SHNDX for SHT_SYMTAB now. + if (SymTabShndx) + return createStringError(obj2yaml_error::not_implemented, + "multiple SHT_SYMTAB_SHNDX sections are not supported"); + SymTabShndx = &Sec; + } } + // We need to locate the SHT_SYMTAB_SHNDX section early, because it might be + // needed for dumping symbols. + if (SymTabShndx) { + if (!SymTab || SymTabShndx->sh_link != SymTab - Sections.begin()) + return createStringError( + obj2yaml_error::not_implemented, + "only SHT_SYMTAB_SHNDX associated with SHT_SYMTAB are supported"); + + auto TableOrErr = Obj.getSHNDXTable(*SymTabShndx); + if (!TableOrErr) + return TableOrErr.takeError(); + ShndxTable = *TableOrErr; + } + if (SymTab) + if (Error E = dumpSymbols(SymTab, Y->Symbols)) + return std::move(E); + if (DynSymTab) + if (Error E = dumpSymbols(DynSymTab, Y->DynamicSymbols)) + return std::move(E); + for (const Elf_Shdr &Sec : Sections) { switch (Sec.sh_type) { case ELF::SHT_DYNAMIC: { @@ -182,10 +214,11 @@ template Expected ELFDumper::dump() { // Do not dump these sections. break; case ELF::SHT_SYMTAB_SHNDX: { - auto TableOrErr = Obj.getSHNDXTable(Sec); - if (!TableOrErr) - return TableOrErr.takeError(); - ShndxTable = *TableOrErr; + Expected SecOrErr = + dumpSymtabShndxSection(&Sec); + if (!SecOrErr) + return SecOrErr.takeError(); + Y->Sections.emplace_back(*SecOrErr); break; } case ELF::SHT_REL: @@ -309,9 +342,6 @@ Error ELFDumper::dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab, S.Name = SymbolNameOrErr.get(); if (Sym->st_shndx >= ELF::SHN_LORESERVE) { - if (Sym->st_shndx == ELF::SHN_XINDEX) - return createStringError(obj2yaml_error::not_implemented, - "SHN_XINDEX symbols are not supported"); S.Index = (ELFYAML::ELF_SHN)Sym->st_shndx; return Error::success(); } @@ -500,6 +530,21 @@ ELFDumper::dumpContentSection(const Elf_Shdr *Shdr) { } template +Expected +ELFDumper::dumpSymtabShndxSection(const Elf_Shdr *Shdr) { + auto S = make_unique(); + if (Error E = dumpCommonSection(Shdr, *S)) + return std::move(E); + + auto EntriesOrErr = Obj.template getSectionContentsAsArray(Shdr); + if (!EntriesOrErr) + return EntriesOrErr.takeError(); + for (const Elf_Word &E : *EntriesOrErr) + S->Entries.push_back(E); + return S.release(); +} + +template Expected ELFDumper::dumpNoBitsSection(const Elf_Shdr *Shdr) { auto S = make_unique(); -- 2.7.4