[gdb/f17] Security fix for loading untrusted inferiors, see "set auto-load" (BZ 756117).
Jan Kratochvil
jankratochvil at fedoraproject.org
Wed Apr 18 00:17:38 UTC 2012
commit 08451779f969455df3b5f16e872f5e698ca794f9
Author: Jan Kratochvil <jan.kratochvil at redhat.com>
Date: Wed Apr 18 02:17:28 2012 +0200
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(-)
---
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 <jan.kratochvil at redhat.com>
++
++ 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 <palves at redhat.com>
+
+ * 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 <http://www.gnu.org/licenses/>. */
++
++
++#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 <tromey at redhat.com>
++
++ * 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 <pedro at codesourcery.com>
+
+ * 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 <stddef.h>
+ #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 <jan.kratochvil at redhat.com>
++
++ 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 <palves at redhat.com>
+
+ * 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 <jan.kratochvil at redhat.com>
++
++ 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 <tromey at redhat.com>
+
+ * 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 <jan.kratochvil at redhat.com>
+
++ * 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 <jan.kratochvil at redhat.com>
++
+ 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
+
++ at item -init-command @var{file}
++ at itemx -ix @var{file}
++ at cindex @code{--init-command}
++ at cindex @code{-ix}
++Execute commands from file @var{file} before loading gdbinit files or the
++inferior.
++ at xref{Startup}.
++
++ at item -init-eval-command @var{command}
++ at itemx -iex @var{command}
++ at cindex @code{--init-eval-command}
++ at cindex @code{-iex}
++Execute a single @value{GDBN} command before loading gdbinit files or the
++inferior.
++ at 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
++ at samp{-ix} options in their specified order. Usually you should use the
++ at 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.
++
++ at 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:
+-
+- at smallexample
+-$ gdb -ex "set auto-load-scripts off" myprogram
+- at 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 <jan.kratochvil at redhat.com>
+
++ 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 <jan.kratochvil at redhat.com>
++
+ * 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 <jan.kratochvil at redhat.com>
++
++ * 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 <sivachandra at google.com>
+
+ * 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.
+
+- at node .debug_gdb_scripts section
++ at 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.
+- at xref{.debug_gdb_scripts section}.
++ at 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 <jan.kratochvil at redhat.com>
+
+ 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 <jan.kratochvil at redhat.com>
++
++ 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 <sys/resource.h>
+ #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 <http://www.gnu.org/licenses/>. */
++
++#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 <http://www.gnu.org/licenses/>. */
++
++#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 <http://www.gnu.org/licenses/>. */
+
+ #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 <jan.kratochvil at redhat.com>
+
++ 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 <jan.kratochvil at redhat.com>
++
+ 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 <signal.h>
++#include <ctype.h>
+
+ #ifdef HAVE_GNU_LIBC_VERSION_H
+ #include <gnu/libc-version.h>
+@@ -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
+ <proc_service.h> 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
++ at 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}).
+
++ at 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.
+
++ at anchor{Home Directory Init File}
+ @item
+ Reads the init file (if any) in your home directory at 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.
+
++ at 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
++ at 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.
+
++ at 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 at t{++} ABI to @var{abi}, or return to automatic detection.
+ @end table
+
++ at node Auto-loading
++ at section Automatically loading associated files
++ at cindex auto-loading
++
++ at value{GDBN} sometimes reads files with commands and settings automatically,
++without being explicitly told so by the user. We call this feature
++ at dfn{auto-loading}. While auto-loading is useful for automatically adapting
++ at 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.
++
++ at table @code
++ at anchor{set auto-load off}
++ at kindex set auto-load off
++ at 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:
++ at smallexample
++$ @kbd{gdb -iex "set auto-load off" untrusted-executable corefile}
++ at 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
++ at option{-nx} option (@pxref{Mode Options}), in addition to
++ at code{set auto-load no}.
++
++ at anchor{show auto-load}
++ at kindex show auto-load
++ at item show auto-load
++Show whether auto-loading of each specific @samp{auto-load} file(s) is enabled
++or disabled.
++
++ at 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.
++ at end smallexample
++
++ at anchor{info auto-load}
++ at kindex info auto-load
++ at item info auto-load
++Print whether each specific @samp{auto-load} file(s) have been auto-loaded or
++not.
++
++ at 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
++ at end smallexample
++ at end table
++
++These are various kinds of files @value{GDBN} can automatically load:
++
++ at itemize @bullet
++ at item
++ at xref{objfile-gdb.py file}, controlled by @ref{set auto-load python-scripts}.
++ at item
++ at xref{objfile-gdb.gdb file}, controlled by @ref{set auto-load gdb-scripts}.
++ at item
++ at xref{dotdebug_gdb_scripts section},
++controlled by @ref{set auto-load python-scripts}.
++ at item
++ at xref{Init File in the Current Directory},
++controlled by @ref{set auto-load local-gdbinit}.
++ at item
++ at xref{libthread_db.so.1 file}, controlled by @ref{set auto-load libthread-db}.
++ at end itemize
++
++These are @value{GDBN} control commands for the auto-loading:
++
++ at multitable @columnfractions .5 .5
++ at item @xref{set auto-load off}.
++ at tab Disable auto-loading globally.
++ at item @xref{show auto-load}.
++ at tab Show setting of all kinds of files.
++ at item @xref{info auto-load}.
++ at tab Show state of all kinds of files.
++ at item @xref{set auto-load gdb-scripts}.
++ at tab Control for @value{GDBN} command scripts.
++ at item @xref{show auto-load gdb-scripts}.
++ at tab Show setting of @value{GDBN} command scripts.
++ at item @xref{info auto-load gdb-scripts}.
++ at tab Show state of @value{GDBN} command scripts.
++ at item @xref{set auto-load python-scripts}.
++ at tab Control for @value{GDBN} Python scripts.
++ at item @xref{show auto-load python-scripts}.
++ at tab Show setting of @value{GDBN} Python scripts.
++ at item @xref{info auto-load python-scripts}.
++ at tab Show state of @value{GDBN} Python scripts.
++ at item @xref{set auto-load local-gdbinit}.
++ at tab Control for init file in the current directory.
++ at item @xref{show auto-load local-gdbinit}.
++ at tab Show setting of init file in the current directory.
++ at item @xref{info auto-load local-gdbinit}.
++ at tab Show state of init file in the current directory.
++ at item @xref{set auto-load libthread-db}.
++ at tab Control for thread debugging library.
++ at item @xref{show auto-load libthread-db}.
++ at tab Show setting of thread debugging library.
++ at item @xref{info auto-load libthread-db}.
++ at tab Show state of thread debugging library.
++ at end multitable
++
++ at 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}
++ at xref{Python Auto-loading}.
++ at end menu
++
++ at node Init File in the Current Directory
++ at subsection Automatically loading init file in the current directory
++ at 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}.
++
++ at table @code
++ at anchor{set auto-load local-gdbinit}
++ at kindex set auto-load local-gdbinit
++ at 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.
++
++ at anchor{show auto-load local-gdbinit}
++ at kindex show auto-load local-gdbinit
++ at 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.
++
++ at anchor{info auto-load local-gdbinit}
++ at kindex info auto-load local-gdbinit
++ at item info auto-load local-gdbinit
++Print whether canned sequences of commands from init file in the
++current directory have been auto-loaded.
++ at end table
++
++ at node libthread_db.so.1 file
++ at subsection Automatically loading thread debugging library
++ at cindex auto-loading libthread_db.so.1
++
++This feature is currently present only on @sc{gnu}/Linux native hosts.
++
++ at 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
++ at 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.
++
++ at table @code
++ at anchor{set auto-load libthread-db}
++ at kindex set auto-load libthread-db
++ at item set auto-load libthread-db [on|off]
++Enable or disable the auto-loading of inferior specific thread debugging library.
++
++ at anchor{show auto-load libthread-db}
++ at kindex show auto-load libthread-db
++ at item show auto-load libthread-db
++Show whether auto-loading of inferior specific thread debugging library is
++enabled or disabled.
++
++ at anchor{info auto-load libthread-db}
++ at kindex info auto-load libthread-db
++ at 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.
++ at end table
++
++ at node objfile-gdb.gdb file
++ at subsection The @file{@var{objfile}-gdb.gdb} file
++ at cindex auto-loading @file{@var{objfile}-gdb.gdb}
++
++ at 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}).
++
++ at table @code
++ at anchor{set auto-load gdb-scripts}
++ at kindex set auto-load gdb-scripts
++ at item set auto-load gdb-scripts [on|off]
++Enable or disable the auto-loading of canned sequences of commands scripts.
++
++ at anchor{show auto-load gdb-scripts}
++ at kindex show auto-load gdb-scripts
++ at item show auto-load gdb-scripts
++Show whether auto-loading of canned sequences of commands scripts is enabled or
++disabled.
++
++ at anchor{info auto-load gdb-scripts}
++ at kindex info auto-load gdb-scripts
++ at cindex print list of auto-loaded canned sequences of commands scripts
++ at item info auto-load gdb-scripts [@var{regexp}]
++Print the list of all canned sequences of commands scripts that @value{GDBN}
++auto-loaded.
++ at 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
+
+- at node Auto-loading
+- at subsection Auto-loading
+- at cindex auto-loading, Python
++ at node Python Auto-loading
++ at subsection Python Auto-loading
++ at 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
+- at kindex set auto-load-scripts
+- at item set auto-load-scripts [yes|no]
++ at anchor{set auto-load python-scripts}
++ at kindex set auto-load python-scripts
++ at item set auto-load python-scripts [on|off]
+ Enable or disable the auto-loading of Python scripts.
+
+- at kindex show auto-load-scripts
+- at item show auto-load-scripts
++ at anchor{show auto-load python-scripts}
++ at kindex show auto-load python-scripts
++ at item show auto-load python-scripts
+ Show whether auto-loading of Python scripts is enabled or disabled.
+
+- at kindex info auto-load-scripts
+- at cindex print list of auto-loaded scripts
+- at item info auto-load-scripts [@var{regexp}]
+-Print the list of all scripts that @value{GDBN} auto-loaded.
++ at anchor{info auto-load python-scripts}
++ at kindex info auto-load python-scripts
++ at cindex print list of auto-loaded Python scripts
++ at 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 <jan.kratochvil at redhat.com>
+
++ 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 <jan.kratochvil at redhat.com>
++
+ 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 <dir1>[:<dir2>...]
++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.
++ at item @xref{set auto-load safe-path}.
++ at tab Control directories trusted for automatic loading.
++ at item @xref{show auto-load safe-path}.
++ at tab Show directories trusted for automatic loading.
++ at item @xref{add-auto-load-safe-path}.
++ at 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.
+
++ at node Auto-loading safe path
++ at subsection Security restriction for auto-loading
++ at 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.
++ at 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:
++
++ at 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".
++ at end smallexample
++
++The list of trusted directories is controlled by the following commands:
++
++ at table @code
++ at anchor{set auto-load safe-path}
++ at kindex set auto-load safe-path
++ at 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.
++
++ at anchor{show auto-load safe-path}
++ at kindex show auto-load safe-path
++ at item show auto-load safe-path
++Show the list of directories trusted for automatic loading and execution of
++scripts.
++
++ at anchor{add-auto-load-safe-path}
++ at kindex add-auto-load-safe-path
++ at 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.
++ at 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:
++
++ at itemize @bullet
++ at 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).
++
++ at 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
++ at value{GDBN} session.
++
++ at 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.
++
++ at 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.
++ at end itemize
++
++On the other hand you can also explicitly forbid automatic files loading which
++also suppresses any such warning messages:
++
++ at itemize @bullet
++ at item @kbd{gdb -iex "set auto-load no" [@dots{}]}
++You can use @value{GDBN} command-line option for a single @value{GDBN} session.
++
++ at 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}).
++ at end itemize
++
++This setting applies to the file names as entered by user. If no entry matches
++ at 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 <jan.kratochvil at redhat.com>
+
++ 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 <jan.kratochvil at redhat.com>
++
+ 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.
+
++ at node Auto-loading verbose mode
++ at subsection Displaying files tried for auto-load
++ at 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.
++
++ at 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".
++ at end smallexample
++
++ at table @code
++ at anchor{set debug auto-load}
++ at kindex set debug auto-load
++ at item set debug auto-load [on|off]
++Set whether to print the filenames attempted to be auto-loaded.
++
++ at anchor{show debug auto-load}
++ at kindex show debug auto-load
++ at item show debug auto-load
++Show whether printing of the filenames attempted to be auto-loaded is turned
++on or off.
++ at 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 <jan.kratochvil at redhat.com> - 7.4.50.20120120-40.fc17
+- Security fix for loading untrusted inferiors, see "set auto-load" (BZ 756117).
+
* Fri Apr 13 2012 Jan Kratochvil <jan.kratochvil at redhat.com> - 7.4.50.20120120-39.fc17
- [RHEL7] Fix/remove readline-devel BuildRequires redundant distro suffic .fc17.
More information about the scm-commits
mailing list