X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fcompile%2Fcompile.c;h=bca7b57ea2e9b95c284f1770751a77a938f0937d;hb=773a1edcd1086fc76a91055bec67e2d14d76940d;hp=d3ce3ba289d54d7ce89e6410216ee8bf4d55f97b;hpb=8d7493201cf01c9836403695f67f7e157341bfd5;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/compile/compile.c b/gdb/compile/compile.c index d3ce3ba289..bca7b57ea2 100644 --- a/gdb/compile/compile.c +++ b/gdb/compile/compile.c @@ -1,6 +1,6 @@ /* General Compile and inject code - Copyright (C) 2014-2015 Free Software Foundation, Inc. + Copyright (C) 2014-2017 Free Software Foundation, Inc. This file is part of GDB. @@ -18,7 +18,7 @@ along with this program. If not, see . */ #include "defs.h" -#include "interps.h" +#include "top.h" #include "ui-out.h" #include "command.h" #include "cli/cli-script.h" @@ -39,6 +39,8 @@ #include "osabi.h" #include "gdb_wait.h" #include "valprint.h" +#include "common/gdb_optional.h" +#include "common/gdb_unlinker.h" @@ -91,8 +93,7 @@ compile_file_command (char *arg, int from_tty) char *buffer; struct cleanup *cleanup; - cleanup = make_cleanup_restore_integer (&interpreter_async); - interpreter_async = 0; + scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0); /* Check the user did not just after command. */ if (arg == NULL) @@ -115,7 +116,7 @@ compile_file_command (char *arg, int from_tty) arg = skip_spaces (arg); arg = gdb_abspath (arg); - make_cleanup (xfree, arg); + cleanup = make_cleanup (xfree, arg); buffer = xstrprintf ("#include \"%s\"\n", arg); make_cleanup (xfree, buffer); eval_compile_command (NULL, buffer, scope, NULL); @@ -130,11 +131,9 @@ compile_file_command (char *arg, int from_tty) static void compile_code_command (char *arg, int from_tty) { - struct cleanup *cleanup; enum compile_i_scope_types scope = COMPILE_I_SIMPLE_SCOPE; - cleanup = make_cleanup_restore_integer (&interpreter_async); - interpreter_async = 0; + scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0); if (arg != NULL && check_raw_argument (&arg)) { @@ -154,14 +153,11 @@ compile_code_command (char *arg, int from_tty) eval_compile_command (NULL, arg, scope, NULL); else { - struct command_line *l = get_command_line (compile_control, ""); + command_line_up l = get_command_line (compile_control, ""); - make_cleanup_free_command_lines (&l); l->control_u.compile.scope = scope; - execute_control_command_untraced (l); + execute_control_command_untraced (l.get ()); } - - do_cleanups (cleanup); } /* Callback for compile_print_command. */ @@ -169,7 +165,7 @@ compile_code_command (char *arg, int from_tty) void compile_print_value (struct value *val, void *data_voidp) { - const struct format_data *fmtp = data_voidp; + const struct format_data *fmtp = (const struct format_data *) data_voidp; print_value (val, fmtp); } @@ -183,12 +179,10 @@ static void compile_print_command (char *arg_param, int from_tty) { const char *arg = arg_param; - struct cleanup *cleanup; enum compile_i_scope_types scope = COMPILE_I_PRINT_ADDRESS_SCOPE; struct format_data fmt; - cleanup = make_cleanup_restore_integer (&interpreter_async); - interpreter_async = 0; + scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0); /* Passing &FMT as SCOPE_DATA is safe as do_module_cleanup will not touch the stale pointer if compile_object_run has already quit. */ @@ -198,15 +192,12 @@ compile_print_command (char *arg_param, int from_tty) eval_compile_command (NULL, arg, scope, &fmt); else { - struct command_line *l = get_command_line (compile_control, ""); + command_line_up l = get_command_line (compile_control, ""); - make_cleanup_free_command_lines (&l); l->control_u.compile.scope = scope; l->control_u.compile.scope_data = &fmt; - execute_control_command_untraced (l); + execute_control_command_untraced (l.get ()); } - - do_cleanups (cleanup); } /* A cleanup function to remove a directory and all its contents. */ @@ -214,7 +205,7 @@ compile_print_command (char *arg_param, int from_tty) static void do_rmdir (void *arg) { - const char *dir = arg; + const char *dir = (const char *) arg; char *zap; int wstat; @@ -255,18 +246,20 @@ get_compile_file_tempdir (void) return tempdir_name; } -/* Compute the names of source and object files to use. The names are - allocated by malloc and should be freed by the caller. */ +/* Compute the names of source and object files to use. */ -static void -get_new_file_names (char **source_file, char **object_file) +static compile_file_names +get_new_file_names () { static int seq; const char *dir = get_compile_file_tempdir (); ++seq; - *source_file = xstrprintf ("%s%sout%d.c", dir, SLASH_STRING, seq); - *object_file = xstrprintf ("%s%sout%d.o", dir, SLASH_STRING, seq); + + return compile_file_names (string_printf ("%s%sout%d.c", + dir, SLASH_STRING, seq), + string_printf ("%s%sout%d.o", + dir, SLASH_STRING, seq)); } /* Get the block and PC at which to evaluate an expression. */ @@ -292,15 +285,17 @@ get_expr_block_and_pc (CORE_ADDR *pc) return block; } -/* Call gdb_buildargv, set its result for S into *ARGVP but calculate also the - number of parsed arguments into *ARGCP. If gdb_buildargv has returned NULL - then *ARGCP is set to zero. */ +/* Call buildargv (via gdb_argv), set its result for S into *ARGVP but + calculate also the number of parsed arguments into *ARGCP. If + buildargv has returned NULL then *ARGCP is set to zero. */ static void build_argc_argv (const char *s, int *argcp, char ***argvp) { - *argvp = gdb_buildargv (s); - *argcp = countargv (*argvp); + gdb_argv args (s); + + *argcp = args.count (); + *argvp = args.release (); } /* String for 'set compile-args' and 'show compile-args'. */ @@ -431,21 +426,11 @@ get_args (const struct compile_instance *compiler, struct gdbarch *gdbarch, static void cleanup_compile_instance (void *arg) { - struct compile_instance *inst = arg; + struct compile_instance *inst = (struct compile_instance *) arg; inst->destroy (inst); } -/* A cleanup function to unlink a file. */ - -static void -cleanup_unlink_file (void *arg) -{ - const char *filename = arg; - - unlink (filename); -} - /* A helper function suitable for use as the "print_callback" in the compiler object. */ @@ -456,20 +441,15 @@ print_callback (void *ignore, const char *message) } /* Process the compilation request. On success it returns the object - file name and *SOURCE_FILEP is set to source file name. On an - error condition, error () is called. The caller is responsible for - freeing both strings. */ + and source file names. On an error condition, error () is + called. */ -static char * +static compile_file_names compile_to_object (struct command_line *cmd, const char *cmd_string, - enum compile_i_scope_types scope, - char **source_filep) + enum compile_i_scope_types scope) { - char *code; - const char *input; - char *source_file, *object_file; struct compile_instance *compiler; - struct cleanup *cleanup, *inner_cleanup; + struct cleanup *cleanup; const struct block *expr_block; CORE_ADDR trash_pc, expr_pc; int argc; @@ -491,7 +471,8 @@ compile_to_object (struct command_line *cmd, const char *cmd_string, /* Set up instance and context for the compiler. */ if (current_language->la_get_compile_instance == NULL) - error (_("No compiler support for this language.")); + error (_("No compiler support for language %s."), + current_language->la_name); compiler = current_language->la_get_compile_instance (); cleanup = make_cleanup (cleanup_compile_instance, compiler); @@ -502,33 +483,32 @@ compile_to_object (struct command_line *cmd, const char *cmd_string, /* From the provided expression, build a scope to pass to the compiler. */ + + string_file input_buf; + const char *input; + if (cmd != NULL) { - struct ui_file *stream = mem_fileopen (); struct command_line *iter; - char *stream_buf; - make_cleanup_ui_file_delete (stream); for (iter = cmd->body_list[0]; iter; iter = iter->next) { - fputs_unfiltered (iter->line, stream); - fputs_unfiltered ("\n", stream); + input_buf.puts (iter->line); + input_buf.puts ("\n"); } - stream_buf = ui_file_xstrdup (stream, NULL); - make_cleanup (xfree, stream_buf); - input = stream_buf; + input = input_buf.c_str (); } else if (cmd_string != NULL) input = cmd_string; else error (_("Neither a simple expression, or a multi-line specified.")); - code = current_language->la_compute_program (compiler, input, gdbarch, - expr_block, expr_pc); - make_cleanup (xfree, code); + std::string code + = current_language->la_compute_program (compiler, input, gdbarch, + expr_block, expr_pc); if (compile_debug) - fprintf_unfiltered (gdb_stdlog, "debug output:\n\n%s", code); + 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); @@ -539,7 +519,7 @@ compile_to_object (struct command_line *cmd, const char *cmd_string, /* Set compiler command-line arguments. */ get_args (compiler, gdbarch, &argc, &argv); - make_cleanup_freeargv (argv); + gdb_argv argv_holder (argv); error_message = compiler->fe->ops->set_arguments (compiler->fe, triplet_rx, argc, argv); @@ -559,37 +539,42 @@ compile_to_object (struct command_line *cmd, const char *cmd_string, argi, argv[argi]); } - get_new_file_names (&source_file, &object_file); - inner_cleanup = make_cleanup (xfree, source_file); - make_cleanup (xfree, object_file); + compile_file_names fnames = get_new_file_names (); - src = gdb_fopen_cloexec (source_file, "w"); - if (src == NULL) - perror_with_name (_("Could not open source file for writing")); - make_cleanup (cleanup_unlink_file, source_file); - if (fputs (code, src) == EOF) - perror_with_name (_("Could not write to source file")); - fclose (src); + gdb::optional source_remover; + + { + gdb_file_up src = gdb_fopen_cloexec (fnames.source_file (), "w"); + if (src == NULL) + perror_with_name (_("Could not open source file for writing")); + + source_remover.emplace (fnames.source_file ()); + + if (fputs (code.c_str (), src.get ()) == EOF) + perror_with_name (_("Could not write to source file")); + } if (compile_debug) fprintf_unfiltered (gdb_stdlog, "source file produced: %s\n\n", - source_file); + fnames.source_file ()); /* Call the compiler and start the compilation process. */ - compiler->fe->ops->set_source_file (compiler->fe, source_file); + compiler->fe->ops->set_source_file (compiler->fe, fnames.source_file ()); - if (!compiler->fe->ops->compile (compiler->fe, object_file, + if (!compiler->fe->ops->compile (compiler->fe, fnames.object_file (), compile_debug)) error (_("Compilation failed.")); if (compile_debug) fprintf_unfiltered (gdb_stdlog, "object file produced: %s\n\n", - object_file); + fnames.object_file ()); + + /* Keep the source file. */ + source_remover->keep (); - discard_cleanups (inner_cleanup); do_cleanups (cleanup); - *source_filep = source_file; - return object_file; + + return fnames; } /* The "compile" prefix command. */ @@ -608,32 +593,27 @@ void eval_compile_command (struct command_line *cmd, const char *cmd_string, enum compile_i_scope_types scope, void *scope_data) { - char *object_file, *source_file; + struct compile_module *compile_module; + + compile_file_names fnames = compile_to_object (cmd, cmd_string, scope); - object_file = compile_to_object (cmd, cmd_string, scope, &source_file); - if (object_file != NULL) + gdb::unlinker object_remover (fnames.object_file ()); + gdb::unlinker source_remover (fnames.source_file ()); + + compile_module = compile_object_load (fnames, scope, scope_data); + if (compile_module == NULL) { - struct cleanup *cleanup_xfree, *cleanup_unlink; - struct compile_module *compile_module; - - cleanup_xfree = make_cleanup (xfree, object_file); - make_cleanup (xfree, source_file); - cleanup_unlink = make_cleanup (cleanup_unlink_file, object_file); - make_cleanup (cleanup_unlink_file, source_file); - compile_module = compile_object_load (object_file, source_file, - scope, scope_data); - if (compile_module == NULL) - { - gdb_assert (scope == COMPILE_I_PRINT_ADDRESS_SCOPE); - do_cleanups (cleanup_xfree); - eval_compile_command (cmd, cmd_string, - COMPILE_I_PRINT_VALUE_SCOPE, scope_data); - return; - } - discard_cleanups (cleanup_unlink); - do_cleanups (cleanup_xfree); - compile_object_run (compile_module); + gdb_assert (scope == COMPILE_I_PRINT_ADDRESS_SCOPE); + eval_compile_command (cmd, cmd_string, + COMPILE_I_PRINT_VALUE_SCOPE, scope_data); + return; } + + /* Keep the files. */ + source_remover.keep (); + object_remover.keep (); + + compile_object_run (compile_module); } /* See compile/compile-internal.h. */