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

llvm-svn: 361869
This commit is contained in:
Peter Collingbourne 2019-05-28 20:01:25 +00:00
parent 297e39ba1f
commit 7fb6630c25
3 changed files with 85 additions and 30 deletions

View File

@ -951,15 +951,13 @@ ELFObjectFile<ELFT>::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: {

View File

@ -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
...

View File

@ -1414,45 +1414,40 @@ ELFDumper<ELFT>::ELFDumper(const object::ELFObjectFile<ELFT> *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;
}
}