Index: ChangeLog

2003-08-18  Andrew Cagney  <cagney@redhat.com>

	* gdbarch.sh (FRAME_RED_ZONE_SIZE): New architecture method.
	* gdbarch.h, gdbarch.c: Re-generate.
	* infcall.c (call_function_by_hand): Adjust the SP by
	frame_red_zone_size before allocating any stack space.
	* rs6000-tdep.c (rs6000_gdbarch_init): Set "frame_red_zone_size".
	* x86-64-tdep.c (x86_64_frame_align): New function.
	(x86_64_init_abi): Set "frame_red_zone_size" and "frame_align".

	* x86-64-tdep.c (x86_64_push_arguments): Revert 2003-08-07 change.
	Remove code adjusting SP so that it skips over the Red Zone.

Index: doc/ChangeLog
2003-08-18  Andrew Cagney  <cagney@redhat.com>

	* gdbint.texinfo (Target Architecture Definition): Document
	"frame_red_zone_size".
This commit is contained in:
Andrew Cagney 2003-08-18 20:04:56 +00:00
parent 4091ea4e21
commit 8b148df9ac
9 changed files with 110 additions and 14 deletions

View File

@ -1,3 +1,16 @@
2003-08-18 Andrew Cagney <cagney@redhat.com>
* gdbarch.sh (FRAME_RED_ZONE_SIZE): New architecture method.
* gdbarch.h, gdbarch.c: Re-generate.
* infcall.c (call_function_by_hand): Adjust the SP by
frame_red_zone_size before allocating any stack space.
* rs6000-tdep.c (rs6000_gdbarch_init): Set "frame_red_zone_size".
* x86-64-tdep.c (x86_64_frame_align): New function.
(x86_64_init_abi): Set "frame_red_zone_size" and "frame_align".
* x86-64-tdep.c (x86_64_push_arguments): Revert 2003-08-07 change.
Remove code adjusting SP so that it skips over the Red Zone.
2003-08-18 Mark Kettenis <kettenis@gnu.org>
* NEWS (New native configurations): Mention FreeBSD/amd64.

View File

@ -1,3 +1,8 @@
2003-08-18 Andrew Cagney <cagney@redhat.com>
* gdbint.texinfo (Target Architecture Definition): Document
"frame_red_zone_size".
2003-08-09 Andrew Cagney <cagney@redhat.com>
* gdb.texinfo (Backtrace): Replace "set/show backtrace-below-main"

View File

@ -3229,6 +3229,24 @@ the direction of stack growth.
By default, no frame based stack alignment is performed.
@item int frame_red_zone_size
The number of bytes, beyond the innermost-stack-address, reserved by the
@sc{abi}. A function is permitted to use this scratch area (instead of
allocating extra stack space).
When performing an inferior function call, to ensure that it does not
modify this area, @value{GDBN} adjusts the innermost-stack-address by
@var{frame_red_zone_size} bytes before pushing parameters onto the
stack.
By default, zero bytes are allocated. The value must be aligned
(@pxref{frame_align}).
The @sc{amd64} (nee x86-64) @sc{abi} documentation refers to the
@emph{red zone} when describing this scratch area.
@cindex red zone
@item DEPRECATED_FRAME_CHAIN(@var{frame})
@findex DEPRECATED_FRAME_CHAIN
Given @var{frame}, return a pointer to the calling frame.

View File

@ -238,6 +238,7 @@ struct gdbarch
gdbarch_stack_align_ftype *stack_align;
gdbarch_frame_align_ftype *frame_align;
gdbarch_reg_struct_has_addr_ftype *reg_struct_has_addr;
int frame_red_zone_size;
int parm_boundary;
const struct floatformat * float_format;
const struct floatformat * double_format;
@ -405,6 +406,7 @@ struct gdbarch startup_gdbarch =
0, /* stack_align */
0, /* frame_align */
0, /* reg_struct_has_addr */
0, /* frame_red_zone_size */
0, /* parm_boundary */
0, /* float_format */
0, /* double_format */
@ -1723,6 +1725,14 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
(long) current_gdbarch->frame_num_args
/*FRAME_NUM_ARGS ()*/);
#endif
#ifdef FRAME_RED_ZONE_SIZE
fprintf_unfiltered (file,
"gdbarch_dump: FRAME_RED_ZONE_SIZE # %s\n",
XSTRING (FRAME_RED_ZONE_SIZE));
fprintf_unfiltered (file,
"gdbarch_dump: FRAME_RED_ZONE_SIZE = %d\n",
FRAME_RED_ZONE_SIZE);
#endif
#ifdef FUNCTION_START_OFFSET
fprintf_unfiltered (file,
"gdbarch_dump: FUNCTION_START_OFFSET # %s\n",
@ -4905,6 +4915,22 @@ set_gdbarch_reg_struct_has_addr (struct gdbarch *gdbarch,
gdbarch->reg_struct_has_addr = reg_struct_has_addr;
}
int
gdbarch_frame_red_zone_size (struct gdbarch *gdbarch)
{
gdb_assert (gdbarch != NULL);
if (gdbarch_debug >= 2)
fprintf_unfiltered (gdb_stdlog, "gdbarch_frame_red_zone_size called\n");
return gdbarch->frame_red_zone_size;
}
void
set_gdbarch_frame_red_zone_size (struct gdbarch *gdbarch,
int frame_red_zone_size)
{
gdbarch->frame_red_zone_size = frame_red_zone_size;
}
int
gdbarch_parm_boundary (struct gdbarch *gdbarch)
{

View File

@ -1942,6 +1942,15 @@ extern void set_gdbarch_reg_struct_has_addr (struct gdbarch *gdbarch, gdbarch_re
#define REG_STRUCT_HAS_ADDR(gcc_p, type) (gdbarch_reg_struct_has_addr (current_gdbarch, gcc_p, type))
#endif
extern int gdbarch_frame_red_zone_size (struct gdbarch *gdbarch);
extern void set_gdbarch_frame_red_zone_size (struct gdbarch *gdbarch, int frame_red_zone_size);
#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (FRAME_RED_ZONE_SIZE)
#error "Non multi-arch definition of FRAME_RED_ZONE_SIZE"
#endif
#if !defined (FRAME_RED_ZONE_SIZE)
#define FRAME_RED_ZONE_SIZE (gdbarch_frame_red_zone_size (current_gdbarch))
#endif
extern int gdbarch_parm_boundary (struct gdbarch *gdbarch);
extern void set_gdbarch_parm_boundary (struct gdbarch *gdbarch, int parm_boundary);
#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (PARM_BOUNDARY)

View File

@ -643,6 +643,7 @@ F:2:FRAME_NUM_ARGS:int:frame_num_args:struct frame_info *frame:frame
F:2:STACK_ALIGN:CORE_ADDR:stack_align:CORE_ADDR sp:sp
M:::CORE_ADDR:frame_align:CORE_ADDR address:address
F:2:REG_STRUCT_HAS_ADDR:int:reg_struct_has_addr:int gcc_p, struct type *type:gcc_p, type
v::FRAME_RED_ZONE_SIZE:int:frame_red_zone_size
v:2:PARM_BOUNDARY:int:parm_boundary
#
v:2:TARGET_FLOAT_FORMAT:const struct floatformat *:float_format::::::default_float_format (gdbarch)::%s:(TARGET_FLOAT_FORMAT)->name

View File

@ -440,6 +440,18 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
CORE_ADDR old_sp = read_sp ();
if (gdbarch_frame_align_p (current_gdbarch))
{
sp = gdbarch_frame_align (current_gdbarch, old_sp);
/* NOTE: cagney/2003-08-13: Skip the "red zone". For some
ABIs, a function can use memory beyond the inner most stack
address. AMD64 called that region the "red zone". Skip at
least the "red zone" size before allocating any space on
the stack. */
if (INNER_THAN (1, 2))
sp -= gdbarch_frame_red_zone_size (current_gdbarch);
else
sp += gdbarch_frame_red_zone_size (current_gdbarch);
/* Still aligned? */
gdb_assert (sp == gdbarch_frame_align (current_gdbarch, sp));
/* NOTE: cagney/2002-09-18:
On a RISC architecture, a void parameterless generic dummy
@ -460,7 +472,6 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
stack. That way, two dummy frames can never be identical.
It does burn a few bytes of stack but that is a small price
to pay :-). */
sp = gdbarch_frame_align (current_gdbarch, old_sp);
if (sp == old_sp)
{
if (INNER_THAN (1, 2))
@ -476,12 +487,16 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
else
/* FIXME: cagney/2002-09-18: Hey, you loose!
Who knows how badly aligned the SP is! Further, per comment
above, if the generic dummy frame ends up empty (because
nothing is pushed) GDB won't be able to correctly perform
back traces. If a target is having trouble with backtraces,
first thing to do is add FRAME_ALIGN() to the architecture
vector. If that fails, try unwind_dummy_id(). */
Who knows how badly aligned the SP is!
If the generic dummy frame ends up empty (because nothing is
pushed) GDB won't be able to correctly perform back traces.
If a target is having trouble with backtraces, first thing to
do is add FRAME_ALIGN() to the architecture vector. If that
fails, try unwind_dummy_id().
If the ABI specifies a "Red Zone" (see the doco) the code
below will quietly trash it. */
sp = old_sp;
}

View File

@ -2944,6 +2944,12 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_deprecated_fix_call_dummy (gdbarch, rs6000_fix_call_dummy);
set_gdbarch_frame_align (gdbarch, rs6000_frame_align);
if (sysv_abi && wordsize == 8)
/* PPC64 SYSV. */
set_gdbarch_frame_red_zone_size (gdbarch, 288);
else if (!sysv_abi && wordsize == 4)
/* PowerOpen / AIX 32 bit. */
set_gdbarch_frame_red_zone_size (gdbarch, 220);
set_gdbarch_deprecated_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos);
set_gdbarch_deprecated_push_return_address (gdbarch, ppc_push_return_address);
set_gdbarch_believe_pcc_promotion (gdbarch, 1);

View File

@ -614,13 +614,6 @@ x86_64_push_arguments (struct regcache *regcache, int nargs,
int *stack_values;
stack_values = alloca (nargs * sizeof (int));
/* Before storing anything to the stack we must skip
the "Red zone" (see the "Function calling sequence" section
of AMD64 ABI).
It could have already been skipped in the function's
prologue, but we don't care and will easily skip it once again. */
sp -= 128;
for (i = 0; i < nargs; i++)
{
enum x86_64_reg_class class[MAX_CLASSES];
@ -1203,6 +1196,14 @@ x86_64_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
return frame_id_build (fp + 16, frame_pc_unwind (next_frame));
}
/* 16 byte align the SP per frame requirements. */
static CORE_ADDR
x86_64_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
{
return sp & -(CORE_ADDR)16;
}
void
x86_64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
@ -1246,6 +1247,8 @@ x86_64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* Call dummy code. */
set_gdbarch_push_dummy_call (gdbarch, x86_64_push_dummy_call);
set_gdbarch_frame_align (gdbarch, x86_64_frame_align);
set_gdbarch_frame_red_zone_size (gdbarch, 128);
set_gdbarch_convert_register_p (gdbarch, x86_64_convert_register_p);
set_gdbarch_register_to_value (gdbarch, i387_register_to_value);