[PATCH 3/5] gdb: refactor file_mappings_builder to use byte_vector

Mihails Strasuns mihails.strasuns@intel.com
Sun Jan 3 13:02:58 GMT 2021


Changes the underlying implementation for the file_mappings_builder to
be based on plain byte vectors rather than obstack.  The latter does not
seem of much benefit here - buffers are discarded after a single `gcore`
invocation and total size is relatively small.  Rewriting it with a byte
vector makes it simpler and allows to slightly more C++-friendly API.

gdb/ChangeLog:
2020-12-17  Mihails Strasuns  <mihails.strasuns@intel.com>

	* elfnote-file.h, elfnote-file.c (file_mappings_builder): Switch to
	  byte vector.
	* linux-tdep.c (linux_make_mappings_corefile_notes): Adapt to
	  file_mappings_builder API changes.
---
 gdb/elfnote-file.c | 55 ++++++++++++++++++++++++----------------------
 gdb/elfnote-file.h | 26 +++++++++++++---------
 gdb/linux-tdep.c   | 11 +++++-----
 3 files changed, 51 insertions(+), 41 deletions(-)

diff --git a/gdb/elfnote-file.c b/gdb/elfnote-file.c
index e68ba08005..4e35aff7df 100644
--- a/gdb/elfnote-file.c
+++ b/gdb/elfnote-file.c
@@ -23,6 +23,14 @@
 #include "elf-bfd.h"
 #include "value.h"
 
+static void
+push_long (gdb::byte_vector *vec, type *long_type, ULONGEST value)
+{
+  gdb_byte buf[sizeof (ULONGEST)];
+  pack_long (buf, long_type, value);
+  vec->insert (vec->end (), &buf[0], &buf[TYPE_LENGTH (long_type)]);
+}
+
 /* See elfnote-file.h.  */
 
 file_mappings_builder::file_mappings_builder (type *long_type)
@@ -30,53 +38,48 @@ file_mappings_builder::file_mappings_builder (type *long_type)
   this->file_count = 0;
   this->long_type = long_type;
   /* Reserve space for the count.  */
-  obstack_blank (&this->data, TYPE_LENGTH (long_type));
+  this->data.resize (TYPE_LENGTH (long_type));
   /* We always write the page size as 1 since we have no good way to
      determine the correct value.  */
-  pack_long (this->buf, long_type, 1);
-  obstack_grow (&this->data, this->buf, TYPE_LENGTH (long_type));
+  push_long (&this->data, this->long_type, 1);
 }
 
 /* See elfnote-file.h.  */
 
 file_mappings_builder &
-file_mappings_builder::add (ULONGEST vaddr, ULONGEST size,
-			    ULONGEST offset, const char *filename)
+file_mappings_builder::add (const file_mapping &mapping)
 {
   ++this->file_count;
-  int length = TYPE_LENGTH (this->long_type);
 
-  pack_long (this->buf, this->long_type, vaddr);
-  obstack_grow (&this->data, this->buf, length);
-  pack_long (this->buf, this->long_type, vaddr + size);
-  obstack_grow (&this->data, this->buf, length);
-  pack_long (this->buf, this->long_type, offset);
-  obstack_grow (&this->data, this->buf, length);
-
-  obstack_grow_str0 (&this->filenames, filename);
+  push_long (&this->data, this->long_type, mapping.vaddr);
+  push_long (&this->data, this->long_type, mapping.vaddr + mapping.size);
+  push_long (&this->data, this->long_type, mapping.offset);
+  const char* p = mapping.filename;
+  do
+    {
+      this->filenames.push_back (*p);
+    }
+  while (*p++ != '\0');
 
   return *this;
 }
 
 /* See elfnote-file.h.  */
 
-void *
-file_mappings_builder::build (int *size)
+gdb::byte_vector
+file_mappings_builder::build ()
 {
   if (this->file_count != 0)
     {
-      /* Write the count to the obstack.  */
-      pack_long ((gdb_byte *) obstack_base (&this->data), this->long_type,
-		 this->file_count);
+      /* Write the count to the reserved space.  */
+      pack_long (this->data.data (), this->long_type, this->file_count);
 
-      /* Copy the filenames to the data obstack.  */
-      int filesize = obstack_object_size (&this->filenames);
-      obstack_grow (&this->data, obstack_base (&this->filenames), filesize);
+      /* Copy the filenames to the main buffer.  */
+      this->data.insert (this->data.end (), this->filenames.begin (),
+			 this->filenames.end ());
 
-      *size = obstack_object_size (&this->data);
-      return obstack_base (&this->data);
+      return std::move (this->data);
     }
 
-  *size = 0;
-  return nullptr;
+  return gdb::byte_vector ();
 }
diff --git a/gdb/elfnote-file.h b/gdb/elfnote-file.h
index cd11e450dc..09a150d4d0 100644
--- a/gdb/elfnote-file.h
+++ b/gdb/elfnote-file.h
@@ -26,19 +26,26 @@
 
 #include "defs.h"
 #include "gdbtypes.h"
-#include "obstack.h"
+#include "gdbsupport/byte-vector.h"
+
+/* Fields for an individual NT_FILE element.  */
+struct file_mapping
+{
+  ULONGEST vaddr;
+  ULONGEST size;
+  ULONGEST offset;
+  const char *filename;
+};
 
 class file_mappings_builder
 {
 private:
-  /* Buffer used for packing numbers.  */
-  gdb_byte buf[sizeof (ULONGEST)];
   /* Number of files mapped.  */
   ULONGEST file_count;
-  /* The filename obstack.  */
-  auto_obstack filenames;
-  /* The obstack for the main part of the data.  */
-  auto_obstack data;
+  /* The filename buffer.  */
+  gdb::byte_vector filenames;
+  /* The address/offset item buffer.  */
+  gdb::byte_vector data;
   /* The architecture's "long" type.  */
   type *long_type;
 
@@ -47,10 +54,9 @@ class file_mappings_builder
   file_mappings_builder (type *long_type);
 
   /* Adds a new mapping to a currently created note.  */
-  file_mappings_builder& add (ULONGEST vaddr, ULONGEST size, ULONGEST offset,
-			      const char *filename);
+  file_mappings_builder &add (const file_mapping &mapping);
 
   /* Finalizes creation of the note data and releases the data buffer.  */
-  void *build (int *size);
+  gdb::byte_vector build ();
 };
 #endif
diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c
index 1a736d3d57..8250c53bea 100644
--- a/gdb/linux-tdep.c
+++ b/gdb/linux-tdep.c
@@ -1512,7 +1512,7 @@ linux_make_mappings_callback (ULONGEST vaddr, ULONGEST size,
     return 0;
 
   auto *map = (file_mappings_builder *) data;
-  map->add (vaddr, size, offset, filename);
+  map->add ({vaddr, size, offset, filename});
 
   return 0;
 }
@@ -1528,18 +1528,19 @@ linux_make_mappings_corefile_notes (struct gdbarch *gdbarch, bfd *obfd,
 {
   struct type *long_type
     = arch_integer_type (gdbarch, gdbarch_long_bit (gdbarch), 0, "long");
+
   file_mappings_builder mapping_builder (long_type);
 
   linux_find_memory_regions_full (gdbarch, dump_note_entry_p,
 				  linux_make_mappings_callback,
 				  &mapping_builder);
 
-  int file_note_size = 0;
-  void *file_note_data = mapping_builder.build (&file_note_size);
+  gdb::byte_vector file_note_data = mapping_builder.build ();
 
-  if (file_note_data != nullptr)
+  if (file_note_data.size () > 0)
     note_data.reset (elfcore_write_file_note (obfd, note_data.release (), note_size,
-					      file_note_data, file_note_size));
+					      file_note_data.data (),
+					      file_note_data.size ()));
 }
 
 /* Structure for passing information from
-- 
2.17.1

Intel Deutschland GmbH
Registered Address: Am Campeon 10-12, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de
Managing Directors: Christin Eisenschmid, Gary Kershaw
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928



More information about the Gdb-patches mailing list