[Lldb-commits] [lldb] Add the ability to get a C++ vtable ValueObject from another ValueObj… (PR #67599)
via lldb-commits
lldb-commits at lists.llvm.org
Wed Sep 27 14:41:12 PDT 2023
================
@@ -0,0 +1,325 @@
+//===-- ValueObjectVTable.cpp ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Core/ValueObjectVTable.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ValueObjectChild.h"
+#include "lldb/Symbol/Function.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private-enumerations.h"
+#include "clang/Tooling/Transformer/RangeSelector.h"
+#include "llvm/Support/MathExtras.h"
+#include <cstdint>
+
+using namespace lldb;
+using namespace lldb_private;
+
+class ValueObjectVTableChild : public ValueObject {
+public:
+ ValueObjectVTableChild(ValueObject &parent, uint32_t func_idx,
+ uint64_t addr_size)
+ : ValueObject(parent), m_func_idx(func_idx), m_addr_size(addr_size) {
+ SetFormat(eFormatPointer);
+ SetName(ConstString(llvm::formatv("[{0}]", func_idx).str()));
+ }
+
+ ~ValueObjectVTableChild() override = default;
+
+ std::optional<uint64_t> GetByteSize() override { return m_addr_size; };
+
+ size_t CalculateNumChildren(uint32_t max) override { return 0; };
+
+ ValueType GetValueType() const override { return eValueTypeVTableEntry; };
+
+ bool IsInScope() override {
+ ValueObject *parent = GetParent();
+ if (parent)
+ return parent->IsInScope();
+ return false;
+ };
+
+protected:
+ bool UpdateValue() override {
+ SetValueIsValid(false);
+ m_value.Clear();
+ ValueObject *parent = GetParent();
+ if (!parent) {
+ m_error.SetErrorString("no parent object");
+ return false;
+ }
+
+ addr_t parent_addr = parent->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+ if (parent_addr == LLDB_INVALID_ADDRESS) {
+ m_error.SetErrorString("parent has invalid address");
+ return false;
+ }
+
+ ProcessSP process_sp = GetProcessSP();
+ if (!process_sp) {
+ m_error.SetErrorString("no process");
+ return false;
+ }
+
+ TargetSP target_sp = GetTargetSP();
+ if (!target_sp) {
+ m_error.SetErrorString("no target");
+ return false;
+ }
+
+ // Each `vtable_entry_addr` points to the function pointer.
+ addr_t vtable_entry_addr = parent_addr + m_func_idx * m_addr_size;
+ addr_t vfunc_ptr =
+ process_sp->ReadPointerFromMemory(vtable_entry_addr, m_error);
+ if (m_error.Fail()) {
+ m_error.SetErrorStringWithFormat(
+ "failed to read virtual function entry 0x%16.16" PRIx64,
+ vtable_entry_addr);
+ return false;
+ }
+
+ Address resolved_vfunc_ptr_address;
+ target_sp->ResolveLoadAddress(vfunc_ptr, resolved_vfunc_ptr_address);
+ if (!resolved_vfunc_ptr_address.IsValid()) {
+ m_error.SetErrorStringWithFormat(
+ "unable to resolve func ptr address: 0x%16.16" PRIx64, vfunc_ptr);
+ return false;
+ }
+
+ // Set our value to be the load address of the function pointer in memory
+ // and our type to be the function pointer type.
+ m_value.SetValueType(Value::ValueType::LoadAddress);
+ m_value.GetScalar() = vtable_entry_addr;
+
+ // See if our resolved address points to a function in the debug info. If
+ // it does, then we can report the type as a function prototype for this
+ // function.
+ Function *function =
+ resolved_vfunc_ptr_address.CalculateSymbolContextFunction();
+ if (function) {
+ m_value.SetCompilerType(function->GetCompilerType());
+ } else {
+ // Set our value's compiler type to a generic function protoype so that
+ // it displays as a hex function pointer for the value and the summary
+ // will display the address description.
+ auto type_system_or_err =
----------------
jimingham wrote:
It's okay for now because we don't have any others, but there could be other languages that have the concept of a VTable, so at some point the eLanguageTypeC_plus_plus should get genericized...
https://github.com/llvm/llvm-project/pull/67599
More information about the lldb-commits
mailing list