[PATCHv2 3/9] gdb: write target description into core file

Andrew Burgess andrew.burgess@embecosm.com
Wed Jan 20 20:23:09 GMT 2021


When a core file is created from within GDB add the target description
into a note within the core file.

When loading a core file, if the target description note is present
then load the target description from the core file.

The benefit of this is that we can be sure that, when analysing the
core file within GDB, that we are using the exact same target
description as was in use at the time the core file was created.

In future commits I intend to add support for bare metal core dumps
for some targets.  These core dumps will include auxiliary registers,
the availability of which can only be established by looking at the
target description.

gdb/ChangeLog:

	* corelow.c: Add 'xml-tdesc.h' include.
	(core_target::read_description): Load the target description from
	the core file when possible.
	* gcore.c: Add 'gdbsupport/tdesc.h' include.
	(write_gcore_file_1): Write out the target description.
---
 gdb/ChangeLog |  9 +++++++++
 gdb/corelow.c | 24 ++++++++++++++++++++++++
 gdb/gcore.c   | 21 +++++++++++++++++++++
 3 files changed, 54 insertions(+)

diff --git a/gdb/corelow.c b/gdb/corelow.c
index a63eab4852b..fd8a5c71e22 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 != NULL)
+	    return result;
+	}
+    }
+
   if (m_core_gdbarch && gdbarch_core_read_description_p (m_core_gdbarch))
     {
       const struct target_desc *result;
diff --git a/gdb/gcore.c b/gdb/gcore.c
index d62aa3a7109..cecb9146994 100644
--- a/gdb/gcore.c
+++ b/gdb/gcore.c
@@ -38,6 +38,7 @@
 #include "gdbsupport/gdb_unlinker.h"
 #include "gdbsupport/byte-vector.h"
 #include "gdbsupport/scope-exit.h"
+#include "gdbsupport/tdesc.h"
 
 /* The largest amount of memory to read from the target at once.  We
    must throttle it to limit the amount of memory used by GDB during
@@ -82,6 +83,26 @@ write_gcore_file_1 (bfd *obfd)
     note_data = gdbarch_make_corefile_notes (target_gdbarch (), obfd,
 					     &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));
+    }
+
   if (note_data == NULL || note_size == 0)
     error (_("Target does not support core file generation."));
 
-- 
2.25.4



More information about the Binutils mailing list