[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