diff options
Diffstat (limited to 'source/Plugins/LanguageRuntime/Java')
3 files changed, 269 insertions, 0 deletions
diff --git a/source/Plugins/LanguageRuntime/Java/CMakeLists.txt b/source/Plugins/LanguageRuntime/Java/CMakeLists.txt new file mode 100644 index 000000000000..4cfd71c2e242 --- /dev/null +++ b/source/Plugins/LanguageRuntime/Java/CMakeLists.txt @@ -0,0 +1,3 @@ +add_lldb_library(lldbPluginLanguageRuntimeJava + JavaLanguageRuntime.cpp + ) diff --git a/source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.cpp b/source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.cpp new file mode 100644 index 000000000000..07312a8af0d6 --- /dev/null +++ b/source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.cpp @@ -0,0 +1,176 @@ +//===-- 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; +} diff --git a/source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.h b/source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.h new file mode 100644 index 000000000000..83ed35dbb59d --- /dev/null +++ b/source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.h @@ -0,0 +1,90 @@ +//===-- JavaLanguageRuntime.h -----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_JavaLanguageRuntime_h_ +#define liblldb_JavaLanguageRuntime_h_ + +// C Includes +// C++ Includes +#include <vector> +// Other libraries and framework includes +// Project includes +#include "lldb/Core/PluginInterface.h" +#include "lldb/Target/LanguageRuntime.h" +#include "lldb/lldb-private.h" + +namespace lldb_private +{ + +class JavaLanguageRuntime : public LanguageRuntime +{ +public: + static void + Initialize(); + + static void + Terminate(); + + static lldb_private::LanguageRuntime * + CreateInstance(Process *process, lldb::LanguageType language); + + static lldb_private::ConstString + GetPluginNameStatic(); + + lldb_private::ConstString + GetPluginName() override; + + uint32_t + GetPluginVersion() override; + + lldb::LanguageType + GetLanguageType() const override + { + return lldb::eLanguageTypeJava; + } + + bool + GetObjectDescription(Stream &str, ValueObject &object) override + { + return false; + } + + bool + GetObjectDescription(Stream &str, Value &value, ExecutionContextScope *exe_scope) override + { + return false; + } + + lldb::BreakpointResolverSP + CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, bool throw_bp) override + { + return nullptr; + } + + TypeAndOrName + FixUpDynamicType(const TypeAndOrName &type_and_or_name, ValueObject &static_value) override; + + bool + CouldHaveDynamicValue(ValueObject &in_value) override; + + bool + GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic, + TypeAndOrName &class_type_or_name, Address &address, + Value::ValueType &value_type) override; + +protected: + JavaLanguageRuntime(Process *process); + +private: + DISALLOW_COPY_AND_ASSIGN(JavaLanguageRuntime); +}; + +} // namespace lldb_private + +#endif // liblldb_JavaLanguageRuntime_h_ |