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
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to