X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fexec.c;h=68bca1be1773f0fc652aec0556b1fdb0668c827e;hb=c3b149eb7697b376df1b3a47d0102afda389ee6d;hp=44b212a4d4443b8282528dd838867501c849b84c;hpb=66b4deae03e7a503f8c543aa198a8c010863135a;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/exec.c b/gdb/exec.c index 44b212a4d4..68bca1be17 100644 --- a/gdb/exec.c +++ b/gdb/exec.c @@ -1,6 +1,6 @@ /* Work with executable files, for GDB. - Copyright (C) 1988-2018 Free Software Foundation, Inc. + Copyright (C) 1988-2020 Free Software Foundation, Inc. This file is part of GDB. @@ -33,19 +33,21 @@ #include "arch-utils.h" #include "gdbthread.h" #include "progspace.h" +#include "progspace-and-thread.h" #include "gdb_bfd.h" #include "gcore.h" #include "source.h" #include -#include "readline/readline.h" +#include "readline/tilde.h" #include "gdbcore.h" #include #include #include "solist.h" #include -#include "common/pathstuff.h" +#include "gdbsupport/pathstuff.h" +#include "cli/cli-style.h" void (*deprecated_file_changed_hook) (const char *); @@ -82,9 +84,53 @@ struct exec_target final : public target_ops static exec_target exec_ops; +/* How to handle a mismatch between the current exec file and the exec + file determined from target. */ + +static const char *const exec_file_mismatch_names[] + = {"ask", "warn", "off", NULL }; +enum exec_file_mismatch_mode + { + exec_file_mismatch_ask, exec_file_mismatch_warn, exec_file_mismatch_off + }; +static const char *exec_file_mismatch = exec_file_mismatch_names[0]; +static enum exec_file_mismatch_mode exec_file_mismatch_mode + = exec_file_mismatch_ask; + +/* Show command. */ +static void +show_exec_file_mismatch_command (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + fprintf_filtered (gdb_stdout, + _("exec-file-mismatch handling is currently \"%s\".\n"), + exec_file_mismatch_names[exec_file_mismatch_mode]); +} + +/* Set command. Change the setting for range checking. */ +static void +set_exec_file_mismatch_command (const char *ignore, + int from_tty, struct cmd_list_element *c) +{ + for (enum exec_file_mismatch_mode mode = exec_file_mismatch_ask; + ; + mode = static_cast(1 + (int) mode)) + { + if (strcmp (exec_file_mismatch, exec_file_mismatch_names[mode]) == 0) + { + exec_file_mismatch_mode = mode; + return; + } + if (mode == exec_file_mismatch_off) + internal_error (__FILE__, __LINE__, + _("Unrecognized exec-file-mismatch setting: \"%s\""), + exec_file_mismatch); + } +} + /* Whether to open exec and core files read-only or read-write. */ -int write_files = 0; +bool write_files = false; static void show_write_files (struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value) @@ -148,7 +194,7 @@ void try_open_exec_file (const char *exec_file_host, struct inferior *inf, symfile_add_flags add_flags) { - struct gdb_exception prev_err = exception_none; + struct gdb_exception prev_err; /* exec_file_attach and symbol_file_add_main may throw an error if the file cannot be opened either locally or remotely. @@ -161,41 +207,86 @@ try_open_exec_file (const char *exec_file_host, struct inferior *inf, Even without a symbol file, the remote-based debugging session should continue normally instead of ending abruptly. Hence we catch thrown errors/exceptions in the following code. */ - std::string saved_message; - TRY + try { /* We must do this step even if exec_file_host is NULL, so that exec_file_attach will clear state. */ exec_file_attach (exec_file_host, add_flags & SYMFILE_VERBOSE); } - CATCH (err, RETURN_MASK_ERROR) + catch (gdb_exception_error &err) { if (err.message != NULL) - warning ("%s", err.message); + warning ("%s", err.what ()); - prev_err = err; - - /* Save message so it doesn't get trashed by the catch below. */ - if (err.message != NULL) - { - saved_message = err.message; - prev_err.message = saved_message.c_str (); - } + prev_err = std::move (err); } - END_CATCH if (exec_file_host != NULL) { - TRY + try { symbol_file_add_main (exec_file_host, add_flags); } - CATCH (err, RETURN_MASK_ERROR) + catch (const gdb_exception_error &err) { if (!exception_print_same (prev_err, err)) - warning ("%s", err.message); + warning ("%s", err.what ()); + } + } +} + +/* See gdbcore.h. */ + +void +validate_exec_file (int from_tty) +{ + /* If user asked to ignore the mismatch, do nothing. */ + if (exec_file_mismatch_mode == exec_file_mismatch_off) + return; + + const char *current_exec_file = get_exec_file (0); + struct inferior *inf = current_inferior (); + /* Try to determine a filename from the process itself. */ + const char *pid_exec_file = target_pid_to_exec_file (inf->pid); + + /* If wee cannot validate the exec file, return. */ + if (current_exec_file == NULL || pid_exec_file == NULL) + return; + + std::string exec_file_target (pid_exec_file); + + /* In case the exec file is not local, exec_file_target has to point at + the target file system. */ + if (is_target_filename (current_exec_file) && !target_filesystem_is_local ()) + exec_file_target = TARGET_SYSROOT_PREFIX + exec_file_target; + + if (exec_file_target != current_exec_file) + { + warning + (_("Mismatch between current exec-file %ps\n" + "and automatically determined exec-file %ps\n" + "exec-file-mismatch handling is currently \"%s\""), + styled_string (file_name_style.style (), current_exec_file), + styled_string (file_name_style.style (), exec_file_target.c_str ()), + exec_file_mismatch_names[exec_file_mismatch_mode]); + if (exec_file_mismatch_mode == exec_file_mismatch_ask) + { + symfile_add_flags add_flags = SYMFILE_MAINLINE; + if (from_tty) + add_flags |= SYMFILE_VERBOSE; + try + { + symbol_file_add_main (exec_file_target.c_str (), add_flags); + exec_file_attach (exec_file_target.c_str (), from_tty); + } + catch (gdb_exception_error &err) + { + warning (_("loading %ps %s"), + styled_string (file_name_style.style (), + exec_file_target.c_str ()), + err.message != NULL ? err.what () : "error"); + } } - END_CATCH } } @@ -341,8 +432,9 @@ exec_file_attach (const char *filename, int from_tty) if (!exec_bfd) { - error (_("\"%s\": could not open as an executable file: %s."), - scratch_pathname, bfd_errmsg (bfd_get_error ())); + error (_("\"%ps\": could not open as an executable file: %s."), + styled_string (file_name_style.style (), scratch_pathname), + bfd_errmsg (bfd_get_error ())); } /* gdb_realpath_keepfile resolves symlinks on the local @@ -358,8 +450,8 @@ exec_file_attach (const char *filename, int from_tty) /* Make sure to close exec_bfd, or else "run" might try to use it. */ exec_close (); - error (_("\"%s\": not in executable format: %s"), - scratch_pathname, + error (_("\"%ps\": not in executable format: %s"), + styled_string (file_name_style.style (), scratch_pathname), gdb_bfd_errmsg (bfd_get_error (), matching).c_str ()); } @@ -368,8 +460,9 @@ exec_file_attach (const char *filename, int from_tty) /* Make sure to close exec_bfd, or else "run" might try to use it. */ exec_close (); - error (_("\"%s\": can't find the file sections: %s"), - scratch_pathname, bfd_errmsg (bfd_get_error ())); + error (_("\"%ps\": can't find the file sections: %s"), + styled_string (file_name_style.style (), scratch_pathname), + bfd_errmsg (bfd_get_error ())); } exec_bfd_mtime = bfd_get_mtime (exec_bfd); @@ -464,14 +557,14 @@ add_to_section_table (bfd *abfd, struct bfd_section *asect, encountered on sparc-solaris 2.10 a shared library with an empty .bss section to which a symbol named "_end" was attached. The address of this symbol still needs to be relocated. */ - aflag = bfd_get_section_flags (abfd, asect); + aflag = bfd_section_flags (asect); if (!(aflag & SEC_ALLOC)) return; (*table_pp)->owner = NULL; (*table_pp)->the_bfd_section = asect; - (*table_pp)->addr = bfd_section_vma (abfd, asect); - (*table_pp)->endaddr = (*table_pp)->addr + bfd_section_size (abfd, asect); + (*table_pp)->addr = bfd_section_vma (asect); + (*table_pp)->endaddr = (*table_pp)->addr + bfd_section_size (asect); (*table_pp)++; } @@ -557,10 +650,23 @@ add_target_sections (void *owner, table->sections[space + i].owner = owner; } + scoped_restore_current_pspace_and_thread restore_pspace_thread; + program_space *curr_pspace = current_program_space; + /* If these are the first file sections we can provide memory - from, push the file_stratum target. */ - if (!target_is_pushed (&exec_ops)) - push_target (&exec_ops); + from, push the file_stratum target. Must do this in all + inferiors sharing the program space. */ + for (inferior *inf : all_inferiors ()) + { + if (inf->pspace != curr_pspace) + continue; + + if (inf->target_is_pushed (&exec_ops)) + continue; + + switch_to_inferior_no_thread (inf); + push_target (&exec_ops); + } } } @@ -581,7 +687,7 @@ add_target_sections_of_objfile (struct objfile *objfile) /* Compute the number of sections to add. */ ALL_OBJFILE_OSECTIONS (objfile, osect) { - if (bfd_get_section_size (osect->the_bfd_section) == 0) + if (bfd_section_size (osect->the_bfd_section) == 0) continue; count++; } @@ -595,7 +701,7 @@ add_target_sections_of_objfile (struct objfile *objfile) ALL_OBJFILE_OSECTIONS (objfile, osect) { - if (bfd_get_section_size (osect->the_bfd_section) == 0) + if (bfd_section_size (osect->the_bfd_section) == 0) continue; gdb_assert (ts < table->sections + space + count); @@ -638,21 +744,39 @@ remove_target_sections (void *owner) old_count = resize_section_table (table, dest - src); /* If we don't have any more sections to read memory from, - remove the file_stratum target from the stack. */ + remove the file_stratum target from the stack of each + inferior sharing the program space. */ if (old_count + (dest - src) == 0) { - struct program_space *pspace; + scoped_restore_current_pspace_and_thread restore_pspace_thread; + program_space *curr_pspace = current_program_space; - ALL_PSPACES (pspace) - if (pspace->target_sections.sections - != pspace->target_sections.sections_end) - return; + for (inferior *inf : all_inferiors ()) + { + if (inf->pspace != curr_pspace) + continue; + + if (inf->pspace->target_sections.sections + != inf->pspace->target_sections.sections_end) + continue; - unpush_target (&exec_ops); + switch_to_inferior_no_thread (inf); + unpush_target (&exec_ops); + } } } } +/* See exec.h. */ + +void +exec_on_vfork () +{ + if (current_program_space->target_sections.sections + != current_program_space->target_sections.sections_end) + push_target (&exec_ops); +} + enum target_xfer_status @@ -675,7 +799,7 @@ exec_read_partial_read_only (gdb_byte *readbuf, ULONGEST offset, continue; vma = s->vma; - size = bfd_get_section_size (s); + size = bfd_section_size (s); if (vma <= offset && offset < (vma + size)) { ULONGEST amt; @@ -715,9 +839,7 @@ section_table_available_memory (CORE_ADDR memaddr, ULONGEST len, for (target_section *p = sections; p < sections_end; p++) { - if ((bfd_get_section_flags (p->the_bfd_section->owner, - p->the_bfd_section) - & SEC_READONLY) == 0) + if ((bfd_section_flags (p->the_bfd_section) & SEC_READONLY) == 0) continue; /* Copy the meta-data, adjusted. */ @@ -891,7 +1013,9 @@ print_section_info (struct target_section_table *t, bfd *abfd) /* FIXME: 16 is not wide enough when gdbarch_addr_bit > 64. */ int wid = gdbarch_addr_bit (gdbarch) <= 32 ? 8 : 16; - printf_filtered ("\t`%s', ", bfd_get_filename (abfd)); + printf_filtered ("\t`%ps', ", + styled_string (file_name_style.style (), + bfd_get_filename (abfd))); wrap_here (" "); printf_filtered (_("file type %s.\n"), bfd_get_target (abfd)); if (abfd == exec_bfd) @@ -904,23 +1028,23 @@ print_section_info (struct target_section_table *t, bfd *abfd) for (p = t->sections; p < t->sections_end; p++) { struct bfd_section *psect = p->the_bfd_section; - bfd *pbfd = psect->owner; - if ((bfd_get_section_flags (pbfd, psect) & (SEC_ALLOC | SEC_LOAD)) + if ((bfd_section_flags (psect) & (SEC_ALLOC | SEC_LOAD)) != (SEC_ALLOC | SEC_LOAD)) continue; - if (bfd_get_section_vma (pbfd, psect) <= abfd->start_address - && abfd->start_address < (bfd_get_section_vma (pbfd, psect) - + bfd_get_section_size (psect))) + if (bfd_section_vma (psect) <= abfd->start_address + && abfd->start_address < (bfd_section_vma (psect) + + bfd_section_size (psect))) { - displacement = p->addr - bfd_get_section_vma (pbfd, psect); + displacement = p->addr - bfd_section_vma (psect); break; } } if (p == t->sections_end) - warning (_("Cannot find section for the entry point of %s."), - bfd_get_filename (abfd)); + warning (_("Cannot find section for the entry point of %ps."), + styled_string (file_name_style.style (), + bfd_get_filename (abfd))); entry_point = gdbarch_addr_bits_remove (gdbarch, bfd_get_start_address (abfd) @@ -945,9 +1069,11 @@ print_section_info (struct target_section_table *t, bfd *abfd) if (info_verbose) printf_filtered (" @ %s", hex_string_custom (psect->filepos, 8)); - printf_filtered (" is %s", bfd_section_name (pbfd, psect)); + printf_filtered (" is %s", bfd_section_name (psect)); if (pbfd != abfd) - printf_filtered (" in %s", bfd_get_filename (pbfd)); + printf_filtered (" in %ps", + styled_string (file_name_style.style (), + bfd_get_filename (pbfd))); printf_filtered ("\n"); } } @@ -985,9 +1111,8 @@ set_section_command (const char *args, int from_tty) table = current_target_sections; for (p = table->sections; p < table->sections_end; p++) { - if (!strncmp (secname, bfd_section_name (p->bfd, - p->the_bfd_section), seclen) - && bfd_section_name (p->bfd, p->the_bfd_section)[seclen] == '\0') + if (!strncmp (secname, bfd_section_name (p->the_bfd_section), seclen) + && bfd_section_name (p->the_bfd_section)[seclen] == '\0') { offset = secaddr - p->addr; p->addr += offset; @@ -1046,8 +1171,9 @@ exec_target::find_memory_regions (find_memory_region_ftype func, void *data) return objfile_find_memory_regions (this, func, data); } +void _initialize_exec (); void -_initialize_exec (void) +_initialize_exec () { struct cmd_list_element *c; @@ -1084,5 +1210,23 @@ Show writing into executable and core files."), NULL, show_write_files, &setlist, &showlist); + add_setshow_enum_cmd ("exec-file-mismatch", class_support, + exec_file_mismatch_names, + &exec_file_mismatch, + _("\ +Set exec-file-mismatch handling (ask|warn|off)."), + _("\ +Show exec-file-mismatch handling (ask|warn|off)."), + _("\ +Specifies how to handle a mismatch between the current exec-file name\n\ +loaded by GDB and the exec-file name automatically determined when attaching\n\ +to a process:\n\n\ + ask - warn the user and ask whether to load the determined exec-file.\n\ + warn - warn the user, but do not change the exec-file.\n\ + off - do not check for mismatch."), + set_exec_file_mismatch_command, + show_exec_file_mismatch_command, + &setlist, &showlist); + add_target (exec_target_info, exec_target_open, filename_completer); }