22
22
#include " lldb/Symbol/Variable.h"
23
23
#include " lldb/Symbol/VariableList.h"
24
24
#include " lldb/Target/ProcessStructReader.h"
25
+ #include " lldb/Target/SectionLoadList.h"
25
26
#include " lldb/Target/Target.h"
26
27
#include " lldb/Utility/LLDBLog.h"
27
28
#include " lldb/Utility/Log.h"
39
40
#include " swift/Remote/MemoryReader.h"
40
41
#include " swift/RemoteAST/RemoteAST.h"
41
42
#include " swift/Runtime/Metadata.h"
43
+ #include " swift/Strings.h"
42
44
43
45
#include < sstream>
44
46
@@ -2941,6 +2943,80 @@ SwiftLanguageRuntimeImpl::GetValueType(ValueObject &in_value,
2941
2943
return Value::ValueType::Scalar;
2942
2944
}
2943
2945
2946
+ namespace {
2947
+ struct SwiftNominalType {
2948
+ std::string module ;
2949
+ std::string identifier;
2950
+ };
2951
+
2952
+ // Find the Swift class that backs an ObjC type.
2953
+ //
2954
+ // A Swift class that uses the @objc(<ClassName>) attribute will emit ObjC
2955
+ // metadata into the binary. Typically, ObjC classes have a symbol in the form
2956
+ // of OBJC_CLASS_$_<ClassName>, however for Swift classes, there are two symbols
2957
+ // that both point to the ObjC class metadata, where the second symbol is a
2958
+ // Swift mangled name.
2959
+ std::optional<SwiftNominalType> GetSwiftClass (ValueObject &valobj,
2960
+ AppleObjCRuntime &objc_runtime) {
2961
+ // To find the Swift symbol, the following preparation steps are taken:
2962
+ // 1. Get the value's ISA pointer
2963
+ // 2. Resolve the ISA load address into an Address instance
2964
+ // 3. Get the Module that contains the Address
2965
+ auto descriptor_sp = objc_runtime.GetClassDescriptor (valobj);
2966
+ if (!descriptor_sp)
2967
+ return {};
2968
+
2969
+ auto isa_load_addr = descriptor_sp->GetISA ();
2970
+ Address isa;
2971
+ const auto §ions = objc_runtime.GetTargetRef ().GetSectionLoadList ();
2972
+ if (!sections.ResolveLoadAddress (isa_load_addr, isa))
2973
+ return {};
2974
+
2975
+ // Next, iterate over the Module's symbol table, looking for a symbol with
2976
+ // following criteria:
2977
+ // 1. The symbol address is the ISA address
2978
+ // 2. The symbol name is a Swift mangled name
2979
+ std::optional<StringRef> swift_symbol;
2980
+ auto find_swift_symbol_for_isa = [&](Symbol *symbol) {
2981
+ if (symbol->GetAddress () == isa) {
2982
+ StringRef symbol_name =
2983
+ symbol->GetMangled ().GetMangledName ().GetStringRef ();
2984
+ if (SwiftLanguageRuntime::IsSwiftMangledName (symbol_name)) {
2985
+ swift_symbol = symbol_name;
2986
+ return false ;
2987
+ }
2988
+ }
2989
+ return true ;
2990
+ };
2991
+
2992
+ isa.GetModule ()->GetSymtab ()->ForEachSymbolContainingFileAddress (
2993
+ isa.GetFileAddress (), find_swift_symbol_for_isa);
2994
+ if (!swift_symbol)
2995
+ return {};
2996
+
2997
+ // Once the Swift symbol is found, demangle it into a node tree. The node tree
2998
+ // provides the final data, the name of the class and the name of its module.
2999
+ swift::Demangle::Context ctx;
3000
+ auto *global = ctx.demangleSymbolAsNode (*swift_symbol);
3001
+ using Kind = Node::Kind;
3002
+ auto *class_node = swift_demangle::nodeAtPath (
3003
+ global, {Kind::TypeMetadata, Kind::Type, Kind::Class});
3004
+ if (class_node && class_node->getNumChildren () == 2 ) {
3005
+ auto module_node = class_node->getFirstChild ();
3006
+ auto ident_node = class_node->getLastChild ();
3007
+ if (module_node->getKind () == Kind::Module && module_node->hasText () &&
3008
+ ident_node->getKind () == Kind::Identifier && ident_node->hasText ()) {
3009
+ auto module_name = module_node->getText ();
3010
+ auto class_name = ident_node->getText ();
3011
+ return SwiftNominalType{module_name.str (), class_name.str ()};
3012
+ }
3013
+ }
3014
+
3015
+ return {};
3016
+ }
3017
+
3018
+ } // namespace
3019
+
2944
3020
bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress_ClangType (
2945
3021
ValueObject &in_value, lldb::DynamicValueType use_dynamic,
2946
3022
TypeAndOrName &class_type_or_name, Address &address,
@@ -2967,9 +3043,22 @@ bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress_ClangType(
2967
3043
dyn_name.startswith (" __NS" ))
2968
3044
return false ;
2969
3045
3046
+ SwiftNominalType swift_class;
3047
+
3048
+ if (auto maybe_swift_class = GetSwiftClass (in_value, *objc_runtime)) {
3049
+ swift_class = *maybe_swift_class;
3050
+ std::string type_name =
3051
+ (llvm::Twine (swift_class.module ) + " ." + swift_class.identifier ).str ();
3052
+ dyn_class_type_or_name.SetName (type_name.data ());
3053
+ address.SetRawAddress (in_value.GetPointerValue ());
3054
+ } else {
3055
+ swift_class.module = swift::MANGLING_MODULE_OBJC;
3056
+ swift_class.identifier = dyn_name;
3057
+ }
3058
+
2970
3059
std::string remangled;
2971
3060
{
2972
- // Create a mangle tree for __C.dyn_name?.
3061
+ // Create a mangle tree for Swift.Optional<$module.$class>
2973
3062
using namespace swift ::Demangle;
2974
3063
NodeFactory factory;
2975
3064
NodePointer global = factory.createNode (Node::Kind::Global);
@@ -2980,7 +3069,8 @@ bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress_ClangType(
2980
3069
NodePointer ety = factory.createNode (Node::Kind::Type);
2981
3070
bge->addChild (ety, factory);
2982
3071
NodePointer e = factory.createNode (Node::Kind::Enum);
2983
- e->addChild (factory.createNode (Node::Kind::Module, " Swift" ), factory);
3072
+ e->addChild (factory.createNode (Node::Kind::Module, swift::STDLIB_NAME),
3073
+ factory);
2984
3074
e->addChild (factory.createNode (Node::Kind::Identifier, " Optional" ),
2985
3075
factory);
2986
3076
ety->addChild (e, factory);
@@ -2989,8 +3079,11 @@ bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress_ClangType(
2989
3079
NodePointer cty = factory.createNode (Node::Kind::Type);
2990
3080
list->addChild (cty, factory);
2991
3081
NodePointer c = factory.createNode (Node::Kind::Class);
2992
- c->addChild (factory.createNode (Node::Kind::Module, " __C" ), factory);
2993
- c->addChild (factory.createNode (Node::Kind::Identifier, dyn_name), factory);
3082
+ c->addChild (factory.createNode (Node::Kind::Module, swift_class.module ),
3083
+ factory);
3084
+ c->addChild (
3085
+ factory.createNode (Node::Kind::Identifier, swift_class.identifier ),
3086
+ factory);
2994
3087
cty->addChild (c, factory);
2995
3088
2996
3089
auto mangling = mangleNode (global);
0 commit comments