From 5e44ecb338cc222e3033b72fe63e67054b942eed Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Fri, 8 Jul 2011 19:54:55 +0000 Subject: [PATCH] * dwarf2loc.c (locexpr_regname): New function. (locexpr_describe_location_piece): Use it. (disassemble_dwarf_expression): Add per_cu argument. Use locexpr_regname. : New cases. (locexpr_describe_location_1): Add per_cu argument. (locexpr_describe_location): Update. (loclist_describe_location): Update. --- gdb/ChangeLog | 13 ++++++ gdb/dwarf2loc.c | 114 +++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 107 insertions(+), 20 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index e33a1da13f5..3ba20a6bec2 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,16 @@ +2011-07-08 Tom Tromey + + * dwarf2loc.c (locexpr_regname): New function. + (locexpr_describe_location_piece): Use it. + (disassemble_dwarf_expression): Add per_cu argument. Use + locexpr_regname. + : + New cases. + (locexpr_describe_location_1): Add per_cu argument. + (locexpr_describe_location): Update. + (loclist_describe_location): Update. + 2011-07-08 Tom Tromey * dwarf2expr.c (execute_stack_op): Add QUIT. diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c index 9afb186a5d2..baac1c69236 100644 --- a/gdb/dwarf2loc.c +++ b/gdb/dwarf2loc.c @@ -2185,6 +2185,18 @@ piece_end_p (const gdb_byte *data, const gdb_byte *end) 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 @@ -2197,13 +2209,11 @@ locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream, 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) @@ -2211,9 +2221,8 @@ locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream, 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) { @@ -2269,11 +2278,9 @@ locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream, 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 @@ -2281,14 +2288,12 @@ locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream, { 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 @@ -2345,7 +2350,8 @@ disassemble_dwarf_expression (struct ui_file *stream, 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; @@ -2458,13 +2464,13 @@ disassemble_dwarf_expression (struct ui_file *stream, 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: @@ -2507,7 +2513,7 @@ disassemble_dwarf_expression (struct ui_file *stream, 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: @@ -2515,7 +2521,7 @@ disassemble_dwarf_expression (struct ui_file *stream, 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; @@ -2598,6 +2604,71 @@ disassemble_dwarf_expression (struct ui_file *stream, 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"); @@ -2614,7 +2685,7 @@ locexpr_describe_location_1 (struct symbol *symbol, CORE_ADDR addr, 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; @@ -2645,7 +2716,8 @@ locexpr_describe_location_1 (struct symbol *symbol, CORE_ADDR addr, 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) { @@ -2709,7 +2781,8 @@ locexpr_describe_location (struct symbol *symbol, CORE_ADDR addr, 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 @@ -2855,7 +2928,8 @@ loclist_describe_location (struct symbol *symbol, CORE_ADDR addr, /* 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"); -- 2.30.2