From 9c16b5ded4bddba6c36fb4677cb2553a3595a60b Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Tue, 28 May 2019 20:01:25 +0000 Subject: [PATCH] Change ELF tools to allow multiple sections per file. This is how multi-partition combined output files are going to look. If we see multiple sections, the tools will just read the first one. Differential Revision: https://reviews.llvm.org/D62349 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@361869 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Object/ELFObjectFile.h | 10 ++--- test/Object/multiple-sections.yaml | 62 +++++++++++++++++++++++++++++ tools/llvm-readobj/ELFDumper.cpp | 43 +++++++++----------- 3 files changed, 85 insertions(+), 30 deletions(-) create mode 100644 test/Object/multiple-sections.yaml diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h index d5e9d3638dc..855742445d2 100644 --- a/include/llvm/Object/ELFObjectFile.h +++ b/include/llvm/Object/ELFObjectFile.h @@ -951,15 +951,13 @@ ELFObjectFile::create(MemoryBufferRef Object) { for (const Elf_Shdr &Sec : *SectionsOrErr) { switch (Sec.sh_type) { case ELF::SHT_DYNSYM: { - if (DotDynSymSec) - return createError("More than one dynamic symbol table!"); - DotDynSymSec = &Sec; + if (!DotDynSymSec) + DotDynSymSec = &Sec; break; } case ELF::SHT_SYMTAB: { - if (DotSymtabSec) - return createError("More than one static symbol table!"); - DotSymtabSec = &Sec; + if (!DotSymtabSec) + DotSymtabSec = &Sec; break; } case ELF::SHT_SYMTAB_SHNDX: { diff --git a/test/Object/multiple-sections.yaml b/test/Object/multiple-sections.yaml new file mode 100644 index 00000000000..e416b760fc5 --- /dev/null +++ b/test/Object/multiple-sections.yaml @@ -0,0 +1,62 @@ +# RUN: yaml2obj %s -o %t.o +# RUN: llvm-readobj -a --elf-cg-profile --addrsig %t.o | FileCheck %s + +# Test that multiple sections with the same type does not trigger an error. + +# CHECK: ElfHeader { +# CHECK: SHT_GNU_verdef { +# CHECK: SHT_GNU_verneed { +# CHECK: CGProfile [ +# CHECK: Addrsig [ + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .symtab2 + Type: SHT_SYMTAB + Link: .strtab + Content: '' + EntSize: 24 + - Name: .versym + Type: SHT_GNU_versym + Entries: [ ] + - Name: .versym2 + Type: SHT_GNU_versym + Entries: [ ] + - Name: .verdef + Type: SHT_GNU_verdef + Info: 0x0000000000000000 + Entries: + - Name: .verdef2 + Type: SHT_GNU_verdef + Info: 0x0000000000000000 + Entries: + - Name: .verneed + Type: SHT_GNU_verneed + Info: 0x0000000000000000 + Dependencies: + - Name: .verneed2 + Type: SHT_GNU_verneed + Info: 0x0000000000000000 + Dependencies: + - Name: .llvm.call-graph-profile + Type: SHT_LLVM_CALL_GRAPH_PROFILE + Content: '' + EntSize: 16 + - Name: .llvm.call-graph-profile2 + Type: SHT_LLVM_CALL_GRAPH_PROFILE + Content: '' + EntSize: 16 + - Name: .llvm_addrsig + Type: SHT_LLVM_ADDRSIG + Content: '' + - Name: .llvm_addrsig2 + Type: SHT_LLVM_ADDRSIG + Content: '' +Symbols: + - Name: f +... diff --git a/tools/llvm-readobj/ELFDumper.cpp b/tools/llvm-readobj/ELFDumper.cpp index 150e98df8bb..fcadf73110e 100644 --- a/tools/llvm-readobj/ELFDumper.cpp +++ b/tools/llvm-readobj/ELFDumper.cpp @@ -1414,45 +1414,40 @@ ELFDumper::ELFDumper(const object::ELFObjectFile *ObjF, for (const Elf_Shdr &Sec : unwrapOrError(Obj->sections())) { switch (Sec.sh_type) { case ELF::SHT_SYMTAB: - if (DotSymtabSec != nullptr) - reportError("Multiple SHT_SYMTAB"); - DotSymtabSec = &Sec; + if (!DotSymtabSec) + DotSymtabSec = &Sec; break; case ELF::SHT_DYNSYM: - if (DynSymRegion.Size) - reportError("Multiple SHT_DYNSYM"); - DynSymRegion = createDRIFrom(&Sec); - // This is only used (if Elf_Shdr present)for naming section in GNU style - DynSymtabName = unwrapOrError(Obj->getSectionName(&Sec)); - DynamicStringTable = unwrapOrError(Obj->getStringTableForSymtab(Sec)); + if (!DynSymRegion.Size) { + DynSymRegion = createDRIFrom(&Sec); + // This is only used (if Elf_Shdr present)for naming section in GNU + // style + DynSymtabName = unwrapOrError(Obj->getSectionName(&Sec)); + DynamicStringTable = unwrapOrError(Obj->getStringTableForSymtab(Sec)); + } break; case ELF::SHT_SYMTAB_SHNDX: ShndxTable = unwrapOrError(Obj->getSHNDXTable(Sec)); break; case ELF::SHT_GNU_versym: - if (SymbolVersionSection != nullptr) - reportError("Multiple SHT_GNU_versym"); - SymbolVersionSection = &Sec; + if (!SymbolVersionSection) + SymbolVersionSection = &Sec; break; case ELF::SHT_GNU_verdef: - if (SymbolVersionDefSection != nullptr) - reportError("Multiple SHT_GNU_verdef"); - SymbolVersionDefSection = &Sec; + if (!SymbolVersionDefSection) + SymbolVersionDefSection = &Sec; break; case ELF::SHT_GNU_verneed: - if (SymbolVersionNeedSection != nullptr) - reportError("Multiple SHT_GNU_verneed"); - SymbolVersionNeedSection = &Sec; + if (!SymbolVersionNeedSection) + SymbolVersionNeedSection = &Sec; break; case ELF::SHT_LLVM_CALL_GRAPH_PROFILE: - if (DotCGProfileSec != nullptr) - reportError("Multiple .llvm.call-graph-profile"); - DotCGProfileSec = &Sec; + if (!DotCGProfileSec) + DotCGProfileSec = &Sec; break; case ELF::SHT_LLVM_ADDRSIG: - if (DotAddrsigSec != nullptr) - reportError("Multiple .llvm_addrsig"); - DotAddrsigSec = &Sec; + if (!DotAddrsigSec) + DotAddrsigSec = &Sec; break; } } -- 2.50.1