/* General Compile and inject code
- Copyright (C) 2014-2017 Free Software Foundation, Inc.
+ Copyright (C) 2014-2018 Free Software Foundation, Inc.
This file is part of GDB.
#include "valprint.h"
#include "common/gdb_optional.h"
#include "common/gdb_unlinker.h"
+#include "common/pathstuff.h"
\f
Return 1 if seen and update *ARG. */
static int
-check_raw_argument (char **arg)
+check_raw_argument (const char **arg)
{
*arg = skip_spaces (*arg);
that may contain calls to the GCC compiler. */
static void
-compile_file_command (char *arg, int from_tty)
+compile_file_command (const char *arg, int from_tty)
{
enum compile_i_scope_types scope = COMPILE_I_SIMPLE_SCOPE;
compile command is the language currently set in GDB. */
static void
-compile_code_command (char *arg, int from_tty)
+compile_code_command (const char *arg, int from_tty)
{
enum compile_i_scope_types scope = COMPILE_I_SIMPLE_SCOPE;
eval_compile_command (NULL, arg, scope, NULL);
else
{
- command_line_up l = get_command_line (compile_control, "");
+ counted_command_line l = get_command_line (compile_control, "");
l->control_u.compile.scope = scope;
execute_control_command_untraced (l.get ());
compile command is the language currently set in GDB. */
static void
-compile_print_command (char *arg_param, int from_tty)
+compile_print_command (const char *arg, int from_tty)
{
- const char *arg = arg_param;
enum compile_i_scope_types scope = COMPILE_I_PRINT_ADDRESS_SCOPE;
struct format_data fmt;
eval_compile_command (NULL, arg, scope, &fmt);
else
{
- command_line_up l = get_command_line (compile_control, "");
+ counted_command_line l = get_command_line (compile_control, "");
l->control_u.compile.scope = scope;
l->control_u.compile.scope_data = &fmt;
/* Implement 'set compile-args'. */
static void
-set_compile_args (char *args, int from_tty, struct cmd_list_element *c)
+set_compile_args (const char *args, int from_tty, struct cmd_list_element *c)
{
freeargv (compile_args_argv);
build_argc_argv (compile_args, &compile_args_argc, &compile_args_argv);
(*argvp)[(*argcp)] = NULL;
}
+/* String for 'set compile-gcc' and 'show compile-gcc'. */
+static char *compile_gcc;
+
+/* Implement 'show compile-gcc'. */
+
+static void
+show_compile_gcc (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("Compile command GCC driver filename is \"%s\".\n"),
+ value);
+}
+
/* Return DW_AT_producer parsed for get_selected_frame () (if any).
Return NULL otherwise.
cs = symtab->producer;
while (*cs != 0 && *cs != '-')
- cs = skip_spaces_const (skip_to_space_const (cs));
+ cs = skip_spaces (skip_to_space (cs));
if (*cs != '-')
return NULL;
return cs;
*destv = NULL;
}
-/* Produce final vector of GCC compilation options. First element is target
- size ("-m64", "-m32" etc.), optionally followed by DW_AT_producer options
- and then compile-args string GDB variable. */
+/* Produce final vector of GCC compilation options.
+
+ The first element of the combined argument vector are arguments
+ relating to the target size ("-m64", "-m32" etc.). These are
+ sourced from the inferior's architecture.
+
+ The second element of the combined argument vector are arguments
+ stored in the inferior DW_AT_producer section. If these are stored
+ in the inferior (there is no guarantee that they are), they are
+ added to the vector.
+
+ The third element of the combined argument vector are argument
+ supplied by the language implementation provided by
+ compile-{lang}-support. These contain language specific arguments.
+
+ The final element of the combined argument vector are arguments
+ supplied by the "set compile-args" command. These are always
+ appended last so as to override any of the arguments automatically
+ generated above. */
static void
get_args (const struct compile_instance *compiler, struct gdbarch *gdbarch,
int argc;
char **argv;
int ok;
- FILE *src;
struct gdbarch *gdbarch = get_current_arch ();
- const char *os_rx;
- const char *arch_rx;
- char *triplet_rx;
+ std::string triplet_rx;
char *error_message;
if (!target_has_execution)
{
struct command_line *iter;
- for (iter = cmd->body_list[0]; iter; iter = iter->next)
+ for (iter = cmd->body_list_0.get (); iter; iter = iter->next)
{
input_buf.puts (iter->line);
input_buf.puts ("\n");
if (compile_debug)
fprintf_unfiltered (gdb_stdlog, "debug output:\n\n%s", code.c_str ());
- os_rx = osabi_triplet_regexp (gdbarch_osabi (gdbarch));
- arch_rx = gdbarch_gnu_triplet_regexp (gdbarch);
+ if (compiler->fe->ops->version >= GCC_FE_VERSION_1)
+ compiler->fe->ops->set_verbose (compiler->fe, compile_debug);
- /* Allow triplets with or without vendor set. */
- triplet_rx = concat (arch_rx, "(-[^-]*)?-", os_rx, (char *) NULL);
- make_cleanup (xfree, triplet_rx);
+ if (compile_gcc[0] != 0)
+ {
+ if (compiler->fe->ops->version < GCC_FE_VERSION_1)
+ error (_("Command 'set compile-gcc' requires GCC version 6 or higher "
+ "(libcc1 interface version 1 or higher)"));
+
+ compiler->fe->ops->set_driver_filename (compiler->fe, compile_gcc);
+ }
+ else
+ {
+ const char *os_rx = osabi_triplet_regexp (gdbarch_osabi (gdbarch));
+ const char *arch_rx = gdbarch_gnu_triplet_regexp (gdbarch);
+
+ /* Allow triplets with or without vendor set. */
+ triplet_rx = std::string (arch_rx) + "(-[^-]*)?-" + os_rx;
+
+ if (compiler->fe->ops->version >= GCC_FE_VERSION_1)
+ compiler->fe->ops->set_triplet_regexp (compiler->fe,
+ triplet_rx.c_str ());
+ }
/* Set compiler command-line arguments. */
get_args (compiler, gdbarch, &argc, &argv);
gdb_argv argv_holder (argv);
- error_message = compiler->fe->ops->set_arguments (compiler->fe, triplet_rx,
- argc, argv);
+ if (compiler->fe->ops->version >= GCC_FE_VERSION_1)
+ error_message = compiler->fe->ops->set_arguments (compiler->fe, argc, argv);
+ else
+ error_message = compiler->fe->ops->set_arguments_v0 (compiler->fe,
+ triplet_rx.c_str (),
+ argc, argv);
if (error_message != NULL)
{
make_cleanup (xfree, error_message);
/* Call the compiler and start the compilation process. */
compiler->fe->ops->set_source_file (compiler->fe, fnames.source_file ());
- if (!compiler->fe->ops->compile (compiler->fe, fnames.object_file (),
- compile_debug))
+ if (compiler->fe->ops->version >= GCC_FE_VERSION_1)
+ ok = compiler->fe->ops->compile (compiler->fe, fnames.object_file ());
+ else
+ ok = compiler->fe->ops->compile_v0 (compiler->fe, fnames.object_file (),
+ compile_debug);
+ if (!ok)
error (_("Compilation failed."));
if (compile_debug)
/* The "compile" prefix command. */
static void
-compile_command (char *args, int from_tty)
+compile_command (const char *args, int from_tty)
{
/* If a sub-command is not specified to the compile prefix command,
assume it is a direct code compilation. */
/* See compile/compile-internal.h. */
-char *
+std::string
compile_register_name_mangled (struct gdbarch *gdbarch, int regnum)
{
const char *regname = gdbarch_register_name (gdbarch, regnum);
- return xstrprintf ("__%s", regname);
+ return string_printf ("__%s", regname);
}
/* See compile/compile-internal.h. */
error (_("Cannot find gdbarch register \"%s\"."), regname);
}
-extern initialize_file_ftype _initialize_compile;
-
void
_initialize_compile (void)
{
" -fno-stack-protector"
);
set_compile_args (compile_args, 0, NULL);
+
+ add_setshow_optional_filename_cmd ("compile-gcc", class_support,
+ &compile_gcc,
+ _("Set compile command "
+ "GCC driver filename"),
+ _("Show compile command "
+ "GCC driver filename"),
+ _("\
+It should be absolute filename of the gcc executable.\n\
+If empty the default target triplet will be searched in $PATH."),
+ NULL, show_compile_gcc, &setlist,
+ &showlist);
+ compile_gcc = xstrdup ("");
}