[PATCH 3/8] gdb: write target description into core file

Andrew Burgess andrew.burgess@embecosm.com
Mon Dec 7 14:38:29 GMT 2020


* Tom Tromey <tom@tromey.com> [2020-12-03 13:36:55 -0700]:

> >>>>> "Andrew" == Andrew Burgess <andrew.burgess@embecosm.com> writes:
> 
> Andrew> +      if (bfd_get_section_contents (core_bfd, tdesc_note_section,
> Andrew> +				    contents.data(), (file_ptr) 0,
> 
> Missing space after "data".
> 
> I suppose the trailing \0 is guaranteed to be in the section data.

Well, it should if the content is well formed, this can be seen in the
change to `write_gcore_file_1` where the length is extended to include
the null.

However, you make a good point.  The content is coming from outside
GDB and could be corrupt, so we shouldn't assume that there is a null
present.

As such I've updated the patch so that we force a null at the end when
reading in the target description, this should ensure GDB doesn't read
outside the section contents.

Thanks
Andrew

---

commit 10e9c51c13a5f1da3ad53fc987d90cbffa8501a9
Author: Andrew Burgess <andrew.burgess@embecosm.com>
Date:   Fri Nov 27 15:41:52 2020 +0000

    gdb: write target description into core file
    
    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.

diff --git a/gdb/corelow.c b/gdb/corelow.c
index 4c1f068053d..f00770080d8 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 9a22b1005f0..bf6f44213bb 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,25 @@ 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_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."));
 


More information about the Binutils mailing list