diff options
Diffstat (limited to 'gdb/compile/compile.c')
-rw-r--r-- | gdb/compile/compile.c | 241 |
1 files changed, 85 insertions, 156 deletions
diff --git a/gdb/compile/compile.c b/gdb/compile/compile.c index 89f9790..229e155 100644 --- a/gdb/compile/compile.c +++ b/gdb/compile/compile.c @@ -1,6 +1,6 @@ /* General Compile and inject code - Copyright (C) 2014-2024 Free Software Foundation, Inc. + Copyright (C) 2014-2025 Free Software Foundation, Inc. This file is part of GDB. @@ -46,126 +46,30 @@ #include "gdbsupport/scoped_ignore_signal.h" #include "gdbsupport/buildargv.h" +/* Hold "compile" commands. */ + +static struct cmd_list_element *compile_command_list; + +#ifdef HAVE_COMPILE /* Initial filename for temporary files. */ #define TMP_PREFIX "/tmp/gdbobj-" -/* Hold "compile" commands. */ - -static struct cmd_list_element *compile_command_list; - /* Debug flag for "compile" commands. */ bool compile_debug; -/* Object of this type are stored in the compiler's symbol_err_map. */ - -struct symbol_error -{ - /* The symbol. */ - - const struct symbol *sym; - - /* The error message to emit. This is malloc'd and owned by the - hash table. */ - - char *message; -}; - -/* An object that maps a gdb type to a gcc type. */ - -struct type_map_instance -{ - /* The gdb type. */ - - struct type *type; - - /* The corresponding gcc type handle. */ - - gcc_type gcc_type_handle; -}; - -/* Hash a type_map_instance. */ - -static hashval_t -hash_type_map_instance (const void *p) -{ - const struct type_map_instance *inst = (const struct type_map_instance *) p; - - return htab_hash_pointer (inst->type); -} - -/* Check two type_map_instance objects for equality. */ - -static int -eq_type_map_instance (const void *a, const void *b) -{ - const struct type_map_instance *insta = (const struct type_map_instance *) a; - const struct type_map_instance *instb = (const struct type_map_instance *) b; - - return insta->type == instb->type; -} - -/* Hash function for struct symbol_error. */ - -static hashval_t -hash_symbol_error (const void *a) -{ - const struct symbol_error *se = (const struct symbol_error *) a; - - return htab_hash_pointer (se->sym); -} - -/* Equality function for struct symbol_error. */ - -static int -eq_symbol_error (const void *a, const void *b) -{ - const struct symbol_error *sea = (const struct symbol_error *) a; - const struct symbol_error *seb = (const struct symbol_error *) b; - - return sea->sym == seb->sym; -} - -/* Deletion function for struct symbol_error. */ - -static void -del_symbol_error (void *a) -{ - struct symbol_error *se = (struct symbol_error *) a; - - xfree (se->message); - xfree (se); -} - -/* Constructor for compile_instance. */ - -compile_instance::compile_instance (struct gcc_base_context *gcc_fe, - const char *options) - : m_gcc_fe (gcc_fe), m_gcc_target_options (options), - m_type_map (htab_create_alloc (10, hash_type_map_instance, - eq_type_map_instance, - xfree, xcalloc, xfree)), - m_symbol_err_map (htab_create_alloc (10, hash_symbol_error, - eq_symbol_error, del_symbol_error, - xcalloc, xfree)) -{ -} - /* See compile-internal.h. */ bool compile_instance::get_cached_type (struct type *type, gcc_type *ret) const { - struct type_map_instance inst, *found; - - inst.type = type; - found = (struct type_map_instance *) htab_find (m_type_map.get (), &inst); - if (found != NULL) + if (auto iter = m_type_map.find (type); + iter != m_type_map.end ()) { - *ret = found->gcc_type_handle; + *ret = iter->second; return true; } @@ -177,25 +81,12 @@ compile_instance::get_cached_type (struct type *type, gcc_type *ret) const void compile_instance::insert_type (struct type *type, gcc_type gcc_type) { - struct type_map_instance inst, *add; - void **slot; - - inst.type = type; - inst.gcc_type_handle = gcc_type; - slot = htab_find_slot (m_type_map.get (), &inst, INSERT); + auto [it, inserted] = m_type_map.emplace (type, gcc_type); - add = (struct type_map_instance *) *slot; /* The type might have already been inserted in order to handle recursive types. */ - if (add != NULL && add->gcc_type_handle != gcc_type) + if (!inserted && it->second != gcc_type) error (_("Unexpected type id from GCC, check you use recent enough GCC.")); - - if (add == NULL) - { - add = XNEW (struct type_map_instance); - *add = inst; - *slot = add; - } } /* See compile-internal.h. */ @@ -204,19 +95,7 @@ void compile_instance::insert_symbol_error (const struct symbol *sym, const char *text) { - struct symbol_error e; - void **slot; - - e.sym = sym; - slot = htab_find_slot (m_symbol_err_map.get (), &e, INSERT); - if (*slot == NULL) - { - struct symbol_error *ep = XNEW (struct symbol_error); - - ep->sym = sym; - ep->message = xstrdup (text); - *slot = ep; - } + m_symbol_err_map.emplace (sym, text); } /* See compile-internal.h. */ @@ -224,20 +103,12 @@ compile_instance::insert_symbol_error (const struct symbol *sym, void compile_instance::error_symbol_once (const struct symbol *sym) { - struct symbol_error search; - struct symbol_error *err; - - if (m_symbol_err_map == NULL) - return; - - search.sym = sym; - err = (struct symbol_error *) htab_find (m_symbol_err_map.get (), &search); - if (err == NULL || err->message == NULL) - return; - - gdb::unique_xmalloc_ptr<char> message (err->message); - err->message = NULL; - error (_("%s"), message.get ()); + if (auto iter = m_symbol_err_map.find (sym); + iter != m_symbol_err_map.end () && !iter->second.empty ()) + { + std::string message = std::move (iter->second); + error (_("%s"), message.c_str ()); + } } /* Implement "show debug compile". */ @@ -657,6 +528,41 @@ print_callback (void *ignore, const char *message) gdb_puts (message, gdb_stderr); } +/* Helper for compile_to_object, to find the compile context + based on the current language. */ +static std::unique_ptr<compile_instance> +get_language_compile_context () +{ + switch (current_language->la_language) + { + case language_c: + return c_get_compile_context (); + case language_cplus: + return cplus_get_compile_context (); + default: + return {}; + } +} + +/* Helper for compile_to_object, to call the correct + compute_program based on the current language. */ +static std::string +compute_program_language (compile_instance *inst, const char *input, + struct gdbarch *gdbarch, + const struct block *block, + CORE_ADDR pc) +{ + switch (current_language->la_language) + { + case language_c: + return c_compute_program (inst, input, gdbarch, block, pc); + case language_cplus: + return cplus_compute_program (inst, input, gdbarch, block, pc); + default: + gdb_assert_not_reached ("Unsupported language"); + } +} + /* Process the compilation request. On success it returns the object and source file names. On an error condition, error () is called. */ @@ -680,7 +586,8 @@ compile_to_object (struct command_line *cmd, const char *cmd_string, /* Set up instance and context for the compiler. */ std::unique_ptr<compile_instance> compiler - = current_language->get_compile_instance (); + = get_language_compile_context (); + if (compiler == nullptr) error (_("No compiler support for language %s."), current_language->name ()); @@ -712,8 +619,8 @@ compile_to_object (struct command_line *cmd, const char *cmd_string, error (_("Neither a simple expression, or a multi-line specified.")); std::string code - = current_language->compute_program (compiler.get (), input, gdbarch, - expr_block, expr_pc); + = compute_program_language (compiler.get (), input, gdbarch, + expr_block, expr_pc); if (compile_debug) gdb_printf (gdb_stdlog, "debug output:\n\n%s", code.c_str ()); @@ -946,21 +853,42 @@ compile_instance::compile (const char *filename, int verbose_level) #undef FORWARD +#else /* HAVE_COMPILE */ + +/* The "compile" prefix command, when support was disabled. */ + +static void +compile_command (const char *args, int from_tty) +{ + error (_("This command is not supported.")); +} + +#endif /* HAVE_COMPILE */ + /* See compile.h. */ cmd_list_element *compile_cmd_element = nullptr; -void _initialize_compile (); -void -_initialize_compile () +INIT_GDB_FILE (compile) { - struct cmd_list_element *c = NULL; - compile_cmd_element = add_prefix_cmd ("compile", class_obscure, - compile_command, _("\ + compile_command, +#ifdef HAVE_COMPILE + _("\ Command to compile source code and inject it into the inferior."), +#else /* HAVE_COMPILE */ + _("\ +Command to compile source code and inject it into the inferior.\n\ +\n\ +Code compilation and injection is not supported in this copy of GDB.\n\ +This command is only a placeholder."), +#endif /* HAVE_COMPILE */ &compile_command_list, 1, &cmdlist); add_com_alias ("expression", compile_cmd_element, class_obscure, 0); +#ifdef HAVE_COMPILE + + struct cmd_list_element *c = NULL; + const auto compile_opts = make_compile_options_def_group (nullptr); static const std::string compile_code_help @@ -1067,4 +995,5 @@ 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); +#endif /* HAVE_COMPILE */ } |