aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools/llvm-objdump/llvm-objdump.cpp
diff options
context:
space:
mode:
authorEmma Pilkington <emma.pilkington95@gmail.com>2024-04-18 13:44:22 -0400
committerGitHub <noreply@github.com>2024-04-18 13:44:22 -0400
commit68e814d9114b6c8910642298714dad6fa79ccad2 (patch)
treecd772f143b4332dc1cf8bba508247599f5ca3eb9 /llvm/tools/llvm-objdump/llvm-objdump.cpp
parente9654880df9b30af11816782a83ebf960536309c (diff)
downloadllvm-68e814d9114b6c8910642298714dad6fa79ccad2.zip
llvm-68e814d9114b6c8910642298714dad6fa79ccad2.tar.gz
llvm-68e814d9114b6c8910642298714dad6fa79ccad2.tar.bz2
[AMDGPU] Add disassembler diagnostics for invalid kernel descriptors (#87400)
These mostly are checking for various reserved bits being set. The diagnostics for gpu-dependent reserved bits have a bit more context since they seem like the most likely ones to be observed in practice. This commit also improves the error handling mechanism for MCDisassembler::onSymbolStart(). Previously it had a comment stream parameter that was just being ignored by llvm-objdump, now it returns errors using Expected<T>.
Diffstat (limited to 'llvm/tools/llvm-objdump/llvm-objdump.cpp')
-rw-r--r--llvm/tools/llvm-objdump/llvm-objdump.cpp65
1 files changed, 35 insertions, 30 deletions
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index 9b65ea5..339822e 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -2051,41 +2051,46 @@ disassembleObject(ObjectFile &Obj, const ObjectFile &DbgObj,
for (size_t SHI = 0; SHI < SymbolsHere.size(); ++SHI) {
SymbolInfoTy Symbol = SymbolsHere[SHI];
- auto Status = DT->DisAsm->onSymbolStart(
- Symbol, Size, Bytes.slice(Start, End - Start), SectionAddr + Start,
- CommentStream);
-
- if (!Status) {
- // If onSymbolStart returns std::nullopt, that means it didn't trigger
- // any interesting handling for this symbol. Try the other symbols
- // defined at this address.
+ Expected<bool> RespondedOrErr = DT->DisAsm->onSymbolStart(
+ Symbol, Size, Bytes.slice(Start, End - Start), SectionAddr + Start);
+
+ if (RespondedOrErr && !*RespondedOrErr) {
+ // This symbol didn't trigger any interesting handling. Try the other
+ // symbols defined at this address.
continue;
}
- if (*Status == MCDisassembler::Fail) {
- // If onSymbolStart returns Fail, that means it identified some kind
- // of special data at this address, but wasn't able to disassemble it
- // meaningfully. So we fall back to disassembling the failed region
- // as bytes, assuming that the target detected the failure before
- // printing anything.
- //
- // Return values Success or SoftFail (i.e no 'real' failure) are
- // expected to mean that the target has emitted its own output.
- //
- // Either way, 'Size' will have been set to the amount of data
- // covered by whatever prologue the target identified. So we advance
- // our own position to beyond that. Sometimes that will be the entire
- // distance to the next symbol, and sometimes it will be just a
- // prologue and we should start disassembling instructions from where
- // it left off.
- outs() << DT->Context->getAsmInfo()->getCommentString()
- << " error in decoding " << SymNamesHere[SHI]
- << " : decoding failed region as bytes.\n";
- for (uint64_t I = 0; I < Size; ++I) {
- outs() << "\t.byte\t " << format_hex(Bytes[I], 1, /*Upper=*/true)
- << "\n";
+ // If onSymbolStart returned an Error, that means it identified some
+ // kind of special data at this address, but wasn't able to disassemble
+ // it meaningfully. So we fall back to printing the error out and
+ // disassembling the failed region as bytes, assuming that the target
+ // detected the failure before printing anything.
+ if (!RespondedOrErr) {
+ std::string ErrMsgStr = toString(RespondedOrErr.takeError());
+ StringRef ErrMsg = ErrMsgStr;
+ do {
+ StringRef Line;
+ std::tie(Line, ErrMsg) = ErrMsg.split('\n');
+ outs() << DT->Context->getAsmInfo()->getCommentString()
+ << " error decoding " << SymNamesHere[SHI] << ": " << Line
+ << '\n';
+ } while (!ErrMsg.empty());
+
+ if (Size) {
+ outs() << DT->Context->getAsmInfo()->getCommentString()
+ << " decoding failed region as bytes\n";
+ for (uint64_t I = 0; I < Size; ++I)
+ outs() << "\t.byte\t " << format_hex(Bytes[I], 1, /*Upper=*/true)
+ << '\n';
}
}
+
+ // Regardless of whether onSymbolStart returned an Error or true, 'Size'
+ // will have been set to the amount of data covered by whatever prologue
+ // the target identified. So we advance our own position to beyond that.
+ // Sometimes that will be the entire distance to the next symbol, and
+ // sometimes it will be just a prologue and we should start
+ // disassembling instructions from where it left off.
Start += Size;
break;
}