From 7286e5c5de53840126b4046a46442872a3b00692 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Thu, 2 Nov 2017 16:24:17 +0100 Subject: [PATCH] libdw: Update acceptable forms and attributes for dwarf_getlocation. dwarf_getlocation has to know which attributes can contain a DWARF expression or location list because the form alone might be ambiguous. Since DWARF4 there is DW_FORM_exprloc so always accept that. But for older DWARF or location lists we cannot just check for DW_FORM_sec_offset since that could be a reference to diffent kinds of sections (based on attribute). Update the attribute list based on the latest DWARF5 encodings table. Note that DW_AT_call_origin wasn't added because that seems to be a typo in the DWARF5 spec. http://dwarfstd.org/ShowIssue.php?issue=171103.1 Signed-off-by: Mark Wielaard --- libdw/ChangeLog | 5 +++++ libdw/dwarf_getlocation.c | 26 +++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/libdw/ChangeLog b/libdw/ChangeLog index 70856498a..bb9e84995 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,8 @@ +2017-11-03 Mark Wielaard + + * dwarf_getlocation.c (attr_ok): Always accept DW_FORM_exprloc. + Update list of acceptable attribute codes based on DWARF5. + 2017-11-03 Mark Wielaard * dwarf.h: Add DW_OP_GNU_variable_value. diff --git a/libdw/dwarf_getlocation.c b/libdw/dwarf_getlocation.c index a4a2761ee..c59546e0d 100644 --- a/libdw/dwarf_getlocation.c +++ b/libdw/dwarf_getlocation.c @@ -45,10 +45,34 @@ attr_ok (Dwarf_Attribute *attr) if (attr == NULL) return false; - /* Must be one of the attributes listed below. */ + /* If it is an exprloc, it is obviously OK. */ + if (dwarf_whatform (attr) == DW_FORM_exprloc) + return true; + + /* Otherwise must be one of the attributes listed below. Older + DWARF versions might have encoded the exprloc as block, and we + cannot easily distinquish attributes in the loclist class because + the same forms are used for different classes. */ switch (attr->code) { case DW_AT_location: + case DW_AT_byte_size: + case DW_AT_bit_offset: + case DW_AT_bit_size: + case DW_AT_lower_bound: + case DW_AT_bit_stride: + case DW_AT_upper_bound: + case DW_AT_count: + case DW_AT_allocated: + case DW_AT_associated: + case DW_AT_data_location: + case DW_AT_byte_stride: + case DW_AT_rank: + case DW_AT_call_value: + case DW_AT_call_target: + case DW_AT_call_target_clobbered: + case DW_AT_call_data_location: + case DW_AT_call_data_value: case DW_AT_data_member_location: case DW_AT_vtable_elem_location: case DW_AT_string_length: -- 2.47.3