Tue Nov 17 11:17:06 1992 Ian Lance Taylor (ian@cygnus.com)
* tm-rs6000.h (BELIEVE_PCC_PROMOTION): Define, since AIX cc gets it right. (aix_framedata): added nosavedpc field. (SAVED_PC_AFTER_CALL): Don't try to optimize; just call read_register. (FRAMELESS_FUNCTION_INVOCATION): Pass second argument of 0. (FRAME_SAVED_PC): If PC not saved, use SAVED_PC_AFTER_CALL. * rs6000-tdep.c (skip_prologue): Handle gcc generated stfd instructions as function_frame_info does. Expand special case of st r31,-4(r1) to be st r31,NUM(r1), since gcc can generate offsets other than -4. (pop_frame): Add 4 rather than sizeof (int) to avoid host dependence. (function_frame_info): Set frameless if the function has no frame, and set nosavedpc if the PC was not saved. Handle gcc generated stfd 31,-4(31); st 31, -12(31) correctly. (frameless_function_invocation): New second argument pcsaved; if 0 return whether the function has a frame, if 1 return whether the function saved PC. (frame_initial_stack_address): Correct typo: cache registers for callee_fi, not for fi, (avoids reading garbage memory locations).
This commit is contained in:
parent
070ee184f7
commit
cdb1cc9214
3 changed files with 88 additions and 29 deletions
|
@ -1,5 +1,34 @@
|
||||||
|
Tue Nov 17 11:17:06 1992 Ian Lance Taylor (ian@cygnus.com)
|
||||||
|
|
||||||
|
* tm-rs6000.h (BELIEVE_PCC_PROMOTION): Define, since AIX cc gets
|
||||||
|
it right.
|
||||||
|
(aix_framedata): added nosavedpc field.
|
||||||
|
(SAVED_PC_AFTER_CALL): Don't try to optimize; just call
|
||||||
|
read_register.
|
||||||
|
(FRAMELESS_FUNCTION_INVOCATION): Pass second argument of 0.
|
||||||
|
(FRAME_SAVED_PC): If PC not saved, use SAVED_PC_AFTER_CALL.
|
||||||
|
* rs6000-tdep.c (skip_prologue): Handle gcc generated stfd
|
||||||
|
instructions as function_frame_info does. Expand special case of
|
||||||
|
st r31,-4(r1) to be st r31,NUM(r1), since gcc can generate offsets
|
||||||
|
other than -4.
|
||||||
|
(pop_frame): Add 4 rather than sizeof (int) to avoid host
|
||||||
|
dependence.
|
||||||
|
(function_frame_info): Set frameless if the function has no frame,
|
||||||
|
and set nosavedpc if the PC was not saved. Handle gcc generated
|
||||||
|
stfd 31,-4(31); st 31, -12(31) correctly.
|
||||||
|
(frameless_function_invocation): New second argument pcsaved; if 0
|
||||||
|
return whether the function has a frame, if 1 return whether the
|
||||||
|
function saved PC.
|
||||||
|
(frame_initial_stack_address): Correct typo: cache registers for
|
||||||
|
callee_fi, not for fi, (avoids reading garbage memory locations).
|
||||||
|
|
||||||
Mon Nov 16 15:58:07 1992 Stu Grossman (grossman at cygnus.com)
|
Mon Nov 16 15:58:07 1992 Stu Grossman (grossman at cygnus.com)
|
||||||
|
|
||||||
|
* infrun.c (wait_for_inferior (just before step_over_function
|
||||||
|
label)): Change test for stepping into subroutine to check for the
|
||||||
|
presence of line number info. This makes stuff compiled with -g1
|
||||||
|
cause GDB to not lose control when stepping.
|
||||||
|
|
||||||
* symtab.c (find_pc_line): Improve code per gnu's suggestions.
|
* symtab.c (find_pc_line): Improve code per gnu's suggestions.
|
||||||
Improve comments as well.
|
Improve comments as well.
|
||||||
|
|
||||||
|
|
|
@ -210,6 +210,11 @@ CORE_ADDR pc;
|
||||||
return pc - 4; /* don't skip over this branch */
|
return pc - 4; /* don't skip over this branch */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((op & 0xfc1f0000) == 0xd8010000) { /* stfd Rx,NUM(r1) */
|
||||||
|
pc += 4; /* store floating register double */
|
||||||
|
op = read_memory_integer (pc, 4);
|
||||||
|
}
|
||||||
|
|
||||||
if ((op & 0xfc1f0000) == 0xbc010000) { /* stm Rx, NUM(r1) */
|
if ((op & 0xfc1f0000) == 0xbc010000) { /* stm Rx, NUM(r1) */
|
||||||
pc += 4;
|
pc += 4;
|
||||||
op = read_memory_integer (pc, 4);
|
op = read_memory_integer (pc, 4);
|
||||||
|
@ -217,7 +222,7 @@ CORE_ADDR pc;
|
||||||
|
|
||||||
while (((tmp = op >> 16) == 0x9001) || /* st r0, NUM(r1) */
|
while (((tmp = op >> 16) == 0x9001) || /* st r0, NUM(r1) */
|
||||||
(tmp == 0x9421) || /* stu r1, NUM(r1) */
|
(tmp == 0x9421) || /* stu r1, NUM(r1) */
|
||||||
(op == 0x93e1fffc)) /* st r31,-4(r1) */
|
(tmp == 0x93e1)) /* st r31,NUM(r1) */
|
||||||
{
|
{
|
||||||
pc += 4;
|
pc += 4;
|
||||||
op = read_memory_integer (pc, 4);
|
op = read_memory_integer (pc, 4);
|
||||||
|
@ -476,7 +481,7 @@ pop_frame ()
|
||||||
if (fdata.saved_gpr != -1)
|
if (fdata.saved_gpr != -1)
|
||||||
for (ii=fdata.saved_gpr; ii <= 31; ++ii) {
|
for (ii=fdata.saved_gpr; ii <= 31; ++ii) {
|
||||||
read_memory (addr, ®isters [REGISTER_BYTE (ii)], 4);
|
read_memory (addr, ®isters [REGISTER_BYTE (ii)], 4);
|
||||||
addr += sizeof (int);
|
addr += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fdata.saved_fpr != -1)
|
if (fdata.saved_fpr != -1)
|
||||||
|
@ -533,7 +538,8 @@ fix_call_dummy(dummyname, pc, fun, nargs, type)
|
||||||
|
|
||||||
/* return information about a function frame.
|
/* return information about a function frame.
|
||||||
in struct aix_frameinfo fdata:
|
in struct aix_frameinfo fdata:
|
||||||
- frameless is TRUE, if function does not save %pc value in its frame.
|
- frameless is TRUE, if function does not have a frame.
|
||||||
|
- nosavedpc is TRUE, if function does not save %pc value in its frame.
|
||||||
- offset is the number of bytes used in the frame to save registers.
|
- offset is the number of bytes used in the frame to save registers.
|
||||||
- saved_gpr is the number of the first saved gpr.
|
- saved_gpr is the number of the first saved gpr.
|
||||||
- saved_fpr is the number of the first saved fpr.
|
- saved_fpr is the number of the first saved fpr.
|
||||||
|
@ -550,20 +556,22 @@ function_frame_info (pc, fdata)
|
||||||
|
|
||||||
fdata->offset = 0;
|
fdata->offset = 0;
|
||||||
fdata->saved_gpr = fdata->saved_fpr = fdata->alloca_reg = -1;
|
fdata->saved_gpr = fdata->saved_fpr = fdata->alloca_reg = -1;
|
||||||
|
fdata->frameless = 1;
|
||||||
|
|
||||||
op = read_memory_integer (pc, 4);
|
op = read_memory_integer (pc, 4);
|
||||||
if (op == 0x7c0802a6) { /* mflr r0 */
|
if (op == 0x7c0802a6) { /* mflr r0 */
|
||||||
pc += 4;
|
pc += 4;
|
||||||
op = read_memory_integer (pc, 4);
|
op = read_memory_integer (pc, 4);
|
||||||
|
fdata->nosavedpc = 0;
|
||||||
fdata->frameless = 0;
|
fdata->frameless = 0;
|
||||||
}
|
}
|
||||||
else /* else, this is a frameless invocation */
|
else /* else, pc is not saved */
|
||||||
fdata->frameless = 1;
|
fdata->nosavedpc = 1;
|
||||||
|
|
||||||
|
|
||||||
if ((op & 0xfc00003e) == 0x7c000026) { /* mfcr Rx */
|
if ((op & 0xfc00003e) == 0x7c000026) { /* mfcr Rx */
|
||||||
pc += 4;
|
pc += 4;
|
||||||
op = read_memory_integer (pc, 4);
|
op = read_memory_integer (pc, 4);
|
||||||
|
fdata->frameless = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((op & 0xfc000000) == 0x48000000) { /* bl foo, to save fprs??? */
|
if ((op & 0xfc000000) == 0x48000000) { /* bl foo, to save fprs??? */
|
||||||
|
@ -577,11 +585,13 @@ function_frame_info (pc, fdata)
|
||||||
if (op == 0x4def7b82 || /* crorc 15, 15, 15 */
|
if (op == 0x4def7b82 || /* crorc 15, 15, 15 */
|
||||||
op == 0x0)
|
op == 0x0)
|
||||||
return; /* prologue is over */
|
return; /* prologue is over */
|
||||||
|
fdata->frameless = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((op & 0xfc1f0000) == 0xd8010000) { /* stfd Rx,NUM(r1) */
|
if ((op & 0xfc1f0000) == 0xd8010000) { /* stfd Rx,NUM(r1) */
|
||||||
pc += 4; /* store floating register double */
|
pc += 4; /* store floating register double */
|
||||||
op = read_memory_integer (pc, 4);
|
op = read_memory_integer (pc, 4);
|
||||||
|
fdata->frameless = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((op & 0xfc1f0000) == 0xbc010000) { /* stm Rx, NUM(r1) */
|
if ((op & 0xfc1f0000) == 0xbc010000) { /* stm Rx, NUM(r1) */
|
||||||
|
@ -589,7 +599,7 @@ function_frame_info (pc, fdata)
|
||||||
fdata->saved_gpr = (op >> 21) & 0x1f;
|
fdata->saved_gpr = (op >> 21) & 0x1f;
|
||||||
tmp2 = op & 0xffff;
|
tmp2 = op & 0xffff;
|
||||||
if (tmp2 > 0x7fff)
|
if (tmp2 > 0x7fff)
|
||||||
tmp2 = 0xffff0000 | tmp2;
|
tmp2 = (~0 &~ 0xffff) | tmp2;
|
||||||
|
|
||||||
if (tmp2 < 0) {
|
if (tmp2 < 0) {
|
||||||
tmp2 = tmp2 * -1;
|
tmp2 = tmp2 * -1;
|
||||||
|
@ -602,29 +612,43 @@ function_frame_info (pc, fdata)
|
||||||
fdata->offset = tmp2;
|
fdata->offset = tmp2;
|
||||||
pc += 4;
|
pc += 4;
|
||||||
op = read_memory_integer (pc, 4);
|
op = read_memory_integer (pc, 4);
|
||||||
|
fdata->frameless = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (((tmp = op >> 16) == 0x9001) || /* st r0, NUM(r1) */
|
while (((tmp = op >> 16) == 0x9001) || /* st r0, NUM(r1) */
|
||||||
(tmp == 0x9421) || /* stu r1, NUM(r1) */
|
(tmp == 0x9421) || /* stu r1, NUM(r1) */
|
||||||
(op == 0x93e1fffc)) /* st r31,-4(r1) */
|
(tmp == 0x93e1)) /* st r31, NUM(r1) */
|
||||||
{
|
{
|
||||||
|
int tmp2;
|
||||||
|
|
||||||
/* gcc takes a short cut and uses this instruction to save r31 only. */
|
/* gcc takes a short cut and uses this instruction to save r31 only. */
|
||||||
|
|
||||||
if (op == 0x93e1fffc) {
|
if (tmp == 0x93e1) {
|
||||||
if (fdata->offset)
|
if (fdata->offset)
|
||||||
/* fatal ("Unrecognized prolog."); */
|
/* fatal ("Unrecognized prolog."); */
|
||||||
printf ("Unrecognized prolog!\n");
|
printf ("Unrecognized prolog!\n");
|
||||||
|
|
||||||
fdata->saved_gpr = 31;
|
fdata->saved_gpr = 31;
|
||||||
fdata->offset = 4;
|
tmp2 = op & 0xffff;
|
||||||
|
if (tmp2 > 0x7fff) {
|
||||||
|
tmp2 = - ((~0 &~ 0xffff) | tmp2);
|
||||||
|
fdata->saved_fpr = (tmp2 - ((32 - 31) * 4)) / 8;
|
||||||
|
if ( fdata->saved_fpr > 0)
|
||||||
|
fdata->saved_fpr = 32 - fdata->saved_fpr;
|
||||||
|
else
|
||||||
|
fdata->saved_fpr = -1;
|
||||||
|
}
|
||||||
|
fdata->offset = tmp2;
|
||||||
}
|
}
|
||||||
pc += 4;
|
pc += 4;
|
||||||
op = read_memory_integer (pc, 4);
|
op = read_memory_integer (pc, 4);
|
||||||
|
fdata->frameless = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((tmp = (op >> 22)) == 0x20f) { /* l r31, ... or */
|
while ((tmp = (op >> 22)) == 0x20f) { /* l r31, ... or */
|
||||||
pc += 4; /* l r30, ... */
|
pc += 4; /* l r30, ... */
|
||||||
op = read_memory_integer (pc, 4);
|
op = read_memory_integer (pc, 4);
|
||||||
|
fdata->frameless = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* store parameters into stack */
|
/* store parameters into stack */
|
||||||
|
@ -636,10 +660,13 @@ function_frame_info (pc, fdata)
|
||||||
{
|
{
|
||||||
pc += 4; /* store fpr double */
|
pc += 4; /* store fpr double */
|
||||||
op = read_memory_integer (pc, 4);
|
op = read_memory_integer (pc, 4);
|
||||||
|
fdata->frameless = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (op == 0x603f0000) /* oril r31, r1, 0x0 */
|
if (op == 0x603f0000) { /* oril r31, r1, 0x0 */
|
||||||
fdata->alloca_reg = 31;
|
fdata->alloca_reg = 31;
|
||||||
|
fdata->frameless = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -906,11 +933,14 @@ CORE_ADDR pc;
|
||||||
|
|
||||||
|
|
||||||
/* Determines whether the function FI has a frame on the stack or not.
|
/* Determines whether the function FI has a frame on the stack or not.
|
||||||
Called from the FRAMELESS_FUNCTION_INVOCATION macro in tm.h. */
|
Called from the FRAMELESS_FUNCTION_INVOCATION macro in tm.h with a
|
||||||
|
second argument of 0, and from the FRAME_SAVED_PC macro with a
|
||||||
|
second argument of 1. */
|
||||||
|
|
||||||
int
|
int
|
||||||
frameless_function_invocation (fi)
|
frameless_function_invocation (fi, pcsaved)
|
||||||
struct frame_info *fi;
|
struct frame_info *fi;
|
||||||
|
int pcsaved;
|
||||||
{
|
{
|
||||||
CORE_ADDR func_start;
|
CORE_ADDR func_start;
|
||||||
struct aix_framedata fdata;
|
struct aix_framedata fdata;
|
||||||
|
@ -924,7 +954,7 @@ struct frame_info *fi;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
function_frame_info (func_start, &fdata);
|
function_frame_info (func_start, &fdata);
|
||||||
return fdata.frameless;
|
return pcsaved ? fdata.nosavedpc : fdata.frameless;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1026,7 +1056,7 @@ frame_initial_stack_address (fi)
|
||||||
for (callee_fi = fi->next; callee_fi; callee_fi = callee_fi->next) {
|
for (callee_fi = fi->next; callee_fi; callee_fi = callee_fi->next) {
|
||||||
|
|
||||||
if (!callee_fi->cache_fsr)
|
if (!callee_fi->cache_fsr)
|
||||||
frame_get_cache_fsr (fi, NULL);
|
frame_get_cache_fsr (callee_fi, NULL);
|
||||||
|
|
||||||
/* this is the address in which alloca register is saved. */
|
/* this is the address in which alloca register is saved. */
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,9 @@ extern int symtab_relocated;
|
||||||
|
|
||||||
#define PC_LOAD_SEGMENT(PC) pc_load_segment_name(PC)
|
#define PC_LOAD_SEGMENT(PC) pc_load_segment_name(PC)
|
||||||
|
|
||||||
|
/* AIX cc seems to get this right. */
|
||||||
|
|
||||||
|
#define BELIEVE_PCC_PROMOTION 1
|
||||||
|
|
||||||
/* Conversion between a register number in stab string to actual register num. */
|
/* Conversion between a register number in stab string to actual register num. */
|
||||||
|
|
||||||
|
@ -82,6 +85,7 @@ struct aix_framedata {
|
||||||
int saved_fpr; /* smallest # of saved fpr */
|
int saved_fpr; /* smallest # of saved fpr */
|
||||||
int alloca_reg; /* alloca register number (frame ptr) */
|
int alloca_reg; /* alloca register number (frame ptr) */
|
||||||
char frameless; /* true if frameless functions. */
|
char frameless; /* true if frameless functions. */
|
||||||
|
char nosavedpc; /* true if pc not saved. */
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -174,13 +178,7 @@ extern int loadinfotextindex;
|
||||||
the new frame is not set up until the new function executes
|
the new frame is not set up until the new function executes
|
||||||
some instructions. */
|
some instructions. */
|
||||||
|
|
||||||
#define SAVED_PC_AFTER_CALL(frame) \
|
#define SAVED_PC_AFTER_CALL(frame) read_register (LR_REGNUM)
|
||||||
(register_valid [LR_REGNUM] ? \
|
|
||||||
(*(int*)®isters[REGISTER_BYTE (LR_REGNUM)]) : \
|
|
||||||
read_register (LR_REGNUM))
|
|
||||||
|
|
||||||
/*#define SAVED_PC_AFTER_CALL(frame) saved_pc_after_call(frame) */
|
|
||||||
|
|
||||||
|
|
||||||
/* Address of end of stack space. */
|
/* Address of end of stack space. */
|
||||||
|
|
||||||
|
@ -423,7 +421,7 @@ extern unsigned int rs6000_struct_return_address;
|
||||||
does not, FRAMELESS is set to 1, else 0. */
|
does not, FRAMELESS is set to 1, else 0. */
|
||||||
|
|
||||||
#define FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) \
|
#define FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) \
|
||||||
FRAMELESS = frameless_function_invocation (FI)
|
FRAMELESS = frameless_function_invocation (FI, 0)
|
||||||
|
|
||||||
/* Functions calling alloca() change the value of the stack pointer. We
|
/* Functions calling alloca() change the value of the stack pointer. We
|
||||||
need to use initial stack pointer (which is saved in r31 by gcc) in
|
need to use initial stack pointer (which is saved in r31 by gcc) in
|
||||||
|
@ -436,17 +434,19 @@ extern unsigned int rs6000_struct_return_address;
|
||||||
CORE_ADDR initial_sp; /* initial stack pointer. */ \
|
CORE_ADDR initial_sp; /* initial stack pointer. */ \
|
||||||
struct frame_saved_regs *cache_fsr; /* saved registers */
|
struct frame_saved_regs *cache_fsr; /* saved registers */
|
||||||
|
|
||||||
/* Frameless function invocation in IBM RS/6000 is half-done. It perfectly
|
/* Frameless function invocation in IBM RS/6000 is sometimes
|
||||||
sets up a new frame, e.g. a new frame (in fact stack) pointer, etc, but it
|
half-done. It perfectly sets up a new frame, e.g. a new frame (in
|
||||||
doesn't save the %pc. In the following, even though it is considered a
|
fact stack) pointer, etc, but it doesn't save the %pc. We call
|
||||||
frameless invocation, we still need to walk one frame up. */
|
frameless_function_invocation to tell us how to get the %pc. */
|
||||||
|
|
||||||
#define INIT_EXTRA_FRAME_INFO(fromleaf, fi) \
|
#define INIT_EXTRA_FRAME_INFO(fromleaf, fi) \
|
||||||
fi->initial_sp = 0; \
|
fi->initial_sp = 0; \
|
||||||
fi->cache_fsr = 0;
|
fi->cache_fsr = 0;
|
||||||
|
|
||||||
#define FRAME_SAVED_PC(FRAME) \
|
#define FRAME_SAVED_PC(FRAME) \
|
||||||
read_memory_integer (read_memory_integer ((FRAME)->frame, 4)+8, 4)
|
(frameless_function_invocation (FRAME, 1) \
|
||||||
|
? SAVED_PC_AFTER_CALL (FRAME) \
|
||||||
|
: read_memory_integer (read_memory_integer ((FRAME)->frame, 4)+8, 4))
|
||||||
|
|
||||||
#define FRAME_ARGS_ADDRESS(FI) \
|
#define FRAME_ARGS_ADDRESS(FI) \
|
||||||
(((struct frame_info*)(FI))->initial_sp ? \
|
(((struct frame_info*)(FI))->initial_sp ? \
|
||||||
|
|
Loading…
Add table
Reference in a new issue