From patchwork Fri Aug 21 21:24:14 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kratochvil X-Patchwork-Id: 8379 Received: (qmail 123200 invoked by alias); 21 Aug 2015 21:24:21 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 123095 invoked by uid 89); 21 Aug 2015 21:24:21 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.2 required=5.0 tests=AWL, BAYES_50, KAM_LAZY_DOMAIN_SECURITY, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=no version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Fri, 21 Aug 2015 21:24:18 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id 95A208CF7E for ; Fri, 21 Aug 2015 21:24:17 +0000 (UTC) Received: from host1.jankratochvil.net (ovpn-116-22.ams2.redhat.com [10.36.116.22]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t7LLOFBb031023 for ; Fri, 21 Aug 2015 17:24:15 -0400 Subject: [PATCH v12 31/32] Make only user-specified executable and symbol filenames sticky From: Jan Kratochvil To: gdb-patches@sourceware.org Date: Fri, 21 Aug 2015 23:24:14 +0200 Message-ID: <20150821212414.6673.40425.stgit@host1.jankratochvil.net> In-Reply-To: <20150821212006.6673.35100.stgit@host1.jankratochvil.net> References: <20150821212006.6673.35100.stgit@host1.jankratochvil.net> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-IsSubscribed: yes Message-ID: <559A7C37.6020501@redhat.com> On 07/03/2015 04:44 PM, Pedro Alves wrote: > (I still suspect that if we reverse the sense of the flag, then > its management ends up being more centralized, as then the > place that sets it is also the place that needs to check it, > instead of doing that in multiple places. But, see below.) It didn't seem fair to impose a subjective preference, so I tried this in order to understand it myself, and I now agree that is really doesn't make much difference, as then we'd have to mark auto-discovered in a few more places that I wasn't originally seeing. There's at least the execd handling in infrun.c, and also spu_symbol_file_add_from_memory. As I was playing with this already, I poked at the other review points I made, and came up with the variant of the patch below. > This function is called while the passed in PID is not the > current inferior. E.g., the remote_add_inferior path. > > Therefore seems to me that these symbol_file_add_main / exec_file_attach > calls can change the symbols of the wrong inferior. ... > I also notice that reread_symbols has an exec_file_attach > call which seems to me results in losing the is_user_supplied > flag if the executable's timestamp changed, at least here: > >> + /* Attempt to open the file that was executed to create this >> + inferior. If the user has explicitly specified executable >> + and/or symbol files then warn the user if their choices do >> + not match. Otherwise, set exec_file and symfile_objfile to >> + the new file. */ >> + exec_file_locate_attach (ptid_get_pid (inferior_ptid), from_tty); >> + >> + if (exec_file_is_user_supplied) >> { >> reopen_exec_file (); >> reread_symbols (); > > > I also notice that the clone-inferior command ends up with > an exec_file_attach call in clone_program_space. That one > should probably be setting the is_user_supplied flag too, > I'd think. Or at least, copying it from the original. > > At this point, I'm wondering about adding a parameter to > exec_file_attach to force considering (now and in future) > the right value to put in the flag in each case. I tried this too (see patch below). As this requires touching the user-supplied paths anyway, it didn't really matter to tag files user-supplied or auto-discovered, so I reverted back to user-supplied. For symbols, we already have the add_flags, so I added SYMFILE_USER_SUPPLIED instead of a new boolean. > >> @@ -2490,11 +2490,14 @@ attach_command_post_wait (char *args, int from_tty, int async_exec) >> inferior = current_inferior (); >> inferior->control.stop_soon = NO_STOP_QUIETLY; >> >> - /* If no exec file is yet known, try to determine it from the >> - process itself. */ >> - if (get_exec_file (0) == NULL) >> - exec_file_locate_attach (ptid_get_pid (inferior_ptid), from_tty); >> - else >> + /* Attempt to open the file that was executed to create this >> + inferior. If the user has explicitly specified executable >> + and/or symbol files then warn the user if their choices do >> + not match. Otherwise, set exec_file and symfile_objfile to >> + the new file. */ >> + exec_file_locate_attach (ptid_get_pid (inferior_ptid), from_tty); >> + >> + if (exec_file_is_user_supplied) >> { >> reopen_exec_file (); >> reread_symbols (); > > It seems to me that we should be able to move these reopen/reread > calls inside exec_file_locate_attach. I did this too. What do you think of the version below? I also tweaked the warnings a bit, to explicitly say "mismatch". This would still need docs/NEWS changes, and a test would be good too. ---------- - pass user-supplied / auto-discovered as arguments to exec_file_attach and symbol_file_add_main - Change exec_file_locate_attach parameter from pid to inferior pointer. - Flip current program space temporarily to make sure we add/reload symbols to/of the right inferior/program space. - Move reopen_exec_file and reread_symbols calls inside exec_file_locate_attach. - Warning message tweaks. - Rename exec_file_locate_attach -> exec_file_and_symbols_resync --- 0 files changed diff --git a/gdb/corefile.c b/gdb/corefile.c index 5246f71..5d861de 100644 --- a/gdb/corefile.c +++ b/gdb/corefile.c @@ -146,7 +146,7 @@ reopen_exec_file (void) res = stat (filename, &st); if (exec_bfd_mtime && exec_bfd_mtime != st.st_mtime) - exec_file_attach (filename, 0); + exec_file_attach (exec_file_was_user_supplied, filename, 0); else /* If we accessed the file since last opening it, close it now; this stops GDB from holding the executable open after it diff --git a/gdb/exec.c b/gdb/exec.c index 0593478..056516b 100644 --- a/gdb/exec.c +++ b/gdb/exec.c @@ -78,7 +78,7 @@ static void exec_open (const char *args, int from_tty) { target_preopen (from_tty); - exec_file_attach (args, from_tty); + exec_file_attach (1, args, from_tty); } /* Close and clear exec_bfd. If we end up with no target sections to @@ -102,6 +102,7 @@ exec_close (void) xfree (exec_filename); exec_filename = NULL; + exec_file_was_user_supplied = 0; } } @@ -138,42 +139,70 @@ exec_file_clear (int from_tty) /* See gdbcore.h. */ void -exec_file_locate_attach (int pid, int from_tty) +exec_file_and_symbols_resync (struct inferior *inf, int from_tty) { char *exec_file, *full_exec_path = NULL; + struct cleanup *old_chain = save_current_program_space (); - /* Do nothing if we already have an executable filename. */ - exec_file = (char *) get_exec_file (0); - if (exec_file != NULL) - return; + /* Switch over temporarily, while reading executable and + symbols. */ + set_current_program_space (inf->pspace); /* Try to determine a filename from the process itself. */ - exec_file = target_pid_to_exec_file (pid); - if (exec_file == NULL) - return; + exec_file = target_pid_to_exec_file (inf->pid); + if (exec_file != NULL) + { + /* If gdb_sysroot is not empty and the discovered filename + is absolute then prefix the filename with gdb_sysroot. */ + if (*gdb_sysroot != '\0' && IS_ABSOLUTE_PATH (exec_file)) + full_exec_path = exec_file_find (exec_file, 0 /* build_idsz */, + NULL /* build_id */, NULL); + + if (full_exec_path == NULL) + { + /* It's possible we don't have a full path, but rather just a + filename. Some targets, such as HP-UX, don't provide the + full path, sigh. + + Attempt to qualify the filename against the source path. + (If that fails, we'll just fall back on the original + filename. Not much more we can do...) */ + if (!source_full_path_of (exec_file, 0 /* build_idsz */, + NULL /* build_id */, &full_exec_path)) + full_exec_path = xstrdup (exec_file); + } + } - /* If gdb_sysroot is not empty and the discovered filename - is absolute then prefix the filename with gdb_sysroot. */ - if (*gdb_sysroot != '\0' && IS_ABSOLUTE_PATH (exec_file)) - full_exec_path = exec_file_find (exec_file, 0 /* build_idsz */, - NULL /* build_id */, NULL); + if (exec_filename != NULL && exec_file_was_user_supplied) + { + if (full_exec_path != NULL && strcmp (full_exec_path, exec_filename) != 0) + warning (_("Detected exec-file mismatch on %s. Running %s; Loaded %s"), + target_pid_to_str (pid_to_ptid (inf->pid)), + full_exec_path, exec_filename); + reopen_exec_file (); + } + else if (full_exec_path != NULL) + exec_file_attach (0, full_exec_path, from_tty); - if (full_exec_path == NULL) + if (symfile_objfile != NULL && symfile_objfile_was_user_supplied) { - /* It's possible we don't have a full path, but rather just a - filename. Some targets, such as HP-UX, don't provide the - full path, sigh. - - Attempt to qualify the filename against the source path. - (If that fails, we'll just fall back on the original - filename. Not much more we can do...) */ - if (!source_full_path_of (exec_file, 0 /* build_idsz */, - NULL /* build_id */, &full_exec_path)) - full_exec_path = xstrdup (exec_file); + const char *symbol_filename = objfile_filename (symfile_objfile); + + if (full_exec_path != NULL + && strcmp (full_exec_path, symbol_filename) != 0) + warning (_("Detected symbol-file mismatch on %s. " + "Running %s; Loaded %s"), + target_pid_to_str (pid_to_ptid (inf->pid)), + full_exec_path, symbol_filename); } + else if (full_exec_path != NULL) + symbol_file_add_main (0, full_exec_path, from_tty); - exec_file_attach (full_exec_path, from_tty); - symbol_file_add_main (full_exec_path, from_tty); + /* Re-read symbol files that were modified since we last loaded + them. */ + reread_symbols (); + + do_cleanups (old_chain); } /* Set FILENAME as the new exec file. @@ -194,7 +223,7 @@ exec_file_locate_attach (int pid, int from_tty) we're supplying the exec pathname late for good reason.) */ void -exec_file_attach (const char *filename, int from_tty) +exec_file_attach (int user_supplied, const char *filename, int from_tty) { struct cleanup *cleanups; @@ -283,6 +312,8 @@ exec_file_attach (const char *filename, int from_tty) do_cleanups (cleanups); + exec_file_was_user_supplied = user_supplied; + bfd_cache_close_all (); observer_notify_executable_changed (); } @@ -324,12 +355,12 @@ exec_file_command (char *args, int from_tty) filename = tilde_expand (*argv); make_cleanup (xfree, filename); - exec_file_attach (filename, from_tty); + exec_file_attach (1, filename, from_tty); do_cleanups (cleanups); } else - exec_file_attach (NULL, from_tty); + exec_file_attach (1, NULL, from_tty); } /* Set both the exec file and the symbol file, in one command. diff --git a/gdb/exec.h b/gdb/exec.h index c7f3b56..aef2926 100644 --- a/gdb/exec.h +++ b/gdb/exec.h @@ -32,6 +32,8 @@ struct objfile; #define exec_bfd current_program_space->ebfd #define exec_bfd_mtime current_program_space->ebfd_mtime #define exec_filename current_program_space->pspace_exec_filename +#define exec_file_was_user_supplied \ + current_program_space->pspace_exec_file_was_user_supplied /* Builds a section table, given args BFD, SECTABLE_PTR, SECEND_PTR. Returns 0 if OK, 1 on error. */ diff --git a/gdb/gdbcore.h b/gdb/gdbcore.h index 0c08b37..f34ee77 100644 --- a/gdb/gdbcore.h +++ b/gdb/gdbcore.h @@ -146,14 +146,23 @@ extern int write_files; extern void core_file_command (char *filename, int from_tty); -extern void exec_file_attach (const char *filename, int from_tty); - -/* If the filename of the main executable is unknown, attempt to - determine it. If a filename is determined, proceed as though - it was just specified with the "file" command. Do nothing if - the filename of the main executable is already known. */ - -extern void exec_file_locate_attach (int pid, int from_tty); +extern void exec_file_attach (int user_supplied, const char *filename, + int from_tty); + +/* Resync executable and symbols. Fetch the filename of the main + executable based on what the target is running. If a filename can + be determined, and the current exec file loaded was not previously + user supplied, then load the discovered filename as exec file. If + the executable loaded had been user supplied (with e.g., the "file" + command), issue a warning if there's a mismatch, and reload the + previously user-specified executable (in case the program was + recompiled since the last time we loaded it). Likewise, if the + currenly load main symbol file was not user supplied, load the + discovered filename as symbol file; otherwise, if there's a + mismatch, warn. End by reading all symbol files that have been + modified since the last time we loaded them. */ + +extern void exec_file_and_symbols_resync (struct inferior *inf, int from_tty); extern void exec_file_clear (int from_tty); diff --git a/gdb/infcmd.c b/gdb/infcmd.c index 82399a4..b6d9474 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -2492,15 +2492,12 @@ attach_command_post_wait (char *args, int from_tty, int async_exec) inferior = current_inferior (); inferior->control.stop_soon = NO_STOP_QUIETLY; - /* If no exec file is yet known, try to determine it from the - process itself. */ - if (get_exec_file (0) == NULL) - exec_file_locate_attach (ptid_get_pid (inferior_ptid), from_tty); - else - { - reopen_exec_file (); - reread_symbols (); - } + /* Attempt to open the file that was executed to create this + inferior. If the user has explicitly specified executable + and/or symbol files then warn the user if their choices do + not match. Otherwise, set exec_file and symfile_objfile to + the new file. */ + exec_file_and_symbols_resync (inferior, from_tty); /* Take any necessary post-attaching actions for this platform. */ target_post_attach (ptid_get_pid (inferior_ptid)); diff --git a/gdb/inferior.c b/gdb/inferior.c index 2e44f17..ec667ce 100644 --- a/gdb/inferior.c +++ b/gdb/inferior.c @@ -869,13 +869,13 @@ add_inferior_command (char *args, int from_tty) if (exec != NULL) { /* Switch over temporarily, while reading executable and - symbols.q. */ + symbols. */ set_current_program_space (inf->pspace); set_current_inferior (inf); switch_to_thread (null_ptid); - exec_file_attach (exec, from_tty); - symbol_file_add_main (exec, from_tty); + exec_file_attach (1, exec, from_tty); + symbol_file_add_main (SYMFILE_USER_SPECIFIED, exec, from_tty); } } diff --git a/gdb/infrun.c b/gdb/infrun.c index c1beafd..ff00e18 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -1212,7 +1212,7 @@ follow_exec (ptid_t ptid, char *execd_pathname) gdb_assert (current_program_space == inf->pspace); /* That a.out is now the one to use. */ - exec_file_attach (execd_pathname, 0); + exec_file_attach (0, execd_pathname, 0); /* SYMFILE_DEFER_BP_RESET is used as the proper displacement for PIE (Position Independent Executable) main symbol file will get applied by diff --git a/gdb/main.c b/gdb/main.c index a17ee34..3cc3d47 100644 --- a/gdb/main.c +++ b/gdb/main.c @@ -405,6 +405,29 @@ catch_command_errors_const (catch_command_errors_const_ftype *command, return 1; } +/* Like catch_command_errors, but specifically for symbol/exec load + routines. */ + +typedef void (catch_exec_or_symbol_errors_ftype) (int, const char *, int); + +static int +catch_exec_or_symbol_errors (catch_exec_or_symbol_errors_ftype *func, + int arg, const char *filename, int from_tty) +{ + TRY + { + func (arg, filename, from_tty); + } + CATCH (e, RETURN_MASK_ALL) + { + exception_print (gdb_stderr, e); + return 0; + } + END_CATCH + + return 1; +} + /* Type of this option. */ enum cmdarg_kind { @@ -1051,20 +1074,23 @@ captured_main (void *data) { /* The exec file and the symbol-file are the same. If we can't open it, better only print one error message. - catch_command_errors returns non-zero on success! */ - if (catch_command_errors_const (exec_file_attach, execarg, - !batch_flag)) - catch_command_errors_const (symbol_file_add_main, symarg, - !batch_flag); + catch_exec_or_symbol_errors returns non-zero on success. */ + if (catch_exec_or_symbol_errors (exec_file_attach, + 1, execarg, !batch_flag)) + catch_exec_or_symbol_errors (symbol_file_add_main, + SYMFILE_USER_SPECIFIED, + symarg, !batch_flag); } else { if (execarg != NULL) - catch_command_errors_const (exec_file_attach, execarg, - !batch_flag); + catch_exec_or_symbol_errors (exec_file_attach, 1, + execarg, !batch_flag); + if (symarg != NULL) - catch_command_errors_const (symbol_file_add_main, symarg, - !batch_flag); + catch_exec_or_symbol_errors (symbol_file_add_main, + SYMFILE_USER_SPECIFIED, + symarg, !batch_flag); } if (corearg && pidarg) diff --git a/gdb/progspace.c b/gdb/progspace.c index ea2f8ec..1b3f689 100644 --- a/gdb/progspace.c +++ b/gdb/progspace.c @@ -182,10 +182,11 @@ clone_program_space (struct program_space *dest, struct program_space *src) set_current_program_space (dest); if (src->pspace_exec_filename != NULL) - exec_file_attach (src->pspace_exec_filename, 0); + exec_file_attach (1, src->pspace_exec_filename, 0); if (src->symfile_object_file != NULL) - symbol_file_add_main (objfile_name (src->symfile_object_file), 0); + symbol_file_add_main (SYMFILE_USER_SPECIFIED, + objfile_name (src->symfile_object_file), 0); do_cleanups (old_chain); return dest; diff --git a/gdb/progspace.h b/gdb/progspace.h index 48f206e..01fd9a3 100644 --- a/gdb/progspace.h +++ b/gdb/progspace.h @@ -154,6 +154,12 @@ struct program_space It needs to be freed by xfree. It is not NULL iff EBFD is not NULL. */ char *pspace_exec_filename; + /* Nonzero if pspace_exec_filename was supplied by the user, + either at startup (on the command-line) or via the "file" or + "add-inferior -exec" commands. Zero if pspace_exec_filename is + unset or was discovered by GDB. */ + int pspace_exec_file_was_user_supplied; + /* The address space attached to this program space. More than one program space may be bound to the same address space. In the traditional unix-like debugging scenario, this will usually @@ -183,6 +189,12 @@ struct program_space (e.g. the argument to the "symbol-file" or "file" command). */ struct objfile *symfile_object_file; + /* Nonzero if symfile_object_file is set and was discovered by + GDB. Zero if symfile_object_file is not set or was supplied + by the user, either at startup (on the command-line) or via the + "file" or "add-inferior -exec" commands. */ + int symfile_object_file_was_user_supplied; + /* All known objfiles are kept in a linked list. This points to the head of this list. */ struct objfile *objfiles; @@ -215,6 +227,11 @@ struct program_space #define symfile_objfile current_program_space->symfile_object_file +/* See program_space->symfile_object_file_was_user_supplied. */ + +#define symfile_objfile_was_user_supplied \ + current_program_space->symfile_object_file_was_user_supplied + /* All known objfiles are kept in a linked list. This points to the root of this list. */ #define object_files current_program_space->objfiles diff --git a/gdb/remote.c b/gdb/remote.c index 12294bc..e2befcf 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -1673,10 +1673,13 @@ remote_add_inferior (int fake_pid_p, int pid, int attached, inf->attach_flag = attached; inf->fake_pid_p = fake_pid_p; - /* If no main executable is currently open then attempt to - open the file that was executed to create this inferior. */ - if (try_open_exec && get_exec_file (0) == NULL) - exec_file_locate_attach (pid, 1); + /* Attempt to open the file that was executed to create this + inferior. If the user has explicitly specified executable + and/or symbol files then warn the user if their choices do + not match. Otherwise, set exec_file and symfile_objfile to + the new file. */ + if (try_open_exec) + exec_file_and_symbols_resync (inf, 1); return inf; } diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c index c725683..858b942 100644 --- a/gdb/solib-svr4.c +++ b/gdb/solib-svr4.c @@ -1071,7 +1071,7 @@ open_symbol_file_object (void *from_ttyp) } /* Have a pathname: read the symbol file. */ - symbol_file_add_main (filename, from_tty); + symbol_file_add_main (0, filename, from_tty); do_cleanups (cleanups); return 1; diff --git a/gdb/symfile.c b/gdb/symfile.c index 1e34c5f..38fd3f1 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -85,7 +85,8 @@ int readnow_symbol_files; /* Read full symbols immediately. */ static void load_command (char *, int); -static void symbol_file_add_main_1 (const char *args, int from_tty, int flags); +static void symbol_file_add_main_1 (int add_flags, const char *args, + int from_tty, int flags); static void add_symbol_file_command (char *, int); @@ -1306,16 +1307,17 @@ symbol_file_add (const char *name, int add_flags, command itself. */ void -symbol_file_add_main (const char *args, int from_tty) +symbol_file_add_main (int add_flags, const char *args, int from_tty) { - symbol_file_add_main_1 (args, from_tty, 0); + symbol_file_add_main_1 (add_flags, args, from_tty, 0); } static void -symbol_file_add_main_1 (const char *args, int from_tty, int flags) +symbol_file_add_main_1 (int add_flags, const char *args, int from_tty, + int flags) { - const int add_flags = (current_inferior ()->symfile_flags - | SYMFILE_MAINLINE | (from_tty ? SYMFILE_VERBOSE : 0)); + add_flags |= (current_inferior ()->symfile_flags + | SYMFILE_MAINLINE | (from_tty ? SYMFILE_VERBOSE : 0)); symbol_file_add (args, add_flags, NULL, flags); @@ -1325,6 +1327,9 @@ symbol_file_add_main_1 (const char *args, int from_tty, int flags) if ((flags & SYMFILE_NO_READ) == 0) set_initial_language (); + + symfile_objfile_was_user_supplied + = (add_flags & SYMFILE_USER_SPECIFIED) != 0; } void @@ -1347,6 +1352,8 @@ symbol_file_clear (int from_tty) gdb_assert (symfile_objfile == NULL); if (from_tty) printf_unfiltered (_("No symbol file now.\n")); + + symfile_objfile_was_user_supplied = 0; } static int @@ -1663,7 +1670,8 @@ symbol_file_command (char *args, int from_tty) error (_("unknown option `%s'"), *argv); else { - symbol_file_add_main_1 (*argv, from_tty, flags); + symbol_file_add_main_1 (SYMFILE_USER_SPECIFIED, + *argv, from_tty, flags); name = *argv; } @@ -2527,7 +2535,8 @@ reread_symbols (void) { /* Reload EXEC_BFD without asking anything. */ - exec_file_attach (bfd_get_filename (objfile->obfd), 0); + exec_file_attach (exec_file_was_user_supplied, + bfd_get_filename (objfile->obfd), 0); } /* Keep the calls order approx. the same as in free_objfile. */ diff --git a/gdb/symfile.h b/gdb/symfile.h index 9ef3f0b..9ef3d19 100644 --- a/gdb/symfile.h +++ b/gdb/symfile.h @@ -457,7 +457,11 @@ enum symfile_add_flags /* Do not immediately read symbols for this file. By default, symbols are read when the objfile is created. */ - SYMFILE_NO_READ = 1 << 4 + SYMFILE_NO_READ = 1 << 4, + + /* Whether the symbol file was user-supplied, as opposed to + auto-discovered by GDB. */ + SYMFILE_USER_SPECIFIED = 1 << 5, }; extern struct objfile *symbol_file_add (const char *, int, @@ -556,7 +560,8 @@ extern CORE_ADDR overlay_unmapped_address (CORE_ADDR, struct obj_section *); extern CORE_ADDR symbol_overlayed_address (CORE_ADDR, struct obj_section *); /* Load symbols from a file. */ -extern void symbol_file_add_main (const char *args, int from_tty); +extern void symbol_file_add_main (int add_flags, + const char *args, int from_tty); /* Clear GDB symbol tables. */ extern void symbol_file_clear (int from_tty);