* config/m88k/tm-m88k.h: Fix typo in comment.
(FP_REGNUM): define in terms of SP_REGNUM rather than by absolute number. Also clearly comment that this is a convenient lie in order to decrease future confusion. (ACTUAL_FP_REGNUM): new macro for FP. (FRAME_CHAIN_VALID): removed. Standard default works fine. * m88k-tdep.c (frame_chain_valid): redundant, so removed. (NEXT_PROLOGUE_INSN): removed unused fourth arg, fixed all callers. (read_next_frame_reg): declare static. (examine_prologue): removed unused variabel insn2, rename insn1 to insn, rewrote comment about finding fp, sp, etc. set frame_fp based on ACTUAL_FP_REGNUM rather than FP_REGNUM which is actually a scammed alias for SP_REGNUM on m88k.
This commit is contained in:
parent
2f03f9a6c6
commit
637603f9e3
3 changed files with 71 additions and 52 deletions
|
@ -1,5 +1,20 @@
|
||||||
Tue Aug 17 15:10:04 1993 K. Richard Pixley (rich@sendai.cygnus.com)
|
Tue Aug 17 15:10:04 1993 K. Richard Pixley (rich@sendai.cygnus.com)
|
||||||
|
|
||||||
|
* config/m88k/tm-m88k.h: Fix typo in comment.
|
||||||
|
(FP_REGNUM): define in terms of SP_REGNUM
|
||||||
|
rather than by absolute number. Also clearly comment that this
|
||||||
|
is a convenient lie in order to decrease future confusion.
|
||||||
|
(ACTUAL_FP_REGNUM): new macro for FP.
|
||||||
|
(FRAME_CHAIN_VALID): removed. Standard default works fine.
|
||||||
|
* m88k-tdep.c (frame_chain_valid): redundant, so removed.
|
||||||
|
(NEXT_PROLOGUE_INSN): removed unused fourth arg, fixed all
|
||||||
|
callers.
|
||||||
|
(read_next_frame_reg): declare static.
|
||||||
|
(examine_prologue): removed unused variabel insn2, rename insn1
|
||||||
|
to insn, rewrote comment about finding fp, sp, etc. set frame_fp
|
||||||
|
based on ACTUAL_FP_REGNUM rather than FP_REGNUM which is
|
||||||
|
actually a scammed alias for SP_REGNUM on m88k.
|
||||||
|
|
||||||
* frame.h: fixed typo in comment.
|
* frame.h: fixed typo in comment.
|
||||||
|
|
||||||
Tue Aug 17 11:14:25 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
|
Tue Aug 17 11:14:25 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
|
||||||
|
|
|
@ -188,7 +188,6 @@ extern CORE_ADDR skip_prologue ();
|
||||||
#define SRP_REGNUM 1 /* Contains subroutine return pointer */
|
#define SRP_REGNUM 1 /* Contains subroutine return pointer */
|
||||||
#define RV_REGNUM 2 /* Contains simple return values */
|
#define RV_REGNUM 2 /* Contains simple return values */
|
||||||
#define SRA_REGNUM 12 /* Contains address of struct return values */
|
#define SRA_REGNUM 12 /* Contains address of struct return values */
|
||||||
#define FP_REGNUM 31 /* Reg fetched to locate frame when pgm stops */
|
|
||||||
#define SP_REGNUM 31 /* Contains address of top of stack */
|
#define SP_REGNUM 31 /* Contains address of top of stack */
|
||||||
#define SXIP_REGNUM 35 /* Contains Shadow Execute Instruction Pointer */
|
#define SXIP_REGNUM 35 /* Contains Shadow Execute Instruction Pointer */
|
||||||
#define SNIP_REGNUM 36 /* Contains Shadow Next Instruction Pointer */
|
#define SNIP_REGNUM 36 /* Contains Shadow Next Instruction Pointer */
|
||||||
|
@ -200,6 +199,15 @@ extern CORE_ADDR skip_prologue ();
|
||||||
#define SFIP_REGNUM 37 /* Contains Shadow Fetched Intruction pointer */
|
#define SFIP_REGNUM 37 /* Contains Shadow Fetched Intruction pointer */
|
||||||
#define NNPC_REGNUM SFIP_REGNUM /* Next Next Program Counter */
|
#define NNPC_REGNUM SFIP_REGNUM /* Next Next Program Counter */
|
||||||
|
|
||||||
|
/* This is rather a confusing lie. Our m88k port using a stack pointer value
|
||||||
|
for the frame address. Hence, the frame address and the frame pointer are
|
||||||
|
only indirectly related. The value of this macro is the register number
|
||||||
|
fetched by the machine "independent" portions of gdb when they want to know
|
||||||
|
about a frame address. Thus, we lie here and claim that FP_REGNUM is
|
||||||
|
SP_REGNUM. */
|
||||||
|
#define FP_REGNUM SP_REGNUM /* Reg fetched to locate frame when pgm stops */
|
||||||
|
#define ACTUAL_FP_REGNUM 30
|
||||||
|
|
||||||
/* PSR status bit definitions. */
|
/* PSR status bit definitions. */
|
||||||
|
|
||||||
#define PSR_MODE 0x80000000
|
#define PSR_MODE 0x80000000
|
||||||
|
@ -317,9 +325,6 @@ extern int frameless_function_invocation ();
|
||||||
#define FRAME_CHAIN(thisframe) \
|
#define FRAME_CHAIN(thisframe) \
|
||||||
frame_chain (thisframe)
|
frame_chain (thisframe)
|
||||||
|
|
||||||
#define FRAME_CHAIN_VALID(chain, thisframe) \
|
|
||||||
frame_chain_valid (chain, thisframe)
|
|
||||||
|
|
||||||
#define FRAMELESS_FUNCTION_INVOCATION(frame, fromleaf) \
|
#define FRAMELESS_FUNCTION_INVOCATION(frame, fromleaf) \
|
||||||
fromleaf = frameless_function_invocation (frame)
|
fromleaf = frameless_function_invocation (frame)
|
||||||
|
|
||||||
|
@ -373,7 +378,7 @@ extern CORE_ADDR frame_locals_address ();
|
||||||
|
|
||||||
We could manage to locate values for all of the so called "preserved"
|
We could manage to locate values for all of the so called "preserved"
|
||||||
registers (some of which may get saved within any particular frame) but
|
registers (some of which may get saved within any particular frame) but
|
||||||
that would require decoding all of the tdesc information. Tht would be
|
that would require decoding all of the tdesc information. That would be
|
||||||
nice information for GDB to have, but it is not strictly manditory if we
|
nice information for GDB to have, but it is not strictly manditory if we
|
||||||
can live without the ability to look at values within (or backup to)
|
can live without the ability to look at values within (or backup to)
|
||||||
previous frames.
|
previous frames.
|
||||||
|
|
|
@ -88,15 +88,6 @@ frameless_function_invocation (frame)
|
||||||
return 1; /* Frameless -- no saved return address */
|
return 1; /* Frameless -- no saved return address */
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
frame_chain_valid (chain, thisframe)
|
|
||||||
CORE_ADDR chain;
|
|
||||||
struct frame_info *thisframe;
|
|
||||||
{
|
|
||||||
return (chain != 0
|
|
||||||
&& !inside_entry_file (FRAME_SAVED_PC (thisframe)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
init_extra_frame_info (fromleaf, fi)
|
init_extra_frame_info (fromleaf, fi)
|
||||||
int fromleaf;
|
int fromleaf;
|
||||||
|
@ -166,7 +157,7 @@ static struct pic_prologue_code pic_prologue_code [] = {
|
||||||
of the instruction. PWORD2 is ignored -- a remnant of the original
|
of the instruction. PWORD2 is ignored -- a remnant of the original
|
||||||
i960 version. */
|
i960 version. */
|
||||||
|
|
||||||
#define NEXT_PROLOGUE_INSN(addr, lim, pword1, pword2) \
|
#define NEXT_PROLOGUE_INSN(addr, lim, pword1) \
|
||||||
(((addr) < (lim)) ? next_insn (addr, pword1) : 0)
|
(((addr) < (lim)) ? next_insn (addr, pword1) : 0)
|
||||||
|
|
||||||
/* Read the m88k instruction at 'memaddr' and return the address of
|
/* Read the m88k instruction at 'memaddr' and return the address of
|
||||||
|
@ -187,7 +178,7 @@ next_insn (memaddr, pword1)
|
||||||
|
|
||||||
/* Read a register from frames called by us (or from the hardware regs). */
|
/* Read a register from frames called by us (or from the hardware regs). */
|
||||||
|
|
||||||
int
|
static int
|
||||||
read_next_frame_reg(fi, regno)
|
read_next_frame_reg(fi, regno)
|
||||||
FRAME fi;
|
FRAME fi;
|
||||||
int regno;
|
int regno;
|
||||||
|
@ -220,7 +211,7 @@ examine_prologue (ip, limit, frame_sp, fsr, fi)
|
||||||
register CORE_ADDR next_ip;
|
register CORE_ADDR next_ip;
|
||||||
register int src;
|
register int src;
|
||||||
register struct pic_prologue_code *pcode;
|
register struct pic_prologue_code *pcode;
|
||||||
unsigned int insn1, insn2;
|
unsigned int insn;
|
||||||
int size, offset;
|
int size, offset;
|
||||||
char must_adjust[32]; /* If set, must adjust offsets in fsr */
|
char must_adjust[32]; /* If set, must adjust offsets in fsr */
|
||||||
int sp_offset = -1; /* -1 means not set (valid must be mult of 8) */
|
int sp_offset = -1; /* -1 means not set (valid must be mult of 8) */
|
||||||
|
@ -228,7 +219,7 @@ examine_prologue (ip, limit, frame_sp, fsr, fi)
|
||||||
CORE_ADDR frame_fp;
|
CORE_ADDR frame_fp;
|
||||||
|
|
||||||
bzero (must_adjust, sizeof (must_adjust));
|
bzero (must_adjust, sizeof (must_adjust));
|
||||||
next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn1, &insn2);
|
next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn);
|
||||||
|
|
||||||
/* Accept move of incoming registers to other registers, using
|
/* Accept move of incoming registers to other registers, using
|
||||||
"or rd,rs,0" or "or.u rd,rs,0" or "or rd,r0,rs" or "or rd,rs,r0".
|
"or rd,rs,0" or "or.u rd,rs,0" or "or rd,r0,rs" or "or rd,rs,r0".
|
||||||
|
@ -243,9 +234,9 @@ examine_prologue (ip, limit, frame_sp, fsr, fi)
|
||||||
#define OR_REG_MOVE2_INSN 0xF4005800 /* or rd,rs,r0 */
|
#define OR_REG_MOVE2_INSN 0xF4005800 /* or rd,rs,r0 */
|
||||||
#define OR_REG_MOVE2_MASK 0xFC00FFFF
|
#define OR_REG_MOVE2_MASK 0xFC00FFFF
|
||||||
while (next_ip &&
|
while (next_ip &&
|
||||||
((insn1 & OR_MOVE_MASK) == OR_MOVE_INSN ||
|
((insn & OR_MOVE_MASK) == OR_MOVE_INSN ||
|
||||||
(insn1 & OR_REG_MOVE1_MASK) == OR_REG_MOVE1_INSN ||
|
(insn & OR_REG_MOVE1_MASK) == OR_REG_MOVE1_INSN ||
|
||||||
(insn1 & OR_REG_MOVE2_MASK) == OR_REG_MOVE2_INSN
|
(insn & OR_REG_MOVE2_MASK) == OR_REG_MOVE2_INSN
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
@ -253,7 +244,7 @@ examine_prologue (ip, limit, frame_sp, fsr, fi)
|
||||||
has already been reflected in what the compiler tells us is the
|
has already been reflected in what the compiler tells us is the
|
||||||
location of these parameters. */
|
location of these parameters. */
|
||||||
ip = next_ip;
|
ip = next_ip;
|
||||||
next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn1, &insn2);
|
next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Accept an optional "subu sp,sp,n" to set up the stack pointer. */
|
/* Accept an optional "subu sp,sp,n" to set up the stack pointer. */
|
||||||
|
@ -262,11 +253,11 @@ examine_prologue (ip, limit, frame_sp, fsr, fi)
|
||||||
#define SUBU_SP_MASK 0xffff0007 /* Note offset must be mult. of 8 */
|
#define SUBU_SP_MASK 0xffff0007 /* Note offset must be mult. of 8 */
|
||||||
#define SUBU_OFFSET(x) ((unsigned)(x & 0xFFFF))
|
#define SUBU_OFFSET(x) ((unsigned)(x & 0xFFFF))
|
||||||
if (next_ip &&
|
if (next_ip &&
|
||||||
((insn1 & SUBU_SP_MASK) == SUBU_SP_INSN)) /* subu r31, r31, N */
|
((insn & SUBU_SP_MASK) == SUBU_SP_INSN)) /* subu r31, r31, N */
|
||||||
{
|
{
|
||||||
sp_offset = -SUBU_OFFSET (insn1);
|
sp_offset = -SUBU_OFFSET (insn);
|
||||||
ip = next_ip;
|
ip = next_ip;
|
||||||
next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn1, &insn2);
|
next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The function must start with a stack-pointer adjustment, or
|
/* The function must start with a stack-pointer adjustment, or
|
||||||
|
@ -291,15 +282,15 @@ examine_prologue (ip, limit, frame_sp, fsr, fi)
|
||||||
|
|
||||||
while (next_ip)
|
while (next_ip)
|
||||||
{
|
{
|
||||||
if ((insn1 & ST_STACK_MASK) == ST_STACK_INSN)
|
if ((insn & ST_STACK_MASK) == ST_STACK_INSN)
|
||||||
size = 1;
|
size = 1;
|
||||||
else if ((insn1 & STD_STACK_MASK) == STD_STACK_INSN)
|
else if ((insn & STD_STACK_MASK) == STD_STACK_INSN)
|
||||||
size = 2;
|
size = 2;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
|
|
||||||
src = ST_SRC (insn1);
|
src = ST_SRC (insn);
|
||||||
offset = ST_OFFSET (insn1);
|
offset = ST_OFFSET (insn);
|
||||||
while (size--)
|
while (size--)
|
||||||
{
|
{
|
||||||
must_adjust[src] = 1;
|
must_adjust[src] = 1;
|
||||||
|
@ -307,7 +298,7 @@ examine_prologue (ip, limit, frame_sp, fsr, fi)
|
||||||
offset += 4;
|
offset += 4;
|
||||||
}
|
}
|
||||||
ip = next_ip;
|
ip = next_ip;
|
||||||
next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn1, &insn2);
|
next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Accept an optional "addu r30,r31,n" to set up the frame pointer. */
|
/* Accept an optional "addu r30,r31,n" to set up the frame pointer. */
|
||||||
|
@ -316,11 +307,11 @@ examine_prologue (ip, limit, frame_sp, fsr, fi)
|
||||||
#define ADDU_FP_MASK 0xffff0000
|
#define ADDU_FP_MASK 0xffff0000
|
||||||
#define ADDU_OFFSET(x) ((unsigned)(x & 0xFFFF))
|
#define ADDU_OFFSET(x) ((unsigned)(x & 0xFFFF))
|
||||||
if (next_ip &&
|
if (next_ip &&
|
||||||
((insn1 & ADDU_FP_MASK) == ADDU_FP_INSN)) /* addu r30, r31, N */
|
((insn & ADDU_FP_MASK) == ADDU_FP_INSN)) /* addu r30, r31, N */
|
||||||
{
|
{
|
||||||
fp_offset = ADDU_OFFSET (insn1);
|
fp_offset = ADDU_OFFSET (insn);
|
||||||
ip = next_ip;
|
ip = next_ip;
|
||||||
next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn1, &insn2);
|
next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Accept the PIC prologue code if present. */
|
/* Accept the PIC prologue code if present. */
|
||||||
|
@ -333,11 +324,11 @@ examine_prologue (ip, limit, frame_sp, fsr, fi)
|
||||||
size-=2;
|
size-=2;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (size-- && next_ip && (pcode->insn == (pcode->mask & insn1)))
|
while (size-- && next_ip && (pcode->insn == (pcode->mask & insn)))
|
||||||
{
|
{
|
||||||
pcode++;
|
pcode++;
|
||||||
ip = next_ip;
|
ip = next_ip;
|
||||||
next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn1, &insn2);
|
next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Accept moves of parameter registers to other registers, using
|
/* Accept moves of parameter registers to other registers, using
|
||||||
|
@ -353,9 +344,9 @@ examine_prologue (ip, limit, frame_sp, fsr, fi)
|
||||||
#define OR_REG_MOVE2_INSN 0xF4005800 /* or rd,rs,r0 */
|
#define OR_REG_MOVE2_INSN 0xF4005800 /* or rd,rs,r0 */
|
||||||
#define OR_REG_MOVE2_MASK 0xFC00FFFF
|
#define OR_REG_MOVE2_MASK 0xFC00FFFF
|
||||||
while (next_ip &&
|
while (next_ip &&
|
||||||
((insn1 & OR_MOVE_MASK) == OR_MOVE_INSN ||
|
((insn & OR_MOVE_MASK) == OR_MOVE_INSN ||
|
||||||
(insn1 & OR_REG_MOVE1_MASK) == OR_REG_MOVE1_INSN ||
|
(insn & OR_REG_MOVE1_MASK) == OR_REG_MOVE1_INSN ||
|
||||||
(insn1 & OR_REG_MOVE2_MASK) == OR_REG_MOVE2_INSN
|
(insn & OR_REG_MOVE2_MASK) == OR_REG_MOVE2_INSN
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
@ -363,7 +354,7 @@ examine_prologue (ip, limit, frame_sp, fsr, fi)
|
||||||
has already been reflected in what the compiler tells us is the
|
has already been reflected in what the compiler tells us is the
|
||||||
location of these parameters. */
|
location of these parameters. */
|
||||||
ip = next_ip;
|
ip = next_ip;
|
||||||
next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn1, &insn2);
|
next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We're done with the prologue. If we don't care about the stack
|
/* We're done with the prologue. If we don't care about the stack
|
||||||
|
@ -373,24 +364,32 @@ examine_prologue (ip, limit, frame_sp, fsr, fi)
|
||||||
if (fi == 0)
|
if (fi == 0)
|
||||||
return ip;
|
return ip;
|
||||||
|
|
||||||
/* OK, now we have:
|
/*
|
||||||
sp_offset original negative displacement of SP
|
OK, now we have:
|
||||||
fp_offset positive displacement between new SP and new FP, or -1
|
|
||||||
fsr->regs[0..31] offset from original SP where reg is stored
|
|
||||||
must_adjust[0..31] set if corresp. offset was set
|
|
||||||
|
|
||||||
The current SP (frame_sp) might not be the original new SP as set
|
sp_offset original (before any alloca calls) displacement of SP
|
||||||
by the function prologue, if alloca has been called. This can
|
(will be negative).
|
||||||
only occur if fp_offset is set, though (the compiler allocates an
|
|
||||||
FP when it sees alloca). In that case, we have the FP,
|
|
||||||
and can calculate the original new SP from the FP.
|
|
||||||
|
|
||||||
Then, we figure out where the arguments and locals are, and
|
fp_offset displacement from original SP to the FP for this frame
|
||||||
relocate the offsets in fsr->regs to absolute addresses. */
|
or -1.
|
||||||
|
|
||||||
|
fsr->regs[0..31] displacement from original SP to the stack
|
||||||
|
location where reg[0..31] is stored.
|
||||||
|
|
||||||
|
must_adjust[0..31] set if corresponding offset was set.
|
||||||
|
|
||||||
|
If alloca has been called between the function prologue and the current
|
||||||
|
IP, then the current SP (frame_sp) will not be the original SP as set by
|
||||||
|
the function prologue. If the current SP is not the original SP, then the
|
||||||
|
compiler will have allocated an FP for this frame, fp_offset will be set,
|
||||||
|
and we can use it to calculate the original SP.
|
||||||
|
|
||||||
|
Then, we figure out where the arguments and locals are, and relocate the
|
||||||
|
offsets in fsr->regs to absolute addresses. */
|
||||||
|
|
||||||
if (fp_offset != -1) {
|
if (fp_offset != -1) {
|
||||||
/* We have a frame pointer, so get it, and base our calc's on it. */
|
/* We have a frame pointer, so get it, and base our calc's on it. */
|
||||||
frame_fp = (CORE_ADDR) read_next_frame_reg (fi->next, FP_REGNUM);
|
frame_fp = (CORE_ADDR) read_next_frame_reg (fi->next, ACTUAL_FP_REGNUM);
|
||||||
frame_sp = frame_fp - fp_offset;
|
frame_sp = frame_fp - fp_offset;
|
||||||
} else {
|
} else {
|
||||||
/* We have no frame pointer, therefore frame_sp is still the same value
|
/* We have no frame pointer, therefore frame_sp is still the same value
|
||||||
|
|
Loading…
Add table
Reference in a new issue