aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog14
-rw-r--r--gdb/corelow.c24
-rw-r--r--gdb/fbsd-tdep.c3
-rw-r--r--gdb/gcore-elf.c30
-rw-r--r--gdb/gcore-elf.h8
-rw-r--r--gdb/linux-tdep.c3
6 files changed, 82 insertions, 0 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 6d2d390..dbcc524 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,17 @@
+2021-03-05 Craig Blackmore <craig.blackmore@embecosm.com>
+ Andrew Burgess <andrew.burgess@embecosm.com>
+
+ * corelow.c: Add 'xml-tdesc.h' include.
+ (core_target::read_description): Load the target description from
+ the core file when possible.
+ * fbsd-tdep.c (fbsd_make_corefile_notes): Add target description
+ note.
+ * gcore-elf.c: Add 'gdbsupport/tdesc.h' include.
+ (gcore_elf_make_tdesc_note): New function.
+ * gcore-elf.h (gcore_elf_make_tdesc_note): Declare.
+ * linux-tdep.c (linux_make_corefile_notes): Add target description
+ note.
+
2021-03-05 Andrew Burgess <andrew.burgess@embecosm.com>
* Makefile.in (SFILES): Add gcore-elf.c.
diff --git a/gdb/corelow.c b/gdb/corelow.c
index a63eab4..a2d2d20 100644
--- a/gdb/corelow.c
+++ b/gdb/corelow.c
@@ -49,6 +49,7 @@
#include <unordered_map>
#include <unordered_set>
#include "gdbcmd.h"
+#include "xml-tdesc.h"
#ifndef O_LARGEFILE
#define O_LARGEFILE 0
@@ -1000,6 +1001,29 @@ core_target::thread_alive (ptid_t ptid)
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;
diff --git a/gdb/fbsd-tdep.c b/gdb/fbsd-tdep.c
index dc4278c..170e8f5 100644
--- a/gdb/fbsd-tdep.c
+++ b/gdb/fbsd-tdep.c
@@ -712,6 +712,9 @@ fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
return NULL;
}
+ /* Include the target description when possible. */
+ gcore_elf_make_tdesc_note (obfd, &note_data, note_size);
+
return note_data;
}
diff --git a/gdb/gcore-elf.c b/gdb/gcore-elf.c
index b0fb808..d9c216b 100644
--- a/gdb/gcore-elf.c
+++ b/gdb/gcore-elf.c
@@ -24,6 +24,7 @@
#include "gdbthread.h"
#include "inferior.h"
#include "regset.h"
+#include "gdbsupport/tdesc.h"
/* Structure for passing information from GCORE_COLLECT_THREAD_REGISTERS
via an iterator to GCORE_COLLECT_REGSET_SECTION_CB. */
@@ -134,3 +135,32 @@ gcore_elf_build_thread_register_notes
gcore_elf_collect_thread_registers (regcache, info->ptid, obfd,
note_data, note_size, stop_signal);
}
+
+/* See gcore-elf.h. */
+
+void
+gcore_elf_make_tdesc_note (bfd *obfd,
+ gdb::unique_xmalloc_ptr<char> *note_data,
+ int *note_size)
+{
+ /* Append the target description to the core file. */
+ const struct target_desc *tdesc = gdbarch_target_desc (target_gdbarch ());
+ const char *tdesc_xml
+ = tdesc == nullptr ? nullptr : tdesc_get_features_xml (tdesc);
+ if (tdesc_xml != nullptr && *tdesc_xml != '\0')
+ {
+ /* Skip the leading '@'. */
+ if (*tdesc_xml == '@')
+ ++tdesc_xml;
+
+ /* Include the null terminator in the length. */
+ size_t tdesc_len = strlen (tdesc_xml) + 1;
+
+ /* Now add the target description into the core file. */
+ note_data->reset (elfcore_write_register_note (obfd,
+ note_data->release (),
+ note_size,
+ ".gdb-tdesc", tdesc_xml,
+ tdesc_len));
+ }
+}
diff --git a/gdb/gcore-elf.h b/gdb/gcore-elf.h
index d667686..b750165 100644
--- a/gdb/gcore-elf.h
+++ b/gdb/gcore-elf.h
@@ -36,4 +36,12 @@ extern void gcore_elf_build_thread_register_notes
(struct gdbarch *gdbarch, struct thread_info *info, gdb_signal stop_signal,
bfd *obfd, gdb::unique_xmalloc_ptr<char> *note_data, int *note_size);
+/* Add content to *NOTE_DATA (and update *NOTE_SIZE) to include a note
+ containing the current targtet's target description. The core file is
+ being written to OBFD. If something goes wrong then *NOTE_DATA can be
+ set to nullptr. */
+
+extern void gcore_elf_make_tdesc_note
+ (bfd *obfd, gdb::unique_xmalloc_ptr<char> *note_data, int *note_size);
+
#endif /* GCORE_ELF_H */
diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c
index 5bfd82d..ab3402a 100644
--- a/gdb/linux-tdep.c
+++ b/gdb/linux-tdep.c
@@ -1935,6 +1935,9 @@ linux_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
/* File mappings. */
linux_make_mappings_corefile_notes (gdbarch, obfd, note_data, note_size);
+ /* Target description. */
+ gcore_elf_make_tdesc_note (obfd, &note_data, note_size);
+
return note_data;
}