[llvm] r366203 - [Object/llvm-readelf/llvm-readobj] - Improve error reporting when e_shstrndx is broken.
George Rimar via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 16 04:07:30 PDT 2019
Author: grimar
Date: Tue Jul 16 04:07:30 2019
New Revision: 366203
URL: http://llvm.org/viewvc/llvm-project?rev=366203&view=rev
Log:
[Object/llvm-readelf/llvm-readobj] - Improve error reporting when e_shstrndx is broken.
When e_shstrndx is broken, it is impossible to get a section name.
In this patch I improved the error message we show and
added tests for Object and for llvm-readelf/llvm-readobj
Message was changed in two places:
1) llvm-readelf/llvm-readobj previously used a code from Object/ELF.h,
now they have a modified version of it (it has less checks and allows
dumping broken things).
2) Code in Object/ELF.h is still used for generic cases.
Differential revision: https://reviews.llvm.org/D64714
Added:
llvm/trunk/test/tools/llvm-readobj/elf-invalid-shstrndx.test
Modified:
llvm/trunk/include/llvm/Object/ELF.h
llvm/trunk/test/Object/invalid.test
llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp
llvm/trunk/tools/llvm-readobj/llvm-readobj.h
Modified: llvm/trunk/include/llvm/Object/ELF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/ELF.h?rev=366203&r1=366202&r2=366203&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/ELF.h (original)
+++ llvm/trunk/include/llvm/Object/ELF.h Tue Jul 16 04:07:30 2019
@@ -466,9 +466,10 @@ ELFFile<ELFT>::getSectionStringTable(Elf
if (!Index) // no section string table.
return "";
+ // TODO: Test a case when the sh_link of the section with index 0 is broken.
if (Index >= Sections.size())
- // TODO: this error is untested.
- return createError("invalid section index");
+ return createError("section header string table index " + Twine(Index) +
+ " does not exist");
return getStringTable(&Sections[Index]);
}
Modified: llvm/trunk/test/Object/invalid.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/invalid.test?rev=366203&r1=366202&r2=366203&view=diff
==============================================================================
--- llvm/trunk/test/Object/invalid.test (original)
+++ llvm/trunk/test/Object/invalid.test Tue Jul 16 04:07:30 2019
@@ -536,3 +536,19 @@ ProgramHeaders:
FileSize: 0xffff0000
Sections:
- Section: .dynamic
+
+# RUN: yaml2obj --docnum=25 %s -o %t25
+# RUN: not obj2yaml 2>&1 %t25 | FileCheck %s -DFILE=%t25 --check-prefix=INVALID-SHSTRNDX
+
+# INVALID-SHSTRNDX: Error reading file: [[FILE]]: section header string table index 255 does not exist
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_X86_64
+ SHStrNdx: 0xFF
+Sections:
+ - Name: .foo
+ Type: SHT_PROGBITS
Added: llvm/trunk/test/tools/llvm-readobj/elf-invalid-shstrndx.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/elf-invalid-shstrndx.test?rev=366203&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/elf-invalid-shstrndx.test (added)
+++ llvm/trunk/test/tools/llvm-readobj/elf-invalid-shstrndx.test Tue Jul 16 04:07:30 2019
@@ -0,0 +1,26 @@
+# RUN: yaml2obj %s -o %t
+# RUN: not llvm-readelf --headers -S 2>&1 %t | FileCheck %s -DFILE=%t --check-prefix=GNU
+# RUN: not llvm-readobj --headers -S 2>&1 %t | FileCheck %s -DFILE=%t --check-prefix=LLVM
+
+# GNU: ELF Header:
+# GNU: Section header string table index: 255
+# GNU-NEXT: There are 4 section headers, starting at offset 0x40:
+# GNU: Section Headers:
+# GNU-NEXT: [Nr] Name
+# GNU-EMPTY:
+# GNU-NEXT: error: '[[FILE]]': section header string table index 255 does not exist
+
+# LLVM: ElfHeader {
+# LLVM: StringTableSectionIndex: 255
+# LLVM-NEXT: }
+# LLVM-NEXT: Sections [
+# LLVM-EMPTY:
+# LLVM-NEXT: error: '[[FILE]]': section header string table index 255 does not exist
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_X86_64
+ SHStrNdx: 0xFF
Modified: llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ELFDumper.cpp?rev=366203&r1=366202&r2=366203&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/ELFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/ELFDumper.cpp Tue Jul 16 04:07:30 2019
@@ -183,6 +183,8 @@ public:
void printELFLinkerOptions() override;
+ const object::ELFObjectFile<ELFT> *getElfObject() const { return ObjF; };
+
private:
std::unique_ptr<DumpStyle<ELFT>> ELFDumperStyle;
@@ -3009,15 +3011,19 @@ static std::string getSectionTypeString(
template <class ELFT>
static StringRef getSectionName(const typename ELFT::Shdr &Sec,
- const ELFFile<ELFT> &Obj,
+ const ELFObjectFile<ELFT> &ElfObj,
ArrayRef<typename ELFT::Shdr> Sections) {
+ const ELFFile<ELFT> &Obj = *ElfObj.getELFFile();
uint32_t Index = Obj.getHeader()->e_shstrndx;
if (Index == ELF::SHN_XINDEX)
Index = Sections[0].sh_link;
if (!Index) // no section string table.
return "";
+ // TODO: Test a case when the sh_link of the section with index 0 is broken.
if (Index >= Sections.size())
- reportError("invalid section index");
+ reportError(ElfObj.getFileName(),
+ createError("section header string table index " +
+ Twine(Index) + " does not exist"));
StringRef Data = toStringRef(unwrapOrError(
Obj.template getSectionContentsAsArray<uint8_t>(&Sections[Index])));
return unwrapOrError(Obj.getSectionName(&Sec, Data));
@@ -3040,10 +3046,11 @@ void GNUStyle<ELFT>::printSectionHeaders
printField(F);
OS << "\n";
+ const ELFObjectFile<ELFT> *ElfObj = this->dumper()->getElfObject();
size_t SectionIndex = 0;
for (const Elf_Shdr &Sec : Sections) {
Fields[0].Str = to_string(SectionIndex);
- Fields[1].Str = getSectionName(Sec, *Obj, Sections);
+ Fields[1].Str = getSectionName(Sec, *ElfObj, Sections);
Fields[2].Str =
getSectionTypeString(Obj->getHeader()->e_machine, Sec.sh_type);
Fields[3].Str =
@@ -4590,8 +4597,9 @@ void LLVMStyle<ELFT>::printSectionHeader
int SectionIndex = -1;
ArrayRef<Elf_Shdr> Sections = unwrapOrError(Obj->sections());
+ const ELFObjectFile<ELFT> *ElfObj = this->dumper()->getElfObject();
for (const Elf_Shdr &Sec : Sections) {
- StringRef Name = getSectionName(Sec, *Obj, Sections);
+ StringRef Name = getSectionName(Sec, *ElfObj, Sections);
DictScope SectionD(W, "Section");
W.printNumber("Index", ++SectionIndex);
W.printNumber("Name", Name, Sec.sh_name);
Modified: llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp?rev=366203&r1=366202&r2=366203&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp Tue Jul 16 04:07:30 2019
@@ -371,11 +371,18 @@ namespace opts {
namespace llvm {
LLVM_ATTRIBUTE_NORETURN void reportError(Twine Msg) {
+ fouts().flush();
errs() << "\n";
WithColor::error(errs()) << Msg << "\n";
exit(1);
}
+void reportError(StringRef Input, Error Err) {
+ if (Input == "-")
+ Input = "<stdin>";
+ error(createFileError(Input, std::move(Err)));
+}
+
void reportWarning(Twine Msg) {
fouts().flush();
errs() << "\n";
@@ -403,12 +410,6 @@ void error(std::error_code EC) {
} // namespace llvm
-static void reportError(StringRef Input, Error Err) {
- if (Input == "-")
- Input = "<stdin>";
- error(createFileError(Input, std::move(Err)));
-}
-
static void reportError(StringRef Input, std::error_code EC) {
reportError(Input, errorCodeToError(EC));
}
Modified: llvm/trunk/tools/llvm-readobj/llvm-readobj.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/llvm-readobj.h?rev=366203&r1=366202&r2=366203&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/llvm-readobj.h (original)
+++ llvm/trunk/tools/llvm-readobj/llvm-readobj.h Tue Jul 16 04:07:30 2019
@@ -22,6 +22,7 @@ namespace llvm {
// Various helper functions.
LLVM_ATTRIBUTE_NORETURN void reportError(Twine Msg);
+ void reportError(StringRef Input, Error Err);
void reportWarning(Twine Msg);
void warn(llvm::Error Err);
void error(std::error_code EC);
More information about the llvm-commits
mailing list