/* 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)
{
/* 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))
{
bfd_set_section_alignment (sec, 2);
/* Set target_section fields. */
- m_core_file_mappings.sections.emplace_back ();
- target_section &ts = m_core_file_mappings.sections.back ();
- ts.addr = start;
- ts.endaddr = end;
- ts.owner = nullptr;
- ts.the_bfd_section = sec;
+ m_core_file_mappings.emplace_back (start, end, sec);
});
normalize_mem_ranges (&m_core_unavailable_mappings);
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);
{
/* 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;
core file provided mappings (e.g. from .note.linuxcore.file
or the like) as this should provide a more accurate
result. If not, check the stratum beneath us, which should
- be the file stratum. */
- if (!m_core_file_mappings.sections.empty ())
- xfer_status = xfer_memory_via_mappings (readbuf, writebuf, offset,
- len, xfered_len);
+ be the file stratum.
+
+ We also check unavailable mappings due to Docker/AUFS driver
+ issues. */
+ if (!m_core_file_mappings.empty ()
+ || !m_core_unavailable_mappings.empty ())
+ {
+ xfer_status = xfer_memory_via_mappings (readbuf, writebuf, offset,
+ len, xfered_len);
+ }
else
xfer_status = this->beneath ()->xfer_partial (object, annex, readbuf,
writebuf, offset, len,
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;
void
core_target::info_proc_mappings (struct gdbarch *gdbarch)
{
- if (!m_core_file_mappings.sections.empty ())
+ if (!m_core_file_mappings.empty ())
{
printf_filtered (_("Mapped address spaces:\n\n"));
if (gdbarch_addr_bit (gdbarch) == 32)
}
}
- for (const target_section &tsp : m_core_file_mappings.sections)
+ for (const target_section &tsp : m_core_file_mappings)
{
ULONGEST start = tsp.addr;
ULONGEST end = tsp.endaddr;
{
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);
}