[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
Thu Sep 28 16:55:58 PDT 2023


================
@@ -54,134 +54,182 @@ bool ItaniumABILanguageRuntime::CouldHaveDynamicValue(ValueObject &in_value) {
                                                           check_objc);
 }
 
-TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfoFromVTableAddress(
-    ValueObject &in_value, lldb::addr_t original_ptr,
-    lldb::addr_t vtable_load_addr) {
-  if (m_process && vtable_load_addr != LLDB_INVALID_ADDRESS) {
-    // Find the symbol that contains the "vtable_load_addr" address
-    Address vtable_addr;
-    Target &target = m_process->GetTarget();
-    if (!target.GetSectionLoadList().IsEmpty()) {
-      if (target.GetSectionLoadList().ResolveLoadAddress(vtable_load_addr,
-                                                         vtable_addr)) {
-        // See if we have cached info for this type already
-        TypeAndOrName type_info = GetDynamicTypeInfo(vtable_addr);
-        if (type_info)
-          return type_info;
-
-        SymbolContext sc;
-        target.GetImages().ResolveSymbolContextForAddress(
-            vtable_addr, eSymbolContextSymbol, sc);
-        Symbol *symbol = sc.symbol;
-        if (symbol != nullptr) {
-          const char *name =
-              symbol->GetMangled().GetDemangledName().AsCString();
-          if (name && strstr(name, vtable_demangled_prefix) == name) {
-            Log *log = GetLog(LLDBLog::Object);
-            LLDB_LOGF(log,
-                      "0x%16.16" PRIx64
-                      ": static-type = '%s' has vtable symbol '%s'\n",
-                      original_ptr, in_value.GetTypeName().GetCString(), name);
-            // We are a C++ class, that's good.  Get the class name and look it
-            // up:
-            const char *class_name = name + strlen(vtable_demangled_prefix);
-            // We know the class name is absolute, so tell FindTypes that by
-            // prefixing it with the root namespace:
-            std::string lookup_name("::");
-            lookup_name.append(class_name);
-            
-            type_info.SetName(class_name);
-            const bool exact_match = true;
-            TypeList class_types;
-
-            // First look in the module that the vtable symbol came from and
-            // look for a single exact match.
-            llvm::DenseSet<SymbolFile *> searched_symbol_files;
-            if (sc.module_sp)
-              sc.module_sp->FindTypes(ConstString(lookup_name), exact_match, 1,
+TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfo(
+    ValueObject &in_value, const VTableInfo &vtable_info) {
+  if (vtable_info.addr.IsSectionOffset()) {
+    // See if we have cached info for this type already
+    TypeAndOrName type_info = GetDynamicTypeInfo(vtable_info.addr);
+    if (type_info)
+      return type_info;
+
+    if (vtable_info.symbol) {
+      Log *log = GetLog(LLDBLog::Object);
+      llvm::StringRef symbol_name =
+          vtable_info.symbol->GetMangled().GetDemangledName().GetStringRef();
+      LLDB_LOGF(log,
+                "0x%16.16" PRIx64
+                ": static-type = '%s' has vtable symbol '%s'\n",
+                in_value.GetPointerValue(),
+                in_value.GetTypeName().GetCString(),
+                symbol_name.str().c_str());
+      // We are a C++ class, that's good.  Get the class name and look it
+      // up:
+      llvm::StringRef class_name = symbol_name;
+      class_name.consume_front(vtable_demangled_prefix);
+      // We know the class name is absolute, so tell FindTypes that by
+      // prefixing it with the root namespace:
+      std::string lookup_name("::");
+      lookup_name.append(class_name.data(), class_name.size());
+
+      type_info.SetName(class_name);
+      const bool exact_match = true;
+      TypeList class_types;
+
+      // First look in the module that the vtable symbol came from and
+      // look for a single exact match.
+      llvm::DenseSet<SymbolFile *> searched_symbol_files;
+      ModuleSP module_sp = vtable_info.symbol->CalculateSymbolContextModule();
+      if (module_sp)
+        module_sp->FindTypes(ConstString(lookup_name), exact_match, 1,
+                              searched_symbol_files, class_types);
+
+      // If we didn't find a symbol, then move on to the entire module
+      // list in the target and get as many unique matches as possible
+      Target &target = m_process->GetTarget();
+      if (class_types.Empty())
+        target.GetImages().FindTypes(nullptr, ConstString(lookup_name),
+                                      exact_match, UINT32_MAX,
                                       searched_symbol_files, class_types);
 
-            // If we didn't find a symbol, then move on to the entire module
-            // list in the target and get as many unique matches as possible
-            if (class_types.Empty())
-              target.GetImages().FindTypes(nullptr, ConstString(lookup_name),
-                                           exact_match, UINT32_MAX,
-                                           searched_symbol_files, class_types);
-
-            lldb::TypeSP type_sp;
-            if (class_types.Empty()) {
-              LLDB_LOGF(log, "0x%16.16" PRIx64 ": is not dynamic\n",
-                        original_ptr);
-              return TypeAndOrName();
+      lldb::TypeSP type_sp;
+      if (class_types.Empty()) {
+        LLDB_LOGF(log, "0x%16.16" PRIx64 ": is not dynamic\n",
+                  in_value.GetPointerValue());
+        return TypeAndOrName();
+      }
+      if (class_types.GetSize() == 1) {
+        type_sp = class_types.GetTypeAtIndex(0);
+        if (type_sp) {
+          if (TypeSystemClang::IsCXXClassType(
+                  type_sp->GetForwardCompilerType())) {
+            LLDB_LOGF(
+                log,
+                "0x%16.16" PRIx64
+                ": static-type = '%s' has dynamic type: uid={0x%" PRIx64
+                "}, type-name='%s'\n",
+                in_value.GetPointerValue(), in_value.GetTypeName().AsCString(),
+                type_sp->GetID(), type_sp->GetName().GetCString());
+            type_info.SetTypeSP(type_sp);
+          }
+        }
+      } else {
+        size_t i;
+        if (log) {
+          for (i = 0; i < class_types.GetSize(); i++) {
+            type_sp = class_types.GetTypeAtIndex(i);
+            if (type_sp) {
+              LLDB_LOGF(
+                  log,
+                  "0x%16.16" PRIx64
+                  ": static-type = '%s' has multiple matching dynamic "
+                  "types: uid={0x%" PRIx64 "}, type-name='%s'\n",
+                  in_value.GetPointerValue(),
+                  in_value.GetTypeName().AsCString(),
+                  type_sp->GetID(), type_sp->GetName().GetCString());
             }
-            if (class_types.GetSize() == 1) {
-              type_sp = class_types.GetTypeAtIndex(0);
-              if (type_sp) {
-                if (TypeSystemClang::IsCXXClassType(
-                        type_sp->GetForwardCompilerType())) {
-                  LLDB_LOGF(
-                      log,
-                      "0x%16.16" PRIx64
-                      ": static-type = '%s' has dynamic type: uid={0x%" PRIx64
-                      "}, type-name='%s'\n",
-                      original_ptr, in_value.GetTypeName().AsCString(),
-                      type_sp->GetID(), type_sp->GetName().GetCString());
-                  type_info.SetTypeSP(type_sp);
-                }
-              }
-            } else {
-              size_t i;
-              if (log) {
-                for (i = 0; i < class_types.GetSize(); i++) {
-                  type_sp = class_types.GetTypeAtIndex(i);
-                  if (type_sp) {
-                    LLDB_LOGF(
-                        log,
-                        "0x%16.16" PRIx64
-                        ": static-type = '%s' has multiple matching dynamic "
-                        "types: uid={0x%" PRIx64 "}, type-name='%s'\n",
-                        original_ptr, in_value.GetTypeName().AsCString(),
-                        type_sp->GetID(), type_sp->GetName().GetCString());
-                  }
-                }
-              }
-
-              for (i = 0; i < class_types.GetSize(); i++) {
-                type_sp = class_types.GetTypeAtIndex(i);
-                if (type_sp) {
-                  if (TypeSystemClang::IsCXXClassType(
-                          type_sp->GetForwardCompilerType())) {
-                    LLDB_LOGF(
-                        log,
-                        "0x%16.16" PRIx64 ": static-type = '%s' has multiple "
-                        "matching dynamic types, picking "
-                        "this one: uid={0x%" PRIx64 "}, type-name='%s'\n",
-                        original_ptr, in_value.GetTypeName().AsCString(),
-                        type_sp->GetID(), type_sp->GetName().GetCString());
-                    type_info.SetTypeSP(type_sp);
-                  }
-                }
-              }
-
-              if (log) {
-                LLDB_LOGF(log,
-                          "0x%16.16" PRIx64
-                          ": static-type = '%s' has multiple matching dynamic "
-                          "types, didn't find a C++ match\n",
-                          original_ptr, in_value.GetTypeName().AsCString());
-              }
+          }
+        }
+
+        for (i = 0; i < class_types.GetSize(); i++) {
+          type_sp = class_types.GetTypeAtIndex(i);
+          if (type_sp) {
+            if (TypeSystemClang::IsCXXClassType(
+                    type_sp->GetForwardCompilerType())) {
+              LLDB_LOGF(
+                  log,
+                  "0x%16.16" PRIx64 ": static-type = '%s' has multiple "
+                  "matching dynamic types, picking "
+                  "this one: uid={0x%" PRIx64 "}, type-name='%s'\n",
+                  in_value.GetPointerValue(),
+                  in_value.GetTypeName().AsCString(),
+                  type_sp->GetID(), type_sp->GetName().GetCString());
+              type_info.SetTypeSP(type_sp);
             }
-            if (type_info)
-              SetDynamicTypeInfo(vtable_addr, type_info);
-            return type_info;
           }
         }
+
+        if (log) {
+          LLDB_LOGF(log,
+                    "0x%16.16" PRIx64
+                    ": static-type = '%s' has multiple matching dynamic "
+                    "types, didn't find a C++ match\n",
+                    in_value.GetPointerValue(),
+                    in_value.GetTypeName().AsCString());
+        }
       }
+      if (type_info)
+        SetDynamicTypeInfo(vtable_info.addr, type_info);
+      return type_info;
     }
   }
   return TypeAndOrName();
 }
 
+// This function can accept both pointers or references to classes as well
+// as instances of classes. For dynamic type detection, only valid ValueObjects
+// that return true to CouldHaveDynamicValue(...) should call this function.
----------------
jimingham wrote:

Ah, I see.  That makes sense.  It might be clearer if instead of "For dynamic type detection" you said:

"If you are using this function to do dynamic type detection..."

https://github.com/llvm/llvm-project/pull/67599


More information about the lldb-commits mailing list