X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fsolib-aix.c;h=ab4f36262903ed2d2c7fa3de2c81d039a06ae3dd;hb=739b5c9c778dee9e2f54d864f83a81ecb0639535;hp=8f335f6a76c3649fc342bc15dc4bc870d3496dea;hpb=41bf6acad7b02f67240f4cf84f066078f9ed7116;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/solib-aix.c b/gdb/solib-aix.c index 8f335f6a76..ab4f362629 100644 --- a/gdb/solib-aix.c +++ b/gdb/solib-aix.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2013-2014 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 "common/scope-exit.h" /* Variable controlling the output of the debugging traces for this module. */ @@ -33,58 +34,33 @@ static int solib_aix_debug; /* Our private data in struct so_list. */ -struct lm_info +struct lm_info_aix : public lm_info_base { /* The name of the file mapped by the loader. Apart from the entry for the main executable, this is usually a shared library (which, on AIX, is an archive library file, created using the "ar" command). */ - char *filename; + std::string filename; /* The name of the shared object file with the actual dynamic - loading dependency. This may be NULL (Eg. main executable). */ - char *member_name; + loading dependency. This may be empty (Eg. main executable). */ + std::string member_name; /* The address in inferior memory where the text section got mapped. */ - CORE_ADDR text_addr; + CORE_ADDR text_addr = 0; /* The size of the text section, obtained via the loader data. */ - ULONGEST text_size; + ULONGEST text_size = 0; /* The address in inferior memory where the data section got mapped. */ - CORE_ADDR data_addr; + CORE_ADDR data_addr = 0; /* The size of the data section, obtained via the loader data. */ - ULONGEST data_size; + ULONGEST data_size = 0; }; -typedef struct lm_info *lm_info_p; -DEF_VEC_P(lm_info_p); - -/* Return a deep copy of the given struct lm_info object. */ - -static struct lm_info * -solib_aix_new_lm_info (struct lm_info *info) -{ - struct lm_info *result = xmalloc (sizeof (struct lm_info)); - - memcpy (result, info, sizeof (struct lm_info)); - result->filename = xstrdup (info->filename); - if (info->member_name != NULL) - result->member_name = xstrdup (info->member_name); - - return result; -} - -/* Free the memory allocated for the given lm_info. */ - -static void -solib_aix_xfree_lm_info (struct lm_info *info) -{ - xfree (info->filename); - xfree (info->member_name); - xfree (info); -} +typedef lm_info_aix *lm_info_aix_p; +DEF_VEC_P(lm_info_aix_p); /* This module's per-inferior data. */ @@ -98,7 +74,7 @@ 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_p) *library_list; + VEC (lm_info_aix_p) *library_list; }; /* Key to our per-inferior data. */ @@ -112,7 +88,8 @@ get_solib_aix_inferior_data (struct inferior *inf) { struct solib_aix_inferior_data *data; - data = inferior_data (inf, solib_aix_inferior_data_handle); + data = ((struct solib_aix_inferior_data *) + inferior_data (inf, solib_aix_inferior_data_handle)); if (data == NULL) { data = XCNEW (struct solib_aix_inferior_data); @@ -126,7 +103,7 @@ get_solib_aix_inferior_data (struct inferior *inf) /* Dummy implementation if XML support is not compiled in. */ -static VEC (lm_info_p) * +static VEC (lm_info_aix_p) * solib_aix_parse_libraries (const char *library) { static int have_warned; @@ -158,32 +135,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_p) **list = user_data; - struct lm_info *item = XCNEW (struct lm_info); + VEC (lm_info_aix_p) **list = (VEC (lm_info_aix_p) **) user_data; + lm_info_aix *item = new lm_info_aix; struct gdb_xml_value *attr; attr = xml_find_attribute (attributes, "name"); - item->filename = xstrdup (attr->value); + item->filename = xstrdup ((const char *) attr->value.get ()); attr = xml_find_attribute (attributes, "member"); if (attr != NULL) - item->member_name = xstrdup (attr->value); + item->member_name = xstrdup ((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_p, *list, item); + VEC_safe_push (lm_info_aix_p, *list, item); } /* Handle the start of a element. */ @@ -191,9 +168,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 = 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, @@ -206,16 +185,17 @@ library_list_start_list (struct gdb_xml_parser *parser, static void solib_aix_free_library_list (void *p) { - VEC (lm_info_p) **result = p; - struct lm_info *info; + 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_p, *result, ix, info); ix++) - solib_aix_xfree_lm_info (info); - VEC_free (lm_info_p, *result); + for (ix = 0; VEC_iterate (lm_info_aix_p, *result, ix, info); ix++) + delete info; + + VEC_free (lm_info_aix_p, *result); *result = NULL; } @@ -255,26 +235,27 @@ 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_p vector. + and return an lm_info_aix_p vector. Return NULL if the parsing failed. */ -static VEC (lm_info_p) * +static VEC (lm_info_aix_p) * solib_aix_parse_libraries (const char *library) { - VEC (lm_info_p) *result = NULL; - struct cleanup *back_to = make_cleanup (solib_aix_free_library_list, - &result); + VEC (lm_info_aix_p) *result = NULL; + auto cleanup = make_scope_exit ([&] () + { + solib_aix_free_library_list (&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); + cleanup.release (); return result; } - do_cleanups (back_to); return NULL; } @@ -290,43 +271,38 @@ 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_p) * +static VEC (lm_info_aix_p) * solib_aix_get_library_list (struct inferior *inf, const char *warning_msg) { struct solib_aix_inferior_data *data; - char *library_document; - struct cleanup *cleanup; /* If already computed, return the cached value. */ data = get_solib_aix_inferior_data (inf); if (data->library_list != NULL) return data->library_list; - library_document = target_read_stralloc (¤t_target, - TARGET_OBJECT_LIBRARIES_AIX, - NULL); - if (library_document == NULL && warning_msg != NULL) + gdb::optional library_document + = target_read_stralloc (current_top_target (), TARGET_OBJECT_LIBRARIES_AIX, + NULL); + if (!library_document && warning_msg != NULL) { warning (_("%s (failed to read TARGET_OBJECT_LIBRARIES_AIX)"), warning_msg); return NULL; } - cleanup = make_cleanup (xfree, library_document); if (solib_aix_debug) fprintf_unfiltered (gdb_stdlog, "DEBUG: TARGET_OBJECT_LIBRARIES_AIX = \n%s\n", - library_document); + library_document->data ()); - data->library_list = solib_aix_parse_libraries (library_document); + data->library_list = solib_aix_parse_libraries (library_document->data ()); if (data->library_list == NULL && warning_msg != NULL) { warning (_("%s (missing XML support?)"), warning_msg); - do_cleanups (cleanup); return NULL; } - do_cleanups (cleanup); return data->library_list; } @@ -393,7 +369,7 @@ solib_aix_relocate_section_addresses (struct so_list *so, struct bfd_section *bfd_sect = sec->the_bfd_section; bfd *abfd = bfd_sect->owner; const char *section_name = bfd_section_name (abfd, bfd_sect); - struct lm_info *info = so->lm_info; + lm_info_aix *info = (lm_info_aix *) so->lm_info; if (strcmp (section_name, ".text") == 0) { @@ -442,10 +418,13 @@ solib_aix_relocate_section_addresses (struct so_list *so, static void solib_aix_free_so (struct so_list *so) { + lm_info_aix *li = (lm_info_aix *) so->lm_info; + if (solib_aix_debug) fprintf_unfiltered (gdb_stdlog, "DEBUG: solib_aix_free_so (%s)\n", so->so_name); - solib_aix_xfree_lm_info (so->lm_info); + + delete li; } /* Implement the "clear_solib" target_so_ops method. */ @@ -462,15 +441,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, - struct lm_info *info) + lm_info_aix *info) { - struct section_offsets *offsets; bfd *abfd = objfile->obfd; - int i; - offsets = XCALLOC (objfile->num_sections, struct section_offsets); + gdb::unique_xmalloc_ptr offsets + (XCNEWVEC (struct section_offsets, objfile->num_sections)); /* .text */ @@ -519,8 +497,8 @@ static void solib_aix_solib_create_inferior_hook (int from_tty) { const char *warning_msg = "unable to relocate main executable"; - VEC (lm_info_p) *library_list; - struct lm_info *exec_info; + VEC (lm_info_aix_p) *library_list; + lm_info_aix *exec_info; /* We need to relocate the main executable... */ @@ -529,41 +507,31 @@ solib_aix_solib_create_inferior_hook (int from_tty) if (library_list == NULL) return; /* Warning already printed. */ - if (VEC_length (lm_info_p, library_list) < 1) + if (VEC_length (lm_info_aix_p, library_list) < 1) { warning (_("unable to relocate main executable (no info from loader)")); return; } - exec_info = VEC_index (lm_info_p, library_list, 0); + exec_info = VEC_index (lm_info_aix_p, library_list, 0); if (symfile_objfile != NULL) { - struct section_offsets *offsets + gdb::unique_xmalloc_ptr offsets = solib_aix_get_section_offsets (symfile_objfile, exec_info); - struct cleanup *cleanup = make_cleanup (xfree, offsets); - objfile_relocate (symfile_objfile, offsets); - do_cleanups (cleanup); + objfile_relocate (symfile_objfile, offsets.get ()); } } -/* Implement the "special_symbol_handling" target_so_ops method. */ - -static void -solib_aix_special_symbol_handling (void) -{ - /* Nothing needed. */ -} - /* Implement the "current_sos" target_so_ops method. */ static struct so_list * solib_aix_current_sos (void) { struct so_list *start = NULL, *last = NULL; - VEC (lm_info_p) *library_list; - struct lm_info *info; + VEC (lm_info_aix_p) *library_list; + lm_info_aix *info; int ix; library_list = solib_aix_get_library_list (current_inferior (), NULL); @@ -573,18 +541,18 @@ solib_aix_current_sos (void) /* 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_p, library_list, ix, info); ix++) + for (ix = 1; VEC_iterate (lm_info_aix_p, library_list, ix, info); ix++) { struct so_list *new_solib = XCNEW (struct so_list); - char *so_name; + std::string so_name; - if (info->member_name == NULL) + if (info->member_name.empty ()) { /* 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 = xstrdup (info->filename); + so_name = info->filename; } else { @@ -592,14 +560,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 = xstrprintf ("%s(%s)", info->filename, info->member_name); + so_name = string_printf ("%s(%s)", info->filename.c_str (), + info->member_name.c_str ()); } - strncpy (new_solib->so_original_name, so_name, + 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 = solib_aix_new_lm_info (info); + new_solib->lm_info = new lm_info_aix (*info); /* Add it to the list. */ if (!start) @@ -617,7 +586,7 @@ solib_aix_current_sos (void) /* Implement the "open_symbol_file_object" target_so_ops method. */ static int -solib_aix_open_symbol_file_object (void *from_ttyp) +solib_aix_open_symbol_file_object (int from_tty) { return 0; } @@ -632,8 +601,8 @@ solib_aix_in_dynsym_resolve_code (CORE_ADDR pc) /* Implement the "bfd_open" target_so_ops method. */ -static bfd * -solib_aix_bfd_open (char *pathname) +static gdb_bfd_ref_ptr +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). @@ -642,12 +611,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; - char *filename; + const char *sep; int filename_len; - char *member_name; - bfd *archive_bfd, *object_bfd; - struct cleanup *cleanup; + int found_file; if (pathname[path_len - 1] != ')') return solib_bfd_open (pathname); @@ -664,75 +630,71 @@ solib_aix_bfd_open (char *pathname) } filename_len = sep - pathname; - filename = xstrprintf ("%.*s", filename_len, pathname); - cleanup = make_cleanup (xfree, filename); - member_name = xstrprintf ("%.*s", path_len - filename_len - 2, sep + 1); - make_cleanup (xfree, member_name); - - archive_bfd = gdb_bfd_open (filename, gnutarget, -1); + std::string filename (string_printf ("%.*s", filename_len, pathname)); + std::string member_name (string_printf ("%.*s", path_len - filename_len - 2, + sep + 1)); + + /* 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. */ + 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.get (), + found_file)); if (archive_bfd == NULL) { warning (_("Could not open `%s' as an executable file: %s"), - filename, bfd_errmsg (bfd_get_error ())); - do_cleanups (cleanup); + filename.c_str (), bfd_errmsg (bfd_get_error ())); return NULL; } - if (bfd_check_format (archive_bfd, bfd_object)) - { - do_cleanups (cleanup); - return archive_bfd; - } + if (bfd_check_format (archive_bfd.get (), bfd_object)) + return archive_bfd; - if (! bfd_check_format (archive_bfd, bfd_archive)) + if (! bfd_check_format (archive_bfd.get (), bfd_archive)) { warning (_("\"%s\": not in executable format: %s."), - filename, bfd_errmsg (bfd_get_error ())); - gdb_bfd_unref (archive_bfd); - do_cleanups (cleanup); + filename.c_str (), bfd_errmsg (bfd_get_error ())); return NULL; } - object_bfd = gdb_bfd_openr_next_archived_file (archive_bfd, NULL); + gdb_bfd_ref_ptr object_bfd + (gdb_bfd_openr_next_archived_file (archive_bfd.get (), NULL)); while (object_bfd != NULL) { - bfd *next; - - if (strcmp (member_name, object_bfd->filename) == 0) + if (member_name == object_bfd->filename) break; - next = gdb_bfd_openr_next_archived_file (archive_bfd, object_bfd); - gdb_bfd_unref (object_bfd); - object_bfd = next; + object_bfd = gdb_bfd_openr_next_archived_file (archive_bfd.get (), + object_bfd.get ()); } if (object_bfd == NULL) { - warning (_("\"%s\": member \"%s\" missing."), filename, member_name); - gdb_bfd_unref (archive_bfd); - do_cleanups (cleanup); + warning (_("\"%s\": member \"%s\" missing."), filename.c_str (), + member_name.c_str ()); return NULL; } - if (! bfd_check_format (object_bfd, bfd_object)) + if (! bfd_check_format (object_bfd.get (), bfd_object)) { warning (_("%s(%s): not in object format: %s."), - filename, member_name, bfd_errmsg (bfd_get_error ())); - gdb_bfd_unref (archive_bfd); - gdb_bfd_unref (object_bfd); - do_cleanups (cleanup); + filename.c_str (), member_name.c_str (), + bfd_errmsg (bfd_get_error ())); return NULL; } - /* Override the returned bfd's name with our synthetic name in order - to allow commands listing all shared libraries to display that - synthetic name. Otherwise, we would only be displaying the name - of the archive member object. */ - xfree (bfd_get_filename (object_bfd)); - object_bfd->filename = xstrdup (pathname); + /* Override the returned bfd's name with the name returned from solib_find + along with appended parenthesized member name in order to allow commands + listing all shared libraries to display. Otherwise, we would only be + displaying the name of the archive member object. */ + xfree (bfd_get_filename (object_bfd.get ())); + object_bfd->filename = xstrprintf ("%s%s", + bfd_get_filename (archive_bfd.get ()), + sep); - gdb_bfd_unref (archive_bfd); - do_cleanups (cleanup); return object_bfd; } @@ -811,9 +773,6 @@ show_solib_aix_debug (struct ui_file *file, int from_tty, /* The target_so_ops for AIX targets. */ struct target_so_ops solib_aix_so_ops; -/* -Wmissing-prototypes */ -extern initialize_file_ftype _initialize_solib_aix; - void _initialize_solib_aix (void) { @@ -823,8 +782,6 @@ _initialize_solib_aix (void) solib_aix_so_ops.clear_solib = solib_aix_clear_solib; solib_aix_so_ops.solib_create_inferior_hook = solib_aix_solib_create_inferior_hook; - solib_aix_so_ops.special_symbol_handling - = solib_aix_special_symbol_handling; solib_aix_so_ops.current_sos = solib_aix_current_sos; solib_aix_so_ops.open_symbol_file_object = solib_aix_open_symbol_file_object; @@ -834,7 +791,7 @@ _initialize_solib_aix (void) 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,