diff --git a/llvm/include/llvm/Object/ELFObjectFile.h b/llvm/include/llvm/Object/ELFObjectFile.h --- a/llvm/include/llvm/Object/ELFObjectFile.h +++ b/llvm/include/llvm/Object/ELFObjectFile.h @@ -92,7 +92,8 @@ virtual uint16_t getEMachine() const = 0; - std::vector> getPltAddresses() const; + std::vector, uint64_t>> + getPltAddresses() const; }; class ELFSectionRef : public SectionRef { diff --git a/llvm/lib/Object/ELFObjectFile.cpp b/llvm/lib/Object/ELFObjectFile.cpp --- a/llvm/lib/Object/ELFObjectFile.cpp +++ b/llvm/lib/Object/ELFObjectFile.cpp @@ -440,7 +440,7 @@ TheTriple.setArchName(Triple); } -std::vector> +std::vector, uint64_t>> ELFObjectFileBase::getPltAddresses() const { std::string Err; const auto Triple = makeTriple(); @@ -498,14 +498,18 @@ 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> Result; + std::vector, 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 --- 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 @@ Info: .got.plt Relocations: - Offset: 0x0000000000230018 - Symbol: f1 + Symbol: [[SYM=f1]] Type: R_AARCH64_JUMP_SLOT - Offset: 0x0000000000230020 Symbol: f2 @@ -52,6 +65,7 @@ Content: '000000000000000000000000000000000000000000000000100021000000000010002100000000001000210000000000' Symbols: - Name: f1 + StName: [[ST_NAME=]] 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 --- a/llvm/test/tools/llvm-objdump/MachO/malformed-machos.test +++ b/llvm/test/tools/llvm-objdump/MachO/malformed-machos.test @@ -55,7 +55,7 @@ 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 --- a/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp +++ b/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp @@ -568,7 +568,9 @@ } if (auto *ElfObject = dyn_cast(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 --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -1394,13 +1394,23 @@ return; if (auto *ElfObj = dyn_cast(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 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 @@ const StringRef FileName = Obj->getFileName(); const MachOObjectFile *MachO = dyn_cast(Obj); for (const SymbolRef &Symbol : Obj->symbols()) { - StringRef Name = unwrapOrError(Symbol.getName(), FileName); - if (Name.empty() && !(Obj->isXCOFF() && SymbolDescription)) + Expected 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)