llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lldb

Author: Thrrreeee (Thrrreeee)

<details>
<summary>Changes</summary>

This patch adds LLDB support for DW_OP_implicit_pointer / 
DW_OP_GNU_implicit_pointer.
It extends DWARFExpression to evaluate these opcodes and preserve the 
referenced DIE offset plus byte offset in Value. The implicit pointer is then 
resolved on demand through SymbolFileDWARF, allowing LLDB to correctly 
dereference such values and access their members.

---

Patch is 32.27 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/203182.diff


11 Files Affected:

- (modified) lldb/include/lldb/Core/Value.h (+18) 
- (modified) lldb/include/lldb/Expression/DWARFExpression.h (+1) 
- (modified) lldb/include/lldb/Symbol/SymbolFile.h (+25-20) 
- (modified) lldb/source/Core/Value.cpp (+6-1) 
- (modified) lldb/source/Expression/DWARFExpression.cpp (+37-10) 
- (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h (+3) 
- (modified) lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (+61-1) 
- (modified) lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h (+6) 
- (modified) lldb/source/ValueObject/ValueObject.cpp (+48) 
- (added) lldb/test/Shell/SymbolFile/DWARF/x86/DW_OP_implicit_pointer.s (+243) 
- (modified) lldb/unittests/Expression/DWARFExpressionTest.cpp (+35-12) 


``````````diff
diff --git a/lldb/include/lldb/Core/Value.h b/lldb/include/lldb/Core/Value.h
index 3714621b469ec..2f4f7a3d23cb2 100644
--- a/lldb/include/lldb/Core/Value.h
+++ b/lldb/include/lldb/Core/Value.h
@@ -19,6 +19,7 @@
 
 #include "llvm/ADT/APInt.h"
 
+#include <optional>
 #include <vector>
 
 #include <cstdint>
@@ -37,6 +38,11 @@ namespace lldb_private {
 
 class Value {
 public:
+  struct ImplicitPointerInfo {
+    uint64_t die_offset = 0;
+    int64_t byte_offset = 0;
+  };
+
   /// Type that describes Value::m_value.
   enum class ValueType {
     Invalid = -1,
@@ -93,6 +99,17 @@ class Value {
     m_context_type = ContextType::Invalid;
   }
 
+  bool IsImplicitPointer() const { return m_implicit_pointer_info.has_value(); 
}
+
+  ImplicitPointerInfo GetImplicitPointerInfo() const {
+    return *m_implicit_pointer_info;
+  }
+
+  void SetImplicitPointer(ImplicitPointerInfo implicit_pointer) {
+    m_implicit_pointer_info = implicit_pointer;
+    m_value_type = ValueType::Invalid;
+  }
+
   void SetContext(ContextType context_type, void *p) {
     m_context_type = context_type;
     m_context = p;
@@ -182,6 +199,7 @@ class Value {
   ValueType m_value_type = ValueType::Scalar;
   ContextType m_context_type = ContextType::Invalid;
   DataBufferHeap m_data_buffer;
+  std::optional<ImplicitPointerInfo> m_implicit_pointer_info;
 };
 
 class ValueList {
diff --git a/lldb/include/lldb/Expression/DWARFExpression.h 
b/lldb/include/lldb/Expression/DWARFExpression.h
index b1895690985a7..38e4fb5c34c57 100644
--- a/lldb/include/lldb/Expression/DWARFExpression.h
+++ b/lldb/include/lldb/Expression/DWARFExpression.h
@@ -44,6 +44,7 @@ class DWARFExpression {
 
     virtual uint16_t GetVersion() const = 0;
     virtual dw_addr_t GetBaseAddress() const = 0;
+    virtual llvm::dwarf::DwarfFormat GetDwarfFormat() const = 0;
     virtual uint8_t GetAddressByteSize() const = 0;
     virtual llvm::Expected<std::pair<uint64_t, bool>>
     GetDIEBitSizeAndSign(uint64_t relative_die_offset) const = 0;
diff --git a/lldb/include/lldb/Symbol/SymbolFile.h 
b/lldb/include/lldb/Symbol/SymbolFile.h
index ae6504c016d7b..a62af4a406503 100644
--- a/lldb/include/lldb/Symbol/SymbolFile.h
+++ b/lldb/include/lldb/Symbol/SymbolFile.h
@@ -207,6 +207,11 @@ class SymbolFile : public PluginInterface {
                        std::vector<SourceModule> &imported_modules) = 0;
   virtual size_t ParseBlocksRecursive(Function &func) = 0;
   virtual size_t ParseVariablesForContext(const SymbolContext &sc) = 0;
+  virtual lldb::ValueObjectSP ResolveImplicitPointer(
+      uint64_t die_offset, int64_t byte_offset, CompilerType pointee_type,
+      ExecutionContextScope *exe_scope, Variable *context_var) {
+    return {};
+  }
   virtual Type *ResolveTypeUID(lldb::user_id_t type_uid) = 0;
 
   /// The characteristics of an array type.
@@ -516,14 +521,15 @@ class SymbolFile : public PluginInterface {
     return {};
   }
 
-  virtual lldb::TypeSP
-  MakeType(lldb::user_id_t uid, ConstString name,
-           std::optional<uint64_t> byte_size, SymbolContextScope *context,
-           lldb::user_id_t encoding_uid,
-           Type::EncodingDataType encoding_uid_type, const Declaration &decl,
-           const CompilerType &compiler_qual_type,
-           Type::ResolveState compiler_type_resolve_state,
-           uint32_t opaque_payload = 0) = 0;
+  virtual lldb::TypeSP MakeType(lldb::user_id_t uid, ConstString name,
+                                std::optional<uint64_t> byte_size,
+                                SymbolContextScope *context,
+                                lldb::user_id_t encoding_uid,
+                                Type::EncodingDataType encoding_uid_type,
+                                const Declaration &decl,
+                                const CompilerType &compiler_qual_type,
+                                Type::ResolveState compiler_type_resolve_state,
+                                uint32_t opaque_payload = 0) = 0;
 
   virtual lldb::TypeSP CopyType(const lldb::TypeSP &other_type) = 0;
 
@@ -617,7 +623,7 @@ class SymbolFileCommon : public SymbolFile {
     return m_debug_info_had_variable_errors;
   }
   void SetDebugInfoHadFrameVariableErrors() override {
-     m_debug_info_had_variable_errors = true;
+    m_debug_info_had_variable_errors = true;
   }
 
   /// This function is used to create types that belong to a SymbolFile. The
@@ -632,21 +638,20 @@ class SymbolFileCommon : public SymbolFile {
                         const CompilerType &compiler_qual_type,
                         Type::ResolveState compiler_type_resolve_state,
                         uint32_t opaque_payload = 0) override {
-     lldb::TypeSP type_sp (new Type(
-         uid, this, name, byte_size, context, encoding_uid,
-         encoding_uid_type, decl, compiler_qual_type,
-         compiler_type_resolve_state, opaque_payload));
-     m_type_list.Insert(type_sp);
-     return type_sp;
+    lldb::TypeSP type_sp(new Type(
+        uid, this, name, byte_size, context, encoding_uid, encoding_uid_type,
+        decl, compiler_qual_type, compiler_type_resolve_state, 
opaque_payload));
+    m_type_list.Insert(type_sp);
+    return type_sp;
   }
 
   lldb::TypeSP CopyType(const lldb::TypeSP &other_type) override {
-     // Make sure the real symbol file matches when copying types.
-     if (GetBackingSymbolFile() != other_type->GetSymbolFile())
+    // Make sure the real symbol file matches when copying types.
+    if (GetBackingSymbolFile() != other_type->GetSymbolFile())
       return lldb::TypeSP();
-     lldb::TypeSP type_sp(new Type(*other_type));
-     m_type_list.Insert(type_sp);
-     return type_sp;
+    lldb::TypeSP type_sp(new Type(*other_type));
+    m_type_list.Insert(type_sp);
+    return type_sp;
   }
 
 protected:
diff --git a/lldb/source/Core/Value.cpp b/lldb/source/Core/Value.cpp
index f9e65d397f05f..e9b57efcfe066 100644
--- a/lldb/source/Core/Value.cpp
+++ b/lldb/source/Core/Value.cpp
@@ -55,7 +55,8 @@ Value::Value(const void *bytes, int len)
 Value::Value(const Value &v)
     : m_value(v.m_value), m_compiler_type(v.m_compiler_type),
       m_context(v.m_context), m_value_type(v.m_value_type),
-      m_context_type(v.m_context_type), m_data_buffer() {
+      m_context_type(v.m_context_type), m_data_buffer(),
+      m_implicit_pointer_info(v.m_implicit_pointer_info) {
   const uintptr_t rhs_value =
       (uintptr_t)v.m_value.ULongLong(LLDB_INVALID_ADDRESS);
   if ((rhs_value != 0) &&
@@ -74,6 +75,7 @@ Value &Value::operator=(const Value &rhs) {
     m_context = rhs.m_context;
     m_value_type = rhs.m_value_type;
     m_context_type = rhs.m_context_type;
+    m_implicit_pointer_info = rhs.m_implicit_pointer_info;
     const uintptr_t rhs_value =
         (uintptr_t)rhs.m_value.ULongLong(LLDB_INVALID_ADDRESS);
     if ((rhs_value != 0) &&
@@ -89,12 +91,14 @@ Value &Value::operator=(const Value &rhs) {
 
 void Value::SetBytes(const void *bytes, int len) {
   m_value_type = ValueType::HostAddress;
+  m_implicit_pointer_info.reset();
   m_data_buffer.CopyData(bytes, len);
   m_value = (uintptr_t)m_data_buffer.GetBytes();
 }
 
 void Value::AppendBytes(const void *bytes, int len) {
   m_value_type = ValueType::HostAddress;
+  m_implicit_pointer_info.reset();
   m_data_buffer.AppendData(bytes, len);
   m_value = (uintptr_t)m_data_buffer.GetBytes();
 }
@@ -639,6 +643,7 @@ void Value::Clear() {
   m_value_type = ValueType::Scalar;
   m_context = nullptr;
   m_context_type = ContextType::Invalid;
+  m_implicit_pointer_info.reset();
   m_data_buffer.Clear();
 }
 
diff --git a/lldb/source/Expression/DWARFExpression.cpp 
b/lldb/source/Expression/DWARFExpression.cpp
index dd436e0c8afd9..519716b5041ab 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -219,7 +219,6 @@ GetOpcodeDataSize(const DataExtractor &data, const 
lldb::offset_t data_offset,
   case DW_OP_APPLE_uninit:
   case DW_OP_PGI_omp_thread_num:
   case DW_OP_hi_user:
-  case DW_OP_GNU_implicit_pointer:
     break;
 
   case DW_OP_addr:
@@ -419,12 +418,14 @@ GetOpcodeDataSize(const DataExtractor &data, const 
lldb::offset_t data_offset,
     return offset - data_offset;
   }
 
-  case DW_OP_implicit_pointer: // 0xa0 4-byte (or 8-byte for DWARF 64) constant
-                               // + LEB128
+  case DW_OP_implicit_pointer: // 0xa0 4-byte (or 8-byte for DWARF64) DIE 
offset
+  case DW_OP_GNU_implicit_pointer: // 0xf2 4-byte (or 8-byte for DWARF64) DIE
+                                   // offset followed by SLEB128 byte offset.
   {
+    DwarfFormat format = dwarf_cu ? dwarf_cu->GetDwarfFormat() : DWARF32;
+    offset += getDwarfOffsetByteSize(format);
     data.Skip_LEB128(&offset);
-    return (dwarf_cu ? dwarf_cu->GetAddressByteSize() : 4) + offset -
-           data_offset;
+    return offset - data_offset;
   }
 
   case DW_OP_GNU_entry_value:
@@ -943,6 +944,9 @@ static llvm::Error Evaluate_DW_OP_deref(EvalContext 
&eval_ctx,
   // Deref a register or implicit location and truncate the value to `size`
   // bytes. See the corresponding comment in DW_OP_deref for more details on
   // why we deref these locations this way.
+  if (eval_ctx.stack.back().IsImplicitPointer())
+    return llvm::createStringError("cannot dereference an implicit pointer");
+
   if (eval_ctx.loc_desc_kind == Register ||
       eval_ctx.loc_desc_kind == Implicit) {
     // Reset context to default values.
@@ -1077,6 +1081,10 @@ static llvm::Error Evaluate_DW_OP_piece(EvalContext 
&eval_ctx,
   if (piece_byte_size == 0)
     return llvm::Error::success();
 
+  if (eval_ctx.pieces.IsImplicitPointer())
+    return llvm::createStringError(
+        "DW_OP_piece cannot combine DW_OP_implicit_pointer with other pieces");
+
   Value curr_piece;
 
   if (eval_ctx.stack.empty()) {
@@ -1100,6 +1108,16 @@ static llvm::Error Evaluate_DW_OP_piece(EvalContext 
&eval_ctx,
     UpdateValueTypeFromLocationDescription(eval_ctx, piece_locdesc,
                                            &curr_piece_source_value);
 
+    if (curr_piece_source_value.IsImplicitPointer()) {
+      if (eval_ctx.pieces.GetBuffer().GetByteSize() != 0)
+        return llvm::createStringError(
+            "DW_OP_piece cannot combine DW_OP_implicit_pointer with other "
+            "pieces");
+      eval_ctx.pieces = curr_piece_source_value;
+      eval_ctx.op_piece_offset += piece_byte_size;
+      return llvm::Error::success();
+    }
+
     const Value::ValueType curr_piece_source_value_type =
         curr_piece_source_value.GetValueType();
     Scalar &scalar = curr_piece_source_value.GetScalar();
@@ -1299,7 +1317,9 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
     const Value *object_address_ptr) {
   uint32_t address_size = opcodes.GetAddressByteSize();
   llvm::DataExtractor expr_data = opcodes.GetAsLLVM();
-  llvm::DWARFExpression expr(expr_data, address_size);
+  std::optional<DwarfFormat> dwarf_format =
+      dwarf_cu ? dwarf_cu->GetDwarfFormat() : DWARF32;
+  llvm::DWARFExpression expr(expr_data, address_size, dwarf_format);
 
   if (expr_data.size() == 0)
     return llvm::createStringError(
@@ -1853,10 +1873,16 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
       break;
     }
 
-    case DW_OP_implicit_pointer: {
+    case DW_OP_implicit_pointer:
+    case DW_OP_GNU_implicit_pointer: {
       eval_ctx.loc_desc_kind = Implicit;
-      return llvm::createStringError("could not evaluate %s",
-                                     DW_OP_value_to_name(opcode));
+      uint64_t die_offset = op->getRawOperand(0);
+      int64_t byte_offset = static_cast<int64_t>(op->getRawOperand(1));
+
+      Value result;
+      result.SetImplicitPointer({die_offset, byte_offset});
+      stack.push_back(result);
+      break;
     }
 
     case DW_OP_push_object_address:
@@ -1981,7 +2007,8 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
   if (stack.empty()) {
     // Nothing on the stack, check if we created a piece value from DW_OP_piece
     // or DW_OP_bit_piece opcodes
-    if (eval_ctx.pieces.GetBuffer().GetByteSize())
+    if (eval_ctx.pieces.GetBuffer().GetByteSize() ||
+        eval_ctx.pieces.IsImplicitPointer())
       return eval_ctx.pieces;
 
     return llvm::createStringError("stack empty after evaluation");
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
index 6fde9af57fa8b..c02060a622ada 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -122,6 +122,9 @@ class DWARFUnit : public DWARFExpression::Delegate, public 
UserID {
   const llvm::dwarf::FormParams &GetFormParams() const {
     return m_header.getFormParams();
   }
+  llvm::dwarf::DwarfFormat GetDwarfFormat() const override {
+    return m_header.getFormat();
+  }
   const llvm::DWARFAbbreviationDeclarationSet *GetAbbreviations() const;
   dw_offset_t GetAbbrevOffset() const;
   uint8_t GetAddressByteSize() const override {
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index c81fd1c83be85..afc1272256746 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -60,7 +60,10 @@
 #include "lldb/Symbol/TypeMap.h"
 #include "lldb/Symbol/TypeSystem.h"
 #include "lldb/Symbol/VariableList.h"
+#include "lldb/ValueObject/ValueObjectConstResult.h"
+#include "lldb/ValueObject/ValueObjectVariable.h"
 
+#include "lldb/Target/ExecutionContextScope.h"
 #include "lldb/Target/Language.h"
 #include "lldb/Target/Target.h"
 
@@ -89,6 +92,7 @@
 #include "llvm/Support/FormatVariadic.h"
 
 #include <algorithm>
+#include <cstdint>
 #include <map>
 #include <memory>
 #include <optional>
@@ -96,7 +100,7 @@
 #include <cctype>
 #include <cstring>
 
-//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
+// #define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
 
 #ifdef ENABLE_DEBUG_PRINTF
 #include <cstdio>
@@ -3443,6 +3447,62 @@ size_t SymbolFileDWARF::ParseVariablesForContext(const 
SymbolContext &sc) {
   return 0;
 }
 
+lldb::ValueObjectSP SymbolFileDWARF::ResolveImplicitPointer(
+    uint64_t die_offset, int64_t byte_offset, CompilerType pointee_type,
+    ExecutionContextScope *exe_scope, Variable *context_var) {
+  if (!pointee_type || !exe_scope)
+    return nullptr;
+
+  SymbolContext sc;
+  if (context_var)
+    context_var->CalculateSymbolContext(&sc);
+  if (!sc.comp_unit)
+    if (StackFrameSP frame_sp = exe_scope->CalculateStackFrame())
+      sc = frame_sp->GetSymbolContext(eSymbolContextCompUnit |
+                                      eSymbolContextFunction |
+                                      eSymbolContextBlock);
+
+  DWARFDIE target_die =
+      DebugInfo().GetDIE(DIERef::Section::DebugInfo, die_offset);
+  if (!target_die)
+    return nullptr;
+
+  if (!sc.comp_unit) {
+    if (DWARFUnit *dwarf_cu = target_die.GetCU())
+      if (auto *compile_unit = llvm::dyn_cast<DWARFCompileUnit>(dwarf_cu))
+        sc.comp_unit = GetCompUnitForDWARFCompUnit(*compile_unit);
+  }
+
+  VariableSP target_var_sp = ParseVariableDIECached(sc, target_die);
+  if (!target_var_sp)
+    return nullptr;
+
+  ValueObjectSP target_valobj_sp =
+      ValueObjectVariable::Create(exe_scope, target_var_sp);
+  if (!target_valobj_sp || !target_valobj_sp->UpdateValueIfNeeded(false))
+    return nullptr;
+
+  DataExtractor target_data;
+  Status target_error;
+  target_valobj_sp->GetData(target_data, target_error);
+  if (target_error.Fail() || target_data.GetByteSize() == 0)
+    return nullptr;
+
+  if (byte_offset < 0 ||
+      static_cast<uint64_t>(byte_offset) > target_data.GetByteSize())
+    return nullptr;
+
+  lldb::offset_t data_offset = byte_offset;
+  lldb::offset_t data_size = target_data.GetByteSize() - data_offset;
+  if (auto type_size =
+          llvm::expectedToOptional(pointee_type.GetByteSize(exe_scope)))
+    data_size = std::min<lldb::offset_t>(data_size, *type_size);
+
+  DataExtractor pointee_data(target_data, data_offset, data_size);
+  return ValueObjectConstResult::Create(exe_scope, pointee_type, ConstString(),
+                                        pointee_data, LLDB_INVALID_ADDRESS);
+}
+
 VariableSP SymbolFileDWARF::ParseVariableDIECached(const SymbolContext &sc,
                                                    const DWARFDIE &die) {
   if (!die)
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h 
b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index 21a190d1b38f0..7f19142c42575 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -136,6 +136,12 @@ class SymbolFileDWARF : public SymbolFileCommon {
 
   size_t ParseVariablesForContext(const SymbolContext &sc) override;
 
+  lldb::ValueObjectSP ResolveImplicitPointer(uint64_t die_offset,
+                                             int64_t byte_offset,
+                                             CompilerType pointee_type,
+                                             ExecutionContextScope *exe_scope,
+                                             Variable *context_var) override;
+
   std::optional<ArrayInfo>
   GetDynamicArrayInfoForUID(lldb::user_id_t type_uid,
                             const ExecutionContext *exe_ctx) override;
diff --git a/lldb/source/ValueObject/ValueObject.cpp 
b/lldb/source/ValueObject/ValueObject.cpp
index 32332c2962e87..eff9d9bada125 100644
--- a/lldb/source/ValueObject/ValueObject.cpp
+++ b/lldb/source/ValueObject/ValueObject.cpp
@@ -23,6 +23,7 @@
 #include "lldb/Symbol/CompileUnit.h"
 #include "lldb/Symbol/CompilerType.h"
 #include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Symbol/SymbolFile.h"
 #include "lldb/Symbol/Type.h"
 #include "lldb/Symbol/Variable.h"
 #include "lldb/Target/ABI.h"
@@ -2393,6 +2394,18 @@ ValueObjectSP 
ValueObject::GetValueForExpressionPath_Impl(
         *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
         return ValueObjectSP();
       }
+      root->UpdateValueIfNeeded(false);
+      if (root->GetValue().IsImplicitPointer()) {
+        Status error;
+        root = DereferenceValueOrAlternate(
+            *root, options.m_synthetic_children_traversal, error);
+        if (error.Fail() || !root) {
+          *reason_to_stop =
+              ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
+          *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
+          return ValueObjectSP();
+        }
+      }
     }
       [[fallthrough]];
     case '.': // or fallthrough from ->
@@ -2817,6 +2830,41 @@ ValueObjectSP ValueObject::Dereference(Status &error) {
   if (m_deref_valobj)
     return m_deref_valobj->GetSP();
 
+  UpdateValueIfNeeded(false);
+  if (m_value.IsImplicitPointer()) {
+    CompilerType pointee_type = GetCompilerType().GetPointeeType();
+    if (!pointee_type) {
+      error = Status::FromErrorString("implicit pointer has no pointee type");
+      return ValueObjectSP();
+    }
+
+    ModuleSP module_sp = GetModule();
+    SymbolFile *symbol_file = module_sp ? module_sp->GetSymbolFile() : nullptr;
+    if (!symbol_file) {
+      error = Status::FromErrorString(
+          "cannot resolve DW_OP_implicit_pointer without symbol file");
+      return ValueObjectSP();
+    }
+
+    ExecutionContext exe_ctx(GetExecutionContextRef());
+    Value::ImplicitPointerInfo implicit_pointer =
+        m_value.GetImplicitPointerInfo();
+    ValueObjectSP result_sp =
+        symbol_file->GetBackingSymbolFile()->ResolveImplicitPointer(
+            implicit_pointer.die_offset, implicit_pointer.byte_offset,
+            pointee_type, exe_ctx.GetBestExecutionContextScope(),
+            GetVariable().get());
+    if (!result_sp) {
+      error = Status::FromErrorStringWithFormat(
+          "cannot resolve DW_OP_implicit_pointer target DIE 0x%" PRIx64,
+          implicit_pointer.die_offset);
+      return ValueObjectSP();
+    }
+
+    error.Clear();
+    return result_sp;
+  }
+
   std::string deref_name_str;
   uint32_t deref_byte_size = 0;
   int32_t deref_byte_offset = 0;
diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/DW_OP_implicit_pointer.s 
b/lldb/test/Shell/SymbolFile/DWARF/x86/DW_OP_implicit_pointer.s
new file mode 100644
index 0000000000000..1e4dc45733775
--- /dev/null
+++ b/lldb/test/Shell/SymbolFile/DWARF/x86/DW_OP_implic...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/203182
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to