Skip to content

Commit 3b83db4

Browse files
committed
[lldb][DWARFASTParserClang] Don't overwrite DW_AT_object_pointer of definition with that of a declaration
In llvm#122742 we will start attaching DW_AT_object_pointer to method declarations (in addition to definitions). Currently when LLDB parses a `DW_TAG_subprogram` definition, it will parse all the attributes of the declaration as well. If we have `DW_AT_object_pointer` on both, then we would overwrite the more specific attribute that we got from the defintion with the one from the specification. This is problematic because LLDB relies on getting the `DW_AT_name` from the `DW_AT_object_pointer`, which doesn't exist on the specification.
1 parent 7e01a32 commit 3b83db4

File tree

2 files changed

+167
-1
lines changed

2 files changed

+167
-1
lines changed

lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,12 @@ ParsedDWARFTypeAttributes::ParsedDWARFTypeAttributes(const DWARFDIE &die) {
377377
break;
378378

379379
case DW_AT_object_pointer:
380-
object_pointer = form_value.Reference();
380+
// GetAttributes follows DW_AT_specification.
381+
// DW_TAG_subprogram definitions and declarations may both
382+
// have a DW_AT_object_pointer. Don't overwrite the one
383+
// we parsed for the definition with the one from the declaration.
384+
if (!object_pointer.IsValid())
385+
object_pointer = form_value.Reference();
381386
break;
382387

383388
case DW_AT_signature:

lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,3 +741,164 @@ TEST_F(DWARFASTParserClangTests, TestUniqueDWARFASTTypeMap_CppInsertMapFind) {
741741

742742
ASSERT_EQ(type_sp, reparsed_type_sp);
743743
}
744+
745+
TEST_F(DWARFASTParserClangTests, TestParseDWARFAttributes_ObjectPointer) {
746+
// This tests the behaviour of ParsedDWARFTypeAttributes
747+
// for DW_TAG_subprogram definitions which have a DW_AT_object_pointer
748+
// *and* a DW_AT_specification that also has a DW_AT_object_pointer.
749+
// We don't want the declaration DW_AT_object_pointer to overwrite the
750+
// one from the more specific definition's.
751+
752+
const char *yamldata = R"(
753+
--- !ELF
754+
FileHeader:
755+
Class: ELFCLASS64
756+
Data: ELFDATA2LSB
757+
Type: ET_EXEC
758+
Machine: EM_AARCH64
759+
DWARF:
760+
debug_str:
761+
- Context
762+
- func
763+
- this
764+
debug_abbrev:
765+
- ID: 0
766+
Table:
767+
- Code: 0x1
768+
Tag: DW_TAG_compile_unit
769+
Children: DW_CHILDREN_yes
770+
Attributes:
771+
- Attribute: DW_AT_language
772+
Form: DW_FORM_data2
773+
- Code: 0x2
774+
Tag: DW_TAG_structure_type
775+
Children: DW_CHILDREN_yes
776+
Attributes:
777+
- Attribute: DW_AT_name
778+
Form: DW_FORM_strp
779+
- Code: 0x3
780+
Tag: DW_TAG_subprogram
781+
Children: DW_CHILDREN_yes
782+
Attributes:
783+
- Attribute: DW_AT_name
784+
Form: DW_FORM_strp
785+
- Attribute: DW_AT_declaration
786+
Form: DW_FORM_flag_present
787+
- Attribute: DW_AT_object_pointer
788+
Form: DW_FORM_ref4
789+
- Attribute: DW_AT_artificial
790+
Form: DW_FORM_flag_present
791+
- Attribute: DW_AT_external
792+
Form: DW_FORM_flag_present
793+
- Code: 0x4
794+
Tag: DW_TAG_formal_parameter
795+
Children: DW_CHILDREN_no
796+
Attributes:
797+
- Attribute: DW_AT_artificial
798+
Form: DW_FORM_flag_present
799+
- Code: 0x5
800+
Tag: DW_TAG_subprogram
801+
Children: DW_CHILDREN_yes
802+
Attributes:
803+
- Attribute: DW_AT_object_pointer
804+
Form: DW_FORM_ref4
805+
- Attribute: DW_AT_specification
806+
Form: DW_FORM_ref4
807+
- Code: 0x6
808+
Tag: DW_TAG_formal_parameter
809+
Children: DW_CHILDREN_no
810+
Attributes:
811+
- Attribute: DW_AT_name
812+
Form: DW_FORM_strp
813+
- Attribute: DW_AT_artificial
814+
Form: DW_FORM_flag_present
815+
debug_info:
816+
- Version: 5
817+
UnitType: DW_UT_compile
818+
AddrSize: 8
819+
Entries:
820+
821+
# DW_TAG_compile_unit
822+
# DW_AT_language [DW_FORM_data2] (DW_LANG_C_plus_plus)
823+
824+
- AbbrCode: 0x1
825+
Values:
826+
- Value: 0x04
827+
828+
# DW_TAG_structure_type
829+
# DW_AT_name [DW_FORM_strp] ("Context")
830+
831+
- AbbrCode: 0x2
832+
Values:
833+
- Value: 0x0
834+
835+
# DW_TAG_subprogram
836+
# DW_AT_name [DW_FORM_strp] ("func")
837+
# DW_AT_object_pointer [DW_FORM_ref4]
838+
- AbbrCode: 0x3
839+
Values:
840+
- Value: 0x8
841+
- Value: 0x1
842+
- Value: 0x1d
843+
- Value: 0x1
844+
- Value: 0x1
845+
846+
# DW_TAG_formal_parameter
847+
# DW_AT_artificial
848+
- AbbrCode: 0x4
849+
Values:
850+
- Value: 0x1
851+
852+
- AbbrCode: 0x0
853+
- AbbrCode: 0x0
854+
855+
# DW_TAG_subprogram
856+
# DW_AT_object_pointer [DW_FORM_ref4] ("this")
857+
# DW_AT_specification [DW_FORM_ref4] ("func")
858+
- AbbrCode: 0x5
859+
Values:
860+
- Value: 0x29
861+
- Value: 0x14
862+
863+
# DW_TAG_formal_parameter
864+
# DW_AT_name [DW_FORM_strp] ("this")
865+
# DW_AT_artificial
866+
- AbbrCode: 0x6
867+
Values:
868+
- Value: 0xd
869+
- Value: 0x1
870+
871+
- AbbrCode: 0x0
872+
- AbbrCode: 0x0
873+
...
874+
)";
875+
YAMLModuleTester t(yamldata);
876+
877+
DWARFUnit *unit = t.GetDwarfUnit();
878+
ASSERT_NE(unit, nullptr);
879+
const DWARFDebugInfoEntry *cu_entry = unit->DIE().GetDIE();
880+
ASSERT_EQ(cu_entry->Tag(), DW_TAG_compile_unit);
881+
ASSERT_EQ(unit->GetDWARFLanguageType(), DW_LANG_C_plus_plus);
882+
DWARFDIE cu_die(unit, cu_entry);
883+
884+
auto holder = std::make_unique<clang_utils::TypeSystemClangHolder>("ast");
885+
auto &ast_ctx = *holder->GetAST();
886+
DWARFASTParserClangStub ast_parser(ast_ctx);
887+
888+
auto context_die = cu_die.GetFirstChild();
889+
ASSERT_TRUE(context_die.IsValid());
890+
ASSERT_EQ(context_die.Tag(), DW_TAG_structure_type);
891+
892+
auto subprogram_definition = context_die.GetSibling();
893+
ASSERT_TRUE(subprogram_definition.IsValid());
894+
ASSERT_EQ(subprogram_definition.Tag(), DW_TAG_subprogram);
895+
ASSERT_FALSE(subprogram_definition.GetAttributeValueAsOptionalUnsigned(
896+
DW_AT_external));
897+
898+
auto param_die = subprogram_definition.GetFirstChild();
899+
ASSERT_TRUE(param_die.IsValid());
900+
901+
ParsedDWARFTypeAttributes attrs(subprogram_definition);
902+
EXPECT_TRUE(attrs.object_pointer.IsValid());
903+
EXPECT_EQ(attrs.object_pointer, param_die);
904+
}

0 commit comments

Comments
 (0)