24#include "gdbsupport/gdb_regex.h"
35#include "readline/tilde.h"
39#include "gdbsupport/filestuff.h"
41#include "gdb/section-scripts.h"
43#include "gdbsupport/pathstuff.h"
52#define AUTO_SECTION_NAME ".debug_gdb_scripts"
55#define DEBUGLINK_SECTION_NAME ".gnu_debuglink"
60 const char *section_name,
unsigned offset);
65 const char *section_name,
unsigned offset);
77 gdb_printf (file, _(
"Debugging output for files "
78 "of 'set auto-load ...' is %s.\n"),
95 gdb_printf (file, _(
"Auto-loading of canned sequences of commands "
135 gdb_printf (file, _(
"Auto-loading of .gdbinit script from current "
136 "directory is %s.\n"),
161 gdb_printf (file, _(
"List of directories from which to load "
162 "auto-loaded scripts is %s.\n"),
179static std::vector<gdb::unique_xmalloc_ptr<char>>
182 char *s = xstrdup (
string);
189 std::vector<gdb::unique_xmalloc_ptr<char>> dir_vec
190 = dirnames_to_char_ptr_vec (s);
210 for (
size_t i = 0; i < len; i++)
213 gdb::unique_xmalloc_ptr<char> expanded (tilde_expand (in_vec.get ()));
214 gdb::unique_xmalloc_ptr<char> real_path = gdb_realpath (expanded.get ());
218 gdb::unique_xmalloc_ptr<char> original = std::move (in_vec);
219 in_vec = std::move (expanded);
223 if (strcmp (in_vec.get (), original.get ()) == 0)
228 original.get (), in_vec.get ());
232 if (strcmp (real_path.get (), in_vec.get ()) != 0)
275 for (cs =
value; *cs && (*cs == DIRNAME_SEPARATOR || IS_DIR_SEPARATOR (*cs));
278 gdb_printf (file, _(
"Auto-load files are safe to load from any "
281 gdb_printf (file, _(
"List of directories from which it is safe to "
282 "auto-load files is %s.\n"),
292 if (args == NULL || *args == 0)
294Directory argument required.\n\
295Use 'set auto-load safe-path /' for disabling the auto-load safe-path security.\
299 DIRNAME_SEPARATOR, args);
310 if (args == NULL || *args == 0)
311 error (_(
"Directory argument required."));
314 DIRNAME_SEPARATOR, args);
323 size_t pattern_len = strlen (pattern);
324 size_t filename_len = strlen (filename);
332 while (pattern_len && IS_DIR_SEPARATOR (pattern[pattern_len - 1]))
334 pattern[pattern_len] =
'\0';
339 if (pattern_len == 0)
349 while (filename_len && IS_DIR_SEPARATOR (filename[filename_len - 1]))
351 filename[filename_len] =
'\0';
352 if (filename_len == 0)
367 while (filename_len > 0 && !IS_DIR_SEPARATOR (filename[filename_len - 1]))
376static ATTRIBUTE_PURE
int
379 char *filename_copy, *pattern_copy;
381 filename_copy = (
char *) alloca (strlen (filename) + 1);
382 strcpy (filename_copy, filename);
383 pattern_copy = (
char *) alloca (strlen (pattern) + 1);
384 strcpy (pattern_copy, pattern);
396 gdb::unique_xmalloc_ptr<char> *filename_realp)
398 const char *pattern = NULL;
409 if (*filename_realp == NULL)
411 *filename_realp = gdb_realpath (filename);
414 filename, filename_realp->get ());
417 if (strcmp (filename_realp->get (), filename) != 0)
441 gdb::unique_xmalloc_ptr<char> filename_real;
442 static bool advice_printed =
false;
451 warning (_(
"File \"%ps\" auto-loading has been declined by your "
452 "`auto-load safe-path' set to \"%s\"."),
460 std::string home_config = find_gdb_home_config_file (
GDBINIT, &buf);
461 if (home_config.empty ())
465 std::string config_dir_file
466 = get_standard_config_filename (
GDBINIT);
467 if (!config_dir_file.empty ())
468 home_config = config_dir_file;
471 const char *homedir = getenv (
"HOME");
472 if (homedir ==
nullptr)
474 home_config = (std::string (homedir) + SLASH_STRING
480To enable execution of this file add\n\
481\tadd-auto-load-safe-path %s\n\
482line to your configuration file \"%ps\".\n\
483To completely disable this security protection add\n\
484\tset auto-load safe-path /\n\
485line to your configuration file \"%ps\".\n\
486For more information about this security protection see the\n\
487\"Auto-loading safe path\" section in the GDB manual. E.g., run from the shell:\n\
488\tinfo \"(gdb)Auto-loading safe path\"\n"),
489 filename_real.get (),
491 home_config.c_str ()),
493 home_config.c_str ()));
494 advice_printed =
true;
564 return htab_hash_string (e->
name) ^ htab_hash_pointer (e->
language);
612 if (info->loaded_script_files == NULL)
627 const char *
name,
const char *full_path,
635 slot = (
struct loaded_script **) htab_find_slot (htab, &entry, INSERT);
636 bool in_hash_table = *slot != NULL;
649 p = ((
char*) *slot) +
sizeof (**slot);
656 (*slot)->full_path = p;
659 (*slot)->full_path = NULL;
664 return in_hash_table;
683 slot = (
struct loaded_script **) htab_find_slot (htab, &entry, INSERT);
684 bool in_hash_table = *slot != NULL;
695 p = ((
char*) *slot) +
sizeof (**slot);
698 (*slot)->full_path = NULL;
703 return in_hash_table;
712 if (info != NULL && info->loaded_script_files != NULL)
724 const char *debugfile;
728 std::string filename = std::string (realname) + suffix;
730 gdb_file_up input = gdb_fopen_cloexec (filename.c_str (),
"r");
731 debugfile = filename.c_str ();
735 input !=
nullptr ?
"exists" :
"does not exist");
737 std::string debugfile_holder;
743 std::vector<gdb::unique_xmalloc_ptr<char>> vec
747 (
"Searching 'set auto-load scripts-directory' path \"%s\".",
751 if (HAS_DRIVE_SPEC (debugfile))
752 filename = (std::string(
"\\") + debugfile[0]
753 + STRIP_DRIVE_SPEC (debugfile));
755 for (
const gdb::unique_xmalloc_ptr<char> &dir : vec)
758 debugfile_holder = dir.get () + filename;
759 debugfile = debugfile_holder.c_str ();
761 input = gdb_fopen_cloexec (debugfile,
"r");
768 :
"does not exist"));
780 (
"Loading %s script \"%s\" by extension for objfile \"%s\".",
805 gdb_assert (sourcer != NULL);
824 gdb::unique_xmalloc_ptr<char> realname
833 size_t len = strlen (realname.get ());
834 const size_t lexe =
sizeof (
".exe") - 1;
836 if (len > lexe && strcasecmp (realname.get () + len - lexe,
".exe") == 0)
839 realname.get ()[len] =
'\0';
842 (
"Stripped .exe suffix, retrying with \"%s\".", realname.get ());
854 if (parent !=
nullptr)
857 gdb::unique_xmalloc_ptr<char> debuglink
858 (bfd_get_debug_link_info (parent->
obfd.get (), &crc32));
860 if (debuglink.get () !=
nullptr
861 && strcmp (debuglink.get (), lbasename (realname.get ())) != 0)
866 std::string p_realname = gdb_realpath (
objfile_name (parent)).get ();
867 size_t last = p_realname.find_last_of (
'/');
869 if (last != std::string::npos)
871 p_realname.replace (last + 1, std::string::npos,
875 (
"Debug filename mismatch, retrying with \"%s\".",
876 p_realname.c_str ());
893 const char *section_name,
unsigned int offset,
904 section_name, offset);
923 (
"Loading %s script \"%s\" from section \"%s\" of objfile \"%s\".",
941 section_name, offset);
946 (opened ? opened->full_path.get (): NULL),
950 if (opened && !in_hash_table)
952 opened->full_path.get ());
963 const char *section_name,
unsigned int offset,
967 const char *newline, *script_text;
973 newline = strchr (script,
'\n');
974 std::string name_holder;
980 name_holder = std::string (script, newline - script);
981 buf = name_holder.c_str ();
982 for (p = buf; *p !=
'\0'; ++p)
988 if (p != buf && *p ==
'\0')
995Missing/bad script name in entry at offset %u in section %s\n\
997 offset, section_name,
1002 script_text = newline + 1;
1006 if (executor == NULL)
1010 section_name, offset);
1023 (
"Loading %s script \"%s\" from section \"%s\" of objfile \"%s\".",
1032 if (is_safe && !in_hash_table)
1050 const char *start,
const char *end)
1055 for (
const char *p = start; p < end; ++p)
1059 unsigned int offset = p - start;
1064 case SECTION_SCRIPT_ID_PYTHON_FILE:
1065 case SECTION_SCRIPT_ID_PYTHON_TEXT:
1068 case SECTION_SCRIPT_ID_SCHEME_FILE:
1069 case SECTION_SCRIPT_ID_SCHEME_TEXT:
1073 warning (_(
"Invalid entry in %s section"), section_name);
1080 while (p < end && *p !=
'\0')
1084 warning (_(
"Non-nul-terminated entry in %s at offset %u"),
1085 section_name, offset);
1092 case SECTION_SCRIPT_ID_PYTHON_FILE:
1093 case SECTION_SCRIPT_ID_SCHEME_FILE:
1096 warning (_(
"Empty entry in %s at offset %u"),
1097 section_name, offset);
1101 section_name, offset, entry);
1103 case SECTION_SCRIPT_ID_PYTHON_TEXT:
1104 case SECTION_SCRIPT_ID_SCHEME_TEXT:
1106 section_name, offset, entry);
1118 asection *scripts_sect;
1119 bfd_byte *data = NULL;
1121 scripts_sect = bfd_get_section_by_name (abfd, section_name);
1122 if (scripts_sect == NULL
1123 || (bfd_section_flags (scripts_sect) & SEC_HAS_CONTENTS) == 0)
1126 if (!bfd_get_full_section_contents (abfd, scripts_sect, &data))
1127 warning (_(
"Couldn't read %s section of %ps"),
1130 bfd_get_filename (abfd)));
1133 gdb::unique_xmalloc_ptr<bfd_byte> data_holder (data);
1135 char *p = (
char *) data;
1137 p + bfd_section_size (scripts_sect));
1190 if (script->
language == data->language && re_exec (script->
name))
1191 data->scripts_p->push_back (script);
1213 uiout->
text (
"\tfull name: ");
1224 return FILENAME_CMP (a->
name, b->
name) < 0;
1256 if (pattern && *pattern)
1258 char *re_err =
re_comp (pattern);
1261 error (_(
"Invalid regexp: %s"), re_err);
1272 std::vector<loaded_script *> script_files, script_texts;
1282 std::sort (script_files.begin (), script_files.end (),
1294 std::sort (script_texts.begin (), script_texts.end (),
1298 int nr_scripts = script_files.size () + script_texts.size ();
1307 "AutoLoadedScriptsTable");
1317 if (nr_scripts == 0)
1319 if (pattern && *pattern)
1320 uiout->
message (
"No auto-load scripts matching %s.\n", pattern);
1322 uiout->
message (
"No auto-load scripts.\n");
1341 gdb_printf (_(
"Local .gdbinit file was not found.\n"));
1343 gdb_printf (_(
"Local .gdbinit file \"%ps\" has been loaded.\n"),
1347 gdb_printf (_(
"Local .gdbinit file \"%ps\" has not been loaded.\n"),
1360 const char *section_name,
unsigned offset)
1365Unsupported auto-load script at offset %u in section %s\n\
1367Use `info auto-load %s-scripts [REGEXP]' to list them."),
1368 offset, section_name,
1384 const char *section_name,
unsigned offset)
1389Missing auto-load script at offset %u in section %s\n\
1391Use `info auto-load %s-scripts [REGEXP]' to list them."),
1392 offset, section_name,
1410 length = args ? strlen (args) : 0;
1412 while (length > 0 && (args[length - 1] ==
' ' || args[length - 1] ==
'\t'))
1415 if (length == 0 || (strncmp (args,
"off", length) != 0
1416 && strncmp (args,
"0", length) != 0
1417 && strncmp (args,
"no", length) != 0
1418 && strncmp (args,
"disable", length) != 0))
1419 error (_(
"Valid is only global 'set auto-load no'; "
1420 "otherwise check the auto-load sub-commands."));
1439Auto-loading specific settings.\n\
1440Configure various auto-load-specific variables such as\n\
1441automatic loading of Python scripts."),
1456Show auto-loading specific settings.\n\
1457Show configuration of various auto-load-specific variables such as\n\
1458automatic loading of Python scripts."),
1498Print current status of auto-loaded files.\n\
1499Print whether various files like Python scripts or .gdbinit files have been\n\
1500found and/or loaded."),
1515 gdb::unique_xmalloc_ptr<char> scripts_directory_help, gdb_name_help,
1516 python_name_help, guile_name_help;
1526Enable or disable auto-loading of canned sequences of commands scripts."), _(
"\
1527Show whether auto-loading of canned sequences of commands scripts is enabled."),
1529If enabled, canned sequences of commands are loaded when the debugger reads\n\
1530an executable or shared library.\n\
1531This option has security implications for untrusted inferiors."),
1537 _(
"Print the list of automatically loaded sequences of commands.\n\
1538Usage: info auto-load gdb-scripts [REGEXP]"),
1543Enable or disable auto-loading of .gdbinit script in current directory."), _(
"\
1544Show whether auto-loading .gdbinit script in current directory is enabled."),
1546If enabled, canned sequences of commands are loaded when debugger starts\n\
1547from .gdbinit file in current directory. Such files are deprecated,\n\
1548use a script associated with inferior executable file instead.\n\
1549This option has security implications for untrusted inferiors."),
1555 _(
"Print whether current directory .gdbinit file has been loaded.\n\
1556Usage: info auto-load local-gdbinit"),
1562GDB scripts: OBJFILE%s\n"),
1564 python_name_help = NULL;
1569Python scripts: OBJFILE%s\n"),
1572 guile_name_help = NULL;
1577Guile scripts: OBJFILE%s\n"),
1580 scripts_directory_help
1582Automatically loaded scripts are located in one of the directories listed\n\
1588This option is ignored for the kinds of scripts \
1589having 'set auto-load ... off'.\n\
1590Directories listed here need to be present also \
1591in the 'set auto-load safe-path'\n\
1593 gdb_name_help.get (),
1594 python_name_help.get () ? python_name_help.get () :
"",
1595 guile_name_help.get () ? guile_name_help.get () :
"");
1599Set the list of directories from which to load auto-loaded scripts."), _(
"\
1600Show the list of directories from which to load auto-loaded scripts."),
1601 scripts_directory_help.get (),
1608Set the list of files and directories that are safe for auto-loading."), _(
"\
1609Show the list of files and directories that are safe for auto-loading."), _(
"\
1610Various files loaded automatically for the 'set auto-load ...' options must\n\
1611be located in one of the directories listed by this option. Warning will be\n\
1612printed and file will not be used otherwise.\n\
1613You can mix both directory and filename entries.\n\
1614Setting this parameter to an empty list resets it to its default value.\n\
1615Setting this parameter to '/' (without the quotes) allows any file\n\
1616for the 'set auto-load ...' options. Each path entry can be also shell\n\
1617wildcard pattern; '*' does not match directory separator.\n\
1618This option is ignored for the kinds of files having 'set auto-load ... off'.\n\
1619This option has security implications for untrusted inferiors."),
1629 _(
"Add entries to the list of directories from which it is safe "
1630 "to auto-load files.\n\
1631See the commands 'set auto-load safe-path' and 'show auto-load safe-path' to\n\
1632access the current full list setting."),
1638 _(
"Add entries to the list of directories from which to load "
1639 "auto-loaded scripts.\n\
1640See the commands 'set auto-load scripts-directory' and\n\
1641'show auto-load scripts-directory' to access the current full list setting."),
1647Set auto-load verifications debugging."), _(
"\
1648Show auto-load verifications debugging."), _(
"\
1649When non-zero, debugging output for files of 'set auto-load ...'\n\
static void add_auto_load_safe_path(const char *args, int from_tty)
static int filename_is_in_auto_load_safe_path_vec(const char *filename, gdb::unique_xmalloc_ptr< char > *filename_realp)
struct auto_load_pspace_info * get_auto_load_pspace_data_for_loading(struct program_space *pspace)
static void add_auto_load_dir(const char *args, int from_tty)
#define AUTO_SECTION_NAME
static std::string auto_load_dir
static int eq_loaded_script_entry(const void *a, const void *b)
static hashval_t hash_loaded_script_entry(const void *data)
static int filename_is_in_pattern_1(char *filename, char *pattern)
static void info_auto_load_cmd(const char *args, int from_tty)
static void show_debug_auto_load(struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value)
static void show_auto_load_dir(struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value)
static void auto_load_section_scripts(struct objfile *objfile, const char *section_name)
bool file_is_auto_load_safe(const char *filename)
static struct auto_load_pspace_info * get_auto_load_pspace_data(struct program_space *pspace)
static void execute_script_contents(struct auto_load_pspace_info *pspace_info, struct objfile *objfile, const struct extension_language_defn *language, const char *section_name, unsigned int offset, const char *script)
void _initialize_auto_load()
bool auto_load_gdb_scripts_enabled(const struct extension_language_defn *extlang)
struct cmd_list_element ** auto_load_info_cmdlist_get(void)
static void show_auto_load_gdb_scripts(struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value)
static void info_auto_load_gdb_scripts(const char *pattern, int from_tty)
static void set_auto_load_safe_path(const char *args, int from_tty, struct cmd_list_element *c)
void auto_load_info_scripts(program_space *pspace, const char *pattern, int from_tty, const extension_language_defn *language)
void load_auto_scripts_for_objfile(struct objfile *objfile)
static ATTRIBUTE_PURE int filename_is_in_pattern(const char *filename, const char *pattern)
bool auto_load_local_gdbinit_loaded
static void print_scripts(const std::vector< loaded_script * > &scripts)
static void init_loaded_scripts_info(struct auto_load_pspace_info *pspace_info)
static bool maybe_add_script_file(struct auto_load_pspace_info *pspace_info, bool loaded, const char *name, const char *full_path, const struct extension_language_defn *language)
static int auto_load_objfile_script_1(struct objfile *objfile, const char *realname, const struct extension_language_defn *language)
static void print_script(struct loaded_script *script)
char auto_load_info_scripts_pattern_nl[]
static void show_auto_load_local_gdbinit(struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value)
static void set_auto_load_dir(const char *args, int from_tty, struct cmd_list_element *c)
static std::vector< gdb::unique_xmalloc_ptr< char > > auto_load_expand_dir_vars(const char *string)
static void set_auto_load_cmd(const char *args, int from_tty)
static void source_script_file(struct auto_load_pspace_info *pspace_info, struct objfile *objfile, const struct extension_language_defn *language, const char *section_name, unsigned int offset, const char *file)
bool auto_load_local_gdbinit
static std::string auto_load_safe_path
static const registry< program_space >::key< auto_load_pspace_info > auto_load_pspace_data
struct cmd_list_element ** auto_load_set_cmdlist_get(void)
static std::vector< gdb::unique_xmalloc_ptr< char > > auto_load_safe_path_vec
static void maybe_print_unsupported_script_warning(struct auto_load_pspace_info *, struct objfile *objfile, const struct extension_language_defn *language, const char *section_name, unsigned offset)
static void source_section_scripts(struct objfile *objfile, const char *section_name, const char *start, const char *end)
static void show_auto_load_safe_path(struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value)
static bool sort_scripts_by_name(loaded_script *a, loaded_script *b)
static void auto_load_gdb_datadir_changed(void)
static bool maybe_add_script_text(struct auto_load_pspace_info *pspace_info, bool loaded, const char *name, const struct extension_language_defn *language)
char * auto_load_local_gdbinit_pathname
static void info_auto_load_local_gdbinit(const char *args, int from_tty)
struct cmd_list_element ** auto_load_show_cmdlist_get(void)
gdb::observers::token auto_load_new_objfile_observer_token
static int collect_matching_scripts(void **slot, void *info)
static void maybe_print_script_not_found_warning(struct auto_load_pspace_info *, struct objfile *objfile, const struct extension_language_defn *language, const char *section_name, unsigned offset)
static bool auto_load_gdb_scripts
static void auto_load_safe_path_vec_update(void)
void auto_load_objfile_script(struct objfile *objfile, const struct extension_language_defn *language)
static void clear_section_scripts(program_space *pspace)
#define auto_load_debug_printf(fmt,...)
ui_file_style style() const
void field_string(const char *fldname, const char *string, const ui_file_style &style=ui_file_style())
void text(const char *string)
void table_header(int width, ui_align align, const std::string &col_name, const std::string &col_hdr)
void message(const char *format,...) ATTRIBUTE_PRINTF(2
struct cmd_list_element * showlist
struct cmd_list_element * infolist
struct cmd_list_element * cmdlist
struct cmd_list_element * setlist
struct cmd_list_element * showdebuglist
gdb::optional< open_script > find_and_open_script(const char *script_file, int search_path)
struct cmd_list_element * setdebuglist
struct cmd_list_element * add_cmd(const char *name, enum command_class theclass, const char *doc, struct cmd_list_element **list)
set_show_commands add_setshow_optional_filename_cmd(const char *name, enum command_class theclass, std::string *var, const char *set_doc, const char *show_doc, const char *help_doc, cmd_func_ftype *set_func, show_value_ftype *show_func, struct cmd_list_element **set_list, struct cmd_list_element **show_list)
void set_cmd_completer(struct cmd_list_element *cmd, completer_ftype *completer)
struct cmd_list_element * add_show_prefix_cmd(const char *name, enum command_class theclass, const char *doc, struct cmd_list_element **subcommands, int allow_unknown, struct cmd_list_element **list)
void cmd_func(struct cmd_list_element *cmd, const char *args, int from_tty)
struct cmd_list_element * add_prefix_cmd(const char *name, enum command_class theclass, cmd_simple_func_ftype *fun, const char *doc, struct cmd_list_element **subcommands, int allow_unknown, struct cmd_list_element **list)
set_show_commands add_setshow_boolean_cmd(const char *name, enum command_class theclass, bool *var, const char *set_doc, const char *show_doc, const char *help_doc, cmd_func_ftype *set_func, show_value_ftype *show_func, struct cmd_list_element **set_list, struct cmd_list_element **show_list)
void do_set_command(const char *arg, int from_tty, struct cmd_list_element *c)
cli_style_option file_name_style
void filename_completer(struct cmd_list_element *ignore, completion_tracker &tracker, const char *text, const char *word)
#define AUTO_LOAD_SAFE_PATH
std::string debug_file_directory
EXTERN_C char * re_comp(const char *)
objfile_script_sourcer_func * ext_lang_objfile_script_sourcer(const struct extension_language_defn *extlang)
const char * ext_lang_name(const struct extension_language_defn *extlang)
bool ext_lang_auto_load_enabled(const struct extension_language_defn *extlang)
const struct extension_language_defn extension_language_gdb
const struct extension_language_defn * get_ext_lang_defn(enum extension_language lang)
void auto_load_ext_lang_scripts_for_objfile(struct objfile *objfile)
const char * ext_lang_auto_load_suffix(const struct extension_language_defn *extlang)
objfile_script_executor_func * ext_lang_objfile_script_executor(const struct extension_language_defn *extlang)
void objfile_script_sourcer_func(const struct extension_language_defn *, struct objfile *, FILE *stream, const char *filename)
void objfile_script_executor_func(const struct extension_language_defn *, struct objfile *, const char *name, const char *script)
int is_target_filename(const char *name)
observable< struct objfile * > new_objfile
observable gdb_datadir_changed
observable< program_space * > all_objfiles_removed
const char * objfile_name(const struct objfile *objfile)
struct program_space * current_program_space
htab_up loaded_script_files
htab_up loaded_script_texts
bool script_not_found_warning_printed
bool unsupported_script_warning_printed
gdb::optional< setting > var
__extension__ enum cmd_types type
struct cmd_list_element * next
const struct extension_language_defn * language
std::vector< loaded_script * > * scripts_p
collect_matching_scripts_data(std::vector< loaded_script * > *scripts_p_, const extension_language_defn *language_)
const struct extension_language_defn * language
const char * original_name
struct objfile * separate_debug_objfile_backlink
struct program_space * pspace
static styled_string_s * styled_string(const ui_file_style &style, const char *str, styled_string_s &&tmp={})
int gdb_filename_fnmatch(const char *pattern, const char *string, int flags)
void gdb_printf(struct ui_file *stream, const char *format,...)
void substitute_path_component(char **stringp, const char *from, const char *to)