This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch 2/3] Code reshuffle: Standalone reader of <library-list/>


Hi,

this part is very ugly, particularly that:
struct lm_info
{
  /* LIB is owner by this structure and should be freed with it.  */
  struct solib_target_lib *lib;
};

But lm_info is opaque struct lm_info *, one has different definition of
struct lm_info in solib-svr4.c (used in [patch 3/3]).  And when there is the
different struct solib_target_lib one can no longer "alias"
struct solib_target_lib as struct lm_info.

One could use #define lm_info ... but such hack does not seem acceptable.

So there is that pointer and one more indirection.

The generic reader of <library-list/> is left in solib-target.c, it is always
included in GDB anyway, not sure why to move it elsewhere.

This patch should have no functional change, it is just a code moving.


Thanks,
Jan


gdb/
2011-10-18  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* defs.h (struct solib_target_list): New opaque declaration.
	(make_cleanup_solib_target_list_free): New declaration.
	* dwarf2loc.c: Include solib-target.h.
	(DEF_VEC_I (CORE_ADDR)): Move to solib-target.h.
	* solib-target.c (DEF_VEC_I (CORE_ADDR)): Move to solib-target.h.
	(struct lm_info): Remove; move it to struct solib_target_lib.  New lib
	pointer to it instead.
	(lm_info_p, DEF_VEC_P(lm_info_p)): Remove.
	(solib_target_parse_libraries): Rename to ...
	(solib_target_list_read): ... here and change the calling convention.
	(library_list_start_segment, library_list_start_section): Replace list
	and last types.
	(library_list_start_library): Replace list type.  Change item to lib
	name and type.
	(library_list_end_library): Replace list type.  Change lm_info to lib
	name and type.
	(solib_target_free_library_list): Rename to ...
	(solib_target_list_free): ... here and change the calling convention.
	Remove variable result, change the variable info name and type to lib.
	(solib_target_parse_libraries): Rename to ...
	(solib_target_list_read): ... here and change the calling convention.
	Move here target_read_stralloc from solib_target_current_sos.
	(solib_target_current_sos): Remove variable library_document.  Change
	variable library_list name and type to list.  Change variable info name
	and type to lib.  Move the target_read_stralloc call to
	solib_target_list_read.  Change lm_info references to lm_info->lib.
	(solib_target_free_so): Change lm_info references to lm_info->lib.
	Free also the lib pointer.
	(solib_target_relocate_section_addresses): Change lm_info references to
	lm_info->lib.  
	* solib-target.h: Include vec.h.
	(DEF_VEC_I (CORE_ADDR), struct solib_target_lib)
	(DEF_VEC_P(solib_target_libp), struct solib_target_list): New
	definitions.
	(solib_target_list_read, solib_target_list_free): New declarations.
	* utils.c: Include solib-target.h.
	(do_solib_target_list_free, make_cleanup_solib_target_list_free): New
	functions.

--- a/gdb/defs.h
+++ b/gdb/defs.h
@@ -378,6 +378,10 @@ extern struct cleanup *make_cleanup_value_free (struct value *);
 struct so_list;
 extern struct cleanup *make_cleanup_free_so (struct so_list *so);
 
+struct solib_target_list;
+extern struct cleanup *
+  make_cleanup_solib_target_list_free (struct solib_target_list *list);
+
 extern struct cleanup *make_final_cleanup (make_cleanup_ftype *, void *);
 
 extern struct cleanup *make_my_cleanup (struct cleanup **,
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -39,6 +39,7 @@
 #include "dwarf2expr.h"
 #include "dwarf2loc.h"
 #include "dwarf2-frame.h"
+#include "solib-target.h"	/* For VEC(CORE_ADDR).  */
 
 #include "gdb_string.h"
 #include "gdb_assert.h"
@@ -443,9 +444,6 @@ func_addr_to_tail_call_list (struct gdbarch *gdbarch, CORE_ADDR addr)
   return sym;
 }
 
-/* Define VEC (CORE_ADDR) functions.  */
-DEF_VEC_I (CORE_ADDR);
-
 /* Verify function with entry point exact address ADDR can never call itself
    via its tail calls (incl. transitively).  Throw NO_ENTRY_VALUE_ERROR if it
    can call itself via tail calls.
--- a/gdb/solib-target.c
+++ b/gdb/solib-target.c
@@ -28,41 +28,25 @@
 
 #include "gdb_string.h"
 
-DEF_VEC_I(CORE_ADDR);
-
 /* Private data for each loaded library.  */
 struct lm_info
 {
-  /* The library's name.  The name is normally kept in the struct
-     so_list; it is only here during XML parsing.  */
-  char *name;
-
-  /* The target can either specify segment bases or section bases, not
-     both.  */
-
-  /* The base addresses for each independently relocatable segment of
-     this shared library.  */
-  VEC(CORE_ADDR) *segment_bases;
-
-  /* The base addresses for each independently allocatable,
-     relocatable section of this shared library.  */
-  VEC(CORE_ADDR) *section_bases;
-
-  /* The cached offsets for each section of this shared library,
-     determined from SEGMENT_BASES, or SECTION_BASES.  */
-  struct section_offsets *offsets;
+  /* LIB is owner by this structure and should be freed with it.  */
+  struct solib_target_lib *lib;
 };
 
-typedef struct lm_info *lm_info_p;
-DEF_VEC_P(lm_info_p);
-
 #if !defined(HAVE_LIBEXPAT)
 
-static VEC(lm_info_p) *
-solib_target_parse_libraries (const char *library)
+/* Read out library list from gdbserver into *LIST.  Return 1 if it was read
+   successfully, 0 otherwise.  *LIST is returned always initiailized.  */
+
+int
+solib_target_list_read (struct solib_target_list *list)
 {
   static int have_warned;
 
+  memset (list, 0, sizeof (*list));
+
   if (!have_warned)
     {
       have_warned = 1;
@@ -70,7 +54,7 @@ solib_target_parse_libraries (const char *library)
 		 "at compile time"));
     }
 
-  return NULL;
+  return 0;
 }
 
 #else /* HAVE_LIBEXPAT */
@@ -84,8 +68,8 @@ library_list_start_segment (struct gdb_xml_parser *parser,
 			    const struct gdb_xml_element *element,
 			    void *user_data, VEC(gdb_xml_value_s) *attributes)
 {
-  VEC(lm_info_p) **list = user_data;
-  struct lm_info *last = VEC_last (lm_info_p, *list);
+  struct solib_target_list *list = user_data;
+  struct solib_target_lib *last = VEC_last (solib_target_libp, list->vec);
   ULONGEST *address_p = xml_find_attribute (attributes, "address")->value;
   CORE_ADDR address = (CORE_ADDR) *address_p;
 
@@ -101,8 +85,8 @@ library_list_start_section (struct gdb_xml_parser *parser,
 			    const struct gdb_xml_element *element,
 			    void *user_data, VEC(gdb_xml_value_s) *attributes)
 {
-  VEC(lm_info_p) **list = user_data;
-  struct lm_info *last = VEC_last (lm_info_p, *list);
+  struct solib_target_list *list = user_data;
+  struct solib_target_lib *last = VEC_last (solib_target_libp, list->vec);
   ULONGEST *address_p = xml_find_attribute (attributes, "address")->value;
   CORE_ADDR address = (CORE_ADDR) *address_p;
 
@@ -120,12 +104,12 @@ library_list_start_library (struct gdb_xml_parser *parser,
 			    const struct gdb_xml_element *element,
 			    void *user_data, VEC(gdb_xml_value_s) *attributes)
 {
-  VEC(lm_info_p) **list = user_data;
-  struct lm_info *item = XZALLOC (struct lm_info);
+  struct solib_target_list *list = user_data;
+  struct solib_target_lib *lib = xzalloc (sizeof (*lib));
   const char *name = xml_find_attribute (attributes, "name")->value;
 
-  item->name = xstrdup (name);
-  VEC_safe_push (lm_info_p, *list, item);
+  lib->name = xstrdup (name);
+  VEC_safe_push (solib_target_libp, list->vec, lib);
 }
 
 static void
@@ -133,11 +117,10 @@ library_list_end_library (struct gdb_xml_parser *parser,
 			  const struct gdb_xml_element *element,
 			  void *user_data, const char *body_text)
 {
-  VEC(lm_info_p) **list = user_data;
-  struct lm_info *lm_info = VEC_last (lm_info_p, *list);
+  struct solib_target_list *list = user_data;
+  struct solib_target_lib *lib = VEC_last (solib_target_libp, list->vec);
 
-  if (lm_info->segment_bases == NULL
-      && lm_info->section_bases == NULL)
+  if (lib->segment_bases == NULL && lib->section_bases == NULL)
     gdb_xml_error (parser,
 		   _("No segment or section bases defined"));
 }
@@ -158,24 +141,23 @@ library_list_start_list (struct gdb_xml_parser *parser,
 		   version);
 }
 
-/* Discard the constructed library list.  */
+/* Discard the constructed library list.  Do not free its memory itself as it
+   is usually an autovariable.  */
 
-static void
-solib_target_free_library_list (void *p)
+void
+solib_target_list_free (struct solib_target_list *list)
 {
-  VEC(lm_info_p) **result = p;
-  struct lm_info *info;
+  struct solib_target_lib *lib;
   int ix;
 
-  for (ix = 0; VEC_iterate (lm_info_p, *result, ix, info); ix++)
+  for (ix = 0; VEC_iterate (solib_target_libp, list->vec, ix, lib); ix++)
     {
-      xfree (info->name);
-      VEC_free (CORE_ADDR, info->segment_bases);
-      VEC_free (CORE_ADDR, info->section_bases);
-      xfree (info);
+      xfree (lib->name);
+      VEC_free (CORE_ADDR, lib->segment_bases);
+      VEC_free (CORE_ADDR, lib->section_bases);
+      xfree (lib);
     }
-  VEC_free (lm_info_p, *result);
-  *result = NULL;
+  VEC_free (solib_target_libp, list->vec);
 }
 
 /* The allowed elements and attributes for an XML library list.
@@ -224,23 +206,38 @@ static const struct gdb_xml_element library_list_elements[] = {
   { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
 };
 
-static VEC(lm_info_p) *
-solib_target_parse_libraries (const char *library)
+/* Read out library list from gdbserver into *LIST.  Return 1 if it was read
+   successfully, 0 otherwise.  *LIST is returned always initiailized.  */
+
+int
+solib_target_list_read (struct solib_target_list *list)
 {
-  VEC(lm_info_p) *result = NULL;
-  struct cleanup *back_to = make_cleanup (solib_target_free_library_list,
-					  &result);
+  char *library_document;
+  VEC(solib_target_libp) *vec = NULL;
+  struct cleanup *back_to_doc, *back_to_vec;
+  int retval = 0;
+
+  memset (list, 0, sizeof (*list));
+
+  library_document = target_read_stralloc (&current_target,
+					   TARGET_OBJECT_LIBRARIES,
+					   NULL);
+  if (library_document == NULL)
+    return 0;
+
+  back_to_doc = make_cleanup (xfree, library_document);
+  back_to_vec = make_cleanup_solib_target_list_free (list);
 
   if (gdb_xml_parse_quick (_("target library list"), "library-list.dtd",
-			   library_list_elements, library, &result) == 0)
+			   library_list_elements, library_document, list) == 0)
     {
       /* Parsed successfully, keep the result.  */
-      discard_cleanups (back_to);
-      return result;
+      discard_cleanups (back_to_vec);
+      retval = 1;
     }
 
-  do_cleanups (back_to);
-  return NULL;
+  do_cleanups (back_to_doc);
+  return retval;
 }
 #endif
 
@@ -248,37 +245,30 @@ static struct so_list *
 solib_target_current_sos (void)
 {
   struct so_list *new_solib, *start = NULL, *last = NULL;
-  const char *library_document;
-  VEC(lm_info_p) *library_list;
-  struct lm_info *info;
+  struct solib_target_list list;
+  struct solib_target_lib *lib;
   int ix;
 
   /* Fetch the list of shared libraries.  */
-  library_document = target_read_stralloc (&current_target,
-					   TARGET_OBJECT_LIBRARIES,
-					   NULL);
-  if (library_document == NULL)
-    return NULL;
-
-  /* Parse the list.  */
-  library_list = solib_target_parse_libraries (library_document);
-  if (library_list == NULL)
+  solib_target_list_read (&list);
+  if (VEC_empty (solib_target_libp, list.vec))
     return NULL;
 
   /* Build a struct so_list for each entry on the list.  */
-  for (ix = 0; VEC_iterate (lm_info_p, library_list, ix, info); ix++)
+  for (ix = 0; VEC_iterate (solib_target_libp, list.vec, ix, lib); ix++)
     {
       new_solib = XZALLOC (struct so_list);
-      strncpy (new_solib->so_name, info->name, SO_NAME_MAX_PATH_SIZE - 1);
+      strncpy (new_solib->so_name, lib->name, SO_NAME_MAX_PATH_SIZE - 1);
       new_solib->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
-      strncpy (new_solib->so_original_name, info->name,
+      strncpy (new_solib->so_original_name, lib->name,
 	       SO_NAME_MAX_PATH_SIZE - 1);
       new_solib->so_original_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
-      new_solib->lm_info = info;
+      new_solib->lm_info = xzalloc (sizeof (*new_solib->lm_info));
+      new_solib->lm_info->lib = lib;
 
       /* We no longer need this copy of the name.  */
-      xfree (info->name);
-      info->name = NULL;
+      xfree (lib->name);
+      lib->name = NULL;
 
       /* Add it to the list.  */
       if (!start)
@@ -291,7 +281,7 @@ solib_target_current_sos (void)
     }
 
   /* Free the library list, but not its members.  */
-  VEC_free (lm_info_p, library_list);
+  VEC_free (solib_target_libp, list.vec);
 
   return start;
 }
@@ -317,9 +307,10 @@ solib_target_clear_solib (void)
 static void
 solib_target_free_so (struct so_list *so)
 {
-  gdb_assert (so->lm_info->name == NULL);
-  xfree (so->lm_info->offsets);
-  VEC_free (CORE_ADDR, so->lm_info->segment_bases);
+  gdb_assert (so->lm_info->lib->name == NULL);
+  xfree (so->lm_info->lib->offsets);
+  VEC_free (CORE_ADDR, so->lm_info->lib->segment_bases);
+  xfree (so->lm_info->lib);
   xfree (so->lm_info);
 }
 
@@ -332,18 +323,19 @@ solib_target_relocate_section_addresses (struct so_list *so,
 
   /* Build the offset table only once per object file.  We can not do
      it any earlier, since we need to open the file first.  */
-  if (so->lm_info->offsets == NULL)
+  if (so->lm_info->lib->offsets == NULL)
     {
       int num_sections = bfd_count_sections (so->abfd);
 
-      so->lm_info->offsets = xzalloc (SIZEOF_N_SECTION_OFFSETS (num_sections));
+      so->lm_info->lib->offsets =
+	xzalloc (SIZEOF_N_SECTION_OFFSETS (num_sections));
 
-      if (so->lm_info->section_bases)
+      if (so->lm_info->lib->section_bases)
 	{
 	  int i;
 	  asection *sect;
 	  int num_section_bases
-	    = VEC_length (CORE_ADDR, so->lm_info->section_bases);
+	    = VEC_length (CORE_ADDR, so->lm_info->lib->section_bases);
 	  int num_alloc_sections = 0;
 
 	  for (i = 0, sect = so->abfd->sections;
@@ -363,7 +355,7 @@ Could not relocate shared library \"%s\": wrong number of ALLOC sections"),
 	      CORE_ADDR *section_bases;
 
 	      section_bases = VEC_address (CORE_ADDR,
-					   so->lm_info->section_bases);
+					   so->lm_info->lib->section_bases);
 
 	      so->addr_low = ~(CORE_ADDR) 0;
 	      so->addr_high = 0;
@@ -387,7 +379,7 @@ Could not relocate shared library \"%s\": wrong number of ALLOC sections"),
 		      gdb_assert (so->addr_low <= so->addr_high);
 		      found_range = 1;
 		    }
-		  so->lm_info->offsets->offsets[i]
+		  so->lm_info->lib->offsets->offsets[i]
 		    = section_bases[bases_index];
 		  bases_index++;
 		}
@@ -396,7 +388,7 @@ Could not relocate shared library \"%s\": wrong number of ALLOC sections"),
 	      gdb_assert (so->addr_low <= so->addr_high);
 	    }
 	}
-      else if (so->lm_info->segment_bases)
+      else if (so->lm_info->lib->segment_bases)
 	{
 	  struct symfile_segment_data *data;
 
@@ -411,12 +403,13 @@ Could not relocate shared library \"%s\": no segments"), so->so_name);
 	      int num_bases;
 	      CORE_ADDR *segment_bases;
 
-	      num_bases = VEC_length (CORE_ADDR, so->lm_info->segment_bases);
+	      num_bases = VEC_length (CORE_ADDR,
+				      so->lm_info->lib->segment_bases);
 	      segment_bases = VEC_address (CORE_ADDR,
-					   so->lm_info->segment_bases);
+					   so->lm_info->lib->segment_bases);
 
 	      if (!symfile_map_offsets_to_segments (so->abfd, data,
-						    so->lm_info->offsets,
+						    so->lm_info->lib->offsets,
 						    num_bases, segment_bases))
 		warning (_("\
 Could not relocate shared library \"%s\": bad offsets"), so->so_name);
@@ -451,7 +444,7 @@ Could not relocate shared library \"%s\": bad offsets"), so->so_name);
 	}
     }
 
-  offset = so->lm_info->offsets->offsets[sec->the_bfd_section->index];
+  offset = so->lm_info->lib->offsets->offsets[sec->the_bfd_section->index];
   sec->addr += offset;
   sec->endaddr += offset;
 }
--- a/gdb/solib-target.h
+++ b/gdb/solib-target.h
@@ -20,6 +20,47 @@
 #ifndef SOLIB_TARGET_H
 #define SOLIB_TARGET_H
 
+#include "vec.h"
+
+/* Define VEC (CORE_ADDR) functions.  */
+DEF_VEC_I (CORE_ADDR);
+
+/* Description of one library as read out from gdbserver.  */
+struct solib_target_lib
+{
+  /* The library's name.  The name is normally kept in the struct
+     so_list; it is only here during XML parsing.  */
+  char *name;
+
+  /* The target can either specify segment bases or section bases, not
+     both.  */
+
+  /* The base addresses for each independently relocatable segment of
+     this shared library.  */
+  VEC(CORE_ADDR) *segment_bases;
+
+  /* The base addresses for each independently allocatable,
+     relocatable section of this shared library.  */
+  VEC(CORE_ADDR) *section_bases;
+
+  /* The cached offsets for each section of this shared library,
+     determined from SEGMENT_BASES, or SECTION_BASES.  */
+  struct section_offsets *offsets;
+};
+
+typedef struct solib_target_lib *solib_target_libp;
+DEF_VEC_P(solib_target_libp);
+
+/* The whole library list as read out from gdbserver.  */
+struct solib_target_list
+{
+  /* All libraries.  The vector can be empty.  */
+  VEC(solib_target_libp) *vec;
+};
+
+extern int solib_target_list_read (struct solib_target_list *list);
+extern void solib_target_list_free (struct solib_target_list *list);
+
 struct target_so_ops;
 extern struct target_so_ops solib_target_so_ops;
 
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -61,6 +61,7 @@
 #include "top.h"
 #include "main.h"
 #include "solist.h"
+#include "solib-target.h"
 
 #include "inferior.h"		/* for signed_pointer_to_address */
 
@@ -514,6 +515,24 @@ make_cleanup_free_so (struct so_list *so)
   return make_my_cleanup (&cleanup_chain, do_free_so, so);
 }
 
+/* Helper for make_cleanup_solib_target_list_free.  */
+
+static void
+do_solib_target_list_free (void *arg)
+{
+  struct solib_target_list *list = arg;
+
+  solib_target_list_free (list);
+}
+
+/* Make cleanup handler calling solib_target_list_free for LIST.  */
+
+struct cleanup *
+make_cleanup_solib_target_list_free (struct solib_target_list *list)
+{
+  return make_my_cleanup (&cleanup_chain, do_solib_target_list_free, list);
+}
+
 struct cleanup *
 make_my_cleanup2 (struct cleanup **pmy_chain, make_cleanup_ftype *function,
 		  void *arg,  void (*free_arg) (void *))


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]