diff --git a/src/apps/debugger/dwarf/AttributeClasses.cpp b/src/apps/debugger/dwarf/AttributeClasses.cpp index 438bfdabc8..89e5b8b6eb 100644 --- a/src/apps/debugger/dwarf/AttributeClasses.cpp +++ b/src/apps/debugger/dwarf/AttributeClasses.cpp @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -17,7 +18,8 @@ enum { AC_MACPTR = 1 << (ATTRIBUTE_CLASS_MACPTR - 1), AC_RANGELISTPTR = 1 << (ATTRIBUTE_CLASS_RANGELISTPTR - 1), AC_REFERENCE = 1 << (ATTRIBUTE_CLASS_REFERENCE - 1), - AC_STRING = 1 << (ATTRIBUTE_CLASS_STRING - 1) + AC_STRING = 1 << (ATTRIBUTE_CLASS_STRING - 1), + AC_EXPRESSION = 1 << (ATTRIBUTE_CLASS_EXPRESSION - 1) }; @@ -127,10 +129,26 @@ static const attribute_name_info_entry kAttributeNameInfos[] = { { ENTRY(elemental), AC_FLAG }, { ENTRY(pure), AC_FLAG }, { ENTRY(recursive), AC_FLAG }, + { ENTRY(signature), AC_REFERENCE }, + { ENTRY(main_subprogram), AC_FLAG }, + { ENTRY(data_bit_offset), AC_CONSTANT }, + { ENTRY(const_expr), AC_FLAG }, + { ENTRY(enum_class), AC_FLAG }, + { ENTRY(linkage_name), AC_STRING }, + { ENTRY(call_site_value), AC_BLOCK | AC_EXPRESSION }, + { ENTRY(call_site_data_value), AC_BLOCK | AC_EXPRESSION }, + { ENTRY(call_site_target), AC_BLOCK | AC_EXPRESSION }, + { ENTRY(call_site_target_clobbered), + AC_BLOCK | AC_EXPRESSION }, + { ENTRY(tail_call), AC_FLAG }, + { ENTRY(all_tail_call_sites), AC_FLAG }, + { ENTRY(all_call_sites), AC_FLAG }, + { ENTRY(all_source_call_sites), AC_FLAG }, + {} }; -static const uint32 kAttributeNameInfoCount = DW_AT_recursive + 1; +static const uint32 kAttributeNameInfoCount = DW_AT_linkage_name + 9; static attribute_name_info_entry sAttributeNameInfos[kAttributeNameInfoCount]; @@ -160,10 +178,16 @@ static const attribute_info_entry kAttributeFormInfos[] = { { ENTRY(ref4), AC_REFERENCE }, { ENTRY(ref8), AC_REFERENCE }, { ENTRY(ref_udata), AC_REFERENCE }, + { ENTRY(indirect), AC_REFERENCE }, + { ENTRY(sec_offset), AC_LINEPTR | AC_LOCLISTPTR | AC_MACPTR + | AC_RANGELISTPTR }, + { ENTRY(exprloc), AC_EXPRESSION }, + { ENTRY(flag_present), AC_FLAG }, + { ENTRY(ref_sig8), AC_REFERENCE }, {} }; -static const uint32 kAttributeFormInfoCount = DW_FORM_ref_udata + 1; +static const uint32 kAttributeFormInfoCount = DW_FORM_ref_sig8 + 1; static attribute_info_entry sAttributeFormInfos[kAttributeFormInfoCount]; static struct InitAttributeInfos { @@ -171,7 +195,12 @@ static struct InitAttributeInfos { { for (uint32 i = 0; kAttributeNameInfos[i].name != NULL; i++) { const attribute_name_info_entry& entry = kAttributeNameInfos[i]; - sAttributeNameInfos[entry.value] = entry; + if (entry.value <= DW_AT_linkage_name) + sAttributeNameInfos[entry.value] = entry; + else { + sAttributeNameInfos[DW_AT_linkage_name + 1 + + (entry.value - DW_AT_call_site_value)] = entry; + } } for (uint32 i = 0; kAttributeFormInfos[i].name != NULL; i++) { @@ -185,8 +214,15 @@ static struct InitAttributeInfos { uint16 get_attribute_name_classes(uint32 name) { - return name < kAttributeNameInfoCount - ? sAttributeNameInfos[name].classes : 0; + if (name < DW_AT_linkage_name) + return sAttributeNameInfos[name].classes; + else if (name >= DW_AT_call_site_value + && name <= DW_AT_all_source_call_sites) { + return sAttributeNameInfos[DW_AT_linkage_name + 1 + + (name - DW_AT_call_site_value)].classes; + } + + return 0; } @@ -217,8 +253,15 @@ get_attribute_class(uint32 name, uint32 form) const char* get_attribute_name_name(uint32 name) { - return name < kAttributeNameInfoCount - ? sAttributeNameInfos[name].name : NULL; + if (name < DW_AT_linkage_name) + return sAttributeNameInfos[name].name; + else if (name >= DW_AT_call_site_value + && name <= DW_AT_all_source_call_sites) { + return sAttributeNameInfos[DW_AT_linkage_name + 1 + + (name - DW_AT_call_site_value)].name; + } + + return NULL; } diff --git a/src/apps/debugger/dwarf/AttributeClasses.h b/src/apps/debugger/dwarf/AttributeClasses.h index ae9424fd65..6b7b873f3d 100644 --- a/src/apps/debugger/dwarf/AttributeClasses.h +++ b/src/apps/debugger/dwarf/AttributeClasses.h @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef ATTRIBUTE_TABLES_H @@ -24,7 +25,8 @@ enum { ATTRIBUTE_CLASS_MACPTR = 7, ATTRIBUTE_CLASS_RANGELISTPTR = 8, ATTRIBUTE_CLASS_REFERENCE = 9, - ATTRIBUTE_CLASS_STRING = 10 + ATTRIBUTE_CLASS_STRING = 10, + ATTRIBUTE_CLASS_EXPRESSION = 11 }; diff --git a/src/apps/debugger/dwarf/DebugInfoEntries.cpp b/src/apps/debugger/dwarf/DebugInfoEntries.cpp index be38f23a2c..502c65ed1a 100644 --- a/src/apps/debugger/dwarf/DebugInfoEntries.cpp +++ b/src/apps/debugger/dwarf/DebugInfoEntries.cpp @@ -2604,6 +2604,91 @@ DIETemplateValueParameterPack::AddChild(DebugInfoEntry* child) } +// #pragma mark - DIECallSite + + +DIECallSite::DIECallSite() + : + fName(NULL) +{ +} + + +uint16 +DIECallSite::Tag() const +{ + return DW_TAG_GNU_call_site; +} + + +const char* +DIECallSite::Name() const +{ + return fName; +} + + +status_t +DIECallSite::AddAttribute_name(uint16 attributeName, + const AttributeValue& value) +{ + fName = value.string; + return B_OK; +} + + +status_t +DIECallSite::AddChild(DebugInfoEntry* child) +{ + if (child->Tag() == DW_TAG_GNU_call_site_parameter) { + fChildren.Add(child); + return B_OK; + } + + return DIEDeclaredBase::AddChild(child); +} + + +// #pragma mark - DIECallSiteParameter + + +DIECallSiteParameter::DIECallSiteParameter() + : + fName(NULL) +{ +} + + +uint16 +DIECallSiteParameter::Tag() const +{ + return DW_TAG_GNU_call_site_parameter; +} + + +const char* +DIECallSiteParameter::Name() const +{ + return fName; +} + + +status_t +DIECallSiteParameter::AddAttribute_name(uint16 attributeName, + const AttributeValue& value) +{ + fName = value.string; + return B_OK; +} + + +status_t +DIECallSiteParameter::AddChild(DebugInfoEntry* child) +{ + return DIEDeclaredBase::AddChild(child); +} + + // #pragma mark - DebugInfoEntryFactory @@ -2795,6 +2880,12 @@ DebugInfoEntryFactory::CreateDebugInfoEntry(uint16 tag, DebugInfoEntry*& _entry) case DW_TAG_GNU_formal_parameter_pack: entry = new(std::nothrow) DIETemplateValueParameterPack; break; + case DW_TAG_GNU_call_site: + entry = new(std::nothrow) DIECallSite; + break; + case DW_TAG_GNU_call_site_parameter: + entry = new(std::nothrow) DIECallSiteParameter; + break; default: return B_ENTRY_NOT_FOUND; break; diff --git a/src/apps/debugger/dwarf/DebugInfoEntries.h b/src/apps/debugger/dwarf/DebugInfoEntries.h index a4a5c01ce4..4d759dd9c4 100644 --- a/src/apps/debugger/dwarf/DebugInfoEntries.h +++ b/src/apps/debugger/dwarf/DebugInfoEntries.h @@ -1641,6 +1641,50 @@ private: }; +class DIECallSite : public DIEDeclaredBase { +public: + DIECallSite(); + + virtual uint16 Tag() const; + + virtual const char* Name() const; + + virtual status_t AddAttribute_name(uint16 attributeName, + const AttributeValue& value); + + const DebugInfoEntryList& Children() const + { return fChildren; } + + virtual status_t AddChild(DebugInfoEntry* child); + +private: + const char* fName; + DebugInfoEntryList fChildren; +}; + + +class DIECallSiteParameter : public DIEDeclaredBase { +public: + DIECallSiteParameter(); + + virtual uint16 Tag() const; + + virtual const char* Name() const; + + virtual status_t AddAttribute_name(uint16 attributeName, + const AttributeValue& value); + + const DebugInfoEntryList& Children() const + { return fChildren; } + + virtual status_t AddChild(DebugInfoEntry* child); + +private: + const char* fName; + DebugInfoEntryList fChildren; +}; + + // #pragma mark - DebugInfoEntryFactory diff --git a/src/apps/debugger/dwarf/DebugInfoEntry.cpp b/src/apps/debugger/dwarf/DebugInfoEntry.cpp index 534636ea22..4938e8ab67 100644 --- a/src/apps/debugger/dwarf/DebugInfoEntry.cpp +++ b/src/apps/debugger/dwarf/DebugInfoEntry.cpp @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -299,6 +300,20 @@ DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(endianity) DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(elemental) DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(pure) DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(recursive) +DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(signature) +DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(main_subprogram) +DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(data_bit_offset) +DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(const_expr) +DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(enum_class) +DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(linkage_name) +DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(call_site_value) +DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(call_site_data_value) +DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(call_site_target) +DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(call_site_target_clobbered) +DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(tail_call) +DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(all_tail_call_sites) +DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(all_call_sites) +DEFINE_DEBUG_INFO_ENTRY_ATTR_SETTER(all_source_call_sites) DeclarationLocation* diff --git a/src/apps/debugger/dwarf/DebugInfoEntry.h b/src/apps/debugger/dwarf/DebugInfoEntry.h index 6cd54c04e9..11e7865035 100644 --- a/src/apps/debugger/dwarf/DebugInfoEntry.h +++ b/src/apps/debugger/dwarf/DebugInfoEntry.h @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef DEBUG_INFO_ENTRY_H @@ -162,6 +163,20 @@ public: DECLARE_DEBUG_INFO_ENTRY_ATTR_SETTER(elemental) DECLARE_DEBUG_INFO_ENTRY_ATTR_SETTER(pure) DECLARE_DEBUG_INFO_ENTRY_ATTR_SETTER(recursive) + DECLARE_DEBUG_INFO_ENTRY_ATTR_SETTER(signature) + DECLARE_DEBUG_INFO_ENTRY_ATTR_SETTER(main_subprogram) + DECLARE_DEBUG_INFO_ENTRY_ATTR_SETTER(data_bit_offset) + DECLARE_DEBUG_INFO_ENTRY_ATTR_SETTER(const_expr) + DECLARE_DEBUG_INFO_ENTRY_ATTR_SETTER(enum_class) + DECLARE_DEBUG_INFO_ENTRY_ATTR_SETTER(linkage_name) + DECLARE_DEBUG_INFO_ENTRY_ATTR_SETTER(call_site_value) + DECLARE_DEBUG_INFO_ENTRY_ATTR_SETTER(call_site_data_value) + DECLARE_DEBUG_INFO_ENTRY_ATTR_SETTER(call_site_target) + DECLARE_DEBUG_INFO_ENTRY_ATTR_SETTER(call_site_target_clobbered) + DECLARE_DEBUG_INFO_ENTRY_ATTR_SETTER(tail_call) + DECLARE_DEBUG_INFO_ENTRY_ATTR_SETTER(all_tail_call_sites) + DECLARE_DEBUG_INFO_ENTRY_ATTR_SETTER(all_call_sites) + DECLARE_DEBUG_INFO_ENTRY_ATTR_SETTER(all_source_call_sites) protected: virtual DeclarationLocation* GetDeclarationLocation(); diff --git a/src/apps/debugger/dwarf/Dwarf.h b/src/apps/debugger/dwarf/Dwarf.h index 1e9c99bc74..06dd514b7b 100644 --- a/src/apps/debugger/dwarf/Dwarf.h +++ b/src/apps/debugger/dwarf/Dwarf.h @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef DWARF_H @@ -64,11 +65,16 @@ enum { DW_TAG_imported_unit = 0x3d, DW_TAG_condition = 0x3f, DW_TAG_shared_type = 0x40, + DW_TAG_type_unit = 0x41, + DW_TAG_rvalue_reference_type = 0x42, + DW_TAG_template_alias = 0x43, DW_TAG_lo_user = 0x4080, DW_TAG_GNU_template_parameter_pack = 0x4107, DW_TAG_GNU_formal_parameter_pack = 0x4108, + DW_TAG_GNU_call_site = 0x4109, + DW_TAG_GNU_call_site_parameter = 0x410a, DW_TAG_hi_user = 0xffff }; @@ -166,7 +172,37 @@ enum { DW_AT_elemental = 0x66, // flag DW_AT_pure = 0x67, // flag DW_AT_recursive = 0x68, // flag + DW_AT_signature = 0x69, // reference + DW_AT_main_subprogram = 0x6a, // flag + DW_AT_data_bit_offset = 0x6b, // constant + DW_AT_const_expr = 0x6c, // flag + DW_AT_enum_class = 0x6d, // flag + DW_AT_linkage_name = 0x6e, // string + // TODO: proposed DWARF5 final values +/* DW_AT_call_site_value = 0x6f, // exprloc + DW_AT_call_site_data_value = 0x70, // exprloc + DW_AT_call_site_target = 0x71, // exprloc + DW_AT_call_site_target_clobbered + = 0x72, // exprloc + DW_AT_tail_call = 0x73, // flag + DW_AT_all_tail_call_sites = 0x74, // flag + DW_AT_all_call_sites = 0x75, // flag + DW_AT_all_source_call_sites = 0x76, // flag +*/ DW_AT_lo_user = 0x2000, + DW_AT_call_site_value = 0x2111, // exprloc + DW_AT_call_site_data_value + = 0x2112, // exprloc + DW_AT_call_site_target + = 0x2113, // exprloc + DW_AT_call_site_target_clobbered + = 0x2114, // exprloc + DW_AT_tail_call = 0x2115, // flag + DW_AT_all_tail_call_sites + = 0x2116, // flag + DW_AT_all_call_sites = 0x2117, // flag + DW_AT_all_source_call_sites + = 0x2118, // flag DW_AT_hi_user = 0x3fff }; @@ -195,6 +231,12 @@ enum { DW_FORM_ref8 = 0x14, // reference DW_FORM_ref_udata = 0x15, // reference DW_FORM_indirect = 0x16, // form in .debug_info + DW_FORM_sec_offset = 0x17, // lineptr, loclistptr, macptr, rangelistptr + DW_FORM_exprloc = 0x18, // dwarf expression + DW_FORM_flag_present + = 0x19, // flag + DW_FORM_ref_sig8 = 0x20 // reference + }; // expression operation diff --git a/src/apps/debugger/dwarf/TagNames.cpp b/src/apps/debugger/dwarf/TagNames.cpp index 4a9b4b5ff2..236c1a960f 100644 --- a/src/apps/debugger/dwarf/TagNames.cpp +++ b/src/apps/debugger/dwarf/TagNames.cpp @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -75,11 +76,18 @@ static const tag_name_info kTagNameInfos[] = { ENTRY(imported_unit), ENTRY(condition), ENTRY(shared_type), + ENTRY(type_unit), + ENTRY(rvalue_reference_type), + ENTRY(template_alias), + ENTRY(GNU_template_parameter_pack), + ENTRY(GNU_formal_parameter_pack), + ENTRY(GNU_call_site), + ENTRY(GNU_call_site_parameter), {} }; -static const uint32 kTagNameInfoCount = DW_TAG_shared_type + 1; +static const uint32 kTagNameInfoCount = DW_TAG_template_alias + 5; static const char* sTagNames[kTagNameInfoCount]; static struct InitTagNames { @@ -87,7 +95,12 @@ static struct InitTagNames { { for (uint32 i = 0; kTagNameInfos[i].name != NULL; i++) { const tag_name_info& info = kTagNameInfos[i]; - sTagNames[info.tag] = info.name; + if (info.tag <= DW_TAG_template_alias) + sTagNames[info.tag] = info.name; + else { + sTagNames[DW_TAG_template_alias + 1 + (info.tag + - DW_TAG_GNU_template_parameter_pack)] = info.name; + } } } } sInitTagNames; @@ -96,5 +109,13 @@ static struct InitTagNames { const char* get_entry_tag_name(uint16 tag) { - return tag < kTagNameInfoCount ? sTagNames[tag] : NULL; + if (tag <= DW_TAG_template_alias) + return sTagNames[tag]; + else if (tag >= DW_TAG_GNU_template_parameter_pack + && tag <= DW_TAG_GNU_call_site_parameter) { + return sTagNames[DW_TAG_template_alias + 1 + (tag + - DW_TAG_GNU_template_parameter_pack)]; + } + + return NULL; }