]> granicus.if.org Git - llvm/commitdiff
[llvm-readobj/llvm-readelf] - Don't fail to dump the object if .dynsym has broken...
authorGeorge Rimar <grimar@accesssoftek.com>
Mon, 10 Jun 2019 14:23:46 +0000 (14:23 +0000)
committerGeorge Rimar <grimar@accesssoftek.com>
Mon, 10 Jun 2019 14:23:46 +0000 (14:23 +0000)
This is https://bugs.llvm.org/show_bug.cgi?id=42215.

GNU readelf allows to dump the objects in that case,
but llvm-readobj/llvm-readelf reports an error and stops.

The patch fixes that.

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

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

test/tools/llvm-readobj/Inputs/elf-broken-dynsym-link.elf-x86-64 [new file with mode: 0644]
test/tools/llvm-readobj/elf-broken-dynsym-link.test [new file with mode: 0644]
test/tools/yaml2obj/explicit-dynsym-no-dynstr.yaml
tools/llvm-readobj/ELFDumper.cpp
tools/llvm-readobj/llvm-readobj.cpp
tools/llvm-readobj/llvm-readobj.h

diff --git a/test/tools/llvm-readobj/Inputs/elf-broken-dynsym-link.elf-x86-64 b/test/tools/llvm-readobj/Inputs/elf-broken-dynsym-link.elf-x86-64
new file mode 100644 (file)
index 0000000..1e11f39
Binary files /dev/null and b/test/tools/llvm-readobj/Inputs/elf-broken-dynsym-link.elf-x86-64 differ
diff --git a/test/tools/llvm-readobj/elf-broken-dynsym-link.test b/test/tools/llvm-readobj/elf-broken-dynsym-link.test
new file mode 100644 (file)
index 0000000..ceb144f
--- /dev/null
@@ -0,0 +1,60 @@
+## Test that we are able to dump section headers even if the
+## .dynsym section's sh_link field is broken.
+
+## Case 1: sh_link is set to 0.
+# RUN: yaml2obj %s -o %t1
+# RUN: llvm-readobj -S %t1 2>&1 | FileCheck %s --check-prefixes=LLVM,ERR
+# RUN: llvm-readelf -S %t1 2>&1 | FileCheck %s --check-prefixes=GNU,ERR
+
+# ERR: warning: invalid sh_type for string table, expected SHT_STRTAB
+
+# LLVM:      Name: .dynsym
+# LLVM-NEXT:  Type: SHT_DYNSYM
+# LLVM-NEXT:  Flags [
+# LLVM-NEXT:    SHF_ALLOC
+# LLVM-NEXT:  ]
+# LLVM-NEXT:  Address: 0x0
+# LLVM-NEXT:  Offset: 0x180
+# LLVM-NEXT:  Size: 24
+# LLVM-NEXT:  Link: 0
+
+# GNU:      Section Headers:
+# GNU-NEXT:  [Nr] Name    Type   Address          Off    Size   ES Flg Lk
+# GNU-NEXT:  [ 0]         NULL   0000000000000000 000000 000000 00 0   0
+# GNU-NEXT:  [ 1] .dynsym DYNSYM 0000000000000000 000180 000018 18 A   0
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_DYN
+  Machine: EM_X86_64
+Sections:
+  - Name: .dynsym
+    Type: SHT_DYNSYM
+
+## TODO: Remove precompiled input object after fixing yaml2obj.
+##       See https://bugs.llvm.org/show_bug.cgi?id=42216.
+
+## Case 2: sh_link is set to 255, which is larger than the number of the sections.
+# RUN: llvm-readobj -S %p/Inputs/elf-broken-dynsym-link.elf-x86-64 2>&1 \
+# RUN:   | FileCheck %s --check-prefixes=LLVM2,ERR2
+# RUN: llvm-readelf -S %p/Inputs/elf-broken-dynsym-link.elf-x86-64 2>&1 \
+# RUN:   | FileCheck %s --check-prefixes=GNU2,ERR2
+
+# ERR2: warning: invalid section index
+
+# LLVM2:      Name: .dynsym
+# LLVM2-NEXT:  Type: SHT_DYNSYM
+# LLVM2-NEXT:  Flags [
+# LLVM2-NEXT:    SHF_ALLOC
+# LLVM2-NEXT:  ]
+# LLVM2-NEXT:  Address: 0x0
+# LLVM2-NEXT:  Offset: 0x180
+# LLVM2-NEXT:  Size: 2
+# LLVM2-NEXT:  Link: 255
+
+# GNU2:      Section Headers:
+# GNU2-NEXT:  [Nr] Name    Type   Address          Off    Size   ES Flg Lk
+# GNU2-NEXT:  [ 0]         NULL   0000000000000000 000000 000000 00 0   0
+# GNU2-NEXT:  [ 1] .dynsym DYNSYM 0000000000000000 000180 000002 18 A   255
index 16c4a6a2d280171cee196c1f51bb4ecabac02ef3..53f6d216ba492dda9bc8b62eccede393a6058465 100644 (file)
@@ -2,14 +2,14 @@
 ## explicitly, but .dynstr is not present.
 
 # RUN: yaml2obj %s -o %t
-# RUN: not llvm-readelf --section-headers %t 2>&1 | FileCheck %s
+# RUN: llvm-readelf --section-headers %t | FileCheck %s
 
-## TODO: Check that .dynsym has Link field set to 0.
-##       GNU readelf is able to dump sections headers,
-##       but llvm-readelf reports an error below too early.
-##       See https://bugs.llvm.org/show_bug.cgi?id=42215.
+## Check that .dynsym has Link field set to 0.
 
-# CHECK: error: invalid sh_type for string table, expected SHT_STRTAB
+# CHECK:      Section Headers:
+# CHECK-NEXT:  [Nr] Name    Type   Address          Off    Size   ES Flg Lk
+# CHECK-NEXT:  [ 0]         NULL   0000000000000000 000000 000000 00 0   0
+# CHECK-NEXT:  [ 1] .dynsym DYNSYM 0000000000000000 000180 000018 18 A   0
 
 --- !ELF
 FileHeader:
index f41adaeaed6b5d4b81da6015ea10f73ca0403153..295763f879190e2cfe125d2dc54899bdac27dbd4 100644 (file)
@@ -1423,7 +1423,11 @@ ELFDumper<ELFT>::ELFDumper(const object::ELFObjectFile<ELFT> *ObjF,
         // 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 (Expected<StringRef> E = Obj->getStringTableForSymtab(Sec))
+          DynamicStringTable = *E;
+        else
+          warn(E.takeError());
       }
       break;
     case ELF::SHT_SYMTAB_SHNDX:
index 1836e0fd0d7f090c5090904bb25c69a733cebc11..7bcdd1ef38c9bc21b1aa594a03c444d8dd27f88b 100644 (file)
@@ -378,6 +378,12 @@ void reportWarning(Twine Msg) {
   WithColor::warning(errs()) << Msg << "\n";
 }
 
+void warn(Error Err) {
+  handleAllErrors(std::move(Err), [&](const ErrorInfoBase &EI) {
+    reportWarning(EI.message());
+  });
+}
+
 void error(Error EC) {
   if (!EC)
     return;
index c89871fbc7e1fc31a215cf9a5fe75bcc471618e1..ac8ced6121f49f8f8326351b2af7307dcb0b1157 100644 (file)
@@ -23,6 +23,7 @@ namespace llvm {
   // Various helper functions.
   LLVM_ATTRIBUTE_NORETURN void reportError(Twine Msg);
   void reportWarning(Twine Msg);
+  void warn(llvm::Error Err);
   void error(std::error_code EC);
   void error(llvm::Error EC);
   template <typename T> T error(llvm::Expected<T> &&E) {