X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fcorelow.c;h=bdbfae372d74f187d1ebde7f03ab823e7c741b7d;hb=98f9338a584c5f68595fc97e692e83f700c8da3d;hp=8e9ac9a32817d9dd3e6b25931fa314f741675a51;hpb=a616bb94509c22c96ae8bf1432ec28a7f3e31778;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/corelow.c b/gdb/corelow.c index 8e9ac9a328..bdbfae372d 100644 --- a/gdb/corelow.c +++ b/gdb/corelow.c @@ -1,6 +1,6 @@ /* Core dump and executable file functions below target vector, for GDB. - Copyright (C) 1986-2018 Free Software Foundation, Inc. + Copyright (C) 1986-2019 Free Software Foundation, Inc. This file is part of GDB. @@ -21,9 +21,6 @@ #include "arch-utils.h" #include #include -#ifdef HAVE_SYS_FILE_H -#include /* needed for F_OK and friends */ -#endif #include "frame.h" /* required by inferior.h */ #include "inferior.h" #include "infrun.h" @@ -31,20 +28,22 @@ #include "command.h" #include "bfd.h" #include "target.h" +#include "process-stratum-target.h" #include "gdbcore.h" #include "gdbthread.h" #include "regcache.h" #include "regset.h" #include "symfile.h" #include "exec.h" -#include "readline/readline.h" +#include "readline/tilde.h" #include "solib.h" #include "filenames.h" #include "progspace.h" #include "objfiles.h" #include "gdb_bfd.h" #include "completer.h" -#include "filestuff.h" +#include "gdbsupport/filestuff.h" +#include "build-id.h" #ifndef O_LARGEFILE #define O_LARGEFILE 0 @@ -58,10 +57,11 @@ static core_fns *sniff_core_bfd (gdbarch *core_gdbarch, static const target_info core_target_info = { "core", N_("Local core dump file"), - N_("Use a core file as a target. Specify the filename of the core file.") + N_("Use a core file as a target.\n\ +Specify the filename of the core file.") }; -class core_target final : public target_ops +class core_target final : public process_stratum_target { public: core_target (); @@ -85,13 +85,16 @@ public: bool thread_alive (ptid_t ptid) override; const struct target_desc *read_description () override; - const char *pid_to_str (ptid_t) override; + std::string pid_to_str (ptid_t) override; const char *thread_name (struct thread_info *) override; + bool has_all_memory () override { return false; } bool has_memory () override; bool has_stack () override; bool has_registers () override; + bool has_execution (ptid_t) override { return false; } + bool info_proc (const char *, enum info_proc_what) override; /* A few helpers. */ @@ -132,8 +135,6 @@ private: /* per-core data */ core_target::core_target () { - to_stratum = process_stratum; - m_core_gdbarch = gdbarch_from_bfd (core_bfd); /* Find a suitable core file handler to munch on core_bfd */ @@ -286,18 +287,18 @@ add_to_thread_list (bfd *abfd, asection *asect, void *reg_sect_arg) int core_tid; int pid, lwpid; asection *reg_sect = (asection *) reg_sect_arg; - int fake_pid_p = 0; + bool fake_pid_p = false; struct inferior *inf; - if (!startswith (bfd_section_name (abfd, asect), ".reg/")) + if (!startswith (bfd_section_name (asect), ".reg/")) return; - core_tid = atoi (bfd_section_name (abfd, asect) + 5); + core_tid = atoi (bfd_section_name (asect) + 5); pid = bfd_core_file_pid (core_bfd); if (pid == 0) { - fake_pid_p = 1; + fake_pid_p = true; pid = CORELOW_PID; } @@ -330,7 +331,7 @@ maybe_say_no_core_file_now (int from_tty) printf_filtered (_("No core file now.\n")); } -/* Backward compatability with old way of specifying core files. */ +/* Backward compatibility with old way of specifying core files. */ void core_file_command (const char *filename, int from_tty) @@ -351,6 +352,27 @@ core_file_command (const char *filename, int from_tty) core_target_open (filename, from_tty); } +/* Locate (and load) an executable file (and symbols) given the core file + BFD ABFD. */ + +static void +locate_exec_from_corefile_build_id (bfd *abfd, int from_tty) +{ + const bfd_build_id *build_id = build_id_bfd_get (abfd); + if (build_id == nullptr) + return; + + gdb_bfd_ref_ptr execbfd + = build_id_to_exec_bfd (build_id->size, build_id->data); + + if (execbfd != nullptr) + { + exec_file_attach (bfd_get_filename (execbfd.get ()), from_tty); + symbol_file_add_main (bfd_get_filename (execbfd.get ()), + symfile_add_flag (from_tty ? SYMFILE_VERBOSE : 0)); + } +} + /* See gdbcore.h. */ void @@ -418,14 +440,7 @@ core_target_open (const char *arg, int from_tty) if (!exec_bfd) set_gdbarch_from_file (core_bfd); - push_target (target); - target_holder.release (); - - /* Do this before acknowledging the inferior, so if - post_create_inferior throws (can happen easilly if you're loading - a core file with the wrong exec), we aren't left with threads - from the previous inferior. */ - init_thread_list (); + push_target (std::move (target_holder)); inferior_ptid = null_ptid; @@ -463,22 +478,24 @@ core_target_open (const char *arg, int from_tty) switch_to_thread (thread); } + if (exec_bfd == nullptr) + locate_exec_from_corefile_build_id (core_bfd, from_tty); + post_create_inferior (target, from_tty); /* Now go through the target stack looking for threads since there may be a thread_stratum target loaded on top of target core by now. The layer above should claim threads found in the BFD sections. */ - TRY + try { target_update_thread_list (); } - CATCH (except, RETURN_MASK_ERROR) + catch (const gdb_exception_error &except) { exception_print (gdb_stderr, except); } - END_CATCH p = bfd_core_file_failing_command (core_bfd); if (p) @@ -525,15 +542,14 @@ core_target_open (const char *arg, int from_tty) anything about threads. That is why the test is >= 2. */ if (thread_count () >= 2) { - TRY + try { thread_command (NULL, from_tty); } - CATCH (except, RETURN_MASK_ERROR) + catch (const gdb_exception_error &except) { exception_print (gdb_stderr, except); } - END_CATCH } } @@ -545,6 +561,8 @@ core_target::detach (inferior *inf, int from_tty) 'this'. */ unpush_target (this); + /* Clear the register cache and the frame cache. */ + registers_changed (); reinit_frame_cache (); maybe_say_no_core_file_now (from_tty); } @@ -591,7 +609,7 @@ core_target::get_core_register_section (struct regcache *regcache, return; } - size = bfd_section_size (core_bfd, section); + size = bfd_section_size (section); if (size < section_min_size) { warning (_("Section `%s' in core file too small."), @@ -621,8 +639,7 @@ core_target::get_core_register_section (struct regcache *regcache, gdb_assert (m_core_vec != nullptr); m_core_vec->core_read_registers (regcache, contents, size, which, - ((CORE_ADDR) - bfd_section_vma (core_bfd, section))); + (CORE_ADDR) bfd_section_vma (section)); } /* Data passed to gdbarch_iterate_over_regset_sections's callback. */ @@ -717,36 +734,6 @@ core_target::files_info () print_section_info (&m_core_section_table, core_bfd); } -struct spuid_list -{ - gdb_byte *buf; - ULONGEST offset; - LONGEST len; - ULONGEST pos; - ULONGEST written; -}; - -static void -add_to_spuid_list (bfd *abfd, asection *asect, void *list_p) -{ - struct spuid_list *list = (struct spuid_list *) list_p; - enum bfd_endian byte_order - = bfd_big_endian (abfd) ? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE; - int fd, pos = 0; - - sscanf (bfd_section_name (abfd, asect), "SPU/%d/regs%n", &fd, &pos); - if (pos == 0) - return; - - if (list->pos >= list->offset && list->pos + 4 <= list->offset + list->len) - { - store_unsigned_integer (list->buf + list->pos - list->offset, - 4, byte_order, fd); - list->written += 4; - } - list->pos += 4; -} - enum target_xfer_status core_target::xfer_partial (enum target_object object, const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf, @@ -775,7 +762,7 @@ core_target::xfer_partial (enum target_object object, const char *annex, if (section == NULL) return TARGET_XFER_E_IO; - size = bfd_section_size (core_bfd, section); + size = bfd_section_size (section); if (offset >= size) return TARGET_XFER_EOF; size -= offset; @@ -810,7 +797,7 @@ core_target::xfer_partial (enum target_object object, const char *annex, if (section == NULL) return TARGET_XFER_E_IO; - size = bfd_section_size (core_bfd, section); + size = bfd_section_size (section); if (offset >= size) return TARGET_XFER_EOF; size -= offset; @@ -873,64 +860,6 @@ core_target::xfer_partial (enum target_object object, const char *annex, } /* FALL THROUGH */ - case TARGET_OBJECT_SPU: - if (readbuf && annex) - { - /* When the SPU contexts are stored in a core file, BFD - represents this with a fake section called - "SPU/". */ - - struct bfd_section *section; - bfd_size_type size; - char sectionstr[100]; - - xsnprintf (sectionstr, sizeof sectionstr, "SPU/%s", annex); - - section = bfd_get_section_by_name (core_bfd, sectionstr); - if (section == NULL) - return TARGET_XFER_E_IO; - - size = bfd_section_size (core_bfd, section); - if (offset >= size) - return TARGET_XFER_EOF; - size -= offset; - if (size > len) - size = len; - - if (size == 0) - return TARGET_XFER_EOF; - if (!bfd_get_section_contents (core_bfd, section, readbuf, - (file_ptr) offset, size)) - { - warning (_("Couldn't read SPU section in core file.")); - return TARGET_XFER_E_IO; - } - - *xfered_len = (ULONGEST) size; - return TARGET_XFER_OK; - } - else if (readbuf) - { - /* NULL annex requests list of all present spuids. */ - struct spuid_list list; - - list.buf = readbuf; - list.offset = offset; - list.len = len; - list.pos = 0; - list.written = 0; - bfd_map_over_sections (core_bfd, add_to_spuid_list, &list); - - if (list.written == 0) - return TARGET_XFER_EOF; - else - { - *xfered_len = (ULONGEST) list.written; - return TARGET_XFER_OK; - } - } - return TARGET_XFER_E_IO; - case TARGET_OBJECT_SIGNAL_INFO: if (readbuf) { @@ -993,10 +922,9 @@ core_target::read_description () return this->beneath ()->read_description (); } -const char * +std::string core_target::pid_to_str (ptid_t ptid) { - static char buf[64]; struct inferior *inf; int pid; @@ -1021,8 +949,7 @@ core_target::pid_to_str (ptid_t ptid) return normal_pid_to_str (ptid); /* No luck. We simply don't have a valid PID to print. */ - xsnprintf (buf, sizeof buf, "
"); - return buf; + return "
"; } const char *