mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-03 13:23:00 +08:00
[Ada/funcalls] do not coerce fat pointers on the stack
When one of the parameter values in a subprogram calls is an array whose value does not come from inferior memory, the debugger first copies the array value in inferior memory. Up to now, the memory used to hold that copy was taken from the stack (just below the SP), but this is causing problems on SPARC v9. So the immediate fix is to follow what C does with arrays and strings, which is allocate memory on the heap. gdb/ChangeLog: * ada-lang.c: #include "value.h". (ensure_lval): Delete advance declaration. Remove gdbarch and sp arguments. Implement using value_allocate_space_in_inferior instead of allocating memory from the stack. (make_array_descriptor): Remove gdbarch and sp parameters. Update calls to ensure_lval. (ada_convert_actual): Remove gdbarch and sp parameters. Update calls to make_array_descriptor and ensure_lval. * ada-lang.h (ada_convert_actual): Update declaration. * infcall.c (value_arg_coerce): Update call to ada_convert_actual.
This commit is contained in:
@ -1,3 +1,16 @@
|
|||||||
|
2010-10-04 Joel Brobecker <brobecker@adacore.com>
|
||||||
|
|
||||||
|
* ada-lang.c: #include "value.h".
|
||||||
|
(ensure_lval): Delete advance declaration. Remove gdbarch and sp
|
||||||
|
arguments. Implement using value_allocate_space_in_inferior
|
||||||
|
instead of allocating memory from the stack.
|
||||||
|
(make_array_descriptor): Remove gdbarch and sp parameters. Update
|
||||||
|
calls to ensure_lval.
|
||||||
|
(ada_convert_actual): Remove gdbarch and sp parameters. Update
|
||||||
|
calls to make_array_descriptor and ensure_lval.
|
||||||
|
* ada-lang.h (ada_convert_actual): Update declaration.
|
||||||
|
* infcall.c (value_arg_coerce): Update call to ada_convert_actual.
|
||||||
|
|
||||||
2010-10-04 Doug Evans <dje@google.com>
|
2010-10-04 Doug Evans <dje@google.com>
|
||||||
|
|
||||||
* python/python.c (_initialize_python): Define new function
|
* python/python.c (_initialize_python): Define new function
|
||||||
|
@ -59,6 +59,7 @@
|
|||||||
#include "stack.h"
|
#include "stack.h"
|
||||||
|
|
||||||
#include "psymtab.h"
|
#include "psymtab.h"
|
||||||
|
#include "value.h"
|
||||||
|
|
||||||
/* Define whether or not the C operator '/' truncates towards zero for
|
/* Define whether or not the C operator '/' truncates towards zero for
|
||||||
differently signed operands (truncation direction is undefined in C).
|
differently signed operands (truncation direction is undefined in C).
|
||||||
@ -102,11 +103,7 @@ static int ada_type_match (struct type *, struct type *, int);
|
|||||||
|
|
||||||
static int ada_args_match (struct symbol *, struct value **, int);
|
static int ada_args_match (struct symbol *, struct value **, int);
|
||||||
|
|
||||||
static struct value *ensure_lval (struct value *,
|
static struct value *make_array_descriptor (struct type *, struct value *);
|
||||||
struct gdbarch *, CORE_ADDR *);
|
|
||||||
|
|
||||||
static struct value *make_array_descriptor (struct type *, struct value *,
|
|
||||||
struct gdbarch *, CORE_ADDR *);
|
|
||||||
|
|
||||||
static void ada_add_block_symbols (struct obstack *,
|
static void ada_add_block_symbols (struct obstack *,
|
||||||
struct block *, const char *,
|
struct block *, const char *,
|
||||||
@ -3928,43 +3925,22 @@ parse_old_style_renaming (struct type *type,
|
|||||||
/* Evaluation: Function Calls */
|
/* Evaluation: Function Calls */
|
||||||
|
|
||||||
/* Return an lvalue containing the value VAL. This is the identity on
|
/* Return an lvalue containing the value VAL. This is the identity on
|
||||||
lvalues, and otherwise has the side-effect of pushing a copy of VAL
|
lvalues, and otherwise has the side-effect of allocating memory
|
||||||
on the stack, using and updating *SP as the stack pointer, and
|
in the inferior where a copy of the value contents is copied. */
|
||||||
returning an lvalue whose value_address points to the copy. */
|
|
||||||
|
|
||||||
static struct value *
|
static struct value *
|
||||||
ensure_lval (struct value *val, struct gdbarch *gdbarch, CORE_ADDR *sp)
|
ensure_lval (struct value *val)
|
||||||
{
|
{
|
||||||
if (! VALUE_LVAL (val))
|
if (VALUE_LVAL (val) == not_lval
|
||||||
|
|| VALUE_LVAL (val) == lval_internalvar)
|
||||||
{
|
{
|
||||||
int len = TYPE_LENGTH (ada_check_typedef (value_type (val)));
|
int len = TYPE_LENGTH (ada_check_typedef (value_type (val)));
|
||||||
|
const CORE_ADDR addr =
|
||||||
|
value_as_long (value_allocate_space_in_inferior (len));
|
||||||
|
|
||||||
/* The following is taken from the structure-return code in
|
set_value_address (val, addr);
|
||||||
call_function_by_hand. FIXME: Therefore, some refactoring seems
|
|
||||||
indicated. */
|
|
||||||
if (gdbarch_inner_than (gdbarch, 1, 2))
|
|
||||||
{
|
|
||||||
/* Stack grows downward. Align SP and value_address (val) after
|
|
||||||
reserving sufficient space. */
|
|
||||||
*sp -= len;
|
|
||||||
if (gdbarch_frame_align_p (gdbarch))
|
|
||||||
*sp = gdbarch_frame_align (gdbarch, *sp);
|
|
||||||
set_value_address (val, *sp);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Stack grows upward. Align the frame, allocate space, and
|
|
||||||
then again, re-align the frame. */
|
|
||||||
if (gdbarch_frame_align_p (gdbarch))
|
|
||||||
*sp = gdbarch_frame_align (gdbarch, *sp);
|
|
||||||
set_value_address (val, *sp);
|
|
||||||
*sp += len;
|
|
||||||
if (gdbarch_frame_align_p (gdbarch))
|
|
||||||
*sp = gdbarch_frame_align (gdbarch, *sp);
|
|
||||||
}
|
|
||||||
VALUE_LVAL (val) = lval_memory;
|
VALUE_LVAL (val) = lval_memory;
|
||||||
|
write_memory (addr, value_contents (val), len);
|
||||||
write_memory (value_address (val), value_contents (val), len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
@ -3976,8 +3952,7 @@ ensure_lval (struct value *val, struct gdbarch *gdbarch, CORE_ADDR *sp)
|
|||||||
values not residing in memory, updating it as needed. */
|
values not residing in memory, updating it as needed. */
|
||||||
|
|
||||||
struct value *
|
struct value *
|
||||||
ada_convert_actual (struct value *actual, struct type *formal_type0,
|
ada_convert_actual (struct value *actual, struct type *formal_type0)
|
||||||
struct gdbarch *gdbarch, CORE_ADDR *sp)
|
|
||||||
{
|
{
|
||||||
struct type *actual_type = ada_check_typedef (value_type (actual));
|
struct type *actual_type = ada_check_typedef (value_type (actual));
|
||||||
struct type *formal_type = ada_check_typedef (formal_type0);
|
struct type *formal_type = ada_check_typedef (formal_type0);
|
||||||
@ -3990,7 +3965,7 @@ ada_convert_actual (struct value *actual, struct type *formal_type0,
|
|||||||
|
|
||||||
if (ada_is_array_descriptor_type (formal_target)
|
if (ada_is_array_descriptor_type (formal_target)
|
||||||
&& TYPE_CODE (actual_target) == TYPE_CODE_ARRAY)
|
&& TYPE_CODE (actual_target) == TYPE_CODE_ARRAY)
|
||||||
return make_array_descriptor (formal_type, actual, gdbarch, sp);
|
return make_array_descriptor (formal_type, actual);
|
||||||
else if (TYPE_CODE (formal_type) == TYPE_CODE_PTR
|
else if (TYPE_CODE (formal_type) == TYPE_CODE_PTR
|
||||||
|| TYPE_CODE (formal_type) == TYPE_CODE_REF)
|
|| TYPE_CODE (formal_type) == TYPE_CODE_REF)
|
||||||
{
|
{
|
||||||
@ -4010,7 +3985,7 @@ ada_convert_actual (struct value *actual, struct type *formal_type0,
|
|||||||
memcpy ((char *) value_contents_raw (val),
|
memcpy ((char *) value_contents_raw (val),
|
||||||
(char *) value_contents (actual),
|
(char *) value_contents (actual),
|
||||||
TYPE_LENGTH (actual_type));
|
TYPE_LENGTH (actual_type));
|
||||||
actual = ensure_lval (val, gdbarch, sp);
|
actual = ensure_lval (val);
|
||||||
}
|
}
|
||||||
result = value_addr (actual);
|
result = value_addr (actual);
|
||||||
}
|
}
|
||||||
@ -4051,8 +4026,7 @@ value_pointer (struct value *value, struct type *type)
|
|||||||
representing a pointer to this descriptor. */
|
representing a pointer to this descriptor. */
|
||||||
|
|
||||||
static struct value *
|
static struct value *
|
||||||
make_array_descriptor (struct type *type, struct value *arr,
|
make_array_descriptor (struct type *type, struct value *arr)
|
||||||
struct gdbarch *gdbarch, CORE_ADDR *sp)
|
|
||||||
{
|
{
|
||||||
struct type *bounds_type = desc_bounds_type (type);
|
struct type *bounds_type = desc_bounds_type (type);
|
||||||
struct type *desc_type = desc_base_type (type);
|
struct type *desc_type = desc_base_type (type);
|
||||||
@ -4074,11 +4048,11 @@ make_array_descriptor (struct type *type, struct value *arr,
|
|||||||
desc_bound_bitsize (bounds_type, i, 1));
|
desc_bound_bitsize (bounds_type, i, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
bounds = ensure_lval (bounds, gdbarch, sp);
|
bounds = ensure_lval (bounds);
|
||||||
|
|
||||||
modify_general_field (value_type (descriptor),
|
modify_general_field (value_type (descriptor),
|
||||||
value_contents_writeable (descriptor),
|
value_contents_writeable (descriptor),
|
||||||
value_pointer (ensure_lval (arr, gdbarch, sp),
|
value_pointer (ensure_lval (arr),
|
||||||
TYPE_FIELD_TYPE (desc_type, 0)),
|
TYPE_FIELD_TYPE (desc_type, 0)),
|
||||||
fat_pntr_data_bitpos (desc_type),
|
fat_pntr_data_bitpos (desc_type),
|
||||||
fat_pntr_data_bitsize (desc_type));
|
fat_pntr_data_bitsize (desc_type));
|
||||||
@ -4090,7 +4064,7 @@ make_array_descriptor (struct type *type, struct value *arr,
|
|||||||
fat_pntr_bounds_bitpos (desc_type),
|
fat_pntr_bounds_bitpos (desc_type),
|
||||||
fat_pntr_bounds_bitsize (desc_type));
|
fat_pntr_bounds_bitsize (desc_type));
|
||||||
|
|
||||||
descriptor = ensure_lval (descriptor, gdbarch, sp);
|
descriptor = ensure_lval (descriptor);
|
||||||
|
|
||||||
if (TYPE_CODE (type) == TYPE_CODE_PTR)
|
if (TYPE_CODE (type) == TYPE_CODE_PTR)
|
||||||
return value_addr (descriptor);
|
return value_addr (descriptor);
|
||||||
|
@ -181,9 +181,7 @@ extern void ada_printstr (struct ui_file *, struct type *, const gdb_byte *,
|
|||||||
const struct value_print_options *);
|
const struct value_print_options *);
|
||||||
|
|
||||||
struct value *ada_convert_actual (struct value *actual,
|
struct value *ada_convert_actual (struct value *actual,
|
||||||
struct type *formal_type0,
|
struct type *formal_type0);
|
||||||
struct gdbarch *gdbarch,
|
|
||||||
CORE_ADDR *sp);
|
|
||||||
|
|
||||||
extern struct value *ada_value_subscript (struct value *, int,
|
extern struct value *ada_value_subscript (struct value *, int,
|
||||||
struct value **);
|
struct value **);
|
||||||
|
@ -143,7 +143,7 @@ value_arg_coerce (struct gdbarch *gdbarch, struct value *arg,
|
|||||||
|
|
||||||
/* Perform any Ada-specific coercion first. */
|
/* Perform any Ada-specific coercion first. */
|
||||||
if (current_language->la_language == language_ada)
|
if (current_language->la_language == language_ada)
|
||||||
arg = ada_convert_actual (arg, type, gdbarch, sp);
|
arg = ada_convert_actual (arg, type);
|
||||||
|
|
||||||
/* Force the value to the target if we will need its address. At
|
/* Force the value to the target if we will need its address. At
|
||||||
this point, we could allocate arguments on the stack instead of
|
this point, we could allocate arguments on the stack instead of
|
||||||
|
Reference in New Issue
Block a user