diff options
author | Alan Modra <amodra@gmail.com> | 2021-07-03 09:38:40 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2021-07-05 20:04:21 +0930 |
commit | 40e1d303cedca7d67f6219686f06b9750659beab (patch) | |
tree | 416c08ac006b675ef6da56119163e7100e7a1ed0 /binutils/dwarf.c | |
parent | 74ace054855321bc5271dd7b354131cd0b71333a (diff) | |
download | gdb-40e1d303cedca7d67f6219686f06b9750659beab.zip gdb-40e1d303cedca7d67f6219686f06b9750659beab.tar.gz gdb-40e1d303cedca7d67f6219686f06b9750659beab.tar.bz2 |
PR28047, readelf crash due to assertion failure
DW_FORM_ref1, DW_FORM_ref2, DW_FORM_ref4, DW_FORM_ref1, and
DW_FORM_ref_udata are all supposed to be within the containing unit.
PR 28047
* dwarf.c (get_type_abbrev_from_form): Add cu_end parameter.
Check DW_FORM_ref1 etc. arg against cu_end rather than end of
section. Adjust all callers.
Diffstat (limited to 'binutils/dwarf.c')
-rw-r--r-- | binutils/dwarf.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/binutils/dwarf.c b/binutils/dwarf.c index 1e7f4db..ad1ee97 100644 --- a/binutils/dwarf.c +++ b/binutils/dwarf.c @@ -2066,6 +2066,7 @@ static abbrev_entry * get_type_abbrev_from_form (unsigned long form, unsigned long uvalue, dwarf_vma cu_offset, + unsigned char *cu_end, const struct dwarf_section *section, unsigned long *abbrev_num_return, unsigned char **data_return, @@ -2106,10 +2107,10 @@ get_type_abbrev_from_form (unsigned long form, case DW_FORM_ref4: case DW_FORM_ref8: case DW_FORM_ref_udata: - if (uvalue + cu_offset > section->size) + if (uvalue + cu_offset > (size_t) (cu_end - section->start)) { - warn (_("Unable to resolve ref form: uvalue %lx + cu_offset %lx > section size %lx\n"), - uvalue, (long) cu_offset, (long) section->size); + warn (_("Unable to resolve ref form: uvalue %lx + cu_offset %lx > CU size %lx\n"), + uvalue, (long) cu_offset, (long) (cu_end - section->start)); return NULL; } uvalue += cu_offset; @@ -2225,6 +2226,7 @@ get_type_signedness (abbrev_entry *entry, type_abbrev = get_type_abbrev_from_form (attr->form, uvalue, cu_offset, + end, section, NULL /* abbrev num return */, &type_data, @@ -2963,8 +2965,10 @@ read_and_display_attr_value (unsigned long attribute, unsigned char *type_data; abbrev_map *map; - type_abbrev = get_type_abbrev_from_form (form, uvalue, cu_offset, - section, NULL, &type_data, &map); + type_abbrev = get_type_abbrev_from_form (form, uvalue, + cu_offset, end, + section, NULL, + &type_data, &map); if (type_abbrev != NULL) { get_type_signedness (type_abbrev, section, type_data, @@ -3297,7 +3301,7 @@ read_and_display_attr_value (unsigned long attribute, unsigned long abbrev_number; abbrev_entry *entry; - entry = get_type_abbrev_from_form (form, uvalue, cu_offset, + entry = get_type_abbrev_from_form (form, uvalue, cu_offset, end, section, & abbrev_number, NULL, NULL); if (entry == NULL) { |