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 ------ */
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 ---*/
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" );
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;
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);
}