158 lines
5.0 KiB
C++
158 lines
5.0 KiB
C++
//===-- 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;
|
|
}
|