| //===-- JavaLanguageRuntime.cpp ---------------------------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "JavaLanguageRuntime.h" |
| |
| #include "lldb/Core/PluginManager.h" |
| #include "lldb/Symbol/JavaASTContext.h" |
| #include "lldb/Symbol/Symbol.h" |
| #include "lldb/Symbol/SymbolContext.h" |
| #include "lldb/Symbol/SymbolFile.h" |
| #include "lldb/Symbol/Type.h" |
| #include "lldb/Symbol/TypeList.h" |
| #include "lldb/Target/SectionLoadList.h" |
| #include "lldb/Target/Target.h" |
| #include "llvm/ADT/StringRef.h" |
| |
| using namespace lldb; |
| using namespace lldb_private; |
| |
| JavaLanguageRuntime::JavaLanguageRuntime(Process *process) |
| : LanguageRuntime(process) {} |
| |
| LanguageRuntime * |
| JavaLanguageRuntime::CreateInstance(Process *process, |
| lldb::LanguageType language) { |
| if (language == eLanguageTypeJava) |
| return new JavaLanguageRuntime(process); |
| return nullptr; |
| } |
| |
| void JavaLanguageRuntime::Initialize() { |
| PluginManager::RegisterPlugin(GetPluginNameStatic(), "Java language runtime", |
| CreateInstance); |
| } |
| |
| void JavaLanguageRuntime::Terminate() { |
| PluginManager::UnregisterPlugin(CreateInstance); |
| } |
| |
| lldb_private::ConstString JavaLanguageRuntime::GetPluginNameStatic() { |
| static ConstString g_name("java"); |
| return g_name; |
| } |
| |
| lldb_private::ConstString JavaLanguageRuntime::GetPluginName() { |
| return GetPluginNameStatic(); |
| } |
| |
| uint32_t JavaLanguageRuntime::GetPluginVersion() { return 1; } |
| |
| bool JavaLanguageRuntime::CouldHaveDynamicValue(ValueObject &in_value) { |
| return true; |
| } |
| |
| static ConstString GetDynamicTypeId(ExecutionContext *exe_ctx, Target *target, |
| ValueObject &in_value) { |
| SymbolContext sc; |
| TypeList class_types; |
| llvm::DenseSet<SymbolFile *> searched_symbol_files; |
| size_t num_matches = target->GetImages().FindTypes( |
| sc, ConstString("Object"), |
| true, // name_is_fully_qualified |
| UINT32_MAX, searched_symbol_files, class_types); |
| for (size_t i = 0; i < num_matches; ++i) { |
| TypeSP type_sp = class_types.GetTypeAtIndex(i); |
| CompilerType compiler_type = type_sp->GetFullCompilerType(); |
| |
| if (compiler_type.GetMinimumLanguage() != eLanguageTypeJava || |
| compiler_type.GetTypeName() != ConstString("java::lang::Object")) |
| continue; |
| |
| if (compiler_type.GetCompleteType() && compiler_type.IsCompleteType()) { |
| uint64_t type_id = JavaASTContext::CalculateDynamicTypeId( |
| exe_ctx, compiler_type, in_value); |
| if (type_id != UINT64_MAX) { |
| char id[32]; |
| snprintf(id, sizeof(id), "0x%" PRIX64, type_id); |
| return ConstString(id); |
| } |
| } |
| } |
| return ConstString(); |
| } |
| |
| bool JavaLanguageRuntime::GetDynamicTypeAndAddress( |
| ValueObject &in_value, lldb::DynamicValueType use_dynamic, |
| TypeAndOrName &class_type_or_name, Address &dynamic_address, |
| Value::ValueType &value_type) { |
| class_type_or_name.Clear(); |
| |
| // null references don't have a dynamic type |
| if (in_value.IsNilReference()) |
| return false; |
| |
| ExecutionContext exe_ctx(in_value.GetExecutionContextRef()); |
| Target *target = exe_ctx.GetTargetPtr(); |
| if (!target) |
| return false; |
| |
| ConstString linkage_name; |
| CompilerType in_type = in_value.GetCompilerType(); |
| if (in_type.IsPossibleDynamicType(nullptr, false, false)) |
| linkage_name = GetDynamicTypeId(&exe_ctx, target, in_value); |
| else |
| linkage_name = JavaASTContext::GetLinkageName(in_type); |
| |
| if (!linkage_name) |
| return false; |
| |
| class_type_or_name.SetName(in_type.GetNonReferenceType().GetTypeName()); |
| |
| SymbolContext sc; |
| TypeList class_types; |
| llvm::DenseSet<SymbolFile *> searched_symbol_files; |
| size_t num_matches = target->GetImages().FindTypes( |
| sc, linkage_name, |
| true, // name_is_fully_qualified |
| UINT32_MAX, searched_symbol_files, class_types); |
| |
| for (size_t i = 0; i < num_matches; ++i) { |
| TypeSP type_sp = class_types.GetTypeAtIndex(i); |
| CompilerType compiler_type = type_sp->GetFullCompilerType(); |
| |
| if (compiler_type.GetMinimumLanguage() != eLanguageTypeJava) |
| continue; |
| |
| if (compiler_type.GetCompleteType() && compiler_type.IsCompleteType()) { |
| class_type_or_name.SetTypeSP(type_sp); |
| |
| Value &value = in_value.GetValue(); |
| value_type = value.GetValueType(); |
| dynamic_address.SetRawAddress(value.GetScalar().ULongLong(0)); |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| TypeAndOrName |
| JavaLanguageRuntime::FixUpDynamicType(const TypeAndOrName &type_and_or_name, |
| ValueObject &static_value) { |
| CompilerType static_type(static_value.GetCompilerType()); |
| |
| TypeAndOrName ret(type_and_or_name); |
| if (type_and_or_name.HasType()) { |
| CompilerType orig_type = type_and_or_name.GetCompilerType(); |
| if (static_type.IsReferenceType()) |
| ret.SetCompilerType(orig_type.GetLValueReferenceType()); |
| } |
| return ret; |
| } |