@@ -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;
@@ -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, ¬e_data, note_size);
+
return note_data;
}
@@ -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));
+ }
+}
@@ -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 */
@@ -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, ¬e_data, note_size);
+
return note_data;
}