Index: gdb/infcall.c |
diff --git a/gdb/infcall.c b/gdb/infcall.c |
index 9af56ba4b9e907b49e854e86c772fccfc770e2c5..1b2c3d6eb4c63e1e17bbaccc87500bc30dd20499 100644 |
--- a/gdb/infcall.c |
+++ b/gdb/infcall.c |
@@ -88,7 +88,7 @@ show_coerce_float_to_double_p (struct ui_file *file, int from_tty, |
The default is to stop in the frame where the signal was received. */ |
-int unwind_on_signal_p = 0; |
+static int unwind_on_signal_p = 0; |
static void |
show_unwind_on_signal_p (struct ui_file *file, int from_tty, |
struct cmd_list_element *c, const char *value) |
@@ -159,7 +159,7 @@ value_arg_coerce (struct gdbarch *gdbarch, struct value *arg, |
struct value *new_value; |
if (TYPE_CODE (arg_type) == TYPE_CODE_REF) |
- return value_cast_pointers (type, arg); |
+ return value_cast_pointers (type, arg, 0); |
/* Cast the value to the reference's target type, and then |
convert it back to a reference. This will issue an error |
@@ -399,7 +399,7 @@ run_inferior_call (struct thread_info *call_thread, CORE_ADDR real_pc) |
TRY_CATCH (e, RETURN_MASK_ALL) |
{ |
- proceed (real_pc, TARGET_SIGNAL_0, 0); |
+ proceed (real_pc, GDB_SIGNAL_0, 0); |
/* Inferior function calls are always synchronous, even if the |
target supports asynchronous execution. Do here what |
@@ -464,7 +464,7 @@ call_function_by_hand (struct value *function, int nargs, struct value **args) |
{ |
CORE_ADDR sp; |
struct type *values_type, *target_values_type; |
- unsigned char struct_return = 0, lang_struct_return = 0; |
+ unsigned char struct_return = 0, hidden_first_param_p = 0; |
CORE_ADDR struct_addr = 0; |
struct infcall_control_state *inf_status; |
struct cleanup *inf_status_cleanup; |
@@ -598,9 +598,9 @@ call_function_by_hand (struct value *function, int nargs, struct value **args) |
the first argument is passed in out0 but the hidden structure |
return pointer would normally be passed in r8. */ |
- if (language_pass_by_reference (values_type)) |
+ if (gdbarch_return_in_first_hidden_param_p (gdbarch, values_type)) |
{ |
- lang_struct_return = 1; |
+ hidden_first_param_p = 1; |
/* Tell the target specific argument pushing routine not to |
expect a value. */ |
@@ -608,8 +608,7 @@ call_function_by_hand (struct value *function, int nargs, struct value **args) |
} |
else |
{ |
- struct_return = using_struct_return (gdbarch, |
- value_type (function), values_type); |
+ struct_return = using_struct_return (gdbarch, function, values_type); |
target_values_type = values_type; |
} |
@@ -619,15 +618,38 @@ call_function_by_hand (struct value *function, int nargs, struct value **args) |
not just the breakpoint but also an extra word containing the |
size (?) of the structure being passed. */ |
- /* The actual breakpoint (at BP_ADDR) is inserted separatly so there |
- is no need to write that out. */ |
- |
switch (gdbarch_call_dummy_location (gdbarch)) |
{ |
case ON_STACK: |
- sp = push_dummy_code (gdbarch, sp, funaddr, |
- args, nargs, target_values_type, |
- &real_pc, &bp_addr, get_current_regcache ()); |
+ { |
+ const gdb_byte *bp_bytes; |
+ CORE_ADDR bp_addr_as_address; |
+ int bp_size; |
+ |
+ /* Be careful BP_ADDR is in inferior PC encoding while |
+ BP_ADDR_AS_ADDRESS is a plain memory address. */ |
+ |
+ sp = push_dummy_code (gdbarch, sp, funaddr, args, nargs, |
+ target_values_type, &real_pc, &bp_addr, |
+ get_current_regcache ()); |
+ |
+ /* Write a legitimate instruction at the point where the infcall |
+ breakpoint is going to be inserted. While this instruction |
+ is never going to be executed, a user investigating the |
+ memory from GDB would see this instruction instead of random |
+ uninitialized bytes. We chose the breakpoint instruction |
+ as it may look as the most logical one to the user and also |
+ valgrind 3.7.0 needs it for proper vgdb inferior calls. |
+ |
+ If software breakpoints are unsupported for this target we |
+ leave the user visible memory content uninitialized. */ |
+ |
+ bp_addr_as_address = bp_addr; |
+ bp_bytes = gdbarch_breakpoint_from_pc (gdbarch, &bp_addr_as_address, |
+ &bp_size); |
+ if (bp_bytes != NULL) |
+ write_memory (bp_addr_as_address, bp_bytes, bp_size); |
+ } |
break; |
case AT_ENTRY_POINT: |
{ |
@@ -635,35 +657,12 @@ call_function_by_hand (struct value *function, int nargs, struct value **args) |
real_pc = funaddr; |
dummy_addr = entry_point_address (); |
+ |
/* A call dummy always consists of just a single breakpoint, so |
- its address is the same as the address of the dummy. */ |
- bp_addr = dummy_addr; |
- break; |
- } |
- case AT_SYMBOL: |
- /* Some executables define a symbol __CALL_DUMMY_ADDRESS whose |
- address is the location where the breakpoint should be |
- placed. Once all targets are using the overhauled frame code |
- this can be deleted - ON_STACK is a better option. */ |
- { |
- struct minimal_symbol *sym; |
- CORE_ADDR dummy_addr; |
+ its address is the same as the address of the dummy. |
- sym = lookup_minimal_symbol ("__CALL_DUMMY_ADDRESS", NULL, NULL); |
- real_pc = funaddr; |
- if (sym) |
- { |
- dummy_addr = SYMBOL_VALUE_ADDRESS (sym); |
- /* Make certain that the address points at real code, and not |
- a function descriptor. */ |
- dummy_addr = gdbarch_convert_from_func_ptr_addr (gdbarch, |
- dummy_addr, |
- ¤t_target); |
- } |
- else |
- dummy_addr = entry_point_address (); |
- /* A call dummy always consists of just a single breakpoint, |
- so it's address is the same as the address of the dummy. */ |
+ The actual breakpoint is inserted separatly so there is no need to |
+ write that out. */ |
bp_addr = dummy_addr; |
break; |
} |
@@ -708,7 +707,7 @@ call_function_by_hand (struct value *function, int nargs, struct value **args) |
stack, if necessary. Make certain that the value is correctly |
aligned. */ |
- if (struct_return || lang_struct_return) |
+ if (struct_return || hidden_first_param_p) |
{ |
int len = TYPE_LENGTH (values_type); |
@@ -734,7 +733,7 @@ call_function_by_hand (struct value *function, int nargs, struct value **args) |
} |
} |
- if (lang_struct_return) |
+ if (hidden_first_param_p) |
{ |
struct value **new_args; |
@@ -772,7 +771,7 @@ call_function_by_hand (struct value *function, int nargs, struct value **args) |
inferior. That way it breaks when it returns. */ |
{ |
- struct breakpoint *bpt; |
+ struct breakpoint *bpt, *longjmp_b; |
struct symtab_and_line sal; |
init_sal (&sal); /* initialize to zeroes */ |
@@ -783,7 +782,22 @@ call_function_by_hand (struct value *function, int nargs, struct value **args) |
PUSH_DUMMY_CALL, saved as the dummy-frame TOS, and used by |
dummy_id to form the frame ID's stack address. */ |
bpt = set_momentary_breakpoint (gdbarch, sal, dummy_id, bp_call_dummy); |
+ |
+ /* set_momentary_breakpoint invalidates FRAME. */ |
+ frame = NULL; |
+ |
bpt->disposition = disp_del; |
+ gdb_assert (bpt->related_breakpoint == bpt); |
+ |
+ longjmp_b = set_longjmp_breakpoint_for_call_dummy (); |
+ if (longjmp_b) |
+ { |
+ /* Link BPT into the chain of LONGJMP_B. */ |
+ bpt->related_breakpoint = longjmp_b; |
+ while (longjmp_b->related_breakpoint != bpt->related_breakpoint) |
+ longjmp_b = longjmp_b->related_breakpoint; |
+ longjmp_b->related_breakpoint = bpt; |
+ } |
} |
/* Create a breakpoint in std::terminate. |
@@ -1036,7 +1050,7 @@ When the function is done executing, GDB will silently stop."), |
/* Figure out the value returned by the function. */ |
retval = allocate_value (values_type); |
- if (lang_struct_return) |
+ if (hidden_first_param_p) |
read_value_memory (retval, 0, 1, struct_addr, |
value_contents_raw (retval), |
TYPE_LENGTH (values_type)); |
@@ -1044,13 +1058,13 @@ When the function is done executing, GDB will silently stop."), |
{ |
/* If the function returns void, don't bother fetching the |
return value. */ |
- switch (gdbarch_return_value (gdbarch, value_type (function), |
- target_values_type, NULL, NULL, NULL)) |
+ switch (gdbarch_return_value (gdbarch, function, target_values_type, |
+ NULL, NULL, NULL)) |
{ |
case RETURN_VALUE_REGISTER_CONVENTION: |
case RETURN_VALUE_ABI_RETURNS_ADDRESS: |
case RETURN_VALUE_ABI_PRESERVES_ADDRESS: |
- gdbarch_return_value (gdbarch, value_type (function), values_type, |
+ gdbarch_return_value (gdbarch, function, values_type, |
retbuf, value_contents_raw (retval), NULL); |
break; |
case RETURN_VALUE_STRUCT_CONVENTION: |