From 08451779f969455df3b5f16e872f5e698ca794f9 Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Wed, 18 Apr 2012 02:17:28 +0200 Subject: [PATCH] Security fix for loading untrusted inferiors, see "set auto-load" (BZ 756117). --- gdb-6.3-security-errata-20050610.patch | 243 ---- gdb-autoload-01of12.patch | 65 + gdb-autoload-02of12.patch | 103 ++ gdb-autoload-03of12.patch | 215 +++ gdb-autoload-04of12.patch | 141 ++ gdb-autoload-05of12.patch | 244 ++++ gdb-autoload-06of12.patch | 71 + gdb-autoload-07of12.patch | 57 + gdb-autoload-08of12.patch | 171 +++ gdb-autoload-09of12.patch | 1168 ++++++++++++++++ gdb-autoload-10of12.patch | 1704 ++++++++++++++++++++++++ gdb-autoload-11of12.patch | 744 +++++++++++ gdb-autoload-12of12.patch | 352 +++++ gdb.spec | 42 +- 14 files changed, 5071 insertions(+), 249 deletions(-) delete mode 100644 gdb-6.3-security-errata-20050610.patch create mode 100644 gdb-autoload-01of12.patch create mode 100644 gdb-autoload-02of12.patch create mode 100644 gdb-autoload-03of12.patch create mode 100644 gdb-autoload-04of12.patch create mode 100644 gdb-autoload-05of12.patch create mode 100644 gdb-autoload-06of12.patch create mode 100644 gdb-autoload-07of12.patch create mode 100644 gdb-autoload-08of12.patch create mode 100644 gdb-autoload-09of12.patch create mode 100644 gdb-autoload-10of12.patch create mode 100644 gdb-autoload-11of12.patch create mode 100644 gdb-autoload-12of12.patch diff --git a/gdb-6.3-security-errata-20050610.patch b/gdb-6.3-security-errata-20050610.patch deleted file mode 100644 index 8e048d8..0000000 --- a/gdb-6.3-security-errata-20050610.patch +++ /dev/null @@ -1,243 +0,0 @@ -http://sourceware.org/ml/gdb-patches/2005-05/threads.html#00637 -Proposed upstream but never committed upstream. - -2005-06-09 Jeff Johnston - - * gdb.base/gdbinit.exp: New testcase. - * gdb.base/gdbinit.sample: Sample .gdbinit for gdbinit.exp. - -2005-06-08 Daniel Jacobowitz - Jeff Johnston - - * Makefile.in (cli-cmds.o): Update. - * configure.in: Add check for getuid. - * configure: Regenerated. - * config.in: Ditto. - * main.c (captured_main): Pass -1 to source_command when loading - gdbinit files. - * cli/cli-cmds.c: Include "gdb_stat.h" and . - (source_command): Update documentation. Check permissions if - FROM_TTY is -1. - -Index: gdb-7.4.50.20111218/gdb/cli/cli-cmds.c -=================================================================== ---- gdb-7.4.50.20111218.orig/gdb/cli/cli-cmds.c 2011-12-16 22:17:42.000000000 +0100 -+++ gdb-7.4.50.20111218/gdb/cli/cli-cmds.c 2011-12-19 00:27:16.572468926 +0100 -@@ -40,6 +40,7 @@ - #include "source.h" - #include "disasm.h" - #include "tracepoint.h" -+#include "gdb_stat.h" - - #include "ui-out.h" - -@@ -485,7 +486,7 @@ show_script_ext_mode (struct ui_file *fi - - int - find_and_open_script (const char *script_file, int search_path, -- FILE **streamp, char **full_pathp) -+ FILE **streamp, char **full_pathp, int from_tty) - { - char *file; - int fd; -@@ -511,6 +512,32 @@ find_and_open_script (const char *script - return 0; - } - -+#ifdef HAVE_GETUID -+ if (from_tty == -1) -+ { -+ struct stat statbuf; -+ -+ if (fstat (fd, &statbuf) < 0) -+ { -+ int save_errno = errno; -+ -+ close (fd); -+ do_cleanups (old_cleanups); -+ errno = save_errno; -+ return 0; -+ } -+ if (statbuf.st_uid != getuid () || (statbuf.st_mode & S_IWOTH)) -+ { -+ /* FILE gets freed by do_cleanups (old_cleanups). */ -+ warning (_("not using untrusted file \"%s\""), file); -+ close (fd); -+ do_cleanups (old_cleanups); -+ errno = EPERM; -+ return 0; -+ } -+ } -+#endif -+ - do_cleanups (old_cleanups); - - *streamp = fdopen (fd, FOPEN_RT); -@@ -572,13 +599,14 @@ source_script_with_search (const char *f - if (file == NULL || *file == 0) - error (_("source command requires file name of file to source.")); - -- if (!find_and_open_script (file, search_path, &stream, &full_path)) -+ if (!find_and_open_script (file, search_path, &stream, &full_path, -+ from_tty)) - { - /* The script wasn't found, or was otherwise inaccessible. - If the source command was invoked interactively, throw an - error. Otherwise (e.g. if it was invoked by a script), - silently ignore the error. */ -- if (from_tty) -+ if (from_tty > 0) - perror_with_name (file); - else - return; -Index: gdb-7.4.50.20111218/gdb/testsuite/gdb.base/gdbinit.exp -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ gdb-7.4.50.20111218/gdb/testsuite/gdb.base/gdbinit.exp 2011-12-19 00:25:26.079891954 +0100 -@@ -0,0 +1,91 @@ -+# Copyright 2005 -+# Free Software Foundation, Inc. -+ -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program; if not, write to the Free Software -+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ -+# Please email any bugs, comments, and/or additions to this file to: -+# bug-gdb@prep.ai.mit.edu -+ -+# This file was written by Jeff Johnston . -+ -+# are we on a target board -+if [is_remote target] { -+ return -+} -+ -+ -+global verbose -+global GDB -+global GDBFLAGS -+global gdb_prompt -+global timeout -+global gdb_spawn_id; -+ -+gdb_stop_suppressing_tests; -+ -+verbose "Spawning $GDB -nw" -+ -+if [info exists gdb_spawn_id] { -+ return 0; -+} -+ -+if ![is_remote host] { -+ if { [which $GDB] == 0 } then { -+ perror "$GDB does not exist." -+ exit 1 -+ } -+} -+ -+set env(HOME) [pwd] -+remote_exec build "rm .gdbinit" -+remote_exec build "cp ${srcdir}/${subdir}/gdbinit.sample .gdbinit" -+remote_exec build "chmod 646 .gdbinit" -+ -+set res [remote_spawn host "$GDB -nw [host_info gdb_opts]"]; -+if { $res < 0 || $res == "" } { -+ perror "Spawning $GDB failed." -+ return 1; -+} -+gdb_expect 360 { -+ -re "warning: not using untrusted file.*\.gdbinit.*\[\r\n\]$gdb_prompt $" { -+ pass "untrusted .gdbinit caught." -+ } -+ -re "$gdb_prompt $" { -+ fail "untrusted .gdbinit caught." -+ } -+ timeout { -+ fail "(timeout) untrusted .gdbinit caught." -+ } -+} -+ -+remote_exec build "chmod 644 .gdbinit" -+set res [remote_spawn host "$GDB -nw [host_info gdb_opts]"]; -+if { $res < 0 || $res == "" } { -+ perror "Spawning $GDB failed." -+ return 1; -+} -+gdb_expect 360 { -+ -re "warning: not using untrusted file.*\.gdbinit.*\[\r\n\]$gdb_prompt $" { -+ fail "trusted .gdbinit allowed." -+ } -+ -re "in gdbinit.*$gdb_prompt $" { -+ pass "trusted .gdbinit allowed." -+ } -+ timeout { -+ fail "(timeout) trusted .gdbinit allowed." -+ } -+} -+ -+remote_exec build "rm .gdbinit" -Index: gdb-7.4.50.20111218/gdb/testsuite/gdb.base/gdbinit.sample -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ gdb-7.4.50.20111218/gdb/testsuite/gdb.base/gdbinit.sample 2011-12-19 00:25:26.079891954 +0100 -@@ -0,0 +1 @@ -+echo "\nin gdbinit" -Index: gdb-7.4.50.20111218/gdb/main.c -=================================================================== ---- gdb-7.4.50.20111218.orig/gdb/main.c 2011-11-05 18:08:30.000000000 +0100 -+++ gdb-7.4.50.20111218/gdb/main.c 2011-12-19 00:25:26.080891950 +0100 -@@ -822,7 +822,7 @@ captured_main (void *data) - debugging or what directory you are in. */ - - if (home_gdbinit && !inhibit_gdbinit) -- catch_command_errors (source_script, home_gdbinit, 0, RETURN_MASK_ALL); -+ catch_command_errors (source_script, home_gdbinit, -1, RETURN_MASK_ALL); - - /* Now perform all the actions indicated by the arguments. */ - if (cdarg != NULL) -@@ -901,7 +901,7 @@ captured_main (void *data) - /* Read the .gdbinit file in the current directory, *if* it isn't - the same as the $HOME/.gdbinit file (it should exist, also). */ - if (local_gdbinit && !inhibit_gdbinit) -- catch_command_errors (source_script, local_gdbinit, 0, RETURN_MASK_ALL); -+ catch_command_errors (source_script, local_gdbinit, -1, RETURN_MASK_ALL); - - /* Now that all .gdbinit's have been read and all -d options have been - processed, we can read any scripts mentioned in SYMARG. -Index: gdb-7.4.50.20111218/gdb/python/py-auto-load.c -=================================================================== ---- gdb-7.4.50.20111218.orig/gdb/python/py-auto-load.c 2011-12-10 23:51:47.000000000 +0100 -+++ gdb-7.4.50.20111218/gdb/python/py-auto-load.c 2011-12-19 00:25:26.080891950 +0100 -@@ -284,7 +284,7 @@ source_section_scripts (struct objfile * - } - - opened = find_and_open_script (file, 1 /*search_path*/, -- &stream, &full_path); -+ &stream, &full_path, 1 /* from_tty */); - - /* If one script isn't found it's not uncommon for more to not be - found either. We don't want to print an error message for each -Index: gdb-7.4.50.20111218/gdb/cli/cli-cmds.h -=================================================================== ---- gdb-7.4.50.20111218.orig/gdb/cli/cli-cmds.h 2011-11-01 15:51:23.000000000 +0100 -+++ gdb-7.4.50.20111218/gdb/cli/cli-cmds.h 2011-12-19 00:25:26.080891950 +0100 -@@ -129,7 +129,8 @@ extern void source_script (char *, int); - /* Exported to objfiles.c. */ - - extern int find_and_open_script (const char *file, int search_path, -- FILE **streamp, char **full_path); -+ FILE **streamp, char **full_path, -+ int from_tty); - - /* Command tracing state. */ - diff --git a/gdb-autoload-01of12.patch b/gdb-autoload-01of12.patch new file mode 100644 index 0000000..d32b21f --- /dev/null +++ b/gdb-autoload-01of12.patch @@ -0,0 +1,65 @@ +http://sourceware.org/ml/gdb-cvs/2012-01/msg00202.html + +### src/gdb/ChangeLog 2012/01/24 19:12:31 1.13771 +### src/gdb/ChangeLog 2012/01/24 20:56:33 1.13772 +## -1,3 +1,12 @@ ++2012-01-24 Jan Kratochvil ++ ++ Code cleanup. ++ * cli/cli-cmds.c (source_script_from_stream): Never fclose STREAM. ++ Update the function comment for it. ++ (source_script_with_search): Call make_cleanup_fclose for STREAM. ++ * cli/cli-script.c (script_from_file): Do not call make_cleanup_fclose ++ for STREAM. ++ + 2012-01-24 Pedro Alves + + * breakpoint.c (bpstat_stop_status): Moving clearing print_it +--- src/gdb/cli/cli-cmds.c 2012/01/23 16:37:03 1.123 ++++ src/gdb/cli/cli-cmds.c 2012/01/24 20:56:33 1.124 +@@ -527,8 +527,7 @@ + return 1; + } + +-/* Load script FILE, which has already been opened as STREAM. +- STREAM is closed before we return. */ ++/* Load script FILE, which has already been opened as STREAM. */ + + static void + source_script_from_stream (FILE *stream, const char *file) +@@ -556,12 +555,9 @@ + else + { + /* Nope, just punt. */ +- fclose (stream); + throw_exception (e); + } + } +- else +- fclose (stream); + } + else + script_from_file (stream, file); +@@ -595,6 +591,7 @@ + } + + old_cleanups = make_cleanup (xfree, full_path); ++ make_cleanup_fclose (stream); + /* The python support reopens the file, so we need to pass full_path here + in case the file was found on the search path. It's useful to do this + anyway so that error messages show the actual file used. But only do +--- src/gdb/cli/cli-script.c 2012/01/04 08:17:17 1.73 ++++ src/gdb/cli/cli-script.c 2012/01/24 20:56:33 1.74 +@@ -1614,11 +1614,9 @@ + if (stream == NULL) + internal_error (__FILE__, __LINE__, _("called with NULL file pointer!")); + +- old_cleanups = make_cleanup_fclose (stream); +- + old_lines.old_line = source_line_number; + old_lines.old_file = source_file_name; +- make_cleanup (source_cleanup_lines, &old_lines); ++ old_cleanups = make_cleanup (source_cleanup_lines, &old_lines); + source_line_number = 0; + source_file_name = file; + /* This will get set every time we read a line. So it won't stay "" diff --git a/gdb-autoload-02of12.patch b/gdb-autoload-02of12.patch new file mode 100644 index 0000000..b44c9bb --- /dev/null +++ b/gdb-autoload-02of12.patch @@ -0,0 +1,103 @@ +http://sourceware.org/ml/gdb-cvs/2012-01/msg00205.html + +--- src/gdb/gdb_vecs.h ++++ src/gdb/gdb_vecs.h 2012-04-17 22:04:23.818666000 +0000 +@@ -0,0 +1,28 @@ ++/* Some commonly-used VEC types. ++ ++ Copyright (C) 2012 Free Software Foundation, Inc. ++ ++ This file is part of GDB. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . */ ++ ++ ++#ifndef GDB_VECS_H ++#define GDB_VECS_H ++ ++#include "vec.h" ++ ++DEF_VEC_P (char_ptr); ++ ++#endif /* GDB_VECS_H */ +### src/gdb/ChangeLog 2012/01/24 21:32:56 1.13774 +### src/gdb/ChangeLog 2012/01/24 21:36:37 1.13775 +## -1,3 +1,10 @@ ++2012-01-24 Tom Tromey ++ ++ * ada-lang.c: Include gdb_vecs.h. ++ * charset.c: Include gdb_vecs.h. ++ * tracepoint.h: Include gdb_vecs.h. ++ * gdb_vecs.h: New file. ++ + 2012-01-24 Pedro Alves + + * breakpoint.c (breakpoint_hit_catch_fork) +--- src/gdb/ada-lang.c 2012/01/06 03:34:45 1.330 ++++ src/gdb/ada-lang.c 2012/01/24 21:36:37 1.331 +@@ -57,6 +57,7 @@ + #include "observer.h" + #include "vec.h" + #include "stack.h" ++#include "gdb_vecs.h" + + #include "psymtab.h" + #include "value.h" +@@ -5628,8 +5629,6 @@ + return sym_name; + } + +-DEF_VEC_P (char_ptr); +- + /* A companion function to ada_make_symbol_completion_list(). + Check if SYM_NAME represents a symbol which name would be suitable + to complete TEXT (TEXT_LEN is the length of TEXT), in which case +--- src/gdb/charset.c 2012/01/04 08:17:00 1.46 ++++ src/gdb/charset.c 2012/01/24 21:36:37 1.47 +@@ -27,6 +27,7 @@ + #include "vec.h" + #include "environ.h" + #include "arch-utils.h" ++#include "gdb_vecs.h" + + #include + #include "gdb_string.h" +@@ -717,8 +718,6 @@ + + extern initialize_file_ftype _initialize_charset; /* -Wmissing-prototype */ + +-DEF_VEC_P (char_ptr); +- + static VEC (char_ptr) *charsets; + + #ifdef PHONY_ICONV +--- src/gdb/tracepoint.h 2012/01/04 08:27:57 1.46 ++++ src/gdb/tracepoint.h 2012/01/24 21:36:37 1.47 +@@ -22,6 +22,7 @@ + #include "breakpoint.h" + #include "target.h" + #include "memrange.h" ++#include "gdb_vecs.h" + + /* A trace state variable is a value managed by a target being + traced. A trace state variable (or tsv for short) can be accessed +@@ -143,8 +144,6 @@ + + /* Struct to collect random info about tracepoints on the target. */ + +-DEF_VEC_P (char_ptr); +- + struct uploaded_tp + { + int number; diff --git a/gdb-autoload-03of12.patch b/gdb-autoload-03of12.patch new file mode 100644 index 0000000..c0efc8c --- /dev/null +++ b/gdb-autoload-03of12.patch @@ -0,0 +1,215 @@ +http://sourceware.org/ml/gdb-cvs/2012-01/msg00219.html + +### src/gdb/ChangeLog 2012/01/26 16:44:29 1.13780 +### src/gdb/ChangeLog 2012/01/26 21:54:42 1.13781 +## -1,3 +1,22 @@ ++2012-01-26 Jan Kratochvil ++ ++ Do not open script filenames twice. ++ * cli/cli-cmds.c (source_script_from_stream): Pass to ++ source_python_script also STREAM. ++ * python/py-auto-load.c (source_section_scripts): Pass to ++ source_python_script_for_objfile also STREAM. ++ (auto_load_objfile_script): Pass to source_python_script_for_objfile ++ also INPUT. ++ * python/python-internal.h (source_python_script_for_objfile): New ++ parameter file, rename parameter file to filename. ++ * python/python.c (python_run_simple_file): Call PyRun_SimpleFile ++ instead if !_WIN32. Update the function comment. ++ (source_python_script, source_python_script_for_objfile) ++ (source_python_script): New parameter file, rename parameter file to ++ filename. Pass FILENAME to python_run_simple_file. ++ * python/python.h (source_python_script): New parameter file, rename ++ parameter file to filename. ++ + 2012-01-26 Pedro Alves + + * corelow.c (core_has_fake_pid): Delete. +Index: gdb-7.4.50.20120120/gdb/cli/cli-cmds.c +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/cli/cli-cmds.c 2012-01-04 09:17:16.000000000 +0100 ++++ gdb-7.4.50.20120120/gdb/cli/cli-cmds.c 2012-04-18 00:41:42.696855430 +0200 +@@ -529,9 +529,7 @@ source_script_from_stream (FILE *stream, + + TRY_CATCH (e, RETURN_MASK_ERROR) + { +- /* The python support reopens the file using python functions, +- so there's no point in passing STREAM here. */ +- source_python_script (file); ++ source_python_script (stream, file); + } + if (e.reason < 0) + { +Index: gdb-7.4.50.20120120/gdb/python/py-auto-load.c +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/python/py-auto-load.c 2012-01-04 09:17:25.000000000 +0100 ++++ gdb-7.4.50.20120120/gdb/python/py-auto-load.c 2012-04-18 00:41:42.696855430 +0200 +@@ -312,7 +312,7 @@ Use `info auto-load-scripts [REGEXP]' to + { + /* If this file is not currently loaded, load it. */ + if (! in_hash_table) +- source_python_script_for_objfile (objfile, full_path); ++ source_python_script_for_objfile (objfile, stream, full_path); + fclose (stream); + xfree (full_path); + } +@@ -431,7 +431,7 @@ auto_load_objfile_script (struct objfile + It's highly unlikely that we'd ever load it twice, + and these scripts are required to be idempotent under multiple + loads anyway. */ +- source_python_script_for_objfile (objfile, debugfile); ++ source_python_script_for_objfile (objfile, input, debugfile); + fclose (input); + } + +Index: gdb-7.4.50.20120120/gdb/python/python-internal.h +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/python/python-internal.h 2012-01-04 09:17:25.000000000 +0100 ++++ gdb-7.4.50.20120120/gdb/python/python-internal.h 2012-04-18 00:41:42.696855430 +0200 +@@ -289,8 +289,8 @@ extern const struct language_defn *pytho + + void gdbpy_print_stack (void); + +-void source_python_script_for_objfile (struct objfile *objfile, +- const char *file); ++void source_python_script_for_objfile (struct objfile *objfile, FILE *file, ++ const char *filename); + + PyObject *python_string_to_unicode (PyObject *obj); + char *unicode_to_target_string (PyObject *unicode_str); +Index: gdb-7.4.50.20120120/gdb/python/python.c +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/python/python.c 2012-04-18 00:41:30.000000000 +0200 ++++ gdb-7.4.50.20120120/gdb/python/python.c 2012-04-18 00:41:42.696855430 +0200 +@@ -154,34 +154,31 @@ ensure_python_env (struct gdbarch *gdbar + return make_cleanup (restore_python_env, env); + } + +-/* A wrapper around PyRun_SimpleFile. FILENAME is the name of +- the Python script to run. ++/* A wrapper around PyRun_SimpleFile. FILE is the Python script to run ++ named FILENAME. + +- One of the parameters of PyRun_SimpleFile is a FILE *. +- The problem is that type FILE is extremely system and compiler +- dependent. So, unless the Python library has been compiled using +- the same build environment as GDB, we run the risk of getting +- a crash due to inconsistencies between the definition used by GDB, +- and the definition used by Python. A mismatch can very likely +- lead to a crash. +- +- There is also the situation where the Python library and GDB +- are using two different versions of the C runtime library. +- This is particularly visible on Windows, where few users would +- build Python themselves (this is no trivial task on this platform), +- and thus use binaries built by someone else instead. Python, +- being built with VC, would use one version of the msvcr DLL +- (Eg. msvcr100.dll), while MinGW uses msvcrt.dll. A FILE * +- from one runtime does not necessarily operate correctly in ++ On Windows hosts few users would build Python themselves (this is no ++ trivial task on this platform), and thus use binaries built by ++ someone else instead. There may happen situation where the Python ++ library and GDB are using two different versions of the C runtime ++ library. Python, being built with VC, would use one version of the ++ msvcr DLL (Eg. msvcr100.dll), while MinGW uses msvcrt.dll. ++ A FILE * from one runtime does not necessarily operate correctly in + the other runtime. + +- To work around this potential issue, we create the FILE object +- using Python routines, thus making sure that it is compatible +- with the Python library. */ ++ To work around this potential issue, we create on Windows hosts the ++ FILE object using Python routines, thus making sure that it is ++ compatible with the Python library. */ + + static void +-python_run_simple_file (const char *filename) ++python_run_simple_file (FILE *file, const char *filename) + { ++#ifndef _WIN32 ++ ++ PyRun_SimpleFile (file, filename); ++ ++#else /* _WIN32 */ ++ + char *full_path; + PyObject *python_file; + struct cleanup *cleanup; +@@ -201,6 +198,8 @@ python_run_simple_file (const char *file + make_cleanup_py_decref (python_file); + PyRun_SimpleFile (PyFile_AsFile (python_file), filename); + do_cleanups (cleanup); ++ ++#endif /* _WIN32 */ + } + + /* Given a command_line, return a command string suitable for passing +@@ -623,17 +622,17 @@ gdbpy_parse_and_eval (PyObject *self, Py + } + + /* Read a file as Python code. +- FILE is the name of the file. ++ FILE is the file to run. FILENAME is name of the file FILE. + This does not throw any errors. If an exception occurs python will print + the traceback and clear the error indicator. */ + + void +-source_python_script (const char *file) ++source_python_script (FILE *file, const char *filename) + { + struct cleanup *cleanup; + + cleanup = ensure_python_env (get_current_arch (), current_language); +- python_run_simple_file (file); ++ python_run_simple_file (file, filename); + do_cleanups (cleanup); + } + +@@ -1041,19 +1040,20 @@ gdbpy_progspaces (PyObject *unused1, PyO + source_python_script_for_objfile; it is NULL at other times. */ + static struct objfile *gdbpy_current_objfile; + +-/* Set the current objfile to OBJFILE and then read FILE as Python code. +- This does not throw any errors. If an exception occurs python will print +- the traceback and clear the error indicator. */ ++/* Set the current objfile to OBJFILE and then read FILE named FILENAME ++ as Python code. This does not throw any errors. If an exception ++ occurs python will print the traceback and clear the error indicator. */ + + void +-source_python_script_for_objfile (struct objfile *objfile, const char *file) ++source_python_script_for_objfile (struct objfile *objfile, FILE *file, ++ const char *filename) + { + struct cleanup *cleanups; + + cleanups = ensure_python_env (get_objfile_arch (objfile), current_language); + gdbpy_current_objfile = objfile; + +- python_run_simple_file (file); ++ python_run_simple_file (file, filename); + + do_cleanups (cleanups); + gdbpy_current_objfile = NULL; +@@ -1129,7 +1129,7 @@ eval_python_from_control_command (struct + } + + void +-source_python_script (const char *file) ++source_python_script (FILE *file, const char *filename) + { + throw_error (UNSUPPORTED_ERROR, + _("Python scripting is not supported in this copy of GDB.")); +Index: gdb-7.4.50.20120120/gdb/python/python.h +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/python/python.h 2012-04-18 00:41:30.000000000 +0200 ++++ gdb-7.4.50.20120120/gdb/python/python.h 2012-04-18 00:41:42.697855427 +0200 +@@ -30,7 +30,7 @@ extern void finish_python_initialization + + void eval_python_from_control_command (struct command_line *); + +-void source_python_script (const char *file); ++void source_python_script (FILE *file, const char *filename); + + void run_python_script (int argc, char **argv); + diff --git a/gdb-autoload-04of12.patch b/gdb-autoload-04of12.patch new file mode 100644 index 0000000..645ac87 --- /dev/null +++ b/gdb-autoload-04of12.patch @@ -0,0 +1,141 @@ +http://sourceware.org/ml/gdb-cvs/2012-03/msg00234.html + +### src/gdb/ChangeLog 2012/03/19 18:13:39 1.14025 +### src/gdb/ChangeLog 2012/03/19 18:16:17 1.14026 +## -1,3 +1,14 @@ ++2012-03-19 Jan Kratochvil ++ ++ Code cleanup. ++ * main.c (struct cmdarg): Move it here from main. Add more comments. ++ (cmdarg_s, VEC (cmdarg_s)): New. ++ (main): Move struct cmdarg from here. New variables cmdarg_vec and ++ cmdarg_p. Remove variables cmdsize and ncmd and their initialization. ++ Install cleanup for cmdarg_vec. Update filling for options 'x' and ++ 'X'. Replace cmdarg processing by cmdarg_vec processing. Remove xfree ++ of CMDARG. ++ + 2012-03-19 Tom Tromey + + * gnu-v3-abi.c (gnuv3_print_vtable): Initialize 'result_vec'. +Index: gdb-7.4.50.20120120/gdb/main.c +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/main.c 2012-04-18 00:41:31.000000000 +0200 ++++ gdb-7.4.50.20120120/gdb/main.c 2012-04-18 00:42:15.354772337 +0200 +@@ -277,6 +277,25 @@ exec_or_core_file_attach (char *filename + } + } + ++/* Arguments of --command option and its counterpart. */ ++typedef struct cmdarg { ++ /* Type of this option. */ ++ enum { ++ /* Option type -x. */ ++ CMDARG_FILE, ++ ++ /* Option type -ex. */ ++ CMDARG_COMMAND ++ } type; ++ ++ /* Value of this option - filename or the GDB command itself. String memory ++ is not owned by this structure despite it is 'const'. */ ++ char *string; ++} cmdarg_s; ++ ++/* Define type VEC (cmdarg_s). */ ++DEF_VEC_O (cmdarg_s); ++ + static int + captured_main (void *data) + { +@@ -303,17 +322,8 @@ captured_main (void *data) + static int print_version; + + /* Pointers to all arguments of --command option. */ +- struct cmdarg { +- enum { +- CMDARG_FILE, +- CMDARG_COMMAND +- } type; +- char *string; +- } *cmdarg; +- /* Allocated size of cmdarg. */ +- int cmdsize; +- /* Number of elements of cmdarg used. */ +- int ncmd; ++ VEC (cmdarg_s) *cmdarg_vec = NULL; ++ struct cmdarg *cmdarg_p; + + /* Indices of all arguments of --directory option. */ + char **dirarg; +@@ -349,9 +359,7 @@ captured_main (void *data) + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); + +- cmdsize = 1; +- cmdarg = (struct cmdarg *) xmalloc (cmdsize * sizeof (*cmdarg)); +- ncmd = 0; ++ make_cleanup (VEC_cleanup (cmdarg_s), &cmdarg_vec); + dirsize = 1; + dirarg = (char **) xmalloc (dirsize * sizeof (*dirarg)); + ndir = 0; +@@ -582,24 +590,19 @@ captured_main (void *data) + pidarg = optarg; + break; + case 'x': +- cmdarg[ncmd].type = CMDARG_FILE; +- cmdarg[ncmd++].string = optarg; +- if (ncmd >= cmdsize) +- { +- cmdsize *= 2; +- cmdarg = xrealloc ((char *) cmdarg, +- cmdsize * sizeof (*cmdarg)); +- } ++ { ++ struct cmdarg cmdarg = { CMDARG_FILE, optarg }; ++ ++ VEC_safe_push (cmdarg_s, cmdarg_vec, &cmdarg); ++ } + break; + case 'X': +- cmdarg[ncmd].type = CMDARG_COMMAND; +- cmdarg[ncmd++].string = optarg; +- if (ncmd >= cmdsize) +- { +- cmdsize *= 2; +- cmdarg = xrealloc ((char *) cmdarg, +- cmdsize * sizeof (*cmdarg)); +- } ++ { ++ struct cmdarg cmdarg = { CMDARG_COMMAND, optarg }; ++ ++ VEC_safe_push (cmdarg_s, cmdarg_vec, &cmdarg); ++ } ++ break; + break; + case 'B': + batch_flag = batch_silent = 1; +@@ -990,16 +993,18 @@ captured_main (void *data) + ALL_OBJFILES (objfile) + load_auto_scripts_for_objfile (objfile); + +- for (i = 0; i < ncmd; i++) ++ for (i = 0; VEC_iterate (cmdarg_s, cmdarg_vec, i, cmdarg_p); i++) ++ switch (cmdarg_p->type) + { +- if (cmdarg[i].type == CMDARG_FILE) +- catch_command_errors (source_script, cmdarg[i].string, ++ case CMDARG_FILE: ++ catch_command_errors (source_script, cmdarg_p->string, + !batch_flag, RETURN_MASK_ALL); +- else /* cmdarg[i].type == CMDARG_COMMAND */ +- catch_command_errors (execute_command, cmdarg[i].string, ++ break; ++ case CMDARG_COMMAND: ++ catch_command_errors (execute_command, cmdarg_p->string, + !batch_flag, RETURN_MASK_ALL); ++ break; + } +- xfree (cmdarg); + + /* Read in the old history after all the command files have been + read. */ diff --git a/gdb-autoload-05of12.patch b/gdb-autoload-05of12.patch new file mode 100644 index 0000000..8dd8cc3 --- /dev/null +++ b/gdb-autoload-05of12.patch @@ -0,0 +1,244 @@ +http://sourceware.org/ml/gdb-cvs/2012-03/msg00235.html + +### src/gdb/ChangeLog 2012/03/19 18:16:17 1.14026 +### src/gdb/ChangeLog 2012/03/19 18:19:23 1.14027 +## -1,5 +1,18 @@ + 2012-03-19 Jan Kratochvil + ++ * NEWS: Describe new options --init-command=FILE, -ix and ++ --init-eval-command=COMMAND, -iex. ++ * main.c (struct cmdarg): New enum items CMDARG_INIT_FILE and ++ CMDARG_INIT_COMMAND. ++ (captured_main): New enum items OPT_IX and OPT_IEX. Add ++ "init-command", "init-eval-command", "ix" and "iex" to the variable ++ long_options. Handle OPT_IX and OPT_IEX. Process them from CMDARG_VEC. ++ New comment for CMDARG_FILE and CMDARG_COMMAND processing. ++ (print_gdb_help): Describe --init-command=FILE, -ix and ++ --init-eval-command=COMMAND, -iex. ++ ++2012-03-19 Jan Kratochvil ++ + Code cleanup. + * main.c (struct cmdarg): Move it here from main. Add more comments. + (cmdarg_s, VEC (cmdarg_s)): New. +Index: gdb-7.4.50.20120120/gdb/NEWS +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/NEWS 2012-04-18 00:41:30.000000000 +0200 ++++ gdb-7.4.50.20120120/gdb/NEWS 2012-04-18 00:42:51.226681068 +0200 +@@ -28,6 +28,13 @@ + now set a breakpoint in build/gcc/expr.c, but not + build/libcpp/expr.c. + ++* New command line options ++ ++--init-command=FILE, -ix Like --command, -x but execute it ++ before loading inferior. ++--init-eval-command=COMMAND, -iex Like --eval-command=COMMAND, -ex but ++ execute it before loading inferior. ++ + *** Changes in GDB 7.4 + + * GDB now handles ambiguous linespecs more consistently; the existing +Index: gdb-7.4.50.20120120/gdb/main.c +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/main.c 2012-04-18 00:42:15.000000000 +0200 ++++ gdb-7.4.50.20120120/gdb/main.c 2012-04-18 00:42:51.226681068 +0200 +@@ -285,7 +285,13 @@ typedef struct cmdarg { + CMDARG_FILE, + + /* Option type -ex. */ +- CMDARG_COMMAND ++ CMDARG_COMMAND, ++ ++ /* Option type -ix. */ ++ CMDARG_INIT_FILE, ++ ++ /* Option type -iex. */ ++ CMDARG_INIT_COMMAND + } type; + + /* Value of this option - filename or the GDB command itself. String memory +@@ -434,7 +440,9 @@ captured_main (void *data) + OPT_STATISTICS, + OPT_TUI, + OPT_NOWINDOWS, +- OPT_WINDOWS ++ OPT_WINDOWS, ++ OPT_IX, ++ OPT_IEX + }; + static struct option long_options[] = + { +@@ -475,6 +483,10 @@ captured_main (void *data) + {"version", no_argument, &print_version, 1}, + {"x", required_argument, 0, 'x'}, + {"ex", required_argument, 0, 'X'}, ++ {"init-command", required_argument, 0, OPT_IX}, ++ {"init-eval-command", required_argument, 0, OPT_IEX}, ++ {"ix", required_argument, 0, OPT_IX}, ++ {"iex", required_argument, 0, OPT_IEX}, + #ifdef GDBTK + {"tclcommand", required_argument, 0, 'z'}, + {"enable-external-editor", no_argument, 0, 'y'}, +@@ -603,6 +615,19 @@ captured_main (void *data) + VEC_safe_push (cmdarg_s, cmdarg_vec, &cmdarg); + } + break; ++ case OPT_IX: ++ { ++ struct cmdarg cmdarg = { CMDARG_INIT_FILE, optarg }; ++ ++ VEC_safe_push (cmdarg_s, cmdarg_vec, &cmdarg); ++ } ++ break; ++ case OPT_IEX: ++ { ++ struct cmdarg cmdarg = { CMDARG_INIT_COMMAND, optarg }; ++ ++ VEC_safe_push (cmdarg_s, cmdarg_vec, &cmdarg); ++ } + break; + case 'B': + batch_flag = batch_silent = 1; +@@ -877,6 +902,20 @@ captured_main (void *data) + quit_pre_print = error_pre_print; + warning_pre_print = _("\nwarning: "); + ++ /* Process '-ix' and '-iex' options early. */ ++ for (i = 0; VEC_iterate (cmdarg_s, cmdarg_vec, i, cmdarg_p); i++) ++ switch (cmdarg_p->type) ++ { ++ case CMDARG_INIT_FILE: ++ catch_command_errors (source_script, cmdarg_p->string, ++ !batch_flag, RETURN_MASK_ALL); ++ break; ++ case CMDARG_INIT_COMMAND: ++ catch_command_errors (execute_command, cmdarg_p->string, ++ !batch_flag, RETURN_MASK_ALL); ++ break; ++ } ++ + /* Read and execute the system-wide gdbinit file, if it exists. + This is done *before* all the command line arguments are + processed; it sets global parameters, which are independent of +@@ -993,6 +1032,7 @@ captured_main (void *data) + ALL_OBJFILES (objfile) + load_auto_scripts_for_objfile (objfile); + ++ /* Process '-x' and '-ex' options. */ + for (i = 0; VEC_iterate (cmdarg_s, cmdarg_vec, i, cmdarg_p); i++) + switch (cmdarg_p->type) + { +@@ -1093,6 +1133,8 @@ Options:\n\n\ + Execute a single GDB command.\n\ + May be used multiple times and in conjunction\n\ + with --command.\n\ ++ --init-command=FILE, -ix Like -x but execute it before loading inferior.\n\ ++ --init-eval-command=COMMAND, -iex Like -ex but before loading inferior.\n\ + --core=COREFILE Analyze the core dump COREFILE.\n\ + --pid=PID Attach to running process PID.\n\ + "), stream); +Index: gdb-7.4.50.20120120/gdb/doc/gdb.texinfo +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/doc/gdb.texinfo 2012-04-18 00:41:31.000000000 +0200 ++++ gdb-7.4.50.20120120/gdb/doc/gdb.texinfo 2012-04-18 00:42:51.232681052 +0200 +@@ -989,6 +989,22 @@ also be interleaved with @samp{-command} + -x setbreakpoints -ex 'run' a.out + @end smallexample + ++@item -init-command @var{file} ++@itemx -ix @var{file} ++@cindex @code{--init-command} ++@cindex @code{-ix} ++Execute commands from file @var{file} before loading gdbinit files or the ++inferior. ++@xref{Startup}. ++ ++@item -init-eval-command @var{command} ++@itemx -iex @var{command} ++@cindex @code{--init-eval-command} ++@cindex @code{-iex} ++Execute a single @value{GDBN} command before loading gdbinit files or the ++inferior. ++@xref{Startup}. ++ + @item -directory @var{directory} + @itemx -d @var{directory} + @cindex @code{--directory} +@@ -1250,6 +1266,13 @@ Sets up the command interpreter as speci + (@pxref{Mode Options, interpreter}). + + @item ++Executes commands and command files specified by the @samp{-iex} and ++@samp{-ix} options in their specified order. Usually you should use the ++@samp{-ex} and @samp{-x} options instead, but this way you can apply ++settings before @value{GDBN} init files get executed and before inferior ++gets loaded. ++ ++@item + @cindex init file + Reads the system-wide @dfn{init file} (if @option{--with-system-gdbinit} was + used when building @value{GDBN}; @pxref{System-wide configuration, +@@ -1283,14 +1306,11 @@ If you wish to disable the auto-loading + you must do something like the following: + + @smallexample +-$ gdb -ex "set auto-load-scripts off" -ex "file myprogram" ++$ gdb -iex "set auto-load-scripts off" myprogram + @end smallexample + +-The following does not work because the auto-loading is turned off too late: +- +-@smallexample +-$ gdb -ex "set auto-load-scripts off" myprogram +-@end smallexample ++Option @samp{-ex} does not work because the auto-loading is then turned ++off too late. + + @item + Reads command files specified by the @samp{-x} option. @xref{Command +Index: gdb-7.4.50.20120120/gdb/testsuite/gdb.gdb/selftest.exp +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/testsuite/gdb.gdb/selftest.exp 2012-04-18 00:41:31.000000000 +0200 ++++ gdb-7.4.50.20120120/gdb/testsuite/gdb.gdb/selftest.exp 2012-04-18 00:42:51.232681052 +0200 +@@ -92,6 +92,10 @@ proc do_steps_and_nexts {} { + set description "step over python_script initialization" + set command "step" + } ++ -re ".*cmdarg_vec = NULL.*$gdb_prompt $" { ++ set description "step over cmdarg_vec initialization" ++ set command "step" ++ } + -re ".*pre_stat_chain = make_command_stats_cleanup.*$gdb_prompt $" { + set description "next over make_command_stats_cleanup and everything it calls" + set command "next" +@@ -128,18 +132,6 @@ proc do_steps_and_nexts {} { + set description "next over conditional stack alignment alloca" + set command "next" + } +- -re ".*cmdsize = 1.*$gdb_prompt $" { +- set description "step over cmdsize initialization" +- set command "next" +- } +- -re ".*cmdarg = .* xmalloc.*$gdb_prompt $" { +- set description "next over cmdarg initialization via xmalloc" +- set command "next" +- } +- -re ".*ncmd = 0.*$gdb_prompt $" { +- set description "next over ncmd initialization" +- set command "next" +- } + -re ".*dirsize = 1.*$gdb_prompt $" { + set description "next over dirsize initialization" + set command "next" +@@ -163,6 +155,10 @@ proc do_steps_and_nexts {} { + set description "next over textdomain PACKAGE" + set command "next" + } ++ -re ".*VEC_cleanup .cmdarg_s.*$gdb_prompt $" { ++ set description "next over cmdarg_s VEC_cleanup" ++ set command "next" ++ } + -re "\[0-9\]+\[\t \]+\{\r\n$gdb_prompt $" { + set description "step over initial brace" + set command "step" diff --git a/gdb-autoload-06of12.patch b/gdb-autoload-06of12.patch new file mode 100644 index 0000000..ae121ef --- /dev/null +++ b/gdb-autoload-06of12.patch @@ -0,0 +1,71 @@ +http://sourceware.org/ml/gdb-cvs/2012-03/msg00236.html + +### src/gdb/ChangeLog 2012/03/19 18:19:23 1.14027 +### src/gdb/ChangeLog 2012/03/19 18:23:51 1.14028 +## -1,5 +1,13 @@ + 2012-03-19 Jan Kratochvil + ++ Code cleanup. ++ * python/py-auto-load.c (source_section_scripts): New variable back_to. ++ Turn fclose and xfree calls into make_cleanup_fclose and make_cleanup ++ with xfree. ++ (auto_load_objfile_script): Turn fclose into make_cleanup_fclose. ++ ++2012-03-19 Jan Kratochvil ++ + * NEWS: Describe new options --init-command=FILE, -ix and + --init-eval-command=COMMAND, -iex. + * main.c (struct cmdarg): New enum items CMDARG_INIT_FILE and +--- src/gdb/python/py-auto-load.c 2012/01/26 21:54:45 1.18 ++++ src/gdb/python/py-auto-load.c 2012/03/19 18:23:52 1.19 +@@ -254,6 +254,7 @@ + FILE *stream; + char *full_path; + int opened, in_hash_table; ++ struct cleanup *back_to; + + if (*p != 1) + { +@@ -286,6 +287,13 @@ + 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 one script isn't found it's not uncommon for more to not be + found either. We don't want to print an error message for each + script, too much noise. Instead, we print the warning once and tell +@@ -313,9 +321,9 @@ + /* If this file is not currently loaded, load it. */ + if (! in_hash_table) + source_python_script_for_objfile (objfile, stream, full_path); +- fclose (stream); +- xfree (full_path); + } ++ ++ do_cleanups (back_to); + } + } + +@@ -420,6 +428,8 @@ + { + struct auto_load_pspace_info *pspace_info; + ++ make_cleanup_fclose (input); ++ + /* Add this script to the hash table too so "info auto-load-scripts" + can print it. */ + pspace_info = +@@ -432,7 +442,6 @@ + and these scripts are required to be idempotent under multiple + loads anyway. */ + source_python_script_for_objfile (objfile, input, debugfile); +- fclose (input); + } + + do_cleanups (cleanups); diff --git a/gdb-autoload-07of12.patch b/gdb-autoload-07of12.patch new file mode 100644 index 0000000..51d129e --- /dev/null +++ b/gdb-autoload-07of12.patch @@ -0,0 +1,57 @@ +http://sourceware.org/ml/gdb-cvs/2012-03/msg00296.html + +### src/gdb/doc/ChangeLog 2012/03/22 08:10:41 1.1289 +### src/gdb/doc/ChangeLog 2012/03/27 20:15:20 1.1290 +## -1,3 +1,12 @@ ++2012-03-27 Jan Kratochvil ++ ++ * gdb.texinfo (Auto-loading): Rename node reference ++ '.debug_gdb_scripts section' to 'dotdebug_gdb_scripts section'. ++ Twice. ++ (.debug_gdb_scripts section): Rename the node ... ++ (dotdebug_gdb_scripts section): ... here. ++ (Maintenance Commands): Also rename this node reference. ++ + 2012-03-22 Siva Chandra Reddy + + * gdb.texinfo (Python API/Values From Inferior): Add description +--- src/gdb/doc/gdb.texinfo 2012/03/22 08:10:41 1.936 ++++ src/gdb/doc/gdb.texinfo 2012/03/27 20:15:20 1.937 +@@ -24717,8 +24717,8 @@ + @file{@var{objfile}-gdb.py} and @code{.debug_gdb_scripts} section. + + @menu +-* objfile-gdb.py file:: The @file{@var{objfile}-gdb.py} file +-* .debug_gdb_scripts section:: The @code{.debug_gdb_scripts} section ++* objfile-gdb.py file:: The @file{@var{objfile}-gdb.py} file ++* dotdebug_gdb_scripts section:: The @code{.debug_gdb_scripts} section + * Which flavor to choose?:: + @end menu + +@@ -24744,7 +24744,7 @@ + + Also printed is the list of scripts that were mentioned in + the @code{.debug_gdb_scripts} section and were not found +-(@pxref{.debug_gdb_scripts section}). ++(@pxref{dotdebug_gdb_scripts section}). + This is useful because their names are not printed when @value{GDBN} + tries to load them and fails. There may be many of them, and printing + an error message for each one is problematic. +@@ -24795,7 +24795,7 @@ + So your @file{-gdb.py} file should be careful to avoid errors if it + is evaluated more than once. + +-@node .debug_gdb_scripts section ++@node dotdebug_gdb_scripts section + @subsubsection The @code{.debug_gdb_scripts} section + @cindex @code{.debug_gdb_scripts} section + +@@ -33475,7 +33475,7 @@ + matching @var{regexp}. + For each script, this command prints its name as specified in the objfile, + and the full path if known. +-@xref{.debug_gdb_scripts section}. ++@xref{dotdebug_gdb_scripts section}. + + @kindex maint print statistics + @cindex bcache statistics diff --git a/gdb-autoload-08of12.patch b/gdb-autoload-08of12.patch new file mode 100644 index 0000000..b48bfc1 --- /dev/null +++ b/gdb-autoload-08of12.patch @@ -0,0 +1,171 @@ +[patch#4 2/8] Code cleanup: new path to VEC in utils.c +http://sourceware.org/ml/gdb-patches/2012-04/msg00086.html +http://sourceware.org/ml/gdb-cvs/2012-04/msg00111.html + - reduced for the backport + +### src/gdb/ChangeLog 2012/04/17 15:45:05 1.14110 +### src/gdb/ChangeLog 2012/04/17 15:47:08 1.14111 +## -1,6 +1,34 @@ + 2012-04-17 Jan Kratochvil + + Code cleanup. ++ * charset.c (find_charset_names): Remove variables ix and elt. ++ Use free_char_ptr_vec. ++ * elfread.c (build_id_to_debug_filename): New variables debugdir_vec, ++ back_to and ix. Use dirnames_to_char_ptr_vec. Remove variable ++ debugdir_end. New variable debugdir_len. ++ * gdb_vecs.h (free_char_ptr_vec, make_cleanup_free_char_ptr_vec) ++ (dirnames_to_char_ptr_vec_append, dirnames_to_char_ptr_vec): New ++ declarations. ++ * progspace.c (clear_program_space_solib_cache): Remove variables ix ++ and elt. Use free_char_ptr_vec. ++ * source.c (add_path): Remove variables argv, arg and argv_index. ++ New variables dir_vec, back_to, ix and name. ++ Use dirnames_to_char_ptr_vec_append. Use freeargv instead of ++ make_cleanup_freeargv. Remove variable separator. Simplify the code ++ no longer expecting DIRNAME_SEPARATOR. ++ (openp): Remove variable p, p1 and len. New variables dir_vec, ++ back_to, ix and dir. Use dirnames_to_char_ptr_vec. Simplify the code ++ no longer expecting DIRNAME_SEPARATOR. ++ * symfile.c (find_separate_debug_file): New variables debugdir_vec, ++ back_to and ix. Use dirnames_to_char_ptr_vec. Remove variable ++ debugdir_end. ++ * utils.c (free_char_ptr_vec, do_free_char_ptr_vec) ++ (make_cleanup_free_char_ptr_vec, dirnames_to_char_ptr_vec_append) ++ (dirnames_to_char_ptr_vec): New functions. ++ ++2012-04-17 Jan Kratochvil ++ ++ Code cleanup. + * source.c (add_path): Remove always true conditional 'p == 0' and + unindent its code block. + +Index: gdb-7.4.50.20120120/gdb/gdb_vecs.h +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/gdb_vecs.h 2012-04-18 00:40:12.067086016 +0200 ++++ gdb-7.4.50.20120120/gdb/gdb_vecs.h 2012-04-18 00:40:23.474056993 +0200 +@@ -25,4 +25,16 @@ + + DEF_VEC_P (char_ptr); + ++/* From utils.c: */ ++ ++extern void free_char_ptr_vec (VEC (char_ptr) *char_ptr_vec); ++ ++extern struct cleanup * ++ make_cleanup_free_char_ptr_vec (VEC (char_ptr) *char_ptr_vec); ++ ++extern void dirnames_to_char_ptr_vec_append (VEC (char_ptr) **vecp, ++ const char *dirnames); ++ ++extern VEC (char_ptr) *dirnames_to_char_ptr_vec (const char *dirnames); ++ + #endif /* GDB_VECS_H */ +Index: gdb-7.4.50.20120120/gdb/utils.c +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/utils.c 2012-04-18 00:40:12.068086013 +0200 ++++ gdb-7.4.50.20120120/gdb/utils.c 2012-04-18 00:40:49.862989855 +0200 +@@ -29,6 +29,7 @@ + #ifdef HAVE_SYS_RESOURCE_H + #include + #endif /* HAVE_SYS_RESOURCE_H */ ++#include "gdb_vecs.h" + + #ifdef TUI + #include "tui/tui.h" /* For tui_get_command_dimension. */ +@@ -3835,6 +3836,95 @@ producer_is_gcc_ge_4 (const char *produc + return minor; + } + ++/* Call xfree for each element of CHAR_PTR_VEC and final VEC_free for ++ CHAR_PTR_VEC itself. ++ ++ You must not modify CHAR_PTR_VEC after it got registered with this function ++ by make_cleanup as the CHAR_PTR_VEC base address may change on its updates. ++ Contrary to VEC_free this function does not (cannot) clear the pointer. */ ++ ++void ++free_char_ptr_vec (VEC (char_ptr) *char_ptr_vec) ++{ ++ int ix; ++ char *name; ++ ++ for (ix = 0; VEC_iterate (char_ptr, char_ptr_vec, ix, name); ++ix) ++ xfree (name); ++ VEC_free (char_ptr, char_ptr_vec); ++} ++ ++/* Helper for make_cleanup_free_char_ptr_vec. */ ++ ++static void ++do_free_char_ptr_vec (void *arg) ++{ ++ VEC (char_ptr) *char_ptr_vec = arg; ++ ++ free_char_ptr_vec (char_ptr_vec); ++} ++ ++/* Make cleanup handler calling xfree for each element of CHAR_PTR_VEC and ++ final VEC_free for CHAR_PTR_VEC itself. ++ ++ You must not modify CHAR_PTR_VEC after this cleanup registration as the ++ CHAR_PTR_VEC base address may change on its updates. Contrary to VEC_free ++ this function does not (cannot) clear the pointer. */ ++ ++struct cleanup * ++make_cleanup_free_char_ptr_vec (VEC (char_ptr) *char_ptr_vec) ++{ ++ return make_cleanup (do_free_char_ptr_vec, char_ptr_vec); ++} ++ ++/* Extended version of dirnames_to_char_ptr_vec - additionally if *VECP is ++ non-NULL the new list elements from DIRNAMES are appended to the existing ++ *VECP list of entries. *VECP address will be updated by this call. */ ++ ++void ++dirnames_to_char_ptr_vec_append (VEC (char_ptr) **vecp, const char *dirnames) ++{ ++ do ++ { ++ size_t this_len; ++ char *next_dir, *this_dir; ++ ++ next_dir = strchr (dirnames, DIRNAME_SEPARATOR); ++ if (next_dir == NULL) ++ this_len = strlen (dirnames); ++ else ++ { ++ this_len = next_dir - dirnames; ++ next_dir++; ++ } ++ ++ this_dir = xmalloc (this_len + 1); ++ memcpy (this_dir, dirnames, this_len); ++ this_dir[this_len] = '\0'; ++ VEC_safe_push (char_ptr, *vecp, this_dir); ++ ++ dirnames = next_dir; ++ } ++ while (dirnames != NULL); ++} ++ ++/* Split DIRNAMES by DIRNAME_SEPARATOR delimiter and return a list of all the ++ elements in their original order. For empty string ("") DIRNAMES return ++ list of one empty string ("") element. ++ ++ You may modify the returned strings. ++ Read free_char_ptr_vec for its cleanup. */ ++ ++VEC (char_ptr) * ++dirnames_to_char_ptr_vec (const char *dirnames) ++{ ++ VEC (char_ptr) *retval = NULL; ++ ++ dirnames_to_char_ptr_vec_append (&retval, dirnames); ++ ++ return retval; ++} ++ + #ifdef HAVE_WAITPID + + #ifdef SIGALRM diff --git a/gdb-autoload-09of12.patch b/gdb-autoload-09of12.patch new file mode 100644 index 0000000..1244cff --- /dev/null +++ b/gdb-autoload-09of12.patch @@ -0,0 +1,1168 @@ +[patch#4 3/8] auto-load: reshuffle code +http://sourceware.org/ml/gdb-patches/2012-04/msg00087.html +http://sourceware.org/ml/gdb-cvs/2012-04/msg00112.html + +Index: gdb-7.4.50.20120120/gdb/auto-load.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ gdb-7.4.50.20120120/gdb/auto-load.c 2012-04-18 00:26:29.049120212 +0200 +@@ -0,0 +1,472 @@ ++/* GDB routines for supporting auto-loaded scripts. ++ ++ Copyright (C) 2012 Free Software Foundation, Inc. ++ ++ This file is part of GDB. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . */ ++ ++#include "defs.h" ++#include "auto-load.h" ++#include "progspace.h" ++#include "python/python.h" ++#include "gdb_regex.h" ++#include "ui-out.h" ++#include "filenames.h" ++#include "command.h" ++#include "observer.h" ++#include "objfiles.h" ++#include "python/python-internal.h" ++ ++/* 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. ++ ++ Both auto_load_scripts && gdbpy_global_auto_load must be true to enable ++ auto-loading. ++ ++ This flag exists to facilitate deferring auto-loading during start-up ++ until after ./.gdbinit has been read; it may augment the search directories ++ used to find the scripts. */ ++int gdbpy_global_auto_load = 1; ++ ++/* For scripts specified in .debug_gdb_scripts, multiple objfiles may load ++ the same script. There's no point in loading the script multiple times, ++ and there can be a lot of objfiles and scripts, so we keep track of scripts ++ loaded this way. */ ++ ++struct auto_load_pspace_info ++{ ++ /* For each program space we keep track of loaded scripts. */ ++ struct htab *loaded_scripts; ++ ++ /* Non-zero if we've issued the warning about an auto-load script not being ++ found. We only want to issue this warning once. */ ++ int script_not_found_warning_printed; ++}; ++ ++/* Objects of this type are stored in the loaded script hash table. */ ++ ++struct loaded_script ++{ ++ /* Name as provided by the objfile. */ ++ const char *name; ++ /* Full path name or NULL if script wasn't found (or was otherwise ++ inaccessible). */ ++ const char *full_path; ++}; ++ ++/* Per-program-space data key. */ ++static const struct program_space_data *auto_load_pspace_data; ++ ++static void ++auto_load_pspace_data_cleanup (struct program_space *pspace, void *arg) ++{ ++ struct auto_load_pspace_info *info; ++ ++ info = program_space_data (pspace, auto_load_pspace_data); ++ if (info != NULL) ++ { ++ if (info->loaded_scripts) ++ htab_delete (info->loaded_scripts); ++ xfree (info); ++ } ++} ++ ++/* Get the current autoload data. If none is found yet, add it now. This ++ function always returns a valid object. */ ++ ++static struct auto_load_pspace_info * ++get_auto_load_pspace_data (struct program_space *pspace) ++{ ++ struct auto_load_pspace_info *info; ++ ++ info = program_space_data (pspace, auto_load_pspace_data); ++ if (info == NULL) ++ { ++ info = XZALLOC (struct auto_load_pspace_info); ++ set_program_space_data (pspace, auto_load_pspace_data, info); ++ } ++ ++ return info; ++} ++ ++/* Hash function for the loaded script hash. */ ++ ++static hashval_t ++hash_loaded_script_entry (const void *data) ++{ ++ const struct loaded_script *e = data; ++ ++ return htab_hash_string (e->name); ++} ++ ++/* Equality function for the loaded script hash. */ ++ ++static int ++eq_loaded_script_entry (const void *a, const void *b) ++{ ++ const struct loaded_script *ea = a; ++ const struct loaded_script *eb = b; ++ ++ return strcmp (ea->name, eb->name) == 0; ++} ++ ++/* Initialize the table to track loaded scripts. ++ Each entry is hashed by the full path name. */ ++ ++static void ++init_loaded_scripts_info (struct auto_load_pspace_info *pspace_info) ++{ ++ /* Choose 31 as the starting size of the hash table, somewhat arbitrarily. ++ Space for each entry is obtained with one malloc so we can free them ++ easily. */ ++ ++ pspace_info->loaded_scripts = htab_create (31, ++ hash_loaded_script_entry, ++ eq_loaded_script_entry, ++ xfree); ++ ++ pspace_info->script_not_found_warning_printed = FALSE; ++} ++ ++/* Wrapper on get_auto_load_pspace_data to also allocate the hash table ++ for loading scripts. */ ++ ++struct auto_load_pspace_info * ++get_auto_load_pspace_data_for_loading (struct program_space *pspace) ++{ ++ struct auto_load_pspace_info *info; ++ ++ info = get_auto_load_pspace_data (pspace); ++ if (info->loaded_scripts == NULL) ++ init_loaded_scripts_info (info); ++ ++ return info; ++} ++ ++/* Add script NAME to hash table of PSPACE_INFO. ++ FULL_PATH is NULL if the script wasn't found. ++ The result is true if the script was already in the hash table. */ ++ ++int ++maybe_add_script (struct auto_load_pspace_info *pspace_info, const char *name, ++ const char *full_path) ++{ ++ struct htab *htab = pspace_info->loaded_scripts; ++ struct loaded_script **slot, entry; ++ int in_hash_table; ++ ++ entry.name = name; ++ entry.full_path = full_path; ++ slot = (struct loaded_script **) htab_find_slot (htab, &entry, INSERT); ++ in_hash_table = *slot != NULL; ++ ++ /* If this script is not in the hash table, add it. */ ++ ++ if (! in_hash_table) ++ { ++ char *p; ++ ++ /* Allocate all space in one chunk so it's easier to free. */ ++ *slot = xmalloc (sizeof (**slot) ++ + strlen (name) + 1 ++ + (full_path != NULL ? (strlen (full_path) + 1) : 0)); ++ p = ((char*) *slot) + sizeof (**slot); ++ strcpy (p, name); ++ (*slot)->name = p; ++ if (full_path != NULL) ++ { ++ p += strlen (p) + 1; ++ strcpy (p, full_path); ++ (*slot)->full_path = p; ++ } ++ else ++ (*slot)->full_path = NULL; ++ } ++ ++ return in_hash_table; ++} ++ ++/* Clear the table of loaded section scripts. */ ++ ++static void ++clear_section_scripts (void) ++{ ++ struct program_space *pspace = current_program_space; ++ struct auto_load_pspace_info *info; ++ ++ info = program_space_data (pspace, auto_load_pspace_data); ++ if (info != NULL && info->loaded_scripts != NULL) ++ { ++ htab_delete (info->loaded_scripts); ++ info->loaded_scripts = NULL; ++ info->script_not_found_warning_printed = FALSE; ++ } ++} ++ ++/* Look for the auto-load script associated with OBJFILE and load it. */ ++ ++void ++auto_load_objfile_script (struct objfile *objfile, const char *suffix) ++{ ++ char *realname; ++ char *filename, *debugfile; ++ int len; ++ FILE *input; ++ struct cleanup *cleanups; ++ ++ realname = gdb_realpath (objfile->name); ++ len = strlen (realname); ++ filename = xmalloc (len + strlen (suffix) + 1); ++ memcpy (filename, realname, len); ++ strcpy (filename + len, suffix); ++ ++ cleanups = make_cleanup (xfree, filename); ++ make_cleanup (xfree, realname); ++ ++ input = fopen (filename, "r"); ++ debugfile = filename; ++ ++ if (!input && debug_file_directory) ++ { ++ /* Also try the same file in the separate debug info directory. */ ++ debugfile = xmalloc (strlen (filename) ++ + strlen (debug_file_directory) + 1); ++ strcpy (debugfile, debug_file_directory); ++ /* FILENAME is absolute, so we don't need a "/" here. */ ++ strcat (debugfile, filename); ++ ++ make_cleanup (xfree, debugfile); ++ input = fopen (debugfile, "r"); ++ } ++ ++ if (!input && gdb_datadir) ++ { ++ /* Also try the same file in a subdirectory of gdb's data ++ directory. */ ++ debugfile = xmalloc (strlen (gdb_datadir) + strlen (filename) ++ + strlen ("/auto-load") + 1); ++ strcpy (debugfile, gdb_datadir); ++ strcat (debugfile, "/auto-load"); ++ /* FILENAME is absolute, so we don't need a "/" here. */ ++ strcat (debugfile, filename); ++ ++ make_cleanup (xfree, debugfile); ++ input = fopen (debugfile, "r"); ++ } ++ ++ if (input) ++ { ++ struct auto_load_pspace_info *pspace_info; ++ ++ make_cleanup_fclose (input); ++ ++ /* Add this script to the hash table too so "info auto-load-scripts" ++ can print it. */ ++ pspace_info = ++ get_auto_load_pspace_data_for_loading (current_program_space); ++ maybe_add_script (pspace_info, debugfile, debugfile); ++ ++ /* 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. */ ++ source_python_script_for_objfile (objfile, input, debugfile); ++ } ++ ++ do_cleanups (cleanups); ++} ++ ++/* This is a new_objfile observer callback to auto-load scripts. ++ ++ Two flavors of auto-loaded scripts are supported. ++ 1) based on the path to the objfile ++ 2) from .debug_gdb_scripts section */ ++ ++static void ++auto_load_new_objfile (struct objfile *objfile) ++{ ++ if (!objfile) ++ { ++ /* OBJFILE is NULL when loading a new "main" symbol-file. */ ++ clear_section_scripts (); ++ return; ++ } ++ ++ load_auto_scripts_for_objfile (objfile); ++} ++ ++/* Collect scripts to be printed in a vec. */ ++ ++typedef struct loaded_script *loaded_script_ptr; ++DEF_VEC_P (loaded_script_ptr); ++ ++/* Traversal function for htab_traverse. ++ Collect the entry if it matches the regexp. */ ++ ++static int ++collect_matching_scripts (void **slot, void *info) ++{ ++ struct loaded_script *script = *slot; ++ VEC (loaded_script_ptr) **scripts_ptr = info; ++ ++ if (re_exec (script->name)) ++ VEC_safe_push (loaded_script_ptr, *scripts_ptr, script); ++ ++ return 1; ++} ++ ++/* Print SCRIPT. */ ++ ++static void ++print_script (struct loaded_script *script) ++{ ++ struct ui_out *uiout = current_uiout; ++ struct cleanup *chain; ++ ++ chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); ++ ++ ui_out_field_string (uiout, "loaded", script->full_path ? "Yes" : "Missing"); ++ ui_out_field_string (uiout, "script", script->name); ++ ui_out_text (uiout, "\n"); ++ ++ /* If the name isn't the full path, print it too. */ ++ if (script->full_path != NULL ++ && strcmp (script->name, script->full_path) != 0) ++ { ++ ui_out_text (uiout, "\tfull name: "); ++ ui_out_field_string (uiout, "full_path", script->full_path); ++ ui_out_text (uiout, "\n"); ++ } ++ ++ do_cleanups (chain); ++} ++ ++/* Helper for info_auto_load_scripts to sort the scripts by name. */ ++ ++static int ++sort_scripts_by_name (const void *ap, const void *bp) ++{ ++ const struct loaded_script *a = *(const struct loaded_script **) ap; ++ const struct loaded_script *b = *(const struct loaded_script **) bp; ++ ++ return FILENAME_CMP (a->name, b->name); ++} ++ ++/* "info auto-load-scripts" command. */ ++ ++static void ++info_auto_load_scripts (char *pattern, int from_tty) ++{ ++ struct ui_out *uiout = current_uiout; ++ struct auto_load_pspace_info *pspace_info; ++ struct cleanup *script_chain; ++ VEC (loaded_script_ptr) *scripts; ++ int nr_scripts; ++ ++ dont_repeat (); ++ ++ pspace_info = get_auto_load_pspace_data (current_program_space); ++ ++ if (pattern && *pattern) ++ { ++ char *re_err = re_comp (pattern); ++ ++ if (re_err) ++ error (_("Invalid regexp: %s"), re_err); ++ } ++ else ++ { ++ re_comp (""); ++ } ++ ++ /* We need to know the number of rows before we build the table. ++ Plus we want to sort the scripts by name. ++ So first traverse the hash table collecting the matching scripts. */ ++ ++ scripts = VEC_alloc (loaded_script_ptr, 10); ++ script_chain = make_cleanup (VEC_cleanup (loaded_script_ptr), &scripts); ++ ++ if (pspace_info != NULL && pspace_info->loaded_scripts != NULL) ++ { ++ immediate_quit++; ++ /* Pass a pointer to scripts as VEC_safe_push can realloc space. */ ++ htab_traverse_noresize (pspace_info->loaded_scripts, ++ collect_matching_scripts, &scripts); ++ immediate_quit--; ++ } ++ ++ nr_scripts = VEC_length (loaded_script_ptr, scripts); ++ make_cleanup_ui_out_table_begin_end (uiout, 2, nr_scripts, ++ "AutoLoadedScriptsTable"); ++ ++ ui_out_table_header (uiout, 7, ui_left, "loaded", "Loaded"); ++ ui_out_table_header (uiout, 70, ui_left, "script", "Script"); ++ ui_out_table_body (uiout); ++ ++ if (nr_scripts > 0) ++ { ++ int i; ++ loaded_script_ptr script; ++ ++ qsort (VEC_address (loaded_script_ptr, scripts), ++ VEC_length (loaded_script_ptr, scripts), ++ sizeof (loaded_script_ptr), sort_scripts_by_name); ++ for (i = 0; VEC_iterate (loaded_script_ptr, scripts, i, script); ++i) ++ print_script (script); ++ } ++ ++ do_cleanups (script_chain); ++ ++ if (nr_scripts == 0) ++ { ++ if (pattern && *pattern) ++ ui_out_message (uiout, 0, "No auto-load scripts matching %s.\n", ++ pattern); ++ else ++ ui_out_message (uiout, 0, "No auto-load scripts.\n"); ++ } ++} ++ ++/* Return non-zero if SCRIPT_NOT_FOUND_WARNING_PRINTED of PSPACE_INFO was unset ++ before calling this function. Always set SCRIPT_NOT_FOUND_WARNING_PRINTED ++ of PSPACE_INFO. */ ++ ++int ++script_not_found_warning_print (struct auto_load_pspace_info *pspace_info) ++{ ++ int retval = !pspace_info->script_not_found_warning_printed; ++ ++ pspace_info->script_not_found_warning_printed = 1; ++ ++ return retval; ++} ++ ++void _initialize_auto_load (void); ++ ++void ++_initialize_auto_load (void) ++{ ++ auto_load_pspace_data ++ = register_program_space_data_with_cleanup (auto_load_pspace_data_cleanup); ++ ++ observer_attach_new_objfile (auto_load_new_objfile); ++ ++ add_info ("auto-load-scripts", ++ info_auto_load_scripts, ++ _("Print the list of automatically loaded scripts.\n\ ++Usage: info auto-load-scripts [REGEXP]")); ++} +Index: gdb-7.4.50.20120120/gdb/auto-load.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ gdb-7.4.50.20120120/gdb/auto-load.h 2012-04-18 00:26:29.049120212 +0200 +@@ -0,0 +1,36 @@ ++/* GDB routines for supporting auto-loaded scripts. ++ ++ Copyright (C) 2012 Free Software Foundation, Inc. ++ ++ This file is part of GDB. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . */ ++ ++#ifndef AUTO_LOAD_H ++#define AUTO_LOAD_H 1 ++ ++struct program_space; ++ ++extern int gdbpy_global_auto_load; ++ ++extern struct auto_load_pspace_info * ++ get_auto_load_pspace_data_for_loading (struct program_space *pspace); ++extern int maybe_add_script (struct auto_load_pspace_info *pspace_info, ++ const char *name, const char *full_path); ++extern void auto_load_objfile_script (struct objfile *objfile, ++ const char *suffix); ++extern int ++ script_not_found_warning_print (struct auto_load_pspace_info *pspace_info); ++ ++#endif /* AUTO_LOAD_H */ +Index: gdb-7.4.50.20120120/gdb/gdb-gdb.gdb.in +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ gdb-7.4.50.20120120/gdb/gdb-gdb.gdb.in 2012-04-18 00:26:29.049120212 +0200 +@@ -0,0 +1,34 @@ ++echo Setting up the environment for debugging gdb.\n ++ ++set complaints 1 ++ ++b internal_error ++ ++b info_command ++commands ++ silent ++ return ++end ++ ++dir @srcdir@/../libiberty ++dir @srcdir@/../bfd ++dir @srcdir@ ++dir . ++set prompt (top-gdb) ++ ++define pdie ++ if $argc == 1 ++ call dump_die ($arg0, 1) ++ else ++ if $argc == 2 ++ call dump_die ($arg0, $arg1) ++ else ++ printf "Syntax: pdie die [depth]\n" ++ end ++ end ++end ++ ++document pdie ++Pretty print a DWARF DIE. ++Syntax: pdie die [depth] ++end +Index: gdb-7.4.50.20120120/gdb/Makefile.in +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/Makefile.in 2012-04-18 00:26:14.000000000 +0200 ++++ gdb-7.4.50.20120120/gdb/Makefile.in 2012-04-18 00:26:53.455058037 +0200 +@@ -680,7 +680,7 @@ TARGET_FLAGS_TO_PASS = \ + # SFILES is used in building the distribution archive. + + SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \ +- addrmap.c \ ++ addrmap.c auto-load.c \ + auxv.c ax-general.c ax-gdb.c \ + bcache.c \ + bfd-target.c \ +@@ -819,7 +819,7 @@ solib-darwin.h solib-ia64-hpux.h solib-s + gnulib/extra/arg-nonnull.h gnulib/extra/c++defs.h gnulib/extra/warn-on-use.h \ + gnulib/stddef.in.h inline-frame.h skip.h stap-probe.h \ + common/common-utils.h common/xml-utils.h common/buffer.h common/ptid.h \ +-common/linux-osdata.h gdb-dlfcn.h ++common/linux-osdata.h gdb-dlfcn.h auto-load.h + + # Header files that already have srcdir in them, or which are in objdir. + +@@ -851,7 +851,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $ + version.o \ + annotate.o \ + addrmap.o \ +- auxv.o \ ++ auto-load.o auxv.o \ + bfd-target.o \ + blockframe.o breakpoint.o findvar.o regcache.o \ + charset.o continuations.o corelow.o disasm.o dummy-frame.o dfp.o \ +@@ -1255,7 +1255,7 @@ distclean: clean + rm -f gdbserver/config.status gdbserver/config.log + rm -f gdbserver/tm.h gdbserver/xm.h gdbserver/nm.h + rm -f gdbserver/Makefile gdbserver/config.cache +- rm -f nm.h config.status config.h stamp-h .gdbinit jit-reader.h ++ rm -f nm.h config.status config.h stamp-h gdb-gdb.gdb jit-reader.h + rm -f y.output yacc.acts yacc.tmp y.tab.h + rm -f config.log config.cache + rm -f Makefile +Index: gdb-7.4.50.20120120/gdb/configure +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/configure 2012-04-18 00:26:14.000000000 +0200 ++++ gdb-7.4.50.20120120/gdb/configure 2012-04-18 00:26:29.053120202 +0200 +@@ -16839,7 +16839,7 @@ ac_config_links="$ac_config_links $ac_co + $as_echo "#define GDB_DEFAULT_HOST_CHARSET \"UTF-8\"" >>confdefs.h + + +-ac_config_files="$ac_config_files Makefile .gdbinit:gdbinit.in doc/Makefile gnulib/Makefile data-directory/Makefile" ++ac_config_files="$ac_config_files Makefile gdb-gdb.gdb doc/Makefile gnulib/Makefile data-directory/Makefile" + + ac_config_commands="$ac_config_commands default" + +@@ -17605,7 +17605,7 @@ do + "jit-reader.h") CONFIG_FILES="$CONFIG_FILES jit-reader.h:jit-reader.in" ;; + "$ac_config_links_1") CONFIG_LINKS="$CONFIG_LINKS $ac_config_links_1" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; +- ".gdbinit") CONFIG_FILES="$CONFIG_FILES .gdbinit:gdbinit.in" ;; ++ "gdb-gdb.gdb") CONFIG_FILES="$CONFIG_FILES gdb-gdb.gdb" ;; + "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; + "gnulib/Makefile") CONFIG_FILES="$CONFIG_FILES gnulib/Makefile" ;; + "data-directory/Makefile") CONFIG_FILES="$CONFIG_FILES data-directory/Makefile" ;; +Index: gdb-7.4.50.20120120/gdb/configure.ac +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/configure.ac 2012-04-18 00:26:14.000000000 +0200 ++++ gdb-7.4.50.20120120/gdb/configure.ac 2012-04-18 00:26:29.053120202 +0200 +@@ -2422,7 +2422,7 @@ dnl At the moment, we just assume it's + AC_DEFINE(GDB_DEFAULT_HOST_CHARSET, "UTF-8", + [Define to be a string naming the default host character set.]) + +-AC_OUTPUT(Makefile .gdbinit:gdbinit.in doc/Makefile gnulib/Makefile data-directory/Makefile, ++AC_OUTPUT(Makefile gdb-gdb.gdb doc/Makefile gnulib/Makefile data-directory/Makefile, + [ + case x$CONFIG_HEADERS in + xconfig.h:config.in) +Index: gdb-7.4.50.20120120/gdb/main.c +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/main.c 2012-04-18 00:26:14.000000000 +0200 ++++ gdb-7.4.50.20120120/gdb/main.c 2012-04-18 00:26:29.054120199 +0200 +@@ -42,6 +42,7 @@ + #include "cli/cli-cmds.h" + #include "python/python.h" + #include "objfiles.h" ++#include "auto-load.h" + + /* The selected interpreter. This will be used as a set command + variable, so it should always be malloc'ed - since +Index: gdb-7.4.50.20120120/gdb/python/py-auto-load.c +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/python/py-auto-load.c 2012-04-18 00:26:14.000000000 +0200 ++++ gdb-7.4.50.20120120/gdb/python/py-auto-load.c 2012-04-18 00:26:29.054120199 +0200 +@@ -18,30 +18,14 @@ + along with this program. If not, see . */ + + #include "defs.h" +-#include "filenames.h" + #include "gdb_string.h" +-#include "gdb_regex.h" + #include "top.h" + #include "exceptions.h" +-#include "command.h" + #include "gdbcmd.h" +-#include "observer.h" +-#include "progspace.h" + #include "objfiles.h" + #include "python.h" + #include "cli/cli-cmds.h" +- +-/* 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. +- +- Both auto_load_scripts && gdbpy_global_auto_load must be true to enable +- auto-loading. +- +- This flag exists to facilitate deferring auto-loading during start-up +- until after ./.gdbinit has been read; it may augment the search directories +- used to find the scripts. */ +-int gdbpy_global_auto_load = 1; ++#include "auto-load.h" + + #ifdef HAVE_PYTHON + +@@ -60,32 +44,6 @@ int gdbpy_global_auto_load = 1; + The leading byte is to allow upward compatible extensions. */ + #define GDBPY_AUTO_SECTION_NAME ".debug_gdb_scripts" + +-/* For scripts specified in .debug_gdb_scripts, multiple objfiles may load +- the same script. There's no point in loading the script multiple times, +- and there can be a lot of objfiles and scripts, so we keep track of scripts +- loaded this way. */ +- +-struct auto_load_pspace_info +-{ +- /* For each program space we keep track of loaded scripts. */ +- struct htab *loaded_scripts; +- +- /* Non-zero if we've issued the warning about an auto-load script not being +- found. We only want to issue this warning once. */ +- int script_not_found_warning_printed; +-}; +- +-/* Objects of this type are stored in the loaded script hash table. */ +- +-struct loaded_script +-{ +- /* Name as provided by the objfile. */ +- const char *name; +- /* Full path name or NULL if script wasn't found (or was otherwise +- inaccessible). */ +- const char *full_path; +-}; +- + /* User-settable option to enable/disable auto-loading: + set auto-load-scripts on|off + This is true if we should auto-load associated scripts when an objfile +@@ -97,136 +55,6 @@ struct loaded_script + The fact that it lives here is just an implementation detail. */ + static int auto_load_scripts = 1; + +-/* Per-program-space data key. */ +-static const struct program_space_data *auto_load_pspace_data; +- +-static void +-auto_load_pspace_data_cleanup (struct program_space *pspace, void *arg) +-{ +- struct auto_load_pspace_info *info; +- +- info = program_space_data (pspace, auto_load_pspace_data); +- if (info != NULL) +- { +- if (info->loaded_scripts) +- htab_delete (info->loaded_scripts); +- xfree (info); +- } +-} +- +-/* Get the current autoload data. If none is found yet, add it now. This +- function always returns a valid object. */ +- +-static struct auto_load_pspace_info * +-get_auto_load_pspace_data (struct program_space *pspace) +-{ +- struct auto_load_pspace_info *info; +- +- info = program_space_data (pspace, auto_load_pspace_data); +- if (info == NULL) +- { +- info = XZALLOC (struct auto_load_pspace_info); +- set_program_space_data (pspace, auto_load_pspace_data, info); +- } +- +- return info; +-} +- +-/* Hash function for the loaded script hash. */ +- +-static hashval_t +-hash_loaded_script_entry (const void *data) +-{ +- const struct loaded_script *e = data; +- +- return htab_hash_string (e->name); +-} +- +-/* Equality function for the loaded script hash. */ +- +-static int +-eq_loaded_script_entry (const void *a, const void *b) +-{ +- const struct loaded_script *ea = a; +- const struct loaded_script *eb = b; +- +- return strcmp (ea->name, eb->name) == 0; +-} +- +-/* Initialize the table to track loaded scripts. +- Each entry is hashed by the full path name. */ +- +-static void +-init_loaded_scripts_info (struct auto_load_pspace_info *pspace_info) +-{ +- /* Choose 31 as the starting size of the hash table, somewhat arbitrarily. +- Space for each entry is obtained with one malloc so we can free them +- easily. */ +- +- pspace_info->loaded_scripts = htab_create (31, +- hash_loaded_script_entry, +- eq_loaded_script_entry, +- xfree); +- +- pspace_info->script_not_found_warning_printed = FALSE; +-} +- +-/* Wrapper on get_auto_load_pspace_data to also allocate the hash table +- for loading scripts. */ +- +-static struct auto_load_pspace_info * +-get_auto_load_pspace_data_for_loading (struct program_space *pspace) +-{ +- struct auto_load_pspace_info *info; +- +- info = get_auto_load_pspace_data (pspace); +- if (info->loaded_scripts == NULL) +- init_loaded_scripts_info (info); +- +- return info; +-} +- +-/* Add script NAME to hash table HTAB. +- FULL_PATH is NULL if the script wasn't found. +- The result is true if the script was already in the hash table. */ +- +-static int +-maybe_add_script (struct htab *htab, const char *name, const char *full_path) +-{ +- struct loaded_script **slot, entry; +- int in_hash_table; +- +- entry.name = name; +- entry.full_path = full_path; +- slot = (struct loaded_script **) htab_find_slot (htab, &entry, INSERT); +- in_hash_table = *slot != NULL; +- +- /* If this script is not in the hash table, add it. */ +- +- if (! in_hash_table) +- { +- char *p; +- +- /* Allocate all space in one chunk so it's easier to free. */ +- *slot = xmalloc (sizeof (**slot) +- + strlen (name) + 1 +- + (full_path != NULL ? (strlen (full_path) + 1) : 0)); +- p = ((char*) *slot) + sizeof (**slot); +- strcpy (p, name); +- (*slot)->name = p; +- if (full_path != NULL) +- { +- p += strlen (p) + 1; +- strcpy (p, full_path); +- (*slot)->full_path = p; +- } +- else +- (*slot)->full_path = NULL; +- } +- +- return in_hash_table; +-} +- + /* Load scripts specified in OBJFILE. + START,END delimit a buffer containing a list of nul-terminated + file names. +@@ -301,20 +129,17 @@ source_section_scripts (struct objfile * + + IWBN if complaints.c were more general-purpose. */ + +- in_hash_table = maybe_add_script (pspace_info->loaded_scripts, file, ++ in_hash_table = maybe_add_script (pspace_info, file, + opened ? full_path : NULL); + + if (! opened) + { + /* We don't throw an error, the program is still debuggable. */ +- if (! pspace_info->script_not_found_warning_printed) +- { +- warning (_("Missing auto-load scripts referenced in section %s\n\ ++ 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-scripts [REGEXP]' to list them."), +- GDBPY_AUTO_SECTION_NAME, objfile->name); +- pspace_info->script_not_found_warning_printed = TRUE; +- } ++ GDBPY_AUTO_SECTION_NAME, objfile->name); + } + else + { +@@ -356,116 +181,6 @@ auto_load_section_scripts (struct objfil + do_cleanups (cleanups); + } + +-/* Clear the table of loaded section scripts. */ +- +-static void +-clear_section_scripts (void) +-{ +- struct program_space *pspace = current_program_space; +- struct auto_load_pspace_info *info; +- +- info = program_space_data (pspace, auto_load_pspace_data); +- if (info != NULL && info->loaded_scripts != NULL) +- { +- htab_delete (info->loaded_scripts); +- info->loaded_scripts = NULL; +- info->script_not_found_warning_printed = FALSE; +- } +-} +- +-/* Look for the auto-load script associated with OBJFILE and load it. */ +- +-static void +-auto_load_objfile_script (struct objfile *objfile, const char *suffix) +-{ +- char *realname; +- char *filename, *debugfile; +- int len; +- FILE *input; +- struct cleanup *cleanups; +- +- realname = gdb_realpath (objfile->name); +- len = strlen (realname); +- filename = xmalloc (len + strlen (suffix) + 1); +- memcpy (filename, realname, len); +- strcpy (filename + len, suffix); +- +- cleanups = make_cleanup (xfree, filename); +- make_cleanup (xfree, realname); +- +- input = fopen (filename, "r"); +- debugfile = filename; +- +- if (!input && debug_file_directory) +- { +- /* Also try the same file in the separate debug info directory. */ +- debugfile = xmalloc (strlen (filename) +- + strlen (debug_file_directory) + 1); +- strcpy (debugfile, debug_file_directory); +- /* FILENAME is absolute, so we don't need a "/" here. */ +- strcat (debugfile, filename); +- +- make_cleanup (xfree, debugfile); +- input = fopen (debugfile, "r"); +- } +- +- if (!input && gdb_datadir) +- { +- /* Also try the same file in a subdirectory of gdb's data +- directory. */ +- debugfile = xmalloc (strlen (gdb_datadir) + strlen (filename) +- + strlen ("/auto-load") + 1); +- strcpy (debugfile, gdb_datadir); +- strcat (debugfile, "/auto-load"); +- /* FILENAME is absolute, so we don't need a "/" here. */ +- strcat (debugfile, filename); +- +- make_cleanup (xfree, debugfile); +- input = fopen (debugfile, "r"); +- } +- +- if (input) +- { +- struct auto_load_pspace_info *pspace_info; +- +- make_cleanup_fclose (input); +- +- /* Add this script to the hash table too so "info auto-load-scripts" +- can print it. */ +- pspace_info = +- get_auto_load_pspace_data_for_loading (current_program_space); +- maybe_add_script (pspace_info->loaded_scripts, debugfile, debugfile); +- +- /* 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. */ +- source_python_script_for_objfile (objfile, input, debugfile); +- } +- +- do_cleanups (cleanups); +-} +- +-/* This is a new_objfile observer callback to auto-load scripts. +- +- Two flavors of auto-loaded scripts are supported. +- 1) based on the path to the objfile +- 2) from .debug_gdb_scripts section */ +- +-static void +-auto_load_new_objfile (struct objfile *objfile) +-{ +- if (!objfile) +- { +- /* OBJFILE is NULL when loading a new "main" symbol-file. */ +- clear_section_scripts (); +- return; +- } +- +- load_auto_scripts_for_objfile (objfile); +-} +- + /* Load any auto-loaded scripts for OBJFILE. */ + + void +@@ -478,146 +193,9 @@ load_auto_scripts_for_objfile (struct ob + } + } + +-/* Collect scripts to be printed in a vec. */ +- +-typedef struct loaded_script *loaded_script_ptr; +-DEF_VEC_P (loaded_script_ptr); +- +-/* Traversal function for htab_traverse. +- Collect the entry if it matches the regexp. */ +- +-static int +-collect_matching_scripts (void **slot, void *info) +-{ +- struct loaded_script *script = *slot; +- VEC (loaded_script_ptr) **scripts_ptr = info; +- +- if (re_exec (script->name)) +- VEC_safe_push (loaded_script_ptr, *scripts_ptr, script); +- +- return 1; +-} +- +-/* Print SCRIPT. */ +- +-static void +-print_script (struct loaded_script *script) +-{ +- struct ui_out *uiout = current_uiout; +- struct cleanup *chain; +- +- chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); +- +- ui_out_field_string (uiout, "loaded", script->full_path ? "Yes" : "Missing"); +- ui_out_field_string (uiout, "script", script->name); +- ui_out_text (uiout, "\n"); +- +- /* If the name isn't the full path, print it too. */ +- if (script->full_path != NULL +- && strcmp (script->name, script->full_path) != 0) +- { +- ui_out_text (uiout, "\tfull name: "); +- ui_out_field_string (uiout, "full_path", script->full_path); +- ui_out_text (uiout, "\n"); +- } +- +- do_cleanups (chain); +-} +- +-/* Helper for info_auto_load_scripts to sort the scripts by name. */ +- +-static int +-sort_scripts_by_name (const void *ap, const void *bp) +-{ +- const struct loaded_script *a = *(const struct loaded_script **) ap; +- const struct loaded_script *b = *(const struct loaded_script **) bp; +- +- return FILENAME_CMP (a->name, b->name); +-} +- +-/* "info auto-load-scripts" command. */ +- +-static void +-info_auto_load_scripts (char *pattern, int from_tty) +-{ +- struct ui_out *uiout = current_uiout; +- struct auto_load_pspace_info *pspace_info; +- struct cleanup *script_chain; +- VEC (loaded_script_ptr) *scripts; +- int nr_scripts; +- +- dont_repeat (); +- +- pspace_info = get_auto_load_pspace_data (current_program_space); +- +- if (pattern && *pattern) +- { +- char *re_err = re_comp (pattern); +- +- if (re_err) +- error (_("Invalid regexp: %s"), re_err); +- } +- else +- { +- re_comp (""); +- } +- +- /* We need to know the number of rows before we build the table. +- Plus we want to sort the scripts by name. +- So first traverse the hash table collecting the matching scripts. */ +- +- scripts = VEC_alloc (loaded_script_ptr, 10); +- script_chain = make_cleanup (VEC_cleanup (loaded_script_ptr), &scripts); +- +- if (pspace_info != NULL && pspace_info->loaded_scripts != NULL) +- { +- immediate_quit++; +- /* Pass a pointer to scripts as VEC_safe_push can realloc space. */ +- htab_traverse_noresize (pspace_info->loaded_scripts, +- collect_matching_scripts, &scripts); +- immediate_quit--; +- } +- +- nr_scripts = VEC_length (loaded_script_ptr, scripts); +- make_cleanup_ui_out_table_begin_end (uiout, 2, nr_scripts, +- "AutoLoadedScriptsTable"); +- +- ui_out_table_header (uiout, 7, ui_left, "loaded", "Loaded"); +- ui_out_table_header (uiout, 70, ui_left, "script", "Script"); +- ui_out_table_body (uiout); +- +- if (nr_scripts > 0) +- { +- int i; +- loaded_script_ptr script; +- +- qsort (VEC_address (loaded_script_ptr, scripts), +- VEC_length (loaded_script_ptr, scripts), +- sizeof (loaded_script_ptr), sort_scripts_by_name); +- for (i = 0; VEC_iterate (loaded_script_ptr, scripts, i, script); ++i) +- print_script (script); +- } +- +- do_cleanups (script_chain); +- +- if (nr_scripts == 0) +- { +- if (pattern && *pattern) +- ui_out_message (uiout, 0, "No auto-load scripts matching %s.\n", +- pattern); +- else +- ui_out_message (uiout, 0, "No auto-load scripts.\n"); +- } +-} +- + void + gdbpy_initialize_auto_load (void) + { +- auto_load_pspace_data +- = register_program_space_data_with_cleanup (auto_load_pspace_data_cleanup); +- +- observer_attach_new_objfile (auto_load_new_objfile); +- + add_setshow_boolean_cmd ("auto-load-scripts", class_support, + &auto_load_scripts, _("\ + Set the debugger's behaviour regarding auto-loaded scripts."), _("\ +@@ -627,11 +205,6 @@ an executable or shared library."), + NULL, NULL, + &setlist, + &showlist); +- +- add_info ("auto-load-scripts", +- info_auto_load_scripts, +- _("Print the list of automatically loaded scripts.\n\ +-Usage: info auto-load-scripts [REGEXP]")); + } + + #else /* ! HAVE_PYTHON */ +Index: gdb-7.4.50.20120120/gdb/python/python.h +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/python/python.h 2012-04-18 00:26:14.000000000 +0200 ++++ gdb-7.4.50.20120120/gdb/python/python.h 2012-04-18 00:26:29.054120199 +0200 +@@ -24,8 +24,6 @@ + + struct breakpoint_object; + +-extern int gdbpy_global_auto_load; +- + extern void finish_python_initialization (void); + + void eval_python_from_control_command (struct command_line *); diff --git a/gdb-autoload-10of12.patch b/gdb-autoload-10of12.patch new file mode 100644 index 0000000..c596982 --- /dev/null +++ b/gdb-autoload-10of12.patch @@ -0,0 +1,1704 @@ +[patch#4 4/8] set auto-load * main part +http://sourceware.org/ml/gdb-patches/2012-04/msg00088.html +http://sourceware.org/ml/gdb-cvs/2012-04/msg00113.html + +### src/gdb/ChangeLog 2012/04/17 15:49:11 1.14112 +### src/gdb/ChangeLog 2012/04/17 15:51:41 1.14113 +## -1,5 +1,101 @@ + 2012-04-17 Jan Kratochvil + ++ auto-load: Implementation. ++ * NEWS: New descriptions for "info auto-load", ++ "info auto-load gdb-scripts", "info auto-load python-scripts", ++ "info auto-load local-gdbinit" and "info auto-load libthread-db". ++ Deprecate "info auto-load-scripts", "set auto-load-scripts on|off" ++ and "show auto-load-scripts". New description for "set auto-load", ++ "show auto-load", "set auto-load gdb-scripts", ++ "show auto-load gdb-scripts", "set auto-load python-scripts", ++ "show auto-load python-scripts", "set auto-load local-gdbinit", ++ "show auto-load local-gdbinit", "set auto-load libthread-db" and ++ "show auto-load libthread-db". ++ * auto-load.c: Remove include python/python-internal.h. Add includes ++ exceptions.h, cli/cli-script.h, gdbcmd.h, cli/cli-decode.h and ++ cli/cli-setshow.h. ++ (GDB_AUTO_FILE_NAME, source_gdb_script_for_objfile) ++ (auto_load_gdb_scripts, show_auto_load_gdb_scripts): New. ++ (gdbpy_global_auto_load): Rename to ... ++ (global_auto_load): ... here. ++ (auto_load_local_gdbinit, auto_load_local_gdbinit_pathname) ++ (auto_load_local_gdbinit_loaded, show_auto_load_local_gdbinit) ++ (script_language_gdb, source_gdb_script_for_objfile): New. ++ (struct loaded_script): New field language. ++ (hash_loaded_script_entry, eq_loaded_script_entry): Calculate also ++ LANGUAGE. ++ (maybe_add_script): Add parameter language. Drop redundant ++ entry.full_path initialization. Initialize entry.language and ++ (*slot)->language. ++ (auto_load_objfile_script): Change parameter suffix to language. ++ Remove the call of maybe_add_script. ++ Call language->source_script_for_objfile. ++ (load_auto_scripts_for_objfile, struct collect_matching_scripts_data): ++ New. ++ (collect_matching_scripts): Adjust it for ++ struct collect_matching_scripts_data. ++ (auto_load_info_scripts_pattern_nl): New variable. ++ (info_auto_load_scripts): Rename to ... ++ (auto_load_info_scripts): ... here, add parameter language. Adjust it ++ for struct collect_matching_scripts_data. ++ (info_auto_load_gdb_scripts, info_auto_load_local_gdbinit) ++ (set_auto_load_cmd, auto_load_set_cmdlist_get, show_auto_load_cmd) ++ (auto_load_show_cmdlist_get, info_auto_load_cmd) ++ (auto_load_info_cmdlist_get): New. ++ (_initialize_auto_load): Move add_info of "auto-load-scripts" to ++ python/py-auto-load.c. New installment for "set auto-load gdb-scripts", ++ "info auto-load gdb-scripts", "set auto-load local-gdbinit" and ++ "info auto-load local-gdbinit". ++ * auto-load.h (struct script_language): New. ++ (gdbpy_global_auto_load): Rename to ... ++ (global_auto_load): ... here. ++ (auto_load_local_gdbinit, auto_load_local_gdbinit_pathname) ++ (auto_load_local_gdbinit_loaded): New declarations. ++ (maybe_add_script): New parameter language. ++ (auto_load_objfile_script): Change parameter suffix to language. ++ (load_auto_scripts_for_objfile, auto_load_info_scripts_pattern_nl) ++ (auto_load_info_scripts, auto_load_set_cmdlist_get) ++ (auto_load_show_cmdlist_get, auto_load_info_cmdlist_get): New ++ declarations. ++ * linux-thread-db.c: Include auto-load.h and ctype.h. ++ (auto_load_thread_db, show_auto_load_thread_db): New. ++ (struct thread_db_info): New field filename. ++ (delete_thread_db_info): Call xfree for FILENAME. ++ (try_thread_db_load): Initialize FILENAME. ++ (try_thread_db_load_from_pdir, try_thread_db_load_from_dir): Return ++ if !AUTO_LOAD_THREAD_DB. ++ (info_auto_load_libthread_db_compare, info_auto_load_libthread_db): New. ++ (_initialize_thread_db): Install auto_load_thread_db ++ as "set auto-load libthread-db" and install info_auto_load_libthread_db ++ as "info auto-load libthread-db". ++ * main.c (captured_main): Rename gdbpy_global_auto_load to ++ global_auto_load. Initialize AUTO_LOAD_LOCAL_GDBINIT_PATHNAME and ++ AUTO_LOAD_LOCAL_GDBINIT_LOADED. ++ (print_gdb_help): Extend the help for 'local init file'. ++ * python/py-auto-load.c: Remove a comment about gdb scripts extension. ++ (GDBPY_AUTO_SECTION_NAME): Extend the comment it is Python specific. ++ (auto_load_scripts): Rename to ... ++ (auto_load_python_scripts): ... here, update the comment. ++ (gdbpy_load_auto_script_for_objfile): New declaration. ++ (show_auto_load_python_scripts, script_language_python) ++ (gdbpy_load_auto_script_for_objfile): New. ++ (source_section_scripts): Refactor the code. ++ (load_auto_scripts_for_objfile): Rename to ... ++ (gdbpy_load_auto_scripts_for_objfile): ... here, update the ++ auto_load_objfile_script caller, drop GDBPY_GLOBAL_AUTO_LOAD checking. ++ (info_auto_load_python_scripts): New. ++ (gdbpy_initialize_auto_load): New variables cmd and cmd_name. ++ Rename "set auto-load-scripts" to "set auto-load python-scripts". ++ Register "set auto-load-scripts" as its deprecated alias. Register ++ "info auto-load python-scripts". Register "info auto-load-scripts" as ++ its deprecated alias. ++ (load_auto_scripts_for_objfile): Rename to ... ++ (gdbpy_load_auto_scripts_for_objfile): ... here. ++ * python/python.h (load_auto_scripts_for_objfile): Rename to ... ++ (gdbpy_load_auto_scripts_for_objfile): ... here. ++ ++2012-04-17 Jan Kratochvil ++ + auto-load: Move files. + * Makefile.in (SFILES): Add auto-load.c. + (HFILES_NO_SRCDIR): Add auto-load.h. +Index: gdb-7.4.50.20120120/gdb/NEWS +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/NEWS 2012-04-18 00:42:51.226681068 +0200 ++++ gdb-7.4.50.20120120/gdb/NEWS 2012-04-18 00:49:02.035737644 +0200 +@@ -28,6 +28,45 @@ + now set a breakpoint in build/gcc/expr.c, but not + build/libcpp/expr.c. + ++* New commands ++ ++ ** "info auto-load" shows status of all kinds of auto-loaded files, ++ "info auto-load gdb-scripts" shows status of auto-loading GDB canned ++ sequences of commands files, "info auto-load python-scripts" ++ shows status of auto-loading Python script files, ++ "info auto-load local-gdbinit" shows status of loading init file ++ (.gdbinit) from current directory and "info auto-load libthread-db" shows ++ status of inferior specific thread debugging shared library loading. ++ ++ ** "info auto-load-scripts", "set auto-load-scripts on|off" ++ and "show auto-load-scripts" commands have been deprecated, use their ++ "info auto-load python-scripts", "set auto-load python-scripts on|off" ++ and "show auto-load python-scripts" counterparts instead. ++ ++* New options ++ ++set auto-load off ++ Disable auto-loading globally. ++ ++show auto-load ++ Show auto-loading setting of all kinds of auto-loaded files. ++ ++set auto-load gdb-scripts on|off ++show auto-load gdb-scripts ++ Control auto-loading of GDB canned sequences of commands files. ++ ++set auto-load python-scripts on|off ++show auto-load python-scripts ++ Control auto-loading of Python script files. ++ ++set auto-load local-gdbinit on|off ++show auto-load local-gdbinit ++ Control loading of init file (.gdbinit) from current directory. ++ ++set auto-load libthread-db on|off ++show auto-load libthread-db ++ Control auto-loading of inferior specific thread debugging shared library. ++ + * New command line options + + --init-command=FILE, -ix Like --command, -x but execute it +Index: gdb-7.4.50.20120120/gdb/auto-load.c +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/auto-load.c 2012-04-18 00:44:26.950437520 +0200 ++++ gdb-7.4.50.20120120/gdb/auto-load.c 2012-04-18 00:46:47.556079780 +0200 +@@ -27,19 +27,92 @@ + #include "command.h" + #include "observer.h" + #include "objfiles.h" +-#include "python/python-internal.h" ++#include "exceptions.h" ++#include "cli/cli-script.h" ++#include "gdbcmd.h" ++#include "cli/cli-decode.h" ++#include "cli/cli-setshow.h" ++ ++/* 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" ++ ++static void source_gdb_script_for_objfile (struct objfile *objfile, FILE *file, ++ const char *filename); ++ ++/* User-settable option to enable/disable auto-loading of GDB_AUTO_FILE_NAME ++ scripts: ++ set auto-load gdb-scripts on|off ++ This is true if we should auto-load associated scripts when an objfile ++ is opened, false otherwise. */ ++static int auto_load_gdb_scripts = 1; ++ ++/* "show" command for the auto_load_gdb_scripts configuration variable. */ ++ ++static void ++show_auto_load_gdb_scripts (struct ui_file *file, int from_tty, ++ struct cmd_list_element *c, const char *value) ++{ ++ fprintf_filtered (file, _("Auto-loading of canned sequences of commands " ++ "scripts is %s.\n"), ++ value); ++} + + /* 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. + +- Both auto_load_scripts && gdbpy_global_auto_load must be true to enable ++ Both auto_load_scripts && global_auto_load must be true to enable + auto-loading. + + This flag exists to facilitate deferring auto-loading during start-up + until after ./.gdbinit has been read; it may augment the search directories + used to find the scripts. */ +-int gdbpy_global_auto_load = 1; ++int global_auto_load = 1; ++ ++/* Auto-load .gdbinit file from the current directory? */ ++int auto_load_local_gdbinit = 1; ++ ++/* Absolute pathname to the current directory .gdbinit, if it exists. */ ++char *auto_load_local_gdbinit_pathname = NULL; ++ ++/* Boolean value if AUTO_LOAD_LOCAL_GDBINIT_PATHNAME has been loaded. */ ++int auto_load_local_gdbinit_loaded = 0; ++ ++/* "show" command for the auto_load_local_gdbinit configuration variable. */ ++ ++static void ++show_auto_load_local_gdbinit (struct ui_file *file, int from_tty, ++ struct cmd_list_element *c, const char *value) ++{ ++ fprintf_filtered (file, _("Auto-loading of .gdbinit script from current " ++ "directory is %s.\n"), ++ value); ++} ++ ++/* 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 void ++source_gdb_script_for_objfile (struct objfile *objfile, FILE *file, ++ const char *filename) ++{ ++ struct auto_load_pspace_info *pspace_info; ++ volatile struct gdb_exception e; ++ ++ /* 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, filename, filename, &script_language_gdb); ++ ++ TRY_CATCH (e, RETURN_MASK_ALL) ++ { ++ script_from_file (file, filename); ++ } ++ exception_print (gdb_stderr, e); ++} + + /* For scripts specified in .debug_gdb_scripts, multiple objfiles may load + the same script. There's no point in loading the script multiple times, +@@ -62,9 +135,12 @@ struct loaded_script + { + /* Name as provided by the objfile. */ + const char *name; ++ + /* Full path name or NULL if script wasn't found (or was otherwise + inaccessible). */ + const char *full_path; ++ ++ const struct script_language *language; + }; + + /* Per-program-space data key. */ +@@ -109,7 +185,7 @@ hash_loaded_script_entry (const void *da + { + const struct loaded_script *e = data; + +- return htab_hash_string (e->name); ++ return htab_hash_string (e->name) ^ htab_hash_pointer (e->language); + } + + /* Equality function for the loaded script hash. */ +@@ -120,7 +196,7 @@ eq_loaded_script_entry (const void *a, c + const struct loaded_script *ea = a; + const struct loaded_script *eb = b; + +- return strcmp (ea->name, eb->name) == 0; ++ return strcmp (ea->name, eb->name) == 0 && ea->language == eb->language; + } + + /* Initialize the table to track loaded scripts. +@@ -156,20 +232,21 @@ get_auto_load_pspace_data_for_loading (s + return info; + } + +-/* Add script NAME to hash table of PSPACE_INFO. +- FULL_PATH is NULL if the script wasn't found. +- The result is true if the script was already in the hash table. */ ++/* Add script NAME in LANGUAGE to hash table of PSPACE_INFO. ++ FULL_PATH is NULL if the script wasn't found. The result is ++ true if the script was already in the hash table. */ + + int +-maybe_add_script (struct auto_load_pspace_info *pspace_info, const char *name, +- const char *full_path) ++maybe_add_script (struct auto_load_pspace_info *pspace_info, ++ const char *name, const char *full_path, ++ const struct script_language *language) + { + struct htab *htab = pspace_info->loaded_scripts; + struct loaded_script **slot, entry; + int in_hash_table; + + entry.name = name; +- entry.full_path = full_path; ++ entry.language = language; + slot = (struct loaded_script **) htab_find_slot (htab, &entry, INSERT); + in_hash_table = *slot != NULL; + +@@ -194,6 +271,7 @@ maybe_add_script (struct auto_load_pspac + } + else + (*slot)->full_path = NULL; ++ (*slot)->language = language; + } + + return in_hash_table; +@@ -216,10 +294,12 @@ clear_section_scripts (void) + } + } + +-/* Look for the auto-load script associated with OBJFILE and load it. */ ++/* Look for the auto-load script in LANGUAGE associated with OBJFILE and load ++ it. */ + + void +-auto_load_objfile_script (struct objfile *objfile, const char *suffix) ++auto_load_objfile_script (struct objfile *objfile, ++ const struct script_language *language) + { + char *realname; + char *filename, *debugfile; +@@ -229,9 +309,9 @@ auto_load_objfile_script (struct objfile + + realname = gdb_realpath (objfile->name); + len = strlen (realname); +- filename = xmalloc (len + strlen (suffix) + 1); ++ filename = xmalloc (len + strlen (language->suffix) + 1); + memcpy (filename, realname, len); +- strcpy (filename + len, suffix); ++ strcpy (filename + len, language->suffix); + + cleanups = make_cleanup (xfree, filename); + make_cleanup (xfree, realname); +@@ -269,27 +349,33 @@ auto_load_objfile_script (struct objfile + + if (input) + { +- struct auto_load_pspace_info *pspace_info; +- + make_cleanup_fclose (input); + +- /* Add this script to the hash table too so "info auto-load-scripts" +- can print it. */ +- pspace_info = +- get_auto_load_pspace_data_for_loading (current_program_space); +- maybe_add_script (pspace_info, debugfile, debugfile); +- + /* 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. */ +- source_python_script_for_objfile (objfile, input, debugfile); ++ language->source_script_for_objfile (objfile, input, debugfile); + } + + do_cleanups (cleanups); + } + ++/* Load any auto-loaded scripts for OBJFILE. */ ++ ++void ++load_auto_scripts_for_objfile (struct objfile *objfile) ++{ ++ if (!global_auto_load) ++ return; ++ ++ if (auto_load_gdb_scripts) ++ auto_load_objfile_script (objfile, &script_language_gdb); ++ ++ gdbpy_load_auto_scripts_for_objfile (objfile); ++} ++ + /* This is a new_objfile observer callback to auto-load scripts. + + Two flavors of auto-loaded scripts are supported. +@@ -314,6 +400,13 @@ auto_load_new_objfile (struct objfile *o + typedef struct loaded_script *loaded_script_ptr; + DEF_VEC_P (loaded_script_ptr); + ++struct collect_matching_scripts_data ++{ ++ VEC (loaded_script_ptr) **scripts_p; ++ ++ const struct script_language *language; ++}; ++ + /* Traversal function for htab_traverse. + Collect the entry if it matches the regexp. */ + +@@ -321,10 +414,10 @@ static int + collect_matching_scripts (void **slot, void *info) + { + struct loaded_script *script = *slot; +- VEC (loaded_script_ptr) **scripts_ptr = info; ++ struct collect_matching_scripts_data *data = info; + +- if (re_exec (script->name)) +- VEC_safe_push (loaded_script_ptr, *scripts_ptr, script); ++ if (script->language == data->language && re_exec (script->name)) ++ VEC_safe_push (loaded_script_ptr, *data->scripts_p, script); + + return 1; + } +@@ -366,10 +459,18 @@ sort_scripts_by_name (const void *ap, co + return FILENAME_CMP (a->name, b->name); + } + +-/* "info auto-load-scripts" command. */ ++/* Special internal GDB value of auto_load_info_scripts's PATTERN identify ++ the "info auto-load XXX" command has been executed through the general ++ "info auto-load" invocation. Extra newline will be printed if needed. */ ++char auto_load_info_scripts_pattern_nl[] = ""; ++ ++/* Implementation for "info auto-load gdb-scripts" ++ (and "info auto-load python-scripts"). List scripts in LANGUAGE matching ++ PATTERN. FROM_TTY is the usual GDB boolean for user interactivity. */ + +-static void +-info_auto_load_scripts (char *pattern, int from_tty) ++void ++auto_load_info_scripts (char *pattern, int from_tty, ++ const struct script_language *language) + { + struct ui_out *uiout = current_uiout; + struct auto_load_pspace_info *pspace_info; +@@ -402,14 +503,22 @@ info_auto_load_scripts (char *pattern, i + + if (pspace_info != NULL && pspace_info->loaded_scripts != NULL) + { ++ struct collect_matching_scripts_data data = { &scripts, language }; ++ + immediate_quit++; + /* Pass a pointer to scripts as VEC_safe_push can realloc space. */ + htab_traverse_noresize (pspace_info->loaded_scripts, +- collect_matching_scripts, &scripts); ++ collect_matching_scripts, &data); + immediate_quit--; + } + + nr_scripts = VEC_length (loaded_script_ptr, scripts); ++ ++ /* Table header shifted right by preceding "gdb-scripts: " would not match ++ its columns. */ ++ if (nr_scripts > 0 && pattern == auto_load_info_scripts_pattern_nl) ++ ui_out_text (uiout, "\n"); ++ + make_cleanup_ui_out_table_begin_end (uiout, 2, nr_scripts, + "AutoLoadedScriptsTable"); + +@@ -441,6 +550,29 @@ info_auto_load_scripts (char *pattern, i + } + } + ++/* Wrapper for "info auto-load gdb-scripts". */ ++ ++static void ++info_auto_load_gdb_scripts (char *pattern, int from_tty) ++{ ++ auto_load_info_scripts (pattern, from_tty, &script_language_gdb); ++} ++ ++/* Implement 'info auto-load local-gdbinit'. */ ++ ++static void ++info_auto_load_local_gdbinit (char *args, int from_tty) ++{ ++ if (auto_load_local_gdbinit_pathname == NULL) ++ printf_filtered (_("Local .gdbinit file was not found.\n")); ++ else if (auto_load_local_gdbinit_loaded) ++ printf_filtered (_("Local .gdbinit file \"%s\" has been loaded.\n"), ++ auto_load_local_gdbinit_pathname); ++ else ++ printf_filtered (_("Local .gdbinit file \"%s\" has not been loaded.\n"), ++ auto_load_local_gdbinit_pathname); ++} ++ + /* Return non-zero if SCRIPT_NOT_FOUND_WARNING_PRINTED of PSPACE_INFO was unset + before calling this function. Always set SCRIPT_NOT_FOUND_WARNING_PRINTED + of PSPACE_INFO. */ +@@ -455,6 +587,132 @@ script_not_found_warning_print (struct a + return retval; + } + ++/* The only valid "set auto-load" argument is off|0|no|disable. */ ++ ++static void ++set_auto_load_cmd (char *args, int from_tty) ++{ ++ struct cmd_list_element *list; ++ size_t length; ++ ++ /* See parse_binary_operation in use by the sub-commands. */ ++ ++ length = args ? strlen (args) : 0; ++ ++ while (length > 0 && (args[length - 1] == ' ' || args[length - 1] == '\t')) ++ length--; ++ ++ if (length == 0 || (strncmp (args, "off", length) != 0 ++ && strncmp (args, "0", length) != 0 ++ && strncmp (args, "no", length) != 0 ++ && strncmp (args, "disable", length) != 0)) ++ error (_("Valid is only global 'set auto-load no'; " ++ "otherwise check the auto-load sub-commands.")); ++ ++ for (list = *auto_load_set_cmdlist_get (); list != NULL; list = list->next) ++ if (list->var_type == var_boolean) ++ { ++ gdb_assert (list->type == set_cmd); ++ do_setshow_command (args, from_tty, list); ++ } ++} ++ ++/* Initialize "set auto-load " commands prefix and return it. */ ++ ++struct cmd_list_element ** ++auto_load_set_cmdlist_get (void) ++{ ++ static struct cmd_list_element *retval; ++ ++ if (retval == NULL) ++ add_prefix_cmd ("auto-load", class_maintenance, set_auto_load_cmd, _("\ ++Auto-loading specific settings.\n\ ++Configure various auto-load-specific variables such as\n\ ++automatic loading of Python scripts."), ++ &retval, "set auto-load ", ++ 1/*allow-unknown*/, &setlist); ++ ++ return &retval; ++} ++ ++/* Command "show auto-load" displays summary of all the current ++ "show auto-load " settings. */ ++ ++static void ++show_auto_load_cmd (char *args, int from_tty) ++{ ++ cmd_show_list (*auto_load_show_cmdlist_get (), from_tty, ""); ++} ++ ++/* Initialize "show auto-load " commands prefix and return it. */ ++ ++struct cmd_list_element ** ++auto_load_show_cmdlist_get (void) ++{ ++ static struct cmd_list_element *retval; ++ ++ if (retval == NULL) ++ add_prefix_cmd ("auto-load", class_maintenance, show_auto_load_cmd, _("\ ++Show auto-loading specific settings.\n\ ++Show configuration of various auto-load-specific variables such as\n\ ++automatic loading of Python scripts."), ++ &retval, "show auto-load ", ++ 0/*allow-unknown*/, &showlist); ++ ++ return &retval; ++} ++ ++/* Command "info auto-load" displays whether the various auto-load files have ++ been loaded. This is reimplementation of cmd_show_list which inserts ++ newlines at proper places. */ ++ ++static void ++info_auto_load_cmd (char *args, int from_tty) ++{ ++ struct cmd_list_element *list; ++ struct cleanup *infolist_chain; ++ struct ui_out *uiout = current_uiout; ++ ++ infolist_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "infolist"); ++ ++ for (list = *auto_load_info_cmdlist_get (); list != NULL; list = list->next) ++ { ++ struct cleanup *option_chain ++ = make_cleanup_ui_out_tuple_begin_end (uiout, "option"); ++ ++ gdb_assert (!list->prefixlist); ++ gdb_assert (list->type == not_set_cmd); ++ ++ ui_out_field_string (uiout, "name", list->name); ++ ui_out_text (uiout, ": "); ++ cmd_func (list, auto_load_info_scripts_pattern_nl, from_tty); ++ ++ /* Close the tuple. */ ++ do_cleanups (option_chain); ++ } ++ ++ /* Close the tuple. */ ++ do_cleanups (infolist_chain); ++} ++ ++/* Initialize "info auto-load " commands prefix and return it. */ ++ ++struct cmd_list_element ** ++auto_load_info_cmdlist_get (void) ++{ ++ static struct cmd_list_element *retval; ++ ++ if (retval == NULL) ++ add_prefix_cmd ("auto-load", class_info, info_auto_load_cmd, _("\ ++Print current status of auto-loaded files.\n\ ++Print whether various files like Python scripts or .gdbinit files have been\n\ ++found and/or loaded."), ++ &retval, "info auto-load ", ++ 0/*allow-unknown*/, &infolist); ++ ++ return &retval; ++} ++ + void _initialize_auto_load (void); + + void +@@ -465,8 +723,38 @@ _initialize_auto_load (void) + + observer_attach_new_objfile (auto_load_new_objfile); + +- add_info ("auto-load-scripts", +- info_auto_load_scripts, +- _("Print the list of automatically loaded scripts.\n\ +-Usage: info auto-load-scripts [REGEXP]")); ++ add_setshow_boolean_cmd ("gdb-scripts", class_support, ++ &auto_load_gdb_scripts, _("\ ++Enable or disable auto-loading of canned sequences of commands scripts."), _("\ ++Show whether auto-loading of canned sequences of commands scripts is enabled."), ++ _("\ ++If enabled, canned sequences of commands are loaded when the debugger reads\n\ ++an executable or shared library.\n\ ++This options has security implications for untrusted inferiors."), ++ NULL, show_auto_load_gdb_scripts, ++ auto_load_set_cmdlist_get (), ++ auto_load_show_cmdlist_get ()); ++ ++ add_cmd ("gdb-scripts", class_info, info_auto_load_gdb_scripts, ++ _("Print the list of automatically loaded sequences of commands.\n\ ++Usage: info auto-load gdb-scripts [REGEXP]"), ++ auto_load_info_cmdlist_get ()); ++ ++ add_setshow_boolean_cmd ("local-gdbinit", class_support, ++ &auto_load_local_gdbinit, _("\ ++Enable or disable auto-loading of .gdbinit script in current directory."), _("\ ++Show whether auto-loading .gdbinit script in current directory is enabled."), ++ _("\ ++If enabled, canned sequences of commands are loaded when debugger starts\n\ ++from .gdbinit file in current directory. Such files are deprecated,\n\ ++use a script associated with inferior executable file instead.\n\ ++This options has security implications for untrusted inferiors."), ++ NULL, show_auto_load_local_gdbinit, ++ auto_load_set_cmdlist_get (), ++ auto_load_show_cmdlist_get ()); ++ ++ add_cmd ("local-gdbinit", class_info, info_auto_load_local_gdbinit, ++ _("Print whether current directory .gdbinit file has been loaded.\n\ ++Usage: info auto-load local-gdbinit"), ++ auto_load_info_cmdlist_get ()); + } +Index: gdb-7.4.50.20120120/gdb/auto-load.h +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/auto-load.h 2012-04-18 00:44:26.951437517 +0200 ++++ gdb-7.4.50.20120120/gdb/auto-load.h 2012-04-18 00:46:47.556079780 +0200 +@@ -22,15 +22,36 @@ + + struct program_space; + +-extern int gdbpy_global_auto_load; ++struct script_language ++{ ++ const char *suffix; ++ ++ void (*source_script_for_objfile) (struct objfile *objfile, FILE *file, ++ const char *filename); ++}; ++ ++extern int global_auto_load; ++ ++extern int auto_load_local_gdbinit; ++extern char *auto_load_local_gdbinit_pathname; ++extern int auto_load_local_gdbinit_loaded; + + extern struct auto_load_pspace_info * + get_auto_load_pspace_data_for_loading (struct program_space *pspace); + extern int maybe_add_script (struct auto_load_pspace_info *pspace_info, +- const char *name, const char *full_path); ++ const char *name, const char *full_path, ++ const struct script_language *language); + extern void auto_load_objfile_script (struct objfile *objfile, +- const char *suffix); ++ 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); ++extern char auto_load_info_scripts_pattern_nl[]; ++extern void auto_load_info_scripts (char *pattern, int from_tty, ++ const struct script_language *language); ++ ++extern struct cmd_list_element **auto_load_set_cmdlist_get (void); ++extern struct cmd_list_element **auto_load_show_cmdlist_get (void); ++extern struct cmd_list_element **auto_load_info_cmdlist_get (void); + + #endif /* AUTO_LOAD_H */ +Index: gdb-7.4.50.20120120/gdb/linux-thread-db.c +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/linux-thread-db.c 2012-01-04 09:17:05.000000000 +0100 ++++ gdb-7.4.50.20120120/gdb/linux-thread-db.c 2012-04-18 00:46:47.557079777 +0200 +@@ -40,8 +40,10 @@ + #include "observer.h" + #include "linux-nat.h" + #include "linux-procfs.h" ++#include "auto-load.h" + + #include ++#include + + #ifdef HAVE_GNU_LIBC_VERSION_H + #include +@@ -75,6 +77,21 @@ + + static char *libthread_db_search_path; + ++/* Set to non-zero if thread_db auto-loading is enabled ++ by the "set auto-load libthread-db" command. */ ++static int auto_load_thread_db = 1; ++ ++/* "show" command for the auto_load_thread_db configuration variable. */ ++ ++static void ++show_auto_load_thread_db (struct ui_file *file, int from_tty, ++ struct cmd_list_element *c, const char *value) ++{ ++ fprintf_filtered (file, _("Auto-loading of inferior specific libthread_db " ++ "is %s.\n"), ++ value); ++} ++ + static void + set_libthread_db_search_path (char *ignored, int from_tty, + struct cmd_list_element *c) +@@ -119,6 +136,10 @@ struct thread_db_info + /* Handle from dlopen for libthread_db.so. */ + void *handle; + ++ /* Absolute pathname from gdb_realpath to disk file used for dlopen-ing ++ HANDLE. It may be NULL for system library. */ ++ char *filename; ++ + /* Structure that identifies the child process for the + interface. */ + struct ps_prochandle proc_handle; +@@ -248,6 +269,8 @@ delete_thread_db_info (int pid) + if (info->handle != NULL) + dlclose (info->handle); + ++ xfree (info->filename); ++ + if (info_prev) + info_prev->next = info->next; + else +@@ -807,6 +830,10 @@ try_thread_db_load (const char *library) + + info = add_thread_db_info (handle); + ++ /* Do not save system library name, that one is always trusted. */ ++ if (strchr (library, '/') != NULL) ++ info->filename = gdb_realpath (library); ++ + if (try_thread_db_load_1 (info)) + return 1; + +@@ -856,6 +883,9 @@ try_thread_db_load_from_pdir (void) + { + struct objfile *obj; + ++ if (!auto_load_thread_db) ++ return 0; ++ + ALL_OBJFILES (obj) + if (libpthread_name_p (obj->name)) + { +@@ -895,6 +925,9 @@ try_thread_db_load_from_dir (const char + char *path; + int result; + ++ if (!auto_load_thread_db) ++ return 0; ++ + path = xmalloc (dir_len + 1 + strlen (LIBTHREAD_DB_SO) + 1); + cleanup = make_cleanup (xfree, path); + +@@ -1802,6 +1835,150 @@ thread_db_resume (struct target_ops *ops + beneath->to_resume (beneath, ptid, step, signo); + } + ++/* qsort helper function for info_auto_load_libthread_db, sort the ++ thread_db_info pointers primarily by their FILENAME and secondarily by their ++ PID, both in ascending order. */ ++ ++static int ++info_auto_load_libthread_db_compare (const void *ap, const void *bp) ++{ ++ struct thread_db_info *a = *(struct thread_db_info **) ap; ++ struct thread_db_info *b = *(struct thread_db_info **) bp; ++ int retval; ++ ++ retval = strcmp (a->filename, b->filename); ++ if (retval) ++ return retval; ++ ++ return (a->pid > b->pid) - (a->pid - b->pid); ++} ++ ++/* Implement 'info auto-load libthread-db'. */ ++ ++static void ++info_auto_load_libthread_db (char *args, int from_tty) ++{ ++ struct ui_out *uiout = current_uiout; ++ const char *cs = args ? args : ""; ++ struct thread_db_info *info, **array; ++ unsigned info_count, unique_filenames; ++ size_t max_filename_len, max_pids_len, pids_len; ++ struct cleanup *back_to; ++ char *pids; ++ int i; ++ ++ while (isspace (*cs)) ++ cs++; ++ if (*cs) ++ error (_("'info auto-load libthread-db' does not accept any parameters")); ++ ++ info_count = 0; ++ for (info = thread_db_list; info; info = info->next) ++ if (info->filename != NULL) ++ info_count++; ++ ++ array = xmalloc (sizeof (*array) * info_count); ++ back_to = make_cleanup (xfree, array); ++ ++ info_count = 0; ++ for (info = thread_db_list; info; info = info->next) ++ if (info->filename != NULL) ++ array[info_count++] = info; ++ ++ /* Sort ARRAY by filenames and PIDs. */ ++ ++ qsort (array, info_count, sizeof (*array), ++ info_auto_load_libthread_db_compare); ++ ++ /* Calculate the number of unique filenames (rows) and the maximum string ++ length of PIDs list for the unique filenames (columns). */ ++ ++ unique_filenames = 0; ++ max_filename_len = 0; ++ max_pids_len = 0; ++ pids_len = 0; ++ for (i = 0; i < info_count; i++) ++ { ++ int pid = array[i]->pid; ++ size_t this_pid_len; ++ ++ for (this_pid_len = 0; pid != 0; pid /= 10) ++ this_pid_len++; ++ ++ if (i == 0 || strcmp (array[i - 1]->filename, array[i]->filename) != 0) ++ { ++ unique_filenames++; ++ max_filename_len = max (max_filename_len, ++ strlen (array[i]->filename)); ++ ++ if (i > 0) ++ { ++ pids_len -= strlen (", "); ++ max_pids_len = max (max_pids_len, pids_len); ++ } ++ pids_len = 0; ++ } ++ pids_len += this_pid_len + strlen (", "); ++ } ++ if (i) ++ { ++ pids_len -= strlen (", "); ++ max_pids_len = max (max_pids_len, pids_len); ++ } ++ ++ /* Table header shifted right by preceding "libthread-db: " would not match ++ its columns. */ ++ if (info_count > 0 && args == auto_load_info_scripts_pattern_nl) ++ ui_out_text (uiout, "\n"); ++ ++ make_cleanup_ui_out_table_begin_end (uiout, 2, unique_filenames, ++ "LinuxThreadDbTable"); ++ ++ ui_out_table_header (uiout, max_filename_len, ui_left, "filename", ++ "Filename"); ++ ui_out_table_header (uiout, pids_len, ui_left, "PIDs", "Pids"); ++ ui_out_table_body (uiout); ++ ++ pids = xmalloc (max_pids_len + 1); ++ make_cleanup (xfree, pids); ++ ++ /* Note I is incremented inside the cycle, not at its end. */ ++ for (i = 0; i < info_count;) ++ { ++ struct cleanup *chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); ++ char *pids_end; ++ ++ info = array[i]; ++ ui_out_field_string (uiout, "filename", info->filename); ++ pids_end = pids; ++ ++ while (i < info_count && strcmp (info->filename, array[i]->filename) == 0) ++ { ++ if (pids_end != pids) ++ { ++ *pids_end++ = ','; ++ *pids_end++ = ' '; ++ } ++ pids_end += xsnprintf (pids_end, &pids[max_pids_len + 1] - pids_end, ++ "%u", array[i]->pid); ++ gdb_assert (pids_end < &pids[max_pids_len + 1]); ++ ++ i++; ++ } ++ *pids_end = '\0'; ++ ++ ui_out_field_string (uiout, "pids", pids); ++ ++ ui_out_text (uiout, "\n"); ++ do_cleanups (chain); ++ } ++ ++ do_cleanups (back_to); ++ ++ if (info_count == 0) ++ ui_out_message (uiout, 0, _("No auto-loaded libthread-db.\n")); ++} ++ + static void + init_thread_db_ops (void) + { +@@ -1863,6 +2040,23 @@ When non-zero, libthread-db debugging is + show_libthread_db_debug, + &setdebuglist, &showdebuglist); + ++ add_setshow_boolean_cmd ("libthread-db", class_support, ++ &auto_load_thread_db, _("\ ++Enable or disable auto-loading of inferior specific libthread_db."), _("\ ++Show whether auto-loading inferior specific libthread_db is enabled."), _("\ ++If enabled, libthread_db will be searched in 'set libthread-db-search-path'\n\ ++locations to load libthread_db compatible with the inferior.\n\ ++Standard system libthread_db still gets loaded even with this option off.\n\ ++This options has security implications for untrusted inferiors."), ++ NULL, show_auto_load_thread_db, ++ auto_load_set_cmdlist_get (), ++ auto_load_show_cmdlist_get ()); ++ ++ add_cmd ("libthread-db", class_info, info_auto_load_libthread_db, ++ _("Print the list of loaded inferior specific libthread_db.\n\ ++Usage: info auto-load libthread-db"), ++ auto_load_info_cmdlist_get ()); ++ + /* Add ourselves to objfile event chain. */ + observer_attach_new_objfile (thread_db_new_objfile); + +Index: gdb-7.4.50.20120120/gdb/main.c +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/main.c 2012-04-18 00:44:26.957437503 +0200 ++++ gdb-7.4.50.20120120/gdb/main.c 2012-04-18 00:46:47.557079777 +0200 +@@ -945,8 +945,8 @@ captured_main (void *data) + /* Skip auto-loading section-specified scripts until we've sourced + local_gdbinit (which is often used to augment the source search + path). */ +- save_auto_load = gdbpy_global_auto_load; +- gdbpy_global_auto_load = 0; ++ save_auto_load = global_auto_load; ++ global_auto_load = 0; + + if (execarg != NULL + && symarg != NULL +@@ -1022,14 +1022,24 @@ captured_main (void *data) + + /* Read the .gdbinit file in the current directory, *if* it isn't + the same as the $HOME/.gdbinit file (it should exist, also). */ +- if (local_gdbinit && !inhibit_gdbinit) +- catch_command_errors (source_script, local_gdbinit, 0, RETURN_MASK_ALL); ++ if (local_gdbinit) ++ { ++ auto_load_local_gdbinit_pathname = gdb_realpath (local_gdbinit); ++ ++ if (!inhibit_gdbinit && auto_load_local_gdbinit) ++ { ++ auto_load_local_gdbinit_loaded = 1; ++ ++ catch_command_errors (source_script, local_gdbinit, 0, ++ RETURN_MASK_ALL); ++ } ++ } + + /* Now that all .gdbinit's have been read and all -d options have been + processed, we can read any scripts mentioned in SYMARG. + We wait until now because it is common to add to the source search + path in local_gdbinit. */ +- gdbpy_global_auto_load = save_auto_load; ++ global_auto_load = save_auto_load; + ALL_OBJFILES (objfile) + load_auto_scripts_for_objfile (objfile); + +@@ -1196,7 +1206,7 @@ At startup, GDB reads the following init + "), home_gdbinit); + if (local_gdbinit) + fprintf_unfiltered (stream, _("\ +- * local init file: ./%s\n\ ++ * local init file (see also 'set auto-load local-gdbinit'): ./%s\n\ + "), local_gdbinit); + fputs_unfiltered (_("\n\ + For more information, type \"help\" from within GDB, or consult the\n\ +Index: gdb-7.4.50.20120120/gdb/doc/gdb.texinfo +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/doc/gdb.texinfo 2012-04-18 00:44:26.928437577 +0200 ++++ gdb-7.4.50.20120120/gdb/doc/gdb.texinfo 2012-04-18 00:46:47.558079774 +0200 +@@ -1034,6 +1034,7 @@ You can run @value{GDBN} in various alte + batch mode or quiet mode. + + @table @code ++@anchor{-nx} + @item -nx + @itemx -n + @cindex @code{--nx} +@@ -1265,6 +1266,7 @@ Here's the description of what @value{GD + Sets up the command interpreter as specified by the command line + (@pxref{Mode Options, interpreter}). + ++@anchor{Option -init-eval-command} + @item + Executes commands and command files specified by the @samp{-iex} and + @samp{-ix} options in their specified order. Usually you should use the +@@ -1279,6 +1281,7 @@ used when building @value{GDBN}; @pxref{ + ,System-wide configuration and settings}) and executes all the commands in + that file. + ++@anchor{Home Directory Init File} + @item + Reads the init file (if any) in your home directory@footnote{On + DOS/Windows systems, the home directory is the one pointed to by the +@@ -1288,9 +1291,12 @@ that file. + @item + Processes command line options and operands. + ++@anchor{Init File in the Current Directory during Startup} + @item + Reads and executes the commands from init file (if any) in the current +-working directory. This is only done if the current directory is ++working directory as long as @samp{set auto-load local-gdbinit} is set to ++@samp{on} (@pxref{Init File in the Current Directory}). ++This is only done if the current directory is + different from your home directory. Thus, you can have more than one + init file, one generic in your home directory, and another, specific + to the program you are debugging, in the directory where you invoke +@@ -1306,7 +1312,7 @@ If you wish to disable the auto-loading + you must do something like the following: + + @smallexample +-$ gdb -iex "set auto-load-scripts off" myprogram ++$ gdb -iex "set auto-load python-scripts off" myprogram + @end smallexample + + Option @samp{-ex} does not work because the auto-loading is then turned +@@ -2891,6 +2897,7 @@ programs with multiple threads. + @xref{Set Watchpoints,,Setting Watchpoints}, for information about + watchpoints in programs with multiple threads. + ++@anchor{set libthread-db-search-path} + @table @code + @kindex set libthread-db-search-path + @cindex search path for @code{libthread_db} +@@ -2905,11 +2912,15 @@ macro. + On @sc{gnu}/Linux and Solaris systems, @value{GDBN} uses a ``helper'' + @code{libthread_db} library to obtain information about threads in the + inferior process. @value{GDBN} will use @samp{libthread-db-search-path} +-to find @code{libthread_db}. ++to find @code{libthread_db}. @value{GDBN} also consults first if inferior ++specific thread debugging library loading is enabled ++by @samp{set auto-load libthread-db} (@pxref{libthread_db.so.1 file}). + + A special entry @samp{$sdir} for @samp{libthread-db-search-path} + refers to the default system directories that are +-normally searched for loading shared libraries. ++normally searched for loading shared libraries. The @samp{$sdir} entry ++is the only kind not needing to be enabled by @samp{set auto-load libthread-db} ++(@pxref{libthread_db.so.1 file}). + + A special entry @samp{$pdir} for @samp{libthread-db-search-path} + refers to the directory from which @code{libpthread} +@@ -20320,6 +20331,7 @@ described here. + * Screen Size:: Screen size + * Numbers:: Numbers + * ABI:: Configuring the current ABI ++* Auto-loading:: Automatically loading associated files + * Messages/Warnings:: Optional warnings and messages + * Debugging Output:: Optional messages about internal happenings + * Other Misc Settings:: Other Miscellaneous Settings +@@ -20745,6 +20757,227 @@ With no argument, show the list of suppo + Set the current C@t{++} ABI to @var{abi}, or return to automatic detection. + @end table + ++@node Auto-loading ++@section Automatically loading associated files ++@cindex auto-loading ++ ++@value{GDBN} sometimes reads files with commands and settings automatically, ++without being explicitly told so by the user. We call this feature ++@dfn{auto-loading}. While auto-loading is useful for automatically adapting ++@value{GDBN} to the needs of your project, it can sometimes produce unexpected ++results or introduce security risks (e.g., if the file comes from untrusted ++sources). ++ ++For these reasons, @value{GDBN} includes commands and options to let you ++control when to auto-load files and which files should be auto-loaded. ++ ++@table @code ++@anchor{set auto-load off} ++@kindex set auto-load off ++@item set auto-load off ++Globally disable loading of all auto-loaded files. ++You may want to use this command with the @samp{-iex} option ++(@pxref{Option -init-eval-command}) such as: ++@smallexample ++$ @kbd{gdb -iex "set auto-load off" untrusted-executable corefile} ++@end smallexample ++ ++Be aware that system init file (@pxref{System-wide configuration}) ++and init files from your home directory (@pxref{Home Directory Init File}) ++still get read (as they come from generally trusted directories). ++To prevent @value{GDBN} from auto-loading even those init files, use the ++@option{-nx} option (@pxref{Mode Options}), in addition to ++@code{set auto-load no}. ++ ++@anchor{show auto-load} ++@kindex show auto-load ++@item show auto-load ++Show whether auto-loading of each specific @samp{auto-load} file(s) is enabled ++or disabled. ++ ++@smallexample ++(gdb) show auto-load ++gdb-scripts: Auto-loading of canned sequences of commands scripts is on. ++libthread-db: Auto-loading of inferior specific libthread_db is on. ++local-gdbinit: Auto-loading of .gdbinit script from current directory is on. ++python-scripts: Auto-loading of Python scripts is on. ++@end smallexample ++ ++@anchor{info auto-load} ++@kindex info auto-load ++@item info auto-load ++Print whether each specific @samp{auto-load} file(s) have been auto-loaded or ++not. ++ ++@smallexample ++(gdb) info auto-load ++gdb-scripts: ++Loaded Script ++Yes /home/user/gdb/gdb-gdb.gdb ++libthread-db: No auto-loaded libthread-db. ++local-gdbinit: Local .gdbinit file "/home/user/gdb/.gdbinit" has been loaded. ++python-scripts: ++Loaded Script ++Yes /home/user/gdb/gdb-gdb.py ++@end smallexample ++@end table ++ ++These are various kinds of files @value{GDBN} can automatically load: ++ ++@itemize @bullet ++@item ++@xref{objfile-gdb.py file}, controlled by @ref{set auto-load python-scripts}. ++@item ++@xref{objfile-gdb.gdb file}, controlled by @ref{set auto-load gdb-scripts}. ++@item ++@xref{dotdebug_gdb_scripts section}, ++controlled by @ref{set auto-load python-scripts}. ++@item ++@xref{Init File in the Current Directory}, ++controlled by @ref{set auto-load local-gdbinit}. ++@item ++@xref{libthread_db.so.1 file}, controlled by @ref{set auto-load libthread-db}. ++@end itemize ++ ++These are @value{GDBN} control commands for the auto-loading: ++ ++@multitable @columnfractions .5 .5 ++@item @xref{set auto-load off}. ++@tab Disable auto-loading globally. ++@item @xref{show auto-load}. ++@tab Show setting of all kinds of files. ++@item @xref{info auto-load}. ++@tab Show state of all kinds of files. ++@item @xref{set auto-load gdb-scripts}. ++@tab Control for @value{GDBN} command scripts. ++@item @xref{show auto-load gdb-scripts}. ++@tab Show setting of @value{GDBN} command scripts. ++@item @xref{info auto-load gdb-scripts}. ++@tab Show state of @value{GDBN} command scripts. ++@item @xref{set auto-load python-scripts}. ++@tab Control for @value{GDBN} Python scripts. ++@item @xref{show auto-load python-scripts}. ++@tab Show setting of @value{GDBN} Python scripts. ++@item @xref{info auto-load python-scripts}. ++@tab Show state of @value{GDBN} Python scripts. ++@item @xref{set auto-load local-gdbinit}. ++@tab Control for init file in the current directory. ++@item @xref{show auto-load local-gdbinit}. ++@tab Show setting of init file in the current directory. ++@item @xref{info auto-load local-gdbinit}. ++@tab Show state of init file in the current directory. ++@item @xref{set auto-load libthread-db}. ++@tab Control for thread debugging library. ++@item @xref{show auto-load libthread-db}. ++@tab Show setting of thread debugging library. ++@item @xref{info auto-load libthread-db}. ++@tab Show state of thread debugging library. ++@end multitable ++ ++@menu ++* Init File in the Current Directory:: @samp{set/show/info auto-load local-gdbinit} ++* libthread_db.so.1 file:: @samp{set/show/info auto-load libthread-db} ++* objfile-gdb.gdb file:: @samp{set/show/info auto-load gdb-script} ++@xref{Python Auto-loading}. ++@end menu ++ ++@node Init File in the Current Directory ++@subsection Automatically loading init file in the current directory ++@cindex auto-loading init file in the current directory ++ ++By default, @value{GDBN} reads and executes the canned sequences of commands ++from init file (if any) in the current working directory, ++see @ref{Init File in the Current Directory during Startup}. ++ ++@table @code ++@anchor{set auto-load local-gdbinit} ++@kindex set auto-load local-gdbinit ++@item set auto-load local-gdbinit [on|off] ++Enable or disable the auto-loading of canned sequences of commands ++(@pxref{Sequences}) found in init file in the current directory. ++ ++@anchor{show auto-load local-gdbinit} ++@kindex show auto-load local-gdbinit ++@item show auto-load local-gdbinit ++Show whether auto-loading of canned sequences of commands from init file in the ++current directory is enabled or disabled. ++ ++@anchor{info auto-load local-gdbinit} ++@kindex info auto-load local-gdbinit ++@item info auto-load local-gdbinit ++Print whether canned sequences of commands from init file in the ++current directory have been auto-loaded. ++@end table ++ ++@node libthread_db.so.1 file ++@subsection Automatically loading thread debugging library ++@cindex auto-loading libthread_db.so.1 ++ ++This feature is currently present only on @sc{gnu}/Linux native hosts. ++ ++@value{GDBN} reads in some cases thread debugging library from places specific ++to the inferior (@pxref{set libthread-db-search-path}). ++ ++The special @samp{libthread-db-search-path} entry @samp{$sdir} is processed ++without checking this @samp{set auto-load libthread-db} switch as system ++libraries have to be trusted in general. In all other cases of ++@samp{libthread-db-search-path} entries @value{GDBN} checks first if @samp{set ++auto-load libthread-db} is enabled before trying to open such thread debugging ++library. ++ ++@table @code ++@anchor{set auto-load libthread-db} ++@kindex set auto-load libthread-db ++@item set auto-load libthread-db [on|off] ++Enable or disable the auto-loading of inferior specific thread debugging library. ++ ++@anchor{show auto-load libthread-db} ++@kindex show auto-load libthread-db ++@item show auto-load libthread-db ++Show whether auto-loading of inferior specific thread debugging library is ++enabled or disabled. ++ ++@anchor{info auto-load libthread-db} ++@kindex info auto-load libthread-db ++@item info auto-load libthread-db ++Print the list of all loaded inferior specific thread debugging libraries and ++for each such library print list of inferior @var{pid}s using it. ++@end table ++ ++@node objfile-gdb.gdb file ++@subsection The @file{@var{objfile}-gdb.gdb} file ++@cindex auto-loading @file{@var{objfile}-gdb.gdb} ++ ++@value{GDBN} tries to load an @file{@var{objfile}-gdb.gdb} file containing ++canned sequences of commands (@pxref{Sequences}), as long as @samp{set ++auto-load gdb-scripts} is set to @samp{on}. ++ ++For more background refer to the similar Python scripts auto-loading ++description (@pxref{objfile-gdb.py file}). ++ ++@table @code ++@anchor{set auto-load gdb-scripts} ++@kindex set auto-load gdb-scripts ++@item set auto-load gdb-scripts [on|off] ++Enable or disable the auto-loading of canned sequences of commands scripts. ++ ++@anchor{show auto-load gdb-scripts} ++@kindex show auto-load gdb-scripts ++@item show auto-load gdb-scripts ++Show whether auto-loading of canned sequences of commands scripts is enabled or ++disabled. ++ ++@anchor{info auto-load gdb-scripts} ++@kindex info auto-load gdb-scripts ++@cindex print list of auto-loaded canned sequences of commands scripts ++@item info auto-load gdb-scripts [@var{regexp}] ++Print the list of all canned sequences of commands scripts that @value{GDBN} ++auto-loaded. ++@end table ++ ++If @var{regexp} is supplied only canned sequences of commands scripts with ++matching names are printed. ++ + @node Messages/Warnings + @section Optional Warnings and Messages + +@@ -21616,7 +21849,7 @@ automatically imported when @value{GDBN} + @menu + * Python Commands:: Accessing Python from @value{GDBN}. + * Python API:: Accessing @value{GDBN} from Python. +-* Auto-loading:: Automatically loading Python code. ++* Python Auto-loading:: Automatically loading Python code. + * Python modules:: Python modules provided by @value{GDBN}. + @end menu + +@@ -22799,7 +23032,7 @@ This practice will enable @value{GDBN} t + your pretty-printers at the same time, because they will have + different names. + +-You should write auto-loaded code (@pxref{Auto-loading}) such that it ++You should write auto-loaded code (@pxref{Python Auto-loading}) such that it + can be evaluated multiple times without changing its meaning. An + ideal auto-load file will consist solely of @code{import}s of your + printer modules, followed by a call to a register pretty-printers with +@@ -23760,7 +23993,7 @@ The following objfile-related functions + + @findex gdb.current_objfile + @defun gdb.current_objfile () +-When auto-loading a Python script (@pxref{Auto-loading}), @value{GDBN} ++When auto-loading a Python script (@pxref{Python Auto-loading}), @value{GDBN} + sets the ``current objfile'' to the corresponding objfile. This + function returns the current objfile. If there is no current objfile, + this function returns @code{None}. +@@ -24671,9 +24904,9 @@ resolve this to the lazy string's charac + writable. + @end defvar + +-@node Auto-loading +-@subsection Auto-loading +-@cindex auto-loading, Python ++@node Python Auto-loading ++@subsection Python Auto-loading ++@cindex Python auto-loading + + When a new object file is read (for example, due to the @code{file} + command, or because the inferior has loaded a shared library), +@@ -24693,32 +24926,35 @@ Auto-loading can be enabled or disabled, + and the list of auto-loaded scripts can be printed. + + @table @code +-@kindex set auto-load-scripts +-@item set auto-load-scripts [yes|no] ++@anchor{set auto-load python-scripts} ++@kindex set auto-load python-scripts ++@item set auto-load python-scripts [on|off] + Enable or disable the auto-loading of Python scripts. + +-@kindex show auto-load-scripts +-@item show auto-load-scripts ++@anchor{show auto-load python-scripts} ++@kindex show auto-load python-scripts ++@item show auto-load python-scripts + Show whether auto-loading of Python scripts is enabled or disabled. + +-@kindex info auto-load-scripts +-@cindex print list of auto-loaded scripts +-@item info auto-load-scripts [@var{regexp}] +-Print the list of all scripts that @value{GDBN} auto-loaded. ++@anchor{info auto-load python-scripts} ++@kindex info auto-load python-scripts ++@cindex print list of auto-loaded Python scripts ++@item info auto-load python-scripts [@var{regexp}] ++Print the list of all Python scripts that @value{GDBN} auto-loaded. + +-Also printed is the list of scripts that were mentioned in ++Also printed is the list of Python scripts that were mentioned in + the @code{.debug_gdb_scripts} section and were not found + (@pxref{dotdebug_gdb_scripts section}). + This is useful because their names are not printed when @value{GDBN} + tries to load them and fails. There may be many of them, and printing + an error message for each one is problematic. + +-If @var{regexp} is supplied only scripts with matching names are printed. ++If @var{regexp} is supplied only Python scripts with matching names are printed. + + Example: + + @smallexample +-(gdb) info auto-load-scripts ++(gdb) info auto-load python-scripts + Loaded Script + Yes py-section-script.py + full name: /tmp/py-section-script.py +Index: gdb-7.4.50.20120120/gdb/python/py-auto-load.c +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/python/py-auto-load.c 2012-04-18 00:44:26.958437500 +0200 ++++ gdb-7.4.50.20120120/gdb/python/py-auto-load.c 2012-04-18 00:46:47.558079774 +0200 +@@ -31,29 +31,56 @@ + + #include "python-internal.h" + +-/* NOTE: It's trivial to also support auto-loading normal gdb scripts. +- There has yet to be a need so it's not implemented. */ +- + /* The suffix of per-objfile scripts to auto-load. + E.g. When the program loads libfoo.so, look for libfoo-gdb.py. */ + #define GDBPY_AUTO_FILE_NAME "-gdb.py" + +-/* The section to look for scripts (in file formats that support sections). ++/* 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: +- set auto-load-scripts on|off +- This is true if we should auto-load associated scripts when an objfile +- is opened, false otherwise. +- At the moment, this only affects python scripts, but there's no reason +- one couldn't also have other kinds of auto-loaded scripts, and there's +- no reason to have them each controlled by a separate flag. +- So we elide "python" from the name here and in the option. +- The fact that it lives here is just an implementation detail. */ +-static int auto_load_scripts = 1; ++/* 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 ++show_auto_load_python_scripts (struct ui_file *file, int from_tty, ++ struct cmd_list_element *c, const char *value) ++{ ++ 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. */ ++ ++static void ++gdbpy_load_auto_script_for_objfile (struct objfile *objfile, FILE *file, ++ const char *filename) ++{ ++ struct auto_load_pspace_info *pspace_info; ++ ++ /* 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, filename, filename, &script_language_python); ++ ++ source_python_script_for_objfile (objfile, file, filename); ++} + + /* Load scripts specified in OBJFILE. + START,END delimit a buffer containing a list of nul-terminated +@@ -121,6 +148,17 @@ source_section_scripts (struct objfile * + make_cleanup_fclose (stream); + make_cleanup (xfree, full_path); + } ++ else ++ { ++ full_path = NULL; ++ ++ /* We don't throw an error, the program is still debuggable. */ ++ 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); ++ } + + /* If one script isn't found it's not uncommon for more to not be + found either. We don't want to print an error message for each +@@ -129,24 +167,12 @@ source_section_scripts (struct objfile * + + IWBN if complaints.c were more general-purpose. */ + +- in_hash_table = maybe_add_script (pspace_info, file, +- opened ? full_path : NULL); ++ in_hash_table = maybe_add_script (pspace_info, file, full_path, ++ &script_language_python); + +- if (! opened) +- { +- /* We don't throw an error, the program is still debuggable. */ +- 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-scripts [REGEXP]' to list them."), +- GDBPY_AUTO_SECTION_NAME, objfile->name); +- } +- else +- { +- /* If this file is not currently loaded, load it. */ +- if (! in_hash_table) +- source_python_script_for_objfile (objfile, stream, full_path); +- } ++ /* 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); + } +@@ -181,36 +207,75 @@ auto_load_section_scripts (struct objfil + do_cleanups (cleanups); + } + +-/* Load any auto-loaded scripts for OBJFILE. */ ++/* Load any Python auto-loaded scripts for OBJFILE. */ + + void +-load_auto_scripts_for_objfile (struct objfile *objfile) ++gdbpy_load_auto_scripts_for_objfile (struct objfile *objfile) + { +- if (auto_load_scripts && gdbpy_global_auto_load) ++ if (auto_load_python_scripts) + { +- auto_load_objfile_script (objfile, GDBPY_AUTO_FILE_NAME); ++ auto_load_objfile_script (objfile, &script_language_python); + auto_load_section_scripts (objfile, GDBPY_AUTO_SECTION_NAME); + } + } ++ ++/* Wrapper for "info auto-load python-scripts". */ ++ ++static void ++info_auto_load_python_scripts (char *pattern, int from_tty) ++{ ++ auto_load_info_scripts (pattern, from_tty, &script_language_python); ++} + + void + gdbpy_initialize_auto_load (void) + { ++ struct cmd_list_element *cmd; ++ char *cmd_name; ++ ++ add_setshow_boolean_cmd ("python-scripts", class_support, ++ &auto_load_python_scripts, _("\ ++Set the debugger's behaviour regarding auto-loaded Python scripts."), _("\ ++Show the debugger's behaviour regarding auto-loaded Python scripts."), _("\ ++If enabled, auto-loaded Python scripts are loaded when the debugger reads\n\ ++an executable or shared library.\n\ ++This options has security implications for untrusted inferiors."), ++ NULL, show_auto_load_python_scripts, ++ auto_load_set_cmdlist_get (), ++ auto_load_show_cmdlist_get ()); ++ + add_setshow_boolean_cmd ("auto-load-scripts", class_support, +- &auto_load_scripts, _("\ +-Set the debugger's behaviour regarding auto-loaded scripts."), _("\ +-Show the debugger's behaviour regarding auto-loaded scripts."), _("\ +-If enabled, auto-loaded scripts are loaded when the debugger reads\n\ +-an executable or shared library."), +- NULL, NULL, +- &setlist, +- &showlist); ++ &auto_load_python_scripts, _("\ ++Set the debugger's behaviour regarding auto-loaded Python scripts, " ++ "deprecated."), ++ _("\ ++Show the debugger's behaviour regarding auto-loaded Python scripts, " ++ "deprecated."), ++ NULL, NULL, show_auto_load_python_scripts, ++ &setlist, &showlist); ++ cmd_name = "auto-load-scripts"; ++ cmd = lookup_cmd (&cmd_name, setlist, "", -1, 1); ++ deprecate_cmd (cmd, "set auto-load python-scripts"); ++ ++ /* It is needed because lookup_cmd updates the CMD_NAME pointer. */ ++ cmd_name = "auto-load-scripts"; ++ cmd = lookup_cmd (&cmd_name, showlist, "", -1, 1); ++ deprecate_cmd (cmd, "show auto-load python-scripts"); ++ ++ add_cmd ("python-scripts", class_info, info_auto_load_python_scripts, ++ _("Print the list of automatically loaded Python scripts.\n\ ++Usage: info auto-load python-scripts [REGEXP]"), ++ auto_load_info_cmdlist_get ()); ++ ++ cmd = add_info ("auto-load-scripts", info_auto_load_python_scripts, _("\ ++Print the list of automatically loaded Python scripts, deprecated.")); ++ deprecate_cmd (cmd, "info auto-load python-scripts"); + } + + #else /* ! HAVE_PYTHON */ + + void +-load_auto_scripts_for_objfile (struct objfile *objfile) ++gdbpy_load_auto_scripts_for_objfile (struct objfile *objfile) + { + } + +Index: gdb-7.4.50.20120120/gdb/python/python.h +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/python/python.h 2012-04-18 00:44:26.958437500 +0200 ++++ gdb-7.4.50.20120120/gdb/python/python.h 2012-04-18 00:44:26.979437446 +0200 +@@ -41,7 +41,7 @@ int apply_val_pretty_printer (struct typ + + void preserve_python_values (struct objfile *objfile, htab_t copied_types); + +-void load_auto_scripts_for_objfile (struct objfile *objfile); ++void gdbpy_load_auto_scripts_for_objfile (struct objfile *objfile); + + int gdbpy_should_stop (struct breakpoint_object *bp_obj); + +Index: gdb-7.4.50.20120120/gdb/testsuite/gdb.base/help.exp +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/testsuite/gdb.base/help.exp 2012-01-04 09:17:45.000000000 +0100 ++++ gdb-7.4.50.20120120/gdb/testsuite/gdb.base/help.exp 2012-04-18 00:44:26.980437444 +0200 +@@ -24,7 +24,7 @@ + gdb_start + + # force the height of the debugger to be pretty large so no pagers get used +-gdb_test_no_output "set height 400" "test set height" ++gdb_test_no_output "set height 500" "test set height" + + # use a larger expect input buffer for long help outputs. + # test help add-symbol-file +Index: gdb-7.4.50.20120120/gdb/testsuite/gdb.python/py-objfile-script.exp +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/testsuite/gdb.python/py-objfile-script.exp 2012-01-16 17:21:52.000000000 +0100 ++++ gdb-7.4.50.20120120/gdb/testsuite/gdb.python/py-objfile-script.exp 2012-04-18 00:46:47.558079774 +0200 +@@ -40,7 +40,7 @@ gdb_reinitialize_dir $srcdir/$subdir + gdb_load ${binfile} + + # Verify gdb loaded the script. +-gdb_test "info auto-load-scripts" "Yes.*/${testfile}-gdb.py.*" ++gdb_test "info auto-load python-scripts" "Yes.*/${testfile}-gdb.py.*" + + if ![runto_main] { + perror "couldn't run to main" +Index: gdb-7.4.50.20120120/gdb/testsuite/gdb.python/py-section-script.exp +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/testsuite/gdb.python/py-section-script.exp 2012-01-16 17:21:52.000000000 +0100 ++++ gdb-7.4.50.20120120/gdb/testsuite/gdb.python/py-section-script.exp 2012-04-18 00:46:47.558079774 +0200 +@@ -52,11 +52,11 @@ gdb_reinitialize_dir $srcdir/$subdir + gdb_load ${binfile} + + # Verify gdb loaded the script. +-gdb_test "info auto-load-scripts" "Yes.*${testfile}.py.*full name: .*/${testfile}.py.*" ++gdb_test "info auto-load python-scripts" "Yes.*${testfile}.py.*full name: .*/${testfile}.py.*" + # Again, with a regexp this time. +-gdb_test "info auto-load-scripts ${testfile}" "Yes.*${testfile}.py.*full name: .*/${testfile}.py.*" ++gdb_test "info auto-load python-scripts ${testfile}" "Yes.*${testfile}.py.*full name: .*/${testfile}.py.*" + # Again, with a regexp that matches no scripts. +-gdb_test "info auto-load-scripts no-script-matches-this" \ ++gdb_test "info auto-load python-scripts no-script-matches-this" \ + "No auto-load scripts matching no-script-matches-this." + + if ![runto_main] { diff --git a/gdb-autoload-11of12.patch b/gdb-autoload-11of12.patch new file mode 100644 index 0000000..4ac68b0 --- /dev/null +++ b/gdb-autoload-11of12.patch @@ -0,0 +1,744 @@ +[patch#4 5/8] set auto-load safe-path +http://sourceware.org/ml/gdb-patches/2012-04/msg00092.html +http://sourceware.org/ml/gdb-cvs/2012-04/msg00114.html + +### src/gdb/ChangeLog 2012/04/17 15:51:41 1.14113 +### src/gdb/ChangeLog 2012/04/17 15:54:28 1.14114 +## -1,5 +1,39 @@ + 2012-04-17 Jan Kratochvil + ++ New option "set auto-load safe-path". ++ * NEWS: New commands "set auto-load safe-path" ++ and "show auto-load safe-path". ++ * auto-load.c: Include gdb_vecs.h, readline/tilde.h and completer.h. ++ (auto_load_safe_path, auto_load_safe_path_vec) ++ (auto_load_safe_path_vec_update, set_auto_load_safe_path) ++ (show_auto_load_safe_path, add_auto_load_safe_path, filename_is_in_dir) ++ (filename_is_in_auto_load_safe_path_vec, file_is_auto_load_safe): New. ++ (source_gdb_script_for_objfile): New variable is_safe. Call ++ file_is_auto_load_safe. Return if it is not. ++ (struct loaded_script): New field loaded. ++ (maybe_add_script): Add parameter loaded. Initialize SLOT with it. ++ (print_script): Use LOADED indicator instead of FULL_PATH. Change ++ output "Missing" to "No". ++ (_initialize_auto_load): New variable cmd. Initialize ++ auto_load_safe_path. Register "set auto-load safe-path", ++ "show auto-load safe-path" and "add-auto-load-safe-path". ++ * auto-load.h (maybe_add_script): Add parameter loaded. ++ (file_is_auto_load_safe): New declaration. ++ * config.in: Regenerate. ++ * configure: Regenerate. ++ * configure.ac: New parameters --with-auto-load-safe-path ++ and --without-auto-load-safe-path. ++ * linux-thread-db.c (try_thread_db_load_from_pdir_1) ++ (try_thread_db_load_from_dir): Check file_is_auto_load_safe first. ++ * main.c (captured_main): Check file_is_auto_load_safe for ++ LOCAL_GDBINIT. ++ * python/py-auto-load.c (gdbpy_load_auto_script_for_objfile): New ++ variable is_safe. Call file_is_auto_load_safe. Return if it is not. ++ (source_section_scripts): Call file_is_auto_load_safe. Return if it is ++ not. ++ ++2012-04-17 Jan Kratochvil ++ + auto-load: Implementation. + * NEWS: New descriptions for "info auto-load", + "info auto-load gdb-scripts", "info auto-load python-scripts", +Index: gdb-7.4.50.20120120/gdb/NEWS +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/NEWS 2012-04-18 00:49:02.000000000 +0200 ++++ gdb-7.4.50.20120120/gdb/NEWS 2012-04-18 00:49:33.282706319 +0200 +@@ -67,6 +67,11 @@ set auto-load libthread-db on|off + show auto-load libthread-db + Control auto-loading of inferior specific thread debugging shared library. + ++set auto-load safe-path [:...] ++show auto-load safe-path ++ Set a list of directories from which it is safe to auto-load files. ++ The delimiter (':' above) may differ according to the host platform. ++ + * New command line options + + --init-command=FILE, -ix Like --command, -x but execute it +Index: gdb-7.4.50.20120120/gdb/auto-load.c +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/auto-load.c 2012-04-18 00:46:47.000000000 +0200 ++++ gdb-7.4.50.20120120/gdb/auto-load.c 2012-04-18 00:49:21.607736020 +0200 +@@ -32,6 +32,9 @@ + #include "gdbcmd.h" + #include "cli/cli-decode.h" + #include "cli/cli-setshow.h" ++#include "gdb_vecs.h" ++#include "readline/tilde.h" ++#include "completer.h" + + /* 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. */ +@@ -90,6 +93,181 @@ show_auto_load_local_gdbinit (struct ui_ + value); + } + ++/* Directory list safe to hold auto-loaded files. It is not checked for ++ absolute paths but they are strongly recommended. It is initialized by ++ _initialize_auto_load. */ ++static char *auto_load_safe_path; ++ ++/* Vector of directory elements of AUTO_LOAD_SAFE_PATH with each one normalized ++ by tilde_expand and possibly each entries has added its gdb_realpath ++ counterpart. */ ++static VEC (char_ptr) *auto_load_safe_path_vec; ++ ++/* Update auto_load_safe_path_vec from current AUTO_LOAD_SAFE_PATH. */ ++ ++static void ++auto_load_safe_path_vec_update (void) ++{ ++ VEC (char_ptr) *dir_vec = NULL; ++ unsigned len; ++ int ix; ++ ++ free_char_ptr_vec (auto_load_safe_path_vec); ++ ++ auto_load_safe_path_vec = dirnames_to_char_ptr_vec (auto_load_safe_path); ++ len = VEC_length (char_ptr, auto_load_safe_path_vec); ++ ++ /* Apply tilde_expand and gdb_realpath to each AUTO_LOAD_SAFE_PATH_VEC ++ element. */ ++ for (ix = 0; ix < len; ix++) ++ { ++ char *dir = VEC_index (char_ptr, auto_load_safe_path_vec, ix); ++ char *expanded = tilde_expand (dir); ++ char *real_path = gdb_realpath (expanded); ++ ++ /* Ensure the current entry is at least tilde_expand-ed. */ ++ xfree (dir); ++ VEC_replace (char_ptr, auto_load_safe_path_vec, ix, expanded); ++ ++ /* If gdb_realpath returns a different content, append it. */ ++ if (strcmp (real_path, expanded) == 0) ++ xfree (real_path); ++ else ++ VEC_safe_push (char_ptr, auto_load_safe_path_vec, real_path); ++ } ++} ++ ++/* "set" command for the auto_load_safe_path configuration variable. */ ++ ++static void ++set_auto_load_safe_path (char *args, int from_tty, struct cmd_list_element *c) ++{ ++ auto_load_safe_path_vec_update (); ++} ++ ++/* "show" command for the auto_load_safe_path configuration variable. */ ++ ++static void ++show_auto_load_safe_path (struct ui_file *file, int from_tty, ++ struct cmd_list_element *c, const char *value) ++{ ++ if (*value == 0) ++ fprintf_filtered (file, _("Auto-load files are safe to load from any " ++ "directory.\n")); ++ else ++ fprintf_filtered (file, _("List of directories from which it is safe to " ++ "auto-load files is %s.\n"), ++ value); ++} ++ ++/* "add-auto-load-safe-path" command for the auto_load_safe_path configuration ++ variable. */ ++ ++static void ++add_auto_load_safe_path (char *args, int from_tty) ++{ ++ char *s; ++ ++ if (args == NULL || *args == 0) ++ error (_("\ ++Adding empty directory element disables the auto-load safe-path security. \ ++Use 'set auto-load safe-path' instead if you mean that.")); ++ ++ s = xstrprintf ("%s%c%s", auto_load_safe_path, DIRNAME_SEPARATOR, args); ++ xfree (auto_load_safe_path); ++ auto_load_safe_path = s; ++ ++ auto_load_safe_path_vec_update (); ++} ++ ++/* Return 1 if FILENAME is equal to DIR or if FILENAME belongs to the ++ subdirectory DIR. Return 0 otherwise. gdb_realpath normalization is never ++ done here. */ ++ ++static ATTRIBUTE_PURE int ++filename_is_in_dir (const char *filename, const char *dir) ++{ ++ size_t dir_len = strlen (dir); ++ ++ while (dir_len && IS_DIR_SEPARATOR (dir[dir_len - 1])) ++ dir_len--; ++ ++ return (filename_ncmp (dir, filename, dir_len) == 0 ++ && (IS_DIR_SEPARATOR (filename[dir_len]) ++ || filename[dir_len] == '\0')); ++} ++ ++/* Return 1 if FILENAME belongs to one of directory components of ++ AUTO_LOAD_SAFE_PATH_VEC. Return 0 otherwise. ++ auto_load_safe_path_vec_update is never called. ++ *FILENAME_REALP may be updated by gdb_realpath of FILENAME - it has to be ++ freed by the caller. */ ++ ++static int ++filename_is_in_auto_load_safe_path_vec (const char *filename, ++ char **filename_realp) ++{ ++ char *dir; ++ int ix; ++ ++ for (ix = 0; VEC_iterate (char_ptr, auto_load_safe_path_vec, ix, dir); ++ix) ++ if (*filename_realp == NULL && filename_is_in_dir (filename, dir)) ++ break; ++ ++ if (dir == NULL) ++ { ++ if (*filename_realp == NULL) ++ *filename_realp = gdb_realpath (filename); ++ ++ for (ix = 0; VEC_iterate (char_ptr, auto_load_safe_path_vec, ix, dir); ++ ++ix) ++ if (filename_is_in_dir (*filename_realp, dir)) ++ break; ++ } ++ ++ if (dir != NULL) ++ return 1; ++ ++ return 0; ++} ++ ++/* Return 1 if FILENAME is located in one of the directories of ++ AUTO_LOAD_SAFE_PATH. Otherwise call warning and return 0. FILENAME does ++ not have to be an absolute path. ++ ++ Existence of FILENAME is not checked. Function will still give a warning ++ even if the caller would quietly skip non-existing file in unsafe ++ directory. */ ++ ++int ++file_is_auto_load_safe (const char *filename) ++{ ++ char *filename_real = NULL; ++ struct cleanup *back_to; ++ ++ back_to = make_cleanup (free_current_contents, &filename_real); ++ ++ if (filename_is_in_auto_load_safe_path_vec (filename, &filename_real)) ++ { ++ do_cleanups (back_to); ++ return 1; ++ } ++ ++ auto_load_safe_path_vec_update (); ++ if (filename_is_in_auto_load_safe_path_vec (filename, &filename_real)) ++ { ++ do_cleanups (back_to); ++ return 1; ++ } ++ ++ warning (_("File \"%s\" auto-loading has been declined by your " ++ "`auto-load safe-path' set to \"%s\"."), ++ filename_real, auto_load_safe_path); ++ ++ do_cleanups (back_to); ++ return 0; ++} ++ + /* Definition of script language for GDB canned sequences of commands. */ + + static const struct script_language script_language_gdb +@@ -99,13 +277,20 @@ 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); ++ + /* 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, filename, filename, &script_language_gdb); ++ maybe_add_script (pspace_info, is_safe, filename, filename, ++ &script_language_gdb); ++ ++ if (!is_safe) ++ return; + + TRY_CATCH (e, RETURN_MASK_ALL) + { +@@ -140,6 +325,9 @@ struct loaded_script + inaccessible). */ + const char *full_path; + ++ /* Non-zero if this script has been loaded. */ ++ int loaded; ++ + const struct script_language *language; + }; + +@@ -232,12 +420,13 @@ get_auto_load_pspace_data_for_loading (s + return info; + } + +-/* Add script NAME in LANGUAGE to hash table of PSPACE_INFO. +- FULL_PATH is NULL if the script wasn't found. The result is ++/* Add script NAME in LANGUAGE to hash table of PSPACE_INFO. LOADED 1 if the ++ script has been (is going to) be loaded, 0 otherwise (such as if it has not ++ been found). FULL_PATH is NULL if the script wasn't found. The result is + true if the script was already in the hash table. */ + + int +-maybe_add_script (struct auto_load_pspace_info *pspace_info, ++maybe_add_script (struct auto_load_pspace_info *pspace_info, int loaded, + const char *name, const char *full_path, + const struct script_language *language) + { +@@ -271,6 +460,7 @@ maybe_add_script (struct auto_load_pspac + } + else + (*slot)->full_path = NULL; ++ (*slot)->loaded = loaded; + (*slot)->language = language; + } + +@@ -432,7 +622,7 @@ print_script (struct loaded_script *scri + + chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); + +- ui_out_field_string (uiout, "loaded", script->full_path ? "Yes" : "Missing"); ++ ui_out_field_string (uiout, "loaded", script->loaded ? "Yes" : "No"); + ui_out_field_string (uiout, "script", script->name); + ui_out_text (uiout, "\n"); + +@@ -718,6 +908,8 @@ void _initialize_auto_load (void); + void + _initialize_auto_load (void) + { ++ struct cmd_list_element *cmd; ++ + auto_load_pspace_data + = register_program_space_data_with_cleanup (auto_load_pspace_data_cleanup); + +@@ -757,4 +949,30 @@ This options has security implications f + _("Print whether current directory .gdbinit file has been loaded.\n\ + Usage: info auto-load local-gdbinit"), + auto_load_info_cmdlist_get ()); ++ ++ auto_load_safe_path = xstrdup (DEFAULT_AUTO_LOAD_SAFE_PATH); ++ auto_load_safe_path_vec_update (); ++ add_setshow_optional_filename_cmd ("safe-path", class_support, ++ &auto_load_safe_path, _("\ ++Set the list of directories from which it is safe to auto-load files."), _("\ ++Show the list of directories from which it is safe to auto-load files."), _("\ ++Various files loaded automatically for the 'set auto-load ...' options must\n\ ++be located in one of the directories listed by this option. Warning will be\n\ ++printed and file will not be used otherwise. Use empty string (or even\n\ ++empty directory entry) to allow any file for the 'set auto-load ...' options.\n\ ++This option is ignored for the kinds of files having 'set auto-load ... off'.\n\ ++This options has security implications for untrusted inferiors."), ++ set_auto_load_safe_path, ++ show_auto_load_safe_path, ++ auto_load_set_cmdlist_get (), ++ auto_load_show_cmdlist_get ()); ++ ++ cmd = add_cmd ("add-auto-load-safe-path", class_support, ++ add_auto_load_safe_path, ++ _("Add entries to the list of directories from which it is safe " ++ "to auto-load files.\n\ ++See the commands 'set auto-load safe-path' and 'show auto-load safe-path' to\n\ ++access the current full list setting."), ++ &cmdlist); ++ set_cmd_completer (cmd, filename_completer); + } +Index: gdb-7.4.50.20120120/gdb/auto-load.h +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/auto-load.h 2012-04-18 00:46:47.000000000 +0200 ++++ gdb-7.4.50.20120120/gdb/auto-load.h 2012-04-18 00:49:21.607736020 +0200 +@@ -39,7 +39,8 @@ extern int auto_load_local_gdbinit_loade + extern struct auto_load_pspace_info * + get_auto_load_pspace_data_for_loading (struct program_space *pspace); + extern int maybe_add_script (struct auto_load_pspace_info *pspace_info, +- const char *name, const char *full_path, ++ 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); +@@ -54,4 +55,6 @@ extern struct cmd_list_element **auto_lo + extern struct cmd_list_element **auto_load_show_cmdlist_get (void); + extern struct cmd_list_element **auto_load_info_cmdlist_get (void); + ++extern int file_is_auto_load_safe (const char *filename); ++ + #endif /* AUTO_LOAD_H */ +Index: gdb-7.4.50.20120120/gdb/config.in +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/config.in 2012-04-18 00:46:47.000000000 +0200 ++++ gdb-7.4.50.20120120/gdb/config.in 2012-04-18 00:49:21.607736020 +0200 +@@ -43,6 +43,9 @@ + moved. */ + #undef DEBUGDIR_RELOCATABLE + ++/* Directories safe to hold auto-loaded files. */ ++#undef DEFAULT_AUTO_LOAD_SAFE_PATH ++ + /* Define to BFD's default architecture. */ + #undef DEFAULT_BFD_ARCH + +Index: gdb-7.4.50.20120120/gdb/configure +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/configure 2012-04-18 00:46:47.000000000 +0200 ++++ gdb-7.4.50.20120120/gdb/configure 2012-04-18 00:49:21.611736010 +0200 +@@ -955,6 +955,7 @@ with_separate_debug_dir + with_gdb_datadir + with_relocated_sources + with_rpm ++with_auto_load_safe_path + enable_targets + enable_64_bit_bfd + enable_gdbcli +@@ -1666,6 +1667,10 @@ Optional Packages: + automatically relocate this path for source files + --with-rpm query rpm database for missing debuginfos (yes/no, + def. auto=librpm.so) ++ --with-auto-load-safe-path=PATH ++ directories safe to hold auto-loaded files ++ --without-auto-load-safe-path ++ do not restrict auto-loaded files locations + --with-libunwind use libunwind frame unwinding support + --with-curses use the curses library instead of the termcap + library +@@ -8477,6 +8482,32 @@ $as_echo "$as_me: WARNING: $RPM_PKG_ERRO + fi + fi + ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for default auto-load safe-path" >&5 ++$as_echo_n "checking for default auto-load safe-path... " >&6; } ++ ++# Check whether --with-auto-load-safe-path was given. ++if test "${with_auto_load_safe_path+set}" = set; then : ++ withval=$with_auto_load_safe_path; if test "$with_auto_load_safe_path" = "no"; then ++ with_auto_load_safe_path="" ++ fi ++else ++ with_auto_load_safe_path="$prefix" ++fi ++ ++ ++ test "x$prefix" = xNONE && prefix="$ac_default_prefix" ++ test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' ++ ac_define_dir=`eval echo $with_auto_load_safe_path` ++ ac_define_dir=`eval echo $ac_define_dir` ++ ++cat >>confdefs.h <<_ACEOF ++#define DEFAULT_AUTO_LOAD_SAFE_PATH "$ac_define_dir" ++_ACEOF ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_auto_load_safe_path" >&5 ++$as_echo "$with_auto_load_safe_path" >&6; } ++ + + + subdirs="$subdirs testsuite" +Index: gdb-7.4.50.20120120/gdb/configure.ac +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/configure.ac 2012-04-18 00:46:47.000000000 +0200 ++++ gdb-7.4.50.20120120/gdb/configure.ac 2012-04-18 00:49:21.611736010 +0200 +@@ -339,6 +339,18 @@ extern rpmdbMatchIterator rpmtsInitItera + fi + fi + ++AC_MSG_CHECKING([for default auto-load safe-path]) ++AC_ARG_WITH(auto-load-safe-path, ++AS_HELP_STRING([--with-auto-load-safe-path=PATH], [directories safe to hold auto-loaded files]) ++AS_HELP_STRING([--without-auto-load-safe-path], [do not restrict auto-loaded files locations]), ++[if test "$with_auto_load_safe_path" = "no"; then ++ with_auto_load_safe_path="" ++ fi], ++[with_auto_load_safe_path="$prefix"]) ++AC_DEFINE_DIR(DEFAULT_AUTO_LOAD_SAFE_PATH, with_auto_load_safe_path, ++ [Directories safe to hold auto-loaded files.]) ++AC_MSG_RESULT([$with_auto_load_safe_path]) ++ + AC_CONFIG_SUBDIRS(testsuite) + + # Check whether to support alternative target configurations +Index: gdb-7.4.50.20120120/gdb/linux-thread-db.c +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/linux-thread-db.c 2012-04-18 00:46:47.000000000 +0200 ++++ gdb-7.4.50.20120120/gdb/linux-thread-db.c 2012-04-18 00:49:21.612736007 +0200 +@@ -868,7 +868,11 @@ try_thread_db_load_from_pdir_1 (struct o + /* This should at minimum hit the first character. */ + gdb_assert (cp != NULL); + strcpy (cp + 1, LIBTHREAD_DB_SO); +- result = try_thread_db_load (path); ++ ++ if (!file_is_auto_load_safe (path)) ++ result = 0; ++ else ++ result = try_thread_db_load (path); + + do_cleanups (cleanup); + return result; +@@ -934,7 +938,11 @@ try_thread_db_load_from_dir (const char + memcpy (path, dir, dir_len); + path[dir_len] = '/'; + strcpy (path + dir_len + 1, LIBTHREAD_DB_SO); +- result = try_thread_db_load (path); ++ ++ if (!file_is_auto_load_safe (path)) ++ result = 0; ++ else ++ result = try_thread_db_load (path); + + do_cleanups (cleanup); + return result; +Index: gdb-7.4.50.20120120/gdb/main.c +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/main.c 2012-04-18 00:46:47.000000000 +0200 ++++ gdb-7.4.50.20120120/gdb/main.c 2012-04-18 00:49:21.612736007 +0200 +@@ -1026,7 +1026,8 @@ captured_main (void *data) + { + auto_load_local_gdbinit_pathname = gdb_realpath (local_gdbinit); + +- if (!inhibit_gdbinit && auto_load_local_gdbinit) ++ if (!inhibit_gdbinit && auto_load_local_gdbinit ++ && file_is_auto_load_safe (local_gdbinit)) + { + auto_load_local_gdbinit_loaded = 1; + +Index: gdb-7.4.50.20120120/gdb/doc/gdb.texinfo +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/doc/gdb.texinfo 2012-04-18 00:46:47.000000000 +0200 ++++ gdb-7.4.50.20120120/gdb/doc/gdb.texinfo 2012-04-18 00:49:21.620735987 +0200 +@@ -20801,6 +20801,8 @@ gdb-scripts: Auto-loading of canned seq + libthread-db: Auto-loading of inferior specific libthread_db is on. + local-gdbinit: Auto-loading of .gdbinit script from current directory is on. + python-scripts: Auto-loading of Python scripts is on. ++safe-path: List of directories from which it is safe to auto-load files ++ is /usr/local. + @end smallexample + + @anchor{info auto-load} +@@ -20872,12 +20874,19 @@ These are @value{GDBN} control commands + @tab Show setting of thread debugging library. + @item @xref{info auto-load libthread-db}. + @tab Show state of thread debugging library. ++@item @xref{set auto-load safe-path}. ++@tab Control directories trusted for automatic loading. ++@item @xref{show auto-load safe-path}. ++@tab Show directories trusted for automatic loading. ++@item @xref{add-auto-load-safe-path}. ++@tab Add directory trusted for automatic loading. + @end multitable + + @menu + * Init File in the Current Directory:: @samp{set/show/info auto-load local-gdbinit} + * libthread_db.so.1 file:: @samp{set/show/info auto-load libthread-db} + * objfile-gdb.gdb file:: @samp{set/show/info auto-load gdb-script} ++* Auto-loading safe path:: @samp{set/show/info auto-load safe-path} + @xref{Python Auto-loading}. + @end menu + +@@ -20978,6 +20987,104 @@ auto-loaded. + If @var{regexp} is supplied only canned sequences of commands scripts with + matching names are printed. + ++@node Auto-loading safe path ++@subsection Security restriction for auto-loading ++@cindex auto-loading safe-path ++ ++As the files of inferior can come from untrusted source (such as submitted by ++an application user) @value{GDBN} does not always load any files automatically. ++@value{GDBN} provides the @samp{set auto-load safe-path} setting to list ++directories trusted for loading files not explicitly requested by user. ++ ++If the path is not set properly you will see a warning and the file will not ++get loaded: ++ ++@smallexample ++$ ./gdb -q ./gdb ++Reading symbols from /home/user/gdb/gdb...done. ++warning: File "/home/user/gdb/gdb-gdb.gdb" auto-loading has been ++ declined by your `auto-load safe-path' set to "/usr/local". ++warning: File "/home/user/gdb/gdb-gdb.py" auto-loading has been ++ declined by your `auto-load safe-path' set to "/usr/local". ++@end smallexample ++ ++The list of trusted directories is controlled by the following commands: ++ ++@table @code ++@anchor{set auto-load safe-path} ++@kindex set auto-load safe-path ++@item set auto-load safe-path @var{directories} ++Set the list of directories (and their subdirectories) trusted for automatic ++loading and execution of scripts. You can also enter a specific trusted file. ++The list of directories uses directory separator (@samp{:} on GNU and Unix ++systems, @samp{;} on MS-Windows and MS-DOS) to separate directories, similarly ++to the @env{PATH} environment variable. ++ ++@anchor{show auto-load safe-path} ++@kindex show auto-load safe-path ++@item show auto-load safe-path ++Show the list of directories trusted for automatic loading and execution of ++scripts. ++ ++@anchor{add-auto-load-safe-path} ++@kindex add-auto-load-safe-path ++@item add-auto-load-safe-path ++Add an entry (or list of entries) the list of directories trusted for automatic ++loading and execution of scripts. Multiple entries may be delimited by the ++host platform directory separator in use. ++@end table ++ ++Setting this variable to an empty string disables this security protection. ++This variable is supposed to be set to the system directories writable by the ++system superuser only. Users can add their source directories in init files in ++their home directories (@pxref{Home Directory Init File}). See also deprecated ++init file in the current directory ++(@pxref{Init File in the Current Directory during Startup}). ++ ++To force @value{GDBN} to load the files it declined to load in the previous ++example, you could use one of the following ways: ++ ++@itemize @bullet ++@item ~/.gdbinit: add-auto-load-safe-path ~/src/gdb ++Specify this trusted directory (or a file) as additional component of the list. ++You have to specify also any existing directories displayed by ++by @samp{show auto-load safe-path} (such as @samp{/usr:/bin} in this example). ++ ++@item @kbd{gdb -iex "set auto-load safe-path /usr:/bin:~/src/gdb" [@dots{}]} ++Specify this directory as in the previous case but just for a single ++@value{GDBN} session. ++ ++@item @kbd{gdb -iex "set auto-load safe-path" [@dots{}]} ++Disable auto-loading safety for a single @value{GDBN} session. ++This assumes all the files you debug during this @value{GDBN} session will come ++from trusted sources. ++ ++@item @kbd{./configure --without-auto-load-safe-path} ++During compilation of @value{GDBN} you may disable any auto-loading safety. ++This assumes all the files you will ever debug with this @value{GDBN} come from ++trusted sources. ++@end itemize ++ ++On the other hand you can also explicitly forbid automatic files loading which ++also suppresses any such warning messages: ++ ++@itemize @bullet ++@item @kbd{gdb -iex "set auto-load no" [@dots{}]} ++You can use @value{GDBN} command-line option for a single @value{GDBN} session. ++ ++@item @samp{~/.gdbinit}: @samp{set auto-load no} ++Disable auto-loading globally for the user ++(@pxref{Home Directory Init File}). While it is improbable, you could also ++use system init file instead (@pxref{System-wide configuration}). ++@end itemize ++ ++This setting applies to the file names as entered by user. If no entry matches ++@value{GDBN} tries as a last resort to also resolve all the file names into ++their canonical form (typically resolving symbolic links) and compare the ++entries again. @value{GDBN} already canonicalizes most of the filenames on its ++own before starting the comparison so a canonical form of directories is ++recommended to be entered. ++ + @node Messages/Warnings + @section Optional Warnings and Messages + +@@ -24955,10 +25062,10 @@ Example: + + @smallexample + (gdb) info auto-load python-scripts +-Loaded Script +-Yes py-section-script.py +- full name: /tmp/py-section-script.py +-Missing my-foo-pretty-printers.py ++Loaded Script ++Yes py-section-script.py ++ full name: /tmp/py-section-script.py ++No my-foo-pretty-printers.py + @end smallexample + @end table + +Index: gdb-7.4.50.20120120/gdb/python/py-auto-load.c +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/python/py-auto-load.c 2012-04-18 00:46:47.000000000 +0200 ++++ gdb-7.4.50.20120120/gdb/python/py-auto-load.c 2012-04-18 00:49:21.621735985 +0200 +@@ -72,14 +72,19 @@ static void + gdbpy_load_auto_script_for_objfile (struct objfile *objfile, FILE *file, + const char *filename) + { ++ int is_safe; + struct auto_load_pspace_info *pspace_info; + ++ is_safe = file_is_auto_load_safe (filename); ++ + /* 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, filename, filename, &script_language_python); ++ maybe_add_script (pspace_info, is_safe, filename, filename, ++ &script_language_python); + +- source_python_script_for_objfile (objfile, file, filename); ++ if (is_safe) ++ source_python_script_for_objfile (objfile, file, filename); + } + + /* Load scripts specified in OBJFILE. +@@ -147,6 +152,9 @@ source_section_scripts (struct objfile * + { + make_cleanup_fclose (stream); + make_cleanup (xfree, full_path); ++ ++ if (!file_is_auto_load_safe (full_path)) ++ opened = 0; + } + else + { +@@ -167,7 +175,7 @@ Use `info auto-load python [REGEXP]' to + + IWBN if complaints.c were more general-purpose. */ + +- in_hash_table = maybe_add_script (pspace_info, file, full_path, ++ in_hash_table = maybe_add_script (pspace_info, opened, file, full_path, + &script_language_python); + + /* If this file is not currently loaded, load it. */ +Index: gdb-7.4.50.20120120/gdb/testsuite/gdb.python/py-objfile-script.exp +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/testsuite/gdb.python/py-objfile-script.exp 2012-04-18 00:46:47.000000000 +0200 ++++ gdb-7.4.50.20120120/gdb/testsuite/gdb.python/py-objfile-script.exp 2012-04-18 00:49:21.621735985 +0200 +@@ -37,6 +37,7 @@ if { [skip_python_tests] } { continue } + set remote_python_file [remote_download host ${srcdir}/${subdir}/${testfile}-gdb.py.in ${subdir}/${testfile}-gdb.py] + + gdb_reinitialize_dir $srcdir/$subdir ++gdb_test_no_output "set auto-load safe-path ${remote_python_file}" "set auto-load safe-path" + gdb_load ${binfile} + + # Verify gdb loaded the script. +Index: gdb-7.4.50.20120120/gdb/testsuite/gdb.python/py-section-script.exp +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/testsuite/gdb.python/py-section-script.exp 2012-04-18 00:46:47.000000000 +0200 ++++ gdb-7.4.50.20120120/gdb/testsuite/gdb.python/py-section-script.exp 2012-04-18 00:49:21.621735985 +0200 +@@ -49,6 +49,7 @@ if { [skip_python_tests] } { continue } + set remote_python_file [remote_download host ${srcdir}/${subdir}/${testfile}.py] + + gdb_reinitialize_dir $srcdir/$subdir ++gdb_test_no_output "set auto-load safe-path ${remote_python_file}" "set auto-load safe-path" + gdb_load ${binfile} + + # Verify gdb loaded the script. diff --git a/gdb-autoload-12of12.patch b/gdb-autoload-12of12.patch new file mode 100644 index 0000000..392bdbc --- /dev/null +++ b/gdb-autoload-12of12.patch @@ -0,0 +1,352 @@ +[patch#4 6/8] set debug auto-load +http://sourceware.org/ml/gdb-patches/2012-04/msg00089.html +http://sourceware.org/ml/gdb-cvs/2012-04/msg00115.html + +### src/gdb/ChangeLog 2012/04/17 15:54:28 1.14114 +### src/gdb/ChangeLog 2012/04/17 15:56:20 1.14115 +## -1,5 +1,27 @@ + 2012-04-17 Jan Kratochvil + ++ New option "set debug auto-load". ++ * NEWS: New commands "set debug auto-load" and "show debug auto-load". ++ * auto-load.c (debug_auto_load, show_debug_auto_load: New. ++ (auto_load_safe_path_vec_update) ++ (filename_is_in_auto_load_safe_path_vec): Call fprintf_unfiltered ++ if DEBUG_AUTO_LOAD. ++ (file_is_auto_load_safe): New parameters debug_fmt and .... ++ Call fprintf_unfiltered if DEBUG_AUTO_LOAD. ++ (source_gdb_script_for_objfile): Extend the file_is_auto_load_safe ++ caller by explanatory string. ++ (_initialize_auto_load): Register "set debug auto-load". ++ * auto-load.h (file_is_auto_load_safe): New parameters debug_fmt ++ and .... ++ * linux-thread-db.c (try_thread_db_load_from_pdir_1) ++ (try_thread_db_load_from_dir): Extend the file_is_auto_load_safe caller ++ by explanatory string. ++ * main.c (captured_main): Likewise. ++ * python/py-auto-load.c (gdbpy_load_auto_script_for_objfile) ++ (source_section_scripts): Likewise. ++ ++2012-04-17 Jan Kratochvil ++ + New option "set auto-load safe-path". + * NEWS: New commands "set auto-load safe-path" + and "show auto-load safe-path". +Index: gdb-7.4.50.20120120/gdb/NEWS +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/NEWS 2012-04-18 00:49:33.000000000 +0200 ++++ gdb-7.4.50.20120120/gdb/NEWS 2012-04-18 00:50:15.018600282 +0200 +@@ -72,6 +72,10 @@ show auto-load safe-path + Set a list of directories from which it is safe to auto-load files. + The delimiter (':' above) may differ according to the host platform. + ++set debug auto-load on|off ++show debug auto-load ++ Control display of debugging info for auto-loading the files above. ++ + * New command line options + + --init-command=FILE, -ix Like --command, -x but execute it +Index: gdb-7.4.50.20120120/gdb/auto-load.c +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/auto-load.c 2012-04-18 00:49:21.000000000 +0200 ++++ gdb-7.4.50.20120120/gdb/auto-load.c 2012-04-18 00:50:04.801626235 +0200 +@@ -43,6 +43,20 @@ + static void source_gdb_script_for_objfile (struct objfile *objfile, FILE *file, + const char *filename); + ++/* Value of the 'set debug auto-load' configuration variable. */ ++static int debug_auto_load = 0; ++ ++/* "show" command for the debug_auto_load configuration variable. */ ++ ++static void ++show_debug_auto_load (struct ui_file *file, int from_tty, ++ struct cmd_list_element *c, const char *value) ++{ ++ fprintf_filtered (file, _("Debugging output for files " ++ "of 'set auto-load ...' is %s.\n"), ++ value); ++} ++ + /* User-settable option to enable/disable auto-loading of GDB_AUTO_FILE_NAME + scripts: + set auto-load gdb-scripts on|off +@@ -112,6 +126,11 @@ auto_load_safe_path_vec_update (void) + unsigned len; + int ix; + ++ if (debug_auto_load) ++ fprintf_unfiltered (gdb_stdlog, ++ _("auto-load: Updating directories of \"%s\".\n"), ++ auto_load_safe_path); ++ + free_char_ptr_vec (auto_load_safe_path_vec); + + auto_load_safe_path_vec = dirnames_to_char_ptr_vec (auto_load_safe_path); +@@ -126,14 +145,34 @@ auto_load_safe_path_vec_update (void) + char *real_path = gdb_realpath (expanded); + + /* Ensure the current entry is at least tilde_expand-ed. */ +- xfree (dir); + VEC_replace (char_ptr, auto_load_safe_path_vec, ix, expanded); + ++ if (debug_auto_load) ++ { ++ if (strcmp (expanded, dir) == 0) ++ fprintf_unfiltered (gdb_stdlog, ++ _("auto-load: Using directory \"%s\".\n"), ++ expanded); ++ else ++ fprintf_unfiltered (gdb_stdlog, ++ _("auto-load: Resolved directory \"%s\" " ++ "as \"%s\".\n"), ++ dir, expanded); ++ } ++ xfree (dir); ++ + /* If gdb_realpath returns a different content, append it. */ + if (strcmp (real_path, expanded) == 0) + xfree (real_path); + else +- VEC_safe_push (char_ptr, auto_load_safe_path_vec, real_path); ++ { ++ VEC_safe_push (char_ptr, auto_load_safe_path_vec, real_path); ++ ++ if (debug_auto_load) ++ fprintf_unfiltered (gdb_stdlog, ++ _("auto-load: And canonicalized as \"%s\".\n"), ++ real_path); ++ } + } + } + +@@ -217,16 +256,30 @@ filename_is_in_auto_load_safe_path_vec ( + if (dir == NULL) + { + if (*filename_realp == NULL) +- *filename_realp = gdb_realpath (filename); ++ { ++ *filename_realp = gdb_realpath (filename); ++ if (debug_auto_load && strcmp (*filename_realp, filename) != 0) ++ fprintf_unfiltered (gdb_stdlog, ++ _("auto-load: Resolved " ++ "file \"%s\" as \"%s\".\n"), ++ filename, *filename_realp); ++ } + +- for (ix = 0; VEC_iterate (char_ptr, auto_load_safe_path_vec, ix, dir); +- ++ix) +- if (filename_is_in_dir (*filename_realp, dir)) +- break; ++ if (strcmp (*filename_realp, filename) != 0) ++ for (ix = 0; VEC_iterate (char_ptr, auto_load_safe_path_vec, ix, dir); ++ ++ix) ++ if (filename_is_in_dir (*filename_realp, dir)) ++ break; + } + + if (dir != NULL) +- return 1; ++ { ++ if (debug_auto_load) ++ fprintf_unfiltered (gdb_stdlog, _("auto-load: File \"%s\" matches " ++ "directory \"%s\".\n"), ++ filename, dir); ++ return 1; ++ } + + return 0; + } +@@ -240,11 +293,20 @@ filename_is_in_auto_load_safe_path_vec ( + directory. */ + + int +-file_is_auto_load_safe (const char *filename) ++file_is_auto_load_safe (const char *filename, const char *debug_fmt, ...) + { + char *filename_real = NULL; + struct cleanup *back_to; + ++ if (debug_auto_load) ++ { ++ va_list debug_args; ++ ++ va_start (debug_args, debug_fmt); ++ vfprintf_unfiltered (gdb_stdlog, debug_fmt, debug_args); ++ va_end (debug_args); ++ } ++ + back_to = make_cleanup (free_current_contents, &filename_real); + + if (filename_is_in_auto_load_safe_path_vec (filename, &filename_real)) +@@ -281,7 +343,10 @@ source_gdb_script_for_objfile (struct ob + struct auto_load_pspace_info *pspace_info; + volatile struct gdb_exception e; + +- is_safe = file_is_auto_load_safe (filename); ++ is_safe = file_is_auto_load_safe (filename, _("auto-load: Loading canned " ++ "sequences of commands script " ++ "\"%s\" for objfile \"%s\".\n"), ++ filename, objfile->name); + + /* Add this script to the hash table too so "info auto-load gdb-scripts" + can print it. */ +@@ -975,4 +1040,13 @@ See the commands 'set auto-load safe-pat + access the current full list setting."), + &cmdlist); + set_cmd_completer (cmd, filename_completer); ++ ++ add_setshow_boolean_cmd ("auto-load", class_maintenance, ++ &debug_auto_load, _("\ ++Set auto-load verifications debugging."), _("\ ++Show auto-load verifications debugging."), _("\ ++When non-zero, debugging output for files of 'set auto-load ...'\n\ ++is displayed."), ++ NULL, show_debug_auto_load, ++ &setdebuglist, &showdebuglist); + } +Index: gdb-7.4.50.20120120/gdb/auto-load.h +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/auto-load.h 2012-04-18 00:49:21.000000000 +0200 ++++ gdb-7.4.50.20120120/gdb/auto-load.h 2012-04-18 00:50:04.801626235 +0200 +@@ -55,6 +55,7 @@ extern struct cmd_list_element **auto_lo + extern struct cmd_list_element **auto_load_show_cmdlist_get (void); + extern struct cmd_list_element **auto_load_info_cmdlist_get (void); + +-extern int file_is_auto_load_safe (const char *filename); ++extern int file_is_auto_load_safe (const char *filename, ++ const char *debug_fmt, ...); + + #endif /* AUTO_LOAD_H */ +Index: gdb-7.4.50.20120120/gdb/linux-thread-db.c +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/linux-thread-db.c 2012-04-18 00:49:21.000000000 +0200 ++++ gdb-7.4.50.20120120/gdb/linux-thread-db.c 2012-04-18 00:50:04.801626235 +0200 +@@ -869,7 +869,9 @@ try_thread_db_load_from_pdir_1 (struct o + gdb_assert (cp != NULL); + strcpy (cp + 1, LIBTHREAD_DB_SO); + +- if (!file_is_auto_load_safe (path)) ++ if (!file_is_auto_load_safe (path, _("auto-load: Loading libthread-db " ++ "library \"%s\" from $pdir.\n"), ++ path)) + result = 0; + else + result = try_thread_db_load (path); +@@ -939,7 +941,10 @@ try_thread_db_load_from_dir (const char + path[dir_len] = '/'; + strcpy (path + dir_len + 1, LIBTHREAD_DB_SO); + +- if (!file_is_auto_load_safe (path)) ++ if (!file_is_auto_load_safe (path, _("auto-load: Loading libthread-db " ++ "library \"%s\" from explicit " ++ "directory.\n"), ++ path)) + result = 0; + else + result = try_thread_db_load (path); +Index: gdb-7.4.50.20120120/gdb/main.c +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/main.c 2012-04-18 00:49:21.000000000 +0200 ++++ gdb-7.4.50.20120120/gdb/main.c 2012-04-18 00:50:04.801626235 +0200 +@@ -1027,7 +1027,10 @@ captured_main (void *data) + auto_load_local_gdbinit_pathname = gdb_realpath (local_gdbinit); + + if (!inhibit_gdbinit && auto_load_local_gdbinit +- && file_is_auto_load_safe (local_gdbinit)) ++ && file_is_auto_load_safe (local_gdbinit, ++ _("auto-load: Loading .gdbinit " ++ "file \"%s\".\n"), ++ local_gdbinit)) + { + auto_load_local_gdbinit_loaded = 1; + +Index: gdb-7.4.50.20120120/gdb/doc/gdb.texinfo +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/doc/gdb.texinfo 2012-04-18 00:49:21.000000000 +0200 ++++ gdb-7.4.50.20120120/gdb/doc/gdb.texinfo 2012-04-18 00:50:04.809626215 +0200 +@@ -20887,6 +20887,7 @@ These are @value{GDBN} control commands + * libthread_db.so.1 file:: @samp{set/show/info auto-load libthread-db} + * objfile-gdb.gdb file:: @samp{set/show/info auto-load gdb-script} + * Auto-loading safe path:: @samp{set/show/info auto-load safe-path} ++* Auto-loading verbose mode:: @samp{set/show debug auto-load} + @xref{Python Auto-loading}. + @end menu + +@@ -21085,6 +21086,45 @@ entries again. @value{GDBN} already can + own before starting the comparison so a canonical form of directories is + recommended to be entered. + ++@node Auto-loading verbose mode ++@subsection Displaying files tried for auto-load ++@cindex auto-loading verbose mode ++ ++For better visibility of all the file locations where you can place scripts to ++be auto-loaded with inferior --- or to protect yourself against accidental ++execution of untrusted scripts --- @value{GDBN} provides a feature for printing ++all the files attempted to be loaded. Both existing and non-existing files may ++be printed. ++ ++For example the list of directories from which it is safe to auto-load files ++(@pxref{Auto-loading safe path}) applies also to canonicalized filenames which ++may not be too obvious while setting it up. ++ ++@smallexample ++(gdb) set debug auto-load ues ++(gdb) file ~/src/t/true ++auto-load: Loading canned sequences of commands script "/tmp/true-gdb.gdb" ++ for objfile "/tmp/true". ++auto-load: Updating directories of "/usr:/opt". ++auto-load: Using directory "/usr". ++auto-load: Using directory "/opt". ++warning: File "/tmp/true-gdb.gdb" auto-loading has been declined ++ by your `auto-load safe-path' set to "/usr:/opt". ++@end smallexample ++ ++@table @code ++@anchor{set debug auto-load} ++@kindex set debug auto-load ++@item set debug auto-load [on|off] ++Set whether to print the filenames attempted to be auto-loaded. ++ ++@anchor{show debug auto-load} ++@kindex show debug auto-load ++@item show debug auto-load ++Show whether printing of the filenames attempted to be auto-loaded is turned ++on or off. ++@end table ++ + @node Messages/Warnings + @section Optional Warnings and Messages + +Index: gdb-7.4.50.20120120/gdb/python/py-auto-load.c +=================================================================== +--- gdb-7.4.50.20120120.orig/gdb/python/py-auto-load.c 2012-04-18 00:49:21.000000000 +0200 ++++ gdb-7.4.50.20120120/gdb/python/py-auto-load.c 2012-04-18 00:50:04.810626212 +0200 +@@ -75,7 +75,10 @@ gdbpy_load_auto_script_for_objfile (stru + int is_safe; + struct auto_load_pspace_info *pspace_info; + +- is_safe = file_is_auto_load_safe (filename); ++ is_safe = file_is_auto_load_safe (filename, ++ _("auto-load: Loading Python script \"%s\" " ++ "by extension for objfile \"%s\".\n"), ++ filename, objfile->name); + + /* Add this script to the hash table too so "info auto-load python-scripts" + can print it. */ +@@ -153,7 +156,12 @@ source_section_scripts (struct objfile * + make_cleanup_fclose (stream); + make_cleanup (xfree, full_path); + +- if (!file_is_auto_load_safe (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)) + opened = 0; + } + else diff --git a/gdb.spec b/gdb.spec index 274fae0..667d5df 100644 --- a/gdb.spec +++ b/gdb.spec @@ -33,7 +33,7 @@ Version: 7.4.50.%{snap} # The release always contains a leading reserved number, start it at 1. # `upstream' is not a part of `name' to stay fully rpm dependencies compatible for the testing. -Release: 39%{?dist} +Release: 40%{?dist} License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ and GPLv2+ with exceptions and GPL+ and LGPLv2+ and BSD and Public Domain Group: Development/Debuggers @@ -174,10 +174,6 @@ Patch145: gdb-6.3-threaded-watchpoints2-20050225.patch #=ia64 Patch153: gdb-6.3-ia64-gcore-page0-20050421.patch -# Security errata for untrusted .gdbinit -#=push -Patch157: gdb-6.3-security-errata-20050610.patch - # IA64 sigtramp prev register patch #=ia64 Patch158: gdb-6.3-ia64-sigtramp-frame-20050708.patch @@ -569,19 +565,38 @@ Patch653: gdb-attach-fail-reasons-5of5.patch Patch657: gdb-attach-fail-reasons-5of5configure.patch # Fix inferior calls, particularly uncaught thrown exceptions (BZ 799531). +#=push+work Patch654: gdb-x86-onstack-1of2.patch Patch658: gdb-x86-onstack-2of2.patch # Fix DWARF DIEs CU vs. section relative offsets (Joel Brobecker, me). +#=push Patch655: gdb-die-cu-offset-1of2.patch Patch656: gdb-die-cu-offset-2of2.patch # [vla] Fix regression on no type for subrange from IBM XLF Fortran (BZ 806920). +#=push Patch660: gdb-subrange-no-type.patch # Workaround crashes from stale frame_info pointer (BZ 804256). +#=push+work Patch661: gdb-stale-frame_info.patch +# Security fix for loading untrusted inferiors, see "set auto-load" (BZ 756117). +#=push +Patch662: gdb-autoload-01of12.patch +Patch663: gdb-autoload-02of12.patch +Patch664: gdb-autoload-03of12.patch +Patch665: gdb-autoload-04of12.patch +Patch666: gdb-autoload-05of12.patch +Patch667: gdb-autoload-06of12.patch +Patch668: gdb-autoload-07of12.patch +Patch669: gdb-autoload-08of12.patch +Patch670: gdb-autoload-09of12.patch +Patch671: gdb-autoload-10of12.patch +Patch672: gdb-autoload-11of12.patch +Patch673: gdb-autoload-12of12.patch + %if 0%{!?rhel:1} || 0%{?rhel} > 6 # RL_STATE_FEDORA_GDB would not be found for: # Patch642: gdb-readline62-ask-more-rh.patch @@ -768,7 +783,6 @@ rm -f gdb/jv-exp.c gdb/m2-exp.c gdb/objc-exp.c gdb/p-exp.c %patch140 -p1 %patch145 -p1 %patch153 -p1 -%patch157 -p1 %patch158 -p1 %patch160 -p1 %patch161 -p1 @@ -873,6 +887,18 @@ rm -f gdb/jv-exp.c gdb/m2-exp.c gdb/objc-exp.c gdb/p-exp.c %patch656 -p1 %patch660 -p1 %patch661 -p1 +%patch662 -p1 +%patch663 -p1 +%patch664 -p1 +%patch665 -p1 +%patch666 -p1 +%patch667 -p1 +%patch668 -p1 +%patch669 -p1 +%patch670 -p1 +%patch671 -p1 +%patch672 -p1 +%patch673 -p1 %patch393 -p1 %if 0%{!?el5:1} || 0%{?scl:1} @@ -992,6 +1018,7 @@ $(: RHEL-5 librpm has incompatible API. ) \ %else # !%{have_inproctrace} --disable-inprocess-agent \ %endif # !%{have_inproctrace} + --with-auto-load-safe-path=%{_prefix} \ %ifarch sparc sparcv9 sparc-%{_vendor}-%{_target_os}%{?_gnu} %else @@ -1352,6 +1379,9 @@ fi %endif # 0%{!?el5:1} || "%{_target_cpu}" == "noarch" %changelog +* Wed Apr 18 2012 Jan Kratochvil - 7.4.50.20120120-40.fc17 +- Security fix for loading untrusted inferiors, see "set auto-load" (BZ 756117). + * Fri Apr 13 2012 Jan Kratochvil - 7.4.50.20120120-39.fc17 - [RHEL7] Fix/remove readline-devel BuildRequires redundant distro suffic .fc17.