summaryrefslogtreecommitdiffstats
path: root/src/readelf.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/readelf.c')
-rw-r--r--src/readelf.c64
1 files changed, 57 insertions, 7 deletions
diff --git a/src/readelf.c b/src/readelf.c
index 466d941e..18588022 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -4180,6 +4180,29 @@ print_bytes (size_t n, const unsigned char *bytes)
}
}
+static int
+get_indexed_addr (Dwarf_CU *cu, Dwarf_Word idx, Dwarf_Addr *addr)
+{
+ Elf_Data *debug_addr = cu->dbg->sectiondata[IDX_debug_addr];
+ if (debug_addr == NULL)
+ return -1;
+
+ Dwarf_Off base = __libdw_cu_addr_base (cu);
+ Dwarf_Word off = idx * cu->address_size;
+ if (base > debug_addr->d_size
+ || off > debug_addr->d_size - base
+ || cu->address_size > debug_addr->d_size - base - off)
+ return -1;
+
+ const unsigned char *addrp = debug_addr->d_buf + base + off;
+ if (cu->address_size == 4)
+ *addr = read_4ubyte_unaligned (cu->dbg, addrp);
+ else
+ *addr = read_8ubyte_unaligned (cu->dbg, addrp);
+
+ return 0;
+}
+
static void
print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
unsigned int vers, unsigned int addrsize, unsigned int offset_size,
@@ -4348,19 +4371,36 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
case DW_OP_piece:
case DW_OP_regx:
case DW_OP_plus_uconst:
- case DW_OP_constu:
+ case DW_OP_constu:;
+ const unsigned char *start = data;
+ uint64_t uleb;
+ NEED (1);
+ get_uleb128 (uleb, data, data + len);
+ printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 "\n",
+ indent, "", (uintmax_t) offset, op_name, uleb);
+ CONSUME (data - start);
+ offset += 1 + (data - start);
+ break;
+
case DW_OP_addrx:
case DW_OP_GNU_addr_index:
case DW_OP_constx:
case DW_OP_GNU_const_index:;
- const unsigned char *start = data;
- uint64_t uleb;
+ start = data;
NEED (1);
get_uleb128 (uleb, data, data + len);
- printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 "\n",
+ printf ("%*s[%2" PRIuMAX "] %s [%" PRIu64 "] ",
indent, "", (uintmax_t) offset, op_name, uleb);
CONSUME (data - start);
offset += 1 + (data - start);
+ if (get_indexed_addr (cu, uleb, &addr) != 0)
+ printf ("???\n");
+ else
+ {
+ a = format_dwarf_addr (dwflmod, 0, addr, addr);
+ printf ("%s\n", a);
+ free (a);
+ }
break;
case DW_OP_bit_piece:
@@ -6148,9 +6188,19 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
}
char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize,
addr, addr);
- printf (" %*s%-20s (%s) %s\n",
- (int) (level * 2), "", dwarf_attr_name (attr),
- dwarf_form_name (form), a);
+ if (form != DW_FORM_addr )
+ {
+ Dwarf_Word index;
+ if (dwarf_formudata (attrp, &index) != 0)
+ goto attrval_out;
+ printf (" %*s%-20s (%s) [%" PRIx64 "] %s\n",
+ (int) (level * 2), "", dwarf_attr_name (attr),
+ dwarf_form_name (form), index, a);
+ }
+ else
+ printf (" %*s%-20s (%s) %s\n",
+ (int) (level * 2), "", dwarf_attr_name (attr),
+ dwarf_form_name (form), a);
free (a);
}
break;