This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[patch 2/3] Code reshuffle: Standalone reader of <library-list/>
- From: Jan Kratochvil <jan dot kratochvil at redhat dot com>
- To: gdb-patches at sourceware dot org
- Cc: Paul Pluzhnikov <ppluzhnikov at google dot com>
- Date: Tue, 18 Oct 2011 22:51:45 +0200
- Subject: [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 (¤t_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 (¤t_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 *))