From: Luboš Luňák Date: Mon, 25 Apr 2022 20:11:27 +0000 (+0200) Subject: implement support for missing DW_LLE_* and DW_RLE_* values X-Git-Tag: VALGRIND_3_20_0~35 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4bb0164e6b2067376f085452a40137f13436384c;p=thirdparty%2Fvalgrind.git implement support for missing DW_LLE_* and DW_RLE_* values --- diff --git a/coregrind/m_debuginfo/d3basics.c b/coregrind/m_debuginfo/d3basics.c index 555e1e00d0..d48589a30c 100644 --- a/coregrind/m_debuginfo/d3basics.c +++ b/coregrind/m_debuginfo/d3basics.c @@ -435,6 +435,37 @@ const HChar* ML_(pp_DW_AT) ( DW_AT attr ) return "DW_AT_???"; } +const HChar* ML_(pp_DW_LLE) ( DW_LLE entry ) +{ + switch (entry) { + case DW_LLE_end_of_list: return "DW_LLE_end_of_list"; + case DW_LLE_base_addressx: return "DW_LLE_base_addressx"; + case DW_LLE_startx_endx: return "DW_LLE_startx_endx"; + case DW_LLE_startx_length: return "DW_LLE_startx_length"; + case DW_LLE_offset_pair: return "DW_LLE_offset_pair"; + case DW_LLE_default_location: return "DW_LLE_default_location"; + case DW_LLE_base_address: return "DW_LLE_base_address"; + case DW_LLE_start_end: return "DW_LLE_start_end"; + case DW_LLE_start_length: return "DW_LLE_start_length"; + case DW_LLE_GNU_view_pair: return "DW_LLE_GNU_view_pair"; + } + return "DW_LLE_???"; +} + +const HChar* ML_(pp_DW_RLE) ( DW_RLE entry ) +{ + switch (entry) { + case DW_RLE_end_of_list: return "DW_RLE_end_of_list"; + case DW_RLE_base_addressx: return "DW_RLE_base_addressx"; + case DW_RLE_startx_endx: return "DW_RLE_startx_endx"; + case DW_RLE_startx_length: return "DW_RLE_startx_length"; + case DW_RLE_offset_pair: return "DW_RLE_offset_pair"; + case DW_RLE_base_address: return "DW_RLE_base_address"; + case DW_RLE_start_end: return "DW_RLE_start_end"; + case DW_RLE_start_length: return "DW_RLE_start_length"; + } + return "DW_RLE_???"; +} /* ------ To do with evaluation of Dwarf expressions ------ */ diff --git a/coregrind/m_debuginfo/priv_d3basics.h b/coregrind/m_debuginfo/priv_d3basics.h index 9d825e39ef..3f6e5c72c9 100644 --- a/coregrind/m_debuginfo/priv_d3basics.h +++ b/coregrind/m_debuginfo/priv_d3basics.h @@ -768,6 +768,8 @@ const HChar* ML_(pp_DW_children) ( DW_children hashch ); const HChar* ML_(pp_DW_TAG) ( DW_TAG tag ); const HChar* ML_(pp_DW_FORM) ( DW_FORM form ); const HChar* ML_(pp_DW_AT) ( DW_AT attr ); +const HChar* ML_(pp_DW_LLE) ( DW_LLE entry ); +const HChar* ML_(pp_DW_RLE) ( DW_RLE entry ); /* --- To do with evaluation of Dwarf expressions --- */ diff --git a/coregrind/m_debuginfo/readdwarf3.c b/coregrind/m_debuginfo/readdwarf3.c index 86af340ebc..5a031a6043 100644 --- a/coregrind/m_debuginfo/readdwarf3.c +++ b/coregrind/m_debuginfo/readdwarf3.c @@ -576,6 +576,55 @@ static UWord uncook_die( const CUConst *cc, UWord die, /*OUT*/Bool *type_flag, return die; } +/* Return an entry from .debug_addr with the given index. + Call one of the variants below that do error-checking. */ +static ULong get_debug_addr_entry_common( ULong index, const CUConst* cc ) +{ + vg_assert(cc->cu_has_addr_base); + /* We make the same word-size assumption as DW_FORM_addr. */ + UWord addr_pos = cc->cu_addr_base + index * sizeof(UWord); + Cursor cur; + init_Cursor( &cur, cc->escn_debug_addr, addr_pos, cc->barf, + "get_debug_addr_entry_common: index points outside .debug_addr" ); + return (ULong)(UWord)get_UWord(&cur); +} + +static ULong get_debug_addr_entry_form( ULong index, const CUConst* cc, + DW_FORM form ) +{ + if(!cc->cu_has_addr_base) { + VG_(printf)( + "get_debug_addr_entry_form: %u (%s) without DW_AT_addr_base\n", + form, ML_(pp_DW_FORM)(form)); + cc->barf("get_debug_addr_entry_form: DW_AT_addr_base not set"); + } + return get_debug_addr_entry_common( index, cc ); +} + +static ULong get_debug_addr_entry_lle( ULong index, const CUConst* cc, + DW_LLE entry ) +{ + if(!cc->cu_has_addr_base) { + VG_(printf)( + "get_debug_addr_entry_lle: %u (%s) without DW_AT_addr_base\n", + entry, ML_(pp_DW_LLE)(entry)); + cc->barf("get_debug_addr_entry_lle: DW_AT_addr_base not set"); + } + return get_debug_addr_entry_common( index, cc ); +} + +static ULong get_debug_addr_entry_rle( ULong index, const CUConst* cc, + DW_RLE entry ) +{ + if(!cc->cu_has_addr_base) { + VG_(printf)( + "get_debug_addr_entry_rle: %u (%s) without DW_AT_addr_base\n", + entry, ML_(pp_DW_RLE)(entry)); + cc->barf("get_debug_addr_entry_rle: DW_AT_addr_base not set"); + } + return get_debug_addr_entry_common( index, cc ); +} + /*------------------------------------------------------------*/ /*--- ---*/ /*--- Helper functions for Guarded Expressions ---*/ @@ -784,8 +833,22 @@ static GExpr* make_general_GX ( const CUConst* cc, get_ULEB128( &loc ); break; case DW_LLE_base_addressx: + base = get_debug_addr_entry_lle( get_ULEB128( &loc ), cc, + DW_LLE_base_addressx ); + break; case DW_LLE_startx_endx: + w1 = get_debug_addr_entry_lle( get_ULEB128( &loc ), cc, + DW_LLE_startx_endx ); + w2 = get_debug_addr_entry_lle( get_ULEB128( &loc ), cc, + DW_LLE_startx_endx ); + len = get_ULEB128( &loc ); + break; case DW_LLE_startx_length: + w1 = get_debug_addr_entry_lle( get_ULEB128( &loc ), cc, + DW_LLE_startx_length ); + w2 = w1 + get_ULEB128( &loc ); + len = get_ULEB128( &loc ); + break; case DW_LLE_default_location: default: cc->barf( "Unhandled or unknown loclists entry" ); @@ -1007,8 +1070,20 @@ get_range_list ( const CUConst* cc, w2 = get_UWord ( &ranges ); break; case DW_RLE_base_addressx: + base = get_debug_addr_entry_rle( get_ULEB128( &ranges ), cc, + DW_RLE_base_addressx ); + break; case DW_RLE_startx_endx: + w1 = get_debug_addr_entry_rle( get_ULEB128( &ranges ), cc, + DW_RLE_startx_endx ); + w2 = get_debug_addr_entry_rle( get_ULEB128( &ranges ), cc, + DW_RLE_startx_endx ); + break; case DW_RLE_startx_length: + w1 = get_debug_addr_entry_rle( get_ULEB128( &ranges ), cc, + DW_RLE_startx_length ); + w2 = w1 + get_ULEB128( &ranges ); + break; default: cc->barf( "Unhandled or unknown range list entry" ); done = True; @@ -1312,23 +1387,7 @@ typedef static void get_Form_contents_addr( /*OUT*/FormContents* cts, DW_FORM form, ULong index, const CUConst* cc, Bool td3 ) { - if(!cc->cu_has_addr_base) { - VG_(printf)( - "get_Form_contents_addr: %u (%s) without DW_AT_addr_base\n", - form, ML_(pp_DW_FORM)(form)); - cc->barf("get_Form_contents_addr: DW_AT_addr_base not set"); - } - /* We make the same word-size assumption as DW_FORM_addr. */ - UWord addr_pos = cc->cu_addr_base + index * sizeof(UWord); - Cursor cur; - init_Cursor( &cur, cc->escn_debug_addr, addr_pos, cc->barf, - "get_Form_contents_addr: index points outside .debug_addr" ); - if (TD3) { - HChar* tmp = ML_(cur_read_strdup)(get_DiCursor_from_Cursor(&cur), "di.getFC.1"); - TRACE_D3("(indirect address, offset: 0x%lx): %s", addr_pos, tmp); - ML_(dinfo_free)(tmp); - } - cts->u.val = (ULong)(UWord)get_UWord(&cur); + cts->u.val = get_debug_addr_entry_form( index, cc, form ); cts->szB = sizeof(UWord); TRACE_D3("0x%lx", (UWord)cts->u.val); }