X-Git-Url: http://drtracing.org/?a=blobdiff_plain;ds=sidebyside;f=gdb%2Fdwarf2loc.c;h=841fb8f2333f8378ce502971298bfc216d684aab;hb=9e35dae42503f6cef9a1f87e31a6f1111f3cb508;hp=acdbb1c95ab9702bf47505de01ceb5c37e73a75d;hpb=dfa52d88e70f7149def79ecf95faea9f87477df4;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c index acdbb1c95a..841fb8f233 100644 --- a/gdb/dwarf2loc.c +++ b/gdb/dwarf2loc.c @@ -1,6 +1,6 @@ /* DWARF 2 location expression support for GDB. - Copyright 2003, 2005 Free Software Foundation, Inc. + Copyright (C) 2003, 2005 Free Software Foundation, Inc. Contributed by Daniel Jacobowitz, MontaVista Software, Inc. @@ -18,8 +18,8 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ #include "defs.h" #include "ui-out.h" @@ -32,6 +32,7 @@ #include "ax-gdb.h" #include "regcache.h" #include "objfiles.h" +#include "exceptions.h" #include "elf/dwarf2.h" #include "dwarf2expr.h" @@ -51,13 +52,14 @@ For now, only return the first matching location expression; there can be more than one in the list. */ -static char * +static gdb_byte * find_location_expression (struct dwarf2_loclist_baton *baton, size_t *locexpr_length, CORE_ADDR pc) { CORE_ADDR low, high; - char *loc_ptr, *buf_end; - unsigned int addr_size = TARGET_ADDR_BIT / TARGET_CHAR_BIT, length; + gdb_byte *loc_ptr, *buf_end; + int length; + unsigned int addr_size = TARGET_ADDR_BIT / TARGET_CHAR_BIT; CORE_ADDR base_mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1)); /* Adjust base_address for relocatable objects. */ CORE_ADDR base_offset = ANOFFSET (baton->objfile->section_offsets, @@ -121,12 +123,12 @@ dwarf_expr_read_reg (void *baton, int dwarf_regnum) struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton; CORE_ADDR result, save_addr; enum lval_type lval_type; - char *buf; + gdb_byte *buf; int optimized, regnum, realnum, regsize; regnum = DWARF2_REG_TO_REGNUM (dwarf_regnum); regsize = register_size (current_gdbarch, regnum); - buf = (char *) alloca (regsize); + buf = alloca (regsize); frame_register (debaton->frame, regnum, &optimized, &lval_type, &save_addr, &realnum, buf); @@ -140,7 +142,7 @@ dwarf_expr_read_reg (void *baton, int dwarf_regnum) /* Read memory at ADDR (length LEN) into BUF. */ static void -dwarf_expr_read_mem (void *baton, char *buf, CORE_ADDR addr, size_t len) +dwarf_expr_read_mem (void *baton, gdb_byte *buf, CORE_ADDR addr, size_t len) { read_memory (addr, buf, len); } @@ -149,7 +151,7 @@ dwarf_expr_read_mem (void *baton, char *buf, CORE_ADDR addr, size_t len) describing the frame base. Return a pointer to it in START and its length in LENGTH. */ static void -dwarf_expr_frame_base (void *baton, unsigned char **start, size_t * length) +dwarf_expr_frame_base (void *baton, gdb_byte **start, size_t * length) { /* FIXME: cagney/2003-03-26: This code should be using get_frame_base_address(), and then implement a dwarf2 specific @@ -162,9 +164,11 @@ dwarf_expr_frame_base (void *baton, unsigned char **start, size_t * length) if (SYMBOL_OPS (framefunc) == &dwarf2_loclist_funcs) { struct dwarf2_loclist_baton *symbaton; + struct frame_info *frame = debaton->frame; + symbaton = SYMBOL_LOCATION_BATON (framefunc); *start = find_location_expression (symbaton, length, - get_frame_pc (debaton->frame)); + get_frame_address_in_block (frame)); } else { @@ -175,7 +179,7 @@ dwarf_expr_frame_base (void *baton, unsigned char **start, size_t * length) } if (*start == NULL) - error ("Could not find the frame base for \"%s\".", + error (_("Could not find the frame base for \"%s\"."), SYMBOL_NATURAL_NAME (framefunc)); } @@ -185,18 +189,8 @@ static CORE_ADDR dwarf_expr_tls_address (void *baton, CORE_ADDR offset) { struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton; - CORE_ADDR addr; - - if (target_get_thread_local_address_p ()) - addr = target_get_thread_local_address (inferior_ptid, - debaton->objfile, - offset); - /* It wouldn't be wrong here to try a gdbarch method, too; finding - TLS is an ABI-specific thing. But we don't do that yet. */ - else - error ("Cannot find thread-local variables on this target"); - return addr; + return target_translate_tls_address (debaton->objfile, offset); } /* Evaluate a location description, starting at DATA and with length @@ -204,7 +198,7 @@ dwarf_expr_tls_address (void *baton, CORE_ADDR offset) of FRAME. */ static struct value * dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame, - unsigned char *data, unsigned short size, + gdb_byte *data, unsigned short size, struct objfile *objfile) { struct gdbarch *arch = get_frame_arch (frame); @@ -232,11 +226,28 @@ dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame, dwarf_expr_eval (ctx, data, size); if (ctx->num_pieces > 0) { - /* We haven't implemented splicing together pieces from - arbitrary sources yet. */ - error ("The value of variable '%s' is distributed across several\n" - "locations, and GDB cannot access its value.\n", - SYMBOL_NATURAL_NAME (var)); + int i; + long offset = 0; + bfd_byte *contents; + + retval = allocate_value (SYMBOL_TYPE (var)); + contents = value_contents_raw (retval); + for (i = 0; i < ctx->num_pieces; i++) + { + struct dwarf_expr_piece *p = &ctx->pieces[i]; + if (p->in_reg) + { + bfd_byte regval[MAX_REGISTER_SIZE]; + int gdb_regnum = DWARF2_REG_TO_REGNUM (p->value); + get_frame_register (frame, gdb_regnum, regval); + memcpy (contents + offset, regval, p->size); + } + else /* In memory? */ + { + read_memory (p->value, contents + offset, p->size); + } + offset += p->size; + } } else if (ctx->in_reg) { @@ -281,16 +292,16 @@ needs_frame_read_reg (void *baton, int regnum) /* Reads from memory do not require a frame. */ static void -needs_frame_read_mem (void *baton, char *buf, CORE_ADDR addr, size_t len) +needs_frame_read_mem (void *baton, gdb_byte *buf, CORE_ADDR addr, size_t len) { memset (buf, 0, len); } /* Frame-relative accesses do require a frame. */ static void -needs_frame_frame_base (void *baton, unsigned char **start, size_t * length) +needs_frame_frame_base (void *baton, gdb_byte **start, size_t * length) { - static char lit0 = DW_OP_lit0; + static gdb_byte lit0 = DW_OP_lit0; struct needs_frame_baton *nf_baton = baton; *start = &lit0; @@ -312,7 +323,7 @@ needs_frame_tls_address (void *baton, CORE_ADDR offset) requires a frame to evaluate. */ static int -dwarf2_loc_desc_needs_frame (unsigned char *data, unsigned short size) +dwarf2_loc_desc_needs_frame (gdb_byte *data, unsigned short size) { struct needs_frame_baton baton; struct dwarf_expr_context *ctx; @@ -348,12 +359,12 @@ dwarf2_loc_desc_needs_frame (unsigned char *data, unsigned short size) } static void -dwarf2_tracepoint_var_ref (struct symbol * symbol, struct agent_expr * ax, - struct axs_value * value, unsigned char *data, +dwarf2_tracepoint_var_ref (struct symbol *symbol, struct agent_expr *ax, + struct axs_value *value, gdb_byte *data, int size) { if (size == 0) - error ("Symbol \"%s\" has been optimized out.", + error (_("Symbol \"%s\" has been optimized out."), SYMBOL_PRINT_NAME (symbol)); if (size == 1 @@ -376,11 +387,11 @@ dwarf2_tracepoint_var_ref (struct symbol * symbol, struct agent_expr * ax, as above. */ int frame_reg; LONGEST frame_offset; - unsigned char *buf_end; + gdb_byte *buf_end; buf_end = read_sleb128 (data + 1, data + size, &frame_offset); if (buf_end != data + size) - error ("Unexpected opcode after DW_OP_fbreg for symbol \"%s\".", + error (_("Unexpected opcode after DW_OP_fbreg for symbol \"%s\"."), SYMBOL_PRINT_NAME (symbol)); TARGET_VIRTUAL_FRAME_POINTER (ax->scope, &frame_reg, &frame_offset); @@ -388,13 +399,30 @@ dwarf2_tracepoint_var_ref (struct symbol * symbol, struct agent_expr * ax, ax_const_l (ax, frame_offset); ax_simple (ax, aop_add); - ax_const_l (ax, frame_offset); + value->kind = axs_lvalue_memory; + } + else if (data[0] >= DW_OP_breg0 + && data[0] <= DW_OP_breg31) + { + unsigned int reg; + LONGEST offset; + gdb_byte *buf_end; + + reg = data[0] - DW_OP_breg0; + buf_end = read_sleb128 (data + 1, data + size, &offset); + if (buf_end != data + size) + error (_("Unexpected opcode after DW_OP_breg%u for symbol \"%s\"."), + reg, SYMBOL_PRINT_NAME (symbol)); + + ax_reg (ax, reg); + ax_const_l (ax, offset); ax_simple (ax, aop_add); + value->kind = axs_lvalue_memory; } else - error ("Unsupported DWARF opcode in the location of \"%s\".", - SYMBOL_PRINT_NAME (symbol)); + error (_("Unsupported DWARF opcode 0x%x in the location of \"%s\"."), + data[0], SYMBOL_PRINT_NAME (symbol)); } /* Return the value of SYMBOL in FRAME using the DWARF-2 expression @@ -506,15 +534,21 @@ loclist_read_variable (struct symbol *symbol, struct frame_info *frame) { struct dwarf2_loclist_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol); struct value *val; - unsigned char *data; + gdb_byte *data; size_t size; data = find_location_expression (dlbaton, &size, - frame ? get_frame_pc (frame) : 0); + frame ? get_frame_address_in_block (frame) + : 0); if (data == NULL) - error ("Variable \"%s\" is not available.", SYMBOL_NATURAL_NAME (symbol)); - - val = dwarf2_evaluate_loc_desc (symbol, frame, data, size, dlbaton->objfile); + { + val = allocate_value (SYMBOL_TYPE (symbol)); + VALUE_LVAL (val) = not_lval; + set_value_optimized_out (val, 1); + } + else + val = dwarf2_evaluate_loc_desc (symbol, frame, data, size, + dlbaton->objfile); return val; } @@ -548,12 +582,12 @@ loclist_tracepoint_var_ref (struct symbol * symbol, struct agent_expr * ax, struct axs_value * value) { struct dwarf2_loclist_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol); - unsigned char *data; + gdb_byte *data; size_t size; data = find_location_expression (dlbaton, &size, ax->scope); if (data == NULL) - error ("Variable \"%s\" is not available.", SYMBOL_NATURAL_NAME (symbol)); + error (_("Variable \"%s\" is not available."), SYMBOL_NATURAL_NAME (symbol)); dwarf2_tracepoint_var_ref (symbol, ax, value, data, size); }