This just makes sure we know how the new forms are encoded. It doesn't yet handle them in the dwarf_form* functions. But it does make it possible to skip them when reading DWARF5.
DW_FORM_implicit_const has zero size (the value is in the abbrev, not in the info). DW_FORM_addrx[1234], DW_FORM_strx[1234], DW_FORM_ref_sup[48] and DW_FORM_data16 have constant size. DW_FORM_strp_sup and DW_FORM_line_strp are offset size. DW_FORM_addrx, DW_FORM_strx, DW_FORM_loclistx and DW_FORM_rnglistx encode a uleb128. Signed-off-by: Mark Wielaard <m...@klomp.org> --- libdw/ChangeLog | 10 ++++++++++ libdw/dwarf.h | 18 ++++++++++++++++++ libdw/libdwP.h | 22 ++++++++++++++++++---- libdw/libdw_form.c | 6 ++++++ 4 files changed, 52 insertions(+), 4 deletions(-) diff --git a/libdw/ChangeLog b/libdw/ChangeLog index 8e3bbef..65e4ddc 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,13 @@ +2018-02-08 Mark Wielaard <m...@klomp.org> + + * dwarf.h: Add DWARF5 DW_FORMs. + * libdwP.h (__libdw_form_val_compute_len): Handle fix length + DW_FORM_implicit_const, DW_FORM_addrx[1234], DW_FORM_strx[1234], + DW_FORM_ref_sup[48] and DW_FORM_data16. + * libdw_form.c (__libdw_form_val_compute_len): DW_FORM_strp_sup + and DW_FORM_line_strp are offset_size. DW_FORM_addrx, DW_FORM_strx, + DW_FORM_loclistx and DW_FORM_rnglistx are uleb128. + 2018-01-30 Mark Wielaard <m...@klomp.org> * Makefile.am (libdw_a_SOURCES): Add dwarf_get_units.c. diff --git a/libdw/dwarf.h b/libdw/dwarf.h index bf81694..4f36206 100644 --- a/libdw/dwarf.h +++ b/libdw/dwarf.h @@ -382,7 +382,25 @@ enum DW_FORM_sec_offset = 0x17, DW_FORM_exprloc = 0x18, DW_FORM_flag_present = 0x19, + DW_FORM_strx = 0x1a, + DW_FORM_addrx = 0x1b, + DW_FORM_ref_sup4 = 0x1c, + DW_FORM_strp_sup = 0x1d, + DW_FORM_data16 = 0x1e, + DW_FORM_line_strp = 0x1f, DW_FORM_ref_sig8 = 0x20, + DW_FORM_implicit_const = 0x21, + DW_FORM_loclistx = 0x22, + DW_FORM_rnglistx = 0x23, + DW_FORM_ref_sup8 = 0x24, + DW_FORM_strx1 = 0x25, + DW_FORM_strx2 = 0x26, + DW_FORM_strx3 = 0x27, + DW_FORM_strx4 = 0x28, + DW_FORM_addrx1 = 0x29, + DW_FORM_addrx2 = 0x2a, + DW_FORM_addrx3 = 0x2b, + DW_FORM_addrx4 = 0x2c, DW_FORM_GNU_ref_alt = 0x1f20, /* offset in alternate .debuginfo. */ DW_FORM_GNU_strp_alt = 0x1f21 /* offset in alternate .debug_str. */ diff --git a/libdw/libdwP.h b/libdw/libdwP.h index 10d1a86..b31497d 100644 --- a/libdw/libdwP.h +++ b/libdw/libdwP.h @@ -576,7 +576,7 @@ extern size_t __libdw_form_val_compute_len (struct Dwarf_CU *cu, const unsigned char *valp) __nonnull_attribute__ (1, 3) internal_function; -/* Find the length of a form attribute. */ +/* Find the length of a form attribute in DIE/info data. */ static inline size_t __nonnull_attribute__ (1, 3) __libdw_form_val_len (struct Dwarf_CU *cu, unsigned int form, @@ -587,10 +587,24 @@ __libdw_form_val_len (struct Dwarf_CU *cu, unsigned int form, static const uint8_t form_lengths[] = { [DW_FORM_flag_present] = 0x80, - [DW_FORM_data1] = 1, [DW_FORM_ref1] = 1, [DW_FORM_flag] = 1, + [DW_FORM_implicit_const] = 0x80, /* Value is in abbrev, not in info. */ + + [DW_FORM_flag] = 1, + [DW_FORM_data1] = 1, [DW_FORM_ref1] = 1, + [DW_FORM_addrx1] = 1, [DW_FORM_strx1] = 1, + [DW_FORM_data2] = 2, [DW_FORM_ref2] = 2, - [DW_FORM_data4] = 4, [DW_FORM_ref4] = 4, - [DW_FORM_data8] = 8, [DW_FORM_ref8] = 8, [DW_FORM_ref_sig8] = 8, + [DW_FORM_addrx2] = 2, [DW_FORM_strx2] = 2, + + [DW_FORM_addrx3] = 3, [DW_FORM_strx3] = 3, + + [DW_FORM_data4] = 4, [DW_FORM_ref4] = 4, [DW_FORM_ref_sup4] = 4, + [DW_FORM_addrx4] = 4, [DW_FORM_strx4] = 4, + + [DW_FORM_ref_sig8] = 8, + [DW_FORM_data8] = 8, [DW_FORM_ref8] = 8, [DW_FORM_ref_sup8] = 8, + + [DW_FORM_data16] = 16, }; /* Return immediately for forms with fixed lengths. */ diff --git a/libdw/libdw_form.c b/libdw/libdw_form.c index 72e2390..ebe6002 100644 --- a/libdw/libdw_form.c +++ b/libdw/libdw_form.c @@ -60,6 +60,8 @@ __libdw_form_val_compute_len (struct Dwarf_CU *cu, unsigned int form, break; case DW_FORM_strp: + case DW_FORM_strp_sup: + case DW_FORM_line_strp: case DW_FORM_sec_offset: case DW_FORM_GNU_ref_alt: case DW_FORM_GNU_strp_alt: @@ -103,6 +105,10 @@ __libdw_form_val_compute_len (struct Dwarf_CU *cu, unsigned int form, case DW_FORM_sdata: case DW_FORM_udata: case DW_FORM_ref_udata: + case DW_FORM_addrx: + case DW_FORM_loclistx: + case DW_FORM_rnglistx: + case DW_FORM_strx: get_uleb128 (u128, valp, endp); result = valp - startp; break; -- 1.8.3.1