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:
Ian Lance Taylor 1992-11-17 21:46:17 +00:00
parent 070ee184f7
commit cdb1cc9214
3 changed files with 88 additions and 29 deletions

View file

@ -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.

View file

@ -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, &registers [REGISTER_BYTE (ii)], 4); read_memory (addr, &registers [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. */

View file

@ -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*)&registers[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 ? \