/* Core dump and executable file functions below target vector, for GDB.
- Copyright (C) 1986-2020 Free Software Foundation, Inc.
+ Copyright (C) 1986-2021 Free Software Foundation, Inc.
This file is part of GDB.
#include <unordered_map>
#include <unordered_set>
#include "gdbcmd.h"
+#include "xml-tdesc.h"
#ifndef O_LARGEFILE
#define O_LARGEFILE 0
core_target::core_target ()
{
+ /* Find a first arch based on the BFD. We need the initial gdbarch so
+ we can setup the hooks to find a target description. */
m_core_gdbarch = gdbarch_from_bfd (core_bfd);
+ /* If the arch is able to read a target description from the core, it
+ could yield a more specific gdbarch. */
+ const struct target_desc *tdesc = read_description ();
+
+ if (tdesc != nullptr)
+ {
+ struct gdbarch_info info;
+ info.abfd = core_bfd;
+ info.target_desc = tdesc;
+ m_core_gdbarch = gdbarch_find_by_info (info);
+ }
+
if (!m_core_gdbarch
|| !gdbarch_iterate_over_regset_sections_p (m_core_gdbarch))
error (_("\"%s\": Core file format not supported"),
/* read_core_file_mappings will invoke this lambda for each mapping
that it finds. */
[&] (int num, ULONGEST start, ULONGEST end, ULONGEST file_ofs,
- const char *filename, const void *other)
+ const char *filename, const bfd_build_id *build_id)
{
/* Architecture-specific read_core_mapping methods are expected to
weed out non-file-backed mappings. */
}
bfd = bfd_map[filename] = bfd_openr (expanded_fname.get (),
- "binary");
+ "binary");
if (bfd == nullptr || !bfd_check_format (bfd, bfd_object))
{
exit_inferior_silent (current_inferior ());
/* Clear out solib state while the bfd is still open. See
- comments in clear_solib in solib.c. */
+ comments in clear_solib in solib.c. */
clear_solib ();
current_program_space->cbfd.reset (nullptr);
}
gdb::unique_xmalloc_ptr<char> filename (tilde_expand (arg));
- if (!IS_ABSOLUTE_PATH (filename.get ()))
+ if (strlen (filename.get ()) != 0
+ && !IS_ABSOLUTE_PATH (filename.get ()))
filename = gdb_abspath (filename.get ());
flags = O_BINARY | O_LARGEFILE;
flags |= O_RDWR;
else
flags |= O_RDONLY;
- scratch_chan = gdb_open_cloexec (filename.get (), flags, 0);
+ scratch_chan = gdb_open_cloexec (filename.get (), flags, 0).release ();
if (scratch_chan < 0)
perror_with_name (filename.get ());
{
/* Do it after the err msg */
/* FIXME: should be checking for errors from bfd_close (for one
- thing, on error it does not free all the storage associated
- with the bfd). */
+ thing, on error it does not free all the storage associated
+ with the bfd). */
error (_("\"%s\" is not a core dump: %s"),
filename.get (), bfd_errmsg (bfd_get_error ()));
}
core file. We don't do this unconditionally since an exec file
typically contains more information that helps us determine the
architecture than a core file. */
- if (!exec_bfd)
+ if (!current_program_space->exec_bfd ())
set_gdbarch_from_file (core_bfd);
- push_target (std::move (target_holder));
+ current_inferior ()->push_target (std::move (target_holder));
switch_to_no_thread ();
switch_to_thread (thread);
}
- if (exec_bfd == nullptr)
+ if (current_program_space->exec_bfd () == nullptr)
locate_exec_from_corefile_build_id (core_bfd, from_tty);
post_create_inferior (from_tty);
/* Note that 'this' is dangling after this call. unpush_target
closes the target, and our close implementation deletes
'this'. */
- unpush_target (this);
+ inf->unpush_target (this);
/* Clear the register cache and the frame cache. */
registers_changed ();
for (const auto &mr : m_core_unavailable_mappings)
{
if (address_in_mem_range (memaddr, &mr))
- {
+ {
if (!address_in_mem_range (memend, &mr))
len = mr.start + mr.length - memaddr;
const struct target_desc *
core_target::read_description ()
{
+ /* If the core file contains a target description note then we will use
+ that in preference to anything else. */
+ bfd_size_type tdesc_note_size = 0;
+ struct bfd_section *tdesc_note_section
+ = bfd_get_section_by_name (core_bfd, ".gdb-tdesc");
+ if (tdesc_note_section != nullptr)
+ tdesc_note_size = bfd_section_size (tdesc_note_section);
+ if (tdesc_note_size > 0)
+ {
+ gdb::char_vector contents (tdesc_note_size + 1);
+ if (bfd_get_section_contents (core_bfd, tdesc_note_section,
+ contents.data (), (file_ptr) 0,
+ tdesc_note_size))
+ {
+ /* Ensure we have a null terminator. */
+ contents[tdesc_note_size] = '\0';
+ const struct target_desc *result
+ = string_read_description_xml (contents.data ());
+ if (result != nullptr)
+ return result;
+ }
+ }
+
if (m_core_gdbarch && gdbarch_core_read_description_p (m_core_gdbarch))
{
const struct target_desc *result;
{
add_target (core_target_info, core_target_open, filename_completer);
add_cmd ("core-file-backed-mappings", class_maintenance,
- maintenance_print_core_file_backed_mappings,
+ maintenance_print_core_file_backed_mappings,
_("Print core file's file-backed mappings."),
&maintenanceprintlist);
}