diff options
author | Tom Tromey <tromey@redhat.com> | 2011-07-08 19:54:55 +0000 |
---|---|---|
committer | Tom Tromey <tromey@redhat.com> | 2011-07-08 19:54:55 +0000 |
commit | 5e44ecb338cc222e3033b72fe63e67054b942eed (patch) | |
tree | 4d047efacbed379778e7aa2c37a40183978ae734 /gdb/dwarf2loc.c | |
parent | e0e9434c89d87e12220d5efd8d56ac83bdd26dfa (diff) | |
download | gdb-5e44ecb338cc222e3033b72fe63e67054b942eed.zip gdb-5e44ecb338cc222e3033b72fe63e67054b942eed.tar.gz gdb-5e44ecb338cc222e3033b72fe63e67054b942eed.tar.bz2 |
* dwarf2loc.c (locexpr_regname): New function.
(locexpr_describe_location_piece): Use it.
(disassemble_dwarf_expression): Add per_cu argument. Use
locexpr_regname.
<DW_OP_GNU_deref_type, DW_OP_GNU_const_type,
DW_OP_GNU_regval_type, DW_OP_GNU_convert, DW_OP_GNU_reinterpret>:
New cases.
(locexpr_describe_location_1): Add per_cu argument.
(locexpr_describe_location): Update.
(loclist_describe_location): Update.
Diffstat (limited to 'gdb/dwarf2loc.c')
-rw-r--r-- | gdb/dwarf2loc.c | 114 |
1 files changed, 94 insertions, 20 deletions
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c index 9afb186..baac1c6 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"); |