//---------------------------------------------------------------------- // LookupAddress //---------------------------------------------------------------------- DWARFDIE DWARFDebugInfo::LookupAddress (const dw_addr_t address, const dw_offset_t hint_die_offset) { DWARFDIE die; DWARFCompileUnit *cu = nullptr; if (hint_die_offset != DW_INVALID_OFFSET) { cu = GetCompileUnit(hint_die_offset); } else { DWARFDebugAranges &cu_aranges = GetCompileUnitAranges (); const dw_offset_t cu_offset = cu_aranges.FindAddress (address); cu = GetCompileUnit(cu_offset); } if (cu) { die = cu->LookupAddress(address); } else { // The hint_die_offset may have been a pointer to the actual item that // we are looking for die = GetDIE(hint_die_offset); if (die) { DWARFDebugInfoEntry* function_die = nullptr; if (die.GetDIE()->LookupAddress (address, die.GetDWARF(), die.GetCU(), &function_die, nullptr)) die.Set (die.GetCU(), function_die); } } return die; }
size_t DWARFASTParserGo::ParseChildMembers(const SymbolContext &sc, const DWARFDIE &parent_die, CompilerType &class_compiler_type) { size_t count = 0; uint32_t member_idx = 0; ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule(); GoASTContext *ast = llvm::dyn_cast_or_null<GoASTContext>(class_compiler_type.GetTypeSystem()); if (ast == nullptr) return 0; for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); die = die.GetSibling()) { dw_tag_t tag = die.Tag(); switch (tag) { case DW_TAG_member: { DWARFAttributes attributes; const size_t num_attributes = die.GetAttributes(attributes); if (num_attributes > 0) { Declaration decl; const char *name = NULL; lldb::user_id_t encoding_uid = LLDB_INVALID_UID; uint32_t member_byte_offset = UINT32_MAX; uint32_t i; for (i = 0; i < num_attributes; ++i) { const dw_attr_t attr = attributes.AttributeAtIndex(i); DWARFFormValue form_value; if (attributes.ExtractFormValueAtIndex(i, form_value)) { switch (attr) { 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()) { Value initialValue(0); Value memberOffset(0); const DWARFDataExtractor &debug_info_data = die.GetDWARF()->get_debug_info_data(); uint32_t block_length = form_value.Unsigned(); uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); if (DWARFExpression::Evaluate(NULL, // ExecutionContext * NULL, // ClangExpressionVariableList * NULL, // ClangExpressionDeclMap * NULL, // RegisterContext * module_sp, debug_info_data, die.GetCU(), block_offset, block_length, eRegisterKindDWARF, &initialValue, NULL, memberOffset, NULL)) { member_byte_offset = memberOffset.ResolveValue(NULL).UInt(); } } else { // With DWARF 3 and later, if the value is an integer constant, // this form value is the offset in bytes from the beginning // of the containing entity. member_byte_offset = form_value.Unsigned(); } break; default: break; } } } Type *member_type = die.ResolveTypeUID(encoding_uid); if (member_type) { CompilerType member_go_type = member_type->GetFullCompilerType(); ConstString name_const_str(name); m_ast.AddFieldToStruct(class_compiler_type, name_const_str, member_go_type, member_byte_offset); } } ++member_idx; } break; default: break; } } return count; }
TypeSP DWARFASTParserJava::ParseArrayTypeFromDIE(const DWARFDIE &die) { SymbolFileDWARF *dwarf = die.GetDWARF(); dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED; ConstString linkage_name; DWARFFormValue type_attr_value; 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_attr_value = form_value; 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"); } } DIERef type_die_ref(type_attr_value); Type *element_type = dwarf->ResolveTypeUID(type_die_ref); 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, type_die_ref.GetUID(dwarf), Type::eEncodingIsUID, &decl, array_compiler_type, Type::eResolveStateFull)); type_sp->SetEncodingType(element_type); return type_sp; }
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; DWARFFormValue encoding_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; 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(DIERef(encoding_uid))) m_ast.AddMemberToObject(compiler_type, ConstString(name), member_type->GetFullCompilerType(), member_byte_offset); } break; } case DW_TAG_inheritance: { DWARFFormValue encoding_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; 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(DIERef(encoding_uid))) m_ast.AddBaseClassToObject(compiler_type, base_type->GetFullCompilerType(), member_byte_offset); break; } default: break; } } }
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.GetDIE() == rhs.GetDIE() && lhs.GetCU() == rhs.GetCU(); }