]> granicus.if.org Git - llvm/commitdiff
[llvm-readobj] - Do not fail to dump the object which has wrong type of .shstrtab.
authorGeorge Rimar <grimar@accesssoftek.com>
Fri, 14 Jun 2019 11:56:10 +0000 (11:56 +0000)
committerGeorge Rimar <grimar@accesssoftek.com>
Fri, 14 Jun 2019 11:56:10 +0000 (11:56 +0000)
Imagine we have object that has .shstrtab with type != SHT_STRTAB.
In this case, we fail to dump the object, though GNU readelf dumps it without
any issues and warnings.

This patch fixes that. It adds a code to ELFDumper.cpp which is based on the implementation of getSectionName from the ELF.h:

https://github.com/llvm-mirror/llvm/blob/master/include/llvm/Object/ELF.h#L608
https://github.com/llvm-mirror/llvm/blob/master/include/llvm/Object/ELF.h#L431
https://github.com/llvm-mirror/llvm/blob/master/include/llvm/Object/ELF.h#L539

The difference is that all non critical errors are ommitted what allows us to
improve the dumping on a tool side. Also, this opens a road for a follow-up that
should allow us to dump the section headers, but drop the section names in case if .shstrtab is completely absent and/or broken.

Differential revision: https://reviews.llvm.org/D63266

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363371 91177308-0d34-0410-b5e6-96231b3b80d8

test/tools/llvm-readobj/Inputs/wrong-shstrtab-type.elf-x86-64 [new file with mode: 0644]
test/tools/llvm-readobj/elf-wrong-shstrtab-type.test [new file with mode: 0644]
tools/llvm-readobj/ELFDumper.cpp

diff --git a/test/tools/llvm-readobj/Inputs/wrong-shstrtab-type.elf-x86-64 b/test/tools/llvm-readobj/Inputs/wrong-shstrtab-type.elf-x86-64
new file mode 100644 (file)
index 0000000..801a21b
Binary files /dev/null and b/test/tools/llvm-readobj/Inputs/wrong-shstrtab-type.elf-x86-64 differ
diff --git a/test/tools/llvm-readobj/elf-wrong-shstrtab-type.test b/test/tools/llvm-readobj/elf-wrong-shstrtab-type.test
new file mode 100644 (file)
index 0000000..2d5fd68
--- /dev/null
@@ -0,0 +1,11 @@
+## wrong-shstrtab-type.elf-x86-64 contains .shstrtab section which has SHT_PROGBITS type.
+## Check we do not fail to dump the section headers in this case.
+
+# RUN: llvm-readobj -S %p/Inputs/wrong-shstrtab-type.elf-x86-64 | FileCheck %s --check-prefix LLVM
+# RUN: llvm-readelf -S %p/Inputs/wrong-shstrtab-type.elf-x86-64 | FileCheck %s --check-prefix GNU
+
+# LLVM:      Name: .shstrtab
+# LLVM-NEXT: Type: SHT_PROGBITS
+
+# GNU: [Nr] Name      Type
+# GNU: [ 3] .shstrtab PROGBITS
index 5efa35197193d0aeff78bc253c751275551cdc24..e751e6db9ebcfdf1f13bc2af45e9c529b8a12825 100644 (file)
@@ -3003,6 +3003,22 @@ static std::string getSectionTypeString(unsigned Arch, unsigned Type) {
   return "";
 }
 
+template <class ELFT>
+static StringRef getSectionName(const typename ELFT::Shdr &Sec,
+                                const ELFFile<ELFT> &Obj,
+                                ArrayRef<typename ELFT::Shdr> Sections) {
+  uint32_t Index = Obj.getHeader()->e_shstrndx;
+  if (Index == ELF::SHN_XINDEX)
+    Index = Sections[0].sh_link;
+  if (!Index) // no section string table.
+    return "";
+  if (Index >= Sections.size())
+    reportError("invalid section index");
+  StringRef Data = toStringRef(unwrapOrError(
+      Obj.template getSectionContentsAsArray<uint8_t>(&Sections[Index])));
+  return unwrapOrError(Obj.getSectionName(&Sec, Data));
+}
+
 template <class ELFT>
 void GNUStyle<ELFT>::printSectionHeaders(const ELFO *Obj) {
   unsigned Bias = ELFT::Is64Bits ? 0 : 8;
@@ -3023,7 +3039,7 @@ void GNUStyle<ELFT>::printSectionHeaders(const ELFO *Obj) {
   size_t SectionIndex = 0;
   for (const Elf_Shdr &Sec : Sections) {
     Fields[0].Str = to_string(SectionIndex);
-    Fields[1].Str = unwrapOrError(Obj->getSectionName(&Sec));
+    Fields[1].Str = getSectionName(Sec, *Obj, Sections);
     Fields[2].Str =
         getSectionTypeString(Obj->getHeader()->e_machine, Sec.sh_type);
     Fields[3].Str =
@@ -4569,13 +4585,11 @@ void LLVMStyle<ELFT>::printSectionHeaders(const ELFO *Obj) {
   ListScope SectionsD(W, "Sections");
 
   int SectionIndex = -1;
-  for (const Elf_Shdr &Sec : unwrapOrError(Obj->sections())) {
-    ++SectionIndex;
-
-    StringRef Name = unwrapOrError(Obj->getSectionName(&Sec));
-
+  ArrayRef<Elf_Shdr> Sections = unwrapOrError(Obj->sections());
+  for (const Elf_Shdr &Sec : Sections) {
+    StringRef Name = getSectionName(Sec, *Obj, Sections);
     DictScope SectionD(W, "Section");
-    W.printNumber("Index", SectionIndex);
+    W.printNumber("Index", ++SectionIndex);
     W.printNumber("Name", Name, Sec.sh_name);
     W.printHex(
         "Type",