Add a set of new plugins to handle Java debugging
The purpose of these plugins is to make LLDB capable of debugging java code JIT-ed by the android runtime. Differential revision: http://reviews.llvm.org/D17616 llvm-svn: 262015
This commit is contained in:
176
lldb/source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.cpp
Normal file
176
lldb/source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.cpp
Normal file
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user