/* 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
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)
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)
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
print_section_info (&m_core_section_table, core_bfd);
}
\f
-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 (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,
}
/* 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/<annex>". */
-
- 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 (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)
{