return data == end || data[0] == DW_OP_piece || data[0] == DW_OP_bit_piece;
}
+/* Helper for locexpr_describe_location_piece that finds the name of a
+ DWARF register. */
+
+static const char *
+locexpr_regname (struct gdbarch *gdbarch, int dwarf_regnum)
+{
+ int regnum;
+
+ regnum = gdbarch_dwarf2_reg_to_regnum (gdbarch, dwarf_regnum);
+ return gdbarch_register_name (gdbarch, regnum);
+}
+
/* Nicely describe a single piece of a location, returning an updated
position in the bytecode sequence. This function cannot recognize
all locations; if a location is not recognized, it simply returns
unsigned int addr_size)
{
struct gdbarch *gdbarch = get_objfile_arch (objfile);
- int regno;
if (data[0] >= DW_OP_reg0 && data[0] <= DW_OP_reg31)
{
- regno = gdbarch_dwarf2_reg_to_regnum (gdbarch, data[0] - DW_OP_reg0);
fprintf_filtered (stream, _("a variable in $%s"),
- gdbarch_register_name (gdbarch, regno));
+ locexpr_regname (gdbarch, data[0] - DW_OP_reg0));
data += 1;
}
else if (data[0] == DW_OP_regx)
ULONGEST reg;
data = read_uleb128 (data + 1, end, ®);
- regno = gdbarch_dwarf2_reg_to_regnum (gdbarch, reg);
fprintf_filtered (stream, _("a variable in $%s"),
- gdbarch_register_name (gdbarch, regno));
+ locexpr_regname (gdbarch, reg));
}
else if (data[0] == DW_OP_fbreg)
{
return save_data;
}
- regno = gdbarch_dwarf2_reg_to_regnum (gdbarch, frame_reg);
-
fprintf_filtered (stream,
_("a variable at frame base reg $%s offset %s+%s"),
- gdbarch_register_name (gdbarch, regno),
+ locexpr_regname (gdbarch, frame_reg),
plongest (base_offset), plongest (frame_offset));
}
else if (data[0] >= DW_OP_breg0 && data[0] <= DW_OP_breg31
{
LONGEST offset;
- regno = gdbarch_dwarf2_reg_to_regnum (gdbarch, data[0] - DW_OP_breg0);
-
data = read_sleb128 (data + 1, end, &offset);
fprintf_filtered (stream,
_("a variable at offset %s from base reg $%s"),
plongest (offset),
- gdbarch_register_name (gdbarch, regno));
+ locexpr_regname (gdbarch, data[0] - DW_OP_breg0));
}
/* The location expression for a TLS variable looks like this (on a
struct gdbarch *arch, unsigned int addr_size,
int offset_size,
const gdb_byte *data, const gdb_byte *end,
- int all)
+ int all,
+ struct dwarf2_per_cu_data *per_cu)
{
const gdb_byte *start = data;
case DW_OP_reg30:
case DW_OP_reg31:
fprintf_filtered (stream, " [$%s]",
- gdbarch_register_name (arch, op - DW_OP_reg0));
+ locexpr_regname (arch, op - DW_OP_reg0));
break;
case DW_OP_regx:
data = read_uleb128 (data, end, &ul);
fprintf_filtered (stream, " %s [$%s]", pulongest (ul),
- gdbarch_register_name (arch, (int) ul));
+ locexpr_regname (arch, (int) ul));
break;
case DW_OP_implicit_value:
case DW_OP_breg31:
data = read_sleb128 (data, end, &l);
fprintf_filtered (stream, " %s [$%s]", plongest (l),
- gdbarch_register_name (arch, op - DW_OP_breg0));
+ locexpr_regname (arch, op - DW_OP_breg0));
break;
case DW_OP_bregx:
data = read_sleb128 (data, end, &l);
fprintf_filtered (stream, " register %s [$%s] offset %s",
pulongest (ul),
- gdbarch_register_name (arch, (int) ul),
+ locexpr_regname (arch, (int) ul),
plongest (l));
break;
plongest (l));
}
break;
+
+ case DW_OP_GNU_deref_type:
+ {
+ int addr_size = *data++;
+ ULONGEST offset;
+ struct type *type;
+
+ data = read_uleb128 (data, end, &offset);
+ type = dwarf2_get_die_type (offset, per_cu);
+ fprintf_filtered (stream, "<");
+ type_print (type, "", stream, -1);
+ fprintf_filtered (stream, " [0x%s]> %d", phex_nz (offset, 0),
+ addr_size);
+ }
+ break;
+
+ case DW_OP_GNU_const_type:
+ {
+ ULONGEST type_die;
+ struct type *type;
+
+ data = read_uleb128 (data, end, &type_die);
+ type = dwarf2_get_die_type (type_die, per_cu);
+ fprintf_filtered (stream, "<");
+ type_print (type, "", stream, -1);
+ fprintf_filtered (stream, " [0x%s]>", phex_nz (type_die, 0));
+ }
+ break;
+
+ case DW_OP_GNU_regval_type:
+ {
+ ULONGEST type_die, reg;
+ struct type *type;
+
+ data = read_uleb128 (data, end, ®);
+ data = read_uleb128 (data, end, &type_die);
+
+ type = dwarf2_get_die_type (type_die, per_cu);
+ fprintf_filtered (stream, "<");
+ type_print (type, "", stream, -1);
+ fprintf_filtered (stream, " [0x%s]> [$%s]", phex_nz (type_die, 0),
+ locexpr_regname (arch, reg));
+ }
+ break;
+
+ case DW_OP_GNU_convert:
+ case DW_OP_GNU_reinterpret:
+ {
+ ULONGEST type_die;
+
+ data = read_uleb128 (data, end, &type_die);
+
+ if (type_die == 0)
+ fprintf_filtered (stream, "<0>");
+ else
+ {
+ struct type *type;
+
+ type = dwarf2_get_die_type (type_die, per_cu);
+ fprintf_filtered (stream, "<");
+ type_print (type, "", stream, -1);
+ fprintf_filtered (stream, " [0x%s]>", phex_nz (type_die, 0));
+ }
+ }
+ break;
}
fprintf_filtered (stream, "\n");
struct ui_file *stream,
const gdb_byte *data, int size,
struct objfile *objfile, unsigned int addr_size,
- int offset_size)
+ int offset_size, struct dwarf2_per_cu_data *per_cu)
{
const gdb_byte *end = data + size;
int first_piece = 1, bad = 0;
data = disassemble_dwarf_expression (stream,
get_objfile_arch (objfile),
addr_size, offset_size, data, end,
- dwarf2_always_disassemble);
+ dwarf2_always_disassemble,
+ per_cu);
if (data < end)
{
locexpr_describe_location_1 (symbol, addr, stream,
dlbaton->data, dlbaton->size,
- objfile, addr_size, offset_size);
+ objfile, addr_size, offset_size,
+ dlbaton->per_cu);
}
/* Describe the location of SYMBOL as an agent value in VALUE, generating
/* Now describe this particular location. */
locexpr_describe_location_1 (symbol, low, stream, loc_ptr, length,
- objfile, addr_size, offset_size);
+ objfile, addr_size, offset_size,
+ dlbaton->per_cu);
fprintf_filtered (stream, "\n");