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:
Tamas Berghammer 2016-02-26 14:21:23 +00:00
parent 5b42c7aa25
commit 87a9769e9b
22 changed files with 3110 additions and 3 deletions

View File

@ -23,6 +23,7 @@ set( LLDB_USED_LIBS
lldbPluginCPlusPlusLanguage
lldbPluginGoLanguage
lldbPluginJavaLanguage
lldbPluginObjCLanguage
lldbPluginObjCPlusPlusLanguage
@ -50,6 +51,7 @@ set( LLDB_USED_LIBS
lldbPluginAppleObjCRuntime
lldbPluginRenderScriptRuntime
lldbPluginLanguageRuntimeGo
lldbPluginLanguageRuntimeJava
lldbPluginCXXItaniumABI
lldbPluginABIMacOSX_arm
lldbPluginABIMacOSX_arm64

View File

@ -0,0 +1,382 @@
//===-- JavaASTContext.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_JavaASTContext_h_
#define liblldb_JavaASTContext_h_
// C Includes
// C++ Includes
#include <map>
#include <memory>
#include <set>
// Other libraries and framework includes
// Project includes
#include "lldb/Core/ConstString.h"
#include "lldb/Symbol/TypeSystem.h"
namespace lldb_private
{
class JavaASTContext : public TypeSystem
{
public:
class JavaType;
typedef std::map<ConstString, std::unique_ptr<JavaType>> JavaTypeMap;
JavaASTContext(const ArchSpec &arch);
~JavaASTContext() override;
//------------------------------------------------------------------
// PluginInterface functions
//------------------------------------------------------------------
ConstString
GetPluginName() override;
uint32_t
GetPluginVersion() override;
static ConstString
GetPluginNameStatic();
static lldb::TypeSystemSP
CreateInstance(lldb::LanguageType language, Module *module, Target *target);
static void
EnumerateSupportedLanguages(std::set<lldb::LanguageType> &languages_for_types,
std::set<lldb::LanguageType> &languages_for_expressions);
static void
Initialize();
static void
Terminate();
DWARFASTParser *
GetDWARFParser() override;
uint32_t
GetPointerByteSize() override;
//----------------------------------------------------------------------
// CompilerDecl functions
//----------------------------------------------------------------------
ConstString
DeclGetName(void *opaque_decl) override;
lldb::VariableSP
DeclGetVariable(void *opaque_decl) override;
void
DeclLinkToObject(void *opaque_decl, std::shared_ptr<void> object) override;
//----------------------------------------------------------------------
// CompilerDeclContext functions
//----------------------------------------------------------------------
std::vector<CompilerDecl>
DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name, const bool ignore_imported_decls) override;
bool
DeclContextIsStructUnionOrClass(void *opaque_decl_ctx) override;
ConstString
DeclContextGetName(void *opaque_decl_ctx) override;
bool
DeclContextIsClassMethod(void *opaque_decl_ctx, lldb::LanguageType *language_ptr, bool *is_instance_method_ptr,
ConstString *language_object_name_ptr) override;
//----------------------------------------------------------------------
// Tests
//----------------------------------------------------------------------
bool
IsArrayType(lldb::opaque_compiler_type_t type, CompilerType *element_type, uint64_t *size,
bool *is_incomplete) override;
bool
IsAggregateType(lldb::opaque_compiler_type_t type) override;
bool
IsCharType(lldb::opaque_compiler_type_t type) override;
bool
IsFloatingPointType(lldb::opaque_compiler_type_t type, uint32_t &count, bool &is_complex) override;
bool
IsFunctionType(lldb::opaque_compiler_type_t type, bool *is_variadic_ptr = nullptr) override;
size_t
GetNumberOfFunctionArguments(lldb::opaque_compiler_type_t type) override;
CompilerType
GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type, const size_t index) override;
bool
IsFunctionPointerType(lldb::opaque_compiler_type_t type) override;
bool
IsIntegerType(lldb::opaque_compiler_type_t type, bool &is_signed) override;
bool
IsPossibleDynamicType(lldb::opaque_compiler_type_t type, CompilerType *target_type, bool check_cplusplus,
bool check_objc) override;
bool
IsPointerType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type = nullptr) override;
bool
IsReferenceType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type = nullptr,
bool *is_rvalue = nullptr) override;
bool
IsPointerOrReferenceType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type = nullptr) override;
bool
IsScalarType(lldb::opaque_compiler_type_t type) override;
bool
IsVoidType(lldb::opaque_compiler_type_t type) override;
bool
IsCStringType(lldb::opaque_compiler_type_t type, uint32_t &length) override;
bool
IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type) override;
bool
IsTypedefType(lldb::opaque_compiler_type_t type) override;
bool
IsVectorType(lldb::opaque_compiler_type_t type, CompilerType *element_type, uint64_t *size) override;
bool
IsPolymorphicClass(lldb::opaque_compiler_type_t type) override;
bool
IsCompleteType(lldb::opaque_compiler_type_t type) override;
bool
IsConst(lldb::opaque_compiler_type_t type) override;
bool
IsBeingDefined(lldb::opaque_compiler_type_t type) override;
bool
IsDefined(lldb::opaque_compiler_type_t type) override;
uint32_t
IsHomogeneousAggregate(lldb::opaque_compiler_type_t type, CompilerType *base_type_ptr) override;
bool
SupportsLanguage(lldb::LanguageType language) override;
bool
GetCompleteType(lldb::opaque_compiler_type_t type) override;
ConstString
GetTypeName(lldb::opaque_compiler_type_t type) override;
uint32_t
GetTypeInfo(lldb::opaque_compiler_type_t type, CompilerType *pointee_or_element_compiler_type = nullptr) override;
lldb::TypeClass
GetTypeClass(lldb::opaque_compiler_type_t type) override;
lldb::LanguageType
GetMinimumLanguage(lldb::opaque_compiler_type_t type) override;
CompilerType
GetArrayElementType(lldb::opaque_compiler_type_t type, uint64_t *stride = nullptr) override;
CompilerType
GetPointeeType(lldb::opaque_compiler_type_t type) override;
CompilerType
GetPointerType(lldb::opaque_compiler_type_t type) override;
CompilerType
GetCanonicalType(lldb::opaque_compiler_type_t type) override;
CompilerType
GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) override;
CompilerType
GetNonReferenceType(lldb::opaque_compiler_type_t type) override;
CompilerType
GetTypedefedType(lldb::opaque_compiler_type_t type) override;
CompilerType
GetBasicTypeFromAST(lldb::BasicType basic_type) override;
CompilerType
GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding, size_t bit_size) override;
size_t
GetTypeBitAlign(lldb::opaque_compiler_type_t type) override;
lldb::BasicType
GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) override;
uint64_t
GetBitSize(lldb::opaque_compiler_type_t type, ExecutionContextScope *exe_scope) override;
lldb::Encoding
GetEncoding(lldb::opaque_compiler_type_t type, uint64_t &count) override;
lldb::Format
GetFormat(lldb::opaque_compiler_type_t type) override;
unsigned
GetTypeQualifiers(lldb::opaque_compiler_type_t type) override;
size_t
GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override;
CompilerType
GetTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx, lldb::TemplateArgumentKind &kind) override;
int
GetFunctionArgumentCount(lldb::opaque_compiler_type_t type) override;
CompilerType
GetFunctionArgumentTypeAtIndex(lldb::opaque_compiler_type_t type, size_t idx) override;
CompilerType
GetFunctionReturnType(lldb::opaque_compiler_type_t type) override;
size_t
GetNumMemberFunctions(lldb::opaque_compiler_type_t type) override;
TypeMemberFunctionImpl
GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type, size_t idx) override;
uint32_t
GetNumFields(lldb::opaque_compiler_type_t type) override;
CompilerType
GetFieldAtIndex(lldb::opaque_compiler_type_t type, size_t idx, std::string &name, uint64_t *bit_offset_ptr,
uint32_t *bitfield_bit_size_ptr, bool *is_bitfield_ptr) override;
uint32_t
GetNumChildren(lldb::opaque_compiler_type_t type, bool omit_empty_base_classes) override;
uint32_t
GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) override;
uint32_t
GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) override;
CompilerType
GetDirectBaseClassAtIndex(lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) override;
CompilerType
GetVirtualBaseClassAtIndex(lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) override;
size_t
ConvertStringToFloatValue(lldb::opaque_compiler_type_t type, const char *s, uint8_t *dst, size_t dst_size) override;
void
DumpValue(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s, lldb::Format format,
const DataExtractor &data, lldb::offset_t data_offset, size_t data_byte_size, uint32_t bitfield_bit_size,
uint32_t bitfield_bit_offset, bool show_types, bool show_summary, bool verbose, uint32_t depth) override;
bool
DumpTypeValue(lldb::opaque_compiler_type_t type, Stream *s, lldb::Format format, const DataExtractor &data,
lldb::offset_t data_offset, size_t data_byte_size, uint32_t bitfield_bit_size,
uint32_t bitfield_bit_offset, ExecutionContextScope *exe_scope) override;
void
DumpTypeDescription(lldb::opaque_compiler_type_t type) override;
void
DumpTypeDescription(lldb::opaque_compiler_type_t type, Stream *s) override;
void
DumpSummary(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s, const DataExtractor &data,
lldb::offset_t data_offset, size_t data_byte_size) override;
CompilerType
GetChildCompilerTypeAtIndex(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx,
bool transparent_pointers, bool omit_empty_base_classes, bool ignore_array_bounds,
std::string &child_name, uint32_t &child_byte_size, int32_t &child_byte_offset,
uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset,
bool &child_is_base_class, bool &child_is_deref_of_parent, ValueObject *valobj,
uint64_t &language_flags) override;
uint32_t
GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, const char *name, bool omit_empty_base_classes) override;
size_t
GetIndexOfChildMemberWithName(lldb::opaque_compiler_type_t type, const char *name, bool omit_empty_base_classes,
std::vector<uint32_t> &child_indexes) override;
CompilerType
GetLValueReferenceType(lldb::opaque_compiler_type_t type) override;
ConstString
DeclContextGetScopeQualifiedName(lldb::opaque_compiler_type_t opaque_decl_ctx) override;
CompilerType
CreateBaseType(const ConstString &name);
CompilerType
CreateObjectType(const ConstString &name, const ConstString &linkage_name, uint32_t byte_size);
CompilerType
CreateArrayType(const CompilerType &element_type, const DWARFExpression &length_expression,
const lldb::addr_t data_offset);
CompilerType
CreateReferenceType(const CompilerType &pointee_type);
void
CompleteObjectType(const CompilerType &object_type);
void
AddBaseClassToObject(const CompilerType &object_type, const CompilerType &member_type, uint32_t member_offset);
void
AddMemberToObject(const CompilerType &object_type, const ConstString &name, const CompilerType &member_type,
uint32_t member_offset);
void
SetDynamicTypeId(const CompilerType &type, const DWARFExpression &type_id);
static uint64_t
CalculateDynamicTypeId(ExecutionContext *exe_ctx, const CompilerType &type, ValueObject &in_value);
static ConstString
GetLinkageName(const CompilerType &type);
//------------------------------------------------------------------
// llvm casting support
//------------------------------------------------------------------
static bool
classof(const TypeSystem *ts)
{
return ts->getKind() == TypeSystem::eKindJava;
}
private:
uint32_t m_pointer_byte_size;
std::unique_ptr<DWARFASTParser> m_dwarf_ast_parser_ap;
JavaTypeMap m_array_type_map;
JavaTypeMap m_base_type_map;
JavaTypeMap m_reference_type_map;
JavaTypeMap m_object_type_map;
JavaASTContext(const JavaASTContext &) = delete;
const JavaASTContext &
operator=(const JavaASTContext &) = delete;
};
}
#endif // liblldb_JavaASTContext_h_

View File

@ -74,6 +74,7 @@ public:
eKindClang,
eKindSwift,
eKindGo,
eKindJava,
kNumKinds
};

View File

@ -26,6 +26,7 @@
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/GoASTContext.h"
#include "lldb/Symbol/JavaASTContext.h"
#include "Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h"
#include "Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h"
@ -46,12 +47,14 @@
#include "Plugins/JITLoader/GDB/JITLoaderGDB.h"
#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
#include "Plugins/Language/Go/GoLanguage.h"
#include "Plugins/Language/Java/JavaLanguage.h"
#include "Plugins/Language/ObjC/ObjCLanguage.h"
#include "Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h"
#include "Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h"
#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h"
#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h"
#include "Plugins/LanguageRuntime/Go/GoLanguageRuntime.h"
#include "Plugins/LanguageRuntime/Java/JavaLanguageRuntime.h"
#include "Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h"
#include "Plugins/MemoryHistory/asan/MemoryHistoryASan.h"
#include "Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h"
@ -272,6 +275,7 @@ SystemInitializerFull::Initialize()
ClangASTContext::Initialize();
GoASTContext::Initialize();
JavaASTContext::Initialize();
ABIMacOSX_i386::Initialize();
ABIMacOSX_arm::Initialize();
@ -308,9 +312,11 @@ SystemInitializerFull::Initialize()
SystemRuntimeMacOSX::Initialize();
RenderScriptRuntime::Initialize();
GoLanguageRuntime::Initialize();
JavaLanguageRuntime::Initialize();
CPlusPlusLanguage::Initialize();
GoLanguage::Initialize();
JavaLanguage::Initialize();
ObjCLanguage::Initialize();
ObjCPlusPlusLanguage::Initialize();
@ -391,6 +397,7 @@ SystemInitializerFull::Terminate()
ClangASTContext::Terminate();
GoASTContext::Terminate();
JavaASTContext::Terminate();
ABIMacOSX_i386::Terminate();
ABIMacOSX_arm::Terminate();
@ -425,9 +432,11 @@ SystemInitializerFull::Terminate()
AppleObjCRuntimeV1::Terminate();
SystemRuntimeMacOSX::Terminate();
RenderScriptRuntime::Terminate();
JavaLanguageRuntime::Terminate();
CPlusPlusLanguage::Terminate();
GoLanguage::Terminate();
JavaLanguage::Terminate();
ObjCLanguage::Terminate();
ObjCPlusPlusLanguage::Terminate();

View File

@ -1,4 +1,5 @@
add_subdirectory(CPlusPlus)
add_subdirectory(Go)
add_subdirectory(Java)
add_subdirectory(ObjC)
add_subdirectory(ObjCPlusPlus)

View File

@ -0,0 +1,4 @@
add_lldb_library(lldbPluginJavaLanguage
JavaFormatterFunctions.cpp
JavaLanguage.cpp
)

View File

@ -0,0 +1,71 @@
//===-- JavaFormatterFunctions.cpp-------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "JavaFormatterFunctions.h"
#include "lldb/DataFormatters/FormattersHelpers.h"
#include "lldb/DataFormatters/StringPrinter.h"
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
bool
lldb_private::formatters::JavaStringSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &opts)
{
if (valobj.IsPointerOrReferenceType())
{
Error error;
ValueObjectSP deref = valobj.Dereference(error);
if (error.Fail())
return false;
return JavaStringSummaryProvider(*deref, stream, opts);
}
ProcessSP process_sp = valobj.GetProcessSP();
if (!process_sp)
return false;
ConstString data_name("value");
ConstString length_name("count");
ValueObjectSP length_sp = valobj.GetChildMemberWithName(length_name, true);
ValueObjectSP data_sp = valobj.GetChildMemberWithName(data_name, true);
if (!data_sp || !length_sp)
return false;
bool success = false;
uint64_t length = length_sp->GetValueAsUnsigned(0, &success);
if (!success)
return false;
if (length == 0)
{
stream.Printf("\"\"");
return true;
}
lldb::addr_t valobj_addr = data_sp->GetAddressOf();
StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
options.SetLocation(valobj_addr);
options.SetProcessSP(process_sp);
options.SetStream(&stream);
options.SetSourceSize(length);
options.SetNeedsZeroTermination(false);
options.SetLanguage(eLanguageTypeJava);
if (StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF16>(options))
return true;
stream.Printf("Summary Unavailable");
return true;
}

View File

@ -0,0 +1,30 @@
//===-- JavaFormatterFunctions.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_JavaFormatterFunctions_h_
#define liblldb_JavaFormatterFunctions_h_
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-forward.h"
namespace lldb_private
{
namespace formatters
{
bool
JavaStringSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options);
} // namespace formatters
} // namespace lldb_private
#endif // liblldb_JavaFormatterFunctions_h_

View File

@ -0,0 +1,99 @@
//===-- JavaLanguage.cpp ----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// C Includes
#include <string.h>
// C++ Includes
#include <functional>
#include <mutex>
// Other libraries and framework includes
#include "llvm/ADT/StringRef.h"
// Project includes
#include "JavaFormatterFunctions.h"
#include "JavaLanguage.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/DataFormatters/DataVisualization.h"
#include "lldb/DataFormatters/FormattersHelpers.h"
#include "lldb/Symbol/JavaASTContext.h"
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
void
JavaLanguage::Initialize()
{
PluginManager::RegisterPlugin(GetPluginNameStatic(), "Java Language", CreateInstance);
}
void
JavaLanguage::Terminate()
{
PluginManager::UnregisterPlugin(CreateInstance);
}
lldb_private::ConstString
JavaLanguage::GetPluginNameStatic()
{
static ConstString g_name("Java");
return g_name;
}
lldb_private::ConstString
JavaLanguage::GetPluginName()
{
return GetPluginNameStatic();
}
uint32_t
JavaLanguage::GetPluginVersion()
{
return 1;
}
Language *
JavaLanguage::CreateInstance(lldb::LanguageType language)
{
if (language == eLanguageTypeJava)
return new JavaLanguage();
return nullptr;
}
bool
JavaLanguage::IsNilReference(ValueObject &valobj)
{
if (!valobj.GetCompilerType().IsReferenceType())
return false;
// If we failed to read the value then it is not a nil reference.
return valobj.GetValueAsUnsigned(UINT64_MAX) == 0;
}
lldb::TypeCategoryImplSP
JavaLanguage::GetFormatters()
{
static std::once_flag g_initialize;
static TypeCategoryImplSP g_category;
std::call_once(g_initialize, [this]() -> void {
DataVisualization::Categories::GetCategory(GetPluginName(), g_category);
if (g_category)
{
lldb::TypeSummaryImplSP string_summary_sp(new CXXFunctionSummaryFormat(
TypeSummaryImpl::Flags().SetDontShowChildren(true), lldb_private::formatters::JavaStringSummaryProvider,
"java.lang.String summary provider"));
g_category->GetTypeSummariesContainer()->Add(ConstString("java::lang::String"), string_summary_sp);
}
});
return g_category;
}

View File

@ -0,0 +1,64 @@
//===-- JavaLanguage.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_JavaLanguage_h_
#define liblldb_JavaLanguage_h_
// C Includes
// C++ Includes
#include <vector>
// Other libraries and framework includes
#include "llvm/ADT/StringRef.h"
// Project includes
#include "lldb/Core/ConstString.h"
#include "lldb/Target/Language.h"
#include "lldb/lldb-private.h"
namespace lldb_private
{
class JavaLanguage : public Language
{
public:
lldb::LanguageType
GetLanguageType() const override
{
return lldb::eLanguageTypeJava;
}
static void
Initialize();
static void
Terminate();
static lldb_private::Language *
CreateInstance(lldb::LanguageType language);
static lldb_private::ConstString
GetPluginNameStatic();
ConstString
GetPluginName() override;
uint32_t
GetPluginVersion() override;
bool
IsNilReference(ValueObject &valobj) override;
lldb::TypeCategoryImplSP
GetFormatters();
};
} // namespace lldb_private
#endif // liblldb_JavaLanguage_h_

View File

@ -1,4 +1,5 @@
add_subdirectory(CPlusPlus)
add_subdirectory(ObjC)
add_subdirectory(Go)
add_subdirectory(Java)
add_subdirectory(RenderScript)

View File

@ -0,0 +1,3 @@
add_lldb_library(lldbPluginLanguageRuntimeJava
JavaLanguageRuntime.cpp
)

View 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;
}

View File

@ -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_

View File

@ -3,6 +3,7 @@ add_lldb_library(lldbPluginSymbolFileDWARF
DWARFAbbreviationDeclaration.cpp
DWARFASTParserClang.cpp
DWARFASTParserGo.cpp
DWARFASTParserJava.cpp
DWARFAttribute.cpp
DWARFCompileUnit.cpp
DWARFDataExtractor.cpp

View File

@ -0,0 +1,553 @@
//===-- DWARFASTParserJava.cpp ----------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "DWARFASTParserJava.h"
#include "DWARFAttribute.h"
#include "DWARFCompileUnit.h"
#include "DWARFDebugInfoEntry.h"
#include "DWARFDebugInfoEntry.h"
#include "DWARFDeclContext.h"
#include "SymbolFileDWARF.h"
#include "lldb/Core/Module.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/SymbolContextScope.h"
#include "lldb/Symbol/TypeList.h"
using namespace lldb;
using namespace lldb_private;
DWARFASTParserJava::DWARFASTParserJava(JavaASTContext &ast) : m_ast(ast)
{
}
DWARFASTParserJava::~DWARFASTParserJava()
{
}
TypeSP
DWARFASTParserJava::ParseBaseTypeFromDIE(const DWARFDIE &die)
{
SymbolFileDWARF *dwarf = die.GetDWARF();
dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
ConstString type_name;
uint64_t byte_size = 0;
DWARFAttributes attributes;
const size_t num_attributes = die.GetAttributes(attributes);
for (uint32_t i = 0; i < num_attributes; ++i)
{
DWARFFormValue form_value;
dw_attr_t attr = attributes.AttributeAtIndex(i);
if (attributes.ExtractFormValueAtIndex(i, form_value))
{
switch (attr)
{
case DW_AT_name:
type_name.SetCString(form_value.AsCString());
break;
case DW_AT_byte_size:
byte_size = form_value.Unsigned();
break;
case DW_AT_encoding:
break;
default:
assert(false && "Unsupported attribute for DW_TAG_base_type");
}
}
}
Declaration decl;
CompilerType compiler_type = m_ast.CreateBaseType(type_name);
return std::make_shared<Type>(die.GetID(), dwarf, type_name, byte_size, nullptr, LLDB_INVALID_UID,
Type::eEncodingIsUID, decl, compiler_type, Type::eResolveStateFull);
}
TypeSP
DWARFASTParserJava::ParseArrayTypeFromDIE(const DWARFDIE &die)
{
SymbolFileDWARF *dwarf = die.GetDWARF();
dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
ConstString linkage_name;
lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
lldb::addr_t data_offset = LLDB_INVALID_ADDRESS;
DWARFExpression length_expression(die.GetCU());
DWARFAttributes attributes;
const size_t num_attributes = die.GetAttributes(attributes);
for (uint32_t i = 0; i < num_attributes; ++i)
{
DWARFFormValue form_value;
dw_attr_t attr = attributes.AttributeAtIndex(i);
if (attributes.ExtractFormValueAtIndex(i, form_value))
{
switch (attr)
{
case DW_AT_linkage_name:
linkage_name.SetCString(form_value.AsCString());
break;
case DW_AT_type:
type_die_offset = form_value.Reference();
break;
case DW_AT_data_member_location:
data_offset = form_value.Unsigned();
break;
case DW_AT_declaration:
break;
default:
assert(false && "Unsupported attribute for DW_TAG_array_type");
}
}
}
for (DWARFDIE child_die = die.GetFirstChild(); child_die.IsValid(); child_die = child_die.GetSibling())
{
if (child_die.Tag() == DW_TAG_subrange_type)
{
DWARFAttributes attributes;
const size_t num_attributes = child_die.GetAttributes(attributes);
for (uint32_t i = 0; i < num_attributes; ++i)
{
DWARFFormValue form_value;
dw_attr_t attr = attributes.AttributeAtIndex(i);
if (attributes.ExtractFormValueAtIndex(i, form_value))
{
switch (attr)
{
case DW_AT_count:
if (form_value.BlockData())
length_expression.CopyOpcodeData(form_value.BlockData(), form_value.Unsigned(),
child_die.GetCU()->GetByteOrder(),
child_die.GetCU()->GetAddressByteSize());
break;
default:
assert(false && "Unsupported attribute for DW_TAG_subrange_type");
}
}
}
}
else
{
assert(false && "Unsupported child for DW_TAG_array_type");
}
}
Type *element_type = dwarf->ResolveTypeUID(type_die_offset);
if (!element_type)
return nullptr;
CompilerType element_compiler_type = element_type->GetForwardCompilerType();
CompilerType array_compiler_type =
m_ast.CreateArrayType(element_compiler_type, length_expression, data_offset);
Declaration decl;
TypeSP type_sp(new Type(die.GetID(), dwarf, array_compiler_type.GetTypeName(), -1, nullptr,
dwarf->MakeUserID(type_die_offset), Type::eEncodingIsUID, &decl,
array_compiler_type, Type::eResolveStateFull));
type_sp->SetEncodingType(element_type);
return type_sp;
}
TypeSP
DWARFASTParserJava::ParseReferenceTypeFromDIE(const DWARFDIE &die)
{
SymbolFileDWARF *dwarf = die.GetDWARF();
dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
Declaration decl;
lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
DWARFAttributes attributes;
const size_t num_attributes = die.GetAttributes(attributes);
for (uint32_t i = 0; i < num_attributes; ++i)
{
DWARFFormValue form_value;
dw_attr_t attr = attributes.AttributeAtIndex(i);
if (attributes.ExtractFormValueAtIndex(i, form_value))
{
switch (attr)
{
case DW_AT_type:
type_die_offset = form_value.Reference();
break;
default:
assert(false && "Unsupported attribute for DW_TAG_array_type");
}
}
}
Type *pointee_type = dwarf->ResolveTypeUID(type_die_offset);
if (!pointee_type)
return nullptr;
CompilerType pointee_compiler_type = pointee_type->GetForwardCompilerType();
CompilerType reference_compiler_type = m_ast.CreateReferenceType(pointee_compiler_type);
TypeSP type_sp(new Type(die.GetID(), dwarf, reference_compiler_type.GetTypeName(), -1, nullptr,
dwarf->MakeUserID(type_die_offset), Type::eEncodingIsUID, &decl,
reference_compiler_type, Type::eResolveStateFull));
type_sp->SetEncodingType(pointee_type);
return type_sp;
}
lldb::TypeSP
DWARFASTParserJava::ParseClassTypeFromDIE(const DWARFDIE &die, bool &is_new_type)
{
SymbolFileDWARF *dwarf = die.GetDWARF();
dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
Declaration decl;
ConstString name;
ConstString linkage_name;
bool is_forward_declaration = false;
uint32_t byte_size = 0;
DWARFAttributes attributes;
const size_t num_attributes = die.GetAttributes(attributes);
for (uint32_t i = 0; i < num_attributes; ++i)
{
DWARFFormValue form_value;
dw_attr_t attr = attributes.AttributeAtIndex(i);
if (attributes.ExtractFormValueAtIndex(i, form_value))
{
switch (attr)
{
case DW_AT_name:
name.SetCString(form_value.AsCString());
break;
case DW_AT_declaration:
is_forward_declaration = form_value.Boolean();
break;
case DW_AT_byte_size:
byte_size = form_value.Unsigned();
break;
case DW_AT_linkage_name:
linkage_name.SetCString(form_value.AsCString());
break;
default:
assert(false && "Unsupported attribute for DW_TAG_class_type");
}
}
}
UniqueDWARFASTType unique_ast_entry;
if (name)
{
std::string qualified_name;
if (die.GetQualifiedName(qualified_name))
{
name.SetCString(qualified_name.c_str());
if (dwarf->GetUniqueDWARFASTTypeMap().Find(name, die, Declaration(), -1, unique_ast_entry))
{
if (unique_ast_entry.m_type_sp)
{
dwarf->GetDIEToType()[die.GetDIE()] = unique_ast_entry.m_type_sp.get();
is_new_type = false;
return unique_ast_entry.m_type_sp;
}
}
}
}
if (is_forward_declaration)
{
DWARFDeclContext die_decl_ctx;
die.GetDWARFDeclContext(die_decl_ctx);
TypeSP type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
if (type_sp)
{
// We found a real definition for this type elsewhere so lets use it
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
is_new_type = false;
return type_sp;
}
}
CompilerType compiler_type(&m_ast, dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
if (!compiler_type)
compiler_type = m_ast.CreateObjectType(name, linkage_name, byte_size);
is_new_type = true;
TypeSP type_sp(new Type(die.GetID(), dwarf, name,
-1, // byte size isn't specified
nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, &decl, compiler_type,
Type::eResolveStateForward));
// Add our type to the unique type map
unique_ast_entry.m_type_sp = type_sp;
unique_ast_entry.m_die = die;
unique_ast_entry.m_declaration = decl;
unique_ast_entry.m_byte_size = -1;
dwarf->GetUniqueDWARFASTTypeMap().Insert(name, unique_ast_entry);
if (!is_forward_declaration)
{
// Leave this as a forward declaration until we need to know the details of the type
dwarf->GetForwardDeclDieToClangType()[die.GetDIE()] = compiler_type.GetOpaqueQualType();
dwarf->GetForwardDeclClangTypeToDie()[compiler_type.GetOpaqueQualType()] = die.GetDIERef();
}
return type_sp;
}
lldb::TypeSP
DWARFASTParserJava::ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, const DWARFDIE &die,
lldb_private::Log *log, bool *type_is_new_ptr)
{
if (type_is_new_ptr)
*type_is_new_ptr = false;
if (!die)
return nullptr;
SymbolFileDWARF *dwarf = die.GetDWARF();
Type *type_ptr = dwarf->m_die_to_type.lookup(die.GetDIE());
if (type_ptr == DIE_IS_BEING_PARSED)
return nullptr;
if (type_ptr != nullptr)
return type_ptr->shared_from_this();
TypeSP type_sp;
if (type_is_new_ptr)
*type_is_new_ptr = true;
switch (die.Tag())
{
case DW_TAG_base_type:
{
type_sp = ParseBaseTypeFromDIE(die);
break;
}
case DW_TAG_array_type:
{
type_sp = ParseArrayTypeFromDIE(die);
break;
}
case DW_TAG_class_type:
{
bool is_new_type = false;
type_sp = ParseClassTypeFromDIE(die, is_new_type);
if (!is_new_type)
return type_sp;
break;
}
case DW_TAG_reference_type:
{
type_sp = ParseReferenceTypeFromDIE(die);
break;
}
}
if (!type_sp)
return nullptr;
DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die);
dw_tag_t sc_parent_tag = sc_parent_die.Tag();
SymbolContextScope *symbol_context_scope = nullptr;
if (sc_parent_tag == DW_TAG_compile_unit)
{
symbol_context_scope = sc.comp_unit;
}
else if (sc.function != nullptr && sc_parent_die)
{
symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
if (symbol_context_scope == nullptr)
symbol_context_scope = sc.function;
}
if (symbol_context_scope != nullptr)
type_sp->SetSymbolContextScope(symbol_context_scope);
dwarf->GetTypeList()->Insert(type_sp);
dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
return type_sp;
}
lldb_private::Function *
DWARFASTParserJava::ParseFunctionFromDWARF(const lldb_private::SymbolContext &sc, const DWARFDIE &die)
{
assert(die.Tag() == DW_TAG_subprogram);
const char *name = nullptr;
const char *mangled = nullptr;
int decl_file = 0;
int decl_line = 0;
int decl_column = 0;
int call_file = 0;
int call_line = 0;
int call_column = 0;
DWARFRangeList func_ranges;
DWARFExpression frame_base(die.GetCU());
if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line, decl_column, call_file, call_line,
call_column, &frame_base))
{
// Union of all ranges in the function DIE (if the function is discontiguous)
AddressRange func_range;
lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase(0);
lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd(0);
if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr)
{
ModuleSP module_sp(die.GetModule());
func_range.GetBaseAddress().ResolveAddressUsingFileSections(lowest_func_addr, module_sp->GetSectionList());
if (func_range.GetBaseAddress().IsValid())
func_range.SetByteSize(highest_func_addr - lowest_func_addr);
}
if (func_range.GetBaseAddress().IsValid())
{
std::unique_ptr<Declaration> decl_ap;
if (decl_file != 0 || decl_line != 0 || decl_column != 0)
decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), decl_line,
decl_column));
if (die.GetDWARF()->FixupAddress(func_range.GetBaseAddress()))
{
FunctionSP func_sp(new Function(sc.comp_unit, die.GetID(), die.GetID(),
Mangled(ConstString(name), false),
nullptr, // No function types in java
func_range));
if (frame_base.IsValid())
func_sp->GetFrameBaseExpression() = frame_base;
sc.comp_unit->AddFunction(func_sp);
return func_sp.get();
}
}
}
return nullptr;
}
bool
DWARFASTParserJava::CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type,
lldb_private::CompilerType &java_type)
{
switch (die.Tag())
{
case DW_TAG_class_type:
{
if (die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 0)
{
if (die.HasChildren())
ParseChildMembers(die, java_type);
m_ast.CompleteObjectType(java_type);
return java_type.IsValid();
}
}
default:
assert(false && "Not a forward java type declaration!");
break;
}
return false;
}
void
DWARFASTParserJava::ParseChildMembers(const DWARFDIE &parent_die, CompilerType &compiler_type)
{
DWARFCompileUnit *dwarf_cu = parent_die.GetCU();
for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); die = die.GetSibling())
{
switch (die.Tag())
{
case DW_TAG_member:
{
const char *name = nullptr;
lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
uint32_t member_byte_offset = UINT32_MAX;
DWARFExpression member_location_expression(dwarf_cu);
bool artificial = true;
DWARFAttributes attributes;
size_t num_attributes = die.GetAttributes(attributes);
for (size_t i = 0; i < num_attributes; ++i)
{
DWARFFormValue form_value;
if (attributes.ExtractFormValueAtIndex(i, form_value))
{
switch (attributes.AttributeAtIndex(i))
{
case DW_AT_name:
name = form_value.AsCString();
break;
case DW_AT_type:
encoding_uid = form_value.Reference();
break;
case DW_AT_data_member_location:
if (form_value.BlockData())
member_location_expression.CopyOpcodeData(
form_value.BlockData(), form_value.Unsigned(), dwarf_cu->GetByteOrder(),
dwarf_cu->GetAddressByteSize());
else
member_byte_offset = form_value.Unsigned();
break;
case DW_AT_artificial:
artificial = form_value.Boolean();
break;
case DW_AT_accessibility:
// TODO: Handle when needed
break;
default:
assert(false && "Unhandled attribute for DW_TAG_member");
break;
}
}
}
if (strcmp(name, ".dynamic_type") == 0)
m_ast.SetDynamicTypeId(compiler_type, member_location_expression);
else
{
if (Type *member_type = die.ResolveTypeUID(encoding_uid))
m_ast.AddMemberToObject(compiler_type, ConstString(name), member_type->GetFullCompilerType(),
member_byte_offset);
}
break;
}
case DW_TAG_inheritance:
{
lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
uint32_t member_byte_offset = UINT32_MAX;
DWARFAttributes attributes;
size_t num_attributes = die.GetAttributes(attributes);
for (size_t i = 0; i < num_attributes; ++i)
{
DWARFFormValue form_value;
if (attributes.ExtractFormValueAtIndex(i, form_value))
{
switch (attributes.AttributeAtIndex(i))
{
case DW_AT_type:
encoding_uid = form_value.Reference();
break;
case DW_AT_data_member_location:
member_byte_offset = form_value.Unsigned();
break;
case DW_AT_accessibility:
// In java all base class is public so we can ignore this attribute
break;
default:
assert(false && "Unhandled attribute for DW_TAG_member");
break;
}
}
}
if (Type *base_type = die.ResolveTypeUID(encoding_uid))
m_ast.AddBaseClassToObject(compiler_type, base_type->GetFullCompilerType(), member_byte_offset);
break;
}
default:
break;
}
}
}

View File

@ -0,0 +1,90 @@
//===-- DWARFASTParserJava.h ------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef SymbolFileDWARF_DWARFASTParserJava_h_
#define SymbolFileDWARF_DWARFASTParserJava_h_
// C Includes
// C++ Includes
// Other libraries and framework includes
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
// Project includes
#include "DWARFASTParser.h"
#include "DWARFDIE.h"
#include "DWARFDefines.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Symbol/JavaASTContext.h"
class DWARFDebugInfoEntry;
class DWARFDIECollection;
class DWARFASTParserJava : public DWARFASTParser
{
public:
DWARFASTParserJava(lldb_private::JavaASTContext &ast);
~DWARFASTParserJava() override;
lldb::TypeSP
ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, const DWARFDIE &die, lldb_private::Log *log,
bool *type_is_new_ptr) override;
lldb_private::Function *
ParseFunctionFromDWARF(const lldb_private::SymbolContext &sc, const DWARFDIE &die) override;
bool
CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type,
lldb_private::CompilerType &java_type) override;
lldb_private::CompilerDeclContext
GetDeclContextForUIDFromDWARF(const DWARFDIE &die) override
{
return lldb_private::CompilerDeclContext();
}
lldb_private::CompilerDeclContext
GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) override
{
return lldb_private::CompilerDeclContext();
}
lldb_private::CompilerDecl
GetDeclForUIDFromDWARF(const DWARFDIE &die) override
{
return lldb_private::CompilerDecl();
}
std::vector<DWARFDIE>
GetDIEForDeclContext(lldb_private::CompilerDeclContext decl_context) override
{
return std::vector<DWARFDIE>();
}
void
ParseChildMembers(const DWARFDIE &parent_die, lldb_private::CompilerType &class_compiler_type);
private:
lldb_private::JavaASTContext &m_ast;
lldb::TypeSP
ParseBaseTypeFromDIE(const DWARFDIE &die);
lldb::TypeSP
ParseArrayTypeFromDIE(const DWARFDIE &die);
lldb::TypeSP
ParseReferenceTypeFromDIE(const DWARFDIE &die);
lldb::TypeSP
ParseClassTypeFromDIE(const DWARFDIE &die, bool &is_new_type);
};
#endif // SymbolFileDWARF_DWARFASTParserJava_h_

View File

@ -1024,10 +1024,10 @@ DWARFCompileUnit::IndexPrivate (DWARFCompileUnit* dwarf_cu,
case DW_TAG_union_type:
case DW_TAG_typedef:
case DW_TAG_unspecified_type:
if (name && is_declaration == false)
{
if (name && !is_declaration)
types.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset()));
}
if (mangled_cstr && !is_declaration)
types.Insert (ConstString(mangled_cstr), DIERef(cu_offset, die.GetOffset()));
break;
case DW_TAG_namespace:
@ -1259,3 +1259,9 @@ DWARFCompileUnit::SetAddrBase(dw_addr_t addr_base, dw_offset_t base_obj_offset)
m_addr_base = addr_base;
m_base_obj_offset = base_obj_offset;
}
lldb::ByteOrder
DWARFCompileUnit::GetByteOrder() const
{
return m_dwarf2Data->GetObjectFile()->GetByteOrder();
}

View File

@ -59,6 +59,8 @@ public:
void BuildAddressRangeTable (SymbolFileDWARF* dwarf2Data,
DWARFDebugAranges* debug_aranges);
lldb::ByteOrder
GetByteOrder() const;
lldb_private::TypeSystem *
GetTypeSystem();

View File

@ -70,6 +70,7 @@ public:
friend class DWARFCompileUnit;
friend class DWARFASTParserClang;
friend class DWARFASTParserGo;
friend class DWARFASTParserJava;
//------------------------------------------------------------------
// Static Functions

View File

@ -16,6 +16,7 @@ add_lldb_library(lldbSymbol
Function.cpp
FuncUnwinders.cpp
GoASTContext.cpp
JavaASTContext.cpp
LineEntry.cpp
LineTable.cpp
ObjectFile.cpp

File diff suppressed because it is too large Load Diff