aprantl updated this revision to Diff 323488.
aprantl added a comment.
Herald added a subscriber: mgorny.
That took me a little to get right, but here you go! Mock process.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D96549/new/
https://reviews.llvm.org/D96549
Files:
lldb/source/Expression/DWARFExpression.cpp
lldb/unittests/Expression/CMakeLists.txt
lldb/unittests/Expression/DWARFExpressionTest.cpp
Index: lldb/unittests/Expression/DWARFExpressionTest.cpp
===================================================================
--- lldb/unittests/Expression/DWARFExpressionTest.cpp
+++ lldb/unittests/Expression/DWARFExpressionTest.cpp
@@ -7,11 +7,15 @@
//===----------------------------------------------------------------------===//
#include "lldb/Expression/DWARFExpression.h"
+#include "Plugins/Platform/Linux/PlatformLinux.h"
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "TestingSupport/Symbol/YAMLModuleTester.h"
#include "lldb/Core/Value.h"
+#include "lldb/Core/Debugger.h"
#include "lldb/Core/dwarf.h"
+#include "lldb/Host/HostInfo.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Utility/Reproducer.h"
#include "lldb/Utility/StreamString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Testing/Support/Error.h"
@@ -21,16 +25,17 @@
static llvm::Expected<Scalar> Evaluate(llvm::ArrayRef<uint8_t> expr,
lldb::ModuleSP module_sp = {},
- DWARFUnit *unit = nullptr) {
+ DWARFUnit *unit = nullptr,
+ ExecutionContext *exe_ctx = nullptr) {
DataExtractor extractor(expr.data(), expr.size(), lldb::eByteOrderLittle,
/*addr_size*/ 4);
Value result;
Status status;
- if (!DWARFExpression::Evaluate(
- /*exe_ctx*/ nullptr, /*reg_ctx*/ nullptr, module_sp, extractor, unit,
- lldb::eRegisterKindLLDB,
- /*initial_value_ptr*/ nullptr,
- /*object_address_ptr*/ nullptr, result, &status))
+ if (!DWARFExpression::Evaluate(exe_ctx, /*reg_ctx*/ nullptr, module_sp,
+ extractor, unit, lldb::eRegisterKindLLDB,
+ /*initial_value_ptr*/ nullptr,
+ /*object_address_ptr*/ nullptr, result,
+ &status))
return status.ToError();
switch (result.GetValueType()) {
@@ -66,6 +71,23 @@
return scalar;
}
+/// This is needed for the tests that use a mock process.
+class DWARFExpressionMockProcessTest : public ::testing::Test {
+public:
+ void SetUp() override {
+ llvm::cantFail(repro::Reproducer::Initialize(repro::ReproducerMode::Off, {}));
+ FileSystem::Initialize();
+ HostInfo::Initialize();
+ platform_linux::PlatformLinux::Initialize();
+ }
+ void TearDown() override {
+ platform_linux::PlatformLinux::Terminate();
+ HostInfo::Terminate();
+ FileSystem::Terminate();
+ repro::Reproducer::Terminate();
+ }
+};
+
TEST(DWARFExpression, DW_OP_pick) {
EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit1, DW_OP_lit0, DW_OP_pick, 0}),
llvm::HasValue(0));
@@ -277,6 +299,59 @@
"Unhandled opcode DW_OP_unknown_ff in DWARFExpression"));
}
-TEST(DWARFExpression, DW_OP_deref) {
+TEST_F(DWARFExpressionMockProcessTest, DW_OP_deref) {
EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit0, DW_OP_deref}), llvm::Failed());
+
+ struct MockProcess : Process {
+ using Process::Process;
+ ConstString GetPluginName() override { return ConstString("mock process"); }
+ uint32_t GetPluginVersion() override { return 0; }
+ bool CanDebug(lldb::TargetSP target,
+ bool plugin_specified_by_name) override {
+ return false;
+ };
+ Status DoDestroy() override { return {}; }
+ void RefreshStateAfterStop() override {}
+ bool DoUpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list) override {
+ return false;
+ };
+ size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
+ Status &error) override {
+ constexpr size_t bufsize = 512;
+ uint8_t memory[bufsize];
+ for (unsigned i = 0; i < bufsize; ++i)
+ memory[i] = i & 0xff;
+ if (vm_addr >= bufsize) {
+ error.SetErrorString("invalid address");
+ return 0;
+ }
+ size_t nbytes = (vm_addr + size < bufsize) ? size : (bufsize - vm_addr);
+ memcpy(buf, memory+vm_addr, nbytes);
+ error.Clear();
+ return nbytes;
+ }
+ };
+
+ // Set up a mock process.
+ ArchSpec arch("i386-pc-linux");
+ Platform::SetHostPlatform(
+ platform_linux::PlatformLinux::CreateInstance(true, &arch));
+ lldb::DebuggerSP debugger_sp = Debugger::CreateInstance();
+ ASSERT_TRUE(debugger_sp);
+ lldb::TargetSP target_sp;
+ lldb::PlatformSP platform_sp;
+ debugger_sp->GetTargetList().CreateTarget(
+ *debugger_sp, "", arch, eLoadDependentsNo, platform_sp, target_sp);
+ ASSERT_TRUE(target_sp);
+ ASSERT_TRUE(target_sp->GetArchitecture().IsValid());
+ ASSERT_TRUE(platform_sp);
+ lldb::ListenerSP listener_sp(Listener::MakeListener("dummy"));
+ lldb::ProcessSP process_sp =
+ std::make_shared<MockProcess>(target_sp, listener_sp);
+ ASSERT_TRUE(process_sp);
+
+ ExecutionContext exe_ctx(process_sp);
+ EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit4, DW_OP_deref}, {}, {}, &exe_ctx),
+ llvm::HasValue(GetScalar(32, 0x07060504, false)));
}
Index: lldb/unittests/Expression/CMakeLists.txt
===================================================================
--- lldb/unittests/Expression/CMakeLists.txt
+++ lldb/unittests/Expression/CMakeLists.txt
@@ -7,6 +7,8 @@
LINK_LIBS
lldbCore
+ lldbPluginObjectFileELF
+ lldbPluginPlatformLinux
lldbPluginExpressionParserClang
lldbPluginTypeSystemClang
lldbUtility
Index: lldb/source/Expression/DWARFExpression.cpp
===================================================================
--- lldb/source/Expression/DWARFExpression.cpp
+++ lldb/source/Expression/DWARFExpression.cpp
@@ -1067,6 +1067,7 @@
stack.back().SetValueType(Value::ValueType::LoadAddress);
// Fall through to load address code below...
} LLVM_FALLTHROUGH;
+ case Value::ValueType::Scalar:
case Value::ValueType::LoadAddress:
if (exe_ctx) {
if (process) {
@@ -1099,7 +1100,6 @@
}
break;
- case Value::ValueType::Scalar:
case Value::ValueType::Invalid:
if (error_ptr)
error_ptr->SetErrorString("Invalid value type for DW_OP_deref.\n");
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits