X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Finfcall.c;h=537596984c159216dcf526e6b02f57d441265780;hb=064f515651b1e730c60652eaf07f94c22841d475;hp=9c104ad0fcc3b1dcdfac817674b71f8e316a1861;hpb=a86c5fc9d872cff24a45c4e19f4cf1e8c9df4c16;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/infcall.c b/gdb/infcall.c index 9c104ad0fc..537596984c 100644 --- a/gdb/infcall.c +++ b/gdb/infcall.c @@ -1,7 +1,7 @@ /* Perform an inferior function call, for GDB, the GNU debugger. - Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, - 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 + Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, + 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. This file is part of GDB. @@ -18,8 +18,8 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ #include "defs.h" #include "breakpoint.h" @@ -109,14 +109,20 @@ value_arg_coerce (struct value *arg, struct type *param_type, switch (TYPE_CODE (type)) { case TYPE_CODE_REF: - if (TYPE_CODE (arg_type) != TYPE_CODE_REF - && TYPE_CODE (arg_type) != TYPE_CODE_PTR) - { - arg = value_addr (arg); - deprecated_set_value_type (arg, param_type); - return arg; - } - break; + { + struct value *new_value; + + if (TYPE_CODE (arg_type) == TYPE_CODE_REF) + return value_cast_pointers (type, arg); + + /* Cast the value to the reference's target type, and then + convert it back to a reference. This will issue an error + if the value was not previously in memory - in some cases + we should clearly be allowing this, but how? */ + new_value = value_cast (TYPE_TARGET_TYPE (type), arg); + new_value = value_ref (new_value); + return new_value; + } case TYPE_CODE_INT: case TYPE_CODE_CHAR: case TYPE_CODE_BOOL: @@ -163,7 +169,8 @@ value_arg_coerce (struct value *arg, struct type *param_type, case TYPE_CODE_STRING: case TYPE_CODE_BITSTRING: case TYPE_CODE_ERROR: - case TYPE_CODE_MEMBER: + case TYPE_CODE_MEMBERPTR: + case TYPE_CODE_METHODPTR: case TYPE_CODE_METHOD: case TYPE_CODE_COMPLEX: default: @@ -225,7 +232,7 @@ find_function_addr (struct value *function, struct type **retval_type) if (retval_type != NULL) *retval_type = value_type; - return funaddr + DEPRECATED_FUNCTION_START_OFFSET; + return funaddr + gdbarch_deprecated_function_start_offset (current_gdbarch); } /* Call breakpoint_auto_delete on the current contents of the bpstat @@ -242,7 +249,8 @@ generic_push_dummy_code (struct gdbarch *gdbarch, CORE_ADDR sp, CORE_ADDR funaddr, int using_gcc, struct value **args, int nargs, struct type *value_type, - CORE_ADDR *real_pc, CORE_ADDR *bp_addr) + CORE_ADDR *real_pc, CORE_ADDR *bp_addr, + struct regcache *regcache) { /* Something here to findout the size of a breakpoint and then allocate space for it on the stack. */ @@ -281,14 +289,17 @@ push_dummy_code (struct gdbarch *gdbarch, CORE_ADDR sp, CORE_ADDR funaddr, int using_gcc, struct value **args, int nargs, struct type *value_type, - CORE_ADDR *real_pc, CORE_ADDR *bp_addr) + CORE_ADDR *real_pc, CORE_ADDR *bp_addr, + struct regcache *regcache) { if (gdbarch_push_dummy_code_p (gdbarch)) return gdbarch_push_dummy_code (gdbarch, sp, funaddr, using_gcc, - args, nargs, value_type, real_pc, bp_addr); + args, nargs, value_type, real_pc, bp_addr, + regcache); else return generic_push_dummy_code (gdbarch, sp, funaddr, using_gcc, - args, nargs, value_type, real_pc, bp_addr); + args, nargs, value_type, real_pc, bp_addr, + regcache); } /* All this stuff with a dummy frame may seem unnecessarily complicated @@ -330,6 +341,9 @@ call_function_by_hand (struct value *function, int nargs, struct value **args) struct cleanup *caller_regcache_cleanup; struct frame_id dummy_id; + if (TYPE_CODE (ftype) == TYPE_CODE_PTR) + ftype = check_typedef (TYPE_TARGET_TYPE (ftype)); + if (!target_has_execution) noprocess (); @@ -358,7 +372,7 @@ call_function_by_hand (struct value *function, int nargs, struct value **args) /* Ensure that the initial SP is correctly aligned. */ { - CORE_ADDR old_sp = read_sp (); + CORE_ADDR old_sp = get_frame_sp (get_current_frame ()); if (gdbarch_frame_align_p (current_gdbarch)) { sp = gdbarch_frame_align (current_gdbarch, old_sp); @@ -367,7 +381,7 @@ call_function_by_hand (struct value *function, int nargs, struct value **args) 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)) + if (gdbarch_inner_than (current_gdbarch, 1, 2)) sp -= gdbarch_frame_red_zone_size (current_gdbarch); else sp += gdbarch_frame_red_zone_size (current_gdbarch); @@ -395,15 +409,17 @@ call_function_by_hand (struct value *function, int nargs, struct value **args) to pay :-). */ if (sp == old_sp) { - if (INNER_THAN (1, 2)) + if (gdbarch_inner_than (current_gdbarch, 1, 2)) /* Stack grows down. */ sp = gdbarch_frame_align (current_gdbarch, old_sp - 1); else /* Stack grows up. */ sp = gdbarch_frame_align (current_gdbarch, old_sp + 1); } - gdb_assert ((INNER_THAN (1, 2) && sp <= old_sp) - || (INNER_THAN (2, 1) && sp >= old_sp)); + gdb_assert ((gdbarch_inner_than (current_gdbarch, 1, 2) + && sp <= old_sp) + || (gdbarch_inner_than (current_gdbarch, 2, 1) + && sp >= old_sp)); } else /* FIXME: cagney/2002-09-18: Hey, you loose! @@ -444,16 +460,16 @@ call_function_by_hand (struct value *function, int nargs, struct value **args) /* The actual breakpoint (at BP_ADDR) is inserted separatly so there is no need to write that out. */ - switch (CALL_DUMMY_LOCATION) + switch (gdbarch_call_dummy_location (current_gdbarch)) { case ON_STACK: /* "dummy_addr" is here just to keep old targets happy. New targets return that same information via "sp" and "bp_addr". */ - if (INNER_THAN (1, 2)) + if (gdbarch_inner_than (current_gdbarch, 1, 2)) { sp = push_dummy_code (current_gdbarch, sp, funaddr, using_gcc, args, nargs, values_type, - &real_pc, &bp_addr); + &real_pc, &bp_addr, get_current_regcache ()); dummy_addr = sp; } else @@ -461,7 +477,7 @@ call_function_by_hand (struct value *function, int nargs, struct value **args) dummy_addr = sp; sp = push_dummy_code (current_gdbarch, sp, funaddr, using_gcc, args, nargs, values_type, - &real_pc, &bp_addr); + &real_pc, &bp_addr, get_current_regcache ()); } break; case AT_ENTRY_POINT: @@ -570,7 +586,7 @@ You must use a pointer to function type variable. Command ignored."), arg_name); } } - if (DEPRECATED_REG_STRUCT_HAS_ADDR_P ()) + if (gdbarch_deprecated_reg_struct_has_addr_p (current_gdbarch)) { int i; /* This is a machine like the sparc, where we may need to pass a @@ -587,7 +603,8 @@ You must use a pointer to function type variable. Command ignored."), arg_name); || (TYPE_CODE (arg_type) == TYPE_CODE_FLT && TYPE_LENGTH (arg_type) > 8) ) - && DEPRECATED_REG_STRUCT_HAS_ADDR (using_gcc, arg_type)) + && gdbarch_deprecated_reg_struct_has_addr + (current_gdbarch, using_gcc, arg_type)) { CORE_ADDR addr; int len; /* = TYPE_LENGTH (arg_type); */ @@ -596,7 +613,7 @@ You must use a pointer to function type variable. Command ignored."), arg_name); len = TYPE_LENGTH (arg_type); aligned_len = len; - if (INNER_THAN (1, 2)) + if (gdbarch_inner_than (current_gdbarch, 1, 2)) { /* stack grows downward */ sp -= aligned_len; @@ -631,7 +648,7 @@ You must use a pointer to function type variable. Command ignored."), arg_name); if (struct_return) { int len = TYPE_LENGTH (values_type); - if (INNER_THAN (1, 2)) + if (gdbarch_inner_than (current_gdbarch, 1, 2)) { /* Stack grows downward. Align STRUCT_ADDR and SP after making space for the return value. */ @@ -656,9 +673,9 @@ You must use a pointer to function type variable. Command ignored."), arg_name); /* Create the dummy stack frame. Pass in the call dummy address as, presumably, the ABI code knows where, in the call dummy, the return address should be pointed. */ - sp = gdbarch_push_dummy_call (current_gdbarch, function, current_regcache, - bp_addr, nargs, args, sp, struct_return, - struct_addr); + sp = gdbarch_push_dummy_call (current_gdbarch, function, + get_current_regcache (), bp_addr, nargs, args, + sp, struct_return, struct_addr); /* Set up a frame ID for the dummy frame so we can pass it to set_momentary_breakpoint. We need to give the breakpoint a frame