diff options
author | Michael Buch <michaelbuch12@gmail.com> | 2025-06-12 16:48:57 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-06-12 16:48:57 +0100 |
commit | 1c1df94d09820959c771cb4aaae4d36cdf5cab5a (patch) | |
tree | 5219c256c5a19549f887c0c22c8361debc5209ab /lldb/source/Commands/CommandObjectMemory.cpp | |
parent | 13fe07d670e8a115929c9e595c4490ef5c75f583 (diff) | |
download | llvm-1c1df94d09820959c771cb4aaae4d36cdf5cab5a.zip llvm-1c1df94d09820959c771cb4aaae4d36cdf5cab5a.tar.gz llvm-1c1df94d09820959c771cb4aaae4d36cdf5cab5a.tar.bz2 |
[lldb][Commands][NFC] Extract memory find expression evaluation into helpers (#143686)
This patch factors out the `-e` option logic into two helper functions.
The `EvaluateExpression` helper might seem redundant but I'll be adding
to it in a follow-up patch to fix an issue when running `memory find -e`
for Swift targets.
Also adds test coverage for the error cases that were previously
untested.
rdar://152113525
Diffstat (limited to 'lldb/source/Commands/CommandObjectMemory.cpp')
-rw-r--r-- | lldb/source/Commands/CommandObjectMemory.cpp | 101 |
1 files changed, 58 insertions, 43 deletions
diff --git a/lldb/source/Commands/CommandObjectMemory.cpp b/lldb/source/Commands/CommandObjectMemory.cpp index 7140333..85ae9f8 100644 --- a/lldb/source/Commands/CommandObjectMemory.cpp +++ b/lldb/source/Commands/CommandObjectMemory.cpp @@ -885,6 +885,52 @@ protected: #define LLDB_OPTIONS_memory_find #include "CommandOptions.inc" +static llvm::Error CopyExpressionResult(ValueObject &result, + DataBufferHeap &buffer) { + uint64_t value = result.GetValueAsUnsigned(0); + auto size_or_err = result.GetCompilerType().GetByteSize(nullptr); + if (!size_or_err) + return size_or_err.takeError(); + + switch (*size_or_err) { + case 1: { + uint8_t byte = (uint8_t)value; + buffer.CopyData(&byte, 1); + } break; + case 2: { + uint16_t word = (uint16_t)value; + buffer.CopyData(&word, 2); + } break; + case 4: { + uint32_t lword = (uint32_t)value; + buffer.CopyData(&lword, 4); + } break; + case 8: { + buffer.CopyData(&value, 8); + } break; + default: + return llvm::createStringError( + "Only expressions resulting in 1, 2, 4, or 8-byte-sized values are " + "supported. For other pattern sizes the --string (-s) option may be " + "used."); + } + + return llvm::Error::success(); +} + +static llvm::Expected<ValueObjectSP> +EvaluateExpression(llvm::StringRef expression, StackFrame &frame, + Process &process) { + ValueObjectSP result_sp; + auto status = + process.GetTarget().EvaluateExpression(expression, &frame, result_sp); + if (status != eExpressionCompleted || !result_sp) + return llvm::createStringError( + "expression evaluation failed. pass a string instead"); + + return result_sp; +} + // Find the specified data in memory class CommandObjectMemoryFind : public CommandObjectParsed { public: @@ -1026,49 +1072,18 @@ protected: } buffer.CopyData(str); } else if (m_memory_options.m_expr.OptionWasSet()) { - StackFrame *frame = m_exe_ctx.GetFramePtr(); - ValueObjectSP result_sp; - if ((eExpressionCompleted == - process->GetTarget().EvaluateExpression( - m_memory_options.m_expr.GetValueAs<llvm::StringRef>().value_or( - ""), - frame, result_sp)) && - result_sp) { - uint64_t value = result_sp->GetValueAsUnsigned(0); - std::optional<uint64_t> size = llvm::expectedToOptional( - result_sp->GetCompilerType().GetByteSize(nullptr)); - if (!size) - return; - switch (*size) { - case 1: { - uint8_t byte = (uint8_t)value; - buffer.CopyData(&byte, 1); - } break; - case 2: { - uint16_t word = (uint16_t)value; - buffer.CopyData(&word, 2); - } break; - case 4: { - uint32_t lword = (uint32_t)value; - buffer.CopyData(&lword, 4); - } break; - case 8: { - buffer.CopyData(&value, 8); - } break; - case 3: - case 5: - case 6: - case 7: - result.AppendError("unknown type. pass a string instead"); - return; - default: - result.AppendError( - "result size larger than 8 bytes. pass a string instead"); - return; - } - } else { - result.AppendError( - "expression evaluation failed. pass a string instead"); + auto result_or_err = EvaluateExpression( + m_memory_options.m_expr.GetValueAs<llvm::StringRef>().value_or(""), + m_exe_ctx.GetFrameRef(), *process); + if (!result_or_err) { + result.AppendError(llvm::toString(result_or_err.takeError())); + return; + } + + ValueObjectSP result_sp = *result_or_err; + + if (auto err = CopyExpressionResult(*result_sp, buffer)) { + result.AppendError(llvm::toString(std::move(err))); return; } } else { |