#include "interps.h"
#include "thread-fsm.h"
#include <algorithm>
-#include "common/scope-exit.h"
+#include "gdbsupport/scope-exit.h"
/* If we can't find a function's name from its address,
we print this instead. */
asynchronous inferior function call implementation, and that in
turn means restructuring the code so that it is event driven. */
+static bool may_call_functions_p = true;
+static void
+show_may_call_functions_p (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c,
+ const char *value)
+{
+ fprintf_filtered (file,
+ _("Permission to call functions in the program is %s.\n"),
+ value);
+}
+
/* How you should pass arguments to a function depends on whether it
was defined in K&R style or prototype style. If you define a
function using the K&R syntax that takes a `float' argument, then
trust the debug information; the user can override this behavior
with "set coerce-float-to-double 0". */
-static int coerce_float_to_double_p = 1;
+static bool coerce_float_to_double_p = true;
static void
show_coerce_float_to_double_p (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
The default is to stop in the frame where the signal was received. */
-static int unwind_on_signal_p = 0;
+static bool unwind_on_signal_p = false;
static void
show_unwind_on_signal_p (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
The default is to unwind the frame if a std::terminate call is
made. */
-static int unwind_on_terminating_exception_p = 1;
+static bool unwind_on_terminating_exception_p = true;
static void
show_unwind_on_terminating_exception_p (struct ui_file *file, int from_tty,
for arguments to be passed to C, Ada or Fortran functions.
If PARAM_TYPE is non-NULL, it is the expected parameter type.
- IS_PROTOTYPED is non-zero if the function declaration is prototyped.
- SP is the stack pointer were additional data can be pushed (updating
- its value as needed). */
+ IS_PROTOTYPED is non-zero if the function declaration is prototyped. */
static struct value *
value_arg_coerce (struct gdbarch *gdbarch, struct value *arg,
- struct type *param_type, int is_prototyped, CORE_ADDR *sp)
+ struct type *param_type, int is_prototyped)
{
const struct builtin_type *builtin = builtin_type (gdbarch);
struct type *arg_type = check_typedef (value_type (arg));
struct symbol *symbol = find_pc_function (funaddr);
if (symbol)
- return SYMBOL_PRINT_NAME (symbol);
+ return symbol->print_name ();
}
{
struct bound_minimal_symbol msymbol = lookup_minimal_symbol_by_pc (funaddr);
if (msymbol.minsym)
- return MSYMBOL_PRINT_NAME (msymbol.minsym);
+ return msymbol.minsym->print_name ();
}
{
run_inferior_call (struct call_thread_fsm *sm,
struct thread_info *call_thread, CORE_ADDR real_pc)
{
- struct gdb_exception caught_error = exception_none;
+ struct gdb_exception caught_error;
int saved_in_infcall = call_thread->control.in_infcall;
ptid_t call_thread_ptid = call_thread->ptid;
enum prompt_state saved_prompt_state = current_ui->prompt_state;
target supports asynchronous execution. */
wait_sync_command_done ();
}
- catch (const gdb_exception_RETURN_MASK_ALL &e)
+ catch (gdb_exception &e)
{
- caught_error = e;
+ caught_error = std::move (e);
}
/* If GDB has the prompt blocked before, then ensure that it remains
return caught_error;
}
+/* Reserve space on the stack for a value of the given type.
+ Return the address of the allocated space.
+ Make certain that the value is correctly aligned.
+ The SP argument is modified. */
+
+static CORE_ADDR
+reserve_stack_space (const type *values_type, CORE_ADDR &sp)
+{
+ struct frame_info *frame = get_current_frame ();
+ struct gdbarch *gdbarch = get_frame_arch (frame);
+ CORE_ADDR addr = 0;
+
+ if (gdbarch_inner_than (gdbarch, 1, 2))
+ {
+ /* Stack grows downward. Align STRUCT_ADDR and SP after
+ making space. */
+ sp -= TYPE_LENGTH (values_type);
+ if (gdbarch_frame_align_p (gdbarch))
+ sp = gdbarch_frame_align (gdbarch, sp);
+ addr = 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);
+ addr = sp;
+ sp += TYPE_LENGTH (values_type);
+ if (gdbarch_frame_align_p (gdbarch))
+ sp = gdbarch_frame_align (gdbarch, sp);
+ }
+
+ return addr;
+}
+
/* See infcall.h. */
struct value *
making dummy frames be different from normal frames, consider that. */
/* Perform a function call in the inferior.
- ARGS is a vector of values of arguments (NARGS of them).
+ ARGS is a vector of values of arguments.
FUNCTION is a value, the function to be called.
Returns a value representing what the function returned.
May fail to return, if a breakpoint or signal is hit
struct gdb_exception e;
char name_buf[RAW_FUNCTION_ADDRESS_SIZE];
+ if (!may_call_functions_p)
+ error (_("Cannot call functions in the program: "
+ "may-call-functions is off."));
+
if (!target_has_execution)
noprocess ();
if (!gdbarch_push_dummy_call_p (gdbarch))
error (_("This target does not support function calls."));
+ /* Find the function type and do a sanity check. */
+ type *ftype;
+ type *values_type;
+ CORE_ADDR funaddr = find_function_addr (function, &values_type, &ftype);
+
+ if (values_type == NULL)
+ values_type = default_return_type;
+ if (values_type == NULL)
+ {
+ const char *name = get_function_name (funaddr,
+ name_buf, sizeof (name_buf));
+ error (_("'%s' has unknown return type; "
+ "cast the call to its declared return type"),
+ name);
+ }
+
+ values_type = check_typedef (values_type);
+
+ if (args.size () < TYPE_NFIELDS (ftype))
+ error (_("Too few arguments in function call."));
+
/* A holder for the inferior status.
This is only needed while we're preparing the inferior function call. */
infcall_control_state_up inf_status (save_infcall_control_state ());
void parameterless generic dummy frame calls to frameless
functions will create a sequence of effectively identical
frames (SP, FP and TOS and PC the same). This, not
- suprisingly, results in what appears to be a stack in an
+ surprisingly, results in what appears to be a stack in an
infinite loop --- when GDB tries to find a generic dummy
frame on the internal dummy frame stack, it will always
find the first one.
}
}
- type *ftype;
- type *values_type;
- CORE_ADDR funaddr = find_function_addr (function, &values_type, &ftype);
-
- if (values_type == NULL)
- values_type = default_return_type;
- if (values_type == NULL)
- {
- const char *name = get_function_name (funaddr,
- name_buf, sizeof (name_buf));
- error (_("'%s' has unknown return type; "
- "cast the call to its declared return type"),
- name);
- }
-
- values_type = check_typedef (values_type);
-
/* Are we returning a value using a structure return? */
if (gdbarch_return_in_first_hidden_param_p (gdbarch, values_type))
internal_error (__FILE__, __LINE__, _("bad switch"));
}
- if (args.size () < TYPE_NFIELDS (ftype))
- error (_("Too few arguments in function call."));
-
for (int i = args.size () - 1; i >= 0; i--)
{
int prototyped;
param_type = NULL;
args[i] = value_arg_coerce (gdbarch, args[i],
- param_type, prototyped, &sp);
+ param_type, prototyped);
if (param_type != NULL && language_pass_by_reference (param_type))
args[i] = value_addr (args[i]);
}
/* Reserve space for the return structure to be written on the
- stack, if necessary. Make certain that the value is correctly
- aligned.
+ stack, if necessary.
While evaluating expressions, we reserve space on the stack for
return values of class type even if the language ABI and the target
if (return_method != return_method_normal
|| (stack_temporaries && class_or_union_p (values_type)))
- {
- if (gdbarch_inner_than (gdbarch, 1, 2))
- {
- /* Stack grows downward. Align STRUCT_ADDR and SP after
- making space for the return value. */
- sp -= TYPE_LENGTH (values_type);
- if (gdbarch_frame_align_p (gdbarch))
- sp = gdbarch_frame_align (gdbarch, sp);
- struct_addr = 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);
- struct_addr = sp;
- sp += TYPE_LENGTH (values_type);
- if (gdbarch_frame_align_p (gdbarch))
- sp = gdbarch_frame_align (gdbarch, sp);
- }
- }
+ struct_addr = reserve_stack_space (values_type, sp);
std::vector<struct value *> new_args;
if (return_method == return_method_hidden_param)
e.what (), name);
case RETURN_QUIT:
default:
- throw_exception (e);
+ throw_exception (std::move (e));
}
}
void
_initialize_infcall (void)
{
+ add_setshow_boolean_cmd ("may-call-functions", no_class,
+ &may_call_functions_p, _("\
+Set permission to call functions in the program."), _("\
+Show permission to call functions in the program."), _("\
+When this permission is on, GDB may call functions in the program.\n\
+Otherwise, any sort of attempt to call a function in the program\n\
+will result in an error."),
+ NULL,
+ show_may_call_functions_p,
+ &setlist, &showlist);
+
add_setshow_boolean_cmd ("coerce-float-to-double", class_obscure,
&coerce_float_to_double_p, _("\
Set coercion of floats to doubles when calling functions."), _("\
-Show coercion of floats to doubles when calling functions"), _("\
+Show coercion of floats to doubles when calling functions."), _("\
Variables of type float should generally be converted to doubles before\n\
calling an unprototyped function, and left alone when calling a prototyped\n\
function. However, some older debug info formats do not provide enough\n\
information to determine that a function is prototyped. If this flag is\n\
set, GDB will perform the conversion for a function it considers\n\
unprototyped.\n\
-The default is to perform the conversion.\n"),
+The default is to perform the conversion."),
NULL,
show_coerce_float_to_double_p,
&setlist, &showlist);