/* Core dump and executable file functions below target vector, for GDB.
- Copyright (C) 1986-2019 Free Software Foundation, Inc.
+ Copyright (C) 1986-2020 Free Software Foundation, Inc.
This file is part of GDB.
#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 "gdb_bfd.h"
#include "completer.h"
#include "gdbsupport/filestuff.h"
+#include "build-id.h"
+#include "gdbsupport/pathstuff.h"
#ifndef O_LARGEFILE
#define O_LARGEFILE 0
bool has_memory () override;
bool has_stack () override;
bool has_registers () override;
- bool has_execution (ptid_t) override { return false; }
+ bool has_execution (inferior *inf) override { return false; }
bool info_proc (const char *, enum info_proc_what) override;
ptid = ptid_t (pid, lwpid, 0);
- add_thread (ptid);
+ add_thread (inf->process_target (), ptid);
/* Warning, Will Robinson, looking at BFD private data! */
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
gdb::unique_xmalloc_ptr<char> filename (tilde_expand (arg));
if (!IS_ABSOLUTE_PATH (filename.get ()))
- filename.reset (concat (current_directory, "/",
- filename.get (), (char *) NULL));
+ filename = gdb_abspath (filename.get ());
flags = O_BINARY | O_LARGEFILE;
if (write_files)
{
inferior_appeared (current_inferior (), CORELOW_PID);
inferior_ptid = ptid_t (CORELOW_PID);
- add_thread_silent (inferior_ptid);
+ add_thread_silent (target, inferior_ptid);
}
else
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
/* Current thread should be NUM 1 but the user does not know that.
If a program is single threaded gdb in general does not mention
anything about threads. That is why the test is >= 2. */
- if (thread_count () >= 2)
+ if (thread_count (target) >= 2)
{
try
{
{
struct bfd_section *section;
bfd_size_type size;
- char *contents;
bool variable_size_section = (regset != NULL
&& regset->flags & REGSET_VARIABLE_SIZE);
section_name.c_str ());
}
- contents = (char *) alloca (size);
- if (! bfd_get_section_contents (core_bfd, section, contents,
- (file_ptr) 0, size))
+ gdb::byte_vector contents (size);
+ if (!bfd_get_section_contents (core_bfd, section, contents.data (),
+ (file_ptr) 0, size))
{
warning (_("Couldn't read %s registers from `%s' section in core file."),
human_name, section_name.c_str ());
if (regset != NULL)
{
- regset->supply_regset (regset, regcache, -1, contents, size);
+ regset->supply_regset (regset, regcache, -1, contents.data (), size);
return;
}
gdb_assert (m_core_vec != nullptr);
- m_core_vec->core_read_registers (regcache, contents, size, which,
+ m_core_vec->core_read_registers (regcache, contents.data (), size, which,
(CORE_ADDR) bfd_section_vma (section));
}
/* Otherwise, this isn't a "threaded" core -- use the PID field, but
only if it isn't a fake PID. */
- inf = find_inferior_ptid (ptid);
+ inf = find_inferior_ptid (this, ptid);
if (inf != NULL && !inf->fake_pid_p)
return normal_pid_to_str (ptid);
return true;
}
+void _initialize_corelow ();
void
-_initialize_corelow (void)
+_initialize_corelow ()
{
add_target (core_target_info, core_target_open, filename_completer);
}