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.
This commit is contained in:
parent
39071cb835
commit
3b3850e852
5 changed files with 133 additions and 69 deletions
|
@ -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
|
||||
|
|
|
@ -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,7 +776,7 @@ 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,
|
||||
trad_frame_set_value (info->saved_regs, D10V_SP_REGNUM,
|
||||
d10v_make_daddr (prev_sp));
|
||||
|
||||
return info;
|
||||
|
|
|
@ -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,22 +830,7 @@ 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,
|
||||
trad_frame_prev_register (next_frame, cache->saved_regs, regnum,
|
||||
optimizedp, lvalp, addrp, realnump, valuep);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
|
|
@ -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[],
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,34 +28,52 @@ 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[],
|
||||
/* 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
|
||||
|
|
Loading…
Reference in a new issue