Imported Upstream version 6.10.0.49

Former-commit-id: 1d6753294b2993e1fbf92de9366bb9544db4189b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2020-01-16 16:38:04 +00:00
parent d94e79959b
commit 468663ddbb
48518 changed files with 2789335 additions and 61176 deletions

View File

@ -0,0 +1,54 @@
add_lldb_library(lldbPluginSymbolFileDWARF PLUGIN
DIERef.cpp
DWARFAbbreviationDeclaration.cpp
DWARFASTParserClang.cpp
DWARFASTParserGo.cpp
DWARFASTParserJava.cpp
DWARFASTParserOCaml.cpp
DWARFAttribute.cpp
DWARFCompileUnit.cpp
DWARFDataExtractor.cpp
DWARFDebugAbbrev.cpp
DWARFDebugAranges.cpp
DWARFDebugArangeSet.cpp
DWARFDebugInfo.cpp
DWARFDebugInfoEntry.cpp
DWARFDebugLine.cpp
DWARFDebugMacro.cpp
DWARFDebugMacinfo.cpp
DWARFDebugMacinfoEntry.cpp
DWARFDebugPubnames.cpp
DWARFDebugPubnamesSet.cpp
DWARFDebugRanges.cpp
DWARFDeclContext.cpp
DWARFDefines.cpp
DWARFDIE.cpp
DWARFDIECollection.cpp
DWARFFormValue.cpp
HashedNameToDIE.cpp
LogChannelDWARF.cpp
NameToDIE.cpp
SymbolFileDWARF.cpp
SymbolFileDWARFDwo.cpp
SymbolFileDWARFDwoDwp.cpp
SymbolFileDWARFDwp.cpp
SymbolFileDWARFDebugMap.cpp
UniqueDWARFASTType.cpp
LINK_LIBS
clangAST
clangBasic
lldbCore
lldbExpression
lldbHost
lldbInterpreter
lldbSymbol
lldbTarget
lldbUtility
lldbPluginObjCLanguage
lldbPluginCPlusPlusLanguage
lldbPluginExpressionParserClang
LINK_COMPONENTS
DebugInfoDWARF
Support
)

View File

@ -0,0 +1,72 @@
//===-- DIERef.cpp ----------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "DIERef.h"
#include "DWARFCompileUnit.h"
#include "DWARFDebugInfo.h"
#include "DWARFFormValue.h"
#include "SymbolFileDWARF.h"
#include "SymbolFileDWARFDebugMap.h"
DIERef::DIERef()
: cu_offset(DW_INVALID_OFFSET), die_offset(DW_INVALID_OFFSET) {}
DIERef::DIERef(dw_offset_t c, dw_offset_t d) : cu_offset(c), die_offset(d) {}
DIERef::DIERef(lldb::user_id_t uid, SymbolFileDWARF *dwarf)
: cu_offset(DW_INVALID_OFFSET), die_offset(uid & 0xffffffff) {
SymbolFileDWARFDebugMap *debug_map = dwarf->GetDebugMapSymfile();
if (debug_map) {
const uint32_t oso_idx = debug_map->GetOSOIndexFromUserID(uid);
SymbolFileDWARF *actual_dwarf = debug_map->GetSymbolFileByOSOIndex(oso_idx);
if (actual_dwarf) {
DWARFDebugInfo *debug_info = actual_dwarf->DebugInfo();
if (debug_info) {
DWARFCompileUnit *dwarf_cu =
debug_info->GetCompileUnitContainingDIEOffset(die_offset);
if (dwarf_cu) {
cu_offset = dwarf_cu->GetOffset();
return;
}
}
}
die_offset = DW_INVALID_OFFSET;
} else {
cu_offset = uid >> 32;
}
}
DIERef::DIERef(const DWARFFormValue &form_value)
: cu_offset(DW_INVALID_OFFSET), die_offset(DW_INVALID_OFFSET) {
if (form_value.IsValid()) {
const DWARFCompileUnit *dwarf_cu = form_value.GetCompileUnit();
if (dwarf_cu) {
if (dwarf_cu->GetBaseObjOffset() != DW_INVALID_OFFSET)
cu_offset = dwarf_cu->GetBaseObjOffset();
else
cu_offset = dwarf_cu->GetOffset();
}
die_offset = form_value.Reference();
}
}
lldb::user_id_t DIERef::GetUID(SymbolFileDWARF *dwarf) const {
//----------------------------------------------------------------------
// Each SymbolFileDWARF will set its ID to what is expected.
//
// SymbolFileDWARF, when used for DWARF with .o files on MacOSX, has the
// ID set to the compile unit index.
//
// SymbolFileDWARFDwo sets the ID to the compile unit offset.
//----------------------------------------------------------------------
if (dwarf && die_offset != DW_INVALID_OFFSET)
return dwarf->GetID() | die_offset;
else
return LLDB_INVALID_UID;
}

View File

@ -0,0 +1,54 @@
//===-- DIERef.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_DIERef_h_
#define SymbolFileDWARF_DIERef_h_
#include "lldb/Core/dwarf.h"
#include "lldb/lldb-defines.h"
class DWARFFormValue;
class SymbolFileDWARF;
struct DIERef {
DIERef();
DIERef(dw_offset_t c, dw_offset_t d);
//----------------------------------------------------------------------
// In order to properly decode a lldb::user_id_t back into a DIERef we
// need the DWARF file since it knows if DWARF in .o files is being used
// (MacOSX) or if DWO files are being used. The encoding of the user ID
// differs between the two types of DWARF.
//----------------------------------------------------------------------
explicit DIERef(lldb::user_id_t uid, SymbolFileDWARF *dwarf);
explicit DIERef(const DWARFFormValue &form_value);
//----------------------------------------------------------------------
// In order to properly encode a DIERef unto a lldb::user_id_t we need
// the DWARF file since it knows if DWARF in .o files is being used
// (MacOSX) or if DWO files are being used. The encoding of the user ID
// differs between the two types of DWARF.
//----------------------------------------------------------------------
lldb::user_id_t GetUID(SymbolFileDWARF *dwarf) const;
bool operator<(const DIERef &ref) const {
return die_offset < ref.die_offset;
}
bool operator<(const DIERef &ref) { return die_offset < ref.die_offset; }
dw_offset_t cu_offset;
dw_offset_t die_offset;
};
typedef std::vector<DIERef> DIEArray;
#endif // SymbolFileDWARF_DIERef_h_

View File

@ -0,0 +1,50 @@
//===-- DWARFASTParser.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_DWARFASTParser_h_
#define SymbolFileDWARF_DWARFASTParser_h_
#include "DWARFDefines.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Symbol/CompilerDecl.h"
#include "lldb/Symbol/CompilerDeclContext.h"
class DWARFDIE;
class DWARFASTParser {
public:
virtual ~DWARFASTParser() {}
virtual lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc,
const DWARFDIE &die,
lldb_private::Log *log,
bool *type_is_new_ptr) = 0;
virtual lldb_private::Function *
ParseFunctionFromDWARF(const lldb_private::SymbolContext &sc,
const DWARFDIE &die) = 0;
virtual bool
CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type,
lldb_private::CompilerType &compiler_type) = 0;
virtual lldb_private::CompilerDecl
GetDeclForUIDFromDWARF(const DWARFDIE &die) = 0;
virtual lldb_private::CompilerDeclContext
GetDeclContextForUIDFromDWARF(const DWARFDIE &die) = 0;
virtual lldb_private::CompilerDeclContext
GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) = 0;
virtual std::vector<DWARFDIE>
GetDIEForDeclContext(lldb_private::CompilerDeclContext decl_context) = 0;
};
#endif // SymbolFileDWARF_DWARFASTParser_h_

View File

@ -0,0 +1 @@
54b12cfb3b8cfb694206fac696016b15c1cab674

View File

@ -0,0 +1,161 @@
//===-- DWARFASTParserClang.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_DWARFASTParserClang_h_
#define SymbolFileDWARF_DWARFASTParserClang_h_
// C Includes
// C++ Includes
// Other libraries and framework includes
#include "clang/AST/CharUnits.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
// Project includes
#include "DWARFASTParser.h"
#include "DWARFDefines.h"
#include "lldb/Core/ClangForward.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/ClangASTImporter.h"
class DWARFDebugInfoEntry;
class DWARFDIECollection;
class DWARFASTParserClang : public DWARFASTParser {
public:
DWARFASTParserClang(lldb_private::ClangASTContext &ast);
~DWARFASTParserClang() override;
// DWARFASTParser interface.
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 &compiler_type) override;
lldb_private::CompilerDecl
GetDeclForUIDFromDWARF(const DWARFDIE &die) override;
std::vector<DWARFDIE>
GetDIEForDeclContext(lldb_private::CompilerDeclContext decl_context) override;
lldb_private::CompilerDeclContext
GetDeclContextForUIDFromDWARF(const DWARFDIE &die) override;
lldb_private::CompilerDeclContext
GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) override;
lldb_private::ClangASTImporter &GetClangASTImporter();
protected:
class DelayedAddObjCClassProperty;
typedef std::vector<DelayedAddObjCClassProperty> DelayedPropertyList;
clang::DeclContext *GetDeclContextForBlock(const DWARFDIE &die);
clang::BlockDecl *ResolveBlockDIE(const DWARFDIE &die);
clang::NamespaceDecl *ResolveNamespaceDIE(const DWARFDIE &die);
bool ParseTemplateDIE(const DWARFDIE &die,
lldb_private::ClangASTContext::TemplateParameterInfos
&template_param_infos);
bool ParseTemplateParameterInfos(
const DWARFDIE &parent_die,
lldb_private::ClangASTContext::TemplateParameterInfos
&template_param_infos);
bool
ParseChildMembers(const lldb_private::SymbolContext &sc, const DWARFDIE &die,
lldb_private::CompilerType &class_compiler_type,
const lldb::LanguageType class_language,
std::vector<clang::CXXBaseSpecifier *> &base_classes,
std::vector<int> &member_accessibilities,
DWARFDIECollection &member_function_dies,
DelayedPropertyList &delayed_properties,
lldb::AccessType &default_accessibility, bool &is_a_class,
lldb_private::ClangASTImporter::LayoutInfo &layout_info);
size_t
ParseChildParameters(const lldb_private::SymbolContext &sc,
clang::DeclContext *containing_decl_ctx,
const DWARFDIE &parent_die, bool skip_artificial,
bool &is_static, bool &is_variadic,
bool &has_template_params,
std::vector<lldb_private::CompilerType> &function_args,
std::vector<clang::ParmVarDecl *> &function_param_decls,
unsigned &type_quals);
void ParseChildArrayInfo(const lldb_private::SymbolContext &sc,
const DWARFDIE &parent_die, int64_t &first_index,
std::vector<uint64_t> &element_orders,
uint32_t &byte_stride, uint32_t &bit_stride);
size_t ParseChildEnumerators(const lldb_private::SymbolContext &sc,
lldb_private::CompilerType &compiler_type,
bool is_signed, uint32_t enumerator_byte_size,
const DWARFDIE &parent_die);
lldb_private::Type *GetTypeForDIE(const DWARFDIE &die);
clang::Decl *GetClangDeclForDIE(const DWARFDIE &die);
clang::DeclContext *GetClangDeclContextForDIE(const DWARFDIE &die);
clang::DeclContext *GetClangDeclContextContainingDIE(const DWARFDIE &die,
DWARFDIE *decl_ctx_die);
bool CopyUniqueClassMethodTypes(const DWARFDIE &src_class_die,
const DWARFDIE &dst_class_die,
lldb_private::Type *class_type,
DWARFDIECollection &failures);
clang::DeclContext *GetCachedClangDeclContextForDIE(const DWARFDIE &die);
void LinkDeclContextToDIE(clang::DeclContext *decl_ctx, const DWARFDIE &die);
void LinkDeclToDIE(clang::Decl *decl, const DWARFDIE &die);
lldb::TypeSP ParseTypeFromDWO(const DWARFDIE &die, lldb_private::Log *log);
//----------------------------------------------------------------------
// Return true if this type is a declaration to a type in an external
// module.
//----------------------------------------------------------------------
lldb::ModuleSP GetModuleForType(const DWARFDIE &die);
typedef llvm::SmallPtrSet<const DWARFDebugInfoEntry *, 4> DIEPointerSet;
typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::DeclContext *>
DIEToDeclContextMap;
// typedef llvm::DenseMap<const clang::DeclContext *, DIEPointerSet>
// DeclContextToDIEMap;
typedef std::multimap<const clang::DeclContext *, const DWARFDIE>
DeclContextToDIEMap;
typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::Decl *>
DIEToDeclMap;
typedef llvm::DenseMap<const clang::Decl *, DIEPointerSet> DeclToDIEMap;
lldb_private::ClangASTContext &m_ast;
DIEToDeclMap m_die_to_decl;
DeclToDIEMap m_decl_to_die;
DIEToDeclContextMap m_die_to_decl_ctx;
DeclContextToDIEMap m_decl_ctx_to_die;
std::unique_ptr<lldb_private::ClangASTImporter> m_clang_ast_importer_ap;
};
#endif // SymbolFileDWARF_DWARFASTParserClang_h_

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,84 @@
//===-- DWARFASTParserGo.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_DWARFASTParserGo_h_
#define SymbolFileDWARF_DWARFASTParserGo_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/GoASTContext.h"
class DWARFDebugInfoEntry;
class DWARFDIECollection;
class DWARFASTParserGo : public DWARFASTParser {
public:
DWARFASTParserGo(lldb_private::GoASTContext &ast);
~DWARFASTParserGo() 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 &go_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>();
}
private:
size_t ParseChildParameters(
const lldb_private::SymbolContext &sc, const DWARFDIE &parent_die,
bool &is_variadic,
std::vector<lldb_private::CompilerType> &function_param_types);
void ParseChildArrayInfo(const lldb_private::SymbolContext &sc,
const DWARFDIE &parent_die, int64_t &first_index,
std::vector<uint64_t> &element_orders,
uint32_t &byte_stride, uint32_t &bit_stride);
size_t ParseChildMembers(const lldb_private::SymbolContext &sc,
const DWARFDIE &die,
lldb_private::CompilerType &class_compiler_type);
lldb_private::GoASTContext &m_ast;
};
#endif // SymbolFileDWARF_DWARFASTParserGo_h_

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,81 @@
//===-- 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

@ -0,0 +1,209 @@
//===-- DWARFASTParserOCaml.cpp ---------------------------------*- C++ -*-===//
#include "DWARFASTParserOCaml.h"
#include "lldb/Core/Module.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Status.h"
using namespace lldb;
using namespace lldb_private;
DWARFASTParserOCaml::DWARFASTParserOCaml(OCamlASTContext &ast) : m_ast(ast) {}
DWARFASTParserOCaml::~DWARFASTParserOCaml() {}
TypeSP DWARFASTParserOCaml::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, byte_size);
return std::make_shared<Type>(die.GetID(), dwarf, type_name, byte_size,
nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID,
decl, compiler_type, Type::eResolveStateFull);
}
lldb::TypeSP DWARFASTParserOCaml::ParseTypeFromDWARF(const SymbolContext &sc,
const DWARFDIE &die,
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: {
break;
}
case DW_TAG_class_type: {
break;
}
case DW_TAG_reference_type: {
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;
}
Function *DWARFASTParserOCaml::ParseFunctionFromDWARF(const SymbolContext &sc,
const DWARFDIE &die) {
DWARFRangeList func_ranges;
const char *name = NULL;
const char *mangled = NULL;
int decl_file = 0;
int decl_line = 0;
int decl_column = 0;
int call_file = 0;
int call_line = 0;
int call_column = 0;
DWARFExpression frame_base(die.GetCU());
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE));
if (die) {
SymbolFileDWARF *dwarf = die.GetDWARF();
if (log) {
dwarf->GetObjectFile()->GetModule()->LogMessage(
log, "DWARFASTParserOCaml::ParseFunctionFromDWARF (die = 0x%8.8x) %s "
"name = '%s')",
die.GetOffset(), DW_TAG_value_to_name(die.Tag()), die.GetName());
}
}
assert(die.Tag() == DW_TAG_subprogram);
if (die.Tag() != DW_TAG_subprogram)
return NULL;
if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line,
decl_column, call_file, call_line, call_column,
&frame_base)) {
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()) {
Mangled func_name;
func_name.SetValue(ConstString(name), true);
FunctionSP func_sp;
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));
SymbolFileDWARF *dwarf = die.GetDWARF();
Type *func_type = dwarf->m_die_to_type.lookup(die.GetDIE());
assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
if (dwarf->FixupAddress(func_range.GetBaseAddress())) {
const user_id_t func_user_id = die.GetID();
func_sp.reset(new Function(sc.comp_unit,
func_user_id, // UserID is the DIE offset
func_user_id, func_name, func_type,
func_range)); // first address range
if (func_sp.get() != NULL) {
if (frame_base.IsValid())
func_sp->GetFrameBaseExpression() = frame_base;
sc.comp_unit->AddFunction(func_sp);
return func_sp.get();
}
}
}
}
return NULL;
}
lldb_private::CompilerDeclContext
DWARFASTParserOCaml::GetDeclContextForUIDFromDWARF(const DWARFDIE &die) {
return CompilerDeclContext();
}
lldb_private::CompilerDeclContext
DWARFASTParserOCaml::GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) {
return CompilerDeclContext();
}

View File

@ -0,0 +1,60 @@
//===-- DWARFASTParserOCaml.h -----------------------------------*- C++ -*-===//
#ifndef SymbolFileDWARF_DWARFASTParserOCaml_h_
#define SymbolFileDWARF_DWARFASTParserOCaml_h_
#include "DWARFASTParser.h"
#include "DWARFCompileUnit.h"
#include "DWARFDIE.h"
#include "DWARFDebugInfo.h"
#include "DWARFDefines.h"
#include "SymbolFileDWARF.h"
#include "lldb/Symbol/OCamlASTContext.h"
class DWARFDebugInfoEntry;
class DWARFDIECollection;
class DWARFASTParserOCaml : public DWARFASTParser {
public:
DWARFASTParserOCaml(lldb_private::OCamlASTContext &ast);
virtual ~DWARFASTParserOCaml();
lldb::TypeSP ParseBaseTypeFromDIE(const DWARFDIE &die);
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 &compiler_type) override {
return false;
}
lldb_private::CompilerDecl
GetDeclForUIDFromDWARF(const DWARFDIE &die) override {
return lldb_private::CompilerDecl();
}
lldb_private::CompilerDeclContext
GetDeclContextForUIDFromDWARF(const DWARFDIE &die) override;
lldb_private::CompilerDeclContext
GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) override;
std::vector<DWARFDIE> GetDIEForDeclContext(
lldb_private::CompilerDeclContext decl_context) override {
return {};
}
protected:
lldb_private::OCamlASTContext &m_ast;
};
#endif // SymbolFileDWARF_DWARFASTParserOCaml_h_

View File

@ -0,0 +1,94 @@
//===-- DWARFAbbreviationDeclaration.cpp ------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "DWARFAbbreviationDeclaration.h"
#include "lldb/Core/dwarf.h"
#include "DWARFFormValue.h"
using namespace lldb_private;
DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration()
: m_code(InvalidCode), m_tag(0), m_has_children(0), m_attributes() {}
DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration(dw_tag_t tag,
uint8_t has_children)
: m_code(InvalidCode), m_tag(tag), m_has_children(has_children),
m_attributes() {}
bool DWARFAbbreviationDeclaration::Extract(const DWARFDataExtractor &data,
lldb::offset_t *offset_ptr) {
return Extract(data, offset_ptr, data.GetULEB128(offset_ptr));
}
bool DWARFAbbreviationDeclaration::Extract(const DWARFDataExtractor &data,
lldb::offset_t *offset_ptr,
dw_uleb128_t code) {
m_code = code;
m_attributes.clear();
if (m_code) {
m_tag = data.GetULEB128(offset_ptr);
m_has_children = data.GetU8(offset_ptr);
while (data.ValidOffset(*offset_ptr)) {
dw_attr_t attr = data.GetULEB128(offset_ptr);
dw_form_t form = data.GetULEB128(offset_ptr);
if (attr && form)
m_attributes.push_back(DWARFAttribute(attr, form));
else
break;
}
return m_tag != 0;
} else {
m_tag = 0;
m_has_children = 0;
}
return false;
}
void DWARFAbbreviationDeclaration::Dump(Stream *s) const {
s->Printf("Debug Abbreviation Declaration: code = 0x%4.4x, tag = %s, "
"has_children = %s\n",
m_code, DW_TAG_value_to_name(m_tag),
DW_CHILDREN_value_to_name(m_has_children));
DWARFAttribute::const_iterator pos;
for (pos = m_attributes.begin(); pos != m_attributes.end(); ++pos)
s->Printf(" attr = %s, form = %s\n",
DW_AT_value_to_name(pos->get_attr()),
DW_FORM_value_to_name(pos->get_form()));
s->Printf("\n");
}
bool DWARFAbbreviationDeclaration::IsValid() {
return m_code != 0 && m_tag != 0;
}
uint32_t
DWARFAbbreviationDeclaration::FindAttributeIndex(dw_attr_t attr) const {
uint32_t i;
const uint32_t kNumAttributes = m_attributes.size();
for (i = 0; i < kNumAttributes; ++i) {
if (m_attributes[i].get_attr() == attr)
return i;
}
return DW_INVALID_INDEX;
}
bool DWARFAbbreviationDeclaration::
operator==(const DWARFAbbreviationDeclaration &rhs) const {
return Tag() == rhs.Tag() && HasChildren() == rhs.HasChildren() &&
Attributes() == rhs.Attributes();
}

View File

@ -0,0 +1,75 @@
//===-- DWARFAbbreviationDeclaration.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_DWARFAbbreviationDeclaration_h_
#define liblldb_DWARFAbbreviationDeclaration_h_
#include "DWARFAttribute.h"
#include "SymbolFileDWARF.h"
class DWARFCompileUnit;
class DWARFAbbreviationDeclaration {
public:
enum { InvalidCode = 0 };
DWARFAbbreviationDeclaration();
// For hand crafting an abbreviation declaration
DWARFAbbreviationDeclaration(dw_tag_t tag, uint8_t has_children);
void AddAttribute(const DWARFAttribute &attr) {
m_attributes.push_back(attr);
}
dw_uleb128_t Code() const { return m_code; }
void SetCode(dw_uleb128_t code) { m_code = code; }
dw_tag_t Tag() const { return m_tag; }
bool HasChildren() const { return m_has_children; }
size_t NumAttributes() const { return m_attributes.size(); }
dw_attr_t GetAttrByIndex(uint32_t idx) const {
return m_attributes.size() > idx ? m_attributes[idx].get_attr() : 0;
}
dw_form_t GetFormByIndex(uint32_t idx) const {
return m_attributes.size() > idx ? m_attributes[idx].get_form() : 0;
}
bool GetAttrAndFormByIndex(uint32_t idx, dw_attr_t &attr,
dw_form_t &form) const {
if (m_attributes.size() > idx) {
m_attributes[idx].get(attr, form);
return true;
}
attr = form = 0;
return false;
}
// idx is assumed to be valid when calling GetAttrAndFormByIndexUnchecked()
void GetAttrAndFormByIndexUnchecked(uint32_t idx, dw_attr_t &attr,
dw_form_t &form) const {
m_attributes[idx].get(attr, form);
}
dw_form_t GetFormByIndexUnchecked(uint32_t idx) const {
return m_attributes[idx].get_form();
}
uint32_t FindAttributeIndex(dw_attr_t attr) const;
bool Extract(const lldb_private::DWARFDataExtractor &data,
lldb::offset_t *offset_ptr);
bool Extract(const lldb_private::DWARFDataExtractor &data,
lldb::offset_t *offset_ptr, dw_uleb128_t code);
bool IsValid();
void Dump(lldb_private::Stream *s) const;
bool operator==(const DWARFAbbreviationDeclaration &rhs) const;
const DWARFAttribute::collection &Attributes() const { return m_attributes; }
protected:
dw_uleb128_t m_code;
dw_tag_t m_tag;
uint8_t m_has_children;
DWARFAttribute::collection m_attributes;
};
#endif // liblldb_DWARFAbbreviationDeclaration_h_

View File

@ -0,0 +1,74 @@
//===-- DWARFAttribute.cpp --------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "DWARFAttribute.h"
#include "DWARFCompileUnit.h"
#include "DWARFDebugInfo.h"
DWARFAttributes::DWARFAttributes() : m_infos() {}
DWARFAttributes::~DWARFAttributes() {}
uint32_t DWARFAttributes::FindAttributeIndex(dw_attr_t attr) const {
collection::const_iterator end = m_infos.end();
collection::const_iterator beg = m_infos.begin();
collection::const_iterator pos;
for (pos = beg; pos != end; ++pos) {
if (pos->attr.get_attr() == attr)
return std::distance(beg, pos);
}
return UINT32_MAX;
}
void DWARFAttributes::Append(const DWARFCompileUnit *cu,
dw_offset_t attr_die_offset, dw_attr_t attr,
dw_form_t form) {
AttributeValue attr_value = {cu, attr_die_offset, {attr, form}};
m_infos.push_back(attr_value);
}
bool DWARFAttributes::ContainsAttribute(dw_attr_t attr) const {
return FindAttributeIndex(attr) != UINT32_MAX;
}
bool DWARFAttributes::RemoveAttribute(dw_attr_t attr) {
uint32_t attr_index = FindAttributeIndex(attr);
if (attr_index != UINT32_MAX) {
m_infos.erase(m_infos.begin() + attr_index);
return true;
}
return false;
}
bool DWARFAttributes::ExtractFormValueAtIndex(
uint32_t i, DWARFFormValue &form_value) const {
const DWARFCompileUnit *cu = CompileUnitAtIndex(i);
form_value.SetCompileUnit(cu);
form_value.SetForm(FormAtIndex(i));
lldb::offset_t offset = DIEOffsetAtIndex(i);
return form_value.ExtractValue(
cu->GetSymbolFileDWARF()->get_debug_info_data(), &offset);
}
uint64_t DWARFAttributes::FormValueAsUnsigned(dw_attr_t attr,
uint64_t fail_value) const {
const uint32_t attr_idx = FindAttributeIndex(attr);
if (attr_idx != UINT32_MAX)
return FormValueAsUnsignedAtIndex(attr_idx, fail_value);
return fail_value;
}
uint64_t
DWARFAttributes::FormValueAsUnsignedAtIndex(uint32_t i,
uint64_t fail_value) const {
DWARFFormValue form_value;
if (ExtractFormValueAtIndex(i, form_value))
return form_value.Reference();
return fail_value;
}

View File

@ -0,0 +1,85 @@
//===-- DWARFAttribute.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_DWARFAttribute_h_
#define SymbolFileDWARF_DWARFAttribute_h_
#include "DWARFDefines.h"
#include "llvm/ADT/SmallVector.h"
#include <vector>
class DWARFCompileUnit;
class DWARFFormValue;
class DWARFAttribute {
public:
DWARFAttribute(dw_attr_t attr, dw_form_t form) : m_attr(attr), m_form(form) {}
void set(dw_attr_t attr, dw_form_t form) {
m_attr = attr;
m_form = form;
}
void set_attr(dw_attr_t attr) { m_attr = attr; }
void set_form(dw_form_t form) { m_form = form; }
dw_attr_t get_attr() const { return m_attr; }
dw_form_t get_form() const { return m_form; }
void get(dw_attr_t &attr, dw_form_t &form) const {
attr = m_attr;
form = m_form;
}
bool operator==(const DWARFAttribute &rhs) const {
return m_attr == rhs.m_attr && m_form == rhs.m_form;
}
typedef std::vector<DWARFAttribute> collection;
typedef collection::iterator iterator;
typedef collection::const_iterator const_iterator;
protected:
dw_attr_t m_attr;
dw_form_t m_form;
};
class DWARFAttributes {
public:
DWARFAttributes();
~DWARFAttributes();
void Append(const DWARFCompileUnit *cu, dw_offset_t attr_die_offset,
dw_attr_t attr, dw_form_t form);
const DWARFCompileUnit *CompileUnitAtIndex(uint32_t i) const {
return m_infos[i].cu;
}
dw_offset_t DIEOffsetAtIndex(uint32_t i) const {
return m_infos[i].die_offset;
}
dw_attr_t AttributeAtIndex(uint32_t i) const {
return m_infos[i].attr.get_attr();
}
dw_attr_t FormAtIndex(uint32_t i) const { return m_infos[i].attr.get_form(); }
bool ExtractFormValueAtIndex(uint32_t i, DWARFFormValue &form_value) const;
uint64_t FormValueAsUnsignedAtIndex(uint32_t i, uint64_t fail_value) const;
uint64_t FormValueAsUnsigned(dw_attr_t attr, uint64_t fail_value) const;
uint32_t FindAttributeIndex(dw_attr_t attr) const;
bool ContainsAttribute(dw_attr_t attr) const;
bool RemoveAttribute(dw_attr_t attr);
void Clear() { m_infos.clear(); }
size_t Size() const { return m_infos.size(); }
protected:
struct AttributeValue {
const DWARFCompileUnit *cu; // Keep the compile unit with each attribute in
// case we have DW_FORM_ref_addr values
dw_offset_t die_offset;
DWARFAttribute attr;
};
typedef llvm::SmallVector<AttributeValue, 8> collection;
collection m_infos;
};
#endif // SymbolFileDWARF_DWARFAttribute_h_

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,224 @@
//===-- DWARFCompileUnit.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_DWARFCompileUnit_h_
#define SymbolFileDWARF_DWARFCompileUnit_h_
#include "DWARFDIE.h"
#include "DWARFDebugInfoEntry.h"
#include "lldb/lldb-enumerations.h"
class NameToDIE;
class SymbolFileDWARF;
class SymbolFileDWARFDwo;
typedef std::shared_ptr<DWARFCompileUnit> DWARFCompileUnitSP;
class DWARFCompileUnit {
public:
enum Producer {
eProducerInvalid = 0,
eProducerClang,
eProducerGCC,
eProducerLLVMGCC,
eProcucerOther
};
static DWARFCompileUnitSP Extract(SymbolFileDWARF *dwarf2Data,
lldb::offset_t *offset_ptr);
~DWARFCompileUnit();
size_t ExtractDIEsIfNeeded(bool cu_die_only);
DWARFDIE LookupAddress(const dw_addr_t address);
size_t AppendDIEsWithTag(const dw_tag_t tag,
DWARFDIECollection &matching_dies,
uint32_t depth = UINT32_MAX) const;
bool Verify(lldb_private::Stream *s) const;
void Dump(lldb_private::Stream *s) const;
// Offset of the initial length field.
dw_offset_t GetOffset() const { return m_offset; }
lldb::user_id_t GetID() const;
// Size in bytes of the initial length + compile unit header.
uint32_t Size() const { return m_is_dwarf64 ? 23 : 11; }
bool ContainsDIEOffset(dw_offset_t die_offset) const {
return die_offset >= GetFirstDIEOffset() &&
die_offset < GetNextCompileUnitOffset();
}
dw_offset_t GetFirstDIEOffset() const { return m_offset + Size(); }
dw_offset_t GetNextCompileUnitOffset() const {
return m_offset + (m_is_dwarf64 ? 12 : 4) + m_length;
}
// Size of the CU data (without initial length and without header).
size_t GetDebugInfoSize() const {
return (m_is_dwarf64 ? 12 : 4) + m_length - Size();
}
// Size of the CU data incl. header but without initial length.
uint32_t GetLength() const { return m_length; }
uint16_t GetVersion() const { return m_version; }
const DWARFAbbreviationDeclarationSet *GetAbbreviations() const {
return m_abbrevs;
}
dw_offset_t GetAbbrevOffset() const;
uint8_t GetAddressByteSize() const { return m_addr_size; }
dw_addr_t GetBaseAddress() const { return m_base_addr; }
dw_addr_t GetAddrBase() const { return m_addr_base; }
dw_addr_t GetRangesBase() const { return m_ranges_base; }
void SetAddrBase(dw_addr_t addr_base, dw_addr_t ranges_base, dw_offset_t base_obj_offset);
void ClearDIEs(bool keep_compile_unit_die);
void BuildAddressRangeTable(SymbolFileDWARF *dwarf2Data,
DWARFDebugAranges *debug_aranges);
lldb::ByteOrder GetByteOrder() const;
lldb_private::TypeSystem *GetTypeSystem();
DWARFFormValue::FixedFormSizes GetFixedFormSizes();
void SetBaseAddress(dw_addr_t base_addr) { m_base_addr = base_addr; }
DWARFDIE
GetCompileUnitDIEOnly() { return DWARFDIE(this, GetCompileUnitDIEPtrOnly()); }
DWARFDIE
DIE() { return DWARFDIE(this, DIEPtr()); }
void AddDIE(DWARFDebugInfoEntry &die) {
// The average bytes per DIE entry has been seen to be
// around 14-20 so lets pre-reserve half of that since
// we are now stripping the NULL tags.
// Only reserve the memory if we are adding children of
// the main compile unit DIE. The compile unit DIE is always
// the first entry, so if our size is 1, then we are adding
// the first compile unit child DIE and should reserve
// the memory.
if (m_die_array.empty())
m_die_array.reserve(GetDebugInfoSize() / 24);
m_die_array.push_back(die);
}
void AddCompileUnitDIE(DWARFDebugInfoEntry &die);
bool HasDIEsParsed() const { return m_die_array.size() > 1; }
DWARFDIE
GetDIE(dw_offset_t die_offset);
static uint8_t GetAddressByteSize(const DWARFCompileUnit *cu);
static bool IsDWARF64(const DWARFCompileUnit *cu);
static uint8_t GetDefaultAddressSize();
static void SetDefaultAddressSize(uint8_t addr_size);
void *GetUserData() const { return m_user_data; }
void SetUserData(void *d);
bool Supports_DW_AT_APPLE_objc_complete_type();
bool DW_AT_decl_file_attributes_are_invalid();
bool Supports_unnamed_objc_bitfields();
void Index(NameToDIE &func_basenames, NameToDIE &func_fullnames,
NameToDIE &func_methods, NameToDIE &func_selectors,
NameToDIE &objc_class_selectors, NameToDIE &globals,
NameToDIE &types, NameToDIE &namespaces);
const DWARFDebugAranges &GetFunctionAranges();
SymbolFileDWARF *GetSymbolFileDWARF() const { return m_dwarf2Data; }
Producer GetProducer();
uint32_t GetProducerVersionMajor();
uint32_t GetProducerVersionMinor();
uint32_t GetProducerVersionUpdate();
static lldb::LanguageType LanguageTypeFromDWARF(uint64_t val);
lldb::LanguageType GetLanguageType();
bool IsDWARF64() const;
bool GetIsOptimized();
SymbolFileDWARFDwo *GetDwoSymbolFile() const {
return m_dwo_symbol_file.get();
}
dw_offset_t GetBaseObjOffset() const { return m_base_obj_offset; }
protected:
SymbolFileDWARF *m_dwarf2Data;
std::unique_ptr<SymbolFileDWARFDwo> m_dwo_symbol_file;
const DWARFAbbreviationDeclarationSet *m_abbrevs;
void *m_user_data = nullptr;
DWARFDebugInfoEntry::collection
m_die_array; // The compile unit debug information entry item
std::unique_ptr<DWARFDebugAranges> m_func_aranges_ap; // A table similar to
// the .debug_aranges
// table, but this one
// points to the exact
// DW_TAG_subprogram
// DIEs
dw_addr_t m_base_addr = 0;
// Offset of the initial length field.
dw_offset_t m_offset;
dw_offset_t m_length;
uint16_t m_version;
uint8_t m_addr_size;
Producer m_producer = eProducerInvalid;
uint32_t m_producer_version_major = 0;
uint32_t m_producer_version_minor = 0;
uint32_t m_producer_version_update = 0;
lldb::LanguageType m_language_type = lldb::eLanguageTypeUnknown;
bool m_is_dwarf64;
lldb_private::LazyBool m_is_optimized = lldb_private::eLazyBoolCalculate;
dw_addr_t m_addr_base = 0; // Value of DW_AT_addr_base
dw_addr_t m_ranges_base = 0; // Value of DW_AT_ranges_base
// If this is a dwo compile unit this is the offset of the base compile unit
// in the main object file
dw_offset_t m_base_obj_offset = DW_INVALID_OFFSET;
void ParseProducerInfo();
static void
IndexPrivate(DWARFCompileUnit *dwarf_cu, const lldb::LanguageType cu_language,
const DWARFFormValue::FixedFormSizes &fixed_form_sizes,
const dw_offset_t cu_offset, NameToDIE &func_basenames,
NameToDIE &func_fullnames, NameToDIE &func_methods,
NameToDIE &func_selectors, NameToDIE &objc_class_selectors,
NameToDIE &globals, NameToDIE &types, NameToDIE &namespaces);
private:
DWARFCompileUnit(SymbolFileDWARF *dwarf2Data);
const DWARFDebugInfoEntry *GetCompileUnitDIEPtrOnly() {
ExtractDIEsIfNeeded(true);
if (m_die_array.empty())
return NULL;
return &m_die_array[0];
}
const DWARFDebugInfoEntry *DIEPtr() {
ExtractDIEsIfNeeded(false);
if (m_die_array.empty())
return NULL;
return &m_die_array[0];
}
DISALLOW_COPY_AND_ASSIGN(DWARFCompileUnit);
};
#endif // SymbolFileDWARF_DWARFCompileUnit_h_

View File

@ -0,0 +1,462 @@
//===-- DWARFDIE.cpp --------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "DWARFDIE.h"
#include "DWARFASTParser.h"
#include "DWARFCompileUnit.h"
#include "DWARFDIECollection.h"
#include "DWARFDebugAbbrev.h"
#include "DWARFDebugAranges.h"
#include "DWARFDebugInfo.h"
#include "DWARFDebugInfoEntry.h"
#include "DWARFDebugRanges.h"
#include "DWARFDeclContext.h"
#include "DWARFFormValue.h"
#include "SymbolFileDWARF.h"
#include "lldb/Core/Module.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/TypeSystem.h"
using namespace lldb_private;
DIERef DWARFDIE::GetDIERef() const {
if (!IsValid())
return DIERef();
dw_offset_t cu_offset = m_cu->GetOffset();
if (m_cu->GetBaseObjOffset() != DW_INVALID_OFFSET)
cu_offset = m_cu->GetBaseObjOffset();
return DIERef(cu_offset, m_die->GetOffset());
}
dw_tag_t DWARFDIE::Tag() const {
if (m_die)
return m_die->Tag();
else
return 0;
}
const char *DWARFDIE::GetTagAsCString() const {
return lldb_private::DW_TAG_value_to_name(Tag());
}
DWARFDIE
DWARFDIE::GetParent() const {
if (IsValid())
return DWARFDIE(m_cu, m_die->GetParent());
else
return DWARFDIE();
}
DWARFDIE
DWARFDIE::GetFirstChild() const {
if (IsValid())
return DWARFDIE(m_cu, m_die->GetFirstChild());
else
return DWARFDIE();
}
DWARFDIE
DWARFDIE::GetSibling() const {
if (IsValid())
return DWARFDIE(m_cu, m_die->GetSibling());
else
return DWARFDIE();
}
DWARFDIE
DWARFDIE::GetReferencedDIE(const dw_attr_t attr) const {
const dw_offset_t die_offset =
GetAttributeValueAsReference(attr, DW_INVALID_OFFSET);
if (die_offset != DW_INVALID_OFFSET)
return GetDIE(die_offset);
else
return DWARFDIE();
}
DWARFDIE
DWARFDIE::GetDIE(dw_offset_t die_offset) const {
if (IsValid())
return m_cu->GetDIE(die_offset);
else
return DWARFDIE();
}
const char *DWARFDIE::GetAttributeValueAsString(const dw_attr_t attr,
const char *fail_value) const {
if (IsValid())
return m_die->GetAttributeValueAsString(GetDWARF(), GetCU(), attr,
fail_value);
else
return fail_value;
}
uint64_t DWARFDIE::GetAttributeValueAsUnsigned(const dw_attr_t attr,
uint64_t fail_value) const {
if (IsValid())
return m_die->GetAttributeValueAsUnsigned(GetDWARF(), GetCU(), attr,
fail_value);
else
return fail_value;
}
int64_t DWARFDIE::GetAttributeValueAsSigned(const dw_attr_t attr,
int64_t fail_value) const {
if (IsValid())
return m_die->GetAttributeValueAsSigned(GetDWARF(), GetCU(), attr,
fail_value);
else
return fail_value;
}
DWARFDIE
DWARFDIE::GetAttributeValueAsReferenceDIE(const dw_attr_t attr) const {
if (IsValid()) {
DWARFCompileUnit *cu = GetCU();
SymbolFileDWARF *dwarf = cu->GetSymbolFileDWARF();
const bool check_specification_or_abstract_origin = true;
DWARFFormValue form_value;
if (m_die->GetAttributeValue(dwarf, cu, attr, form_value, nullptr,
check_specification_or_abstract_origin))
return dwarf->GetDIE(DIERef(form_value));
}
return DWARFDIE();
}
uint64_t DWARFDIE::GetAttributeValueAsReference(const dw_attr_t attr,
uint64_t fail_value) const {
if (IsValid())
return m_die->GetAttributeValueAsReference(GetDWARF(), GetCU(), attr,
fail_value);
else
return fail_value;
}
uint64_t DWARFDIE::GetAttributeValueAsAddress(const dw_attr_t attr,
uint64_t fail_value) const {
if (IsValid())
return m_die->GetAttributeValueAsAddress(GetDWARF(), GetCU(), attr,
fail_value);
else
return fail_value;
}
DWARFDIE
DWARFDIE::LookupDeepestBlock(lldb::addr_t file_addr) const {
if (IsValid()) {
SymbolFileDWARF *dwarf = GetDWARF();
DWARFCompileUnit *cu = GetCU();
DWARFDebugInfoEntry *function_die = nullptr;
DWARFDebugInfoEntry *block_die = nullptr;
if (m_die->LookupAddress(file_addr, dwarf, cu, &function_die, &block_die)) {
if (block_die && block_die != function_die) {
if (cu->ContainsDIEOffset(block_die->GetOffset()))
return DWARFDIE(cu, block_die);
else
return DWARFDIE(dwarf->DebugInfo()->GetCompileUnit(
DIERef(cu->GetOffset(), block_die->GetOffset())),
block_die);
}
}
}
return DWARFDIE();
}
lldb::user_id_t DWARFDIE::GetID() const {
return GetDIERef().GetUID(GetDWARF());
}
const char *DWARFDIE::GetName() const {
if (IsValid())
return m_die->GetName(GetDWARF(), m_cu);
else
return nullptr;
}
const char *DWARFDIE::GetMangledName() const {
if (IsValid())
return m_die->GetMangledName(GetDWARF(), m_cu);
else
return nullptr;
}
const char *DWARFDIE::GetPubname() const {
if (IsValid())
return m_die->GetPubname(GetDWARF(), m_cu);
else
return nullptr;
}
const char *DWARFDIE::GetQualifiedName(std::string &storage) const {
if (IsValid())
return m_die->GetQualifiedName(GetDWARF(), m_cu, storage);
else
return nullptr;
}
lldb::LanguageType DWARFDIE::GetLanguage() const {
if (IsValid())
return m_cu->GetLanguageType();
else
return lldb::eLanguageTypeUnknown;
}
lldb::ModuleSP DWARFDIE::GetModule() const {
SymbolFileDWARF *dwarf = GetDWARF();
if (dwarf)
return dwarf->GetObjectFile()->GetModule();
else
return lldb::ModuleSP();
}
lldb_private::CompileUnit *DWARFDIE::GetLLDBCompileUnit() const {
if (IsValid())
return GetDWARF()->GetCompUnitForDWARFCompUnit(GetCU());
else
return nullptr;
}
lldb_private::Type *DWARFDIE::ResolveType() const {
if (IsValid())
return GetDWARF()->ResolveType(*this, true);
else
return nullptr;
}
lldb_private::Type *DWARFDIE::ResolveTypeUID(const DIERef &die_ref) const {
SymbolFileDWARF *dwarf = GetDWARF();
if (dwarf)
return dwarf->ResolveTypeUID(dwarf->GetDIE(die_ref), true);
else
return nullptr;
}
void DWARFDIE::GetDeclContextDIEs(DWARFDIECollection &decl_context_dies) const {
if (IsValid()) {
DWARFDIE parent_decl_ctx_die =
m_die->GetParentDeclContextDIE(GetDWARF(), GetCU());
if (parent_decl_ctx_die && parent_decl_ctx_die.GetDIE() != GetDIE()) {
decl_context_dies.Append(parent_decl_ctx_die);
parent_decl_ctx_die.GetDeclContextDIEs(decl_context_dies);
}
}
}
void DWARFDIE::GetDWARFDeclContext(DWARFDeclContext &dwarf_decl_ctx) const {
if (IsValid()) {
dwarf_decl_ctx.SetLanguage(GetLanguage());
m_die->GetDWARFDeclContext(GetDWARF(), GetCU(), dwarf_decl_ctx);
} else {
dwarf_decl_ctx.Clear();
}
}
void DWARFDIE::GetDWOContext(std::vector<CompilerContext> &context) const {
const dw_tag_t tag = Tag();
if (tag == DW_TAG_compile_unit)
return;
DWARFDIE parent = GetParent();
if (parent)
parent.GetDWOContext(context);
switch (tag) {
case DW_TAG_module:
context.push_back(
CompilerContext(CompilerContextKind::Module, ConstString(GetName())));
break;
case DW_TAG_namespace:
context.push_back(CompilerContext(CompilerContextKind::Namespace,
ConstString(GetName())));
break;
case DW_TAG_structure_type:
context.push_back(CompilerContext(CompilerContextKind::Structure,
ConstString(GetName())));
break;
case DW_TAG_union_type:
context.push_back(
CompilerContext(CompilerContextKind::Union, ConstString(GetName())));
break;
case DW_TAG_class_type:
context.push_back(
CompilerContext(CompilerContextKind::Class, ConstString(GetName())));
break;
case DW_TAG_enumeration_type:
context.push_back(CompilerContext(CompilerContextKind::Enumeration,
ConstString(GetName())));
break;
case DW_TAG_subprogram:
context.push_back(CompilerContext(CompilerContextKind::Function,
ConstString(GetPubname())));
break;
case DW_TAG_variable:
context.push_back(CompilerContext(CompilerContextKind::Variable,
ConstString(GetPubname())));
break;
case DW_TAG_typedef:
context.push_back(
CompilerContext(CompilerContextKind::Typedef, ConstString(GetName())));
break;
default:
break;
}
}
DWARFDIE
DWARFDIE::GetParentDeclContextDIE() const {
if (IsValid())
return m_die->GetParentDeclContextDIE(GetDWARF(), m_cu);
else
return DWARFDIE();
}
dw_offset_t DWARFDIE::GetOffset() const {
if (IsValid())
return m_die->GetOffset();
else
return DW_INVALID_OFFSET;
}
dw_offset_t DWARFDIE::GetCompileUnitRelativeOffset() const {
if (IsValid())
return m_die->GetOffset() - m_cu->GetOffset();
else
return DW_INVALID_OFFSET;
}
SymbolFileDWARF *DWARFDIE::GetDWARF() const {
if (m_cu)
return m_cu->GetSymbolFileDWARF();
else
return nullptr;
}
lldb_private::TypeSystem *DWARFDIE::GetTypeSystem() const {
if (m_cu)
return m_cu->GetTypeSystem();
else
return nullptr;
}
DWARFASTParser *DWARFDIE::GetDWARFParser() const {
lldb_private::TypeSystem *type_system = GetTypeSystem();
if (type_system)
return type_system->GetDWARFParser();
else
return nullptr;
}
bool DWARFDIE::IsStructOrClass() const {
const dw_tag_t tag = Tag();
return tag == DW_TAG_class_type || tag == DW_TAG_structure_type;
}
DWARFDIE
DWARFDIE::GetContainingDWOModuleDIE() const {
if (IsValid()) {
DWARFDIE top_module_die;
// Now make sure this DIE is scoped in a DW_TAG_module tag and return true
// if so
for (DWARFDIE parent = GetParent(); parent.IsValid();
parent = parent.GetParent()) {
const dw_tag_t tag = parent.Tag();
if (tag == DW_TAG_module)
top_module_die = parent;
else if (tag == DW_TAG_compile_unit)
break;
}
return top_module_die;
}
return DWARFDIE();
}
lldb::ModuleSP DWARFDIE::GetContainingDWOModule() const {
if (IsValid()) {
DWARFDIE dwo_module_die = GetContainingDWOModuleDIE();
if (dwo_module_die) {
const char *module_name = dwo_module_die.GetName();
if (module_name)
return GetDWARF()->GetDWOModule(lldb_private::ConstString(module_name));
}
}
return lldb::ModuleSP();
}
bool DWARFDIE::HasChildren() const {
return m_die && m_die->HasChildren();
}
bool DWARFDIE::Supports_DW_AT_APPLE_objc_complete_type() const {
return IsValid() && GetDWARF()->Supports_DW_AT_APPLE_objc_complete_type(m_cu);
}
size_t DWARFDIE::GetAttributes(DWARFAttributes &attributes,
uint32_t depth) const {
if (IsValid()) {
return m_die->GetAttributes(m_cu, m_cu->GetFixedFormSizes(), attributes,
depth);
}
if (depth == 0)
attributes.Clear();
return 0;
}
bool DWARFDIE::GetDIENamesAndRanges(
const char *&name, const char *&mangled, DWARFRangeList &ranges,
int &decl_file, int &decl_line, int &decl_column, int &call_file,
int &call_line, int &call_column,
lldb_private::DWARFExpression *frame_base) const {
if (IsValid()) {
return m_die->GetDIENamesAndRanges(
GetDWARF(), GetCU(), name, mangled, ranges, decl_file, decl_line,
decl_column, call_file, call_line, call_column, frame_base);
} else
return false;
}
void DWARFDIE::Dump(lldb_private::Stream *s,
const uint32_t recurse_depth) const {
if (s && IsValid())
m_die->Dump(GetDWARF(), GetCU(), *s, recurse_depth);
}
CompilerDecl DWARFDIE::GetDecl() const {
DWARFASTParser *dwarf_ast = GetDWARFParser();
if (dwarf_ast)
return dwarf_ast->GetDeclForUIDFromDWARF(*this);
else
return CompilerDecl();
}
CompilerDeclContext DWARFDIE::GetDeclContext() const {
DWARFASTParser *dwarf_ast = GetDWARFParser();
if (dwarf_ast)
return dwarf_ast->GetDeclContextForUIDFromDWARF(*this);
else
return CompilerDeclContext();
}
CompilerDeclContext DWARFDIE::GetContainingDeclContext() const {
DWARFASTParser *dwarf_ast = GetDWARFParser();
if (dwarf_ast)
return dwarf_ast->GetDeclContextContainingUIDFromDWARF(*this);
else
return CompilerDeclContext();
}
bool operator==(const DWARFDIE &lhs, const DWARFDIE &rhs) {
return lhs.GetDIE() == rhs.GetDIE() && lhs.GetCU() == rhs.GetCU();
}
bool operator!=(const DWARFDIE &lhs, const DWARFDIE &rhs) {
return !(lhs == rhs);
}

View File

@ -0,0 +1,221 @@
//===-- DWARFDIE.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_DWARFDIE_h_
#define SymbolFileDWARF_DWARFDIE_h_
#include "lldb/Core/dwarf.h"
#include "lldb/lldb-types.h"
struct DIERef;
class DWARFASTParser;
class DWARFAttributes;
class DWARFCompileUnit;
class DWARFDebugInfoEntry;
class DWARFDeclContext;
class DWARFDIECollection;
class SymbolFileDWARF;
class DWARFDIE {
public:
DWARFDIE() : m_cu(nullptr), m_die(nullptr) {}
DWARFDIE(DWARFCompileUnit *cu, DWARFDebugInfoEntry *die)
: m_cu(cu), m_die(die) {}
DWARFDIE(const DWARFCompileUnit *cu, DWARFDebugInfoEntry *die)
: m_cu(const_cast<DWARFCompileUnit *>(cu)), m_die(die) {}
DWARFDIE(DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
: m_cu(cu), m_die(const_cast<DWARFDebugInfoEntry *>(die)) {}
DWARFDIE(const DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
: m_cu(const_cast<DWARFCompileUnit *>(cu)),
m_die(const_cast<DWARFDebugInfoEntry *>(die)) {}
//----------------------------------------------------------------------
// Tests
//----------------------------------------------------------------------
explicit operator bool() const { return IsValid(); }
bool IsValid() const { return m_cu && m_die; }
bool IsStructOrClass() const;
bool HasChildren() const;
bool Supports_DW_AT_APPLE_objc_complete_type() const;
//----------------------------------------------------------------------
// Accessors
//----------------------------------------------------------------------
SymbolFileDWARF *GetDWARF() const;
DWARFCompileUnit *GetCU() const { return m_cu; }
DWARFDebugInfoEntry *GetDIE() const { return m_die; }
DIERef GetDIERef() const;
lldb_private::TypeSystem *GetTypeSystem() const;
DWARFASTParser *GetDWARFParser() const;
void Set(DWARFCompileUnit *cu, DWARFDebugInfoEntry *die) {
if (cu && die) {
m_cu = cu;
m_die = die;
} else {
Clear();
}
}
void Clear() {
m_cu = nullptr;
m_die = nullptr;
}
lldb::ModuleSP GetContainingDWOModule() const;
DWARFDIE
GetContainingDWOModuleDIE() const;
//----------------------------------------------------------------------
// Accessing information about a DIE
//----------------------------------------------------------------------
dw_tag_t Tag() const;
const char *GetTagAsCString() const;
dw_offset_t GetOffset() const;
dw_offset_t GetCompileUnitRelativeOffset() const;
//----------------------------------------------------------------------
// Get the LLDB user ID for this DIE. This is often just the DIE offset,
// but it might have a SymbolFileDWARF::GetID() in the high 32 bits if
// we are doing Darwin DWARF in .o file, or DWARF stand alone debug
// info.
//----------------------------------------------------------------------
lldb::user_id_t GetID() const;
const char *GetName() const;
const char *GetMangledName() const;
const char *GetPubname() const;
const char *GetQualifiedName(std::string &storage) const;
lldb::LanguageType GetLanguage() const;
lldb::ModuleSP GetModule() const;
lldb_private::CompileUnit *GetLLDBCompileUnit() const;
lldb_private::Type *ResolveType() const;
//----------------------------------------------------------------------
// Resolve a type by UID using this DIE's DWARF file
//----------------------------------------------------------------------
lldb_private::Type *ResolveTypeUID(const DIERef &die_ref) const;
//----------------------------------------------------------------------
// Functions for obtaining DIE relations and references
//----------------------------------------------------------------------
DWARFDIE
GetParent() const;
DWARFDIE
GetFirstChild() const;
DWARFDIE
GetSibling() const;
DWARFDIE
GetReferencedDIE(const dw_attr_t attr) const;
//----------------------------------------------------------------------
// Get a another DIE from the same DWARF file as this DIE. This will
// check the current DIE's compile unit first to see if "die_offset" is
// in the same compile unit, and fall back to checking the DWARF file.
//----------------------------------------------------------------------
DWARFDIE
GetDIE(dw_offset_t die_offset) const;
DWARFDIE
LookupDeepestBlock(lldb::addr_t file_addr) const;
DWARFDIE
GetParentDeclContextDIE() const;
//----------------------------------------------------------------------
// DeclContext related functions
//----------------------------------------------------------------------
void GetDeclContextDIEs(DWARFDIECollection &decl_context_dies) const;
void GetDWARFDeclContext(DWARFDeclContext &dwarf_decl_ctx) const;
void GetDWOContext(std::vector<lldb_private::CompilerContext> &context) const;
//----------------------------------------------------------------------
// Getting attribute values from the DIE.
//
// GetAttributeValueAsXXX() functions should only be used if you are
// looking for one or two attributes on a DIE. If you are trying to
// parse all attributes, use GetAttributes (...) instead
//----------------------------------------------------------------------
const char *GetAttributeValueAsString(const dw_attr_t attr,
const char *fail_value) const;
uint64_t GetAttributeValueAsUnsigned(const dw_attr_t attr,
uint64_t fail_value) const;
int64_t GetAttributeValueAsSigned(const dw_attr_t attr,
int64_t fail_value) const;
uint64_t GetAttributeValueAsReference(const dw_attr_t attr,
uint64_t fail_value) const;
DWARFDIE
GetAttributeValueAsReferenceDIE(const dw_attr_t attr) const;
uint64_t GetAttributeValueAsAddress(const dw_attr_t attr,
uint64_t fail_value) const;
size_t GetAttributes(DWARFAttributes &attributes, uint32_t depth = 0) const;
bool GetDIENamesAndRanges(const char *&name, const char *&mangled,
DWARFRangeList &ranges, int &decl_file,
int &decl_line, int &decl_column, int &call_file,
int &call_line, int &call_column,
lldb_private::DWARFExpression *frame_base) const;
//----------------------------------------------------------------------
// Pretty printing
//----------------------------------------------------------------------
void Dump(lldb_private::Stream *s, const uint32_t recurse_depth) const;
lldb_private::CompilerDecl GetDecl() const;
lldb_private::CompilerDeclContext GetDeclContext() const;
lldb_private::CompilerDeclContext GetContainingDeclContext() const;
protected:
DWARFCompileUnit *m_cu;
DWARFDebugInfoEntry *m_die;
};
bool operator==(const DWARFDIE &lhs, const DWARFDIE &rhs);
bool operator!=(const DWARFDIE &lhs, const DWARFDIE &rhs);
#endif // SymbolFileDWARF_DWARFDIE_h_

Some files were not shown because too many files have changed in this diff Show More