Index: llvm/include/llvm/Object/ELF.h =================================================================== --- llvm/include/llvm/Object/ELF.h +++ llvm/include/llvm/Object/ELF.h @@ -670,7 +670,6 @@ Elf_Shdr_Range Sections) const { if (Sec.sh_type != ELF::SHT_SYMTAB && Sec.sh_type != ELF::SHT_DYNSYM) - // TODO: this error is untested. return createError( "invalid sh_type for symbol table, expected SHT_SYMTAB or SHT_DYNSYM"); auto SectionOrErr = object::getSection(Sections, Sec.sh_link); Index: llvm/test/tools/llvm-readobj/ELF/relocations-errors.test =================================================================== --- /dev/null +++ llvm/test/tools/llvm-readobj/ELF/relocations-errors.test @@ -0,0 +1,93 @@ +## Check how do we report warnings when dumping an object with broken relocations. + +# RUN: yaml2obj %s -o %t64 +# RUN: llvm-readobj --relocations %t64 2>&1 | FileCheck %s -DFILE=%t64 --check-prefix=LLVM +# RUN: llvm-readelf --relocations %t64 2>&1 | FileCheck %s -DFILE=%t64 --check-prefix=GNU + +# LLVM: Relocations [ +# LLVM-NEXT: Section (3) .rel.text { +# LLVM-NEXT: warning: '[[FILE]]': unable to access section [index 6] data at 0x17e7e7e8b0: offset goes past the end of file +# LLVM-NEXT: 0x2 R_X86_64_NONE - 0x0 +# LLVM-NEXT: warning: '[[FILE]]': invalid section index: 255 +# LLVM-NEXT: warning: '[[FILE]]': a section [index 2] has an invalid sh_name (0xfefefefe) offset which goes past the end of the section name string table +# LLVM-NEXT: } +# LLVM-NEXT: Section (4) .rela.text { +# LLVM-NEXT: warning: '[[FILE]]': invalid sh_type for symbol table, expected SHT_SYMTAB or SHT_DYNSYM +# LLVM-NEXT: } +# LLVM-NEXT: ] + +# GNU: Relocation section '.rel.text' at offset 0x41 contains 5 entries: +# GNU-NEXT: Offset Info Type Symbol's Value Symbol's Name +# GNU-NEXT: warning: '[[FILE]]': unable to access section [index 6] data at 0x17e7e7e8b0: offset goes past the end of file +# GNU-NEXT: 0000000000000002 0000000000000000 R_X86_64_NONE +# GNU-NEXT: warning: '[[FILE]]': invalid section index: 255 +# GNU-NEXT: warning: '[[FILE]]': a section [index 2] has an invalid sh_name (0xfefefefe) offset which goes past the end of the section name string table +# GNU-EMPTY: +# GNU-NEXT: Relocation section '.rela.text' at offset 0x91 contains 1 entries: +# GNU-NEXT: Offset Info Type Symbol's Value Symbol's Name + Addend +# GNU-NEXT: warning: '[[FILE]]': invalid sh_type for symbol table, expected SHT_SYMTAB or SHT_DYNSYM + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Content: '00' + - Name: .foo + Type: SHT_PROGBITS + ShName: 0xFEFEFEFE + - Name: .rel.text + Type: SHT_REL + Info: .text + Relocations: +## Case 1: There is no a symbol with index of 0xFEFEFEFE. Also, check +## that warnings we report are uniqified. + - Offset: 0x0 + Symbol: 0xFEFEFEFE + Type: R_X86_64_NONE + - Offset: 0x1 + Symbol: 0xFEFEFEFE + Type: R_X86_64_NONE +## Case 2: Test that no warning is reported for a relocation against a symbol with index 0. + - Offset: 0x2 + Symbol: 0 + Type: R_X86_64_NONE +## Case 3: Test a relocation against a section symbol that has an invalid +## section index (larger than the number of sections). + - Offset: 0x3 + Symbol: .sec.symbol1 + Type: R_X86_64_NONE +## Case 4: Test a relocation against a section symbol that has an invalid +## sh_name offset that goes past the end of the section name string table. + - Offset: 0x4 + Symbol: .sec.symbol2 + Type: R_X86_64_NONE +## Case 5: Test a relocation in the section that is linked to a symbol table that +## has a section type that is not a SHT_SYMTAB or SHT_DYNSYM. +## In this case the code fails to find a corresponding symbol string table. + - Name: .rela.text + Type: SHT_RELA + Info: .text + Link: .fake.symtab + Relocations: + - Offset: 0x5 + Symbol: symbol + Type: R_X86_64_NONE + - Name: .fake.symtab + Type: SHT_PROGBITS + EntSize: 24 + Size: 48 +Symbols: + - Name: symbol + Section: .text + Value: 0 + - Name: .sec.symbol1 + Type: STT_SECTION + Index: 0xFF + - Name: .sec.symbol2 + Type: STT_SECTION + Index: 0x2 Index: llvm/tools/llvm-readobj/ELFDumper.cpp =================================================================== --- llvm/tools/llvm-readobj/ELFDumper.cpp +++ llvm/tools/llvm-readobj/ELFDumper.cpp @@ -3317,11 +3317,13 @@ template void GNUStyle::printRelocation(const ELFO *Obj, const Elf_Shdr *SymTab, const Elf_Rela &R, bool IsRela) { - const typename ELFT::Sym *Sym; - std::string Name; - std::tie(Sym, Name) = unwrapOrError( - this->FileName, this->dumper()->getRelocationTarget(SymTab, R)); - printRelocation(Obj, Sym, Name, R, IsRela); + Expected> Target = + this->dumper()->getRelocationTarget(SymTab, R); + if (!Target) + this->reportUniqueWarning(Target.takeError()); + else + printRelocation(Obj, /*Sym=*/(*Target).first, /*Name=*/(*Target).second, R, + IsRela); } template @@ -5734,11 +5736,14 @@ template void LLVMStyle::printRelocation(const ELFO *Obj, Elf_Rela Rel, const Elf_Shdr *SymTab) { - const typename ELFT::Sym *Sym; - std::string TargetName; - std::tie(Sym, TargetName) = unwrapOrError( - this->FileName, this->dumper()->getRelocationTarget(SymTab, Rel)); + Expected> Target = + this->dumper()->getRelocationTarget(SymTab, Rel); + if (!Target) { + this->reportUniqueWarning(Target.takeError()); + return; + } + std::string TargetName = (*Target).second; SmallString<32> RelocName; Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName);