From a6f97d361938de8ac8b9797473494d36f0cca58d Mon Sep 17 00:00:00 2001 From: cagney Date: Tue, 5 Nov 2002 21:44:04 +0000 Subject: [PATCH] 2002-11-05 Andrew Cagney * gdbarch.sh (GET_SAVED_REGISTER): Change to a predicate function. * gdbarch.h, gdbarch.c: Regnerate. * frame.h (frame_register): Declare. * frame.c (frame_register): New function. (get_saved_register): Test GET_SAVED_REGISTER_P before calling GET_SAVED_REGISTER, otherwize call generic_unwind_get_saved_register. (frame_register_read): Use frame_register instead of get_saved_register. --- gdb/ChangeLog | 12 +++++++++ gdb/frame.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---- gdb/frame.h | 10 ++++++++ gdb/gdbarch.c | 10 ++++++-- gdb/gdbarch.h | 22 ++++++++++++++++- gdb/gdbarch.sh | 2 +- 6 files changed, 125 insertions(+), 9 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index b1e8d19aef..f52cb67ffc 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,15 @@ +2002-11-05 Andrew Cagney + + * gdbarch.sh (GET_SAVED_REGISTER): Change to a predicate function. + * gdbarch.h, gdbarch.c: Regnerate. + * frame.h (frame_register): Declare. + * frame.c (frame_register): New function. + (get_saved_register): Test GET_SAVED_REGISTER_P before calling + GET_SAVED_REGISTER, otherwize call + generic_unwind_get_saved_register. + (frame_register_read): Use frame_register instead of + get_saved_register. + 2002-11-05 Elena Zannoni * event-loop.c (start_event_loop): Add comment. diff --git a/gdb/frame.c b/gdb/frame.c index d7d7f0a302..096619156f 100644 --- a/gdb/frame.c +++ b/gdb/frame.c @@ -125,6 +125,66 @@ frame_register_unwind (struct frame_info *frame, int regnum, } void +frame_register (struct frame_info *frame, int regnum, + int *optimizedp, enum lval_type *lvalp, + CORE_ADDR *addrp, int *realnump, void *bufferp) +{ + /* Require all but BUFFERP to be valid. A NULL BUFFERP indicates + that the value proper does not need to be fetched. */ + gdb_assert (optimizedp != NULL); + gdb_assert (lvalp != NULL); + gdb_assert (addrp != NULL); + gdb_assert (realnump != NULL); + /* gdb_assert (bufferp != NULL); */ + + /* Ulgh! Old code that, for lval_register, sets ADDRP to the offset + of the register in the register cache. It should instead return + the REGNUM corresponding to that register. Translate the . */ + if (GET_SAVED_REGISTER_P ()) + { + GET_SAVED_REGISTER (bufferp, optimizedp, addrp, frame, regnum, lvalp); + /* Compute the REALNUM if the caller wants it. */ + if (*lvalp == lval_register) + { + int regnum; + for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++) + { + if (*addrp == register_offset_hack (current_gdbarch, regnum)) + { + *realnump = regnum; + return; + } + } + internal_error (__FILE__, __LINE__, + "Failed to compute the register number corresponding" + " to 0x%s", paddr_d (*addrp)); + } + *realnump = -1; + return; + } + + /* Reached the the bottom (youngest, inner most) of the frame chain + (youngest, inner most) frame, go direct to the hardware register + cache (do not pass go, do not try to cache the value, ...). The + unwound value would have been cached in frame->next but that + doesn't exist. This doesn't matter as the hardware register + cache is stopping any unnecessary accesses to the target. */ + + /* NOTE: cagney/2002-04-14: It would be nice if, instead of a + special case, there was always an inner frame dedicated to the + hardware registers. Unfortunatly, there is too much unwind code + around that looks up/down the frame chain while making the + assumption that each frame level is using the same unwind code. */ + + if (frame == NULL) + frame_register_unwind (NULL, regnum, optimizedp, lvalp, addrp, realnump, + bufferp); + else + frame_register_unwind (frame->next, regnum, optimizedp, lvalp, addrp, + realnump, bufferp); +} + +void frame_unwind_signed_register (struct frame_info *frame, int regnum, LONGEST *val) { @@ -240,7 +300,13 @@ get_saved_register (char *raw_buffer, int regnum, enum lval_type *lval) { - GET_SAVED_REGISTER (raw_buffer, optimized, addrp, frame, regnum, lval); + if (GET_SAVED_REGISTER_P ()) + { + GET_SAVED_REGISTER (raw_buffer, optimized, addrp, frame, regnum, lval); + return; + } + generic_unwind_get_saved_register (raw_buffer, optimized, addrp, frame, + regnum, lval); } /* frame_register_read () @@ -253,9 +319,11 @@ get_saved_register (char *raw_buffer, int frame_register_read (struct frame_info *frame, int regnum, void *myaddr) { - int optim; - get_saved_register (myaddr, &optim, (CORE_ADDR *) NULL, frame, - regnum, (enum lval_type *) NULL); + int optimized; + enum lval_type lval; + CORE_ADDR addr; + int realnum; + frame_register (frame, regnum, &optimized, &lval, &addr, &realnum, myaddr); /* FIXME: cagney/2002-05-15: This test, is just bogus. @@ -267,7 +335,7 @@ frame_register_read (struct frame_info *frame, int regnum, void *myaddr) if (register_cached (regnum) < 0) return 0; /* register value not available */ - return !optim; + return !optimized; } diff --git a/gdb/frame.h b/gdb/frame.h index 89a148e10c..8fd9244458 100644 --- a/gdb/frame.h +++ b/gdb/frame.h @@ -350,6 +350,16 @@ extern void frame_register_unwind (struct frame_info *frame, int regnum, CORE_ADDR *addrp, int *realnump, void *valuep); +/* Return the value of the register in this FRAME. Convenience + function that is equivalent to frame_register_unwind + (get_next_frame (FRAME), ...). If VALUEP is NULL, don't + fetch/compute the value. */ + +extern void frame_register (struct frame_info *frame, int regnum, + int *optimizedp, enum lval_type *lvalp, + CORE_ADDR *addrp, int *realnump, + void *valuep); + /* Unwind FRAME so that the value of register REGNUM, in the previous frame is returned. Simplified versions of frame_register_unwind. */ /* NOTE: cagney/2002-09-13: Return void as one day these functions may diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index eaa7c47b25..468726d63f 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -534,7 +534,6 @@ gdbarch_alloc (const struct gdbarch_info *info, current_gdbarch->init_frame_pc_first = init_frame_pc_noop; current_gdbarch->init_frame_pc = init_frame_pc_default; current_gdbarch->coerce_float_to_double = default_coerce_float_to_double; - current_gdbarch->get_saved_register = generic_unwind_get_saved_register; current_gdbarch->register_convertible = generic_register_convertible_not; current_gdbarch->convert_register_p = legacy_convert_register_p; current_gdbarch->register_to_value = legacy_register_to_value; @@ -718,7 +717,7 @@ verify_gdbarch (struct gdbarch *gdbarch) /* Skip verify of init_frame_pc_first, invalid_p == 0 */ /* Skip verify of init_frame_pc, invalid_p == 0 */ /* Skip verify of coerce_float_to_double, invalid_p == 0 */ - /* Skip verify of get_saved_register, invalid_p == 0 */ + /* Skip verify of get_saved_register, has predicate */ /* Skip verify of register_convertible, invalid_p == 0 */ /* Skip verify of register_convert_to_virtual, invalid_p == 0 */ /* Skip verify of register_convert_to_raw, invalid_p == 0 */ @@ -3678,6 +3677,13 @@ set_gdbarch_coerce_float_to_double (struct gdbarch *gdbarch, gdbarch->coerce_float_to_double = coerce_float_to_double; } +int +gdbarch_get_saved_register_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->get_saved_register != 0; +} + void gdbarch_get_saved_register (struct gdbarch *gdbarch, char *raw_buffer, int *optimized, CORE_ADDR *addrp, struct frame_info *frame, int regnum, enum lval_type *lval) { diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index 3add874d33..a2fa46532c 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -1210,9 +1210,29 @@ extern void set_gdbarch_coerce_float_to_double (struct gdbarch *gdbarch, gdbarch #endif #endif +#if defined (GET_SAVED_REGISTER) +/* Legacy for systems yet to multi-arch GET_SAVED_REGISTER */ +#if !defined (GET_SAVED_REGISTER_P) +#define GET_SAVED_REGISTER_P() (1) +#endif +#endif + +/* Default predicate for non- multi-arch targets. */ +#if (!GDB_MULTI_ARCH) && !defined (GET_SAVED_REGISTER_P) +#define GET_SAVED_REGISTER_P() (0) +#endif + +extern int gdbarch_get_saved_register_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (GET_SAVED_REGISTER_P) +#error "Non multi-arch definition of GET_SAVED_REGISTER" +#endif +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (GET_SAVED_REGISTER_P) +#define GET_SAVED_REGISTER_P() (gdbarch_get_saved_register_p (current_gdbarch)) +#endif + /* Default (function) for non- multi-arch platforms. */ #if (!GDB_MULTI_ARCH) && !defined (GET_SAVED_REGISTER) -#define GET_SAVED_REGISTER(raw_buffer, optimized, addrp, frame, regnum, lval) (generic_unwind_get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval)) +#define GET_SAVED_REGISTER(raw_buffer, optimized, addrp, frame, regnum, lval) (internal_error (__FILE__, __LINE__, "GET_SAVED_REGISTER"), 0) #endif typedef void (gdbarch_get_saved_register_ftype) (char *raw_buffer, int *optimized, CORE_ADDR *addrp, struct frame_info *frame, int regnum, enum lval_type *lval); diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh index 4ed80c3572..f7f9a661d8 100755 --- a/gdb/gdbarch.sh +++ b/gdb/gdbarch.sh @@ -508,7 +508,7 @@ f:2:INIT_FRAME_PC:void:init_frame_pc:int fromleaf, struct frame_info *prev:froml v:2:BELIEVE_PCC_PROMOTION:int:believe_pcc_promotion::::::: v:2:BELIEVE_PCC_PROMOTION_TYPE:int:believe_pcc_promotion_type::::::: f:2:COERCE_FLOAT_TO_DOUBLE:int:coerce_float_to_double:struct type *formal, struct type *actual:formal, actual:::default_coerce_float_to_double::0 -f:2:GET_SAVED_REGISTER:void:get_saved_register:char *raw_buffer, int *optimized, CORE_ADDR *addrp, struct frame_info *frame, int regnum, enum lval_type *lval:raw_buffer, optimized, addrp, frame, regnum, lval:::generic_unwind_get_saved_register::0 +F:2:GET_SAVED_REGISTER:void:get_saved_register:char *raw_buffer, int *optimized, CORE_ADDR *addrp, struct frame_info *frame, int regnum, enum lval_type *lval:raw_buffer, optimized, addrp, frame, regnum, lval # f:2:REGISTER_CONVERTIBLE:int:register_convertible:int nr:nr:::generic_register_convertible_not::0 f:2:REGISTER_CONVERT_TO_VIRTUAL:void:register_convert_to_virtual:int regnum, struct type *type, char *from, char *to:regnum, type, from, to:::0::0 -- 2.11.0