diff options
-rw-r--r-- | gdb/ChangeLog | 28 | ||||
-rw-r--r-- | gdb/dwarf2loc.c | 21 | ||||
-rw-r--r-- | gdb/findvar.c | 26 | ||||
-rw-r--r-- | gdb/frame-unwind.c | 3 | ||||
-rw-r--r-- | gdb/frame.c | 16 | ||||
-rw-r--r-- | gdb/frame.h | 4 | ||||
-rw-r--r-- | gdb/sentinel-frame.c | 2 | ||||
-rw-r--r-- | gdb/valarith.c | 2 | ||||
-rw-r--r-- | gdb/valops.c | 13 | ||||
-rw-r--r-- | gdb/value.c | 47 | ||||
-rw-r--r-- | gdb/value.h | 16 |
11 files changed, 140 insertions, 38 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 9740a23..caad792 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,33 @@ 2016-11-16 Kevin Buettner <kevinb@redhat.com> + * value.h (VALUE_FRAME_ID): Rename to VALUE_NEXT_FRAME_ID. Update + comment. Create new VALUE_FRAME_ID which is defined in terms of + VALUE_NEXT_FRAME_ID. + (deprecated_value_frame_id_hack): Rename to + deprecated_value_next_frame_id_hack. + * dwarf2loc.c, findvar.c, frame-unwind.c, sentinel-frame.c, + valarith.c, valops.c, value.c: Adjust nearly all occurences of + VALUE_FRAME_ID to VALUE_NEXT_FRAME_ID. Add comments for those + which did not change. + * value.c (struct value): Rename frame_id field to next_frame_id. + Update comment. + (deprecated_value_frame_id_hack): Rename to + deprecated_value_next_frame_id_hack. + (value_fetch_lazy): Call frame_unwind_register_value() + instead of get_frame_register_value(). + * frame.c (get_prev_frame_id_by_id): New function. + * frame.h (get_prev_frame_id_by_id): Declare. + * dwarf2loc.c (dwarf2_evaluate_loc_desc_full): Make + VALUE_NEXT_FRAME_ID refer to the next frame. + * findvar.c (value_of_register_lazy): Likewise. + (default_value_from_register): Likewise. + (value_from_register): Likewise. + * frame_unwind.c (frame_unwind_got_optimized): Likewise. + * sentinel-frame.c (sentinel_frame_prev_register): Likewise. + * value.h (VALUE_FRAME_ID): Update comment describing this macro. + +2016-11-16 Kevin Buettner <kevinb@redhat.com> + * frame.h (enum frame_id_stack_status): Add FID_STACK_SENTINEL. (struct frame_id): Increase number of bits required for storing stack status to 3 from 2. diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c index 93aec1f..44dceda 100644 --- a/gdb/dwarf2loc.c +++ b/gdb/dwarf2loc.c @@ -1672,13 +1672,18 @@ read_pieced_value (struct value *v) gdb_byte *contents; struct piece_closure *c = (struct piece_closure *) value_computed_closure (v); - struct frame_info *frame = frame_find_by_id (VALUE_FRAME_ID (v)); + struct frame_info *frame; size_t type_len; size_t buffer_size = 0; std::vector<gdb_byte> buffer; int bits_big_endian = gdbarch_bits_big_endian (get_type_arch (value_type (v))); + /* VALUE_FRAME_ID is used instead of VALUE_NEXT_FRAME_ID here + because FRAME is passed to get_frame_register_bytes(), which + does its own "->next" operation. */ + frame = frame_find_by_id (VALUE_FRAME_ID (v)); + if (value_type (v) != value_enclosing_type (v)) internal_error (__FILE__, __LINE__, _("Should not be able to create a lazy value with " @@ -1841,13 +1846,18 @@ write_pieced_value (struct value *to, struct value *from) const gdb_byte *contents; struct piece_closure *c = (struct piece_closure *) value_computed_closure (to); - struct frame_info *frame = frame_find_by_id (VALUE_FRAME_ID (to)); + struct frame_info *frame; size_t type_len; size_t buffer_size = 0; std::vector<gdb_byte> buffer; int bits_big_endian = gdbarch_bits_big_endian (get_type_arch (value_type (to))); + /* VALUE_FRAME_ID is used instead of VALUE_NEXT_FRAME_ID here + because FRAME is passed to get_frame_register_bytes() and + put_frame_register_bytes(), both of which do their own "->next" + operations. */ + frame = frame_find_by_id (VALUE_FRAME_ID (to)); if (frame == NULL) { mark_value_bytes_optimized_out (to, 0, TYPE_LENGTH (value_type (to))); @@ -2301,7 +2311,10 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, if (ctx.num_pieces > 0) { struct piece_closure *c; - struct frame_id frame_id = get_frame_id (frame); + struct frame_id frame_id + = frame == NULL + ? null_frame_id + : get_frame_id (get_next_frame_sentinel_okay (frame)); ULONGEST bit_size = 0; int i; @@ -2316,7 +2329,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, closure but before allocating the result. */ do_cleanups (value_chain); retval = allocate_computed_value (type, &pieced_value_funcs, c); - VALUE_FRAME_ID (retval) = frame_id; + VALUE_NEXT_FRAME_ID (retval) = frame_id; set_value_offset (retval, byte_offset); } else diff --git a/gdb/findvar.c b/gdb/findvar.c index 6e28a29..bab717a 100644 --- a/gdb/findvar.c +++ b/gdb/findvar.c @@ -283,17 +283,23 @@ value_of_register_lazy (struct frame_info *frame, int regnum) { struct gdbarch *gdbarch = get_frame_arch (frame); struct value *reg_val; + struct frame_info *next_frame; gdb_assert (regnum < (gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch))); - /* We should have a valid (i.e. non-sentinel) frame. */ - gdb_assert (frame_id_p (get_frame_id (frame))); + gdb_assert (frame != NULL); + + next_frame = get_next_frame_sentinel_okay (frame); + + /* We should have a valid next frame. */ + gdb_assert (frame_id_p (get_frame_id (next_frame))); reg_val = allocate_value_lazy (register_type (gdbarch, regnum)); VALUE_LVAL (reg_val) = lval_register; VALUE_REGNUM (reg_val) = regnum; - VALUE_FRAME_ID (reg_val) = get_frame_id (frame); + VALUE_NEXT_FRAME_ID (reg_val) = get_frame_id (next_frame); + return reg_val; } @@ -815,9 +821,17 @@ default_value_from_register (struct gdbarch *gdbarch, struct type *type, { int len = TYPE_LENGTH (type); struct value *value = allocate_value (type); + struct frame_info *frame; VALUE_LVAL (value) = lval_register; - VALUE_FRAME_ID (value) = frame_id; + frame = frame_find_by_id (frame_id); + + if (frame == NULL) + frame_id = null_frame_id; + else + frame_id = get_frame_id (get_next_frame_sentinel_okay (frame)); + + VALUE_NEXT_FRAME_ID (value) = frame_id; VALUE_REGNUM (value) = regnum; /* Any structure stored in more than one register will always be @@ -902,7 +916,7 @@ value_from_register (struct type *type, int regnum, struct frame_info *frame) including the location. */ v = allocate_value (type); VALUE_LVAL (v) = lval_register; - VALUE_FRAME_ID (v) = get_frame_id (frame); + VALUE_NEXT_FRAME_ID (v) = get_frame_id (get_next_frame_sentinel_okay (frame)); VALUE_REGNUM (v) = regnum; ok = gdbarch_register_to_value (gdbarch, frame, regnum, type1, value_contents_raw (v), &optim, @@ -950,7 +964,7 @@ address_from_register (int regnum, struct frame_info *frame) where the ID of FRAME is not yet known. Calling value_from_register would therefore abort in get_frame_id. However, since we only need a temporary value that is never used as lvalue, we actually do not - really need to set its VALUE_FRAME_ID. Therefore, we re-implement + really need to set its VALUE_NEXT_FRAME_ID. Therefore, we re-implement the core of value_from_register, but use the null_frame_id. */ /* Some targets require a special conversion routine even for plain diff --git a/gdb/frame-unwind.c b/gdb/frame-unwind.c index 187e6c2..974a236 100644 --- a/gdb/frame-unwind.c +++ b/gdb/frame-unwind.c @@ -210,7 +210,8 @@ frame_unwind_got_optimized (struct frame_info *frame, int regnum) mark_value_bytes_optimized_out (val, 0, TYPE_LENGTH (type)); VALUE_LVAL (val) = lval_register; VALUE_REGNUM (val) = regnum; - VALUE_FRAME_ID (val) = get_frame_id (frame); + VALUE_NEXT_FRAME_ID (val) + = get_frame_id (get_next_frame_sentinel_okay (frame)); return val; } diff --git a/gdb/frame.c b/gdb/frame.c index 54dc833..02635e6 100644 --- a/gdb/frame.c +++ b/gdb/frame.c @@ -2305,6 +2305,22 @@ get_prev_frame (struct frame_info *this_frame) return get_prev_frame_always (this_frame); } +struct frame_id +get_prev_frame_id_by_id (struct frame_id id) +{ + struct frame_id prev_id; + struct frame_info *frame; + + frame = frame_find_by_id (id); + + if (frame != NULL) + prev_id = get_frame_id (get_prev_frame (frame)); + else + prev_id = null_frame_id; + + return prev_id; +} + CORE_ADDR get_frame_pc (struct frame_info *frame) { diff --git a/gdb/frame.h b/gdb/frame.h index dc25ce9..e5c3d10 100644 --- a/gdb/frame.h +++ b/gdb/frame.h @@ -331,6 +331,10 @@ extern struct frame_info *get_prev_frame_always (struct frame_info *); is not found. */ extern struct frame_info *frame_find_by_id (struct frame_id id); +/* Given a frame's ID, find the previous frame's ID. Returns null_frame_id + if the frame is not found. */ +extern struct frame_id get_prev_frame_id_by_id (struct frame_id id); + /* Base attributes of a frame: */ /* The frame's `resume' address. Where the program will resume in diff --git a/gdb/sentinel-frame.c b/gdb/sentinel-frame.c index 6cd1bc3..eb827eb 100644 --- a/gdb/sentinel-frame.c +++ b/gdb/sentinel-frame.c @@ -51,7 +51,7 @@ sentinel_frame_prev_register (struct frame_info *this_frame, struct value *value; value = regcache_cooked_read_value (cache->regcache, regnum); - VALUE_FRAME_ID (value) = get_frame_id (this_frame); + VALUE_NEXT_FRAME_ID (value) = sentinel_frame_id; return value; } diff --git a/gdb/valarith.c b/gdb/valarith.c index de6fcfd..2c56110 100644 --- a/gdb/valarith.c +++ b/gdb/valarith.c @@ -227,7 +227,7 @@ value_subscripted_rvalue (struct value *array, LONGEST index, int lowerbound) set_value_component_location (v, array); VALUE_REGNUM (v) = VALUE_REGNUM (array); - VALUE_FRAME_ID (v) = VALUE_FRAME_ID (array); + VALUE_NEXT_FRAME_ID (v) = VALUE_NEXT_FRAME_ID (array); set_value_offset (v, value_offset (array) + elt_offs); return v; } diff --git a/gdb/valops.c b/gdb/valops.c index 40392e8..8a45641 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -1112,8 +1112,15 @@ value_assign (struct value *toval, struct value *fromval) struct gdbarch *gdbarch; int value_reg; - /* Figure out which frame this is in currently. */ + /* Figure out which frame this is in currently. + + We use VALUE_FRAME_ID for obtaining the value's frame id instead of + VALUE_NEXT_FRAME_ID due to requiring a frame which may be passed to + put_frame_register_bytes() below. That function will (eventually) + perform the necessary unwind operation by first obtaining the next + frame. */ frame = frame_find_by_id (VALUE_FRAME_ID (toval)); + value_reg = VALUE_REGNUM (toval); if (!frame) @@ -1333,7 +1340,7 @@ address_of_variable (struct symbol *var, const struct block *b) struct frame_info *frame; const char *regname; - frame = frame_find_by_id (VALUE_FRAME_ID (val)); + frame = frame_find_by_id (VALUE_NEXT_FRAME_ID (val)); gdb_assert (frame); regname = gdbarch_register_name (get_frame_arch (frame), @@ -3820,7 +3827,7 @@ value_slice (struct value *array, int lowbound, int length) } set_value_component_location (slice, array); - VALUE_FRAME_ID (slice) = VALUE_FRAME_ID (array); + VALUE_NEXT_FRAME_ID (slice) = VALUE_NEXT_FRAME_ID (array); set_value_offset (slice, value_offset (array) + offset); } diff --git a/gdb/value.c b/gdb/value.c index 62c5e37..0575a55 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -262,9 +262,11 @@ struct value bitfields. */ struct value *parent; - /* Frame register value is relative to. This will be described in - the lval enum above as "lval_register". */ - struct frame_id frame_id; + /* Frame ID of "next" frame to which a register value is relative. A + register value is indicated when the lval enum (above) is set to + lval_register. So, if the register value is found relative to frame F, + then the frame id of F->next will be stored in next_frame_id. */ + struct frame_id next_frame_id; /* Type of the value. */ struct type *type; @@ -943,7 +945,7 @@ allocate_value_lazy (struct type *type) val->enclosing_type = type; VALUE_LVAL (val) = not_lval; val->location.address = 0; - VALUE_FRAME_ID (val) = null_frame_id; + VALUE_NEXT_FRAME_ID (val) = null_frame_id; val->offset = 0; val->bitpos = 0; val->bitsize = 0; @@ -1582,9 +1584,9 @@ deprecated_value_internalvar_hack (struct value *value) } struct frame_id * -deprecated_value_frame_id_hack (struct value *value) +deprecated_value_next_frame_id_hack (struct value *value) { - return &value->frame_id; + return &value->next_frame_id; } short * @@ -1786,7 +1788,7 @@ value_copy (struct value *arg) val->offset = arg->offset; val->bitpos = arg->bitpos; val->bitsize = arg->bitsize; - VALUE_FRAME_ID (val) = VALUE_FRAME_ID (arg); + VALUE_NEXT_FRAME_ID (val) = VALUE_NEXT_FRAME_ID (arg); VALUE_REGNUM (val) = VALUE_REGNUM (arg); val->lazy = arg->lazy; val->embedded_offset = value_embedded_offset (arg); @@ -3228,7 +3230,7 @@ value_primitive_field (struct value *arg1, LONGEST offset, } set_value_component_location (v, arg1); VALUE_REGNUM (v) = VALUE_REGNUM (arg1); - VALUE_FRAME_ID (v) = VALUE_FRAME_ID (arg1); + VALUE_NEXT_FRAME_ID (v) = VALUE_NEXT_FRAME_ID (arg1); return v; } @@ -3974,7 +3976,7 @@ value_fetch_lazy (struct value *val) } else if (VALUE_LVAL (val) == lval_register) { - struct frame_info *frame; + struct frame_info *next_frame; int regnum; struct type *type = check_typedef (value_type (val)); struct value *new_val = val, *mark = value_mark (); @@ -3985,27 +3987,33 @@ value_fetch_lazy (struct value *val) while (VALUE_LVAL (new_val) == lval_register && value_lazy (new_val)) { - struct frame_id frame_id = VALUE_FRAME_ID (new_val); + struct frame_id next_frame_id = VALUE_NEXT_FRAME_ID (new_val); - frame = frame_find_by_id (frame_id); + next_frame = frame_find_by_id (next_frame_id); regnum = VALUE_REGNUM (new_val); - gdb_assert (frame != NULL); + gdb_assert (next_frame != NULL); /* Convertible register routines are used for multi-register values and for interpretation in different types (e.g. float or int from a double register). Lazy register values should have the register's natural type, so they do not apply. */ - gdb_assert (!gdbarch_convert_register_p (get_frame_arch (frame), + gdb_assert (!gdbarch_convert_register_p (get_frame_arch (next_frame), regnum, type)); - new_val = get_frame_register_value (frame, regnum); + /* FRAME was obtained, above, via VALUE_NEXT_FRAME_ID. + Since a "->next" operation was performed when setting + this field, we do not need to perform a "next" operation + again when unwinding the register. That's why + frame_unwind_register_value() is called here instead of + get_frame_register_value(). */ + new_val = frame_unwind_register_value (next_frame, regnum); /* If we get another lazy lval_register value, it means the - register is found by reading it from the next frame. - get_frame_register_value should never return a value with - the frame id pointing to FRAME. If it does, it means we + register is found by reading it from NEXT_FRAME's next frame. + frame_unwind_register_value should never return a value with + the frame id pointing to NEXT_FRAME. If it does, it means we either have two consecutive frames with the same frame id in the frame chain, or some code is trying to unwind behind get_prev_frame's back (e.g., a frame unwind @@ -4014,7 +4022,7 @@ value_fetch_lazy (struct value *val) in this situation. */ if (VALUE_LVAL (new_val) == lval_register && value_lazy (new_val) - && frame_id_eq (VALUE_FRAME_ID (new_val), frame_id)) + && frame_id_eq (VALUE_NEXT_FRAME_ID (new_val), next_frame_id)) internal_error (__FILE__, __LINE__, _("infinite loop while fetching a register")); } @@ -4034,6 +4042,9 @@ value_fetch_lazy (struct value *val) if (frame_debug) { struct gdbarch *gdbarch; + struct frame_info *frame; + /* VALUE_FRAME_ID is used here, instead of VALUE_NEXT_FRAME_ID, + so that the frame level will be shown correctly. */ frame = frame_find_by_id (VALUE_FRAME_ID (val)); regnum = VALUE_REGNUM (val); gdbarch = get_frame_arch (frame); diff --git a/gdb/value.h b/gdb/value.h index f962508..afcbcae 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -434,10 +434,18 @@ extern void set_value_address (struct value *, CORE_ADDR); extern struct internalvar **deprecated_value_internalvar_hack (struct value *); #define VALUE_INTERNALVAR(val) (*deprecated_value_internalvar_hack (val)) -/* Frame register value is relative to. This will be described in the - lval enum above as "lval_register". */ -extern struct frame_id *deprecated_value_frame_id_hack (struct value *); -#define VALUE_FRAME_ID(val) (*deprecated_value_frame_id_hack (val)) +/* Frame ID of "next" frame to which a register value is relative. A + register value is indicated by VALUE_LVAL being set to lval_register. + So, if the register value is found relative to frame F, then the + frame id of F->next will be stored in VALUE_NEXT_FRAME_ID. */ +extern struct frame_id *deprecated_value_next_frame_id_hack (struct value *); +#define VALUE_NEXT_FRAME_ID(val) (*deprecated_value_next_frame_id_hack (val)) + +/* Frame ID of frame to which a register value is relative. This is + similar to VALUE_NEXT_FRAME_ID, above, but may not be assigned to. + Note that VALUE_FRAME_ID effectively undoes the "next" operation + that was performed during the assignment to VALUE_NEXT_FRAME_ID. */ +#define VALUE_FRAME_ID(val) (get_prev_frame_id_by_id (VALUE_NEXT_FRAME_ID (val))) /* Register number if the value is from a register. */ extern short *deprecated_value_regnum_hack (struct value *); |