X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gdb%2Fsolib-aix.c;h=d13b651944150fb0c7749558f2dafd95383020e3;hb=d9c4ba536c522b8dc2194d4100270a159be7894a;hp=74f0eaa60f0ef5e3bb0d765374bc7a2006b08d24;hpb=e2882c85786571175a0b0bfc3bcd2f14620b1ea3;p=external%2Fbinutils.git diff --git a/gdb/solib-aix.c b/gdb/solib-aix.c index 74f0eaa..d13b651 100644 --- a/gdb/solib-aix.c +++ b/gdb/solib-aix.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2013-2018 Free Software Foundation, Inc. +/* Copyright (C) 2013-2019 Free Software Foundation, Inc. This file is part of GDB. @@ -24,8 +24,9 @@ #include "objfiles.h" #include "symtab.h" #include "xcoffread.h" -#include "observer.h" +#include "observable.h" #include "gdbcmd.h" +#include "gdbsupport/scope-exit.h" /* Variable controlling the output of the debugging traces for this module. */ @@ -58,14 +59,11 @@ struct lm_info_aix : public lm_info_base ULONGEST data_size = 0; }; -typedef lm_info_aix *lm_info_aix_p; -DEF_VEC_P(lm_info_aix_p); - /* This module's per-inferior data. */ struct solib_aix_inferior_data { - /* The list of shared libraries. NULL if not computed yet. + /* The list of shared libraries. Note that the first element of this list is always the main executable, which is not technically a shared library. But @@ -73,11 +71,11 @@ struct solib_aix_inferior_data the same principles applied to shared libraries also apply to the main executable. So it's simpler to keep it as part of this list. */ - VEC (lm_info_aix_p) *library_list; + gdb::optional> library_list; }; /* Key to our per-inferior data. */ -static const struct inferior_data *solib_aix_inferior_data_handle; +static inferior_key solib_aix_inferior_data_handle; /* Return this module's data for the given inferior. If none is found, add a zero'ed one now. */ @@ -87,13 +85,9 @@ get_solib_aix_inferior_data (struct inferior *inf) { struct solib_aix_inferior_data *data; - data = ((struct solib_aix_inferior_data *) - inferior_data (inf, solib_aix_inferior_data_handle)); + data = solib_aix_inferior_data_handle.get (inf); if (data == NULL) - { - data = XCNEW (struct solib_aix_inferior_data); - set_inferior_data (inf, solib_aix_inferior_data_handle, data); - } + data = solib_aix_inferior_data_handle.emplace (inf); return data; } @@ -102,7 +96,7 @@ get_solib_aix_inferior_data (struct inferior *inf) /* Dummy implementation if XML support is not compiled in. */ -static VEC (lm_info_aix_p) * +static gdb::optional> solib_aix_parse_libraries (const char *library) { static int have_warned; @@ -114,14 +108,7 @@ solib_aix_parse_libraries (const char *library) "at compile time")); } - return NULL; -} - -/* Dummy implementation if XML support is not compiled in. */ - -static void -solib_aix_free_library_list (void *p) -{ + return {}; } #else /* HAVE_LIBEXPAT */ @@ -134,32 +121,32 @@ static void library_list_start_library (struct gdb_xml_parser *parser, const struct gdb_xml_element *element, void *user_data, - VEC (gdb_xml_value_s) *attributes) + std::vector &attributes) { - VEC (lm_info_aix_p) **list = (VEC (lm_info_aix_p) **) user_data; - lm_info_aix *item = new lm_info_aix; + std::vector *list = (std::vector *) user_data; + lm_info_aix item; struct gdb_xml_value *attr; attr = xml_find_attribute (attributes, "name"); - item->filename = xstrdup ((const char *) attr->value); + item.filename = (const char *) attr->value.get (); attr = xml_find_attribute (attributes, "member"); if (attr != NULL) - item->member_name = xstrdup ((const char *) attr->value); + item.member_name = (const char *) attr->value.get (); attr = xml_find_attribute (attributes, "text_addr"); - item->text_addr = * (ULONGEST *) attr->value; + item.text_addr = * (ULONGEST *) attr->value.get (); attr = xml_find_attribute (attributes, "text_size"); - item->text_size = * (ULONGEST *) attr->value; + item.text_size = * (ULONGEST *) attr->value.get (); attr = xml_find_attribute (attributes, "data_addr"); - item->data_addr = * (ULONGEST *) attr->value; + item.data_addr = * (ULONGEST *) attr->value.get (); attr = xml_find_attribute (attributes, "data_size"); - item->data_size = * (ULONGEST *) attr->value; + item.data_size = * (ULONGEST *) attr->value.get (); - VEC_safe_push (lm_info_aix_p, *list, item); + list->push_back (std::move (item)); } /* Handle the start of a element. */ @@ -167,9 +154,11 @@ library_list_start_library (struct gdb_xml_parser *parser, static void library_list_start_list (struct gdb_xml_parser *parser, const struct gdb_xml_element *element, - void *user_data, VEC (gdb_xml_value_s) *attributes) + void *user_data, + std::vector &attributes) { - char *version = (char *) xml_find_attribute (attributes, "version")->value; + char *version + = (char *) xml_find_attribute (attributes, "version")->value.get (); if (strcmp (version, "1.0") != 0) gdb_xml_error (parser, @@ -177,25 +166,6 @@ library_list_start_list (struct gdb_xml_parser *parser, version); } -/* Discard the constructed library list. */ - -static void -solib_aix_free_library_list (void *p) -{ - VEC (lm_info_aix_p) **result = (VEC (lm_info_aix_p) **) p; - lm_info_aix *info; - int ix; - - if (solib_aix_debug) - fprintf_unfiltered (gdb_stdlog, "DEBUG: solib_aix_free_library_list\n"); - - for (ix = 0; VEC_iterate (lm_info_aix_p, *result, ix, info); ix++) - delete info; - - VEC_free (lm_info_aix_p, *result); - *result = NULL; -} - /* The allowed elements and attributes for an AIX library list described in XML format. The root element is a . */ @@ -232,33 +202,26 @@ static const struct gdb_xml_element library_list_elements[] = }; /* Parse LIBRARY, a string containing the loader info in XML format, - and return an lm_info_aix_p vector. + and return a vector of lm_info_aix objects. - Return NULL if the parsing failed. */ + Return an empty option if the parsing failed. */ -static VEC (lm_info_aix_p) * +static gdb::optional> solib_aix_parse_libraries (const char *library) { - VEC (lm_info_aix_p) *result = NULL; - struct cleanup *back_to = make_cleanup (solib_aix_free_library_list, - &result); + std::vector result; if (gdb_xml_parse_quick (_("aix library list"), "library-list-aix.dtd", - library_list_elements, library, &result) == 0) - { - /* Parsed successfully, keep the result. */ - discard_cleanups (back_to); - return result; - } + library_list_elements, library, &result) == 0) + return result; - do_cleanups (back_to); - return NULL; + return {}; } #endif /* HAVE_LIBEXPAT */ -/* Return the loader info for the given inferior (INF), or NULL if - the list could not be computed. +/* Return the loader info for the given inferior (INF), or an empty + option if the list could not be computed. Cache the result in per-inferior data, so as to avoid recomputing it each time this function is called. @@ -267,37 +230,34 @@ solib_aix_parse_libraries (const char *library) is not NULL, then print a warning including WARNING_MSG and a description of the error. */ -static VEC (lm_info_aix_p) * +static gdb::optional> & solib_aix_get_library_list (struct inferior *inf, const char *warning_msg) { struct solib_aix_inferior_data *data; /* If already computed, return the cached value. */ data = get_solib_aix_inferior_data (inf); - if (data->library_list != NULL) + if (data->library_list.has_value ()) return data->library_list; - gdb::unique_xmalloc_ptr library_document - = target_read_stralloc (¤t_target, TARGET_OBJECT_LIBRARIES_AIX, + gdb::optional library_document + = target_read_stralloc (current_top_target (), TARGET_OBJECT_LIBRARIES_AIX, NULL); - if (library_document == NULL && warning_msg != NULL) + if (!library_document && warning_msg != NULL) { warning (_("%s (failed to read TARGET_OBJECT_LIBRARIES_AIX)"), warning_msg); - return NULL; + return data->library_list; } if (solib_aix_debug) fprintf_unfiltered (gdb_stdlog, "DEBUG: TARGET_OBJECT_LIBRARIES_AIX = \n%s\n", - library_document.get ()); + library_document->data ()); - data->library_list = solib_aix_parse_libraries (library_document.get ()); - if (data->library_list == NULL && warning_msg != NULL) - { - warning (_("%s (missing XML support?)"), warning_msg); - return NULL; - } + data->library_list = solib_aix_parse_libraries (library_document->data ()); + if (!data->library_list.has_value () && warning_msg != NULL) + warning (_("%s (missing XML support?)"), warning_msg); return data->library_list; } @@ -437,14 +397,14 @@ solib_aix_clear_solib (void) The resulting array is computed on the heap and must be deallocated after use. */ -static struct section_offsets * +static gdb::unique_xmalloc_ptr solib_aix_get_section_offsets (struct objfile *objfile, lm_info_aix *info) { - struct section_offsets *offsets; bfd *abfd = objfile->obfd; - offsets = XCNEWVEC (struct section_offsets, objfile->num_sections); + gdb::unique_xmalloc_ptr offsets + (XCNEWVEC (struct section_offsets, objfile->num_sections)); /* .text */ @@ -493,32 +453,27 @@ static void solib_aix_solib_create_inferior_hook (int from_tty) { const char *warning_msg = "unable to relocate main executable"; - VEC (lm_info_aix_p) *library_list; - lm_info_aix *exec_info; /* We need to relocate the main executable... */ - library_list = solib_aix_get_library_list (current_inferior (), - warning_msg); - if (library_list == NULL) + gdb::optional> &library_list + = solib_aix_get_library_list (current_inferior (), warning_msg); + if (!library_list.has_value ()) return; /* Warning already printed. */ - if (VEC_length (lm_info_aix_p, library_list) < 1) + if (library_list->empty ()) { warning (_("unable to relocate main executable (no info from loader)")); return; } - exec_info = VEC_index (lm_info_aix_p, library_list, 0); - + lm_info_aix &exec_info = (*library_list)[0]; if (symfile_objfile != NULL) { - struct section_offsets *offsets - = solib_aix_get_section_offsets (symfile_objfile, exec_info); - struct cleanup *cleanup = make_cleanup (xfree, offsets); + gdb::unique_xmalloc_ptr offsets + = solib_aix_get_section_offsets (symfile_objfile, &exec_info); - objfile_relocate (symfile_objfile, offsets); - do_cleanups (cleanup); + objfile_relocate (symfile_objfile, offsets.get ()); } } @@ -528,29 +483,29 @@ static struct so_list * solib_aix_current_sos (void) { struct so_list *start = NULL, *last = NULL; - VEC (lm_info_aix_p) *library_list; - lm_info_aix *info; int ix; - library_list = solib_aix_get_library_list (current_inferior (), NULL); - if (library_list == NULL) + gdb::optional> &library_list + = solib_aix_get_library_list (current_inferior (), NULL); + if (!library_list.has_value ()) return NULL; /* Build a struct so_list for each entry on the list. We skip the first entry, since this is the entry corresponding to the main executable, not a shared library. */ - for (ix = 1; VEC_iterate (lm_info_aix_p, library_list, ix, info); ix++) + for (ix = 1; ix < library_list->size (); ix++) { struct so_list *new_solib = XCNEW (struct so_list); std::string so_name; - if (info->member_name.empty ()) + lm_info_aix &info = (*library_list)[ix]; + if (info.member_name.empty ()) { - /* INFO->FILENAME is probably not an archive, but rather + /* INFO.FILENAME is probably not an archive, but rather a shared object. Unusual, but it should be possible to link a program against a shared object directory, without having to put it in an archive first. */ - so_name = info->filename; + so_name = info.filename; } else { @@ -558,15 +513,15 @@ solib_aix_current_sos (void) is a member of an archive. Create a synthetic so_name that follows the same convention as AIX's ldd tool (Eg: "/lib/libc.a(shr.o)"). */ - so_name = string_printf ("%s(%s)", info->filename.c_str (), - info->member_name.c_str ()); + so_name = string_printf ("%s(%s)", info.filename.c_str (), + info.member_name.c_str ()); } strncpy (new_solib->so_original_name, so_name.c_str (), SO_NAME_MAX_PATH_SIZE - 1); new_solib->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; memcpy (new_solib->so_name, new_solib->so_original_name, SO_NAME_MAX_PATH_SIZE); - new_solib->lm_info = new lm_info_aix (*info); + new_solib->lm_info = new lm_info_aix (info); /* Add it to the list. */ if (!start) @@ -600,7 +555,7 @@ solib_aix_in_dynsym_resolve_code (CORE_ADDR pc) /* Implement the "bfd_open" target_so_ops method. */ static gdb_bfd_ref_ptr -solib_aix_bfd_open (char *pathname) +solib_aix_bfd_open (const char *pathname) { /* The pathname is actually a synthetic filename with the following form: "/path/to/sharedlib(member.o)" (double-quotes excluded). @@ -609,10 +564,9 @@ solib_aix_bfd_open (char *pathname) FIXME: This is a little hacky. Perhaps we should provide access to the solib's lm_info here? */ const int path_len = strlen (pathname); - char *sep; + const char *sep; int filename_len; int found_file; - char *found_pathname; if (pathname[path_len - 1] != ')') return solib_bfd_open (pathname); @@ -636,10 +590,12 @@ solib_aix_bfd_open (char *pathname) /* Calling solib_find makes certain that sysroot path is set properly if program has a dependency on .a archive and sysroot is set via set sysroot command. */ - found_pathname = solib_find (filename.c_str (), &found_file); + gdb::unique_xmalloc_ptr found_pathname + = solib_find (filename.c_str (), &found_file); if (found_pathname == NULL) perror_with_name (pathname); - gdb_bfd_ref_ptr archive_bfd (solib_bfd_fopen (found_pathname, found_file)); + gdb_bfd_ref_ptr archive_bfd (solib_bfd_fopen (found_pathname.get (), + found_file)); if (archive_bfd == NULL) { warning (_("Could not open `%s' as an executable file: %s"), @@ -755,7 +711,7 @@ solib_aix_normal_stop_observer (struct bpstats *unused_1, int unused_2) /* The inferior execution has been resumed, and it just stopped again. This means that the list of shared libraries may have evolved. Reset our cached value. */ - solib_aix_free_library_list (&data->library_list); + data->library_list.reset (); } /* Implements the "show debug aix-solib" command. */ @@ -786,9 +742,7 @@ _initialize_solib_aix (void) = solib_aix_in_dynsym_resolve_code; solib_aix_so_ops.bfd_open = solib_aix_bfd_open; - solib_aix_inferior_data_handle = register_inferior_data (); - - observer_attach_normal_stop (solib_aix_normal_stop_observer); + gdb::observers::normal_stop.attach (solib_aix_normal_stop_observer); /* Debug this file's internals. */ add_setshow_boolean_cmd ("aix-solib", class_maintenance,