[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] Error out on DW_AT_location with invalid encoding
Hi,
When processing a file containing an DW_AT_location with encoding DW_FORM_addr,
we run into this assert in write_die:
...
dwz: dwz.c:9068: write_die: \
Assertion `p && (form == DW_FORM_sec_offset || form == DW_FORM_data4)' failed
...
Error out instead (and do it earlier, in read_debug_info):
...
$ ./dwz -m 3 1 2
./dwz: 1: DW_AT_stmt_list not DW_FORM_sec_offset or DW_FORM_data4
./dwz: 2: DW_AT_stmt_list not DW_FORM_sec_offset or DW_FORM_data4
./dwz: Too few files for multifile optimization
...
OK for trunk?
Thanks,
- Tom
Error out on DW_AT_location with invalid encoding
2019-02-14 Tom de Vries <tdevries@suse.de>
PR dwz/24171
* dwz.c (get_AT_int): Add and handle formp parameter.
(read_debug_info): Error out on invalid DW_AT_location encoding.
---
dwz.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/dwz.c b/dwz.c
index 4ef8657..79cddb6 100644
--- a/dwz.c
+++ b/dwz.c
@@ -1325,16 +1325,16 @@ get_AT (dw_die_ref die, enum dwarf_attribute at, enum dwarf_form *formp)
/* Return an integer attribute AT of DIE. Set *PRESENT to true
if found. */
static uint64_t
-get_AT_int (dw_die_ref die, enum dwarf_attribute at, bool *present)
+get_AT_int (dw_die_ref die, enum dwarf_attribute at, bool *present,
+ enum dwarf_form *formp)
{
- enum dwarf_form form;
unsigned char *ptr;
- ptr = get_AT (die, at, &form);
+ ptr = get_AT (die, at, formp);
*present = false;
if (ptr == NULL)
return 0;
*present = true;
- switch (form)
+ switch (*formp)
{
case DW_FORM_ref_addr:
return read_size (ptr, die_cu (die)->cu_version == 2 ? ptr_size : 4);
@@ -5000,9 +5000,18 @@ read_debug_info (DSO *dso, int kind)
}
cu->cu_comp_dir = get_AT_string (cu->cu_die, DW_AT_comp_dir);
- debug_line_off = get_AT_int (cu->cu_die, DW_AT_stmt_list, &present);
+ enum dwarf_form form;
+ debug_line_off
+ = get_AT_int (cu->cu_die, DW_AT_stmt_list, &present, &form);
if (present)
{
+ if (!(form == DW_FORM_sec_offset || form == DW_FORM_data4))
+ {
+ error (0, 0, "%s: DW_AT_stmt_list not DW_FORM_sec_offset or"
+ " DW_FORM_data4", dso->filename);
+ goto fail;
+ }
+
if (cu_files != NULL && last_debug_line_off == debug_line_off)
{
cu->cu_nfiles = cu_nfiles;