/* 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.
#include "arch-utils.h"
#include <signal.h>
#include <fcntl.h>
-#ifdef HAVE_SYS_FILE_H
-#include <sys/file.h> /* needed for F_OK and friends */
-#endif
#include "frame.h" /* required by inferior.h */
#include "inferior.h"
#include "infrun.h"
#include "command.h"
#include "bfd.h"
#include "target.h"
+#include "process-stratum-target.h"
#include "gdbcore.h"
#include "gdbthread.h"
#include "regcache.h"
#include "objfiles.h"
#include "gdb_bfd.h"
#include "completer.h"
-#include "filestuff.h"
+#include "common/filestuff.h"
#ifndef O_LARGEFILE
#define O_LARGEFILE 0
N_("Use a core file as a target. 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 ();
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. */
void get_core_register_section (struct regcache *regcache,
const struct regset *regset,
const char *name,
- int min_size,
+ int section_min_size,
int which,
const char *human_name,
bool required);
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 */
{
if (core_bfd)
{
- int pid = ptid_get_pid (inferior_ptid);
inferior_ptid = null_ptid; /* Avoid confusion from thread
stuff. */
- if (pid != 0)
- exit_inferior_silent (pid);
+ exit_inferior_silent (current_inferior ());
/* Clear out solib state while the bfd is still open. See
comments in clear_solib in solib.c. */
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/"))
pid = bfd_core_file_pid (core_bfd);
if (pid == 0)
{
- fake_pid_p = 1;
+ fake_pid_p = true;
pid = CORELOW_PID;
}
inf->fake_pid_p = fake_pid_p;
}
- ptid = ptid_build (pid, lwpid, 0);
+ ptid = ptid_t (pid, lwpid, 0);
add_thread (ptid);
{
const char *p;
int siggy;
- struct cleanup *old_chain;
int scratch_chan;
int flags;
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;
bfd_map_over_sections (core_bfd, add_to_thread_list,
bfd_get_section_by_name (core_bfd, ".reg"));
- if (ptid_equal (inferior_ptid, null_ptid))
+ if (inferior_ptid == null_ptid)
{
/* Either we found no .reg/NN section, and hence we have a
non-threaded core (single-threaded, from gdb's perspective),
which was the "main" thread. The latter case shouldn't
usually happen, but we're dealing with input here, which can
always be broken in different ways. */
- struct thread_info *thread = first_thread_of_process (-1);
+ thread_info *thread = first_thread_of_inferior (current_inferior ());
if (thread == NULL)
{
inferior_appeared (current_inferior (), CORELOW_PID);
- inferior_ptid = pid_to_ptid (CORELOW_PID);
+ inferior_ptid = ptid_t (CORELOW_PID);
add_thread_silent (inferior_ptid);
}
else
- switch_to_thread (thread->ptid);
+ switch_to_thread (thread);
}
post_create_inferior (target, from_tty);
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)
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
}
}
'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);
}
core_target::get_core_register_section (struct regcache *regcache,
const struct regset *regset,
const char *name,
- int min_size,
+ int section_min_size,
int which,
const char *human_name,
bool required)
}
size = bfd_section_size (core_bfd, section);
- if (size < min_size)
+ if (size < section_min_size)
{
warning (_("Section `%s' in core file too small."),
section_name.c_str ());
return;
}
- if (size != min_size && !variable_size_section)
+ if (size != section_min_size && !variable_size_section)
{
warning (_("Unexpected size of section `%s' in core file."),
section_name.c_str ());
register note section. */
static void
-get_core_registers_cb (const char *sect_name, int size,
+get_core_registers_cb (const char *sect_name, int supply_size, int collect_size,
const struct regset *regset,
const char *human_name, void *cb_data)
{
auto *data = (get_core_registers_cb_data *) cb_data;
bool required = false;
+ bool variable_size_section = (regset != NULL
+ && regset->flags & REGSET_VARIABLE_SIZE);
+
+ if (!variable_size_section)
+ gdb_assert (supply_size == collect_size);
if (strcmp (sect_name, ".reg") == 0)
{
/* The 'which' parameter is only used when no regset is provided.
Thus we just set it to -1. */
data->target->get_core_register_section (data->regcache, regset, sect_name,
- size, -1, human_name, required);
+ supply_size, -1, human_name,
+ required);
}
/* Get the registers out of a core file. This is the machine-
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;
"process", with normal_pid_to_str. */
/* Try the LWPID field first. */
- pid = ptid_get_lwp (ptid);
+ pid = ptid.lwp ();
if (pid != 0)
- return normal_pid_to_str (pid_to_ptid (pid));
+ return normal_pid_to_str (ptid_t (pid));
/* Otherwise, this isn't a "threaded" core -- use the PID field, but
only if it isn't a fake PID. */
return normal_pid_to_str (ptid);
/* No luck. We simply don't have a valid PID to print. */
- xsnprintf (buf, sizeof buf, "<main task>");
- return buf;
+ return "<main task>";
}
const char *