diff options
author | Fangrui Song <i@maskray.me> | 2020-08-13 08:13:26 -0700 |
---|---|---|
committer | Fangrui Song <i@maskray.me> | 2020-08-13 08:13:42 -0700 |
commit | 7f8c49b016003a1a642235b14788648736809a58 (patch) | |
tree | e6f0732c28d4e8f85b7c82c9e24c0361bf084947 /llvm | |
parent | 1ffc299628948ee0bee3ffb7451c9085b5a80e83 (diff) | |
download | llvm-7f8c49b016003a1a642235b14788648736809a58.zip llvm-7f8c49b016003a1a642235b14788648736809a58.tar.gz llvm-7f8c49b016003a1a642235b14788648736809a58.tar.bz2 |
[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
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/include/llvm/Object/ELFObjectFile.h | 3 | ||||
-rw-r--r-- | llvm/lib/Object/ELFObjectFile.cpp | 14 | ||||
-rw-r--r-- | llvm/test/tools/llvm-objdump/ELF/AArch64/plt.test | 16 | ||||
-rw-r--r-- | llvm/test/tools/llvm-objdump/MachO/malformed-machos.test | 2 | ||||
-rw-r--r-- | llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp | 4 | ||||
-rw-r--r-- | llvm/tools/llvm-objdump/llvm-objdump.cpp | 32 |
6 files changed, 53 insertions, 18 deletions
diff --git a/llvm/include/llvm/Object/ELFObjectFile.h b/llvm/include/llvm/Object/ELFObjectFile.h index 62ecd8b..35a54c7 100644 --- a/llvm/include/llvm/Object/ELFObjectFile.h +++ b/llvm/include/llvm/Object/ELFObjectFile.h @@ -92,7 +92,8 @@ public: 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 c919d25..72eaeb7 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 6238cf55..915b1c0 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 c64f8bf..c66a4b11 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 d2b4db3b5..1070446 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 320bbb5..3ce7e8d 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) |