Index: llvm/trunk/include/llvm/Object/ELF.h =================================================================== --- llvm/trunk/include/llvm/Object/ELF.h +++ llvm/trunk/include/llvm/Object/ELF.h @@ -635,8 +635,11 @@ 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) + Index: llvm/trunk/include/llvm/ObjectYAML/ELFYAML.h =================================================================== --- llvm/trunk/include/llvm/ObjectYAML/ELFYAML.h +++ llvm/trunk/include/llvm/ObjectYAML/ELFYAML.h @@ -128,6 +128,7 @@ NoBits, Verdef, Verneed, + SymtabShndxSection, Symver, MipsABIFlags }; @@ -274,6 +275,16 @@ } }; +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; Index: llvm/trunk/lib/ObjectYAML/ELFEmitter.cpp =================================================================== --- llvm/trunk/lib/ObjectYAML/ELFEmitter.cpp +++ llvm/trunk/lib/ObjectYAML/ELFEmitter.cpp @@ -141,6 +141,9 @@ 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 @@ } 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 @@ } 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) { Index: llvm/trunk/lib/ObjectYAML/ELFYAML.cpp =================================================================== --- llvm/trunk/lib/ObjectYAML/ELFYAML.cpp +++ llvm/trunk/lib/ObjectYAML/ELFYAML.cpp @@ -563,7 +563,7 @@ 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 @@ 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 @@ 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 @@ 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()); Index: llvm/trunk/test/Object/invalid.test =================================================================== --- llvm/trunk/test/Object/invalid.test +++ llvm/trunk/test/Object/invalid.test @@ -207,7 +207,7 @@ # 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 @@ 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. Index: llvm/trunk/test/tools/llvm-readobj/elf-section-types.test =================================================================== --- llvm/trunk/test/tools/llvm-readobj/elf-section-types.test +++ llvm/trunk/test/tools/llvm-readobj/elf-section-types.test @@ -166,8 +166,7 @@ - Name: symtab_shndx Type: SHT_SYMTAB_SHNDX Link: .symtab - EntSize: 0x4 - Content: "0000000000000000" + Entries: [ 0, 1 ] - Name: relr Type: SHT_RELR - Name: android_rel Index: llvm/trunk/test/tools/obj2yaml/elf-sht-symtab-shndx.yaml =================================================================== --- llvm/trunk/test/tools/obj2yaml/elf-sht-symtab-shndx.yaml +++ llvm/trunk/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 Index: llvm/trunk/test/tools/obj2yaml/special-symbol-indices.yaml =================================================================== --- llvm/trunk/test/tools/obj2yaml/special-symbol-indices.yaml +++ llvm/trunk/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 @@ - 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 Index: llvm/trunk/test/tools/yaml2obj/elf-sht-symtab-shndx.yaml =================================================================== --- llvm/trunk/test/tools/yaml2obj/elf-sht-symtab-shndx.yaml +++ llvm/trunk/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 Index: llvm/trunk/tools/obj2yaml/elf2yaml.cpp =================================================================== --- llvm/trunk/tools/obj2yaml/elf2yaml.cpp +++ llvm/trunk/tools/obj2yaml/elf2yaml.cpp @@ -59,6 +59,8 @@ 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 @@ // 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 @@ // 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 @@ 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 @@ } 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();