* s390-tdep.c (s390_push_dummy_call): Error on stack overflow

during inferior call stack frame setup.
This commit is contained in:
Ulrich Weigand 2010-06-25 17:47:29 +00:00
parent f1d8ee6626
commit c0cc4c83bd
2 changed files with 24 additions and 9 deletions

View file

@ -1,3 +1,8 @@
2010-06-25 Ulrich Weigand <uweigand@de.ibm.com>
* s390-tdep.c (s390_push_dummy_call): Error on stack overflow
during inferior call stack frame setup.
2010-06-25 Ken Werner <ken.werner@de.ibm.com> 2010-06-25 Ken Werner <ken.werner@de.ibm.com>
* solib-spu.c: Include "exception.h". * solib-spu.c: Include "exception.h".

View file

@ -2343,14 +2343,13 @@ s390_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int word_size = gdbarch_ptr_bit (gdbarch) / 8; int word_size = gdbarch_ptr_bit (gdbarch) / 8;
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
ULONGEST orig_sp;
int i; int i;
/* If the i'th argument is passed as a reference to a copy, then /* If the i'th argument is passed as a reference to a copy, then
copy_addr[i] is the address of the copy we made. */ copy_addr[i] is the address of the copy we made. */
CORE_ADDR *copy_addr = alloca (nargs * sizeof (CORE_ADDR)); CORE_ADDR *copy_addr = alloca (nargs * sizeof (CORE_ADDR));
/* Build the reference-to-copy area. */ /* Reserve space for the reference-to-copy area. */
for (i = 0; i < nargs; i++) for (i = 0; i < nargs; i++)
{ {
struct value *arg = args[i]; struct value *arg = args[i];
@ -2361,7 +2360,6 @@ s390_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
{ {
sp -= length; sp -= length;
sp = align_down (sp, alignment_of (type)); sp = align_down (sp, alignment_of (type));
write_memory (sp, value_contents (arg), length);
copy_addr[i] = sp; copy_addr[i] = sp;
} }
} }
@ -2376,13 +2374,26 @@ s390_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
boundary. */ boundary. */
sp = align_down (sp, 8); sp = align_down (sp, 8);
/* Allocate the standard frame areas: the register save area, the
word reserved for the compiler (which seems kind of meaningless),
and the back chain pointer. */
sp -= 16*word_size + 32;
/* Now we have the final SP value. Make sure we didn't underflow;
on 31-bit, this would result in addresses with the high bit set,
which causes confusion elsewhere. Note that if we error out
here, stack and registers remain untouched. */
if (gdbarch_addr_bits_remove (gdbarch, sp) != sp)
error (_("Stack overflow"));
/* Finally, place the actual parameters, working from SP towards /* Finally, place the actual parameters, working from SP towards
higher addresses. The code above is supposed to reserve enough higher addresses. The code above is supposed to reserve enough
space for this. */ space for this. */
{ {
int fr = 0; int fr = 0;
int gr = 2; int gr = 2;
CORE_ADDR starg = sp; CORE_ADDR starg = sp + 16*word_size + 32;
/* A struct is returned using general register 2. */ /* A struct is returned using general register 2. */
if (struct_return) if (struct_return)
@ -2400,6 +2411,10 @@ s390_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
if (s390_function_arg_pass_by_reference (type)) if (s390_function_arg_pass_by_reference (type))
{ {
/* Actually copy the argument contents to the stack slot
that was reserved above. */
write_memory (copy_addr[i], value_contents (arg), length);
if (gr <= 6) if (gr <= 6)
{ {
regcache_cooked_write_unsigned (regcache, S390_R0_REGNUM + gr, regcache_cooked_write_unsigned (regcache, S390_R0_REGNUM + gr,
@ -2475,11 +2490,6 @@ s390_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
} }
} }
/* Allocate the standard frame areas: the register save area, the
word reserved for the compiler (which seems kind of meaningless),
and the back chain pointer. */
sp -= 16*word_size + 32;
/* Store return address. */ /* Store return address. */
regcache_cooked_write_unsigned (regcache, S390_RETADDR_REGNUM, bp_addr); regcache_cooked_write_unsigned (regcache, S390_RETADDR_REGNUM, bp_addr);