On 17-01-19 15:14, Tom de Vries wrote: > On 17-01-19 01:35, Ian Lance Taylor wrote: >> On Wed, Jan 16, 2019 at 4:17 PM Tom de Vries <tdevr...@suse.de> wrote: >>> >>> this handles DW_FORM_GNU_ref_alt which references the .debug_info >>> section in the .gnu_debugaltlink file. >>> >>> OK for trunk? >>> >>> Thanks, >>> - Tom >>> >>> On 11-12-18 11:14, Tom de Vries wrote: >>>> 2018-12-10 Tom de Vries <tdevr...@suse.de> >>>> >>>> * dwarf.c (enum attr_val_encoding): Add ATTR_VAL_REF_ALT_INFO. >>>> (struct unit): Add low and high fields. >>>> (struct unit_vector): New type. >>>> (struct dwarf_data): Add units and units_counts fields. >>>> (read_attribute): Handle DW_FORM_GNU_ref_alt using >>>> ATTR_VAL_REF_ALT_INFO. >>>> (find_unit): New function. >>>> (find_address_ranges): Add and handle unit_tag parameter. >>>> (build_address_map): Add and handle units_vec parameter. >>>> (read_referenced_name_1): Handle DW_FORM_GNU_ref_alt. >>>> (build_dwarf_data): Pass units_vec to build_address_map. Store >>>> resulting >>>> units vector. >> >> >>>> @@ -281,6 +283,10 @@ struct unit >>>> /* The offset of UNIT_DATA from the start of the information for >>>> this compilation unit. */ >>>> size_t unit_data_offset; >>>> + /* Start of the compilation unit. */ >>>> + size_t low; >>>> + /* End of the compilation unit. */ >>>> + size_t high; >> >> The comments should say what low and high are measured in, which I >> guess is file offset. Or is it offset from the start of UNIT_DATA? >> Either way, If that is right, then the fields should be named >> low_offset and high_offset. Otherwise it seems easy to confuse with >> function_addrs, where low and high refer to PC values. >> > > Done. > >> Also if they are offsets from UNIT_DATA then size_t is OK, but if the >> are file offsets they should be off_t. >> > > AFAIU, in the case where off_t vs size_t would make a difference, we're > running into trouble much earlier. I've filed PR 88890 - "libbacktrace > on 32-bit system with _FILE_OFFSET_BITS == 64" ( > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88890 ) about this. > > Anyway, I've made the conservative choice of using off_t for now (but I > could argue that it's a memory offset, given that the assumption is that > the entire debug section is read into memory). > >>>> @@ -2144,6 +2198,22 @@ read_referenced_name_1 (struct dwarf_data *ddata, >>>> struct unit *u, >>>> || val->encoding == ATTR_VAL_REF_UNIT) >>>> return read_referenced_name (ddata, u, val->u.uint, error_callback, >>>> data); >>>> >>>> + if (val->encoding == ATTR_VAL_REF_ALT_INFO) >>>> + { >>>> + struct unit *alt_unit >>>> + = find_unit (ddata->altlink->units, ddata->altlink->units_count, >>>> + val->u.uint); >>>> + if (alt_unit == NULL) >>>> + { >>>> + error_callback (data, >>>> + "Could not find unit for DW_FORM_GNU_ref_alt", 0); >> >> s/Could/could/ >> >> or maybe just skip this error_callback call as discussed earlier. >> >> > > Skipped. > >>>> + return NULL; >>>> + } >>>> + uint64_t unit_offset = val->u.uint - alt_unit->low; >> >> Earlier a unit_offset was the offset of the unit within unit_data, but >> here this is an offset within a single unit. This should just be >> called offset, which is the name used by read_referenced_name. >> > > Done. > >> This is OK with those changes. > > Committed in two parts. > > First part ... >
And second part. Thanks, - Tom
[libbacktrace] Handle DW_FORM_GNU_ref_alt Handle DW_FORM_GNU_ref_alt which references the .debug_info section in the .gnu_debugaltlink file. 2018-12-10 Tom de Vries <tdevr...@suse.de> PR libbacktrace/82857 * dwarf.c (enum attr_val_encoding): Add ATTR_VAL_REF_ALT_INFO. (read_attribute): Handle DW_FORM_GNU_ref_alt using ATTR_VAL_REF_ALT_INFO. (read_referenced_name_from_attr): Handle DW_FORM_GNU_ref_alt. --- libbacktrace/dwarf.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/libbacktrace/dwarf.c b/libbacktrace/dwarf.c index 6f56c46774b..aacbd3a453d 100644 --- a/libbacktrace/dwarf.c +++ b/libbacktrace/dwarf.c @@ -143,6 +143,8 @@ enum attr_val_encoding ATTR_VAL_REF_UNIT, /* An offset to other data within the .dwarf_info section. */ ATTR_VAL_REF_INFO, + /* An offset to other data within the alt .dwarf_info section. */ + ATTR_VAL_REF_ALT_INFO, /* An offset to data in some other section. */ ATTR_VAL_REF_SECTION, /* A type signature. */ @@ -858,7 +860,7 @@ read_attribute (enum dwarf_form form, struct dwarf_buf *buf, val->encoding = ATTR_VAL_NONE; return 1; } - val->encoding = ATTR_VAL_REF_SECTION; + val->encoding = ATTR_VAL_REF_ALT_INFO; return 1; case DW_FORM_GNU_strp_alt: { @@ -2200,6 +2202,19 @@ read_referenced_name_from_attr (struct dwarf_data *ddata, struct unit *u, || val->encoding == ATTR_VAL_REF_UNIT) return read_referenced_name (ddata, u, val->u.uint, error_callback, data); + if (val->encoding == ATTR_VAL_REF_ALT_INFO) + { + struct unit *alt_unit + = find_unit (ddata->altlink->units, ddata->altlink->units_count, + val->u.uint); + if (alt_unit == NULL) + return NULL; + + uint64_t offset = val->u.uint - alt_unit->low_offset; + return read_referenced_name (ddata->altlink, alt_unit, offset, + error_callback, data); + } + return NULL; }