From: Doug Evans Date: Sat, 30 Nov 2013 05:29:26 +0000 (-0800) Subject: Move .debug_gdb_script processing to auto-load.c. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=5b2bf9471f1499bee578fcd60c05afe85794e280;p=binutils-gdb.git Move .debug_gdb_script processing to auto-load.c. Simplify handling of auto-loaded objfile scripts. .debug_gdb_scripts was always intended to handle more than just python, thus the rightful home for the code that processes it is not in py-foo.c. This is just a cleanup to move the code to a better place. This also simplifies the handling of the ${objfile}-${suffix} auto-loaded scripts. There's no need for each of the the handlers to do is-safe-to-load checking, or call maybe_add_script. Doing it in the caller removes the duplication. * auto-load.h (script_language): New members name, auto_load_enabled. Add missing comments on struct members. (auto_load_objfile_script): Delete. * auto-load.c: #include "cli/cli-cmds.h". (auto_load_gdb_scripts_enabled): New function. (script_language_gdb): Update, add new members. (source_gdb_script_for_objfile): Simplify, auto-load safe-checking and call to maybe_add_script moved to caller. (auto_load_objfile_script_1): Auto-load safe-checking and call to maybe_add_script moved here. (auto_load_objfile_script): Make static. Early exit if support for scripting language hasn't been compiled in, or auto-loading has been disabled. (source_section_scripts): Argument "source_name" renamed to "section_name". All uses updated. Replace uses of AUTO_SECTION_NAME with section_name. Skip loading script if support for scripting language hasn't been compiled in, or auto-loading has been disabled. Call language->source_script_for_objfile instead of calling source_python_script_for_objfile directly. (load_auto_scripts_for_objfile): Update. * python/py-auto-load.c: Delete #include "cli/cli-cmds.h". (gdbpy_load_auto_script_for_objfile): Delete. (auto_load_python_scripts_enabled): New function. (script_language_python): Update, add new members. (gdbpy_script_language_defn): New function. * python/python.h (gdbpy_load_auto_scripts_for_objfile): Delete. (gdbpy_script_language_defn): Declare. * auto-load.c (AUTO_SECTION_NAME): Moved here and renamed from py-auto-load.c, GDBPY_AUTO_SECTION_NAME. (source_section_scripts): Moved here from py-auto-load.c. (auto_load_section_scripts): Ditto. * python/py-auto-load.c (GDBPY_AUTO_SECTION_NAME): Moved to auto-load.c, renamed AUTO_SECTION_NAME. (source_section_scripts, auto_load_section_scripts): Moved to auto-load.c. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 2033b47b5f0..9246e4de480 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,42 @@ +2013-11-30 Doug Evans + + * auto-load.h (script_language): New members name, auto_load_enabled. + Add missing comments on struct members. + (auto_load_objfile_script): Delete. + * auto-load.c: #include "cli/cli-cmds.h". + (auto_load_gdb_scripts_enabled): New function. + (script_language_gdb): Update, add new members. + (source_gdb_script_for_objfile): Simplify, auto-load safe-checking + and call to maybe_add_script moved to caller. + (auto_load_objfile_script_1): Auto-load safe-checking and + call to maybe_add_script moved here. + (auto_load_objfile_script): Make static. Early exit if support for + scripting language hasn't been compiled in, or auto-loading has been + disabled. + (source_section_scripts): Argument "source_name" renamed to + "section_name". All uses updated. Replace uses of AUTO_SECTION_NAME + with section_name. Skip loading script if support for scripting + language hasn't been compiled in, or auto-loading has been disabled. + Call language->source_script_for_objfile instead of calling + source_python_script_for_objfile directly. + (load_auto_scripts_for_objfile): Update. + * python/py-auto-load.c: Delete #include "cli/cli-cmds.h". + (gdbpy_load_auto_script_for_objfile): Delete. + (auto_load_python_scripts_enabled): New function. + (script_language_python): Update, add new members. + (gdbpy_script_language_defn): New function. + * python/python.h (gdbpy_load_auto_scripts_for_objfile): Delete. + (gdbpy_script_language_defn): Declare. + + * auto-load.c (AUTO_SECTION_NAME): Moved here and renamed from + py-auto-load.c, GDBPY_AUTO_SECTION_NAME. + (source_section_scripts): Moved here from py-auto-load.c. + (auto_load_section_scripts): Ditto. + * python/py-auto-load.c (GDBPY_AUTO_SECTION_NAME): Moved to + auto-load.c, renamed AUTO_SECTION_NAME. + (source_section_scripts, auto_load_section_scripts): Moved to + auto-load.c. + 2013-11-30 Yao Qi * remote.c (getpkt_or_notif_sane_1): Fix typo "checksm". diff --git a/gdb/auto-load.c b/gdb/auto-load.c index 2c534c79088..02b08bef762 100644 --- a/gdb/auto-load.c +++ b/gdb/auto-load.c @@ -30,6 +30,7 @@ #include "exceptions.h" #include "cli/cli-script.h" #include "gdbcmd.h" +#include "cli/cli-cmds.h" #include "cli/cli-decode.h" #include "cli/cli-setshow.h" #include "gdb_vecs.h" @@ -40,6 +41,14 @@ #include "top.h" #include "filestuff.h" +/* The section to look in for auto-loaded scripts (in file formats that + support sections). + Each entry in this section is a record that begins with a leading byte + identifying the record type. + At the moment we only support one record type: A leading byte of 1, + followed by the path of a python script to load. */ +#define AUTO_SECTION_NAME ".debug_gdb_scripts" + /* The suffix of per-objfile scripts to auto-load as non-Python command files. E.g. When the program loads libfoo.so, look for libfoo-gdb.gdb. */ #define GDB_AUTO_FILE_NAME "-gdb.gdb" @@ -79,6 +88,14 @@ show_auto_load_gdb_scripts (struct ui_file *file, int from_tty, value); } +/* Return non-zero if auto-loading gdb scripts is enabled. */ + +static int +auto_load_gdb_scripts_enabled (void) +{ + return auto_load_gdb_scripts; +} + /* Internal-use flag to enable/disable auto-loading. This is true if we should auto-load python code when an objfile is opened, false otherwise. @@ -502,31 +519,20 @@ For more information about this security protection see the\n\ /* Definition of script language for GDB canned sequences of commands. */ -static const struct script_language script_language_gdb - = { GDB_AUTO_FILE_NAME, source_gdb_script_for_objfile }; +static const struct script_language script_language_gdb = +{ + "gdb", + GDB_AUTO_FILE_NAME, + auto_load_gdb_scripts_enabled, + source_gdb_script_for_objfile +}; static void source_gdb_script_for_objfile (struct objfile *objfile, FILE *file, const char *filename) { - int is_safe; - struct auto_load_pspace_info *pspace_info; volatile struct gdb_exception e; - is_safe = file_is_auto_load_safe (filename, _("auto-load: Loading canned " - "sequences of commands script " - "\"%s\" for objfile \"%s\".\n"), - filename, objfile_name (objfile)); - - /* Add this script to the hash table too so "info auto-load gdb-scripts" - can print it. */ - pspace_info = get_auto_load_pspace_data_for_loading (current_program_space); - maybe_add_script (pspace_info, is_safe, filename, filename, - &script_language_gdb); - - if (!is_safe) - return; - TRY_CATCH (e, RETURN_MASK_ALL) { script_from_file (file, filename); @@ -780,14 +786,31 @@ auto_load_objfile_script_1 (struct objfile *objfile, const char *realname, if (input) { + int is_safe; + struct auto_load_pspace_info *pspace_info; + make_cleanup_fclose (input); + is_safe + = file_is_auto_load_safe (filename, + _("auto-load: Loading %s script \"%s\"" + " by extension for objfile \"%s\".\n"), + language->name, filename, + objfile_name (objfile)); + + /* Add this script to the hash table too so + "info auto-load ${lang}-scripts" can print it. */ + pspace_info + = get_auto_load_pspace_data_for_loading (current_program_space); + maybe_add_script (pspace_info, is_safe, filename, filename, language); + /* To preserve existing behaviour we don't check for whether the script was already in the table, and always load it. It's highly unlikely that we'd ever load it twice, and these scripts are required to be idempotent under multiple loads anyway. */ - language->source_script_for_objfile (objfile, input, debugfile); + if (is_safe) + language->source_script_for_objfile (objfile, input, debugfile); retval = 1; } @@ -801,12 +824,21 @@ auto_load_objfile_script_1 (struct objfile *objfile, const char *realname, /* Look for the auto-load script in LANGUAGE associated with OBJFILE and load it. */ -void +static void auto_load_objfile_script (struct objfile *objfile, const struct script_language *language) { - char *realname = gdb_realpath (objfile_name (objfile)); - struct cleanup *cleanups = make_cleanup (xfree, realname); + char *realname; + struct cleanup *cleanups; + + /* Skip this script if support has not been compiled in or + auto-loading it has been disabled. */ + if (language == NULL + || !language->auto_load_enabled ()) + return; + + realname = gdb_realpath (objfile_name (objfile)); + cleanups = make_cleanup (xfree, realname); if (!auto_load_objfile_script_1 (objfile, realname, language)) { @@ -831,6 +863,153 @@ auto_load_objfile_script (struct objfile *objfile, do_cleanups (cleanups); } +/* Load scripts specified in OBJFILE. + START,END delimit a buffer containing a list of nul-terminated + file names. + SECTION_NAME is used in error messages. + + Scripts are found per normal "source -s" command processing. + First the script is looked for in $cwd. If not found there the + source search path is used. + + The section contains a list of path names of script files to load. + Each path is null-terminated. */ + +static void +source_section_scripts (struct objfile *objfile, const char *section_name, + const char *start, const char *end) +{ + const char *p; + struct auto_load_pspace_info *pspace_info; + + pspace_info = get_auto_load_pspace_data_for_loading (current_program_space); + + for (p = start; p < end; ++p) + { + const char *file; + FILE *stream; + char *full_path; + int opened, in_hash_table; + struct cleanup *back_to; + /* At the moment we only support python scripts in .debug_gdb_scripts, + but that can change. */ + const struct script_language *language = gdbpy_script_language_defn (); + + if (*p != 1) + { + warning (_("Invalid entry in %s section"), section_name); + /* We could try various heuristics to find the next valid entry, + but it's safer to just punt. */ + break; + } + file = ++p; + + while (p < end && *p != '\0') + ++p; + if (p == end) + { + char *buf = alloca (p - file + 1); + + memcpy (buf, file, p - file); + buf[p - file] = '\0'; + warning (_("Non-null-terminated path in %s: %s"), + section_name, buf); + /* Don't load it. */ + break; + } + if (p == file) + { + warning (_("Empty path in %s"), section_name); + continue; + } + + /* Skip this script if support has not been compiled in or + auto-loading it has been disabled. */ + if (language == NULL + || !language->auto_load_enabled ()) + { + /* No message is printed, just skip it. */ + continue; + } + + opened = find_and_open_script (file, 1 /*search_path*/, + &stream, &full_path); + + back_to = make_cleanup (null_cleanup, NULL); + if (opened) + { + make_cleanup_fclose (stream); + make_cleanup (xfree, full_path); + + if (!file_is_auto_load_safe (full_path, + _("auto-load: Loading %s script " + "\"%s\" from section \"%s\" of " + "objfile \"%s\".\n"), + language->name, full_path, section_name, + objfile_name (objfile))) + opened = 0; + } + else + { + full_path = NULL; + + /* If one script isn't found it's not uncommon for more to not be + found either. We don't want to print a message for each script, + too much noise. Instead, we print the warning once and tell the + user how to find the list of scripts that weren't loaded. + We don't throw an error, the program is still debuggable. + + IWBN if complaints.c were more general-purpose. */ + + if (script_not_found_warning_print (pspace_info)) + warning (_("Missing auto-load scripts referenced in section %s\n\ +of file %s\n\ +Use `info auto-load %s-scripts [REGEXP]' to list them."), + section_name, objfile_name (objfile), language->name); + } + + in_hash_table = maybe_add_script (pspace_info, opened, file, full_path, + language); + + /* If this file is not currently loaded, load it. */ + if (opened && !in_hash_table) + { + gdb_assert (language->source_script_for_objfile != NULL); + language->source_script_for_objfile (objfile, stream, full_path); + } + + do_cleanups (back_to); + } +} + +/* Load scripts specified in section SECTION_NAME of OBJFILE. */ + +static void +auto_load_section_scripts (struct objfile *objfile, const char *section_name) +{ + bfd *abfd = objfile->obfd; + asection *scripts_sect; + bfd_byte *data = NULL; + + scripts_sect = bfd_get_section_by_name (abfd, section_name); + if (scripts_sect == NULL) + return; + + if (!bfd_get_full_section_contents (abfd, scripts_sect, &data)) + warning (_("Couldn't read %s section of %s"), + section_name, bfd_get_filename (abfd)); + else + { + struct cleanup *cleanups; + char *p = (char *) data; + + cleanups = make_cleanup (xfree, p); + source_section_scripts (objfile, section_name, p, + p + bfd_get_section_size (scripts_sect)); + do_cleanups (cleanups); + } +} + /* Load any auto-loaded scripts for OBJFILE. */ void @@ -839,10 +1018,10 @@ load_auto_scripts_for_objfile (struct objfile *objfile) if (!global_auto_load || (objfile->flags & OBJF_NOT_FILENAME) != 0) return; - if (auto_load_gdb_scripts) - auto_load_objfile_script (objfile, &script_language_gdb); + auto_load_objfile_script (objfile, &script_language_gdb); + auto_load_objfile_script (objfile, gdbpy_script_language_defn ()); - gdbpy_load_auto_scripts_for_objfile (objfile); + auto_load_section_scripts (objfile, AUTO_SECTION_NAME); } /* This is a new_objfile observer callback to auto-load scripts. diff --git a/gdb/auto-load.h b/gdb/auto-load.h index 6a666229dd4..2ddebc57608 100644 --- a/gdb/auto-load.h +++ b/gdb/auto-load.h @@ -24,8 +24,18 @@ struct program_space; struct script_language { + /* The name of the language, lowercase. */ + const char *name; + + /* The suffix added to objfiles to get their auto-load script. + E.g., "-gdb.py". */ const char *suffix; + /* Returns non-zero if auto-loading scripts in this language is enabled. */ + int (*auto_load_enabled) (void); + + /* Worker routine to load the script. It has already been opened and + deemed safe to load. */ void (*source_script_for_objfile) (struct objfile *objfile, FILE *file, const char *filename); }; @@ -42,8 +52,6 @@ extern int maybe_add_script (struct auto_load_pspace_info *pspace_info, int loaded, const char *name, const char *full_path, const struct script_language *language); -extern void auto_load_objfile_script (struct objfile *objfile, - const struct script_language *language); extern void load_auto_scripts_for_objfile (struct objfile *objfile); extern int script_not_found_warning_print (struct auto_load_pspace_info *pspace_info); diff --git a/gdb/python/py-auto-load.c b/gdb/python/py-auto-load.c index 827918a7fde..d5450b37bc6 100644 --- a/gdb/python/py-auto-load.c +++ b/gdb/python/py-auto-load.c @@ -24,30 +24,18 @@ #include "gdbcmd.h" #include "objfiles.h" #include "python.h" -#include "cli/cli-cmds.h" #include "auto-load.h" #ifdef HAVE_PYTHON #include "python-internal.h" -/* The section to look for Python auto-loaded scripts (in file formats that - support sections). - Each entry in this section is a byte of value 1, and then the nul-terminated - name of the script. The script name may include a directory. - The leading byte is to allow upward compatible extensions. */ -#define GDBPY_AUTO_SECTION_NAME ".debug_gdb_scripts" - /* User-settable option to enable/disable auto-loading of Python scripts: set auto-load python-scripts on|off This is true if we should auto-load associated Python scripts when an objfile is opened, false otherwise. */ static int auto_load_python_scripts = 1; -static void gdbpy_load_auto_script_for_objfile (struct objfile *objfile, - FILE *file, - const char *filename); - /* "show" command for the auto_load_python_scripts configuration variable. */ static void @@ -57,177 +45,30 @@ show_auto_load_python_scripts (struct ui_file *file, int from_tty, fprintf_filtered (file, _("Auto-loading of Python scripts is %s.\n"), value); } -/* Definition of script language for Python scripts. */ - -static const struct script_language script_language_python - = { GDBPY_AUTO_FILE_NAME, gdbpy_load_auto_script_for_objfile }; - -/* Wrapper of source_python_script_for_objfile for script_language_python. */ +/* Return non-zero if auto-loading Python scripts is enabled. */ -static void -gdbpy_load_auto_script_for_objfile (struct objfile *objfile, FILE *file, - const char *filename) +static int +auto_load_python_scripts_enabled (void) { - int is_safe; - struct auto_load_pspace_info *pspace_info; - - is_safe = file_is_auto_load_safe (filename, - _("auto-load: Loading Python script \"%s\" " - "by extension for objfile \"%s\".\n"), - filename, objfile_name (objfile)); - - /* Add this script to the hash table too so "info auto-load python-scripts" - can print it. */ - pspace_info = get_auto_load_pspace_data_for_loading (current_program_space); - maybe_add_script (pspace_info, is_safe, filename, filename, - &script_language_python); - - if (is_safe) - source_python_script_for_objfile (objfile, file, filename); + return auto_load_python_scripts; } -/* Load scripts specified in OBJFILE. - START,END delimit a buffer containing a list of nul-terminated - file names. - SOURCE_NAME is used in error messages. - - Scripts are found per normal "source -s" command processing. - First the script is looked for in $cwd. If not found there the - source search path is used. - - The section contains a list of path names of files containing - python code to load. Each path is null-terminated. */ - -static void -source_section_scripts (struct objfile *objfile, const char *source_name, - const char *start, const char *end) -{ - const char *p; - struct auto_load_pspace_info *pspace_info; - - pspace_info = get_auto_load_pspace_data_for_loading (current_program_space); - - for (p = start; p < end; ++p) - { - const char *file; - FILE *stream; - char *full_path; - int opened, in_hash_table; - struct cleanup *back_to; - - if (*p != 1) - { - warning (_("Invalid entry in %s section"), GDBPY_AUTO_SECTION_NAME); - /* We could try various heuristics to find the next valid entry, - but it's safer to just punt. */ - break; - } - file = ++p; - - while (p < end && *p != '\0') - ++p; - if (p == end) - { - char *buf = alloca (p - file + 1); - - memcpy (buf, file, p - file); - buf[p - file] = '\0'; - warning (_("Non-null-terminated path in %s: %s"), - source_name, buf); - /* Don't load it. */ - break; - } - if (p == file) - { - warning (_("Empty path in %s"), source_name); - continue; - } - - opened = find_and_open_script (file, 1 /*search_path*/, - &stream, &full_path); - - back_to = make_cleanup (null_cleanup, NULL); - if (opened) - { - make_cleanup_fclose (stream); - make_cleanup (xfree, full_path); - - if (!file_is_auto_load_safe (full_path, - _("auto-load: Loading Python script " - "\"%s\" from section \"%s\" of " - "objfile \"%s\".\n"), - full_path, GDBPY_AUTO_SECTION_NAME, - objfile_name (objfile))) - opened = 0; - } - else - { - full_path = NULL; - - /* If one script isn't found it's not uncommon for more to not be - found either. We don't want to print a message for each script, - too much noise. Instead, we print the warning once and tell the - user how to find the list of scripts that weren't loaded. - We don't throw an error, the program is still debuggable. - - IWBN if complaints.c were more general-purpose. */ - - if (script_not_found_warning_print (pspace_info)) - warning (_("Missing auto-load scripts referenced in section %s\n\ -of file %s\n\ -Use `info auto-load python [REGEXP]' to list them."), - GDBPY_AUTO_SECTION_NAME, objfile_name (objfile)); - } - - in_hash_table = maybe_add_script (pspace_info, opened, file, full_path, - &script_language_python); - - /* If this file is not currently loaded, load it. */ - if (opened && !in_hash_table) - source_python_script_for_objfile (objfile, stream, full_path); - - do_cleanups (back_to); - } -} - -/* Load scripts specified in section SECTION_NAME of OBJFILE. */ +/* Definition of script language for Python scripts. */ -static void -auto_load_section_scripts (struct objfile *objfile, const char *section_name) +static const struct script_language script_language_python = { - bfd *abfd = objfile->obfd; - asection *scripts_sect; - bfd_byte *data = NULL; - - scripts_sect = bfd_get_section_by_name (abfd, section_name); - if (scripts_sect == NULL) - return; + "python", + GDBPY_AUTO_FILE_NAME, + auto_load_python_scripts_enabled, + source_python_script_for_objfile +}; - if (!bfd_get_full_section_contents (abfd, scripts_sect, &data)) - warning (_("Couldn't read %s section of %s"), - section_name, bfd_get_filename (abfd)); - else - { - struct cleanup *cleanups; - char *p = (char *) data; +/* Return the Python script language definition. */ - cleanups = make_cleanup (xfree, p); - source_section_scripts (objfile, section_name, p, - p + bfd_get_section_size (scripts_sect)); - do_cleanups (cleanups); - } -} - -/* Load any Python auto-loaded scripts for OBJFILE. */ - -void -gdbpy_load_auto_scripts_for_objfile (struct objfile *objfile) +const struct script_language * +gdbpy_script_language_defn (void) { - if (auto_load_python_scripts) - { - auto_load_objfile_script (objfile, &script_language_python); - auto_load_section_scripts (objfile, GDBPY_AUTO_SECTION_NAME); - } + return &script_language_python; } /* Wrapper for "info auto-load python-scripts". */ @@ -287,9 +128,13 @@ Print the list of automatically loaded Python scripts, deprecated.")); #else /* ! HAVE_PYTHON */ -void -gdbpy_load_auto_scripts_for_objfile (struct objfile *objfile) +/* Return the Python script language definition. + Since support isn't compiled in, return NULL. */ + +const struct script_language * +gdbpy_script_language_defn (void) { + return NULL; } #endif /* ! HAVE_PYTHON */ diff --git a/gdb/python/python.h b/gdb/python/python.h index 047fb4c9f21..c07b2aa719c 100644 --- a/gdb/python/python.h +++ b/gdb/python/python.h @@ -109,7 +109,7 @@ enum py_bt_status apply_frame_filter (struct frame_info *frame, int flags, void preserve_python_values (struct objfile *objfile, htab_t copied_types); -void gdbpy_load_auto_scripts_for_objfile (struct objfile *objfile); +const struct script_language *gdbpy_script_language_defn (void); int gdbpy_should_stop (struct gdbpy_breakpoint_object *bp_obj);