[llvm] 7f8c49b - [llvm-objdump] Change symbol name/PLT decoding errors to warnings

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 13 08:13:50 PDT 2020


Author: Fangrui Song
Date: 2020-08-13T08:13:42-07:00
New Revision: 7f8c49b016003a1a642235b14788648736809a58

URL: https://github.com/llvm/llvm-project/commit/7f8c49b016003a1a642235b14788648736809a58
DIFF: https://github.com/llvm/llvm-project/commit/7f8c49b016003a1a642235b14788648736809a58.diff

LOG: [llvm-objdump] Change symbol name/PLT decoding errors to warnings

If the referenced symbol of a J[U]MP_SLOT is invalid (e.g. symbol index 0), llvm-objdump -d will bail out:

```
error: 'a': st_name (0x326600) is past the end of the string table of size 0x7
```

where 0x326600 is the st_name field of the first entry past the end of .symtab

Change it to a warning to continue dumping.
`X86/plt.test` uses a prebuilt executable, so I pick `ELF/AArch64/plt.test`
which has a YAML input and can be easily modified.

Reviewed By: jhenderson

Differential Revision: https://reviews.llvm.org/D85623

Added: 
    

Modified: 
    llvm/include/llvm/Object/ELFObjectFile.h
    llvm/lib/Object/ELFObjectFile.cpp
    llvm/test/tools/llvm-objdump/ELF/AArch64/plt.test
    llvm/test/tools/llvm-objdump/MachO/malformed-machos.test
    llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp
    llvm/tools/llvm-objdump/llvm-objdump.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Object/ELFObjectFile.h b/llvm/include/llvm/Object/ELFObjectFile.h
index 62ecd8b5a7e5..35a54c7045b1 100644
--- a/llvm/include/llvm/Object/ELFObjectFile.h
+++ b/llvm/include/llvm/Object/ELFObjectFile.h
@@ -92,7 +92,8 @@ class ELFObjectFileBase : public ObjectFile {
 
   virtual uint16_t getEMachine() const = 0;
 
-  std::vector<std::pair<DataRefImpl, uint64_t>> getPltAddresses() const;
+  std::vector<std::pair<Optional<DataRefImpl>, uint64_t>>
+  getPltAddresses() const;
 };
 
 class ELFSectionRef : public SectionRef {

diff  --git a/llvm/lib/Object/ELFObjectFile.cpp b/llvm/lib/Object/ELFObjectFile.cpp
index c919d25855d2..72eaeb78a21d 100644
--- a/llvm/lib/Object/ELFObjectFile.cpp
+++ b/llvm/lib/Object/ELFObjectFile.cpp
@@ -440,7 +440,7 @@ void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const {
   TheTriple.setArchName(Triple);
 }
 
-std::vector<std::pair<DataRefImpl, uint64_t>>
+std::vector<std::pair<Optional<DataRefImpl>, uint64_t>>
 ELFObjectFileBase::getPltAddresses() const {
   std::string Err;
   const auto Triple = makeTriple();
@@ -498,14 +498,18 @@ ELFObjectFileBase::getPltAddresses() const {
     GotToPlt.insert(std::make_pair(Entry.second, Entry.first));
   // Find the relocations in the dynamic relocation table that point to
   // locations in the GOT for which we know the corresponding PLT entry.
-  std::vector<std::pair<DataRefImpl, uint64_t>> Result;
+  std::vector<std::pair<Optional<DataRefImpl>, uint64_t>> Result;
   for (const auto &Relocation : RelaPlt->relocations()) {
     if (Relocation.getType() != JumpSlotReloc)
       continue;
     auto PltEntryIter = GotToPlt.find(Relocation.getOffset());
-    if (PltEntryIter != GotToPlt.end())
-      Result.push_back(std::make_pair(
-          Relocation.getSymbol()->getRawDataRefImpl(), PltEntryIter->second));
+    if (PltEntryIter != GotToPlt.end()) {
+      symbol_iterator Sym = Relocation.getSymbol();
+      if (Sym == symbol_end())
+        Result.emplace_back(None, PltEntryIter->second);
+      else
+        Result.emplace_back(Sym->getRawDataRefImpl(), PltEntryIter->second);
+    }
   }
   return Result;
 }

diff  --git a/llvm/test/tools/llvm-objdump/ELF/AArch64/plt.test b/llvm/test/tools/llvm-objdump/ELF/AArch64/plt.test
index 6238cf5565f7..915b1c0dec17 100644
--- a/llvm/test/tools/llvm-objdump/ELF/AArch64/plt.test
+++ b/llvm/test/tools/llvm-objdump/ELF/AArch64/plt.test
@@ -18,6 +18,19 @@
 # CHECK-BTI-NEXT: bti   c
 # CHECK-BTI-NEXT: adrp  x16, {{.*}}
 
+# RUN: yaml2obj -D SYM=0 %s -o %tindex
+# RUN: llvm-objdump -d %tindex 2>&1 | FileCheck %s --check-prefix=INVALID_INDEX -DFILE=%tindex
+
+# INVALID_INDEX: warning: '[[FILE]]': PLT entry at 0x210030 references an invalid symbol{{$}}
+# INVALID_INDEX: Disassembly of section .text:
+
+# RUN: yaml2obj -D ST_NAME=0x1234 %s -o %tst_name
+# RUN: llvm-objdump -d %tst_name 2>&1 | FileCheck %s --check-prefix=INVALID_ST_NAME -DFILE=%tst_name
+
+# INVALID_ST_NAME:      warning: '[[FILE]]': st_name (0x1234) is past the end of the string table of size 0x7
+# INVALID_ST_NAME-NEXT: warning: '[[FILE]]': PLT entry at 0x210030 references an invalid symbol{{$}}
+# INVALID_ST_NAME:      Disassembly of section .text:
+
 --- !ELF
 FileHeader:
   Class:   ELFCLASS64
@@ -32,7 +45,7 @@ Sections:
     Info:    .got.plt
     Relocations:
       - Offset: 0x0000000000230018
-        Symbol: f1
+        Symbol: [[SYM=f1]]
         Type:   R_AARCH64_JUMP_SLOT
       - Offset: 0x0000000000230020
         Symbol: f2
@@ -52,6 +65,7 @@ Sections:
     Content: '000000000000000000000000000000000000000000000000100021000000000010002100000000001000210000000000'
 Symbols:
   - Name:    f1
+    StName:  [[ST_NAME=<none>]]
     Type:    STT_FUNC
     Binding: STB_GLOBAL
   - Name:    f2

diff  --git a/llvm/test/tools/llvm-objdump/MachO/malformed-machos.test b/llvm/test/tools/llvm-objdump/MachO/malformed-machos.test
index c64f8bf9f9e3..c66a4b11b374 100644
--- a/llvm/test/tools/llvm-objdump/MachO/malformed-machos.test
+++ b/llvm/test/tools/llvm-objdump/MachO/malformed-machos.test
@@ -55,7 +55,7 @@ INVALID-SYMBOL-INDR-ARCHIVE-UNIVERSAL: macho-invalid-symbol-indr-archive-univers
 RUN: not llvm-objdump --macho -d %p/Inputs/macho-invalid-symbol-strx 2>&1 | FileCheck --check-prefix INVALID-SYMBOL-STRX %s
 INVALID-SYMBOL-STRX: macho-invalid-symbol-strx': truncated or malformed object (bad string table index: 22 past the end of string table, for symbol at index 1)
 
-RUN: not llvm-objdump -d %p/Inputs/macho-invalid-symbol-strx 2>&1 | FileCheck --check-prefix INVALID-SYMBOL-STRX-NO-MACHO-FLAG %s
+RUN: llvm-objdump -d %p/Inputs/macho-invalid-symbol-strx 2>&1 | FileCheck --check-prefix INVALID-SYMBOL-STRX-NO-MACHO-FLAG %s
 INVALID-SYMBOL-STRX-NO-MACHO-FLAG: macho-invalid-symbol-strx': truncated or malformed object (bad string index: 22 for symbol at index 1)
 
 RUN: not llvm-objdump --macho -d --arch all %p/Inputs/macho-invalid-symbol-strx-universal 2>&1 | FileCheck --check-prefix INVALID-SYMBOL-STRX-UNIVERSAL %s

diff  --git a/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp b/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp
index d2b4db3b5751..107044647f08 100644
--- a/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp
+++ b/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp
@@ -568,7 +568,9 @@ Error FileAnalysis::parseSymbolTable() {
   }
   if (auto *ElfObject = dyn_cast<object::ELFObjectFileBase>(Object)) {
     for (const auto &Addr : ElfObject->getPltAddresses()) {
-      object::SymbolRef Sym(Addr.first, Object);
+      if (!Addr.first)
+        continue;
+      object::SymbolRef Sym(*Addr.first, Object);
       auto SymNameOrErr = Sym.getName();
       if (!SymNameOrErr)
         consumeError(SymNameOrErr.takeError());

diff  --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index 320bbb5d358b..3ce7e8de3994 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -1394,13 +1394,23 @@ static void addPltEntries(const ObjectFile *Obj,
     return;
   if (auto *ElfObj = dyn_cast<ELFObjectFileBase>(Obj)) {
     for (auto PltEntry : ElfObj->getPltAddresses()) {
-      SymbolRef Symbol(PltEntry.first, ElfObj);
-      uint8_t SymbolType = getElfSymbolType(Obj, Symbol);
-
-      StringRef Name = unwrapOrError(Symbol.getName(), Obj->getFileName());
-      if (!Name.empty())
-        AllSymbols[*Plt].emplace_back(
-            PltEntry.second, Saver.save((Name + "@plt").str()), SymbolType);
+      if (PltEntry.first) {
+        SymbolRef Symbol(*PltEntry.first, ElfObj);
+        uint8_t SymbolType = getElfSymbolType(Obj, Symbol);
+        if (Expected<StringRef> NameOrErr = Symbol.getName()) {
+          if (!NameOrErr->empty())
+            AllSymbols[*Plt].emplace_back(
+                PltEntry.second, Saver.save((*NameOrErr + "@plt").str()),
+                SymbolType);
+          continue;
+        } else {
+          // The warning has been reported in disassembleObject().
+          consumeError(NameOrErr.takeError());
+        }
+      }
+      reportWarning("PLT entry at 0x" + Twine::utohexstr(PltEntry.second) +
+                        " references an invalid symbol",
+                    Obj->getFileName());
     }
   }
 }
@@ -1594,8 +1604,12 @@ static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj,
   const StringRef FileName = Obj->getFileName();
   const MachOObjectFile *MachO = dyn_cast<const MachOObjectFile>(Obj);
   for (const SymbolRef &Symbol : Obj->symbols()) {
-    StringRef Name = unwrapOrError(Symbol.getName(), FileName);
-    if (Name.empty() && !(Obj->isXCOFF() && SymbolDescription))
+    Expected<StringRef> NameOrErr = Symbol.getName();
+    if (!NameOrErr) {
+      reportWarning(toString(NameOrErr.takeError()), FileName);
+      continue;
+    }
+    if (NameOrErr->empty() && !(Obj->isXCOFF() && SymbolDescription))
       continue;
 
     if (Obj->isELF() && getElfSymbolType(Obj, Symbol) == ELF::STT_SECTION)


        


More information about the llvm-commits mailing list