diff options
-rw-r--r-- | gdb/ChangeLog | 17 | ||||
-rw-r--r-- | gdb/d10v-tdep.c | 6 | ||||
-rw-r--r-- | gdb/i386-tdep.c | 59 | ||||
-rw-r--r-- | gdb/trad-frame.c | 68 | ||||
-rw-r--r-- | gdb/trad-frame.h | 50 |
5 files changed, 132 insertions, 68 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index d082c45..34d6db0 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,20 @@ +2003-07-01 Andrew Cagney <cagney@redhat.com> + + * trad-frame.h: Update comments, a -1 .addr is reserved. + (trad_frame_value_p, trad_frame_addr_p): Declare. + (trad_frame_reg_p): Declare. + (trad_frame_set_value): Rename trad_frame_register_value. + (trad_frame_set_unknown): Declare. + * trad-frame.c (trad_frame_realreg_p): New function. + (trad_frame_addr_p, trad_frame_value_p): New function. + (trad_frame_set_unknown): New function. + (trad_frame_alloc_saved_regs): Initialize .addr to -1, not zero. + (trad_frame_prev_register): Use trad_frame_realreg_p, + trad_frame_addr_p and trad_frame_value_p. + (trad_frame_set_value): Rename trad_frame_register_value. + * d10v-tdep.c (d10v_frame_unwind_cache): Use trad_frame_addr_p + and trad_frame_set_value. + 2003-06-30 Jim Blandy <jimb@redhat.com> Patch from IBM (authors unspecified, probably Ulrich Weigand and diff --git a/gdb/d10v-tdep.c b/gdb/d10v-tdep.c index d522580..8a6df8e 100644 --- a/gdb/d10v-tdep.c +++ b/gdb/d10v-tdep.c @@ -763,7 +763,7 @@ d10v_frame_unwind_cache (struct frame_info *next_frame, /* Adjust all the saved registers so that they contain addresses and not offsets. */ for (i = 0; i < NUM_REGS - 1; i++) - if (info->saved_regs[i].addr) + if (trad_frame_addr_p (info->saved_regs, i)) { info->saved_regs[i].addr = (info->prev_sp + info->saved_regs[i].addr); } @@ -776,8 +776,8 @@ d10v_frame_unwind_cache (struct frame_info *next_frame, /* The previous frame's SP needed to be computed. Save the computed value. */ - trad_frame_register_value (info->saved_regs, D10V_SP_REGNUM, - d10v_make_daddr (prev_sp)); + trad_frame_set_value (info->saved_regs, D10V_SP_REGNUM, + d10v_make_daddr (prev_sp)); return info; } diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index 3b98180..a639b17 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -41,6 +41,7 @@ #include "symtab.h" #include "target.h" #include "value.h" +#include "trad-frame.h" #include "gdb_assert.h" #include "gdb_string.h" @@ -248,8 +249,10 @@ struct i386_frame_cache CORE_ADDR sp_offset; CORE_ADDR pc; - /* Saved registers. */ - CORE_ADDR saved_regs[I386_NUM_SAVED_REGS]; + /* Saved registers. While trad-frame allocates space for the full + NUM_REGS + NUM_PSEUDOREGS, some of the code below cheats and + allocates space for only I386_NUM_SAVED_REGS. */ + struct trad_frame_saved_reg *saved_regs; CORE_ADDR saved_sp; int pc_in_eax; @@ -260,7 +263,7 @@ struct i386_frame_cache /* Allocate and initialize a frame cache. */ static struct i386_frame_cache * -i386_alloc_frame_cache (void) +i386_alloc_frame_cache (struct frame_info *next_frame) { struct i386_frame_cache *cache; int i; @@ -272,10 +275,7 @@ i386_alloc_frame_cache (void) cache->sp_offset = -4; cache->pc = 0; - /* Saved registers. We initialize these to -1 since zero is a valid - offset (that's where %ebp is supposed to be stored). */ - for (i = 0; i < I386_NUM_SAVED_REGS; i++) - cache->saved_regs[i] = -1; + cache->saved_regs = trad_frame_alloc_saved_regs (next_frame); cache->saved_sp = 0; cache->pc_in_eax = 0; @@ -449,7 +449,7 @@ i386_analyze_frame_setup (CORE_ADDR pc, CORE_ADDR current_pc, { /* Take into account that we've executed the `pushl %ebp' that starts this instruction sequence. */ - cache->saved_regs[I386_EBP_REGNUM] = 0; + cache->saved_regs[I386_EBP_REGNUM].addr = 0; cache->sp_offset += 4; /* If that's all, return now. */ @@ -547,7 +547,7 @@ i386_analyze_register_saves (CORE_ADDR pc, CORE_ADDR current_pc, if (op < 0x50 || op > 0x57) break; - cache->saved_regs[op - 0x50] = offset; + cache->saved_regs[op - 0x50].addr = offset; offset -= 4; pc++; } @@ -609,6 +609,11 @@ i386_skip_prologue (CORE_ADDR start_pc) unsigned char op; int i; + /* Allocate space for the maximum number of saved registers. This + should include all registers mentioned above, and %eip. */ + cache.saved_regs = alloca (I386_NUM_SAVED_REGS + * sizeof (cache.saved_regs[0])); + cache.locals = -1; pc = i386_analyze_prologue (start_pc, 0xffffffff, &cache); if (cache.locals < 0) @@ -690,7 +695,7 @@ i386_frame_cache (struct frame_info *next_frame, void **this_cache) if (*this_cache) return *this_cache; - cache = i386_alloc_frame_cache (); + cache = i386_alloc_frame_cache (next_frame); *this_cache = cache; /* In principle, for normal frames, %ebp holds the frame pointer, @@ -708,7 +713,7 @@ i386_frame_cache (struct frame_info *next_frame, void **this_cache) return cache; /* For normal frames, %eip is stored at 4(%ebp). */ - cache->saved_regs[I386_EIP_REGNUM] = 4; + cache->saved_regs[I386_EIP_REGNUM].addr = 4; cache->pc = frame_func_unwind (next_frame); if (cache->pc != 0) @@ -735,8 +740,9 @@ i386_frame_cache (struct frame_info *next_frame, void **this_cache) /* Adjust all the saved registers such that they contain addresses instead of offsets. */ for (i = 0; i < I386_NUM_SAVED_REGS; i++) - if (cache->saved_regs[i] != -1) - cache->saved_regs[i] += cache->base; + if (cache->saved_regs[i].realnum >= 0 + && cache->saved_regs[i].addr != -1) + cache->saved_regs[i].addr += cache->base; return cache; } @@ -824,23 +830,8 @@ i386_frame_prev_register (struct frame_info *next_frame, void **this_cache, return; } - if (regnum < I386_NUM_SAVED_REGS && cache->saved_regs[regnum] != -1) - { - *optimizedp = 0; - *lvalp = lval_memory; - *addrp = cache->saved_regs[regnum]; - *realnump = -1; - if (valuep) - { - /* Read the value in from memory. */ - read_memory (*addrp, valuep, - register_size (current_gdbarch, regnum)); - } - return; - } - - frame_register_unwind (next_frame, regnum, - optimizedp, lvalp, addrp, realnump, valuep); + trad_frame_prev_register (next_frame, cache->saved_regs, regnum, + optimizedp, lvalp, addrp, realnump, valuep); } static const struct frame_unwind i386_frame_unwind = @@ -870,7 +861,7 @@ i386_sigtramp_frame_cache (struct frame_info *next_frame, void **this_cache) if (*this_cache) return *this_cache; - cache = i386_alloc_frame_cache (); + cache = i386_alloc_frame_cache (next_frame); frame_unwind_register (next_frame, I386_ESP_REGNUM, buf); cache->base = extract_unsigned_integer (buf, 4) - 4; @@ -884,12 +875,12 @@ i386_sigtramp_frame_cache (struct frame_info *next_frame, void **this_cache) for (i = 0; i < tdep->sc_num_regs; i++) if (tdep->sc_reg_offset[i] != -1) - cache->saved_regs[i] = addr + tdep->sc_reg_offset[i]; + cache->saved_regs[i].addr = addr + tdep->sc_reg_offset[i]; } else { - cache->saved_regs[I386_EIP_REGNUM] = addr + tdep->sc_pc_offset; - cache->saved_regs[I386_ESP_REGNUM] = addr + tdep->sc_sp_offset; + cache->saved_regs[I386_EIP_REGNUM].addr = addr + tdep->sc_pc_offset; + cache->saved_regs[I386_ESP_REGNUM].addr = addr + tdep->sc_sp_offset; } *this_cache = cache; diff --git a/gdb/trad-frame.c b/gdb/trad-frame.c index 92e6f83..d73813b 100644 --- a/gdb/trad-frame.c +++ b/gdb/trad-frame.c @@ -38,36 +38,70 @@ trad_frame_alloc_saved_regs (struct frame_info *next_frame) struct trad_frame_saved_reg *this_saved_regs = FRAME_OBSTACK_CALLOC (numregs, struct trad_frame_saved_reg); for (regnum = 0; regnum < numregs; regnum++) - this_saved_regs[regnum].realnum = regnum; + { + this_saved_regs[regnum].realreg = regnum; + this_saved_regs[regnum].addr = -1; + } return this_saved_regs; } +enum { REG_VALUE = -1, REG_UNKNOWN = -2 }; + +int +trad_frame_value_p (struct trad_frame_saved_reg this_saved_regs[], int regnum) +{ + return (this_saved_regs[regnum].realreg == REG_VALUE); +} + +int +trad_frame_addr_p (struct trad_frame_saved_reg this_saved_regs[], int regnum) +{ + return (this_saved_regs[regnum].realreg >= 0 + && this_saved_regs[regnum].addr != -1); +} + +int +trad_frame_realreg_p (struct trad_frame_saved_reg this_saved_regs[], + int regnum) +{ + return (this_saved_regs[regnum].realreg >= 0 + && this_saved_regs[regnum].addr == -1); +} + void -trad_frame_register_value (struct trad_frame_saved_reg this_saved_regs[], - int regnum, LONGEST val) +trad_frame_set_value (struct trad_frame_saved_reg this_saved_regs[], + int regnum, LONGEST val) { - /* Make the REALNUM invalid, indicating that the ADDR contains the + /* Make the REALREG invalid, indicating that the ADDR contains the register's value. */ - this_saved_regs[regnum].realnum = -1; + this_saved_regs[regnum].realreg = REG_VALUE; this_saved_regs[regnum].addr = val; } void +trad_frame_set_unknown (struct trad_frame_saved_reg this_saved_regs[], + int regnum) +{ + /* Make the REALREG invalid, indicating that the value is not known. */ + this_saved_regs[regnum].realreg = REG_UNKNOWN; + this_saved_regs[regnum].addr = -1; +} + +void trad_frame_prev_register (struct frame_info *next_frame, struct trad_frame_saved_reg this_saved_regs[], int regnum, int *optimizedp, enum lval_type *lvalp, CORE_ADDR *addrp, - int *realnump, void *bufferp) + int *realregp, void *bufferp) { struct gdbarch *gdbarch = get_frame_arch (next_frame); - if (this_saved_regs[regnum].realnum >= 0 - && this_saved_regs[regnum].addr != 0) + if (trad_frame_addr_p (this_saved_regs, regnum)) { /* The register was saved in memory. */ *optimizedp = 0; *lvalp = lval_memory; *addrp = this_saved_regs[regnum].addr; - *realnump = -1; + *realregp = -1; if (bufferp != NULL) { /* Read the value in from memory. */ @@ -75,22 +109,26 @@ trad_frame_prev_register (struct frame_info *next_frame, register_size (gdbarch, regnum)); } } - else if (this_saved_regs[regnum].realnum >= 0 - && this_saved_regs[regnum].addr == 0) + else if (trad_frame_realreg_p (this_saved_regs, regnum)) { /* As the next frame to return the value of the register. */ - frame_register_unwind (next_frame, this_saved_regs[regnum].realnum, - optimizedp, lvalp, addrp, realnump, bufferp); + frame_register_unwind (next_frame, this_saved_regs[regnum].realreg, + optimizedp, lvalp, addrp, realregp, bufferp); } - else + else if (trad_frame_value_p (this_saved_regs, regnum)) { /* The register's value is available. */ *optimizedp = 0; *lvalp = not_lval; *addrp = 0; - *realnump = -1; + *realregp = -1; if (bufferp != NULL) store_unsigned_integer (bufferp, register_size (gdbarch, regnum), this_saved_regs[regnum].addr); } + else + { + error ("Register %s not available", + gdbarch_register_name (gdbarch, regnum)); + } } diff --git a/gdb/trad-frame.h b/gdb/trad-frame.h index 2b04c7e..55720c7 100644 --- a/gdb/trad-frame.h +++ b/gdb/trad-frame.h @@ -28,33 +28,51 @@ struct frame_info; the value of REGNUM for the previous frame can be found in this frame. - The table is initialized with an identity encoding (ADDR == 0, - REALNUM == REGNUM) indicating that the value of REGNUM in the - previous frame can be found in register REGNUM (== REALNUM) in this + The table is initialized with an identity encoding (ADDR == -1, + REALREG == REGNUM) indicating that the value of REGNUM in the + previous frame can be found in register REGNUM (== REALREG) in this frame. The initial encoding can then be changed: - Modify ADDR (REALNUM >= 0, ADDR != 0) to indicate that the value of - register REGNUM in the previous frame can be found in memory at - ADDR in this frame. + Modify ADDR (REALREG >= 0, ADDR != -1) to indicate that the value + of register REGNUM in the previous frame can be found in memory at + ADDR in this frame (addr_p, !realreg_p, !value_p). - Modify REALNUM (REALNUM >= 0, ADDR == 0) to indicate that the value - of register REGNUM in the previous frame is found in register - REALNUM in this frame. + Modify REALREG (REALREG >= 0, ADDR == -1) to indicate that the + value of register REGNUM in the previous frame is found in register + REALREG in this frame (!addr_p, realreg_p, !value_p). - Call trad_frame_register_value (REALNUM < 0) to indicate that the - value of register REGNUM in the previous frame is found in ADDR. */ + Call trad_frame_set_value (REALREG == -1) to indicate that the + value of register REGNUM in the previous frame is found in ADDR + (!addr_p, !realreg_p, value_p). + + Call trad_frame_set_unknown (REALREG == -2) to indicate that the + register's value is not known. */ struct trad_frame_saved_reg { LONGEST addr; /* A CORE_ADDR fits in a longest. */ - int realnum; + int realreg; }; -/* Convenience function, encode REGNUM's location in the trad-frame. */ -void trad_frame_register_value (struct trad_frame_saved_reg this_saved_regs[], - int regnum, LONGEST val); +/* Encode REGNUM value in the trad-frame. */ +void trad_frame_set_value (struct trad_frame_saved_reg this_saved_regs[], + int regnum, LONGEST val); + +/* Mark REGNUM as unknown. */ +void trad_frame_set_unknown (struct trad_frame_saved_reg this_saved_regs[], + int regnum); + +/* Convenience functions, return non-zero if the register has been + encoded as specified. */ +int trad_frame_value_p (struct trad_frame_saved_reg this_saved_regs[], + int regnum); +int trad_frame_addr_p (struct trad_frame_saved_reg this_saved_regs[], + int regnum); +int trad_frame_realreg_p (struct trad_frame_saved_reg this_saved_regs[], + int regnum); + /* Return a freshly allocated (and initialized) trad_frame array. */ struct trad_frame_saved_reg *trad_frame_alloc_saved_regs (struct frame_info *next_frame); @@ -65,6 +83,6 @@ void trad_frame_prev_register (struct frame_info *next_frame, struct trad_frame_saved_reg this_saved_regs[], int regnum, int *optimizedp, enum lval_type *lvalp, CORE_ADDR *addrp, - int *realnump, void *bufferp); + int *realregp, void *bufferp); #endif |