On 16-01-19 02:06, Ian Lance Taylor wrote: > On Tue, Dec 11, 2018 at 2:14 AM Tom de Vries <tdevr...@suse.de> wrote: >> >> Handle DW_FORM_GNU_strp_alt and DW_FORM_GNU_ref_alt references robustly in >> presence of missing .gnu_debugaltlink file. >> >> 2018-11-11 Tom de Vries <tdevr...@suse.de> >> >> * dwarf.c (enum attr_val_encoding): Add ATTR_VAL_NONE. >> (read_attribute): Add altlink parameter. Handle missing altlink for >> DW_FORM_GNU_strp_alt and DW_FORM_GNU_ref_alt. >> (find_address_ranges, build_address_map, build_dwarf_data): Add and >> handle altlink parameter. >> (read_referenced_name, read_function_entry): Add argument to >> read_attribute call. > > > >> read_attribute (enum dwarf_form form, struct dwarf_buf *buf, >> int is_dwarf64, int version, int addrsize, >> const unsigned char *dwarf_str, size_t dwarf_str_size, >> - struct attr_val *val) >> + struct attr_val *val, struct dwarf_data *altlink) >> { > > altlink is not a result parameter, so it should be before val. > >
Done. >> @@ -1277,7 +1289,8 @@ find_address_ranges (struct backtrace_state *state, >> uintptr_t base_address, >> size_t dwarf_ranges_size, >> int is_bigendian, backtrace_error_callback >> error_callback, >> void *data, struct unit *u, >> - struct unit_addrs_vector *addrs) >> + struct unit_addrs_vector *addrs, >> + struct dwarf_data *altlink) > > Same. altlink should be before the error_callback parameter. > > Done. >> @@ -1431,7 +1444,8 @@ build_address_map (struct backtrace_state *state, >> uintptr_t base_address, >> const unsigned char *dwarf_ranges, size_t >> dwarf_ranges_size, >> const unsigned char *dwarf_str, size_t dwarf_str_size, >> int is_bigendian, backtrace_error_callback error_callback, >> - void *data, struct unit_addrs_vector *addrs) >> + void *data, struct unit_addrs_vector *addrs, >> + struct dwarf_data *altlink) > > Same. > Done. Thanks, - Tom
[libbacktrace] Handle alt FORMS without .gnu_debugaltlink Handle DW_FORM_GNU_strp_alt and DW_FORM_GNU_ref_alt references robustly in presence of missing .gnu_debugaltlink file. 2018-11-11 Tom de Vries <tdevr...@suse.de> * dwarf.c (enum attr_val_encoding): Add ATTR_VAL_NONE. (read_attribute): Add altlink parameter. Handle missing altlink for DW_FORM_GNU_strp_alt and DW_FORM_GNU_ref_alt. (find_address_ranges, build_address_map, build_dwarf_data): Add and handle altlink parameter. (read_referenced_name, read_function_entry): Add argument to read_attribute call. --- libbacktrace/dwarf.c | 44 +++++++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/libbacktrace/dwarf.c b/libbacktrace/dwarf.c index 5469f968468..0e2d57122a2 100644 --- a/libbacktrace/dwarf.c +++ b/libbacktrace/dwarf.c @@ -129,6 +129,8 @@ struct abbrevs enum attr_val_encoding { + /* No attribute value. */ + ATTR_VAL_NONE, /* An address. */ ATTR_VAL_ADDRESS, /* A unsigned integer. */ @@ -700,7 +702,7 @@ static int read_attribute (enum dwarf_form form, struct dwarf_buf *buf, int is_dwarf64, int version, int addrsize, const unsigned char *dwarf_str, size_t dwarf_str_size, - struct attr_val *val) + struct dwarf_data *altlink, struct attr_val *val) { /* Avoid warnings about val.u.FIELD may be used uninitialized if this function is inlined. The warnings aren't valid but can @@ -806,7 +808,7 @@ read_attribute (enum dwarf_form form, struct dwarf_buf *buf, form = read_uleb128 (buf); return read_attribute ((enum dwarf_form) form, buf, is_dwarf64, version, addrsize, dwarf_str, dwarf_str_size, - val); + altlink, val); } case DW_FORM_sec_offset: val->encoding = ATTR_VAL_REF_SECTION; @@ -832,12 +834,22 @@ read_attribute (enum dwarf_form form, struct dwarf_buf *buf, val->u.uint = read_uleb128 (buf); return 1; case DW_FORM_GNU_ref_alt: - val->encoding = ATTR_VAL_REF_SECTION; val->u.uint = read_offset (buf, is_dwarf64); + if (altlink == NULL) + { + val->encoding = ATTR_VAL_NONE; + return 1; + } + val->encoding = ATTR_VAL_REF_SECTION; return 1; case DW_FORM_GNU_strp_alt: - val->encoding = ATTR_VAL_REF_SECTION; val->u.uint = read_offset (buf, is_dwarf64); + if (altlink == NULL) + { + val->encoding = ATTR_VAL_NONE; + return 1; + } + val->encoding = ATTR_VAL_REF_SECTION; return 1; default: dwarf_buf_error (buf, "unrecognized DWARF form"); @@ -1275,9 +1287,9 @@ find_address_ranges (struct backtrace_state *state, uintptr_t base_address, const unsigned char *dwarf_str, size_t dwarf_str_size, const unsigned char *dwarf_ranges, size_t dwarf_ranges_size, - int is_bigendian, backtrace_error_callback error_callback, - void *data, struct unit *u, - struct unit_addrs_vector *addrs) + int is_bigendian, struct dwarf_data *altlink, + backtrace_error_callback error_callback, void *data, + struct unit *u, struct unit_addrs_vector *addrs) { while (unit_buf->left > 0) { @@ -1313,7 +1325,7 @@ find_address_ranges (struct backtrace_state *state, uintptr_t base_address, if (!read_attribute (abbrev->attrs[i].form, unit_buf, u->is_dwarf64, u->version, u->addrsize, - dwarf_str, dwarf_str_size, &val)) + dwarf_str, dwarf_str_size, altlink, &val)) return 0; switch (abbrev->attrs[i].name) @@ -1411,7 +1423,7 @@ find_address_ranges (struct backtrace_state *state, uintptr_t base_address, if (!find_address_ranges (state, base_address, unit_buf, dwarf_str, dwarf_str_size, dwarf_ranges, dwarf_ranges_size, - is_bigendian, error_callback, data, + is_bigendian, altlink, error_callback, data, u, addrs)) return 0; } @@ -1430,8 +1442,9 @@ build_address_map (struct backtrace_state *state, uintptr_t base_address, const unsigned char *dwarf_abbrev, size_t dwarf_abbrev_size, const unsigned char *dwarf_ranges, size_t dwarf_ranges_size, const unsigned char *dwarf_str, size_t dwarf_str_size, - int is_bigendian, backtrace_error_callback error_callback, - void *data, struct unit_addrs_vector *addrs) + int is_bigendian, struct dwarf_data *altlink, + backtrace_error_callback error_callback, void *data, + struct unit_addrs_vector *addrs) { struct dwarf_buf info; struct backtrace_vector units; @@ -1532,7 +1545,7 @@ build_address_map (struct backtrace_state *state, uintptr_t base_address, if (!find_address_ranges (state, base_address, &unit_buf, dwarf_str, dwarf_str_size, dwarf_ranges, dwarf_ranges_size, - is_bigendian, error_callback, data, + is_bigendian, altlink, error_callback, data, u, addrs)) goto fail; @@ -2147,7 +2160,7 @@ read_referenced_name (struct dwarf_data *ddata, struct unit *u, if (!read_attribute (abbrev->attrs[i].form, &unit_buf, u->is_dwarf64, u->version, u->addrsize, ddata->dwarf_str, ddata->dwarf_str_size, - &val)) + ddata->altlink, &val)) return NULL; switch (abbrev->attrs[i].name) @@ -2369,7 +2382,7 @@ read_function_entry (struct backtrace_state *state, struct dwarf_data *ddata, if (!read_attribute (abbrev->attrs[i].form, unit_buf, u->is_dwarf64, u->version, u->addrsize, ddata->dwarf_str, ddata->dwarf_str_size, - &val)) + ddata->altlink, &val)) return 0; /* The compile unit sets the base address for any address @@ -2995,7 +3008,8 @@ build_dwarf_data (struct backtrace_state *state, if (!build_address_map (state, base_address, dwarf_info, dwarf_info_size, dwarf_abbrev, dwarf_abbrev_size, dwarf_ranges, dwarf_ranges_size, dwarf_str, dwarf_str_size, - is_bigendian, error_callback, data, &addrs_vec)) + is_bigendian, altlink, error_callback, data, + &addrs_vec)) return NULL; if (!backtrace_vector_release (state, &addrs_vec.vec, error_callback, data))