Index: ax-gdb.c =================================================================== RCS file: /cvs/src/src/gdb/ax-gdb.c,v retrieving revision 1.53 diff -p -r1.53 ax-gdb.c *** ax-gdb.c 14 Jul 2009 21:40:30 -0000 1.53 --- ax-gdb.c 18 Dec 2009 19:27:46 -0000 *************** gen_expr (struct expression *exp, union *** 1768,1773 **** --- 1768,1797 ---- } + struct agent_expr * + gen_trace_for_var (CORE_ADDR scope, struct symbol *var) + { + struct cleanup *old_chain = 0; + struct agent_expr *ax = new_agent_expr (scope); + struct axs_value value; + + old_chain = make_cleanup_free_agent_expr (ax); + + trace_kludge = 1; + gen_var_ref (NULL, ax, &value, var); + + /* Make sure we record the final object, and get rid of it. */ + gen_traced_pop (ax, &value); + + /* Oh, and terminate. */ + ax_simple (ax, aop_end); + + /* We have successfully built the agent expr, so cancel the cleanup + request. If we add more cleanups that we always want done, this + will have to get more complicated. */ + discard_cleanups (old_chain); + return ax; + } /* Generating bytecode from GDB expressions: driver */ Index: ax-gdb.h =================================================================== RCS file: /cvs/src/src/gdb/ax-gdb.h,v retrieving revision 1.12 diff -p -r1.12 ax-gdb.h *** ax-gdb.h 14 Jul 2009 21:40:30 -0000 1.12 --- ax-gdb.h 18 Dec 2009 19:27:46 -0000 *************** struct axs_value *** 99,104 **** --- 99,106 ---- function to discover which registers the expression uses. */ extern struct agent_expr *gen_trace_for_expr (CORE_ADDR, struct expression *); + extern struct agent_expr *gen_trace_for_var (CORE_ADDR, struct symbol *); + extern struct agent_expr *gen_eval_for_expr (CORE_ADDR, struct expression *); #endif /* AX_GDB_H */ Index: dwarf2loc.c =================================================================== RCS file: /cvs/src/src/gdb/dwarf2loc.c,v retrieving revision 1.68 diff -p -r1.68 dwarf2loc.c *** dwarf2loc.c 15 Sep 2009 16:20:53 -0000 1.68 --- dwarf2loc.c 18 Dec 2009 19:27:46 -0000 *************** *** 41,46 **** --- 41,50 ---- #include "gdb_string.h" #include "gdb_assert.h" + static void + dwarf_expr_frame_base_1 (struct symbol *framefunc, CORE_ADDR pc, + gdb_byte **start, size_t * length); + /* A helper function for dealing with location lists. Given a symbol baton (BATON) and a pc value (PC), find the appropriate location expression, set *LOCEXPR_LENGTH, and return a pointer *************** dwarf_expr_frame_base (void *baton, gdb_ *** 166,181 **** something has gone wrong. */ gdb_assert (framefunc != NULL); if (SYMBOL_LOCATION_BATON (framefunc) == NULL) *start = NULL; else if (SYMBOL_COMPUTED_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_address_in_block (frame)); } else { --- 170,192 ---- something has gone wrong. */ gdb_assert (framefunc != NULL); + dwarf_expr_frame_base_1 (framefunc, + get_frame_address_in_block (debaton->frame), + start, length); + } + + static void + dwarf_expr_frame_base_1 (struct symbol *framefunc, CORE_ADDR pc, + gdb_byte **start, size_t * length) + { if (SYMBOL_LOCATION_BATON (framefunc) == NULL) *start = NULL; else if (SYMBOL_COMPUTED_OPS (framefunc) == &dwarf2_loclist_funcs) { struct dwarf2_loclist_baton *symbaton; symbaton = SYMBOL_LOCATION_BATON (framefunc); ! *start = find_location_expression (symbaton, length, pc); } else { *************** dwarf2_tracepoint_var_ref (struct symbol *** 617,637 **** } else if (data[0] == DW_OP_fbreg) { ! /* And this is worse than just minimal; we should honor the frame base ! as above. */ ! int frame_reg; LONGEST frame_offset; 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\"."), SYMBOL_PRINT_NAME (symbol)); - gdbarch_virtual_frame_pointer (gdbarch, - ax->scope, &frame_reg, &frame_offset); ax_reg (ax, frame_reg); ! ax_const_l (ax, frame_offset); ax_simple (ax, aop_add); value->kind = axs_lvalue_memory; --- 628,679 ---- } else if (data[0] == DW_OP_fbreg) { ! struct block *b; ! struct symbol *framefunc; ! int frame_reg = 0; LONGEST frame_offset; gdb_byte *buf_end; + gdb_byte *base_data; + size_t base_size; + LONGEST base_offset = 0; + + b = block_for_pc (ax->scope); + + if (!b) + error (_("No block found for address")); + + framefunc = block_linkage_function (b); + + if (!framefunc) + error (_("No function found for block")); + + dwarf_expr_frame_base_1 (framefunc, ax->scope, + &base_data, &base_size); + + if (base_data[0] >= DW_OP_breg0 + && base_data[0] <= DW_OP_breg31) + { + frame_reg = base_data[0] - DW_OP_breg0; + buf_end = read_sleb128 (base_data + 1, base_data + base_size, &base_offset); + if (buf_end != base_data + base_size) + error (_("Unexpected opcode after DW_OP_breg%u for symbol \"%s\"."), + frame_reg, SYMBOL_PRINT_NAME (symbol)); + } + else + { + /* We don't know what to do with the frame base expression, + so we can't trace this variable; give up. */ + error (_("Cannot generate expression to collect symbol \"%s\"."), + SYMBOL_PRINT_NAME (symbol)); + } 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\"."), SYMBOL_PRINT_NAME (symbol)); ax_reg (ax, frame_reg); ! ax_const_l (ax, base_offset + frame_offset); ax_simple (ax, aop_add); value->kind = axs_lvalue_memory; Index: tracepoint.c =================================================================== RCS file: /cvs/src/src/gdb/tracepoint.c,v retrieving revision 1.126 diff -p -r1.126 tracepoint.c *** tracepoint.c 14 Jul 2009 21:40:30 -0000 1.126 --- tracepoint.c 18 Dec 2009 19:27:46 -0000 *************** static void *** 725,731 **** collect_symbol (struct collection_list *collect, struct symbol *sym, struct gdbarch *gdbarch, ! long frame_regno, long frame_offset) { unsigned long len; unsigned int reg; --- 725,732 ---- collect_symbol (struct collection_list *collect, struct symbol *sym, struct gdbarch *gdbarch, ! long frame_regno, long frame_offset, ! CORE_ADDR scope) { unsigned long len; unsigned int reg; *************** collect_symbol (struct collection_list * *** 817,822 **** --- 818,867 ---- printf_filtered ("%s has been optimized out of existence.\n", SYMBOL_PRINT_NAME (sym)); break; + + case LOC_COMPUTED: + { + struct agent_expr *aexpr; + struct cleanup *old_chain1 = NULL; + struct agent_reqs areqs; + + aexpr = gen_trace_for_var (scope, sym); + + old_chain1 = make_cleanup_free_agent_expr (aexpr); + + ax_reqs (aexpr, &areqs); + if (areqs.flaw != agent_flaw_none) + error (_("malformed expression")); + + if (areqs.min_height < 0) + error (_("gdb: Internal error: expression has min height < 0")); + if (areqs.max_height > 20) + error (_("expression too complicated, try simplifying")); + + discard_cleanups (old_chain1); + add_aexpr (collect, aexpr); + + /* take care of the registers */ + if (areqs.reg_mask_len > 0) + { + int ndx1, ndx2; + + for (ndx1 = 0; ndx1 < areqs.reg_mask_len; ndx1++) + { + QUIT; /* allow user to bail out with ^C */ + if (areqs.reg_mask[ndx1] != 0) + { + /* assume chars have 8 bits */ + for (ndx2 = 0; ndx2 < 8; ndx2++) + if (areqs.reg_mask[ndx1] & (1 << ndx2)) + /* it's used -- record it */ + add_register (collect, + ndx1 * 8 + ndx2); + } + } + } + } + break; } } *************** add_local_symbols (struct collection_lis *** 843,849 **** { count++; collect_symbol (collect, sym, gdbarch, ! frame_regno, frame_offset); } } if (BLOCK_FUNCTION (block)) --- 888,894 ---- { count++; collect_symbol (collect, sym, gdbarch, ! frame_regno, frame_offset, pc); } } if (BLOCK_FUNCTION (block)) *************** encode_actions (struct breakpoint *t, ch *** 1122,1128 **** exp->elts[2].symbol, t->gdbarch, frame_reg, ! frame_offset); break; default: /* full-fledged expression */ --- 1167,1174 ---- exp->elts[2].symbol, t->gdbarch, frame_reg, ! frame_offset, ! t->loc->address); break; default: /* full-fledged expression */