]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
implement support for missing DW_LLE_* and DW_RLE_* values
authorLuboš Luňák <l.lunak@centrum.cz>
Mon, 25 Apr 2022 20:11:27 +0000 (22:11 +0200)
committerMark Wielaard <mark@klomp.org>
Tue, 14 Jun 2022 18:47:02 +0000 (20:47 +0200)
coregrind/m_debuginfo/d3basics.c
coregrind/m_debuginfo/priv_d3basics.h
coregrind/m_debuginfo/readdwarf3.c

index 555e1e00d0d768cebfb14dc50f214d9b66f49106..d48589a30ca2555761ad221fe400b44297d1ca00 100644 (file)
@@ -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 ------ */
 
index 9d825e39ef4c8991954aac341c1d19bc21d9537c..3f6e5c72c9e44a114829f10026c0681a2fa0b2a3 100644 (file)
@@ -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 --- */
index 86af340ebc6dcc21e590c4e56498d42f448671a2..5a031a60430cf841d5d0fde062971f16fba2e374 100644 (file)
@@ -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);
 }