* [RFA 0/8] C++-ification series #5 @ 2016-11-29 5:06 Tom Tromey 2016-11-29 5:06 ` [RFA 8/8] Add constructor and destructor to demangle_parse_info Tom Tromey ` (7 more replies) 0 siblings, 8 replies; 50+ messages in thread From: Tom Tromey @ 2016-11-29 5:06 UTC (permalink / raw) To: gdb-patches This series holds a few more C++-ification changes: * Generalizes gdbpy_ref to an "externally refcounted" smart pointer, with the behavior controlled by a policy class. This is then used to convert BFD refcounting. * Adds a class to optionally unlink a file in the destructor. * Adds a class to call value_free_to_mark in the destructor. * Adds a class to optionally discard psymtabs in the destructor. * Fix up one more cleanup in the Python code that I missed. * Change demangle_parse_info to have a constructor and destructor and use unique_ptr for managing these. gdb is getting relatively close to no cleanups in the Python layer after this series (25 hits for "make_cleanup"). Please review. I'm running this through the buildbot and will comment when that is done. Note that the BFD refcounting change is a bit tricky. It probably should have extra testing -- I tested it locally, and there's the buildbot, and additionally I built it locally using the mingw32 cross toolchain; but even so it's possible that there are paths that weren't updated. These will manifest as build failures on some other host. One thing that would be nice is if there were a way to build gdb such that all the nat* code were built. This would at least catch compiler errors. I think it could be done by having stub implementations of any platform-specific APIs that are used (just a #define for each would probably suffice), and by arranging for only the real nat*.c file's initialization function to be called at startup. Tom ^ permalink raw reply [flat|nested] 50+ messages in thread
* [RFA 8/8] Add constructor and destructor to demangle_parse_info 2016-11-29 5:06 [RFA 0/8] C++-ification series #5 Tom Tromey @ 2016-11-29 5:06 ` Tom Tromey 2016-12-02 15:04 ` Pedro Alves 2016-11-29 5:06 ` [RFA 7/8] Use unique_xmalloc_ptr in execute_gdb_command Tom Tromey ` (6 subsequent siblings) 7 siblings, 1 reply; 50+ messages in thread From: Tom Tromey @ 2016-11-29 5:06 UTC (permalink / raw) To: gdb-patches; +Cc: Tom Tromey This adds a constructor and destructor to demangle_parse_info, and then changes all the users to use them. This removes make_cleanup_cp_demangled_name_parse_free and its single use. 2016-11-28 Tom Tromey <tom@tromey.com> * python/py-type.c (typy_legacy_template_argument): Update. * cp-support.h (struct demangle_parse_info) (demangle_parse_info, ~demangle_parse_info): Declare new members. (cp_demangled_name_to_comp): Return unique_ptr. (cp_demangled_name_parse_free) (make_cleanup_cp_demangled_name_parse_free) (cp_new_demangle_parse_info): Remove. * cp-support.c (do_demangled_name_parse_free_cleanup) (make_cleanup_cp_demangled_name_parse_free): Remove. (inspect_type, cp_canonicalize_string_full) (cp_canonicalize_string): Update. (mangled_name_to_comp): Change return type. (cp_class_name_from_physname, method_name_from_physname) (cp_func_name, cp_remove_params): Update. * cp-name-parser.y (demangle_parse_info): New constructor, from cp_new_demangle_parse_info. (~demangle_parse_info): New destructor, from cp_demangled_name_parse_free. (cp_merge_demangle_parse_infos): Update. (cp_demangled_name_to_comp): Change return type. --- gdb/ChangeLog | 23 +++++++++++++++++++++++ gdb/cp-name-parser.y | 39 ++++++++++----------------------------- gdb/cp-support.c | 52 +++++++++++++--------------------------------------- gdb/cp-support.h | 11 +++++------ gdb/python/py-type.c | 6 +----- 5 files changed, 52 insertions(+), 79 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index d0d2ef6..a117997 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,28 @@ 2016-11-28 Tom Tromey <tom@tromey.com> + * python/py-type.c (typy_legacy_template_argument): Update. + * cp-support.h (struct demangle_parse_info) (demangle_parse_info, + ~demangle_parse_info): Declare new members. + (cp_demangled_name_to_comp): Return unique_ptr. + (cp_demangled_name_parse_free) + (make_cleanup_cp_demangled_name_parse_free) + (cp_new_demangle_parse_info): Remove. + * cp-support.c (do_demangled_name_parse_free_cleanup) + (make_cleanup_cp_demangled_name_parse_free): Remove. + (inspect_type, cp_canonicalize_string_full) + (cp_canonicalize_string): Update. + (mangled_name_to_comp): Change return type. + (cp_class_name_from_physname, method_name_from_physname) + (cp_func_name, cp_remove_params): Update. + * cp-name-parser.y (demangle_parse_info): New constructor, from + cp_new_demangle_parse_info. + (~demangle_parse_info): New destructor, from + cp_demangled_name_parse_free. + (cp_merge_demangle_parse_infos): Update. + (cp_demangled_name_to_comp): Change return type. + +2016-11-28 Tom Tromey <tom@tromey.com> + * python/python.c (execute_gdb_command): Use unique_xmalloc_ptr. 2016-11-28 Tom Tromey <tom@tromey.com> diff --git a/gdb/cp-name-parser.y b/gdb/cp-name-parser.y index c6a5c34..6f281ab 100644 --- a/gdb/cp-name-parser.y +++ b/gdb/cp-name-parser.y @@ -1999,29 +1999,19 @@ cp_comp_to_string (struct demangle_component *result, int estimated_len) &err); } -/* A convenience function to allocate and initialize a new struct - demangled_parse_info. */ +/* Constructor for demangle_parse_info. */ -struct demangle_parse_info * -cp_new_demangle_parse_info (void) +demangle_parse_info::demangle_parse_info () +: info (NULL), + tree (NULL) { - struct demangle_parse_info *info; - - info = XNEW (struct demangle_parse_info); - info->info = NULL; - info->tree = NULL; - obstack_init (&info->obstack); - - return info; + obstack_init (&obstack); } -/* Free any memory associated with the given PARSE_INFO. */ +/* Destructor for demangle_parse_info. */ -void -cp_demangled_name_parse_free (struct demangle_parse_info *parse_info) +demangle_parse_info::~demangle_parse_info () { - struct demangle_info *info = parse_info->info; - /* Free any allocated chunks of memory for the parse. */ while (info != NULL) { @@ -2032,15 +2022,11 @@ cp_demangled_name_parse_free (struct demangle_parse_info *parse_info) } /* Free any memory allocated during typedef replacement. */ - obstack_free (&parse_info->obstack, NULL); - - /* Free the parser info. */ - free (parse_info); + obstack_free (&obstack, NULL); } /* Merge the two parse trees given by DEST and SRC. The parse tree in SRC is attached to DEST at the node represented by TARGET. - SRC is then freed. NOTE 1: Since there is no API to merge obstacks, this function does even attempt to try it. Fortunately, we do not (yet?) need this ability. @@ -2067,9 +2053,6 @@ cp_merge_demangle_parse_infos (struct demangle_parse_info *dest, /* Clear the (pointer to) SRC's parse data so that it is not freed when cp_demangled_parse_info_free is called. */ src->info = NULL; - - /* Free SRC. */ - cp_demangled_name_parse_free (src); } /* Convert a demangled name to a demangle_component tree. On success, @@ -2078,11 +2061,10 @@ cp_merge_demangle_parse_infos (struct demangle_parse_info *dest, returned, and an error message will be set in *ERRMSG (which does not need to be freed). */ -struct demangle_parse_info * +struct std::unique_ptr<demangle_parse_info> cp_demangled_name_to_comp (const char *demangled_name, const char **errmsg) { static char errbuf[60]; - struct demangle_parse_info *result; prev_lexptr = lexptr = demangled_name; error_lexptr = NULL; @@ -2090,7 +2072,7 @@ cp_demangled_name_to_comp (const char *demangled_name, const char **errmsg) demangle_info = allocate_info (); - result = cp_new_demangle_parse_info (); + std::unique_ptr<demangle_parse_info> result (new demangle_parse_info); result->info = demangle_info; if (yyparse ()) @@ -2102,7 +2084,6 @@ cp_demangled_name_to_comp (const char *demangled_name, const char **errmsg) strcat (errbuf, "'"); *errmsg = errbuf; } - cp_demangled_name_parse_free (result); return NULL; } diff --git a/gdb/cp-support.c b/gdb/cp-support.c index d409b0b..a6edb3c 100644 --- a/gdb/cp-support.c +++ b/gdb/cp-support.c @@ -95,24 +95,6 @@ copy_string_to_obstack (struct obstack *obstack, const char *string, return (char *) obstack_copy (obstack, string, *len); } -/* A cleanup wrapper for cp_demangled_name_parse_free. */ - -static void -do_demangled_name_parse_free_cleanup (void *data) -{ - struct demangle_parse_info *info = (struct demangle_parse_info *) data; - - cp_demangled_name_parse_free (info); -} - -/* Create a cleanup for C++ name parsing. */ - -struct cleanup * -make_cleanup_cp_demangled_name_parse_free (struct demangle_parse_info *info) -{ - return make_cleanup (do_demangled_name_parse_free_cleanup, info); -} - /* Return 1 if STRING is clearly already in canonical form. This function is conservative; things which it does not recognize are assumed to be non-canonical, and the parser will sort them out @@ -209,7 +191,7 @@ inspect_type (struct demangle_parse_info *info, long len; int is_anon; struct type *type; - struct demangle_parse_info *i; + std::unique_ptr<demangle_parse_info> i; struct ui_file *buf; /* Get the real type of the typedef. */ @@ -272,7 +254,7 @@ inspect_type (struct demangle_parse_info *info, if (i != NULL) { /* Merge the two trees. */ - cp_merge_demangle_parse_infos (info, ret_comp, i); + cp_merge_demangle_parse_infos (info, ret_comp, i.get ()); /* Replace any newly introduced typedefs -- but not if the type is anonymous (that would lead to infinite @@ -540,22 +522,19 @@ cp_canonicalize_string_full (const char *string, { std::string ret; unsigned int estimated_len; - struct demangle_parse_info *info; + std::unique_ptr<demangle_parse_info> info; estimated_len = strlen (string) * 2; info = cp_demangled_name_to_comp (string, NULL); if (info != NULL) { /* Replace all the typedefs in the tree. */ - replace_typedefs (info, info->tree, finder, data); + replace_typedefs (info.get (), info->tree, finder, data); /* Convert the tree back into a string. */ ret = cp_comp_to_string (info->tree, estimated_len); gdb_assert (!ret.empty ()); - /* Free the parse information. */ - cp_demangled_name_parse_free (info); - /* Finally, compare the original string with the computed name, returning NULL if they are the same. */ if (ret == string) @@ -581,7 +560,7 @@ cp_canonicalize_string_no_typedefs (const char *string) std::string cp_canonicalize_string (const char *string) { - struct demangle_parse_info *info; + std::unique_ptr<demangle_parse_info> info; unsigned int estimated_len; if (cp_already_canonical (string)) @@ -593,7 +572,6 @@ cp_canonicalize_string (const char *string) estimated_len = strlen (string) * 2; std::string ret = cp_comp_to_string (info->tree, estimated_len); - cp_demangled_name_parse_free (info); if (ret.empty ()) { @@ -614,12 +592,11 @@ cp_canonicalize_string (const char *string) freed when finished with the tree, or NULL if none was needed. OPTIONS will be passed to the demangler. */ -static struct demangle_parse_info * +static std::unique_ptr<demangle_parse_info> mangled_name_to_comp (const char *mangled_name, int options, void **memory, char **demangled_p) { char *demangled_name; - struct demangle_parse_info *info; /* If it looks like a v3 mangled name, then try to go directly to trees. */ @@ -631,7 +608,7 @@ mangled_name_to_comp (const char *mangled_name, int options, options, memory); if (ret) { - info = cp_new_demangle_parse_info (); + std::unique_ptr<demangle_parse_info> info (new demangle_parse_info); info->tree = ret; *demangled_p = NULL; return info; @@ -646,7 +623,8 @@ mangled_name_to_comp (const char *mangled_name, int options, /* If we could demangle the name, parse it to build the component tree. */ - info = cp_demangled_name_to_comp (demangled_name, NULL); + std::unique_ptr<demangle_parse_info> info + (cp_demangled_name_to_comp (demangled_name, NULL)); if (info == NULL) { @@ -666,7 +644,7 @@ cp_class_name_from_physname (const char *physname) void *storage = NULL; char *demangled_name = NULL, *ret; struct demangle_component *ret_comp, *prev_comp, *cur_comp; - struct demangle_parse_info *info; + std::unique_ptr<demangle_parse_info> info; int done; info = mangled_name_to_comp (physname, DMGL_ANSI, @@ -745,7 +723,6 @@ cp_class_name_from_physname (const char *physname) xfree (storage); xfree (demangled_name); - cp_demangled_name_parse_free (info); return ret; } @@ -815,7 +792,7 @@ method_name_from_physname (const char *physname) void *storage = NULL; char *demangled_name = NULL, *ret; struct demangle_component *ret_comp; - struct demangle_parse_info *info; + std::unique_ptr<demangle_parse_info> info; info = mangled_name_to_comp (physname, DMGL_ANSI, &storage, &demangled_name); @@ -832,7 +809,6 @@ method_name_from_physname (const char *physname) xfree (storage); xfree (demangled_name); - cp_demangled_name_parse_free (info); return ret; } @@ -847,7 +823,7 @@ cp_func_name (const char *full_name) { char *ret; struct demangle_component *ret_comp; - struct demangle_parse_info *info; + std::unique_ptr<demangle_parse_info> info; info = cp_demangled_name_to_comp (full_name, NULL); if (!info) @@ -859,7 +835,6 @@ cp_func_name (const char *full_name) if (ret_comp != NULL) ret = cp_comp_to_string (ret_comp, 10); - cp_demangled_name_parse_free (info); return ret; } @@ -872,7 +847,7 @@ cp_remove_params (const char *demangled_name) { int done = 0; struct demangle_component *ret_comp; - struct demangle_parse_info *info; + std::unique_ptr<demangle_parse_info> info; char *ret = NULL; if (demangled_name == NULL) @@ -905,7 +880,6 @@ cp_remove_params (const char *demangled_name) if (ret_comp->type == DEMANGLE_COMPONENT_TYPED_NAME) ret = cp_comp_to_string (d_left (ret_comp), 10); - cp_demangled_name_parse_free (info); return ret; } diff --git a/gdb/cp-support.h b/gdb/cp-support.h index ca7a7d4..ffccded 100644 --- a/gdb/cp-support.h +++ b/gdb/cp-support.h @@ -58,6 +58,10 @@ struct demangle_parse_info /* Any temporary memory used during typedef replacement. */ struct obstack obstack; + + demangle_parse_info (); + + ~demangle_parse_info (); }; @@ -135,21 +139,16 @@ struct type *cp_find_type_baseclass_by_name (struct type *parent_type, /* Functions from cp-name-parser.y. */ -extern struct demangle_parse_info *cp_demangled_name_to_comp +extern std::unique_ptr<demangle_parse_info> cp_demangled_name_to_comp (const char *demangled_name, const char **errmsg); extern char *cp_comp_to_string (struct demangle_component *result, int estimated_len); -extern void cp_demangled_name_parse_free (struct demangle_parse_info *); -extern struct cleanup *make_cleanup_cp_demangled_name_parse_free - (struct demangle_parse_info *); extern void cp_merge_demangle_parse_infos (struct demangle_parse_info *, struct demangle_component *, struct demangle_parse_info *); -extern struct demangle_parse_info *cp_new_demangle_parse_info (void); - /* The list of "maint cplus" commands. */ extern struct cmd_list_element *maint_cplus_cmd_list; diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c index 5139c92..64b59f1 100644 --- a/gdb/python/py-type.c +++ b/gdb/python/py-type.c @@ -832,7 +832,7 @@ typy_legacy_template_argument (struct type *type, const struct block *block, { int i; struct demangle_component *demangled; - struct demangle_parse_info *info = NULL; + std::unique_ptr<demangle_parse_info> info; const char *err; struct type *argtype; struct cleanup *cleanup; @@ -860,7 +860,6 @@ typy_legacy_template_argument (struct type *type, const struct block *block, return NULL; } demangled = info->tree; - cleanup = make_cleanup_cp_demangled_name_parse_free (info); /* Strip off component names. */ while (demangled->type == DEMANGLE_COMPONENT_QUAL_NAME @@ -869,7 +868,6 @@ typy_legacy_template_argument (struct type *type, const struct block *block, if (demangled->type != DEMANGLE_COMPONENT_TEMPLATE) { - do_cleanups (cleanup); PyErr_SetString (PyExc_RuntimeError, _("Type is not a template.")); return NULL; } @@ -882,14 +880,12 @@ typy_legacy_template_argument (struct type *type, const struct block *block, if (! demangled) { - do_cleanups (cleanup); PyErr_Format (PyExc_RuntimeError, _("No argument %d in template."), argno); return NULL; } argtype = typy_lookup_type (demangled->u.s_binary.left, block); - do_cleanups (cleanup); if (! argtype) return NULL; -- 2.7.4 ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 8/8] Add constructor and destructor to demangle_parse_info 2016-11-29 5:06 ` [RFA 8/8] Add constructor and destructor to demangle_parse_info Tom Tromey @ 2016-12-02 15:04 ` Pedro Alves 2016-12-13 13:50 ` Tom Tromey 0 siblings, 1 reply; 50+ messages in thread From: Pedro Alves @ 2016-12-02 15:04 UTC (permalink / raw) To: Tom Tromey, gdb-patches On 11/29/2016 05:05 AM, Tom Tromey wrote: > @@ -646,7 +623,8 @@ mangled_name_to_comp (const char *mangled_name, int options, > > /* If we could demangle the name, parse it to build the component > tree. */ > - info = cp_demangled_name_to_comp (demangled_name, NULL); > + std::unique_ptr<demangle_parse_info> info > + (cp_demangled_name_to_comp (demangled_name, NULL)); Style question: When initializing a unique_ptr from a function that returns a unique_ptr already, IMO, using = reads a little better over ()s, like: std::unique_ptr<demangle_parse_info> info = cp_demangled_name_to_comp (demangled_name, NULL); I.e., kind of like how you'd call make_unique with '=' instead of unique_ptr<T> foo (make_unique<T>()); which I've never seen. I wonder whether that's just me? > diff --git a/gdb/cp-support.h b/gdb/cp-support.h > index ca7a7d4..ffccded 100644 > --- a/gdb/cp-support.h > +++ b/gdb/cp-support.h > @@ -58,6 +58,10 @@ struct demangle_parse_info > > /* Any temporary memory used during typedef replacement. */ > struct obstack obstack; > + > + demangle_parse_info (); > + > + ~demangle_parse_info (); Put these before the data fields. Otherwise LGTM. Thanks, Pedro Alves ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 8/8] Add constructor and destructor to demangle_parse_info 2016-12-02 15:04 ` Pedro Alves @ 2016-12-13 13:50 ` Tom Tromey 0 siblings, 0 replies; 50+ messages in thread From: Tom Tromey @ 2016-12-13 13:50 UTC (permalink / raw) To: Pedro Alves; +Cc: Tom Tromey, gdb-patches >>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes: Pedro> When initializing a unique_ptr from a function that returns a Pedro> unique_ptr already, IMO, using = reads a little better Pedro> over ()s, like: Pedro> std::unique_ptr<demangle_parse_info> info Pedro> = cp_demangled_name_to_comp (demangled_name, NULL); Pedro> I.e., kind of like how you'd call make_unique with '=' instead Pedro> of Pedro> unique_ptr<T> foo (make_unique<T>()); Pedro> which I've never seen. Pedro> I wonder whether that's just me? I don't really have a preference either way. I made this change. >> + demangle_parse_info (); >> + >> + ~demangle_parse_info (); Pedro> Put these before the data fields. Done. Tom ^ permalink raw reply [flat|nested] 50+ messages in thread
* [RFA 7/8] Use unique_xmalloc_ptr in execute_gdb_command 2016-11-29 5:06 [RFA 0/8] C++-ification series #5 Tom Tromey 2016-11-29 5:06 ` [RFA 8/8] Add constructor and destructor to demangle_parse_info Tom Tromey @ 2016-11-29 5:06 ` Tom Tromey 2016-11-29 5:22 ` Tom Tromey 2016-12-02 14:49 ` Pedro Alves 2016-11-29 5:06 ` [RFA 1/8] Add gdb_ref_ptr.h Tom Tromey ` (5 subsequent siblings) 7 siblings, 2 replies; 50+ messages in thread From: Tom Tromey @ 2016-11-29 5:06 UTC (permalink / raw) To: gdb-patches; +Cc: Tom Tromey This replaces a cleanup in execute_gdb_command with an instance of unique_xmalloc_ptr. std::string was not used because execute_command and execute_command_to_string don't accept a "const char *" (in fact the reason for copying the string at all). 2016-11-28 Tom Tromey <tom@tromey.com> * python/python.c (execute_gdb_command): Use unique_xmalloc_ptr. --- gdb/ChangeLog | 4 ++++ gdb/python/python.c | 8 +++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index cf61306..d0d2ef6 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,9 @@ 2016-11-28 Tom Tromey <tom@tromey.com> + * python/python.c (execute_gdb_command): Use unique_xmalloc_ptr. + +2016-11-28 Tom Tromey <tom@tromey.com> + * value.h (value_freer::~value_freer): Call release. (value_freer::release): New method. * dwarf2loc.c (dwarf2_evaluate_loc_desc_full): Use value_freer. diff --git a/gdb/python/python.c b/gdb/python/python.c index 83b9805..83894a1 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -601,8 +601,7 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw) TRY { /* Copy the argument text in case the command modifies it. */ - char *copy = xstrdup (arg); - struct cleanup *cleanup = make_cleanup (xfree, copy); + gdb::unique_xmalloc_ptr<char> copy (xstrdup (arg)); struct interp *interp; scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0); @@ -616,10 +615,9 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw) prevent_dont_repeat (); if (to_string) - to_string_res = execute_command_to_string (copy, from_tty); + to_string_res = execute_command_to_string (copy.get (), from_tty); else - execute_command (copy, from_tty); - do_cleanups (cleanup); + execute_command (copy.get (), from_tty); } CATCH (except, RETURN_MASK_ALL) { -- 2.7.4 ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 7/8] Use unique_xmalloc_ptr in execute_gdb_command 2016-11-29 5:06 ` [RFA 7/8] Use unique_xmalloc_ptr in execute_gdb_command Tom Tromey @ 2016-11-29 5:22 ` Tom Tromey 2016-12-15 3:49 ` Tom Tromey 2016-12-02 14:49 ` Pedro Alves 1 sibling, 1 reply; 50+ messages in thread From: Tom Tromey @ 2016-11-29 5:22 UTC (permalink / raw) To: Tom Tromey; +Cc: gdb-patches >>>>> "Tom" == Tom Tromey <tom@tromey.com> writes: Tom> This replaces a cleanup in execute_gdb_command with an instance of Tom> unique_xmalloc_ptr. std::string was not used because execute_command Tom> and execute_command_to_string don't accept a "const char *" (in fact Tom> the reason for copying the string at all). To my surprise, this patch is broken. I must not have re-run the python tests locally after writing it :( The problem is that prevent_dont_repeat returns a cleanup, which is then left dangling after this patch. I'm looking into a fix. Meanwhile I think the rest of the series can still be considered. Tom ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 7/8] Use unique_xmalloc_ptr in execute_gdb_command 2016-11-29 5:22 ` Tom Tromey @ 2016-12-15 3:49 ` Tom Tromey 2016-12-20 17:48 ` Pedro Alves 0 siblings, 1 reply; 50+ messages in thread From: Tom Tromey @ 2016-12-15 3:49 UTC (permalink / raw) To: Tom Tromey; +Cc: gdb-patches >>>>> "Tom" == Tom Tromey <tom@tromey.com> writes: Tom> To my surprise, this patch is broken. Tom> I must not have re-run the python tests locally after writing it :( Tom> The problem is that prevent_dont_repeat returns a cleanup, which is then Tom> left dangling after this patch. Here's the updated patch. I ran this one through the buildbot. Tom commit 1a638a680bae42954d4ebc896cb5828a9e27709b Author: Tom Tromey <tom@tromey.com> Date: Mon Nov 28 21:11:53 2016 -0700 Remove cleanups from execute_gdb_command This replaces a cleanup in execute_gdb_command with an instance of std::string. Testing showed that this originally missed a cleanup that was returned by prevent_dont_repeat. This version of the patch changes prevent_dont_repeat to be a class, avoiding a cleanup. 2016-12-14 Tom Tromey <tom@tromey.com> * top.c (prevent_dont_repeat): Now a constructor. * python/python.c (execute_gdb_command): Use std::string. Update. * guile/guile.c (gdbscm_execute_gdb_command): Update. * command.h (prevent_dont_repeat): Now a class, not a function. * breakpoint.c (bpstat_do_actions_1): Update. diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 023c112..576270d 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,12 @@ +2016-12-14 Tom Tromey <tom@tromey.com> + + * top.c (prevent_dont_repeat): Now a constructor. + * python/python.c (execute_gdb_command): Use std::string. + Update. + * guile/guile.c (gdbscm_execute_gdb_command): Update. + * command.h (prevent_dont_repeat): Now a class, not a function. + * breakpoint.c (bpstat_do_actions_1): Update. + 2016-12-13 Tom Tromey <tom@tromey.com> * value.h (value_freer::~value_freer): Call reset. diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 92aac3a..5af1dfa 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -4685,7 +4685,7 @@ bpstat_do_actions_1 (bpstat *bsp) executing_breakpoint_commands = 1; old_chain = make_cleanup (cleanup_executing_breakpoints, 0); - prevent_dont_repeat (); + prevent_dont_repeat preventer (); /* This pointer will iterate over the list of bpstat's. */ bs = *bsp; diff --git a/gdb/command.h b/gdb/command.h index 965d91f..38ff38a 100644 --- a/gdb/command.h +++ b/gdb/command.h @@ -408,7 +408,17 @@ extern void error_no_arg (const char *) ATTRIBUTE_NORETURN; extern void dont_repeat (void); -extern struct cleanup *prevent_dont_repeat (void); +/* Prevent dont_repeat from doing anything. */ +class prevent_dont_repeat +{ + public: + + prevent_dont_repeat (); + + private: + + scoped_restore_tmpl<int> m_save_suppress; +}; /* Used to mark commands that don't do anything. If we just leave the function field NULL, the command is interpreted as a help topic, or diff --git a/gdb/guile/guile.c b/gdb/guile/guile.c index 9a126a1..599896b 100644 --- a/gdb/guile/guile.c +++ b/gdb/guile/guile.c @@ -332,7 +332,7 @@ gdbscm_execute_gdb_command (SCM command_scm, SCM rest) inner_cleanups = make_cleanup_restore_integer (¤t_ui->async); current_ui->async = 0; - prevent_dont_repeat (); + prevent_dont_repeat preventer (); if (to_string) to_string_res = execute_command_to_string (command, from_tty); else diff --git a/gdb/python/python.c b/gdb/python/python.c index 83b9805..cf9502d 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -601,8 +601,7 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw) TRY { /* Copy the argument text in case the command modifies it. */ - char *copy = xstrdup (arg); - struct cleanup *cleanup = make_cleanup (xfree, copy); + std::string copy (arg); struct interp *interp; scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0); @@ -614,12 +613,11 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw) interp = interp_lookup (current_ui, "console"); current_uiout = interp_ui_out (interp); - prevent_dont_repeat (); + prevent_dont_repeat preventer (); if (to_string) - to_string_res = execute_command_to_string (copy, from_tty); + to_string_res = execute_command_to_string (©[0], from_tty); else - execute_command (copy, from_tty); - do_cleanups (cleanup); + execute_command (©[0], from_tty); } CATCH (except, RETURN_MASK_ALL) { diff --git a/gdb/top.c b/gdb/top.c index 7d8b6e8..1aa926b 100644 --- a/gdb/top.c +++ b/gdb/top.c @@ -757,13 +757,9 @@ dont_repeat (void) /* Prevent dont_repeat from working, and return a cleanup that restores the previous state. */ -struct cleanup * -prevent_dont_repeat (void) +prevent_dont_repeat::prevent_dont_repeat () +: m_save_suppress (&suppress_dont_repeat, 1) { - struct cleanup *result = make_cleanup_restore_integer (&suppress_dont_repeat); - - suppress_dont_repeat = 1; - return result; } \f ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 7/8] Use unique_xmalloc_ptr in execute_gdb_command 2016-12-15 3:49 ` Tom Tromey @ 2016-12-20 17:48 ` Pedro Alves 2016-12-20 18:13 ` Tom Tromey 2016-12-20 23:31 ` Tom Tromey 0 siblings, 2 replies; 50+ messages in thread From: Pedro Alves @ 2016-12-20 17:48 UTC (permalink / raw) To: Tom Tromey; +Cc: gdb-patches On 12/15/2016 03:48 AM, Tom Tromey wrote: >>>>>> "Tom" == Tom Tromey <tom@tromey.com> writes: > > Tom> To my surprise, this patch is broken. > Tom> I must not have re-run the python tests locally after writing it :( > > Tom> The problem is that prevent_dont_repeat returns a cleanup, which is then > Tom> left dangling after this patch. > > Here's the updated patch. > I ran this one through the buildbot. > In some other local patch that I hadn't posted, I handled a similar situation of save/restoring some global that we don't want to expose by making the "make_cleanup_..." function return a scoped_restore, which avoids having to create a new class. It seems a bit simpler that creating a class to me, and maybe a tiny bit more efficient code-space wise (rtti?) Did you consider this approach? In this case, it'd look like this: From 3138a3fb72f76d0d1bb5a2e1db57e450c37dd43a Mon Sep 17 00:00:00 2001 From: Pedro Alves <palves@redhat.com> Date: Tue, 20 Dec 2016 17:30:56 +0000 Subject: [PATCH] Return scoped_restore instead of cleanup --- gdb/breakpoint.c | 2 +- gdb/command.h | 2 +- gdb/top.c | 16 ++++++---------- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index d737cad..dc72986 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -4685,7 +4685,7 @@ bpstat_do_actions_1 (bpstat *bsp) executing_breakpoint_commands = 1; old_chain = make_cleanup (cleanup_executing_breakpoints, 0); - prevent_dont_repeat (); + scoped_restore save_dont_repeat = prevent_dont_repeat (); /* This pointer will iterate over the list of bpstat's. */ bs = *bsp; diff --git a/gdb/command.h b/gdb/command.h index 965d91f..7b87814 100644 --- a/gdb/command.h +++ b/gdb/command.h @@ -408,7 +408,7 @@ extern void error_no_arg (const char *) ATTRIBUTE_NORETURN; extern void dont_repeat (void); -extern struct cleanup *prevent_dont_repeat (void); +extern scoped_restore_tmpl<bool> prevent_dont_repeat (); /* Used to mark commands that don't do anything. If we just leave the function field NULL, the command is interpreted as a help topic, or diff --git a/gdb/top.c b/gdb/top.c index 7d8b6e8..280af71 100644 --- a/gdb/top.c +++ b/gdb/top.c @@ -732,10 +732,10 @@ execute_command_to_string (char *p, int from_tty) } \f -/* When nonzero, cause dont_repeat to do nothing. This should only be +/* When true, cause dont_repeat to do nothing. This should only be set via prevent_dont_repeat. */ -static int suppress_dont_repeat = 0; +static bool suppress_dont_repeat = false; /* Commands call this if they do not want to be repeated by null lines. */ @@ -754,16 +754,12 @@ dont_repeat (void) *saved_command_line = 0; } -/* Prevent dont_repeat from working, and return a cleanup that +/* Prevent dont_repeat from working, and return a scoped restore that restores the previous state. */ - -struct cleanup * -prevent_dont_repeat (void) +scoped_restore_tmpl<bool> +prevent_dont_repeat () { - struct cleanup *result = make_cleanup_restore_integer (&suppress_dont_repeat); - - suppress_dont_repeat = 1; - return result; + return make_scoped_restore (&suppress_dont_repeat, true); } \f -- 2.5.5 ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 7/8] Use unique_xmalloc_ptr in execute_gdb_command 2016-12-20 17:48 ` Pedro Alves @ 2016-12-20 18:13 ` Tom Tromey 2016-12-23 20:01 ` Tom Tromey 2016-12-20 23:31 ` Tom Tromey 1 sibling, 1 reply; 50+ messages in thread From: Tom Tromey @ 2016-12-20 18:13 UTC (permalink / raw) To: Pedro Alves; +Cc: Tom Tromey, gdb-patches >>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes: Pedro> In some other local patch that I hadn't posted, I handled a similar Pedro> situation of save/restoring some global that we don't want to expose Pedro> by making the "make_cleanup_..." function return a scoped_restore, which Pedro> avoids having to create a new class. It seems a bit simpler that Pedro> creating a class to me, and maybe a tiny bit more efficient code-space Pedro> wise (rtti?) Did you consider this approach? I didn't, but I like it, so I'll make this change. Tom ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 7/8] Use unique_xmalloc_ptr in execute_gdb_command 2016-12-20 18:13 ` Tom Tromey @ 2016-12-23 20:01 ` Tom Tromey 2017-01-10 17:59 ` Pedro Alves 0 siblings, 1 reply; 50+ messages in thread From: Tom Tromey @ 2016-12-23 20:01 UTC (permalink / raw) To: Tom Tromey; +Cc: Pedro Alves, gdb-patches Pedro> In some other local patch that I hadn't posted, I handled a similar Pedro> situation of save/restoring some global that we don't want to expose Pedro> by making the "make_cleanup_..." function return a scoped_restore, which Pedro> avoids having to create a new class. It seems a bit simpler that Pedro> creating a class to me, and maybe a tiny bit more efficient code-space Pedro> wise (rtti?) Did you consider this approach? Tom> I didn't, but I like it, so I'll make this change. Here's the new version of this patch. Tom commit 20649c18216bf744aade97fed85c8a61b2e2905c Author: Tom Tromey <tom@tromey.com> Date: Mon Nov 28 21:11:53 2016 -0700 Remove cleanups from execute_gdb_command This replaces a cleanup in execute_gdb_command with an instance of std::string. Testing showed that this originally missed a cleanup that was returned by prevent_dont_repeat. This version of the patch changes prevent_dont_repeat to return a scoped_restore rather than a cleanup. 2016-12-14 Tom Tromey <tom@tromey.com> * top.c (prevent_dont_repeat): Change return type. * python/python.c (execute_gdb_command): Use std::string. Update. * guile/guile.c (gdbscm_execute_gdb_command): Update. * command.h (prevent_dont_repeat): Change return type. * breakpoint.c (bpstat_do_actions_1): Update. diff --git a/gdb/ChangeLog b/gdb/ChangeLog index d402851..c482013 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,12 @@ +2016-12-14 Tom Tromey <tom@tromey.com> + + * top.c (prevent_dont_repeat): Change return type. + * python/python.c (execute_gdb_command): Use std::string. + Update. + * guile/guile.c (gdbscm_execute_gdb_command): Update. + * command.h (prevent_dont_repeat): Change return type. + * breakpoint.c (bpstat_do_actions_1): Update. + 2016-12-13 Tom Tromey <tom@tromey.com> * value.h (scoped_value_mark::~scoped_value_mark): Call diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 6fd18fd..e47e73b 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -4685,7 +4685,7 @@ bpstat_do_actions_1 (bpstat *bsp) executing_breakpoint_commands = 1; old_chain = make_cleanup (cleanup_executing_breakpoints, 0); - prevent_dont_repeat (); + scoped_restore preventer = prevent_dont_repeat (); /* This pointer will iterate over the list of bpstat's. */ bs = *bsp; diff --git a/gdb/command.h b/gdb/command.h index 965d91f..924d8d3 100644 --- a/gdb/command.h +++ b/gdb/command.h @@ -408,7 +408,7 @@ extern void error_no_arg (const char *) ATTRIBUTE_NORETURN; extern void dont_repeat (void); -extern struct cleanup *prevent_dont_repeat (void); +extern scoped_restore_tmpl<int> prevent_dont_repeat (void); /* Used to mark commands that don't do anything. If we just leave the function field NULL, the command is interpreted as a help topic, or diff --git a/gdb/guile/guile.c b/gdb/guile/guile.c index 9a126a1..a95b894 100644 --- a/gdb/guile/guile.c +++ b/gdb/guile/guile.c @@ -332,7 +332,7 @@ gdbscm_execute_gdb_command (SCM command_scm, SCM rest) inner_cleanups = make_cleanup_restore_integer (¤t_ui->async); current_ui->async = 0; - prevent_dont_repeat (); + scoped_restore preventer = prevent_dont_repeat (); if (to_string) to_string_res = execute_command_to_string (command, from_tty); else diff --git a/gdb/python/python.c b/gdb/python/python.c index 83b9805..e92f72c 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -601,8 +601,7 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw) TRY { /* Copy the argument text in case the command modifies it. */ - char *copy = xstrdup (arg); - struct cleanup *cleanup = make_cleanup (xfree, copy); + std::string copy (arg); struct interp *interp; scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0); @@ -614,12 +613,11 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw) interp = interp_lookup (current_ui, "console"); current_uiout = interp_ui_out (interp); - prevent_dont_repeat (); + scoped_restore preventer = prevent_dont_repeat (); if (to_string) - to_string_res = execute_command_to_string (copy, from_tty); + to_string_res = execute_command_to_string (©[0], from_tty); else - execute_command (copy, from_tty); - do_cleanups (cleanup); + execute_command (©[0], from_tty); } CATCH (except, RETURN_MASK_ALL) { diff --git a/gdb/top.c b/gdb/top.c index 077fb2a..9960e6b 100644 --- a/gdb/top.c +++ b/gdb/top.c @@ -757,13 +757,10 @@ dont_repeat (void) /* Prevent dont_repeat from working, and return a cleanup that restores the previous state. */ -struct cleanup * +scoped_restore_tmpl<int> prevent_dont_repeat (void) { - struct cleanup *result = make_cleanup_restore_integer (&suppress_dont_repeat); - - suppress_dont_repeat = 1; - return result; + return make_scoped_restore (&suppress_dont_repeat, 1); } \f ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 7/8] Use unique_xmalloc_ptr in execute_gdb_command 2016-12-23 20:01 ` Tom Tromey @ 2017-01-10 17:59 ` Pedro Alves 2017-01-10 19:22 ` Tom Tromey 0 siblings, 1 reply; 50+ messages in thread From: Pedro Alves @ 2017-01-10 17:59 UTC (permalink / raw) To: Tom Tromey; +Cc: gdb-patches On 12/23/2016 08:00 PM, Tom Tromey wrote: > Pedro> In some other local patch that I hadn't posted, I handled a similar > Pedro> situation of save/restoring some global that we don't want to expose > Pedro> by making the "make_cleanup_..." function return a scoped_restore, which > Pedro> avoids having to create a new class. It seems a bit simpler that > Pedro> creating a class to me, and maybe a tiny bit more efficient code-space > Pedro> wise (rtti?) Did you consider this approach? > > Tom> I didn't, but I like it, so I'll make this change. > > Here's the new version of this patch. OK. Thanks, Pedro Alves ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 7/8] Use unique_xmalloc_ptr in execute_gdb_command 2017-01-10 17:59 ` Pedro Alves @ 2017-01-10 19:22 ` Tom Tromey 0 siblings, 0 replies; 50+ messages in thread From: Tom Tromey @ 2017-01-10 19:22 UTC (permalink / raw) To: Pedro Alves; +Cc: Tom Tromey, gdb-patches Tom> Here's the new version of this patch. Pedro> OK. Thanks for these reviews. I think now all of my various c++-ification series are fully approved, so I plan to rebase, re-test (on the buildbot), and then push. Once this happens (it may be a day or two) please let me know if there are any difficulties; I'll fix them as soon as I'm able. Tom ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 7/8] Use unique_xmalloc_ptr in execute_gdb_command 2016-12-20 17:48 ` Pedro Alves 2016-12-20 18:13 ` Tom Tromey @ 2016-12-20 23:31 ` Tom Tromey 2016-12-20 23:56 ` Pedro Alves 1 sibling, 1 reply; 50+ messages in thread From: Tom Tromey @ 2016-12-20 23:31 UTC (permalink / raw) To: Pedro Alves; +Cc: Tom Tromey, gdb-patches >>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes: Pedro> -extern struct cleanup *prevent_dont_repeat (void); Pedro> +extern scoped_restore_tmpl<bool> prevent_dont_repeat (); Probably this should use __attribute__((warn_unused_result)), but that isn't wrapped in ansidecl.h (yet) and I don't know offhand what version test to use for it. Do you? Tom ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 7/8] Use unique_xmalloc_ptr in execute_gdb_command 2016-12-20 23:31 ` Tom Tromey @ 2016-12-20 23:56 ` Pedro Alves 2016-12-22 14:50 ` Tom Tromey 0 siblings, 1 reply; 50+ messages in thread From: Pedro Alves @ 2016-12-20 23:56 UTC (permalink / raw) To: Tom Tromey; +Cc: gdb-patches On 12/20/2016 11:27 PM, Tom Tromey wrote: >>>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes: > > Pedro> -extern struct cleanup *prevent_dont_repeat (void); > Pedro> +extern scoped_restore_tmpl<bool> prevent_dont_repeat (); > > Probably this should use __attribute__((warn_unused_result)), but that > isn't wrapped in ansidecl.h (yet) and I don't know offhand what version > test to use for it. Do you? Good idea. Looks like it's GCC 3.4. glibc has: /* If fortification mode, we warn about unused results of certain function calls which can lead to problems. */ #if __GNUC_PREREQ (3,4) # define __attribute_warn_unused_result__ \ __attribute__ ((__warn_unused_result__)) # if __USE_FORTIFY_LEVEL > 0 # define __wur __attribute_warn_unused_result__ # endif #else # define __attribute_warn_unused_result__ /* empty */ #endif #ifndef __wur # define __wur /* Ignore */ #endif Grepping my F23's system headers I see other hits for GCC 3.4: /usr/include/lzma.h:237: /* warn_unused_result was added in GCC 3.4. */ /usr/include/llvm/Support/Compiler.h:125:#if __has_attribute(warn_unused_result) || LLVM_GNUC_PREREQ(3, 4, 0) /usr/include/llvm/Support/Compiler.h:126:#define LLVM_ATTRIBUTE_UNUSED_RESULT __attribute__((__warn_unused_result__)) Thanks, Pedro Alves ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 7/8] Use unique_xmalloc_ptr in execute_gdb_command 2016-12-20 23:56 ` Pedro Alves @ 2016-12-22 14:50 ` Tom Tromey 2016-12-22 15:09 ` Pedro Alves 0 siblings, 1 reply; 50+ messages in thread From: Tom Tromey @ 2016-12-22 14:50 UTC (permalink / raw) To: Pedro Alves; +Cc: Tom Tromey, gdb-patches >>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes: Tom> Probably this should use __attribute__((warn_unused_result)), but that Tom> isn't wrapped in ansidecl.h (yet) and I don't know offhand what version Tom> test to use for it. Do you? Pedro> Good idea. Looks like it's GCC 3.4. This turns out not to work :( FWIW in addition to the ATTRIBUTE_WARN_UNUSED_RESULT patch, I also had to patch gdb's configure script to add -Wunused-result, as -Wunused turns this off. The g++ bug is known: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=38172 It looks like the accepted fix upstream to use the C++17 [[nodiscard]] attribute; not sure if we can use that somehow. Meanwhile I'm going to drop this part of my patch. Tom ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 7/8] Use unique_xmalloc_ptr in execute_gdb_command 2016-12-22 14:50 ` Tom Tromey @ 2016-12-22 15:09 ` Pedro Alves 2016-12-22 15:29 ` Tom Tromey 0 siblings, 1 reply; 50+ messages in thread From: Pedro Alves @ 2016-12-22 15:09 UTC (permalink / raw) To: Tom Tromey; +Cc: gdb-patches On 12/22/2016 02:49 PM, Tom Tromey wrote: >>>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes: > > Tom> Probably this should use __attribute__((warn_unused_result)), but that > Tom> isn't wrapped in ansidecl.h (yet) and I don't know offhand what version > Tom> test to use for it. Do you? > > Pedro> Good idea. Looks like it's GCC 3.4. > > This turns out not to work :( > > FWIW in addition to the ATTRIBUTE_WARN_UNUSED_RESULT patch, I also had > to patch gdb's configure script to add -Wunused-result, as -Wunused > turns this off. > Bummer. :-( > The g++ bug is known: > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=38172 > > It looks like the accepted fix upstream to use the C++17 [[nodiscard]] > attribute; not sure if we can use that somehow. Can't see why not, if we put it behind some ATTRIBUTE_NODISCARD or some such define. Sounds like with that we could put the attribute in the scoped_restore_impl template itself ('struct [[nodiscard]] foo'), and get the warning for all similar make_foo_scoped_restore-like functions for free. > > Meanwhile I'm going to drop this part of my patch. That's fine, we can always add it later. Thanks much for experimenting. Thanks, Pedro Alves ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 7/8] Use unique_xmalloc_ptr in execute_gdb_command 2016-12-22 15:09 ` Pedro Alves @ 2016-12-22 15:29 ` Tom Tromey 2016-12-22 15:40 ` Pedro Alves 0 siblings, 1 reply; 50+ messages in thread From: Tom Tromey @ 2016-12-22 15:29 UTC (permalink / raw) To: Pedro Alves; +Cc: Tom Tromey, gdb-patches >>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes: >> It looks like the accepted fix upstream to use the C++17 [[nodiscard]] >> attribute; not sure if we can use that somehow. Pedro> Can't see why not, if we put it behind some ATTRIBUTE_NODISCARD or Pedro> some such define. It wasn't obvious to me (and as you can tell I'm not doing much research into this kind of thing lately...) what condition to use. C++17 isn't official yet, and presumably even if we had some value for __cplusplus to check, we'd also have to check for when exactly it was added to g++? Tom ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 7/8] Use unique_xmalloc_ptr in execute_gdb_command 2016-12-22 15:29 ` Tom Tromey @ 2016-12-22 15:40 ` Pedro Alves 0 siblings, 0 replies; 50+ messages in thread From: Pedro Alves @ 2016-12-22 15:40 UTC (permalink / raw) To: Tom Tromey; +Cc: gdb-patches On 12/22/2016 03:29 PM, Tom Tromey wrote: > C++17 isn't > official yet, and presumably even if we had some value for __cplusplus > to check, we'd also have to check for when exactly it was added to g++? According to: https://gcc.gnu.org/projects/cxx-status.html that could be checked with __has_cpp_attribute(nodiscard). From that page, seems like G++ 4.8 had an [[gnu::warn_unused_result]] alternative that perhaps works on C++11 too. I have no experience with it though. But as I said, we can always add this later. Thanks, Pedro Alves ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 7/8] Use unique_xmalloc_ptr in execute_gdb_command 2016-11-29 5:06 ` [RFA 7/8] Use unique_xmalloc_ptr in execute_gdb_command Tom Tromey 2016-11-29 5:22 ` Tom Tromey @ 2016-12-02 14:49 ` Pedro Alves 2016-12-13 13:30 ` Tom Tromey 1 sibling, 1 reply; 50+ messages in thread From: Pedro Alves @ 2016-12-02 14:49 UTC (permalink / raw) To: Tom Tromey, gdb-patches On 11/29/2016 05:05 AM, Tom Tromey wrote: > This replaces a cleanup in execute_gdb_command with an instance of > unique_xmalloc_ptr. std::string was not used because execute_command > and execute_command_to_string don't accept a "const char *" (in fact > the reason for copying the string at all). You can do: std::string copy (arg); ... to_string_res = execute_command_to_string (©[0], from_tty); That's fine in C++11. Thanks, Pedro Alves ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 7/8] Use unique_xmalloc_ptr in execute_gdb_command 2016-12-02 14:49 ` Pedro Alves @ 2016-12-13 13:30 ` Tom Tromey 0 siblings, 0 replies; 50+ messages in thread From: Tom Tromey @ 2016-12-13 13:30 UTC (permalink / raw) To: Pedro Alves; +Cc: Tom Tromey, gdb-patches >>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes: Pedro> You can do: Pedro> std::string copy (arg); Pedro> ... Pedro> to_string_res = execute_command_to_string (©[0], from_tty); Thanks, I made this change. Tom ^ permalink raw reply [flat|nested] 50+ messages in thread
* [RFA 1/8] Add gdb_ref_ptr.h 2016-11-29 5:06 [RFA 0/8] C++-ification series #5 Tom Tromey 2016-11-29 5:06 ` [RFA 8/8] Add constructor and destructor to demangle_parse_info Tom Tromey 2016-11-29 5:06 ` [RFA 7/8] Use unique_xmalloc_ptr in execute_gdb_command Tom Tromey @ 2016-11-29 5:06 ` Tom Tromey 2016-12-02 13:08 ` Pedro Alves 2016-12-03 0:05 ` Pedro Alves 2016-11-29 5:06 ` [RFA 3/8] Introduce and use gdb::unlinker Tom Tromey ` (4 subsequent siblings) 7 siblings, 2 replies; 50+ messages in thread From: Tom Tromey @ 2016-11-29 5:06 UTC (permalink / raw) To: gdb-patches; +Cc: Tom Tromey This adds a new gdb_ref_ptr.h, that implements a reference-counting smart pointer class, where the user of the class supplies a reference-counting policy object. This class will be used in the next patch, which changes most explicit BFD reference counts to use this new type. Meanwhile, this patch changes gdbpy_ref to be a specialization of this new class. This change required adding new nullptr_t overloads some operators in gdb_ref_ptr.h. I suspect this was needed because some Python header redefines NULL, but I'm not certain. 2016-11-28 Tom Tromey <tom@tromey.com> * common/gdb_ref_ptr.h: New file. * python/py-ref.h (struct gdbpy_ref_policy): New. (gdbpy_ref): Now a typedef. --- gdb/ChangeLog | 6 ++ gdb/common/gdb_ref_ptr.h | 209 +++++++++++++++++++++++++++++++++++++++++++++++ gdb/python/py-ref.h | 135 ++---------------------------- 3 files changed, 224 insertions(+), 126 deletions(-) create mode 100644 gdb/common/gdb_ref_ptr.h diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 8cbe8ad..f455f7f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,11 @@ 2016-11-28 Tom Tromey <tom@tromey.com> + * common/gdb_ref_ptr.h: New file. + * python/py-ref.h (struct gdbpy_ref_policy): New. + (gdbpy_ref): Now a typedef. + +2016-11-28 Tom Tromey <tom@tromey.com> + * utils.h (make_cleanup_htab_delete): Don't declare. * utils.c (do_htab_delete_cleanup, make_cleanup_htab_delete): Remove. diff --git a/gdb/common/gdb_ref_ptr.h b/gdb/common/gdb_ref_ptr.h new file mode 100644 index 0000000..cc8ba94 --- /dev/null +++ b/gdb/common/gdb_ref_ptr.h @@ -0,0 +1,209 @@ +/* Reference-counted smart pointer class + + Copyright (C) 2016 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef GDB_REF_PTR_H +#define GDB_REF_PTR_H + +#include <cstddef> + +namespace gdb +{ + +/* An instance of this class either holds a reference to a + reference-counted object or is "NULL". Reference counting is + handled externally by a policy class. If the object holds a + reference, then when the object is destroyed, the reference is + decref'd. + + Normally an instance is constructed using a pointer. This sort of + initialization lets this class manage the lifetime of that + reference. + + Assignment and copy construction will make a new reference as + appropriate. Assignment from a plain pointer is disallowed to + avoid confusion about whether this acquires a new reference; + instead use the "reset" method -- which, like the pointer + constructor, transfers ownership. + + The policy class must provide two static methods: + void incref (T *); + void decref (T *); +*/ +template<typename T, typename POLICY> +class ref_ptr +{ + public: + + /* Create a new NULL instance. */ + ref_ptr () + : m_obj (NULL) + { + } + + /* Create a new instance. OBJ is a reference, management of which + is now transferred to this class. */ + explicit ref_ptr (T *obj) + : m_obj (obj) + { + } + + /* Copy another instance. */ + ref_ptr (const ref_ptr &other) + : m_obj (other.m_obj) + { + if (m_obj != NULL) + POLICY::incref (m_obj); + } + + /* Transfer ownership from OTHER. */ + ref_ptr (ref_ptr &&other) + : m_obj (other.m_obj) + { + other.m_obj = NULL; + } + + /* Destroy this instance. */ + ~ref_ptr () + { + if (m_obj != NULL) + POLICY::decref (m_obj); + } + + /* Copy another instance. */ + ref_ptr &operator= (const ref_ptr &other) + { + /* Do nothing on self-assignment. */ + if (this != &other) + { + reset (other.m_obj); + if (m_obj != NULL) + POLICY::incref (m_obj); + } + return *this; + } + + /* Transfer ownership from OTHER. */ + ref_ptr &operator= (ref_ptr &&other) + { + /* Do nothing on self-assignment. */ + if (this != &other) + { + reset (other.m_obj); + other.m_obj = NULL; + } + return *this; + } + + /* Change this instance's referent. OBJ is a reference, management + of which is now transferred to this class. */ + void reset (T *obj) + { + if (m_obj != NULL) + POLICY::decref (m_obj); + m_obj = obj; + } + + /* Return this instance's referent without changing the state of + this class. */ + T *get () const + { + return m_obj; + } + + /* Return this instance's referent, and stop managing this + reference. The caller is now responsible for the ownership of + the reference. */ + T *release () + { + T *result = m_obj; + + m_obj = NULL; + return result; + } + + private: + + T *m_obj; +}; + +template<typename T, typename POLICY> +inline bool operator== (const ref_ptr<T, POLICY> &self, + const ref_ptr<T, POLICY> &other) +{ + return self.get () == other.get (); +} + +template<typename T, typename POLICY> +inline bool operator== (const ref_ptr<T, POLICY> &self, const T *other) +{ + return self.get () == other; +} + +template<typename T, typename POLICY> +inline bool operator== (const ref_ptr<T, POLICY> &self, const std::nullptr_t) +{ + return self.get () == nullptr; +} + +template<typename T, typename POLICY> +inline bool operator== (const T *self, const ref_ptr<T, POLICY> &other) +{ + return self == other.get (); +} + +template<typename T, typename POLICY> +inline bool operator== (const std::nullptr_t, const ref_ptr<T, POLICY> &other) +{ + return nullptr == other.get (); +} + +template<typename T, typename POLICY> +inline bool operator!= (const ref_ptr<T, POLICY> &self, + const ref_ptr<T, POLICY> &other) +{ + return self.get () != other.get (); +} + +template<typename T, typename POLICY> +inline bool operator!= (const ref_ptr<T, POLICY> &self, const T *other) +{ + return self.get () != other; +} + +template<typename T, typename POLICY> +inline bool operator!= (const ref_ptr<T, POLICY> &self, const std::nullptr_t) +{ + return self.get () != nullptr; +} + +template<typename T, typename POLICY> +inline bool operator!= (const T *self, const ref_ptr<T, POLICY> &other) +{ + return self != other.get (); +} + +template<typename T, typename POLICY> +inline bool operator!= (const std::nullptr_t, const ref_ptr<T, POLICY> &other) +{ + return nullptr != other.get (); +} + +} + +#endif /* GDB_REF_PTR_H */ diff --git a/gdb/python/py-ref.h b/gdb/python/py-ref.h index f0e4aae..b2479bf 100644 --- a/gdb/python/py-ref.h +++ b/gdb/python/py-ref.h @@ -20,140 +20,23 @@ #ifndef GDB_PYTHON_REF_H #define GDB_PYTHON_REF_H -/* An instance of this class either holds a reference to a PyObject, - or is "NULL". If it holds a reference, then when the object is - destroyed, the PyObject is decref'd. +#include "common/gdb_ref_ptr.h" - Normally an instance is constructed using a PyObject*. This sort - of initialization lets this class manage the lifetime of that - reference. - - Assignment and copy construction will make a new reference as - appropriate. Assignment from a plain PyObject* is disallowed to - avoid confusion about whether this acquires a new reference; - instead use the "reset" method -- which, like the PyObject* - constructor, transfers ownership. -*/ -class gdbpy_ref +/* A policy class for gdb::ref_ptr for Python reference counting. */ +struct gdbpy_ref_policy { - public: - - /* Create a new NULL instance. */ - gdbpy_ref () - : m_obj (NULL) - { - } - - /* Create a new instance. OBJ is a reference, management of which - is now transferred to this class. */ - explicit gdbpy_ref (PyObject *obj) - : m_obj (obj) - { - } - - /* Copy another instance. */ - gdbpy_ref (const gdbpy_ref &other) - : m_obj (other.m_obj) - { - Py_XINCREF (m_obj); - } - - /* Transfer ownership from OTHER. */ - gdbpy_ref (gdbpy_ref &&other) - : m_obj (other.m_obj) - { - other.m_obj = NULL; - } - - /* Destroy this instance. */ - ~gdbpy_ref () - { - Py_XDECREF (m_obj); - } - - /* Copy another instance. */ - gdbpy_ref &operator= (const gdbpy_ref &other) - { - /* Do nothing on self-assignment. */ - if (this != &other) - { - reset (other.m_obj); - Py_XINCREF (m_obj); - } - return *this; - } - - /* Transfer ownership from OTHER. */ - gdbpy_ref &operator= (gdbpy_ref &&other) + static void incref (PyObject *ptr) { - /* Do nothing on self-assignment. */ - if (this != &other) - { - reset (other.m_obj); - other.m_obj = NULL; - } - return *this; + Py_INCREF (ptr); } - /* Change this instance's referent. OBJ is a reference, management - of which is now transferred to this class. */ - void reset (PyObject *obj) + static void decref (PyObject *ptr) { - Py_XDECREF (m_obj); - m_obj = obj; + Py_DECREF (ptr); } - - /* Return this instance's referent. In Python terms this is a - borrowed pointer. */ - PyObject *get () const - { - return m_obj; - } - - /* Return this instance's referent, and stop managing this - reference. The caller is now responsible for the ownership of - the reference. */ - PyObject *release () - { - PyObject *result = m_obj; - - m_obj = NULL; - return result; - } - - private: - - PyObject *m_obj; }; -inline bool operator== (const gdbpy_ref &self, const gdbpy_ref &other) -{ - return self.get () == other.get (); -} - -inline bool operator== (const gdbpy_ref &self, const PyObject *other) -{ - return self.get () == other; -} - -inline bool operator== (const PyObject *self, const gdbpy_ref &other) -{ - return self == other.get (); -} - -inline bool operator!= (const gdbpy_ref &self, const gdbpy_ref &other) -{ - return self.get () != other.get (); -} - -inline bool operator!= (const gdbpy_ref &self, const PyObject *other) -{ - return self.get () != other; -} - -inline bool operator!= (const PyObject *self, const gdbpy_ref &other) -{ - return self != other.get (); -} +/* A gdb::ref_ptr that has been specialized for Python objects. */ +typedef gdb::ref_ptr<PyObject, gdbpy_ref_policy> gdbpy_ref; #endif /* GDB_PYTHON_REF_H */ -- 2.7.4 ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 1/8] Add gdb_ref_ptr.h 2016-11-29 5:06 ` [RFA 1/8] Add gdb_ref_ptr.h Tom Tromey @ 2016-12-02 13:08 ` Pedro Alves 2016-12-02 17:46 ` Tom Tromey 2016-12-03 0:05 ` Pedro Alves 1 sibling, 1 reply; 50+ messages in thread From: Pedro Alves @ 2016-12-02 13:08 UTC (permalink / raw) To: Tom Tromey, gdb-patches On 11/29/2016 05:05 AM, Tom Tromey wrote: > This adds a new gdb_ref_ptr.h, that implements a reference-counting > smart pointer class, where the user of the class supplies a > reference-counting policy object. > > This class will be used in the next patch, which changes most explicit > BFD reference counts to use this new type. Meanwhile, this patch > changes gdbpy_ref to be a specialization of this new class. > > This change required adding new nullptr_t overloads some operators in > gdb_ref_ptr.h. I suspect this was needed because some Python header > redefines NULL, but I'm not certain. Can you please remove them and see what breaks? Odd that this would be something about Python, given the class is being used in Python code today? BTW, it's worth noting that there's a proposal to add (an oddly named) policy-based intrusive ref counting smart pointer to the standard: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0468r0.html Thanks, Pedro Alves ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 1/8] Add gdb_ref_ptr.h 2016-12-02 13:08 ` Pedro Alves @ 2016-12-02 17:46 ` Tom Tromey 2016-12-02 18:11 ` Pedro Alves 0 siblings, 1 reply; 50+ messages in thread From: Tom Tromey @ 2016-12-02 17:46 UTC (permalink / raw) To: Pedro Alves; +Cc: Tom Tromey, gdb-patches >>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes: Pedro> Can you please remove them and see what breaks? Odd that this would be Pedro> something about Python, given the class is being used in Python code Pedro> today? Yes, it's odd. If I comment out the nullptr_t overloads, I get build failures like: ../../binutils-gdb/gdb/python/py-exitedevent.c:31:20: error: no match for ‘operator==’ (operand types are ‘gdbpy_ref {aka gdb::ref_ptr<_object, gdbpy_ref_policy>}’ and ‘long int’) if (exited_event == NULL) ^ ../../binutils-gdb/gdb/common/gdb_ref_ptr.h:183:13: note: template argument deduction/substitution failed: In file included from ../../binutils-gdb/gdb/python/py-ref.h:23:0, from ../../binutils-gdb/gdb/python/py-event.h:27, from ../../binutils-gdb/gdb/python/py-event.c:21: ../../binutils-gdb/gdb/common/gdb_ref_ptr.h:171:13: note: candidate: template<class T, class POLICY> bool gdb::operator==(const T*, const gdb::ref_ptr<T, POLICY>&) inline bool operator== (const T *self, const ref_ptr<T, POLICY> &other) ^~~~~~~~ I don't understand why it picks this particular candidate, but re-reading it now I think my earlier theory is wrong. Tom ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 1/8] Add gdb_ref_ptr.h 2016-12-02 17:46 ` Tom Tromey @ 2016-12-02 18:11 ` Pedro Alves 2016-12-02 19:52 ` Tom Tromey 0 siblings, 1 reply; 50+ messages in thread From: Pedro Alves @ 2016-12-02 18:11 UTC (permalink / raw) To: Tom Tromey; +Cc: gdb-patches On 12/02/2016 05:46 PM, Tom Tromey wrote: >>>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes: > > Pedro> Can you please remove them and see what breaks? Odd that this would be > Pedro> something about Python, given the class is being used in Python code > Pedro> today? > > Yes, it's odd. If I comment out the nullptr_t overloads, I get build > failures like: > > ../../binutils-gdb/gdb/python/py-exitedevent.c:31:20: error: no match for âoperator==â (operand types are âgdbpy_ref {aka gdb::ref_ptr<_object, gdbpy_ref_policy>}â and âlong intâ) > if (exited_event == NULL) > ^ > ../../binutils-gdb/gdb/common/gdb_ref_ptr.h:183:13: note: template argument deduction/substitution failed: > In file included from ../../binutils-gdb/gdb/python/py-ref.h:23:0, > from ../../binutils-gdb/gdb/python/py-event.h:27, > from ../../binutils-gdb/gdb/python/py-event.c:21: > ../../binutils-gdb/gdb/common/gdb_ref_ptr.h:171:13: note: candidate: template<class T, class POLICY> bool gdb::operator==(const T*, const gdb::ref_ptr<T, POLICY>&) > inline bool operator== (const T *self, const ref_ptr<T, POLICY> &other) > ^~~~~~~~ > > > I don't understand why it picks this particular candidate, but I think gcc will list you all candidates, mentioning why each one can't work. I.e., it likely tells you more further below? > re-reading it now I think my earlier theory is wrong. Does it still happen if you remove the cstddef include? Do you have your code in some branch? It seems none of the gdbpy_ref stuff is in master yet. Thanks, Pedro Alves ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 1/8] Add gdb_ref_ptr.h 2016-12-02 18:11 ` Pedro Alves @ 2016-12-02 19:52 ` Tom Tromey 2016-12-02 23:45 ` Pedro Alves 0 siblings, 1 reply; 50+ messages in thread From: Tom Tromey @ 2016-12-02 19:52 UTC (permalink / raw) To: Pedro Alves; +Cc: Tom Tromey, gdb-patches >>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes: Pedro> I think gcc will list you all candidates, mentioning why each one Pedro> can't work. I.e., it likely tells you more further below? Yeah, it does, I missed that. Pedro> Does it still happen if you remove the cstddef include? Yes. Pedro> Do you have your code in some branch? It seems none of the Pedro> gdbpy_ref stuff is in master yet. I pushed it to py-cxx-changes on my github account. I haven't pushed anything in since I have one giant branch and there were some issues with a couple individual patches. The final two patches on that branch aren't submitted yet, they are the fixes I need to fold in and resubmit. Tom ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 1/8] Add gdb_ref_ptr.h 2016-12-02 19:52 ` Tom Tromey @ 2016-12-02 23:45 ` Pedro Alves 0 siblings, 0 replies; 50+ messages in thread From: Pedro Alves @ 2016-12-02 23:45 UTC (permalink / raw) To: Tom Tromey; +Cc: gdb-patches On 12/02/2016 07:52 PM, Tom Tromey wrote: >>>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes: > > Pedro> I think gcc will list you all candidates, mentioning why each one > Pedro> can't work. I.e., it likely tells you more further below? > > Yeah, it does, I missed that. Ah, trying locally and getting at the compile log helped. The overload we'd expect to work, doesn't: ..../src/gdb/solib-darwin.c: In function ‘void darwin_solib_get_all_image_info_addr_at_init(darwin_info*)’: ..../src/gdb/solib-darwin.c:467:16: error: no match for ‘operator!=’ (operand types are ‘gdb_bfd_ref_ptr {aka gdb::ref_ptr<bfd, gdb_bfd_ref_policy>}’ and ‘long int’) if (dyld_bfd != NULL) ^ [...] ..../src/gdb/common/gdb_ref_ptr.h:212:13: note: candidate: template<class T, class POLICY> bool gdb::operator!=(const gdb::ref_ptr<T, POLICY>&, const T*) inline bool operator!= (const ref_ptr<T, POLICY> &self, const T *other) ^ ..../src/gdb/common/gdb_ref_ptr.h:212:13: note: template argument deduction/substitution failed: ..../src/gdb/solib-darwin.c:467:19: note: mismatched types ‘const T*’ and ‘long int’ if (dyld_bfd != NULL) ^ [...] That's simply because template type deduction, which happens before overload resolution, does not consider implicit conversions. And then there's no overload in the overload set that satisfied the operation. Before the gdb_ref_ptr.h patch (this email thread), gdbpy_ref is not a template, so: inline bool operator!= (const gdbpy_ref &self, const PyObject *other); is left in the overload set, at which point implicit conversions can apply. I was a bit mystified about why my gdb_unique_ptr shim had == NULL working without nullptr_t overloads, but I remember now. It was because it was using the safe bool idiom to make it work. I.e., adding this to ref_ptr would make operator==/operator!= work without the nullptr_t overloads too: /* "explicit operator bool ()" emulation using the safe bool idiom. */ private: typedef void (ref_ptr::*explicit_operator_bool) () const; void this_type_does_not_support_comparisons () const {} public: operator explicit_operator_bool () const { return (m_obj != NULL ? &ref_ptr::this_type_does_not_support_comparisons : 0); } With this, despite the fact that no operator== candidate template matches, the compile still manages to call the built-in, non-template: bool operator==(member function ptr, long); > Pedro> Do you have your code in some branch? It seems none of the > Pedro> gdbpy_ref stuff is in master yet. > > I pushed it to py-cxx-changes on my github account. Thanks, that helped. So the conclusion is that the nullptr_t overloads are necessary because ref_ptr is now a template. BTW, notice that both retain_ptr (that proposal I linked to), and unique_ptr have these same overloads. Thanks, Pedro Alves ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 1/8] Add gdb_ref_ptr.h 2016-11-29 5:06 ` [RFA 1/8] Add gdb_ref_ptr.h Tom Tromey 2016-12-02 13:08 ` Pedro Alves @ 2016-12-03 0:05 ` Pedro Alves 2016-12-13 13:13 ` Tom Tromey 1 sibling, 1 reply; 50+ messages in thread From: Pedro Alves @ 2016-12-03 0:05 UTC (permalink / raw) To: Tom Tromey, gdb-patches On 11/29/2016 05:05 AM, Tom Tromey wrote: > This adds a new gdb_ref_ptr.h, that implements a reference-counting > smart pointer class, where the user of the class supplies a > reference-counting policy object. > > This class will be used in the next patch, which changes most explicit > BFD reference counts to use this new type. Meanwhile, this patch > changes gdbpy_ref to be a specialization of this new class. > > This change required adding new nullptr_t overloads some operators in > gdb_ref_ptr.h. I suspect this was needed because some Python header > redefines NULL, but I'm not certain. > > 2016-11-28 Tom Tromey <tom@tromey.com> > > * common/gdb_ref_ptr.h: New file. > * python/py-ref.h (struct gdbpy_ref_policy): New. > (gdbpy_ref): Now a typedef. > --- > gdb/ChangeLog | 6 ++ > gdb/common/gdb_ref_ptr.h | 209 +++++++++++++++++++++++++++++++++++++++++++++++ > gdb/python/py-ref.h | 135 ++---------------------------- > 3 files changed, 224 insertions(+), 126 deletions(-) > create mode 100644 gdb/common/gdb_ref_ptr.h > > diff --git a/gdb/ChangeLog b/gdb/ChangeLog > index 8cbe8ad..f455f7f 100644 > --- a/gdb/ChangeLog > +++ b/gdb/ChangeLog > @@ -1,5 +1,11 @@ > 2016-11-28 Tom Tromey <tom@tromey.com> > > + * common/gdb_ref_ptr.h: New file. > + * python/py-ref.h (struct gdbpy_ref_policy): New. > + (gdbpy_ref): Now a typedef. > + > +2016-11-28 Tom Tromey <tom@tromey.com> > + > * utils.h (make_cleanup_htab_delete): Don't declare. > * utils.c (do_htab_delete_cleanup, make_cleanup_htab_delete): > Remove. > diff --git a/gdb/common/gdb_ref_ptr.h b/gdb/common/gdb_ref_ptr.h > new file mode 100644 > index 0000000..cc8ba94 > --- /dev/null > +++ b/gdb/common/gdb_ref_ptr.h > @@ -0,0 +1,209 @@ > +/* Reference-counted smart pointer class > + > + Copyright (C) 2016 Free Software Foundation, Inc. > + > + This file is part of GDB. > + > + This program is free software; you can redistribute it and/or modify > + it under the terms of the GNU General Public License as published by > + the Free Software Foundation; either version 3 of the License, or > + (at your option) any later version. > + > + This program is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + GNU General Public License for more details. > + > + You should have received a copy of the GNU General Public License > + along with this program. If not, see <http://www.gnu.org/licenses/>. */ > + > +#ifndef GDB_REF_PTR_H > +#define GDB_REF_PTR_H > + > +#include <cstddef> > + > +namespace gdb > +{ > + > +/* An instance of this class either holds a reference to a > + reference-counted object or is "NULL". Reference counting is > + handled externally by a policy class. If the object holds a > + reference, then when the object is destroyed, the reference is > + decref'd. > + > + Normally an instance is constructed using a pointer. This sort of > + initialization lets this class manage the lifetime of that > + reference. > + > + Assignment and copy construction will make a new reference as > + appropriate. Assignment from a plain pointer is disallowed to > + avoid confusion about whether this acquires a new reference; > + instead use the "reset" method -- which, like the pointer > + constructor, transfers ownership. > + > + The policy class must provide two static methods: > + void incref (T *); > + void decref (T *); > +*/ > +template<typename T, typename POLICY> > +class ref_ptr BTW, I noticed today that the GCC standards say: "Template parameter names should use CamelCase, following the C++ Standard." and they do seem to follow it. I think it's a good idea. Would you mind adjusting accordingly? I also noticed the "self/other" naming in the global operators: +template<typename T, typename POLICY> +inline bool operator== (const ref_ptr<T, POLICY> &self, + const ref_ptr<T, POLICY> &other) +{ I'd find it pedantically more correct to write lhs/rhs, since there's no actual this/self here. Could you tweak that too? Thanks, Pedro Alves ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 1/8] Add gdb_ref_ptr.h 2016-12-03 0:05 ` Pedro Alves @ 2016-12-13 13:13 ` Tom Tromey 0 siblings, 0 replies; 50+ messages in thread From: Tom Tromey @ 2016-12-13 13:13 UTC (permalink / raw) To: Pedro Alves; +Cc: Tom Tromey, gdb-patches >>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes: Pedro> BTW, I noticed today that the GCC standards say: Pedro> "Template parameter names should use CamelCase, following the C++ Pedro> Standard." Pedro> and they do seem to follow it. I think it's a good idea. Pedro> Would you mind adjusting accordingly? No problem, I did that. FWIW my personal style is also to use CamelCase for macro arguments. Pedro> I also noticed the "self/other" naming in the global operators: Pedro> +template<typename T, typename POLICY> Pedro> +inline bool operator== (const ref_ptr<T, POLICY> &self, Pedro> + const ref_ptr<T, POLICY> &other) Pedro> +{ Pedro> I'd find it pedantically more correct to write lhs/rhs, since Pedro> there's no actual this/self here. Could you tweak that too? I did this too. Tom ^ permalink raw reply [flat|nested] 50+ messages in thread
* [RFA 3/8] Introduce and use gdb::unlinker 2016-11-29 5:06 [RFA 0/8] C++-ification series #5 Tom Tromey ` (2 preceding siblings ...) 2016-11-29 5:06 ` [RFA 1/8] Add gdb_ref_ptr.h Tom Tromey @ 2016-11-29 5:06 ` Tom Tromey 2016-12-02 13:17 ` Pedro Alves 2016-11-29 5:06 ` [RFA 4/8] Remove make_cleanup_discard_psymtabs Tom Tromey ` (3 subsequent siblings) 7 siblings, 1 reply; 50+ messages in thread From: Tom Tromey @ 2016-11-29 5:06 UTC (permalink / raw) To: gdb-patches; +Cc: Tom Tromey This introduces a new class, gdb::unlinker, that unlinks a file in the destructor. The user of this class has the option to preserve the file instead, by calling the "keep" method. This patch then changes the spots in gdb that use unlink in a cleanup to use this class instead. In one spot I went ahead and removed all the cleanups from the function. This fixes one latent bug -- do_bfd_delete_cleanup could refer to freed memory, by decref'ing the BFD before using its filename. 2016-11-28 Tom Tromey <tom@tromey.com> * record-full.c (record_full_save_cleanups): Remove. (record_full_save): Use gdb::unlinker. * gcore.c (do_bfd_delete_cleanup): Remove. (gcore_command): Use gdb::unlinker, unique_xmalloc_ptr. Remove cleanups. * dwarf2read.c (unlink_if_set): Remove. (write_psymtabs_to_index): Use gdb::unlinker. * common/gdb_unlinker.h: New file. --- gdb/ChangeLog | 11 +++++++++ gdb/common/gdb_unlinker.h | 60 +++++++++++++++++++++++++++++++++++++++++++++++ gdb/dwarf2read.c | 21 ++++------------- gdb/gcore.c | 38 ++++++++++-------------------- gdb/record-full.c | 54 +++++++++++++++++------------------------- 5 files changed, 110 insertions(+), 74 deletions(-) create mode 100644 gdb/common/gdb_unlinker.h diff --git a/gdb/ChangeLog b/gdb/ChangeLog index ce21840..18814d3 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,16 @@ 2016-11-28 Tom Tromey <tom@tromey.com> + * record-full.c (record_full_save_cleanups): Remove. + (record_full_save): Use gdb::unlinker. + * gcore.c (do_bfd_delete_cleanup): Remove. + (gcore_command): Use gdb::unlinker, unique_xmalloc_ptr. Remove + cleanups. + * dwarf2read.c (unlink_if_set): Remove. + (write_psymtabs_to_index): Use gdb::unlinker. + * common/gdb_unlinker.h: New file. + +2016-11-28 Tom Tromey <tom@tromey.com> + * windows-tdep.c (windows_xfer_shared_library): Update. * windows-nat.c (windows_make_so): Update. * utils.h (make_cleanup_bfd_unref): Remove. diff --git a/gdb/common/gdb_unlinker.h b/gdb/common/gdb_unlinker.h new file mode 100644 index 0000000..0f3b98a --- /dev/null +++ b/gdb/common/gdb_unlinker.h @@ -0,0 +1,60 @@ +/* Unlinking class + + Copyright (C) 2016 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef GDB_UNLINKER_H +#define GDB_UNLINKER_H + +namespace gdb +{ + +/* An object of this class holds a filename and, when the object goes + of scope, the file is removed using unlink. + + A user of this class can request that the file be preserved using + the "keep" method. */ +class unlinker +{ + public: + + unlinker (const char *filename) ATTRIBUTE_NONNULL (1) + : m_filename (filename) + { + gdb_assert (filename != NULL); + } + + ~unlinker () + { + if (m_filename != NULL) + unlink (m_filename); + } + + /* Keep the file, rather than unlink it. */ + void keep () + { + m_filename = NULL; + } + + private: + + const char *m_filename; +}; + +} + +#endif /* GDB_UNLINKER_H */ diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 0780ae0..a021aad 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -69,6 +69,7 @@ #include "filestuff.h" #include "build-id.h" #include "namespace.h" +#include "common/gdb_unlinker.h" #include <fcntl.h> #include <sys/types.h> @@ -23156,16 +23157,6 @@ write_obstack (FILE *file, struct obstack *obstack) error (_("couldn't data write to file")); } -/* Unlink a file if the argument is not NULL. */ - -static void -unlink_if_set (void *p) -{ - char **filename = (char **) p; - if (*filename) - unlink (*filename); -} - /* A helper struct used when iterating over debug_types. */ struct signatured_type_index_data { @@ -23250,7 +23241,7 @@ static void write_psymtabs_to_index (struct objfile *objfile, const char *dir) { struct cleanup *cleanup; - char *filename, *cleanup_filename; + char *filename; struct obstack contents, addr_obstack, constant_pool, symtab_obstack; struct obstack cu_list, types_cu_list; int i; @@ -23280,8 +23271,7 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir) if (!out_file) error (_("Can't open `%s' for writing"), filename); - cleanup_filename = filename; - make_cleanup (unlink_if_set, &cleanup_filename); + gdb::unlinker unlink_file (filename); symtab = create_mapped_symtab (); make_cleanup (cleanup_mapped_symtab, symtab); @@ -23420,9 +23410,8 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir) fclose (out_file); - /* We want to keep the file, so we set cleanup_filename to NULL - here. See unlink_if_set. */ - cleanup_filename = NULL; + /* We want to keep the file. */ + unlink_file.keep (); do_cleanups (cleanup); } diff --git a/gdb/gcore.c b/gdb/gcore.c index 0b05cf9..ed89cc9 100644 --- a/gdb/gcore.c +++ b/gdb/gcore.c @@ -35,6 +35,7 @@ #include "gdb_bfd.h" #include "readline/tilde.h" #include <algorithm> +#include "common/gdb_unlinker.h" /* The largest amount of memory to read from the target at once. We must throttle it to limit the amount of memory used by GDB during @@ -135,59 +136,44 @@ write_gcore_file (bfd *obfd) throw_exception (except); } -static void -do_bfd_delete_cleanup (void *arg) -{ - bfd *obfd = (bfd *) arg; - const char *filename = obfd->filename; - - gdb_bfd_unref ((bfd *) arg); - unlink (filename); -} - /* gcore_command -- implements the 'gcore' command. Generate a core file from the inferior process. */ static void gcore_command (char *args, int from_tty) { - struct cleanup *filename_chain; - struct cleanup *bfd_chain; - char *corefilename; - bfd *obfd; + gdb::unique_xmalloc_ptr<char> corefilename; /* No use generating a corefile without a target process. */ if (!target_has_execution) noprocess (); if (args && *args) - corefilename = tilde_expand (args); + corefilename.reset (tilde_expand (args)); else { /* Default corefile name is "core.PID". */ - corefilename = xstrprintf ("core.%d", ptid_get_pid (inferior_ptid)); + corefilename.reset (xstrprintf ("core.%d", ptid_get_pid (inferior_ptid))); } - filename_chain = make_cleanup (xfree, corefilename); if (info_verbose) fprintf_filtered (gdb_stdout, - "Opening corefile '%s' for output.\n", corefilename); + "Opening corefile '%s' for output.\n", + corefilename.get ()); /* Open the output file. */ - obfd = create_gcore_bfd (corefilename).release (); + gdb_bfd_ref_ptr obfd (create_gcore_bfd (corefilename.get ())); - /* Need a cleanup that will close and delete the file. */ - bfd_chain = make_cleanup (do_bfd_delete_cleanup, obfd); + /* Arrange to unlink the file on failure. */ + gdb::unlinker unlink_file (corefilename.get ()); /* Call worker function. */ - write_gcore_file (obfd); + write_gcore_file (obfd.get ()); /* Succeeded. */ - discard_cleanups (bfd_chain); - gdb_bfd_unref (obfd); + unlink_file.keep (); - fprintf_filtered (gdb_stdout, "Saved corefile %s\n", corefilename); - do_cleanups (filename_chain); + fprintf_filtered (gdb_stdout, "Saved corefile %s\n", corefilename.get ()); } static unsigned long diff --git a/gdb/record-full.c b/gdb/record-full.c index 7ab394b..7499760 100644 --- a/gdb/record-full.c +++ b/gdb/record-full.c @@ -35,6 +35,7 @@ #include "gdb_bfd.h" #include "observer.h" #include "infrun.h" +#include "common/gdb_unlinker.h" #include <signal.h> @@ -2537,17 +2538,6 @@ cmd_record_full_restore (char *args, int from_tty) record_full_open (args, from_tty); } -static void -record_full_save_cleanups (void *data) -{ - bfd *obfd = (bfd *) data; - char *pathname = xstrdup (bfd_get_filename (obfd)); - - gdb_bfd_unref (obfd); - unlink (pathname); - xfree (pathname); -} - /* Save the execution log to a file. We use a modified elf corefile format, with an extra section for our data. */ @@ -2558,9 +2548,7 @@ record_full_save (struct target_ops *self, const char *recfilename) uint32_t magic; struct regcache *regcache; struct gdbarch *gdbarch; - struct cleanup *old_cleanups; struct cleanup *set_cleanups; - bfd *obfd; int save_size = 0; asection *osec = NULL; int bfd_offset = 0; @@ -2571,8 +2559,10 @@ record_full_save (struct target_ops *self, const char *recfilename) recfilename); /* Open the output file. */ - obfd = create_gcore_bfd (recfilename).release (); - old_cleanups = make_cleanup (record_full_save_cleanups, obfd); + gdb_bfd_ref_ptr obfd (create_gcore_bfd (recfilename)); + + /* Arrange to remove the output file on failure. */ + gdb::unlinker unlink_file (recfilename); /* Save the current record entry to "cur_record_full_list". */ cur_record_full_list = record_full_list; @@ -2615,20 +2605,20 @@ record_full_save (struct target_ops *self, const char *recfilename) } /* Make the new bfd section. */ - osec = bfd_make_section_anyway_with_flags (obfd, "precord", + osec = bfd_make_section_anyway_with_flags (obfd.get (), "precord", SEC_HAS_CONTENTS | SEC_READONLY); if (osec == NULL) error (_("Failed to create 'precord' section for corefile %s: %s"), recfilename, bfd_errmsg (bfd_get_error ())); - bfd_set_section_size (obfd, osec, save_size); - bfd_set_section_vma (obfd, osec, 0); - bfd_set_section_alignment (obfd, osec, 0); - bfd_section_lma (obfd, osec) = 0; + bfd_set_section_size (obfd.get (), osec, save_size); + bfd_set_section_vma (obfd.get (), osec, 0); + bfd_set_section_alignment (obfd.get (), osec, 0); + bfd_section_lma (obfd.get (), osec) = 0; /* Save corefile state. */ - write_gcore_file (obfd); + write_gcore_file (obfd.get ()); /* Write out the record log. */ /* Write the magic code. */ @@ -2638,7 +2628,7 @@ record_full_save (struct target_ops *self, const char *recfilename) " Writing 4-byte magic cookie " "RECORD_FULL_FILE_MAGIC (0x%s)\n", phex_nz (magic, 4)); - bfdcore_write (obfd, osec, &magic, sizeof (magic), &bfd_offset); + bfdcore_write (obfd.get (), osec, &magic, sizeof (magic), &bfd_offset); /* Save the entries to recfd and forward execute to the end of record list. */ @@ -2653,7 +2643,7 @@ record_full_save (struct target_ops *self, const char *recfilename) uint64_t addr; type = record_full_list->type; - bfdcore_write (obfd, osec, &type, sizeof (type), &bfd_offset); + bfdcore_write (obfd.get (), osec, &type, sizeof (type), &bfd_offset); switch (record_full_list->type) { @@ -2668,11 +2658,11 @@ record_full_save (struct target_ops *self, const char *recfilename) /* Write regnum. */ regnum = netorder32 (record_full_list->u.reg.num); - bfdcore_write (obfd, osec, ®num, + bfdcore_write (obfd.get (), osec, ®num, sizeof (regnum), &bfd_offset); /* Write regval. */ - bfdcore_write (obfd, osec, + bfdcore_write (obfd.get (), osec, record_full_get_loc (record_full_list), record_full_list->u.reg.len, &bfd_offset); break; @@ -2690,15 +2680,16 @@ record_full_save (struct target_ops *self, const char *recfilename) /* Write memlen. */ len = netorder32 (record_full_list->u.mem.len); - bfdcore_write (obfd, osec, &len, sizeof (len), &bfd_offset); + bfdcore_write (obfd.get (), osec, &len, sizeof (len), + &bfd_offset); /* Write memaddr. */ addr = netorder64 (record_full_list->u.mem.addr); - bfdcore_write (obfd, osec, &addr, + bfdcore_write (obfd.get (), osec, &addr, sizeof (addr), &bfd_offset); /* Write memval. */ - bfdcore_write (obfd, osec, + bfdcore_write (obfd.get (), osec, record_full_get_loc (record_full_list), record_full_list->u.mem.len, &bfd_offset); break; @@ -2712,12 +2703,12 @@ record_full_save (struct target_ops *self, const char *recfilename) (unsigned long) sizeof (count)); /* Write signal value. */ signal = netorder32 (record_full_list->u.end.sigval); - bfdcore_write (obfd, osec, &signal, + bfdcore_write (obfd.get (), osec, &signal, sizeof (signal), &bfd_offset); /* Write insn count. */ count = netorder32 (record_full_list->u.end.insn_num); - bfdcore_write (obfd, osec, &count, + bfdcore_write (obfd.get (), osec, &count, sizeof (count), &bfd_offset); break; } @@ -2746,8 +2737,7 @@ record_full_save (struct target_ops *self, const char *recfilename) } do_cleanups (set_cleanups); - gdb_bfd_unref (obfd); - discard_cleanups (old_cleanups); + unlink_file.keep (); /* Succeeded. */ printf_filtered (_("Saved core file %s with execution log.\n"), -- 2.7.4 ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 3/8] Introduce and use gdb::unlinker 2016-11-29 5:06 ` [RFA 3/8] Introduce and use gdb::unlinker Tom Tromey @ 2016-12-02 13:17 ` Pedro Alves 0 siblings, 0 replies; 50+ messages in thread From: Pedro Alves @ 2016-12-02 13:17 UTC (permalink / raw) To: Tom Tromey, gdb-patches On 11/29/2016 05:05 AM, Tom Tromey wrote: > This introduces a new class, gdb::unlinker, that unlinks a file in the > destructor. The user of this class has the option to preserve the > file instead, by calling the "keep" method. Thanks. > > This patch then changes the spots in gdb that use unlink in a cleanup > to use this class instead. In one spot I went ahead and removed all > the cleanups from the function. > > This fixes one latent bug -- do_bfd_delete_cleanup could refer to > freed memory, by decref'ing the BFD before using its filename. LGTM. Thanks, Pedro Alves ^ permalink raw reply [flat|nested] 50+ messages in thread
* [RFA 4/8] Remove make_cleanup_discard_psymtabs 2016-11-29 5:06 [RFA 0/8] C++-ification series #5 Tom Tromey ` (3 preceding siblings ...) 2016-11-29 5:06 ` [RFA 3/8] Introduce and use gdb::unlinker Tom Tromey @ 2016-11-29 5:06 ` Tom Tromey 2016-12-02 14:21 ` Pedro Alves 2016-11-29 5:06 ` [RFA 5/8] Add value_freer Tom Tromey ` (2 subsequent siblings) 7 siblings, 1 reply; 50+ messages in thread From: Tom Tromey @ 2016-11-29 5:06 UTC (permalink / raw) To: gdb-patches; +Cc: Tom Tromey This removes make_cleanup_discard_psymtabs in favor of a new class. 2016-11-28 Tom Tromey <tom@tromey.com> * dwarf2read.c (dwarf2_build_psymtabs): Use psymtab_discarder. * psympriv.h (make_cleanup_discard_psymtabs): Don't declare. * psymtab.c (discard_psymtabs_upto): Remove. (make_cleanup_discard_psymtabs): Remove. (struct psymtab_state): Remove. --- gdb/ChangeLog | 8 ++++++++ gdb/dwarf2read.c | 5 ++--- gdb/psympriv.h | 36 +++++++++++++++++++++++++++++++++++- gdb/psymtab.c | 38 -------------------------------------- 4 files changed, 45 insertions(+), 42 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 18814d3..d00862a 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,13 @@ 2016-11-28 Tom Tromey <tom@tromey.com> + * dwarf2read.c (dwarf2_build_psymtabs): Use psymtab_discarder. + * psympriv.h (make_cleanup_discard_psymtabs): Don't declare. + * psymtab.c (discard_psymtabs_upto): Remove. + (make_cleanup_discard_psymtabs): Remove. + (struct psymtab_state): Remove. + +2016-11-28 Tom Tromey <tom@tromey.com> + * record-full.c (record_full_save_cleanups): Remove. (record_full_save): Use gdb::unlinker. * gcore.c (do_bfd_delete_cleanup): Remove. diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index a021aad..0c5d374 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -4268,10 +4268,9 @@ dwarf2_build_psymtabs (struct objfile *objfile) /* This isn't really ideal: all the data we allocate on the objfile's obstack is still uselessly kept around. However, freeing it seems unsafe. */ - struct cleanup *cleanups = make_cleanup_discard_psymtabs (objfile); - + psymtab_discarder psymtabs (objfile); dwarf2_build_psymtabs_hard (objfile); - discard_cleanups (cleanups); + psymtabs.keep (); } CATCH (except, RETURN_MASK_ERROR) { diff --git a/gdb/psympriv.h b/gdb/psympriv.h index 915208e..846e970 100644 --- a/gdb/psympriv.h +++ b/gdb/psympriv.h @@ -21,6 +21,7 @@ #define PSYMPRIV_H #include "psymtab.h" +#include "objfiles.h" struct psymbol_allocation_list; @@ -225,7 +226,40 @@ extern struct partial_symtab *allocate_psymtab (const char *, extern void discard_psymtab (struct objfile *, struct partial_symtab *); -extern struct cleanup *make_cleanup_discard_psymtabs (struct objfile *); +/* Used when recording partial symbol tables. On destruction, + discards any partial symbol tables that have been built. However, + the tables can be kept by calling the "keep" method. */ +class psymtab_discarder +{ + public: + + psymtab_discarder (struct objfile *objfile) + : m_objfile (objfile), + m_psymtab (objfile->psymtabs) + { + } + + ~psymtab_discarder () + { + if (m_objfile != NULL) + while (m_objfile->psymtabs != m_psymtab) + discard_psymtab (m_objfile, m_objfile->psymtabs); + } + + /* Keep any partial symbol tables that were built. */ + void keep () + { + m_objfile = NULL; + } + + private: + + /* The objfile. If NULL this serves as a sentinel to indicate that + the psymtabs should be kept. */ + struct objfile *m_objfile; + /* How far back to free. */ + struct partial_symtab *m_psymtab; +}; /* Traverse all psymtabs in one objfile. */ diff --git a/gdb/psymtab.c b/gdb/psymtab.c index 825df77..31731ca 100644 --- a/gdb/psymtab.c +++ b/gdb/psymtab.c @@ -1836,44 +1836,6 @@ discard_psymtab (struct objfile *objfile, struct partial_symtab *pst) objfile->free_psymtabs = pst; } -/* An object of this type is passed to discard_psymtabs_upto. */ - -struct psymtab_state -{ - /* The objfile where psymtabs are discarded. */ - - struct objfile *objfile; - - /* The first psymtab to save. */ - - struct partial_symtab *save; -}; - -/* A cleanup function used by make_cleanup_discard_psymtabs. */ - -static void -discard_psymtabs_upto (void *arg) -{ - struct psymtab_state *state = (struct psymtab_state *) arg; - - while (state->objfile->psymtabs != state->save) - discard_psymtab (state->objfile, state->objfile->psymtabs); -} - -/* Return a new cleanup that discards all psymtabs created in OBJFILE - after this function is called. */ - -struct cleanup * -make_cleanup_discard_psymtabs (struct objfile *objfile) -{ - struct psymtab_state *state = XNEW (struct psymtab_state); - - state->objfile = objfile; - state->save = objfile->psymtabs; - - return make_cleanup_dtor (discard_psymtabs_upto, state, xfree); -} - \f /* We need to pass a couple of items to the addrmap_foreach function, -- 2.7.4 ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 4/8] Remove make_cleanup_discard_psymtabs 2016-11-29 5:06 ` [RFA 4/8] Remove make_cleanup_discard_psymtabs Tom Tromey @ 2016-12-02 14:21 ` Pedro Alves 0 siblings, 0 replies; 50+ messages in thread From: Pedro Alves @ 2016-12-02 14:21 UTC (permalink / raw) To: Tom Tromey, gdb-patches On 11/29/2016 05:05 AM, Tom Tromey wrote: > This removes make_cleanup_discard_psymtabs in favor of a new class. > > 2016-11-28 Tom Tromey <tom@tromey.com> > > * dwarf2read.c (dwarf2_build_psymtabs): Use psymtab_discarder. > * psympriv.h (make_cleanup_discard_psymtabs): Don't declare. > * psymtab.c (discard_psymtabs_upto): Remove. > (make_cleanup_discard_psymtabs): Remove. > (struct psymtab_state): Remove. OK. Thanks, Pedro Alves ^ permalink raw reply [flat|nested] 50+ messages in thread
* [RFA 5/8] Add value_freer 2016-11-29 5:06 [RFA 0/8] C++-ification series #5 Tom Tromey ` (4 preceding siblings ...) 2016-11-29 5:06 ` [RFA 4/8] Remove make_cleanup_discard_psymtabs Tom Tromey @ 2016-11-29 5:06 ` Tom Tromey 2016-12-02 14:24 ` Pedro Alves 2016-11-29 5:06 ` [RFA 2/8] Use class to manage BFD reference counts Tom Tromey 2016-11-29 5:06 ` [RFA 6/8] Use value_freer in dwarf2_evaluate_loc_desc_full Tom Tromey 7 siblings, 1 reply; 50+ messages in thread From: Tom Tromey @ 2016-11-29 5:06 UTC (permalink / raw) To: gdb-patches; +Cc: Tom Tromey This adds a value_freer class, that records the value mark in the constructor and then calls value_free_to_mark in the destructor. It then updates various spots in gdb to use this class, rather than a cleanup. It would be better overall to replace "struct value *" with a shared_ptr, maybe eliminating the need for this class (watchpoints would perhaps need some new mechanism as well). However, that's difficult to do. 2016-11-28 Tom Tromey <tom@tromey.com> * python/py-value.c (valpy_dereference, valpy_referenced_value) (valpy_reference_value, valpy_const_value, valpy_get_address) (valpy_get_dynamic_type, valpy_lazy_string, valpy_do_cast) (valpy_getitem, valpy_call, valpy_binop_throw, valpy_negative) (valpy_absolute, valpy_richcompare_throw): Use value_freer. * dwarf2loc.c (dwarf2_loc_desc_get_symbol_read_needs): Use value_freer. * dwarf2-frame.c (execute_stack_op): Use value_freer. * value.h (value_freer): New class. --- gdb/ChangeLog | 12 ++++++++++ gdb/dwarf2-frame.c | 5 +---- gdb/dwarf2loc.c | 8 ++----- gdb/python/py-value.c | 62 +++++++++++++++------------------------------------ gdb/value.h | 22 ++++++++++++++++++ 5 files changed, 55 insertions(+), 54 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index d00862a..6197bfb 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,17 @@ 2016-11-28 Tom Tromey <tom@tromey.com> + * python/py-value.c (valpy_dereference, valpy_referenced_value) + (valpy_reference_value, valpy_const_value, valpy_get_address) + (valpy_get_dynamic_type, valpy_lazy_string, valpy_do_cast) + (valpy_getitem, valpy_call, valpy_binop_throw, valpy_negative) + (valpy_absolute, valpy_richcompare_throw): Use value_freer. + * dwarf2loc.c (dwarf2_loc_desc_get_symbol_read_needs): Use + value_freer. + * dwarf2-frame.c (execute_stack_op): Use value_freer. + * value.h (value_freer): New class. + +2016-11-28 Tom Tromey <tom@tromey.com> + * dwarf2read.c (dwarf2_build_psymtabs): Use psymtab_discarder. * psympriv.h (make_cleanup_discard_psymtabs): Don't declare. * psymtab.c (discard_psymtabs_upto): Remove. diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c index beab304..6e5e4fd 100644 --- a/gdb/dwarf2-frame.c +++ b/gdb/dwarf2-frame.c @@ -403,10 +403,9 @@ execute_stack_op (const gdb_byte *exp, ULONGEST len, int addr_size, CORE_ADDR initial, int initial_in_stack_memory) { CORE_ADDR result; - struct cleanup *old_chain; dwarf_expr_executor ctx; - old_chain = make_cleanup_value_free_to_mark (value_mark ()); + value_freer free_values; ctx.this_frame = this_frame; ctx.gdbarch = get_frame_arch (this_frame); @@ -430,8 +429,6 @@ execute_stack_op (const gdb_byte *exp, ULONGEST len, int addr_size, Not implemented: computing unwound register using explicit value operator")); } - do_cleanups (old_chain); - return result; } \f diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c index 6284e68..0d8a47c 100644 --- a/gdb/dwarf2loc.c +++ b/gdb/dwarf2loc.c @@ -2840,16 +2840,14 @@ dwarf2_loc_desc_get_symbol_read_needs (const gdb_byte *data, size_t size, struct dwarf2_per_cu_data *per_cu) { int in_reg; - struct cleanup *old_chain; struct objfile *objfile = dwarf2_per_cu_objfile (per_cu); + value_freer free_values; + symbol_needs_eval_context ctx; ctx.needs = SYMBOL_NEEDS_NONE; ctx.per_cu = per_cu; - - old_chain = make_cleanup_value_free_to_mark (value_mark ()); - ctx.gdbarch = get_objfile_arch (objfile); ctx.addr_size = dwarf2_per_cu_addr_size (per_cu); ctx.ref_addr_size = dwarf2_per_cu_ref_addr_size (per_cu); @@ -2870,8 +2868,6 @@ dwarf2_loc_desc_get_symbol_read_needs (const gdb_byte *data, size_t size, in_reg = 1; } - do_cleanups (old_chain); - if (in_reg) ctx.needs = SYMBOL_NEEDS_FRAME; return ctx.needs; diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c index c1f3e16..2afa4e6 100644 --- a/gdb/python/py-value.c +++ b/gdb/python/py-value.c @@ -178,11 +178,10 @@ valpy_dereference (PyObject *self, PyObject *args) TRY { struct value *res_val; - struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); + value_freer free_values; res_val = value_ind (((value_object *) self)->value); result = value_to_value_object (res_val); - do_cleanups (cleanup); } CATCH (except, RETURN_MASK_ALL) { @@ -209,7 +208,7 @@ valpy_referenced_value (PyObject *self, PyObject *args) TRY { struct value *self_val, *res_val; - struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); + value_freer free_values; self_val = ((value_object *) self)->value; switch (TYPE_CODE (check_typedef (value_type (self_val)))) @@ -226,7 +225,6 @@ valpy_referenced_value (PyObject *self, PyObject *args) } result = value_to_value_object (res_val); - do_cleanups (cleanup); } CATCH (except, RETURN_MASK_ALL) { @@ -247,12 +245,10 @@ valpy_reference_value (PyObject *self, PyObject *args) TRY { struct value *self_val; - struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); + value_freer free_values; self_val = ((value_object *) self)->value; result = value_to_value_object (value_ref (self_val)); - - do_cleanups (cleanup); } CATCH (except, RETURN_MASK_ALL) { @@ -273,13 +269,11 @@ valpy_const_value (PyObject *self, PyObject *args) TRY { struct value *self_val, *res_val; - struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); + value_freer free_values; self_val = ((value_object *) self)->value; res_val = make_cv_value (1, 0, self_val); result = value_to_value_object (res_val); - - do_cleanups (cleanup); } CATCH (except, RETURN_MASK_ALL) { @@ -301,12 +295,10 @@ valpy_get_address (PyObject *self, void *closure) TRY { struct value *res_val; - struct cleanup *cleanup - = make_cleanup_value_free_to_mark (value_mark ()); + value_freer free_values; res_val = value_addr (val_obj->value); val_obj->address = value_to_value_object (res_val); - do_cleanups (cleanup); } CATCH (except, RETURN_MASK_ALL) { @@ -354,7 +346,7 @@ valpy_get_dynamic_type (PyObject *self, void *closure) TRY { struct value *val = obj->value; - struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); + value_freer free_values; type = value_type (val); type = check_typedef (type); @@ -387,8 +379,6 @@ valpy_get_dynamic_type (PyObject *self, void *closure) /* Re-use object's static type. */ type = NULL; } - - do_cleanups (cleanup); } CATCH (except, RETURN_MASK_ALL) { @@ -428,7 +418,7 @@ valpy_lazy_string (PyObject *self, PyObject *args, PyObject *kw) TRY { - struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); + value_freer free_values; if (TYPE_CODE (value_type (value)) == TYPE_CODE_PTR) value = value_ind (value); @@ -436,8 +426,6 @@ valpy_lazy_string (PyObject *self, PyObject *args, PyObject *kw) str_obj = gdbpy_create_lazy_string_object (value_address (value), length, user_encoding, value_type (value)); - - do_cleanups (cleanup); } CATCH (except, RETURN_MASK_ALL) { @@ -514,7 +502,7 @@ valpy_do_cast (PyObject *self, PyObject *args, enum exp_opcode op) { struct value *val = ((value_object *) self)->value; struct value *res_val; - struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); + value_freer free_values; if (op == UNOP_DYNAMIC_CAST) res_val = value_dynamic_cast (type, val); @@ -527,7 +515,6 @@ valpy_do_cast (PyObject *self, PyObject *args, enum exp_opcode op) } result = value_to_value_object (res_val); - do_cleanups (cleanup); } CATCH (except, RETURN_MASK_ALL) { @@ -737,8 +724,8 @@ valpy_getitem (PyObject *self, PyObject *key) TRY { struct value *tmp = self_value->value; - struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); struct value *res_val = NULL; + value_freer free_values; if (field) res_val = value_struct_elt (&tmp, NULL, field.get (), NULL, @@ -783,7 +770,6 @@ valpy_getitem (PyObject *self, PyObject *key) if (res_val) result = value_to_value_object (res_val); - do_cleanups (cleanup); } CATCH (ex, RETURN_MASK_ALL) { @@ -861,12 +847,11 @@ valpy_call (PyObject *self, PyObject *args, PyObject *keywords) TRY { - struct cleanup *cleanup = make_cleanup_value_free_to_mark (mark); + value_freer free_values; struct value *return_value; return_value = call_function_by_hand (function, args_count, vargs); result = value_to_value_object (return_value); - do_cleanups (cleanup); } CATCH (except, RETURN_MASK_ALL) { @@ -1014,11 +999,12 @@ valpy_binop_throw (enum valpy_opcode opcode, PyObject *self, PyObject *other) PyObject *result = NULL; struct value *arg1, *arg2; - struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); struct value *res_val = NULL; enum exp_opcode op = OP_NULL; int handled = 0; + value_freer free_values; + /* If the gdb.Value object is the second operand, then it will be passed to us as the OTHER argument, and SELF will be an entirely different kind of object, altogether. Because of this, we can't @@ -1026,17 +1012,11 @@ valpy_binop_throw (enum valpy_opcode opcode, PyObject *self, PyObject *other) python as well. */ arg1 = convert_value_from_python (self); if (arg1 == NULL) - { - do_cleanups (cleanup); - return NULL; - } + return NULL; arg2 = convert_value_from_python (other); if (arg2 == NULL) - { - do_cleanups (cleanup); - return NULL; - } + return NULL; switch (opcode) { @@ -1130,7 +1110,6 @@ valpy_binop_throw (enum valpy_opcode opcode, PyObject *self, PyObject *other) if (res_val) result = value_to_value_object (res_val); - do_cleanups (cleanup); return result; } @@ -1209,12 +1188,11 @@ valpy_negative (PyObject *self) TRY { /* Perhaps overkill, but consistency has some virtue. */ - struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); + value_freer free_values; struct value *val; val = value_neg (((value_object *) self)->value); result = value_to_value_object (val); - do_cleanups (cleanup); } CATCH (except, RETURN_MASK_ALL) { @@ -1239,12 +1217,10 @@ valpy_absolute (PyObject *self) TRY { - struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); + value_freer free_values; if (value_less (value, value_zero (value_type (value), not_lval))) isabs = 0; - - do_cleanups (cleanup); } CATCH (except, RETURN_MASK_ALL) { @@ -1362,15 +1338,14 @@ valpy_richcompare_throw (PyObject *self, PyObject *other, int op) int result; struct value *value_other; struct value *value_self; - struct value *mark = value_mark (); struct cleanup *cleanup; + value_freer free_values; + value_other = convert_value_from_python (other); if (value_other == NULL) return -1; - cleanup = make_cleanup_value_free_to_mark (mark); - value_self = ((value_object *) self)->value; switch (op) @@ -1403,7 +1378,6 @@ valpy_richcompare_throw (PyObject *self, PyObject *other, int op) break; } - do_cleanups (cleanup); return result; } diff --git a/gdb/value.h b/gdb/value.h index f776323..399bf48 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -714,6 +714,28 @@ extern struct value *value_mark (void); extern void value_free_to_mark (const struct value *mark); +/* A helper class that uses value_mark at construction time and calls + value_free_to_mark in the destructor. This is used to clear out + temporary values created during the lifetime of this object. */ +class value_freer +{ + public: + + value_freer () + : m_value (value_mark ()) + { + } + + ~value_freer () + { + value_free_to_mark (m_value); + } + + private: + + const struct value *m_value; +}; + extern struct value *value_cstring (const char *ptr, ssize_t len, struct type *char_type); extern struct value *value_string (const char *ptr, ssize_t len, -- 2.7.4 ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 5/8] Add value_freer 2016-11-29 5:06 ` [RFA 5/8] Add value_freer Tom Tromey @ 2016-12-02 14:24 ` Pedro Alves 0 siblings, 0 replies; 50+ messages in thread From: Pedro Alves @ 2016-12-02 14:24 UTC (permalink / raw) To: Tom Tromey, gdb-patches On 11/29/2016 05:05 AM, Tom Tromey wrote: > This adds a value_freer class, that records the value mark in the > constructor and then calls value_free_to_mark in the destructor. It > then updates various spots in gdb to use this class, rather than a > cleanup. > > It would be better overall to replace "struct value *" with a > shared_ptr, maybe eliminating the need for this class (watchpoints > would perhaps need some new mechanism as well). However, that's > difficult to do. > > 2016-11-28 Tom Tromey <tom@tromey.com> > > * python/py-value.c (valpy_dereference, valpy_referenced_value) > (valpy_reference_value, valpy_const_value, valpy_get_address) > (valpy_get_dynamic_type, valpy_lazy_string, valpy_do_cast) > (valpy_getitem, valpy_call, valpy_binop_throw, valpy_negative) > (valpy_absolute, valpy_richcompare_throw): Use value_freer. > * dwarf2loc.c (dwarf2_loc_desc_get_symbol_read_needs): Use > value_freer. > * dwarf2-frame.c (execute_stack_op): Use value_freer. > * value.h (value_freer): New class. OK. Thanks, Pedro Alves ^ permalink raw reply [flat|nested] 50+ messages in thread
* [RFA 2/8] Use class to manage BFD reference counts 2016-11-29 5:06 [RFA 0/8] C++-ification series #5 Tom Tromey ` (5 preceding siblings ...) 2016-11-29 5:06 ` [RFA 5/8] Add value_freer Tom Tromey @ 2016-11-29 5:06 ` Tom Tromey 2016-12-02 13:05 ` Pedro Alves 2016-11-29 5:06 ` [RFA 6/8] Use value_freer in dwarf2_evaluate_loc_desc_full Tom Tromey 7 siblings, 1 reply; 50+ messages in thread From: Tom Tromey @ 2016-11-29 5:06 UTC (permalink / raw) To: gdb-patches; +Cc: Tom Tromey This introduces a new specialization of gdb::ref_ptr that can be used to manage BFD reference counts. Then it changes most places in gdb to use this new class, rather than explicit reference-counting or cleanups. This patch removes make_cleanup_bfd_unref. If you look you will see a couple of spots using "release" where a use of gdb_bfd_ref_ptr would be cleaner. These will be fixed in the next patch. I think this patch fixes some latent bugs. For example, it seems to me that previously objfpy_add_separate_debug_file leaked a BFD. I'm not 100% certain that the macho_symfile_read_all_oso change is correct. The existing code here is hard for me to follow. One goal of this sort of automated reference counting, though, is to make it more difficult to make logic errors; so hopefully the code is clear now. 2016-11-28 Tom Tromey <tom@tromey.com> * windows-tdep.c (windows_xfer_shared_library): Update. * windows-nat.c (windows_make_so): Update. * utils.h (make_cleanup_bfd_unref): Remove. * utils.c (do_bfd_close_cleanup, make_cleanup_bfd_unref): Remove. * symfile.h (symfile_bfd_open) (find_separate_debug_file_in_section): Return gdb_bfd_ref_ptr. * symfile.c (read_symbols, symbol_file_add) (separate_debug_file_exists): Update. (symfile_bfd_open): Return gdb_bfd_ref_ptr. (generic_load, reread_symbols): Update. * symfile-mem.c (symbol_file_add_from_memory): Update. * spu-linux-nat.c (spu_bfd_open): Return gdb_bfd_ref_ptr. (spu_symbol_file_add_from_memory): Update. * solist.h (struct target_so_ops) <bfd_open>: Return gdb_bfd_ref_ptr. (solib_bfd_fopen, solib_bfd_open): Return gdb_bfd_ref_ptr. * solib.c (solib_bfd_fopen, solib_bfd_open): Return gdb_bfd_ref_ptr. (solib_map_sections, reload_shared_libraries_1): Update. * solib-svr4.c (enable_break): Update. * solib-spu.c (spu_bfd_fopen): Return gdb_bfd_ref_ptr. * solib-frv.c (enable_break2): Update. * solib-dsbt.c (enable_break): Update. * solib-darwin.c (gdb_bfd_mach_o_fat_extract): Return gdb_bfd_ref_ptr. (darwin_solib_get_all_image_info_addr_at_init): Update. (darwin_bfd_open): Return gdb_bfd_ref_ptr. * solib-aix.c (solib_aix_bfd_open): Return gdb_bfd_ref_ptr. * record-full.c (record_full_save): Update. * python/py-objfile.c (objfpy_add_separate_debug_file): Update. * procfs.c (insert_dbx_link_bpt_in_file): Update. * minidebug.c (find_separate_debug_file_in_section): Return gdb_bfd_ref_ptr. * machoread.c (macho_add_oso_symfile): Change abfd to gdb_bfd_ref_ptr. (macho_symfile_read_all_oso): Update. (macho_check_dsym): Return gdb_bfd_ref_ptr. (macho_symfile_read): Update. * jit.c (bfd_open_from_target_memory): Return gdb_bfd_ref_ptr. (jit_bfd_try_read_symtab): Update. * gdb_bfd.h (gdb_bfd_open, gdb_bfd_fopen, gdb_bfd_openr) (gdb_bfd_openw, gdb_bfd_openr_iovec) (gdb_bfd_openr_next_archived_file, gdb_bfd_fdopenr): Return gdb_bfd_ref_ptr. (gdb_bfd_ref_policy): New struct. (gdb_bfd_ref_ptr): New typedef. * gdb_bfd.c (gdb_bfd_open, gdb_bfd_fopen, gdb_bfd_openr) (gdb_bfd_openw, gdb_bfd_openr_iovec) (gdb_bfd_openr_next_archived_file, gdb_bfd_fdopenr): Return gdb_bfd_ref_ptr. * gcore.h (create_gcore_bfd): Return gdb_bfd_ref_ptr. * gcore.c (create_gcore_bfd): Return gdb_bfd_ref_ptr. (gcore_command): Update. * exec.c (exec_file_attach): Update. * elfread.c (elf_symfile_read): Update. * dwarf2read.c (dwarf2_get_dwz_file): Update. (try_open_dwop_file, open_dwo_file): Return gdb_bfd_ref_ptr. (open_and_init_dwo_file): Update. (open_dwp_file): Return gdb_bfd_ref_ptr. (open_and_init_dwp_file): Update. * corelow.c (core_open): Update. * compile/compile-object-load.c (compile_object_load): Update. * common/gdb_ref_ptr.h (ref_ptr::operator->): New operator. * coffread.c (coff_symfile_read): Update. * cli/cli-dump.c (bfd_openr_or_error, bfd_openw_or_error): Return gdb_bfd_ref_ptr. Rename. (dump_bfd_file, restore_command): Update. * build-id.h (build_id_to_debug_bfd): Return gdb_bfd_ref_ptr. * build-id.c (build_id_to_debug_bfd): Return gdb_bfd_ref_ptr. (find_separate_debug_file_by_buildid): Update. --- gdb/ChangeLog | 73 ++++++++++++++++++++++++++++++++ gdb/build-id.c | 30 +++++-------- gdb/build-id.h | 6 ++- gdb/cli/cli-dump.c | 55 +++++++++++------------- gdb/coffread.c | 6 +-- gdb/common/gdb_ref_ptr.h | 6 +++ gdb/compile/compile-object-load.c | 20 ++++----- gdb/corelow.c | 14 +++---- gdb/dwarf2read.c | 77 +++++++++++++++------------------- gdb/elfread.c | 17 ++++---- gdb/exec.c | 12 ++++-- gdb/gcore.c | 12 +++--- gdb/gcore.h | 4 +- gdb/gdb_bfd.c | 34 +++++++-------- gdb/gdb_bfd.h | 81 +++++++++++++++++++++-------------- gdb/jit.c | 30 ++++++------- gdb/machoread.c | 88 +++++++++++++++------------------------ gdb/minidebug.c | 16 ++++--- gdb/procfs.c | 11 ++--- gdb/python/py-objfile.c | 4 +- gdb/record-full.c | 2 +- gdb/solib-aix.c | 74 +++++++++++++------------------- gdb/solib-darwin.c | 67 +++++++++++------------------ gdb/solib-dsbt.c | 23 +++++----- gdb/solib-frv.c | 28 +++++-------- gdb/solib-spu.c | 37 ++++++++-------- gdb/solib-svr4.c | 31 +++++++------- gdb/solib.c | 50 ++++++++++------------ gdb/solist.h | 7 ++-- gdb/spu-linux-nat.c | 40 ++++++++---------- gdb/symfile-mem.c | 7 ++-- gdb/symfile.c | 81 +++++++++++++---------------------- gdb/symfile.h | 5 ++- gdb/utils.c | 12 ------ gdb/utils.h | 2 - gdb/windows-nat.c | 19 ++++----- gdb/windows-tdep.c | 6 +-- 37 files changed, 516 insertions(+), 571 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index f455f7f..ce21840 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,78 @@ 2016-11-28 Tom Tromey <tom@tromey.com> + * windows-tdep.c (windows_xfer_shared_library): Update. + * windows-nat.c (windows_make_so): Update. + * utils.h (make_cleanup_bfd_unref): Remove. + * utils.c (do_bfd_close_cleanup, make_cleanup_bfd_unref): Remove. + * symfile.h (symfile_bfd_open) + (find_separate_debug_file_in_section): Return gdb_bfd_ref_ptr. + * symfile.c (read_symbols, symbol_file_add) + (separate_debug_file_exists): Update. + (symfile_bfd_open): Return gdb_bfd_ref_ptr. + (generic_load, reread_symbols): Update. + * symfile-mem.c (symbol_file_add_from_memory): Update. + * spu-linux-nat.c (spu_bfd_open): Return gdb_bfd_ref_ptr. + (spu_symbol_file_add_from_memory): Update. + * solist.h (struct target_so_ops) <bfd_open>: Return + gdb_bfd_ref_ptr. + (solib_bfd_fopen, solib_bfd_open): Return gdb_bfd_ref_ptr. + * solib.c (solib_bfd_fopen, solib_bfd_open): Return + gdb_bfd_ref_ptr. + (solib_map_sections, reload_shared_libraries_1): Update. + * solib-svr4.c (enable_break): Update. + * solib-spu.c (spu_bfd_fopen): Return gdb_bfd_ref_ptr. + * solib-frv.c (enable_break2): Update. + * solib-dsbt.c (enable_break): Update. + * solib-darwin.c (gdb_bfd_mach_o_fat_extract): Return + gdb_bfd_ref_ptr. + (darwin_solib_get_all_image_info_addr_at_init): Update. + (darwin_bfd_open): Return gdb_bfd_ref_ptr. + * solib-aix.c (solib_aix_bfd_open): Return gdb_bfd_ref_ptr. + * record-full.c (record_full_save): Update. + * python/py-objfile.c (objfpy_add_separate_debug_file): Update. + * procfs.c (insert_dbx_link_bpt_in_file): Update. + * minidebug.c (find_separate_debug_file_in_section): Return + gdb_bfd_ref_ptr. + * machoread.c (macho_add_oso_symfile): Change abfd to + gdb_bfd_ref_ptr. + (macho_symfile_read_all_oso): Update. + (macho_check_dsym): Return gdb_bfd_ref_ptr. + (macho_symfile_read): Update. + * jit.c (bfd_open_from_target_memory): Return gdb_bfd_ref_ptr. + (jit_bfd_try_read_symtab): Update. + * gdb_bfd.h (gdb_bfd_open, gdb_bfd_fopen, gdb_bfd_openr) + (gdb_bfd_openw, gdb_bfd_openr_iovec) + (gdb_bfd_openr_next_archived_file, gdb_bfd_fdopenr): Return + gdb_bfd_ref_ptr. + (gdb_bfd_ref_policy): New struct. + (gdb_bfd_ref_ptr): New typedef. + * gdb_bfd.c (gdb_bfd_open, gdb_bfd_fopen, gdb_bfd_openr) + (gdb_bfd_openw, gdb_bfd_openr_iovec) + (gdb_bfd_openr_next_archived_file, gdb_bfd_fdopenr): Return + gdb_bfd_ref_ptr. + * gcore.h (create_gcore_bfd): Return gdb_bfd_ref_ptr. + * gcore.c (create_gcore_bfd): Return gdb_bfd_ref_ptr. + (gcore_command): Update. + * exec.c (exec_file_attach): Update. + * elfread.c (elf_symfile_read): Update. + * dwarf2read.c (dwarf2_get_dwz_file): Update. + (try_open_dwop_file, open_dwo_file): Return gdb_bfd_ref_ptr. + (open_and_init_dwo_file): Update. + (open_dwp_file): Return gdb_bfd_ref_ptr. + (open_and_init_dwp_file): Update. + * corelow.c (core_open): Update. + * compile/compile-object-load.c (compile_object_load): Update. + * common/gdb_ref_ptr.h (ref_ptr::operator->): New operator. + * coffread.c (coff_symfile_read): Update. + * cli/cli-dump.c (bfd_openr_or_error, bfd_openw_or_error): Return + gdb_bfd_ref_ptr. Rename. + (dump_bfd_file, restore_command): Update. + * build-id.h (build_id_to_debug_bfd): Return gdb_bfd_ref_ptr. + * build-id.c (build_id_to_debug_bfd): Return gdb_bfd_ref_ptr. + (find_separate_debug_file_by_buildid): Update. + +2016-11-28 Tom Tromey <tom@tromey.com> + * common/gdb_ref_ptr.h: New file. * python/py-ref.h (struct gdbpy_ref_policy): New. (gdbpy_ref): Now a typedef. diff --git a/gdb/build-id.c b/gdb/build-id.c index 886f2d7..029cb4d 100644 --- a/gdb/build-id.c +++ b/gdb/build-id.c @@ -67,14 +67,14 @@ build_id_verify (bfd *abfd, size_t check_len, const bfd_byte *check) /* See build-id.h. */ -bfd * +gdb_bfd_ref_ptr build_id_to_debug_bfd (size_t build_id_len, const bfd_byte *build_id) { char *link, *debugdir; VEC (char_ptr) *debugdir_vec; struct cleanup *back_to; int ix; - bfd *abfd = NULL; + gdb_bfd_ref_ptr abfd; int alloc_len; /* DEBUG_FILE_DIRECTORY/.build-id/ab/cdef */ @@ -127,11 +127,10 @@ build_id_to_debug_bfd (size_t build_id_len, const bfd_byte *build_id) if (abfd == NULL) continue; - if (build_id_verify (abfd, build_id_len, build_id)) + if (build_id_verify (abfd.get(), build_id_len, build_id)) break; - gdb_bfd_unref (abfd); - abfd = NULL; + abfd.release (); } do_cleanups (back_to); @@ -148,25 +147,16 @@ find_separate_debug_file_by_buildid (struct objfile *objfile) build_id = build_id_bfd_get (objfile->obfd); if (build_id != NULL) { - bfd *abfd; - - abfd = build_id_to_debug_bfd (build_id->size, build_id->data); + gdb_bfd_ref_ptr abfd (build_id_to_debug_bfd (build_id->size, + build_id->data)); /* Prevent looping on a stripped .debug file. */ if (abfd != NULL - && filename_cmp (bfd_get_filename (abfd), + && filename_cmp (bfd_get_filename (abfd.get ()), objfile_name (objfile)) == 0) - { - warning (_("\"%s\": separate debug info file has no debug info"), - bfd_get_filename (abfd)); - gdb_bfd_unref (abfd); - } + warning (_("\"%s\": separate debug info file has no debug info"), + bfd_get_filename (abfd.get ())); else if (abfd != NULL) - { - char *result = xstrdup (bfd_get_filename (abfd)); - - gdb_bfd_unref (abfd); - return result; - } + return xstrdup (bfd_get_filename (abfd.get ())); } return NULL; } diff --git a/gdb/build-id.h b/gdb/build-id.h index ddf0765..6c37dee 100644 --- a/gdb/build-id.h +++ b/gdb/build-id.h @@ -20,6 +20,8 @@ #ifndef BUILD_ID_H #define BUILD_ID_H +#include "gdb_bfd.h" + /* Locate NT_GNU_BUILD_ID from ABFD and return its content. */ extern const struct bfd_build_id *build_id_bfd_get (bfd *abfd); @@ -35,8 +37,8 @@ extern int build_id_verify (bfd *abfd, return NULL. The returned reference to the BFD must be released by the caller. */ -extern bfd *build_id_to_debug_bfd (size_t build_id_len, - const bfd_byte *build_id); +extern gdb_bfd_ref_ptr build_id_to_debug_bfd (size_t build_id_len, + const bfd_byte *build_id); /* Find the separate debug file for OBJFILE, by using the build-id associated with OBJFILE's BFD. If successful, returns a malloc'd diff --git a/gdb/cli/cli-dump.c b/gdb/cli/cli-dump.c index 781c638..ace721a 100644 --- a/gdb/cli/cli-dump.c +++ b/gdb/cli/cli-dump.c @@ -103,45 +103,40 @@ fopen_with_cleanup (const char *filename, const char *mode) return file; } -static bfd * -bfd_openr_with_cleanup (const char *filename, const char *target) +static gdb_bfd_ref_ptr +bfd_openr_or_error (const char *filename, const char *target) { - bfd *ibfd; - - ibfd = gdb_bfd_openr (filename, target); + gdb_bfd_ref_ptr ibfd (gdb_bfd_openr (filename, target)); if (ibfd == NULL) - error (_("Failed to open %s: %s."), filename, + error (_("Failed to open %s: %s."), filename, bfd_errmsg (bfd_get_error ())); - make_cleanup_bfd_unref (ibfd); - if (!bfd_check_format (ibfd, bfd_object)) + if (!bfd_check_format (ibfd.get (), bfd_object)) error (_("'%s' is not a recognized file format."), filename); return ibfd; } -static bfd * -bfd_openw_with_cleanup (const char *filename, const char *target, - const char *mode) +static gdb_bfd_ref_ptr +bfd_openw_or_error (const char *filename, const char *target, const char *mode) { - bfd *obfd; + gdb_bfd_ref_ptr obfd; if (*mode == 'w') /* Write: create new file */ { obfd = gdb_bfd_openw (filename, target); if (obfd == NULL) - error (_("Failed to open %s: %s."), filename, + error (_("Failed to open %s: %s."), filename, bfd_errmsg (bfd_get_error ())); - make_cleanup_bfd_unref (obfd); - if (!bfd_set_format (obfd, bfd_object)) - error (_("bfd_openw_with_cleanup: %s."), bfd_errmsg (bfd_get_error ())); + if (!bfd_set_format (obfd.get (), bfd_object)) + error (_("bfd_openw_or_error: %s."), bfd_errmsg (bfd_get_error ())); } else if (*mode == 'a') /* Append to existing file. */ { /* FIXME -- doesn't work... */ error (_("bfd_openw does not work with append.")); } else - error (_("bfd_openw_with_cleanup: unknown mode %s."), mode); + error (_("bfd_openw_or_error: unknown mode %s."), mode); return obfd; } @@ -187,20 +182,19 @@ dump_bfd_file (const char *filename, const char *mode, const char *target, CORE_ADDR vaddr, const bfd_byte *buf, ULONGEST len) { - bfd *obfd; asection *osection; - obfd = bfd_openw_with_cleanup (filename, target, mode); - osection = bfd_make_section_anyway (obfd, ".newsec"); - bfd_set_section_size (obfd, osection, len); - bfd_set_section_vma (obfd, osection, vaddr); - bfd_set_section_alignment (obfd, osection, 0); - bfd_set_section_flags (obfd, osection, (SEC_HAS_CONTENTS - | SEC_ALLOC - | SEC_LOAD)); + gdb_bfd_ref_ptr obfd (bfd_openw_or_error (filename, target, mode)); + osection = bfd_make_section_anyway (obfd.get (), ".newsec"); + bfd_set_section_size (obfd.get (), osection, len); + bfd_set_section_vma (obfd.get (), osection, vaddr); + bfd_set_section_alignment (obfd.get (), osection, 0); + bfd_set_section_flags (obfd.get (), osection, (SEC_HAS_CONTENTS + | SEC_ALLOC + | SEC_LOAD)); osection->entsize = 0; - if (!bfd_set_section_contents (obfd, osection, buf, 0, len)) - warning (_("writing dump file '%s' (%s)"), filename, + if (!bfd_set_section_contents (obfd.get (), osection, buf, 0, len)) + warning (_("writing dump file '%s' (%s)"), filename, bfd_errmsg (bfd_get_error ())); } @@ -624,12 +618,11 @@ restore_command (char *args_in, int from_tty) else { /* Open the file for loading. */ - ibfd = bfd_openr_with_cleanup (filename, NULL); + gdb_bfd_ref_ptr ibfd (bfd_openr_or_error (filename, NULL)); /* Process the sections. */ - bfd_map_over_sections (ibfd, restore_section_callback, &data); + bfd_map_over_sections (ibfd.get (), restore_section_callback, &data); } - return; } static void diff --git a/gdb/coffread.c b/gdb/coffread.c index 501e901..db32a92 100644 --- a/gdb/coffread.c +++ b/gdb/coffread.c @@ -742,10 +742,10 @@ coff_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags) if (debugfile) { - bfd *abfd = symfile_bfd_open (debugfile); + gdb_bfd_ref_ptr abfd (symfile_bfd_open (debugfile)); - make_cleanup_bfd_unref (abfd); - symbol_file_add_separate (abfd, debugfile, symfile_flags, objfile); + symbol_file_add_separate (abfd.get (), debugfile, symfile_flags, + objfile); } } diff --git a/gdb/common/gdb_ref_ptr.h b/gdb/common/gdb_ref_ptr.h index cc8ba94..989af97 100644 --- a/gdb/common/gdb_ref_ptr.h +++ b/gdb/common/gdb_ref_ptr.h @@ -137,6 +137,12 @@ class ref_ptr return result; } + /* Let users refer to members of the underlying pointer. */ + T *operator-> () const + { + return m_obj; + } + private: T *m_obj; diff --git a/gdb/compile/compile-object-load.c b/gdb/compile/compile-object-load.c index c08aa2b..7351148 100644 --- a/gdb/compile/compile-object-load.c +++ b/gdb/compile/compile-object-load.c @@ -612,7 +612,6 @@ compile_object_load (const compile_file_names &file_names, enum compile_i_scope_types scope, void *scope_data) { struct cleanup *cleanups, *cleanups_free_objfile; - bfd *abfd; struct setup_sections_data setup_sections_data; CORE_ADDR addr, regs_addr, out_value_addr = 0; struct symbol *func_sym; @@ -634,17 +633,16 @@ compile_object_load (const compile_file_names &file_names, filename = tilde_expand (file_names.object_file ()); cleanups = make_cleanup (xfree, filename); - abfd = gdb_bfd_open (filename, gnutarget, -1); + gdb_bfd_ref_ptr abfd (gdb_bfd_open (filename, gnutarget, -1)); if (abfd == NULL) error (_("\"%s\": could not open as compiled module: %s"), filename, bfd_errmsg (bfd_get_error ())); - make_cleanup_bfd_unref (abfd); - if (!bfd_check_format_matches (abfd, bfd_object, &matching)) + if (!bfd_check_format_matches (abfd.get (), bfd_object, &matching)) error (_("\"%s\": not in loadable format: %s"), filename, gdb_bfd_errmsg (bfd_get_error (), matching)); - if ((bfd_get_file_flags (abfd) & (EXEC_P | DYNAMIC)) != 0) + if ((bfd_get_file_flags (abfd.get ()) & (EXEC_P | DYNAMIC)) != 0) error (_("\"%s\": not in object format."), filename); setup_sections_data.last_size = 0; @@ -653,17 +651,17 @@ compile_object_load (const compile_file_names &file_names, setup_sections_data.last_max_alignment = 1; setup_sections_data.munmap_list_headp = &munmap_list_head; make_cleanup (munmap_listp_free_cleanup, &munmap_list_head); - bfd_map_over_sections (abfd, setup_sections, &setup_sections_data); - setup_sections (abfd, NULL, &setup_sections_data); + bfd_map_over_sections (abfd.get (), setup_sections, &setup_sections_data); + setup_sections (abfd.get (), NULL, &setup_sections_data); - storage_needed = bfd_get_symtab_upper_bound (abfd); + storage_needed = bfd_get_symtab_upper_bound (abfd.get ()); if (storage_needed < 0) error (_("Cannot read symbols of compiled module \"%s\": %s"), filename, bfd_errmsg (bfd_get_error ())); /* SYMFILE_VERBOSE is not passed even if FROM_TTY, user is not interested in "Reading symbols from ..." message for automatically generated file. */ - objfile = symbol_file_add_from_bfd (abfd, filename, 0, NULL, 0, NULL); + objfile = symbol_file_add_from_bfd (abfd.get (), filename, 0, NULL, 0, NULL); cleanups_free_objfile = make_cleanup_free_objfile (objfile); func_sym = lookup_global_symbol_from_objfile (objfile, @@ -712,7 +710,7 @@ compile_object_load (const compile_file_names &file_names, called from default_symfile_relocate. */ symbol_table = (asymbol **) obstack_alloc (&objfile->objfile_obstack, storage_needed); - number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table); + number_of_symbols = bfd_canonicalize_symtab (abfd.get (), symbol_table); if (number_of_symbols < 0) error (_("Cannot parse symbols of compiled module \"%s\": %s"), filename, bfd_errmsg (bfd_get_error ())); @@ -771,7 +769,7 @@ compile_object_load (const compile_file_names &file_names, if (missing_symbols) error (_("%ld symbols were missing, cannot continue."), missing_symbols); - bfd_map_over_sections (abfd, copy_sections, symbol_table); + bfd_map_over_sections (abfd.get (), copy_sections, symbol_table); regs_type = get_regs_type (func_sym, objfile); if (regs_type == NULL) diff --git a/gdb/corelow.c b/gdb/corelow.c index 376b7c9..04d2b87 100644 --- a/gdb/corelow.c +++ b/gdb/corelow.c @@ -275,7 +275,6 @@ core_open (const char *arg, int from_tty) int siggy; struct cleanup *old_chain; char *temp; - bfd *temp_bfd; int scratch_chan; int flags; char *filename; @@ -310,20 +309,19 @@ core_open (const char *arg, int from_tty) if (scratch_chan < 0) perror_with_name (filename); - temp_bfd = gdb_bfd_fopen (filename, gnutarget, - write_files ? FOPEN_RUB : FOPEN_RB, - scratch_chan); + gdb_bfd_ref_ptr temp_bfd (gdb_bfd_fopen (filename, gnutarget, + write_files ? FOPEN_RUB : FOPEN_RB, + scratch_chan)); if (temp_bfd == NULL) perror_with_name (filename); - if (!bfd_check_format (temp_bfd, bfd_core) - && !gdb_check_format (temp_bfd)) + if (!bfd_check_format (temp_bfd.get (), bfd_core) + && !gdb_check_format (temp_bfd.get ())) { /* Do it after the err msg */ /* FIXME: should be checking for errors from bfd_close (for one thing, on error it does not free all the storage associated with the bfd). */ - make_cleanup_bfd_unref (temp_bfd); error (_("\"%s\" is not a core dump: %s"), filename, bfd_errmsg (bfd_get_error ())); } @@ -333,7 +331,7 @@ core_open (const char *arg, int from_tty) do_cleanups (old_chain); unpush_target (&core_ops); - core_bfd = temp_bfd; + core_bfd = temp_bfd.release (); old_chain = make_cleanup (core_close_cleanup, 0 /*ignore*/); core_gdbarch = gdbarch_from_bfd (core_bfd); diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index b088dea..0780ae0 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -2476,7 +2476,6 @@ locate_dwz_sections (bfd *abfd, asection *sectp, void *arg) static struct dwz_file * dwarf2_get_dwz_file (void) { - bfd *dwz_bfd; char *data; struct cleanup *cleanup; const char *filename; @@ -2520,14 +2519,11 @@ dwarf2_get_dwz_file (void) /* First try the file name given in the section. If that doesn't work, try to use the build-id instead. */ - dwz_bfd = gdb_bfd_open (filename, gnutarget, -1); + gdb_bfd_ref_ptr dwz_bfd (gdb_bfd_open (filename, gnutarget, -1)); if (dwz_bfd != NULL) { - if (!build_id_verify (dwz_bfd, buildid_len, buildid)) - { - gdb_bfd_unref (dwz_bfd); - dwz_bfd = NULL; - } + if (!build_id_verify (dwz_bfd.get (), buildid_len, buildid)) + dwz_bfd.release (); } if (dwz_bfd == NULL) @@ -2539,13 +2535,13 @@ dwarf2_get_dwz_file (void) result = OBSTACK_ZALLOC (&dwarf2_per_objfile->objfile->objfile_obstack, struct dwz_file); - result->dwz_bfd = dwz_bfd; + result->dwz_bfd = dwz_bfd.release (); - bfd_map_over_sections (dwz_bfd, locate_dwz_sections, result); + bfd_map_over_sections (result->dwz_bfd, locate_dwz_sections, result); do_cleanups (cleanup); - gdb_bfd_record_inclusion (dwarf2_per_objfile->objfile->obfd, dwz_bfd); + gdb_bfd_record_inclusion (dwarf2_per_objfile->objfile->obfd, result->dwz_bfd); dwarf2_per_objfile->dwz_file = result; return result; } @@ -10448,10 +10444,9 @@ lookup_dwo_unit_in_dwp (struct dwp_file *dwp_file, const char *comp_dir, If unable to find/open the file, return NULL. NOTE: This function is derived from symfile_bfd_open. */ -static bfd * +static gdb_bfd_ref_ptr try_open_dwop_file (const char *file_name, int is_dwp, int search_cwd) { - bfd *sym_bfd; int desc, flags; char *absolute_name; /* Blech. OPF_TRY_CWD_FIRST also disables searching the path list if @@ -10478,25 +10473,22 @@ try_open_dwop_file (const char *file_name, int is_dwp, int search_cwd) O_RDONLY | O_BINARY, &absolute_name); xfree (search_path); if (desc < 0) - return NULL; + return gdb_bfd_ref_ptr (); - sym_bfd = gdb_bfd_open (absolute_name, gnutarget, desc); + gdb_bfd_ref_ptr sym_bfd (gdb_bfd_open (absolute_name, gnutarget, desc)); xfree (absolute_name); if (sym_bfd == NULL) - return NULL; - bfd_set_cacheable (sym_bfd, 1); + return gdb_bfd_ref_ptr (); + bfd_set_cacheable (sym_bfd.get (), 1); - if (!bfd_check_format (sym_bfd, bfd_object)) - { - gdb_bfd_unref (sym_bfd); /* This also closes desc. */ - return NULL; - } + if (!bfd_check_format (sym_bfd.get (), bfd_object)) + return gdb_bfd_ref_ptr (); /* Success. Record the bfd as having been included by the objfile's bfd. This is important because things like demangled_names_hash lives in the objfile's per_bfd space and may have references to things like symbol names that live in the DWO/DWP file's per_bfd space. PR 16426. */ - gdb_bfd_record_inclusion (dwarf2_per_objfile->objfile->obfd, sym_bfd); + gdb_bfd_record_inclusion (dwarf2_per_objfile->objfile->obfd, sym_bfd.get ()); return sym_bfd; } @@ -10508,11 +10500,9 @@ try_open_dwop_file (const char *file_name, int is_dwp, int search_cwd) Upon success, the canonicalized path of the file is stored in the bfd, same as symfile_bfd_open. */ -static bfd * +static gdb_bfd_ref_ptr open_dwo_file (const char *file_name, const char *comp_dir) { - bfd *abfd; - if (IS_ABSOLUTE_PATH (file_name)) return try_open_dwop_file (file_name, 0 /*is_dwp*/, 0 /*search_cwd*/); @@ -10525,7 +10515,8 @@ open_dwo_file (const char *file_name, const char *comp_dir) /* NOTE: If comp_dir is a relative path, this will also try the search path, which seems useful. */ - abfd = try_open_dwop_file (path_to_try, 0 /*is_dwp*/, 1 /*search_cwd*/); + gdb_bfd_ref_ptr abfd (try_open_dwop_file (path_to_try, 0 /*is_dwp*/, + 1 /*search_cwd*/)); xfree (path_to_try); if (abfd != NULL) return abfd; @@ -10535,7 +10526,7 @@ open_dwo_file (const char *file_name, const char *comp_dir) is a list of paths. */ if (*debug_file_directory == '\0') - return NULL; + return gdb_bfd_ref_ptr (); return try_open_dwop_file (file_name, 0 /*is_dwp*/, 1 /*search_cwd*/); } @@ -10611,10 +10602,9 @@ open_and_init_dwo_file (struct dwarf2_per_cu_data *per_cu, { struct objfile *objfile = dwarf2_per_objfile->objfile; struct dwo_file *dwo_file; - bfd *dbfd; struct cleanup *cleanups; - dbfd = open_dwo_file (dwo_name, comp_dir); + gdb_bfd_ref_ptr dbfd (open_dwo_file (dwo_name, comp_dir)); if (dbfd == NULL) { if (dwarf_read_debug) @@ -10624,11 +10614,12 @@ open_and_init_dwo_file (struct dwarf2_per_cu_data *per_cu, dwo_file = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_file); dwo_file->dwo_name = dwo_name; dwo_file->comp_dir = comp_dir; - dwo_file->dbfd = dbfd; + dwo_file->dbfd = dbfd.release (); cleanups = make_cleanup (free_dwo_file_cleanup, dwo_file); - bfd_map_over_sections (dbfd, dwarf2_locate_dwo_sections, &dwo_file->sections); + bfd_map_over_sections (dwo_file->dbfd, dwarf2_locate_dwo_sections, + &dwo_file->sections); dwo_file->cu = create_dwo_cu (dwo_file); @@ -10780,12 +10771,11 @@ allocate_dwp_loaded_cutus_table (struct objfile *objfile) Upon success, the canonicalized path of the file is stored in the bfd, same as symfile_bfd_open. */ -static bfd * +static gdb_bfd_ref_ptr open_dwp_file (const char *file_name) { - bfd *abfd; - - abfd = try_open_dwop_file (file_name, 1 /*is_dwp*/, 1 /*search_cwd*/); + gdb_bfd_ref_ptr abfd (try_open_dwop_file (file_name, 1 /*is_dwp*/, + 1 /*search_cwd*/)); if (abfd != NULL) return abfd; @@ -10806,7 +10796,7 @@ open_dwp_file (const char *file_name) 0 /*search_cwd*/); } - return NULL; + return gdb_bfd_ref_ptr (); } /* Initialize the use of the DWP file for the current objfile. @@ -10819,7 +10809,6 @@ open_and_init_dwp_file (void) struct objfile *objfile = dwarf2_per_objfile->objfile; struct dwp_file *dwp_file; char *dwp_name; - bfd *dbfd; struct cleanup *cleanups = make_cleanup (null_cleanup, 0); /* Try to find first .dwp for the binary file before any symbolic links @@ -10841,7 +10830,7 @@ open_and_init_dwp_file (void) dwp_name = xstrprintf ("%s.dwp", objfile->original_name); make_cleanup (xfree, dwp_name); - dbfd = open_dwp_file (dwp_name); + gdb_bfd_ref_ptr dbfd (open_dwp_file (dwp_name)); if (dbfd == NULL && strcmp (objfile->original_name, objfile_name (objfile)) != 0) { @@ -10859,17 +10848,18 @@ open_and_init_dwp_file (void) return NULL; } dwp_file = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwp_file); - dwp_file->name = bfd_get_filename (dbfd); - dwp_file->dbfd = dbfd; + dwp_file->name = bfd_get_filename (dbfd.get ()); + dwp_file->dbfd = dbfd.release (); do_cleanups (cleanups); /* +1: section 0 is unused */ - dwp_file->num_sections = bfd_count_sections (dbfd) + 1; + dwp_file->num_sections = bfd_count_sections (dwp_file->dbfd) + 1; dwp_file->elf_sections = OBSTACK_CALLOC (&objfile->objfile_obstack, dwp_file->num_sections, asection *); - bfd_map_over_sections (dbfd, dwarf2_locate_common_dwp_sections, dwp_file); + bfd_map_over_sections (dwp_file->dbfd, dwarf2_locate_common_dwp_sections, + dwp_file); dwp_file->cus = create_dwp_hash_table (dwp_file, 0); @@ -10889,7 +10879,8 @@ open_and_init_dwp_file (void) dwp_file->version = dwp_file->cus->version; if (dwp_file->version == 2) - bfd_map_over_sections (dbfd, dwarf2_locate_v2_dwp_sections, dwp_file); + bfd_map_over_sections (dwp_file->dbfd, dwarf2_locate_v2_dwp_sections, + dwp_file); dwp_file->loaded_cus = allocate_dwp_loaded_cutus_table (objfile); dwp_file->loaded_tus = allocate_dwp_loaded_cutus_table (objfile); diff --git a/gdb/elfread.c b/gdb/elfread.c index c6d0fdb..7e2358b 100644 --- a/gdb/elfread.c +++ b/gdb/elfread.c @@ -1265,21 +1265,18 @@ elf_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags) && objfile->separate_debug_objfile == NULL && objfile->separate_debug_objfile_backlink == NULL) { - char *debugfile; - - debugfile = find_separate_debug_file_by_buildid (objfile); + gdb::unique_xmalloc_ptr<char> debugfile + (find_separate_debug_file_by_buildid (objfile)); if (debugfile == NULL) - debugfile = find_separate_debug_file_by_debuglink (objfile); + debugfile.reset (find_separate_debug_file_by_debuglink (objfile)); - if (debugfile) + if (debugfile != NULL) { - struct cleanup *cleanup = make_cleanup (xfree, debugfile); - bfd *abfd = symfile_bfd_open (debugfile); + gdb_bfd_ref_ptr abfd (symfile_bfd_open (debugfile.get ())); - make_cleanup_bfd_unref (abfd); - symbol_file_add_separate (abfd, debugfile, symfile_flags, objfile); - do_cleanups (cleanup); + symbol_file_add_separate (abfd.get (), debugfile.get (), + symfile_flags, objfile); } } } diff --git a/gdb/exec.c b/gdb/exec.c index eeca005..875a675 100644 --- a/gdb/exec.c +++ b/gdb/exec.c @@ -258,7 +258,9 @@ exec_file_attach (const char *filename, int from_tty) this at the end of the function; but acquiring it now lets the BFD cache return it if this call refers to the same file. */ gdb_bfd_ref (exec_bfd); - cleanups = make_cleanup_bfd_unref (exec_bfd); + gdb_bfd_ref_ptr exec_bfd_holder (exec_bfd); + + cleanups = make_cleanup (null_cleanup, NULL); /* Remove any previous exec file. */ exec_close (); @@ -333,11 +335,13 @@ exec_file_attach (const char *filename, int from_tty) make_cleanup (xfree, canonical_pathname); } + gdb_bfd_ref_ptr temp; if (write_files && !load_via_target) - exec_bfd = gdb_bfd_fopen (canonical_pathname, gnutarget, - FOPEN_RUB, scratch_chan); + temp = gdb_bfd_fopen (canonical_pathname, gnutarget, + FOPEN_RUB, scratch_chan); else - exec_bfd = gdb_bfd_open (canonical_pathname, gnutarget, scratch_chan); + temp = gdb_bfd_open (canonical_pathname, gnutarget, scratch_chan); + exec_bfd = temp.release (); if (!exec_bfd) { diff --git a/gdb/gcore.c b/gdb/gcore.c index cb4d703..0b05cf9 100644 --- a/gdb/gcore.c +++ b/gdb/gcore.c @@ -49,15 +49,15 @@ static int gcore_memory_sections (bfd *); /* create_gcore_bfd -- helper for gcore_command (exported). Open a new bfd core file for output, and return the handle. */ -bfd * +gdb_bfd_ref_ptr create_gcore_bfd (const char *filename) { - bfd *obfd = gdb_bfd_openw (filename, default_gcore_target ()); + gdb_bfd_ref_ptr obfd (gdb_bfd_openw (filename, default_gcore_target ())); - if (!obfd) + if (obfd == NULL) error (_("Failed to open '%s' for output."), filename); - bfd_set_format (obfd, bfd_core); - bfd_set_arch_mach (obfd, default_gcore_arch (), default_gcore_mach ()); + bfd_set_format (obfd.get (), bfd_core); + bfd_set_arch_mach (obfd.get (), default_gcore_arch (), default_gcore_mach ()); return obfd; } @@ -174,7 +174,7 @@ gcore_command (char *args, int from_tty) "Opening corefile '%s' for output.\n", corefilename); /* Open the output file. */ - obfd = create_gcore_bfd (corefilename); + obfd = create_gcore_bfd (corefilename).release (); /* Need a cleanup that will close and delete the file. */ bfd_chain = make_cleanup (do_bfd_delete_cleanup, obfd); diff --git a/gdb/gcore.h b/gdb/gcore.h index 91107e0..f4f0545 100644 --- a/gdb/gcore.h +++ b/gdb/gcore.h @@ -20,7 +20,9 @@ #if !defined (GCORE_H) #define GCORE_H 1 -extern bfd *create_gcore_bfd (const char *filename); +#include "gdb_bfd.h" + +extern gdb_bfd_ref_ptr create_gcore_bfd (const char *filename); extern void write_gcore_file (bfd *obfd); extern bfd *load_corefile (char *filename, int from_tty); extern int objfile_find_memory_regions (struct target_ops *self, diff --git a/gdb/gdb_bfd.c b/gdb/gdb_bfd.c index df00f87..d483177 100644 --- a/gdb/gdb_bfd.c +++ b/gdb/gdb_bfd.c @@ -356,7 +356,7 @@ gdb_bfd_iovec_fileio_fstat (struct bfd *abfd, void *stream, /* See gdb_bfd.h. */ -struct bfd * +gdb_bfd_ref_ptr gdb_bfd_open (const char *name, const char *target, int fd) { hashval_t hash; @@ -392,7 +392,7 @@ gdb_bfd_open (const char *name, const char *target, int fd) if (fd == -1) { bfd_set_error (bfd_error_system_call); - return NULL; + return gdb_bfd_ref_ptr (); } } @@ -428,12 +428,12 @@ gdb_bfd_open (const char *name, const char *target, int fd) bfd_get_filename (abfd)); close (fd); gdb_bfd_ref (abfd); - return abfd; + return gdb_bfd_ref_ptr (abfd); } abfd = bfd_fopen (name, target, FOPEN_RB, fd); if (abfd == NULL) - return NULL; + return gdb_bfd_ref_ptr (); if (debug_bfd_cache) fprintf_unfiltered (gdb_stdlog, @@ -449,7 +449,7 @@ gdb_bfd_open (const char *name, const char *target, int fd) } gdb_bfd_ref (abfd); - return abfd; + return gdb_bfd_ref_ptr (abfd); } /* A helper function that releases any section data attached to the @@ -772,7 +772,7 @@ gdb_bfd_crc (struct bfd *abfd, unsigned long *crc_out) /* See gdb_bfd.h. */ -bfd * +gdb_bfd_ref_ptr gdb_bfd_fopen (const char *filename, const char *target, const char *mode, int fd) { @@ -781,12 +781,12 @@ gdb_bfd_fopen (const char *filename, const char *target, const char *mode, if (result) gdb_bfd_ref (result); - return result; + return gdb_bfd_ref_ptr (result); } /* See gdb_bfd.h. */ -bfd * +gdb_bfd_ref_ptr gdb_bfd_openr (const char *filename, const char *target) { bfd *result = bfd_openr (filename, target); @@ -794,12 +794,12 @@ gdb_bfd_openr (const char *filename, const char *target) if (result) gdb_bfd_ref (result); - return result; + return gdb_bfd_ref_ptr (result); } /* See gdb_bfd.h. */ -bfd * +gdb_bfd_ref_ptr gdb_bfd_openw (const char *filename, const char *target) { bfd *result = bfd_openw (filename, target); @@ -807,12 +807,12 @@ gdb_bfd_openw (const char *filename, const char *target) if (result) gdb_bfd_ref (result); - return result; + return gdb_bfd_ref_ptr (result); } /* See gdb_bfd.h. */ -bfd * +gdb_bfd_ref_ptr gdb_bfd_openr_iovec (const char *filename, const char *target, void *(*open_func) (struct bfd *nbfd, void *open_closure), @@ -835,7 +835,7 @@ gdb_bfd_openr_iovec (const char *filename, const char *target, if (result) gdb_bfd_ref (result); - return result; + return gdb_bfd_ref_ptr (result); } /* See gdb_bfd.h. */ @@ -861,7 +861,7 @@ gdb_bfd_mark_parent (bfd *child, bfd *parent) /* See gdb_bfd.h. */ -bfd * +gdb_bfd_ref_ptr gdb_bfd_openr_next_archived_file (bfd *archive, bfd *previous) { bfd *result = bfd_openr_next_archived_file (archive, previous); @@ -869,7 +869,7 @@ gdb_bfd_openr_next_archived_file (bfd *archive, bfd *previous) if (result) gdb_bfd_mark_parent (result, archive); - return result; + return gdb_bfd_ref_ptr (result); } /* See gdb_bfd.h. */ @@ -886,7 +886,7 @@ gdb_bfd_record_inclusion (bfd *includer, bfd *includee) /* See gdb_bfd.h. */ -bfd * +gdb_bfd_ref_ptr gdb_bfd_fdopenr (const char *filename, const char *target, int fd) { bfd *result = bfd_fdopenr (filename, target, fd); @@ -894,7 +894,7 @@ gdb_bfd_fdopenr (const char *filename, const char *target, int fd) if (result) gdb_bfd_ref (result); - return result; + return gdb_bfd_ref_ptr (result); } \f diff --git a/gdb/gdb_bfd.h b/gdb/gdb_bfd.h index a5b5ee9..8c4a60a 100644 --- a/gdb/gdb_bfd.h +++ b/gdb/gdb_bfd.h @@ -21,6 +21,7 @@ #define GDB_BFD_H #include "registry.h" +#include "common/gdb_ref_ptr.h" DECLARE_REGISTRY (bfd); @@ -39,6 +40,34 @@ int is_target_filename (const char *name); int gdb_bfd_has_target_filename (struct bfd *abfd); +/* Increment the reference count of ABFD. It is fine for ABFD to be + NULL; in this case the function does nothing. */ + +void gdb_bfd_ref (struct bfd *abfd); + +/* Decrement the reference count of ABFD. If this is the last + reference, ABFD will be freed. If ABFD is NULL, this function does + nothing. */ + +void gdb_bfd_unref (struct bfd *abfd); + +/* A policy class for gdb::ref_ptr for BFD reference counting. */ +struct gdb_bfd_ref_policy +{ + static void incref (struct bfd *abfd) + { + gdb_bfd_ref (abfd); + } + + static void decref (struct bfd *abfd) + { + gdb_bfd_unref (abfd); + } +}; + +/* A gdb::ref_ptr that has been specialized for BFD objects. */ +typedef gdb::ref_ptr<struct bfd, gdb_bfd_ref_policy> gdb_bfd_ref_ptr; + /* Open a read-only (FOPEN_RB) BFD given arguments like bfd_fopen. If NAME starts with TARGET_SYSROOT_PREFIX then the BFD will be opened using target fileio operations if necessary. Returns NULL @@ -51,18 +80,7 @@ int gdb_bfd_has_target_filename (struct bfd *abfd); not be exactly NAME but rather NAME with TARGET_SYSROOT_PREFIX stripped. */ -struct bfd *gdb_bfd_open (const char *name, const char *target, int fd); - -/* Increment the reference count of ABFD. It is fine for ABFD to be - NULL; in this case the function does nothing. */ - -void gdb_bfd_ref (struct bfd *abfd); - -/* Decrement the reference count of ABFD. If this is the last - reference, ABFD will be freed. If ABFD is NULL, this function does - nothing. */ - -void gdb_bfd_unref (struct bfd *abfd); +gdb_bfd_ref_ptr gdb_bfd_open (const char *name, const char *target, int fd); /* Mark the CHILD BFD as being a member of PARENT. Also, increment the reference count of CHILD. Calling this function ensures that @@ -110,45 +128,46 @@ int gdb_bfd_crc (struct bfd *abfd, unsigned long *crc_out); /* A wrapper for bfd_fopen that initializes the gdb-specific reference count. */ -bfd *gdb_bfd_fopen (const char *, const char *, const char *, int); +gdb_bfd_ref_ptr gdb_bfd_fopen (const char *, const char *, const char *, int); /* A wrapper for bfd_openr that initializes the gdb-specific reference count. */ -bfd *gdb_bfd_openr (const char *, const char *); +gdb_bfd_ref_ptr gdb_bfd_openr (const char *, const char *); /* A wrapper for bfd_openw that initializes the gdb-specific reference count. */ -bfd *gdb_bfd_openw (const char *, const char *); +gdb_bfd_ref_ptr gdb_bfd_openw (const char *, const char *); /* A wrapper for bfd_openr_iovec that initializes the gdb-specific reference count. */ -bfd *gdb_bfd_openr_iovec (const char *filename, const char *target, - void *(*open_func) (struct bfd *nbfd, - void *open_closure), - void *open_closure, - file_ptr (*pread_func) (struct bfd *nbfd, - void *stream, - void *buf, - file_ptr nbytes, - file_ptr offset), - int (*close_func) (struct bfd *nbfd, - void *stream), - int (*stat_func) (struct bfd *abfd, - void *stream, - struct stat *sb)); +gdb_bfd_ref_ptr gdb_bfd_openr_iovec (const char *filename, const char *target, + void *(*open_func) (struct bfd *nbfd, + void *open_closure), + void *open_closure, + file_ptr (*pread_func) (struct bfd *nbfd, + void *stream, + void *buf, + file_ptr nbytes, + file_ptr offset), + int (*close_func) (struct bfd *nbfd, + void *stream), + int (*stat_func) (struct bfd *abfd, + void *stream, + struct stat *sb)); /* A wrapper for bfd_openr_next_archived_file that initializes the gdb-specific reference count. */ -bfd *gdb_bfd_openr_next_archived_file (bfd *archive, bfd *previous); +gdb_bfd_ref_ptr gdb_bfd_openr_next_archived_file (bfd *archive, bfd *previous); /* A wrapper for bfd_fdopenr that initializes the gdb-specific reference count. */ -bfd *gdb_bfd_fdopenr (const char *filename, const char *target, int fd); +gdb_bfd_ref_ptr gdb_bfd_fdopenr (const char *filename, const char *target, + int fd); \f diff --git a/gdb/jit.c b/gdb/jit.c index 03b6bd8..2101115 100644 --- a/gdb/jit.c +++ b/gdb/jit.c @@ -136,7 +136,7 @@ mem_bfd_iovec_stat (struct bfd *abfd, void *stream, struct stat *sb) /* Open a BFD from the target's memory. */ -static struct bfd * +static gdb_bfd_ref_ptr bfd_open_from_target_memory (CORE_ADDR addr, ULONGEST size, char *target) { struct target_buffer *buffer = XNEW (struct target_buffer); @@ -892,7 +892,6 @@ jit_bfd_try_read_symtab (struct jit_code_entry *code_entry, CORE_ADDR entry_addr, struct gdbarch *gdbarch) { - bfd *nbfd; struct section_addr_info *sai; struct bfd_section *sec; struct objfile *objfile; @@ -907,8 +906,9 @@ jit_bfd_try_read_symtab (struct jit_code_entry *code_entry, paddress (gdbarch, code_entry->symfile_addr), pulongest (code_entry->symfile_size)); - nbfd = bfd_open_from_target_memory (code_entry->symfile_addr, - code_entry->symfile_size, gnutarget); + gdb_bfd_ref_ptr nbfd (bfd_open_from_target_memory (code_entry->symfile_addr, + code_entry->symfile_size, + gnutarget)); if (nbfd == NULL) { puts_unfiltered (_("Error opening JITed symbol file, ignoring it.\n")); @@ -917,42 +917,42 @@ jit_bfd_try_read_symtab (struct jit_code_entry *code_entry, /* Check the format. NOTE: This initializes important data that GDB uses! We would segfault later without this line. */ - if (!bfd_check_format (nbfd, bfd_object)) + if (!bfd_check_format (nbfd.get (), bfd_object)) { printf_unfiltered (_("\ JITed symbol file is not an object file, ignoring it.\n")); - gdb_bfd_unref (nbfd); return; } /* Check bfd arch. */ b = gdbarch_bfd_arch_info (gdbarch); - if (b->compatible (b, bfd_get_arch_info (nbfd)) != b) + if (b->compatible (b, bfd_get_arch_info (nbfd.get ())) != b) warning (_("JITed object file architecture %s is not compatible " - "with target architecture %s."), bfd_get_arch_info - (nbfd)->printable_name, b->printable_name); + "with target architecture %s."), + bfd_get_arch_info (nbfd.get ())->printable_name, + b->printable_name); /* Read the section address information out of the symbol file. Since the file is generated by the JIT at runtime, it should all of the absolute addresses that we care about. */ - sai = alloc_section_addr_info (bfd_count_sections (nbfd)); + sai = alloc_section_addr_info (bfd_count_sections (nbfd.get ())); old_cleanups = make_cleanup_free_section_addr_info (sai); i = 0; for (sec = nbfd->sections; sec != NULL; sec = sec->next) - if ((bfd_get_section_flags (nbfd, sec) & (SEC_ALLOC|SEC_LOAD)) != 0) + if ((bfd_get_section_flags (nbfd.get (), sec) & (SEC_ALLOC|SEC_LOAD)) != 0) { /* We assume that these virtual addresses are absolute, and do not treat them as offsets. */ - sai->other[i].addr = bfd_get_section_vma (nbfd, sec); - sai->other[i].name = xstrdup (bfd_get_section_name (nbfd, sec)); + sai->other[i].addr = bfd_get_section_vma (nbfd.get (), sec); + sai->other[i].name = xstrdup (bfd_get_section_name (nbfd.get (), sec)); sai->other[i].sectindex = sec->index; ++i; } sai->num_sections = i; /* This call does not take ownership of SAI. */ - make_cleanup_bfd_unref (nbfd); - objfile = symbol_file_add_from_bfd (nbfd, bfd_get_filename (nbfd), 0, sai, + objfile = symbol_file_add_from_bfd (nbfd.get (), + bfd_get_filename (nbfd.get ()), 0, sai, OBJF_SHARED | OBJF_NOT_FILENAME, NULL); do_cleanups (old_cleanups); diff --git a/gdb/machoread.c b/gdb/machoread.c index 00f25a4..4f0313e 100644 --- a/gdb/machoread.c +++ b/gdb/machoread.c @@ -429,7 +429,8 @@ macho_resolve_oso_sym_with_minsym (struct objfile *main_objfile, asymbol *sym) /* Add oso file OSO/ABFD as a symbol file. */ static void -macho_add_oso_symfile (oso_el *oso, bfd *abfd, const char *name, +macho_add_oso_symfile (oso_el *oso, const gdb_bfd_ref_ptr &abfd, + const char *name, struct objfile *main_objfile, symfile_add_flags symfile_flags) { @@ -439,7 +440,6 @@ macho_add_oso_symfile (oso_el *oso, bfd *abfd, const char *name, asymbol **symp; struct bfd_hash_table table; int nbr_sections; - struct cleanup *cleanup; /* Per section flag to mark which section have been rebased. */ unsigned char *sections_rebased; @@ -448,18 +448,16 @@ macho_add_oso_symfile (oso_el *oso, bfd *abfd, const char *name, printf_unfiltered (_("Loading debugging symbols from oso: %s\n"), oso->name); - if (!bfd_check_format (abfd, bfd_object)) + if (!bfd_check_format (abfd.get (), bfd_object)) { warning (_("`%s': can't read symbols: %s."), oso->name, bfd_errmsg (bfd_get_error ())); - gdb_bfd_unref (abfd); return; } - if (abfd->my_archive == NULL && oso->mtime != bfd_get_mtime (abfd)) + if (abfd->my_archive == NULL && oso->mtime != bfd_get_mtime (abfd.get ())) { warning (_("`%s': file time stamp mismatch."), oso->name); - gdb_bfd_unref (abfd); return; } @@ -468,19 +466,18 @@ macho_add_oso_symfile (oso_el *oso, bfd *abfd, const char *name, oso->nbr_syms)) { warning (_("`%s': can't create hash table"), oso->name); - gdb_bfd_unref (abfd); return; } - bfd_set_cacheable (abfd, 1); + bfd_set_cacheable (abfd.get (), 1); /* Read symbols table. */ - storage = bfd_get_symtab_upper_bound (abfd); + storage = bfd_get_symtab_upper_bound (abfd.get ()); symbol_table = (asymbol **) xmalloc (storage); - bfd_canonicalize_symtab (abfd, symbol_table); + bfd_canonicalize_symtab (abfd.get (), symbol_table); /* Init section flags. */ - nbr_sections = bfd_count_sections (abfd); + nbr_sections = bfd_count_sections (abfd.get ()); sections_rebased = (unsigned char *) alloca (nbr_sections); for (i = 0; i < nbr_sections; i++) sections_rebased[i] = 0; @@ -601,7 +598,7 @@ macho_add_oso_symfile (oso_el *oso, bfd *abfd, const char *name, sec->name, sym->name, paddress (arch, res)); } - bfd_set_section_vma (abfd, sec, res); + bfd_set_section_vma (abfd.get (), sec, res); sections_rebased[sec->index] = 1; } } @@ -617,13 +614,12 @@ macho_add_oso_symfile (oso_el *oso, bfd *abfd, const char *name, /* We need to clear SYMFILE_MAINLINE to avoid interractive question from symfile.c:symbol_file_add_with_addrs_or_offsets. */ - cleanup = make_cleanup_bfd_unref (abfd); symbol_file_add_from_bfd - (abfd, name, symfile_flags & ~(SYMFILE_MAINLINE | SYMFILE_VERBOSE), NULL, + (abfd.get (), name, symfile_flags & ~(SYMFILE_MAINLINE | SYMFILE_VERBOSE), + NULL, main_objfile->flags & (OBJF_REORDERED | OBJF_SHARED | OBJF_READNOW | OBJF_USERLOADED), main_objfile); - do_cleanups (cleanup); } /* Read symbols from the vector of oso files. @@ -651,8 +647,6 @@ macho_symfile_read_all_oso (VEC (oso_el) **oso_vector_ptr, pfx_len = get_archive_prefix_len (oso->name); if (pfx_len > 0) { - bfd *archive_bfd; - bfd *member_bfd; int last_ix; oso_el *oso2; int ix2; @@ -668,7 +662,8 @@ macho_symfile_read_all_oso (VEC (oso_el) **oso_vector_ptr, } /* Open the archive and check the format. */ - archive_bfd = gdb_bfd_open (archive_name.c_str (), gnutarget, -1); + gdb_bfd_ref_ptr archive_bfd (gdb_bfd_open (archive_name.c_str (), + gnutarget, -1)); if (archive_bfd == NULL) { warning (_("Could not open OSO archive file \"%s\""), @@ -676,22 +671,21 @@ macho_symfile_read_all_oso (VEC (oso_el) **oso_vector_ptr, ix = last_ix; continue; } - if (!bfd_check_format (archive_bfd, bfd_archive)) + if (!bfd_check_format (archive_bfd.get (), bfd_archive)) { warning (_("OSO archive file \"%s\" not an archive."), archive_name.c_str ()); - gdb_bfd_unref (archive_bfd); ix = last_ix; continue; } - member_bfd = gdb_bfd_openr_next_archived_file (archive_bfd, NULL); + gdb_bfd_ref_ptr member_bfd + (gdb_bfd_openr_next_archived_file (archive_bfd.get (), NULL)); if (member_bfd == NULL) { warning (_("Could not read archive members out of " "OSO archive \"%s\""), archive_name.c_str ()); - gdb_bfd_unref (archive_bfd); ix = last_ix; continue; } @@ -699,7 +693,6 @@ macho_symfile_read_all_oso (VEC (oso_el) **oso_vector_ptr, /* Load all oso in this library. */ while (member_bfd != NULL) { - bfd *prev; const char *member_name = member_bfd->filename; int member_len = strlen (member_name); @@ -721,13 +714,8 @@ macho_symfile_read_all_oso (VEC (oso_el) **oso_vector_ptr, } } - prev = member_bfd; - member_bfd = gdb_bfd_openr_next_archived_file (archive_bfd, - member_bfd); - - /* Free previous member if not referenced by an oso. */ - if (ix2 >= last_ix) - gdb_bfd_unref (prev); + member_bfd = gdb_bfd_openr_next_archived_file (archive_bfd.get (), + member_bfd.get ()); } for (ix2 = ix; ix2 < last_ix; ix2++) { @@ -741,10 +729,8 @@ macho_symfile_read_all_oso (VEC (oso_el) **oso_vector_ptr, } else { - bfd *abfd; - - abfd = gdb_bfd_open (oso->name, gnutarget, -1); - if (!abfd) + gdb_bfd_ref_ptr abfd (gdb_bfd_open (oso->name, gnutarget, -1)); + if (abfd == NULL) warning (_("`%s': can't open to read symbols: %s."), oso->name, bfd_errmsg (bfd_get_error ())); else @@ -768,7 +754,7 @@ macho_symfile_read_all_oso (VEC (oso_el) **oso_vector_ptr, Return NULL if no valid dsym file is found (FILENAMEP is not used in such case). */ -static bfd * +static gdb_bfd_ref_ptr macho_check_dsym (struct objfile *objfile, char **filenamep) { size_t name_len = strlen (objfile_name (objfile)); @@ -776,7 +762,6 @@ macho_check_dsym (struct objfile *objfile, char **filenamep) const char *base_name = lbasename (objfile_name (objfile)); size_t base_len = strlen (base_name); char *dsym_filename = (char *) alloca (name_len + dsym_len + base_len + 1); - bfd *dsym_bfd; bfd_mach_o_load_command *main_uuid; bfd_mach_o_load_command *dsym_uuid; @@ -785,42 +770,39 @@ macho_check_dsym (struct objfile *objfile, char **filenamep) strcpy (dsym_filename + name_len + dsym_len, base_name); if (access (dsym_filename, R_OK) != 0) - return NULL; + return gdb_bfd_ref_ptr (); if (bfd_mach_o_lookup_command (objfile->obfd, BFD_MACH_O_LC_UUID, &main_uuid) == 0) { warning (_("can't find UUID in %s"), objfile_name (objfile)); - return NULL; + return gdb_bfd_ref_ptr (); } - dsym_bfd = gdb_bfd_openr (dsym_filename, gnutarget); + gdb_bfd_ref_ptr dsym_bfd (gdb_bfd_openr (dsym_filename, gnutarget)); if (dsym_bfd == NULL) { warning (_("can't open dsym file %s"), dsym_filename); - return NULL; + return gdb_bfd_ref_ptr (); } - if (!bfd_check_format (dsym_bfd, bfd_object)) + if (!bfd_check_format (dsym_bfd.get (), bfd_object)) { - gdb_bfd_unref (dsym_bfd); warning (_("bad dsym file format: %s"), bfd_errmsg (bfd_get_error ())); - return NULL; + return gdb_bfd_ref_ptr (); } - if (bfd_mach_o_lookup_command (dsym_bfd, + if (bfd_mach_o_lookup_command (dsym_bfd.get (), BFD_MACH_O_LC_UUID, &dsym_uuid) == 0) { warning (_("can't find UUID in %s"), dsym_filename); - gdb_bfd_unref (dsym_bfd); - return NULL; + return gdb_bfd_ref_ptr (); } if (memcmp (dsym_uuid->command.uuid.uuid, main_uuid->command.uuid.uuid, sizeof (main_uuid->command.uuid.uuid))) { warning (_("dsym file UUID doesn't match the one in %s"), objfile_name (objfile)); - gdb_bfd_unref (dsym_bfd); - return NULL; + return gdb_bfd_ref_ptr (); } *filenamep = xstrdup (dsym_filename); return dsym_bfd; @@ -831,7 +813,6 @@ macho_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags) { bfd *abfd = objfile->obfd; long storage_needed; - bfd *dsym_bfd; VEC (oso_el) *oso_vector = NULL; struct cleanup *old_chain = make_cleanup (VEC_cleanup (oso_el), &oso_vector); @@ -879,7 +860,7 @@ macho_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags) dwarf2_build_frame_info (objfile); /* Check for DSYM file. */ - dsym_bfd = macho_check_dsym (objfile, &dsym_filename); + gdb_bfd_ref_ptr dsym_bfd (macho_check_dsym (objfile, &dsym_filename)); if (dsym_bfd != NULL) { struct bfd_section *asect, *dsect; @@ -896,14 +877,13 @@ macho_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags) { if (strcmp (asect->name, dsect->name) != 0) break; - bfd_set_section_size (dsym_bfd, dsect, + bfd_set_section_size (dsym_bfd.get (), dsect, bfd_get_section_size (asect)); } /* Add the dsym file as a separate file. */ - make_cleanup_bfd_unref (dsym_bfd); - symbol_file_add_separate (dsym_bfd, dsym_filename, symfile_flags, - objfile); + symbol_file_add_separate (dsym_bfd.get (), dsym_filename, + symfile_flags, objfile); /* Don't try to read dwarf2 from main file or shared libraries. */ do_cleanups (old_chain); diff --git a/gdb/minidebug.c b/gdb/minidebug.c index 4323294..f54f0cc 100644 --- a/gdb/minidebug.c +++ b/gdb/minidebug.c @@ -256,35 +256,33 @@ lzma_stat (struct bfd *abfd, If we find one we create a iovec based bfd that decompresses the object data on demand. If we don't find one, return NULL. */ -bfd * +gdb_bfd_ref_ptr find_separate_debug_file_in_section (struct objfile *objfile) { asection *section; - bfd *abfd; + gdb_bfd_ref_ptr abfd; if (objfile->obfd == NULL) - return NULL; + return gdb_bfd_ref_ptr (); section = bfd_get_section_by_name (objfile->obfd, ".gnu_debugdata"); if (section == NULL) - return NULL; + return gdb_bfd_ref_ptr (); #ifdef HAVE_LIBLZMA abfd = gdb_bfd_openr_iovec (objfile_name (objfile), gnutarget, lzma_open, section, lzma_pread, lzma_close, lzma_stat); if (abfd == NULL) - return NULL; + return gdb_bfd_ref_ptr (); - if (!bfd_check_format (abfd, bfd_object)) + if (!bfd_check_format (abfd.get (), bfd_object)) { warning (_("Cannot parse .gnu_debugdata section; not a BFD object")); - gdb_bfd_unref (abfd); - return NULL; + return gdb_bfd_ref_ptr (); } #else warning (_("Cannot parse .gnu_debugdata section; LZMA support was " "disabled at compile time")); - abfd = NULL; #endif /* !HAVE_LIBLZMA */ return abfd; diff --git a/gdb/procfs.c b/gdb/procfs.c index ff814ba..f8fd487 100644 --- a/gdb/procfs.c +++ b/gdb/procfs.c @@ -3413,26 +3413,24 @@ dbx_link_addr (bfd *abfd) static int insert_dbx_link_bpt_in_file (int fd, CORE_ADDR ignored) { - bfd *abfd; long storage_needed; CORE_ADDR sym_addr; - abfd = gdb_bfd_fdopenr ("unamed", 0, fd); + gdb_bfd_ref_ptr abfd (gdb_bfd_fdopenr ("unamed", 0, fd)); if (abfd == NULL) { warning (_("Failed to create a bfd: %s."), bfd_errmsg (bfd_get_error ())); return 0; } - if (!bfd_check_format (abfd, bfd_object)) + if (!bfd_check_format (abfd.get (), bfd_object)) { /* Not the correct format, so we can not possibly find the dbx_link symbol in it. */ - gdb_bfd_unref (abfd); return 0; } - sym_addr = dbx_link_addr (abfd); + sym_addr = dbx_link_addr (abfd.get ()); if (sym_addr != 0) { struct breakpoint *dbx_link_bpt; @@ -3444,14 +3442,11 @@ insert_dbx_link_bpt_in_file (int fd, CORE_ADDR ignored) if (dbx_link_bpt == NULL) { warning (_("Failed to insert dbx_link breakpoint.")); - gdb_bfd_unref (abfd); return 0; } - gdb_bfd_unref (abfd); return 1; } - gdb_bfd_unref (abfd); return 0; } diff --git a/gdb/python/py-objfile.c b/gdb/python/py-objfile.c index 497d0ba..42e26b7 100644 --- a/gdb/python/py-objfile.c +++ b/gdb/python/py-objfile.c @@ -445,9 +445,9 @@ objfpy_add_separate_debug_file (PyObject *self, PyObject *args, PyObject *kw) TRY { - bfd *abfd = symfile_bfd_open (file_name); + gdb_bfd_ref_ptr abfd (symfile_bfd_open (file_name)); - symbol_file_add_separate (abfd, file_name, 0, obj->objfile); + symbol_file_add_separate (abfd.get (), file_name, 0, obj->objfile); } CATCH (except, RETURN_MASK_ALL) { diff --git a/gdb/record-full.c b/gdb/record-full.c index 603a9ba..7ab394b 100644 --- a/gdb/record-full.c +++ b/gdb/record-full.c @@ -2571,7 +2571,7 @@ record_full_save (struct target_ops *self, const char *recfilename) recfilename); /* Open the output file. */ - obfd = create_gcore_bfd (recfilename); + obfd = create_gcore_bfd (recfilename).release (); old_cleanups = make_cleanup (record_full_save_cleanups, obfd); /* Save the current record entry to "cur_record_full_list". */ diff --git a/gdb/solib-aix.c b/gdb/solib-aix.c index 75634df..96aa83e 100644 --- a/gdb/solib-aix.c +++ b/gdb/solib-aix.c @@ -624,7 +624,7 @@ solib_aix_in_dynsym_resolve_code (CORE_ADDR pc) /* Implement the "bfd_open" target_so_ops method. */ -static bfd * +static gdb_bfd_ref_ptr solib_aix_bfd_open (char *pathname) { /* The pathname is actually a synthetic filename with the following @@ -635,11 +635,7 @@ solib_aix_bfd_open (char *pathname) to the solib's lm_info here? */ const int path_len = strlen (pathname); char *sep; - char *filename; int filename_len; - char *member_name; - bfd *archive_bfd, *object_bfd; - struct cleanup *cleanup; int found_file; char *found_pathname; @@ -658,82 +654,70 @@ 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); + gdb::unique_xmalloc_ptr<char> filename + (xstrprintf ("%.*s", filename_len, pathname)); + gdb::unique_xmalloc_ptr<char> member_name + (xstrprintf ("%.*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. */ - found_pathname = solib_find (filename, &found_file); + found_pathname = solib_find (filename.get (), &found_file); if (found_pathname == NULL) perror_with_name (pathname); - archive_bfd = solib_bfd_fopen (found_pathname, found_file); + gdb_bfd_ref_ptr archive_bfd (solib_bfd_fopen (found_pathname, 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); - return NULL; + filename.get (), bfd_errmsg (bfd_get_error ())); + return gdb_bfd_ref_ptr (); } - 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); - return NULL; + filename.get (), bfd_errmsg (bfd_get_error ())); + return gdb_bfd_ref_ptr (); } - 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 (strcmp (member_name.get (), object_bfd->filename) == 0) 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); - return NULL; + warning (_("\"%s\": member \"%s\" missing."), filename.get (), + member_name.get ()); + return gdb_bfd_ref_ptr (); } - 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); - return NULL; + filename.get (), member_name.get (), + bfd_errmsg (bfd_get_error ())); + return gdb_bfd_ref_ptr (); } /* 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)); + xfree (bfd_get_filename (object_bfd.get ())); object_bfd->filename = xstrprintf ("%s%s", - bfd_get_filename (archive_bfd), sep); + bfd_get_filename (archive_bfd.get ()), + sep); - gdb_bfd_unref (archive_bfd); - do_cleanups (cleanup); return object_bfd; } diff --git a/gdb/solib-darwin.c b/gdb/solib-darwin.c index 24cf848..6a8f2da 100644 --- a/gdb/solib-darwin.c +++ b/gdb/solib-darwin.c @@ -427,21 +427,21 @@ darwin_in_dynsym_resolve_code (CORE_ADDR pc) counting properly. This will either return NULL, or return a new reference to a BFD. */ -static bfd * +static gdb_bfd_ref_ptr gdb_bfd_mach_o_fat_extract (bfd *abfd, bfd_format format, const bfd_arch_info_type *arch) { bfd *result = bfd_mach_o_fat_extract (abfd, format, arch); if (result == NULL) - return NULL; + return gdb_bfd_ref_ptr (); if (result == abfd) gdb_bfd_ref (result); else gdb_bfd_mark_parent (result, abfd); - return result; + return gdb_bfd_ref_ptr (result); } /* Extract dyld_all_image_addr when the process was just created, assuming the @@ -452,8 +452,6 @@ darwin_solib_get_all_image_info_addr_at_init (struct darwin_info *info) { char *interp_name; CORE_ADDR load_addr = 0; - bfd *dyld_bfd = NULL; - struct cleanup *cleanup; /* This method doesn't work with an attached process. */ if (current_inferior ()->attach_flag) @@ -464,42 +462,30 @@ darwin_solib_get_all_image_info_addr_at_init (struct darwin_info *info) if (!interp_name) return; - cleanup = make_cleanup (null_cleanup, NULL); - /* Create a bfd for the interpreter. */ - dyld_bfd = gdb_bfd_open (interp_name, gnutarget, -1); - if (dyld_bfd) + gdb_bfd_ref_ptr dyld_bfd (gdb_bfd_open (interp_name, gnutarget, -1)); + if (dyld_bfd != NULL) { - bfd *sub; - - make_cleanup_bfd_unref (dyld_bfd); - sub = gdb_bfd_mach_o_fat_extract - (dyld_bfd, bfd_object, gdbarch_bfd_arch_info (target_gdbarch ())); - if (sub) - { - dyld_bfd = sub; - make_cleanup_bfd_unref (sub); - } + gdb_bfd_ref_ptr sub + (gdb_bfd_mach_o_fat_extract (dyld_bfd.get (), bfd_object, + gdbarch_bfd_arch_info (target_gdbarch ()))); + if (sub != NULL) + dyld_bfd = sub; else - dyld_bfd = NULL; - } - if (!dyld_bfd) - { - do_cleanups (cleanup); - return; + dyld_bfd.release (); } + if (dyld_bfd == NULL) + return; /* We find the dynamic linker's base address by examining the current pc (which should point at the entry point for the dynamic linker) and subtracting the offset of the entry point. */ load_addr = (regcache_read_pc (get_current_regcache ()) - - bfd_get_start_address (dyld_bfd)); + - bfd_get_start_address (dyld_bfd.get ())); /* Now try to set a breakpoint in the dynamic linker. */ info->all_image_addr = - lookup_symbol_from_bfd (dyld_bfd, "_dyld_all_image_infos"); - - do_cleanups (cleanup); + lookup_symbol_from_bfd (dyld_bfd.get (), "_dyld_all_image_infos"); if (info->all_image_addr == 0) return; @@ -634,13 +620,11 @@ darwin_lookup_lib_symbol (struct objfile *objfile, return (struct block_symbol) {NULL, NULL}; } -static bfd * +static gdb_bfd_ref_ptr darwin_bfd_open (char *pathname) { char *found_pathname; int found_file; - bfd *abfd; - bfd *res; /* Search for shared library file. */ found_pathname = solib_find (pathname, &found_file); @@ -648,24 +632,21 @@ darwin_bfd_open (char *pathname) perror_with_name (pathname); /* Open bfd for shared library. */ - abfd = solib_bfd_fopen (found_pathname, found_file); + gdb_bfd_ref_ptr abfd (solib_bfd_fopen (found_pathname, found_file)); - res = gdb_bfd_mach_o_fat_extract (abfd, bfd_object, - gdbarch_bfd_arch_info (target_gdbarch ())); - if (!res) - { - make_cleanup_bfd_unref (abfd); - error (_("`%s': not a shared-library: %s"), - bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ())); - } + gdb_bfd_ref_ptr res + (gdb_bfd_mach_o_fat_extract (abfd.get (), bfd_object, + gdbarch_bfd_arch_info (target_gdbarch ()))); + if (res == NULL) + error (_("`%s': not a shared-library: %s"), + bfd_get_filename (abfd.get ()), bfd_errmsg (bfd_get_error ())); /* The current filename for fat-binary BFDs is a name generated by BFD, usually a string containing the name of the architecture. Reset its value to the actual filename. */ - xfree (bfd_get_filename (res)); + xfree (bfd_get_filename (res.get ())); res->filename = xstrdup (pathname); - gdb_bfd_unref (abfd); return res; } diff --git a/gdb/solib-dsbt.c b/gdb/solib-dsbt.c index d66fe5d..14cab05 100644 --- a/gdb/solib-dsbt.c +++ b/gdb/solib-dsbt.c @@ -816,7 +816,6 @@ enable_break (void) { unsigned int interp_sect_size; char *buf; - bfd *tmp_bfd = NULL; CORE_ADDR addr; struct int_elf32_dsbt_loadmap *ldm; int ret; @@ -832,6 +831,7 @@ enable_break (void) loaded so that we can load its symbols and place a breakpoint in the dynamic linker itself. */ + gdb_bfd_ref_ptr tmp_bfd; TRY { tmp_bfd = solib_bfd_open (buf); @@ -852,29 +852,31 @@ enable_break (void) /* Record the relocated start and end address of the dynamic linker text and plt section for dsbt_in_dynsym_resolve_code. */ - interp_sect = bfd_get_section_by_name (tmp_bfd, ".text"); + interp_sect = bfd_get_section_by_name (tmp_bfd.get (), ".text"); if (interp_sect) { info->interp_text_sect_low - = bfd_section_vma (tmp_bfd, interp_sect); + = bfd_section_vma (tmp_bfd.get (), interp_sect); info->interp_text_sect_low += displacement_from_map (ldm, info->interp_text_sect_low); info->interp_text_sect_high = info->interp_text_sect_low - + bfd_section_size (tmp_bfd, interp_sect); + + bfd_section_size (tmp_bfd.get (), interp_sect); } - interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt"); + interp_sect = bfd_get_section_by_name (tmp_bfd.get (), ".plt"); if (interp_sect) { info->interp_plt_sect_low = - bfd_section_vma (tmp_bfd, interp_sect); + bfd_section_vma (tmp_bfd.get (), interp_sect); info->interp_plt_sect_low += displacement_from_map (ldm, info->interp_plt_sect_low); info->interp_plt_sect_high = - info->interp_plt_sect_low + bfd_section_size (tmp_bfd, interp_sect); + info->interp_plt_sect_low + bfd_section_size (tmp_bfd.get (), + interp_sect); } - addr = gdb_bfd_lookup_symbol (tmp_bfd, cmp_name, "_dl_debug_state"); + addr = gdb_bfd_lookup_symbol (tmp_bfd.get (), cmp_name, + "_dl_debug_state"); if (addr != 0) { if (solib_dsbt_debug) @@ -901,10 +903,7 @@ enable_break (void) ret = 0; } - /* We're done with the temporary bfd. */ - gdb_bfd_unref (tmp_bfd); - - /* We're also done with the loadmap. */ + /* We're done with the loadmap. */ xfree (ldm); return ret; diff --git a/gdb/solib-frv.c b/gdb/solib-frv.c index 61a4ed0..0387b44 100644 --- a/gdb/solib-frv.c +++ b/gdb/solib-frv.c @@ -532,7 +532,6 @@ enable_break2 (void) { unsigned int interp_sect_size; char *buf; - bfd *tmp_bfd = NULL; int status; CORE_ADDR addr, interp_loadmap_addr; gdb_byte addr_buf[FRV_PTR_SIZE]; @@ -554,6 +553,7 @@ enable_break2 (void) be trivial on GNU/Linux). Therefore, we have to try an alternate mechanism to find the dynamic linker's base address. */ + gdb_bfd_ref_ptr tmp_bfd; TRY { tmp_bfd = solib_bfd_open (buf); @@ -575,7 +575,6 @@ enable_break2 (void) { warning (_("Unable to determine dynamic linker loadmap address.")); enable_break_failure_warning (); - gdb_bfd_unref (tmp_bfd); return 0; } @@ -590,41 +589,41 @@ enable_break2 (void) warning (_("Unable to load dynamic linker loadmap at address %s."), hex_string_custom (interp_loadmap_addr, 8)); enable_break_failure_warning (); - gdb_bfd_unref (tmp_bfd); return 0; } /* Record the relocated start and end address of the dynamic linker text and plt section for svr4_in_dynsym_resolve_code. */ - interp_sect = bfd_get_section_by_name (tmp_bfd, ".text"); + interp_sect = bfd_get_section_by_name (tmp_bfd.get (), ".text"); if (interp_sect) { interp_text_sect_low - = bfd_section_vma (tmp_bfd, interp_sect); + = bfd_section_vma (tmp_bfd.get (), interp_sect); interp_text_sect_low += displacement_from_map (ldm, interp_text_sect_low); interp_text_sect_high - = interp_text_sect_low + bfd_section_size (tmp_bfd, interp_sect); + = interp_text_sect_low + bfd_section_size (tmp_bfd.get (), + interp_sect); } - interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt"); + interp_sect = bfd_get_section_by_name (tmp_bfd.get (), ".plt"); if (interp_sect) { interp_plt_sect_low = - bfd_section_vma (tmp_bfd, interp_sect); + bfd_section_vma (tmp_bfd.get (), interp_sect); interp_plt_sect_low += displacement_from_map (ldm, interp_plt_sect_low); interp_plt_sect_high = - interp_plt_sect_low + bfd_section_size (tmp_bfd, interp_sect); + interp_plt_sect_low + bfd_section_size (tmp_bfd.get (), + interp_sect); } - addr = gdb_bfd_lookup_symbol (tmp_bfd, cmp_name, "_dl_debug_addr"); + addr = gdb_bfd_lookup_symbol (tmp_bfd.get (), cmp_name, "_dl_debug_addr"); if (addr == 0) { warning (_("Could not find symbol _dl_debug_addr " "in dynamic linker")); enable_break_failure_warning (); - gdb_bfd_unref (tmp_bfd); return 0; } @@ -675,7 +674,6 @@ enable_break2 (void) "(at address %s) from dynamic linker"), hex_string_custom (addr + 8, 8)); enable_break_failure_warning (); - gdb_bfd_unref (tmp_bfd); return 0; } addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order); @@ -687,15 +685,11 @@ enable_break2 (void) "(at address %s) from dynamic linker"), hex_string_custom (addr, 8)); enable_break_failure_warning (); - gdb_bfd_unref (tmp_bfd); return 0; } addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order); - /* We're done with the temporary bfd. */ - gdb_bfd_unref (tmp_bfd); - - /* We're also done with the loadmap. */ + /* We're done with the loadmap. */ xfree (ldm); /* Remove all the solib event breakpoints. Their addresses diff --git a/gdb/solib-spu.c b/gdb/solib-spu.c index fa2977e..117398d 100644 --- a/gdb/solib-spu.c +++ b/gdb/solib-spu.c @@ -319,36 +319,32 @@ spu_bfd_iovec_stat (bfd *abfd, void *stream, struct stat *sb) return 0; } -static bfd * +static gdb_bfd_ref_ptr spu_bfd_fopen (char *name, CORE_ADDR addr) { - bfd *nbfd; CORE_ADDR *open_closure = XNEW (CORE_ADDR); *open_closure = addr; - nbfd = gdb_bfd_openr_iovec (name, "elf32-spu", - spu_bfd_iovec_open, open_closure, - spu_bfd_iovec_pread, spu_bfd_iovec_close, - spu_bfd_iovec_stat); - if (!nbfd) - return NULL; + gdb_bfd_ref_ptr nbfd (gdb_bfd_openr_iovec (name, "elf32-spu", + spu_bfd_iovec_open, open_closure, + spu_bfd_iovec_pread, + spu_bfd_iovec_close, + spu_bfd_iovec_stat)); + if (nbfd == NULL) + return gdb_bfd_ref_ptr (); - if (!bfd_check_format (nbfd, bfd_object)) - { - gdb_bfd_unref (nbfd); - return NULL; - } + if (!bfd_check_format (nbfd.get (), bfd_object)) + return gdb_bfd_ref_ptr (); return nbfd; } /* Open shared library BFD. */ -static bfd * +static gdb_bfd_ref_ptr spu_bfd_open (char *pathname) { char *original_name = strrchr (pathname, '@'); - bfd *abfd; asection *spu_name; unsigned long long addr; int fd; @@ -362,22 +358,23 @@ spu_bfd_open (char *pathname) internal_error (__FILE__, __LINE__, "bad object ID"); /* Open BFD representing SPE executable. */ - abfd = spu_bfd_fopen (original_name, (CORE_ADDR) addr); - if (!abfd) + gdb_bfd_ref_ptr abfd (spu_bfd_fopen (original_name, (CORE_ADDR) addr)); + if (abfd == NULL) error (_("Cannot read SPE executable at %s"), original_name); /* Retrieve SPU name note. */ - spu_name = bfd_get_section_by_name (abfd, ".note.spu_name"); + spu_name = bfd_get_section_by_name (abfd.get (), ".note.spu_name"); if (spu_name) { - int sect_size = bfd_section_size (abfd, spu_name); + int sect_size = bfd_section_size (abfd.get (), spu_name); if (sect_size > 20) { char *buf = (char *) alloca (sect_size - 20 + strlen (original_name) + 1); - bfd_get_section_contents (abfd, spu_name, buf, 20, sect_size - 20); + bfd_get_section_contents (abfd.get (), spu_name, buf, 20, + sect_size - 20); buf[sect_size - 20] = '\0'; strcat (buf, original_name); diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c index 0e18292..b801364 100644 --- a/gdb/solib-svr4.c +++ b/gdb/solib-svr4.c @@ -2355,7 +2355,6 @@ enable_break (struct svr4_info *info, int from_tty) int load_addr_found = 0; int loader_found_in_list = 0; struct so_list *so; - bfd *tmp_bfd = NULL; struct target_ops *tmp_bfd_target; sym_addr = 0; @@ -2369,6 +2368,7 @@ enable_break (struct svr4_info *info, int from_tty) be trivial on GNU/Linux). Therefore, we have to try an alternate mechanism to find the dynamic linker's base address. */ + gdb_bfd_ref_ptr tmp_bfd; TRY { tmp_bfd = solib_bfd_open (interp_name); @@ -2382,11 +2382,9 @@ enable_break (struct svr4_info *info, int from_tty) goto bkpt_at_symbol; /* Now convert the TMP_BFD into a target. That way target, as - well as BFD operations can be used. */ - tmp_bfd_target = target_bfd_reopen (tmp_bfd); - /* target_bfd_reopen acquired its own reference, so we can - release ours now. */ - gdb_bfd_unref (tmp_bfd); + well as BFD operations can be used. target_bfd_reopen + acquires its own reference. */ + tmp_bfd_target = target_bfd_reopen (tmp_bfd.get ()); /* On a running target, we can get the dynamic linker's base address from the shared library table. */ @@ -2397,7 +2395,7 @@ enable_break (struct svr4_info *info, int from_tty) { load_addr_found = 1; loader_found_in_list = 1; - load_addr = lm_addr_check (so, tmp_bfd); + load_addr = lm_addr_check (so, tmp_bfd.get ()); break; } so = so->next; @@ -2418,7 +2416,7 @@ enable_break (struct svr4_info *info, int from_tty) if (addr_bit < (sizeof (CORE_ADDR) * HOST_CHAR_BIT)) { CORE_ADDR space_size = (CORE_ADDR) 1 << addr_bit; - CORE_ADDR tmp_entry_point = exec_entry_point (tmp_bfd, + CORE_ADDR tmp_entry_point = exec_entry_point (tmp_bfd.get (), tmp_bfd_target); gdb_assert (load_addr < space_size); @@ -2447,7 +2445,7 @@ enable_break (struct svr4_info *info, int from_tty) = get_thread_arch_regcache (inferior_ptid, target_gdbarch ()); load_addr = (regcache_read_pc (regcache) - - exec_entry_point (tmp_bfd, tmp_bfd_target)); + - exec_entry_point (tmp_bfd.get (), tmp_bfd_target)); } if (!loader_found_in_list) @@ -2460,29 +2458,30 @@ enable_break (struct svr4_info *info, int from_tty) /* Record the relocated start and end address of the dynamic linker text and plt section for svr4_in_dynsym_resolve_code. */ - interp_sect = bfd_get_section_by_name (tmp_bfd, ".text"); + interp_sect = bfd_get_section_by_name (tmp_bfd.get (), ".text"); if (interp_sect) { info->interp_text_sect_low = - bfd_section_vma (tmp_bfd, interp_sect) + load_addr; + bfd_section_vma (tmp_bfd.get (), interp_sect) + load_addr; info->interp_text_sect_high = info->interp_text_sect_low - + bfd_section_size (tmp_bfd, interp_sect); + + bfd_section_size (tmp_bfd.get (), interp_sect); } - interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt"); + interp_sect = bfd_get_section_by_name (tmp_bfd.get (), ".plt"); if (interp_sect) { info->interp_plt_sect_low = - bfd_section_vma (tmp_bfd, interp_sect) + load_addr; + bfd_section_vma (tmp_bfd.get (), interp_sect) + load_addr; info->interp_plt_sect_high = info->interp_plt_sect_low - + bfd_section_size (tmp_bfd, interp_sect); + + bfd_section_size (tmp_bfd.get (), interp_sect); } /* Now try to set a breakpoint in the dynamic linker. */ for (bkpt_namep = solib_break_names; *bkpt_namep != NULL; bkpt_namep++) { - sym_addr = gdb_bfd_lookup_symbol (tmp_bfd, cmp_name_and_sec_flags, + sym_addr = gdb_bfd_lookup_symbol (tmp_bfd.get (), + cmp_name_and_sec_flags, *bkpt_namep); if (sym_addr != 0) break; diff --git a/gdb/solib.c b/gdb/solib.c index db370e9..44e1396 100644 --- a/gdb/solib.c +++ b/gdb/solib.c @@ -474,15 +474,15 @@ solib_find (char *in_pathname, int *fd) function. If unsuccessful, the FD will be closed (unless FD was -1). */ -bfd * +gdb_bfd_ref_ptr solib_bfd_fopen (char *pathname, int fd) { - bfd *abfd = gdb_bfd_open (pathname, gnutarget, fd); + gdb_bfd_ref_ptr abfd (gdb_bfd_open (pathname, gnutarget, fd)); - if (abfd != NULL && !gdb_bfd_has_target_filename (abfd)) - bfd_set_cacheable (abfd, 1); + if (abfd != NULL && !gdb_bfd_has_target_filename (abfd.get ())) + bfd_set_cacheable (abfd.get (), 1); - if (!abfd) + if (abfd == NULL) { make_cleanup (xfree, pathname); error (_("Could not open `%s' as an executable file: %s"), @@ -496,12 +496,11 @@ solib_bfd_fopen (char *pathname, int fd) /* Find shared library PATHNAME and open a BFD for it. */ -bfd * +gdb_bfd_ref_ptr solib_bfd_open (char *pathname) { char *found_pathname; int found_file; - bfd *abfd; const struct bfd_arch_info *b; /* Search for shared library file. */ @@ -511,28 +510,26 @@ solib_bfd_open (char *pathname) /* Return failure if the file could not be found, so that we can accumulate messages about missing libraries. */ if (errno == ENOENT) - return NULL; + return gdb_bfd_ref_ptr (); perror_with_name (pathname); } /* Open bfd for shared library. */ - abfd = solib_bfd_fopen (found_pathname, found_file); + gdb_bfd_ref_ptr abfd (solib_bfd_fopen (found_pathname, found_file)); /* Check bfd format. */ - if (!bfd_check_format (abfd, bfd_object)) - { - make_cleanup_bfd_unref (abfd); - error (_("`%s': not in executable format: %s"), - bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ())); - } + if (!bfd_check_format (abfd.get (), bfd_object)) + error (_("`%s': not in executable format: %s"), + bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ())); /* Check bfd arch. */ b = gdbarch_bfd_arch_info (target_gdbarch ()); - if (!b->compatible (b, bfd_get_arch_info (abfd))) + if (!b->compatible (b, bfd_get_arch_info (abfd.get ()))) warning (_("`%s': Shared library architecture %s is not compatible " "with target architecture %s."), bfd_get_filename (abfd), - bfd_get_arch_info (abfd)->printable_name, b->printable_name); + bfd_get_arch_info (abfd.get ())->printable_name, + b->printable_name); return abfd; } @@ -556,18 +553,17 @@ solib_map_sections (struct so_list *so) char *filename; struct target_section *p; struct cleanup *old_chain; - bfd *abfd; filename = tilde_expand (so->so_name); old_chain = make_cleanup (xfree, filename); - abfd = ops->bfd_open (filename); + gdb_bfd_ref_ptr abfd (ops->bfd_open (filename)); do_cleanups (old_chain); if (abfd == NULL) return 0; /* Leave bfd open, core_xfer_memory and "info files" need it. */ - so->abfd = abfd; + so->abfd = abfd.release (); /* Copy the full path name into so_name, allowing symbol_file_add to find it later. This also affects the =library-loaded GDB/MI @@ -575,14 +571,14 @@ solib_map_sections (struct so_list *so) the library's host-side path. If we let the target dictate that objfile's path, and the target is different from the host, GDB/MI will not provide the correct host-side path. */ - if (strlen (bfd_get_filename (abfd)) >= SO_NAME_MAX_PATH_SIZE) + if (strlen (bfd_get_filename (so->abfd)) >= SO_NAME_MAX_PATH_SIZE) error (_("Shared library file name is too long.")); - strcpy (so->so_name, bfd_get_filename (abfd)); + strcpy (so->so_name, bfd_get_filename (so->abfd)); - if (build_section_table (abfd, &so->sections, &so->sections_end)) + if (build_section_table (so->abfd, &so->sections, &so->sections_end)) { error (_("Can't find the file sections in `%s': %s"), - bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ())); + bfd_get_filename (so->abfd), bfd_errmsg (bfd_get_error ())); } for (p = so->sections; p < so->sections_end; p++) @@ -1373,7 +1369,6 @@ reload_shared_libraries_1 (int from_tty) for (so = so_list_head; so != NULL; so = so->next) { char *filename, *found_pathname = NULL; - bfd *abfd; int was_loaded = so->symbols_loaded; symfile_add_flags add_flags = SYMFILE_DEFER_BP_RESET; @@ -1382,12 +1377,11 @@ reload_shared_libraries_1 (int from_tty) filename = tilde_expand (so->so_original_name); make_cleanup (xfree, filename); - abfd = solib_bfd_open (filename); + gdb_bfd_ref_ptr abfd (solib_bfd_open (filename)); if (abfd != NULL) { - found_pathname = xstrdup (bfd_get_filename (abfd)); + found_pathname = xstrdup (bfd_get_filename (abfd.get ())); make_cleanup (xfree, found_pathname); - gdb_bfd_unref (abfd); } /* If this shared library is no longer associated with its previous diff --git a/gdb/solist.h b/gdb/solist.h index f709483..ca02051 100644 --- a/gdb/solist.h +++ b/gdb/solist.h @@ -22,6 +22,7 @@ #define SO_NAME_MAX_PATH_SIZE 512 /* FIXME: Should be dynamic */ /* For domain_enum domain. */ #include "symtab.h" +#include "gdb_bfd.h" /* Forward declaration for target specific link map information. This struct is opaque to all but the target specific file. */ @@ -121,7 +122,7 @@ struct target_so_ops int (*in_dynsym_resolve_code) (CORE_ADDR pc); /* Find and open shared library binary file. */ - bfd *(*bfd_open) (char *pathname); + gdb_bfd_ref_ptr (*bfd_open) (char *pathname); /* Optional extra hook for finding and opening a solib. If TEMP_PATHNAME is non-NULL: If the file is successfully opened a @@ -178,10 +179,10 @@ extern char *exec_file_find (char *in_pathname, int *fd); extern char *solib_find (char *in_pathname, int *fd); /* Open BFD for shared library file. */ -extern bfd *solib_bfd_fopen (char *pathname, int fd); +extern gdb_bfd_ref_ptr solib_bfd_fopen (char *pathname, int fd); /* Find solib binary file and open it. */ -extern bfd *solib_bfd_open (char *in_pathname); +extern gdb_bfd_ref_ptr solib_bfd_open (char *in_pathname); /* FIXME: gdbarch needs to control this variable. */ extern struct target_so_ops *current_target_so_ops; diff --git a/gdb/spu-linux-nat.c b/gdb/spu-linux-nat.c index f1d58ec..75d8868 100644 --- a/gdb/spu-linux-nat.c +++ b/gdb/spu-linux-nat.c @@ -318,37 +318,35 @@ spu_bfd_iovec_stat (struct bfd *abfd, void *stream, struct stat *sb) return 0; } -static bfd * +static gdb_bfd_ref_ptr spu_bfd_open (ULONGEST addr) { - struct bfd *nbfd; asection *spu_name; ULONGEST *open_closure = XNEW (ULONGEST); *open_closure = addr; - nbfd = gdb_bfd_openr_iovec ("<in-memory>", "elf32-spu", - spu_bfd_iovec_open, open_closure, - spu_bfd_iovec_pread, spu_bfd_iovec_close, - spu_bfd_iovec_stat); - if (!nbfd) - return NULL; + gdb_bfd_ref_ptr nbfd (gdb_bfd_openr_iovec ("<in-memory>", "elf32-spu", + spu_bfd_iovec_open, open_closure, + spu_bfd_iovec_pread, + spu_bfd_iovec_close, + spu_bfd_iovec_stat)); + if (nbfd == NULL) + return gdb_bfd_ref_ptr (); - if (!bfd_check_format (nbfd, bfd_object)) - { - gdb_bfd_unref (nbfd); - return NULL; - } + if (!bfd_check_format (nbfd.get (), bfd_object)) + return gdb_bfd_ref_ptr (); /* Retrieve SPU name note and update BFD name. */ - spu_name = bfd_get_section_by_name (nbfd, ".note.spu_name"); + spu_name = bfd_get_section_by_name (nbfd.get (), ".note.spu_name"); if (spu_name) { - int sect_size = bfd_section_size (nbfd, spu_name); + int sect_size = bfd_section_size (nbfd.get (), spu_name); if (sect_size > 20) { char *buf = (char *)alloca (sect_size - 20 + 1); - bfd_get_section_contents (nbfd, spu_name, buf, 20, sect_size - 20); + bfd_get_section_contents (nbfd.get (), spu_name, buf, 20, + sect_size - 20); buf[sect_size - 20] = '\0'; xfree ((char *)nbfd->filename); @@ -367,7 +365,6 @@ static void spu_symbol_file_add_from_memory (int inferior_fd) { ULONGEST addr; - struct bfd *nbfd; gdb_byte id[128]; char annex[32]; @@ -385,15 +382,12 @@ spu_symbol_file_add_from_memory (int inferior_fd) return; /* Open BFD representing SPE executable and read its symbols. */ - nbfd = spu_bfd_open (addr); - if (nbfd) + gdb_bfd_ref_ptr nbfd (spu_bfd_open (addr)); + if (nbfd != NULL) { - struct cleanup *cleanup = make_cleanup_bfd_unref (nbfd); - - symbol_file_add_from_bfd (nbfd, bfd_get_filename (nbfd), + symbol_file_add_from_bfd (nbfd.get (), bfd_get_filename (nbfd), SYMFILE_VERBOSE | SYMFILE_MAINLINE, NULL, 0, NULL); - do_cleanups (cleanup); } } diff --git a/gdb/symfile-mem.c b/gdb/symfile-mem.c index 58257b9..ec283b2 100644 --- a/gdb/symfile-mem.c +++ b/gdb/symfile-mem.c @@ -102,20 +102,21 @@ symbol_file_add_from_memory (struct bfd *templ, CORE_ADDR addr, error (_("Failed to read a valid object file image from memory.")); gdb_bfd_ref (nbfd); + /* Manage the new reference for the duration of this function. */ + gdb_bfd_ref_ptr nbfd_holder (nbfd); + xfree (bfd_get_filename (nbfd)); if (name == NULL) nbfd->filename = xstrdup ("shared object read from target memory"); else nbfd->filename = name; - cleanup = make_cleanup_bfd_unref (nbfd); - if (!bfd_check_format (nbfd, bfd_object)) error (_("Got object file from memory but can't read symbols: %s."), bfd_errmsg (bfd_get_error ())); sai = alloc_section_addr_info (bfd_count_sections (nbfd)); - make_cleanup (xfree, sai); + cleanup = make_cleanup (xfree, sai); i = 0; for (sec = nbfd->sections; sec != NULL; sec = sec->next) if ((bfd_get_section_flags (nbfd, sec) & (SEC_ALLOC|SEC_LOAD)) != 0) diff --git a/gdb/symfile.c b/gdb/symfile.c index 52f99bf..4775d5b 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -876,8 +876,7 @@ read_symbols (struct objfile *objfile, symfile_add_flags add_flags) && objfile->separate_debug_objfile == NULL && objfile->separate_debug_objfile_backlink == NULL) { - bfd *abfd = find_separate_debug_file_in_section (objfile); - struct cleanup *cleanup = make_cleanup_bfd_unref (abfd); + gdb_bfd_ref_ptr abfd (find_separate_debug_file_in_section (objfile)); if (abfd != NULL) { @@ -885,11 +884,9 @@ read_symbols (struct objfile *objfile, symfile_add_flags add_flags) virtual section-as-bfd like the bfd filename containing the section. Therefore use also non-canonical name form for the same file containing the section. */ - symbol_file_add_separate (abfd, objfile->original_name, add_flags, - objfile); + symbol_file_add_separate (abfd.get (), objfile->original_name, + add_flags, objfile); } - - do_cleanups (cleanup); } if ((add_flags & SYMFILE_NO_READ) == 0) require_partial_symbols (objfile, 0); @@ -1287,13 +1284,10 @@ struct objfile * symbol_file_add (const char *name, symfile_add_flags add_flags, struct section_addr_info *addrs, objfile_flags flags) { - bfd *bfd = symfile_bfd_open (name); - struct cleanup *cleanup = make_cleanup_bfd_unref (bfd); - struct objfile *objf; + gdb_bfd_ref_ptr bfd (symfile_bfd_open (name)); - objf = symbol_file_add_from_bfd (bfd, name, add_flags, addrs, flags, NULL); - do_cleanups (cleanup); - return objf; + return symbol_file_add_from_bfd (bfd.get (), name, add_flags, addrs, + flags, NULL); } /* Call symbol_file_add() with default values and update whatever is @@ -1354,7 +1348,6 @@ separate_debug_file_exists (const char *name, unsigned long crc, { unsigned long file_crc; int file_crc_p; - bfd *abfd; struct stat parent_stat, abfd_stat; int verified_as_different; @@ -1367,9 +1360,9 @@ separate_debug_file_exists (const char *name, unsigned long crc, if (filename_cmp (name, objfile_name (parent_objfile)) == 0) return 0; - abfd = gdb_bfd_open (name, gnutarget, -1); + gdb_bfd_ref_ptr abfd (gdb_bfd_open (name, gnutarget, -1)); - if (!abfd) + if (abfd == NULL) return 0; /* Verify symlinks were not the cause of filename_cmp name difference above. @@ -1383,24 +1376,19 @@ separate_debug_file_exists (const char *name, unsigned long crc, numbers will never set st_ino to zero, this is merely an optimization, so we do not need to worry about false negatives. */ - if (bfd_stat (abfd, &abfd_stat) == 0 + if (bfd_stat (abfd.get (), &abfd_stat) == 0 && abfd_stat.st_ino != 0 && bfd_stat (parent_objfile->obfd, &parent_stat) == 0) { if (abfd_stat.st_dev == parent_stat.st_dev && abfd_stat.st_ino == parent_stat.st_ino) - { - gdb_bfd_unref (abfd); - return 0; - } + return 0; verified_as_different = 1; } else verified_as_different = 0; - file_crc_p = gdb_bfd_crc (abfd, &file_crc); - - gdb_bfd_unref (abfd); + file_crc_p = gdb_bfd_crc (abfd.get (), &file_crc); if (!file_crc_p) return 0; @@ -1721,10 +1709,9 @@ set_initial_language (void) includes a newly malloc'd` copy of NAME (tilde-expanded and made absolute). In case of trouble, error() is called. */ -bfd * +gdb_bfd_ref_ptr symfile_bfd_open (const char *name) { - bfd *sym_bfd; int desc = -1; struct cleanup *back_to = make_cleanup (null_cleanup, 0); @@ -1760,20 +1747,17 @@ symfile_bfd_open (const char *name) name = absolute_name; } - sym_bfd = gdb_bfd_open (name, gnutarget, desc); - if (!sym_bfd) + gdb_bfd_ref_ptr sym_bfd (gdb_bfd_open (name, gnutarget, desc)); + if (sym_bfd == NULL) error (_("`%s': can't open to read symbols: %s."), name, bfd_errmsg (bfd_get_error ())); - if (!gdb_bfd_has_target_filename (sym_bfd)) - bfd_set_cacheable (sym_bfd, 1); + if (!gdb_bfd_has_target_filename (sym_bfd.get ())) + bfd_set_cacheable (sym_bfd.get (), 1); - if (!bfd_check_format (sym_bfd, bfd_object)) - { - make_cleanup_bfd_unref (sym_bfd); - error (_("`%s': can't read symbols: %s."), name, - bfd_errmsg (bfd_get_error ())); - } + if (!bfd_check_format (sym_bfd.get (), bfd_object)) + error (_("`%s': can't read symbols: %s."), name, + bfd_errmsg (bfd_get_error ())); do_cleanups (back_to); @@ -2073,7 +2057,6 @@ static void print_transfer_performance (struct ui_file *stream, void generic_load (const char *args, int from_tty) { - bfd *loadfile_bfd; char *filename; struct cleanup *old_cleanups = make_cleanup (null_cleanup, 0); struct load_section_data cbdata; @@ -2114,25 +2097,23 @@ generic_load (const char *args, int from_tty) } /* Open the file for loading. */ - loadfile_bfd = gdb_bfd_open (filename, gnutarget, -1); + gdb_bfd_ref_ptr loadfile_bfd (gdb_bfd_open (filename, gnutarget, -1)); if (loadfile_bfd == NULL) { perror_with_name (filename); return; } - make_cleanup_bfd_unref (loadfile_bfd); - - if (!bfd_check_format (loadfile_bfd, bfd_object)) + if (!bfd_check_format (loadfile_bfd.get (), bfd_object)) { error (_("\"%s\" is not an object file: %s"), filename, bfd_errmsg (bfd_get_error ())); } - bfd_map_over_sections (loadfile_bfd, add_section_size_callback, + bfd_map_over_sections (loadfile_bfd.get (), add_section_size_callback, (void *) &total_progress.total_size); - bfd_map_over_sections (loadfile_bfd, load_section_callback, &cbdata); + bfd_map_over_sections (loadfile_bfd.get (), load_section_callback, &cbdata); using namespace std::chrono; @@ -2144,7 +2125,7 @@ generic_load (const char *args, int from_tty) steady_clock::time_point end_time = steady_clock::now (); - entry = bfd_get_start_address (loadfile_bfd); + entry = bfd_get_start_address (loadfile_bfd.get ()); entry = gdbarch_addr_bits_remove (target_gdbarch (), entry); ui_out_text (uiout, "Start address "); ui_out_field_fmt (uiout, "address", "%s", paddress (target_gdbarch (), entry)); @@ -2568,22 +2549,16 @@ reread_symbols (void) /* Clean up any state BFD has sitting around. */ { - struct bfd *obfd = objfile->obfd; + gdb_bfd_ref_ptr obfd (objfile->obfd); char *obfd_filename; obfd_filename = bfd_get_filename (objfile->obfd); /* Open the new BFD before freeing the old one, so that the filename remains live. */ - objfile->obfd = gdb_bfd_open (obfd_filename, gnutarget, -1); + gdb_bfd_ref_ptr temp (gdb_bfd_open (obfd_filename, gnutarget, -1)); + objfile->obfd = temp.release (); if (objfile->obfd == NULL) - { - /* We have to make a cleanup and error here, rather - than erroring later, because once we unref OBFD, - OBFD_FILENAME will be freed. */ - make_cleanup_bfd_unref (obfd); - error (_("Can't open %s to read symbols."), obfd_filename); - } - gdb_bfd_unref (obfd); + error (_("Can't open %s to read symbols."), obfd_filename); } original_name = xstrdup (objfile->original_name); diff --git a/gdb/symfile.h b/gdb/symfile.h index 59952cb..7a2e6fb 100644 --- a/gdb/symfile.h +++ b/gdb/symfile.h @@ -25,6 +25,7 @@ #include "probe.h" #include "symfile-add-flags.h" #include "objfile-flags.h" +#include "gdb_bfd.h" /* Opaque declarations. */ struct target_section; @@ -499,7 +500,7 @@ extern void set_initial_language (void); extern void find_lowest_section (bfd *, asection *, void *); -extern bfd *symfile_bfd_open (const char *); +extern gdb_bfd_ref_ptr symfile_bfd_open (const char *); extern int get_section_index (struct objfile *, char *); @@ -646,6 +647,6 @@ extern void elfmdebug_build_psymtabs (struct objfile *, /* From minidebug.c. */ -extern bfd *find_separate_debug_file_in_section (struct objfile *); +extern gdb_bfd_ref_ptr find_separate_debug_file_in_section (struct objfile *); #endif /* !defined(SYMFILE_H) */ diff --git a/gdb/utils.c b/gdb/utils.c index 77c38bf..6ee6fc8 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -151,18 +151,6 @@ make_cleanup_freeargv (char **arg) return make_cleanup (do_freeargv, arg); } -static void -do_bfd_close_cleanup (void *arg) -{ - gdb_bfd_unref ((bfd *) arg); -} - -struct cleanup * -make_cleanup_bfd_unref (bfd *abfd) -{ - return make_cleanup (do_bfd_close_cleanup, abfd); -} - /* Helper function which does the work for make_cleanup_fclose. */ static void diff --git a/gdb/utils.h b/gdb/utils.h index 349530e..4407eeb 100644 --- a/gdb/utils.h +++ b/gdb/utils.h @@ -81,8 +81,6 @@ extern struct cleanup *(make_cleanup_free_section_addr_info extern struct cleanup *make_cleanup_fclose (FILE *file); -extern struct cleanup *make_cleanup_bfd_unref (bfd *abfd); - struct obstack; extern struct cleanup *make_cleanup_obstack_free (struct obstack *obstack); diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c index 5b79f34..efccd71 100644 --- a/gdb/windows-nat.c +++ b/gdb/windows-nat.c @@ -669,32 +669,27 @@ windows_make_so (const char *name, LPVOID load_addr) p = strchr (so->so_name, '\0') - (sizeof ("/cygwin1.dll") - 1); if (p >= so->so_name && strcasecmp (p, "/cygwin1.dll") == 0) { - bfd *abfd; asection *text = NULL; CORE_ADDR text_vma; - abfd = gdb_bfd_open (so->so_name, "pei-i386", -1); + gdb_bfd_ref_ptr abfd (gdb_bfd_open (so->so_name, "pei-i386", -1)); - if (!abfd) + if (abfd == NULL) return so; - if (bfd_check_format (abfd, bfd_object)) - text = bfd_get_section_by_name (abfd, ".text"); + if (bfd_check_format (abfd.get (), bfd_object)) + text = bfd_get_section_by_name (abfd.get (), ".text"); if (!text) - { - gdb_bfd_unref (abfd); - return so; - } + return so; /* The symbols in a dll are offset by 0x1000, which is the offset from 0 of the first byte in an image - because of the file header and the section alignment. */ cygwin_load_start = (CORE_ADDR) (uintptr_t) ((char *) load_addr + 0x1000); - cygwin_load_end = cygwin_load_start + bfd_section_size (abfd, text); - - gdb_bfd_unref (abfd); + cygwin_load_end = cygwin_load_start + bfd_section_size (abfd.get (), + text); } #endif diff --git a/gdb/windows-tdep.c b/gdb/windows-tdep.c index 810607a..2f79d8d 100644 --- a/gdb/windows-tdep.c +++ b/gdb/windows-tdep.c @@ -372,7 +372,6 @@ windows_xfer_shared_library (const char* so_name, CORE_ADDR load_addr, struct gdbarch *gdbarch, struct obstack *obstack) { char *p; - struct bfd * dll; CORE_ADDR text_offset; obstack_grow_str (obstack, "<library name=\""); @@ -380,12 +379,11 @@ windows_xfer_shared_library (const char* so_name, CORE_ADDR load_addr, obstack_grow_str (obstack, p); xfree (p); obstack_grow_str (obstack, "\"><segment address=\""); - dll = gdb_bfd_open (so_name, gnutarget, -1); + gdb_bfd_ref_ptr dll (gdb_bfd_open (so_name, gnutarget, -1)); /* The following calls are OK even if dll is NULL. The default value 0x1000 is returned by pe_text_section_offset in that case. */ - text_offset = pe_text_section_offset (dll); - gdb_bfd_unref (dll); + text_offset = pe_text_section_offset (dll.get ()); obstack_grow_str (obstack, paddress (gdbarch, load_addr + text_offset)); obstack_grow_str (obstack, "\"/></library>"); } -- 2.7.4 ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 2/8] Use class to manage BFD reference counts 2016-11-29 5:06 ` [RFA 2/8] Use class to manage BFD reference counts Tom Tromey @ 2016-12-02 13:05 ` Pedro Alves 2016-12-13 13:26 ` Tom Tromey 0 siblings, 1 reply; 50+ messages in thread From: Pedro Alves @ 2016-12-02 13:05 UTC (permalink / raw) To: Tom Tromey, gdb-patches > @@ -10535,7 +10526,7 @@ open_dwo_file (const char *file_name, const char *comp_dir) > is a list of paths. */ > > if (*debug_file_directory == '\0') > - return NULL; > + return gdb_bfd_ref_ptr (); This provides a good reason to have an implicit construction from nullptr_t. You had it in the original gdbpy_reference submission, but I had asked to remove it. If we add it back, these cases could be more clearly written as "return NULL/nullptr". Could you do that, and then drop all the hunks like: > - return NULL; > + return gdb_bfd_ref_ptr (); ? > @@ -658,82 +654,70 @@ 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); > + gdb::unique_xmalloc_ptr<char> filename > + (xstrprintf ("%.*s", filename_len, pathname)); > + gdb::unique_xmalloc_ptr<char> member_name > + (xstrprintf ("%.*s", path_len - filename_len - 2, sep + 1)); I think these could be: 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. */ > - found_pathname = solib_find (filename, &found_file); > + found_pathname = solib_find (filename.get (), &found_file); > if (found_pathname == NULL) > perror_with_name (pathname); > - archive_bfd = solib_bfd_fopen (found_pathname, found_file); > + gdb_bfd_ref_ptr archive_bfd (solib_bfd_fopen (found_pathname, 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); > - return NULL; > + filename.get (), bfd_errmsg (bfd_get_error ())); > + return gdb_bfd_ref_ptr (); > } > > - 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); > - return NULL; > + filename.get (), bfd_errmsg (bfd_get_error ())); > + return gdb_bfd_ref_ptr (); > } > > - 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 (strcmp (member_name.get (), object_bfd->filename) == 0) > break; Then here: member_name == object_bfd->filename > > - 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 ()); > } > Otherwise LGTM. Thanks, Pedro Alves ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 2/8] Use class to manage BFD reference counts 2016-12-02 13:05 ` Pedro Alves @ 2016-12-13 13:26 ` Tom Tromey 2016-12-15 4:12 ` Tom Tromey 2016-12-20 17:19 ` [pushed] gdb: Constify solib_find (Re: [RFA 2/8] Use class to manage BFD reference counts) Pedro Alves 0 siblings, 2 replies; 50+ messages in thread From: Tom Tromey @ 2016-12-13 13:26 UTC (permalink / raw) To: Pedro Alves; +Cc: Tom Tromey, gdb-patches >>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes: >> - return NULL; >> + return gdb_bfd_ref_ptr (); Pedro> This provides a good reason to have an implicit construction from Pedro> nullptr_t. You had it in the original gdbpy_reference Pedro> submission, but I had asked to remove it. If we add it back, Pedro> these cases could be more clearly written as "return Pedro> NULL/nullptr". Could you do that, and then drop all the hunks Pedro> like: >> - return NULL; >> + return gdb_bfd_ref_ptr (); Pedro> ? I did this. Pedro> I think these could be: Pedro> std::string filename Pedro> = string_printf ("%.*s", filename_len, pathname); Pedro> std::string member_name Pedro> = string_printf ("%.*s", path_len - filename_len - 2, sep + 1)); I did this, but it's a bit ugly as solib_find isn't const-correct. I'll send a new patch soon. Tom ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 2/8] Use class to manage BFD reference counts 2016-12-13 13:26 ` Tom Tromey @ 2016-12-15 4:12 ` Tom Tromey 2016-12-20 18:18 ` Pedro Alves 2016-12-20 17:19 ` [pushed] gdb: Constify solib_find (Re: [RFA 2/8] Use class to manage BFD reference counts) Pedro Alves 1 sibling, 1 reply; 50+ messages in thread From: Tom Tromey @ 2016-12-15 4:12 UTC (permalink / raw) To: Tom Tromey; +Cc: Pedro Alves, gdb-patches >>>>> "Tom" == Tom Tromey <tom@tromey.com> writes: Tom> I'll send a new patch soon. Here it is. This was part of the series I sent through buildbot. Tom commit 01194fdb20215d47306a30814000a5663afa5fa1 Author: Tom Tromey <tom@tromey.com> Date: Mon Nov 21 11:12:23 2016 -0700 Use class to manage BFD reference counts This introduces a new specialization of gdb::ref_ptr that can be used to manage BFD reference counts. Then it changes most places in gdb to use this new class, rather than explicit reference-counting or cleanups. This patch removes make_cleanup_bfd_unref. If you look you will see a couple of spots using "release" where a use of gdb_bfd_ref_ptr would be cleaner. These will be fixed in the next patch. I think this patch fixes some latent bugs. For example, it seems to me that previously objfpy_add_separate_debug_file leaked a BFD. I'm not 100% certain that the macho_symfile_read_all_oso change is correct. The existing code here is hard for me to follow. One goal of this sort of automated reference counting, though, is to make it more difficult to make logic errors; so hopefully the code is clear now. 2016-12-13 Tom Tromey <tom@tromey.com> * windows-tdep.c (windows_xfer_shared_library): Update. * windows-nat.c (windows_make_so): Update. * utils.h (make_cleanup_bfd_unref): Remove. * utils.c (do_bfd_close_cleanup, make_cleanup_bfd_unref): Remove. * symfile.h (symfile_bfd_open) (find_separate_debug_file_in_section): Return gdb_bfd_ref_ptr. * symfile.c (read_symbols, symbol_file_add) (separate_debug_file_exists): Update. (symfile_bfd_open): Return gdb_bfd_ref_ptr. (generic_load, reread_symbols): Update. * symfile-mem.c (symbol_file_add_from_memory): Update. * spu-linux-nat.c (spu_bfd_open): Return gdb_bfd_ref_ptr. (spu_symbol_file_add_from_memory): Update. * solist.h (struct target_so_ops) <bfd_open>: Return gdb_bfd_ref_ptr. (solib_bfd_fopen, solib_bfd_open): Return gdb_bfd_ref_ptr. * solib.c (solib_bfd_fopen, solib_bfd_open): Return gdb_bfd_ref_ptr. (solib_map_sections, reload_shared_libraries_1): Update. * solib-svr4.c (enable_break): Update. * solib-spu.c (spu_bfd_fopen): Return gdb_bfd_ref_ptr. * solib-frv.c (enable_break2): Update. * solib-dsbt.c (enable_break): Update. * solib-darwin.c (gdb_bfd_mach_o_fat_extract): Return gdb_bfd_ref_ptr. (darwin_solib_get_all_image_info_addr_at_init): Update. (darwin_bfd_open): Return gdb_bfd_ref_ptr. * solib-aix.c (solib_aix_bfd_open): Return gdb_bfd_ref_ptr. * record-full.c (record_full_save): Update. * python/py-objfile.c (objfpy_add_separate_debug_file): Update. * procfs.c (insert_dbx_link_bpt_in_file): Update. * minidebug.c (find_separate_debug_file_in_section): Return gdb_bfd_ref_ptr. * machoread.c (macho_add_oso_symfile): Change abfd to gdb_bfd_ref_ptr. (macho_symfile_read_all_oso): Update. (macho_check_dsym): Return gdb_bfd_ref_ptr. (macho_symfile_read): Update. * jit.c (bfd_open_from_target_memory): Return gdb_bfd_ref_ptr. (jit_bfd_try_read_symtab): Update. * gdb_bfd.h (gdb_bfd_open, gdb_bfd_fopen, gdb_bfd_openr) (gdb_bfd_openw, gdb_bfd_openr_iovec) (gdb_bfd_openr_next_archived_file, gdb_bfd_fdopenr): Return gdb_bfd_ref_ptr. (gdb_bfd_ref_policy): New struct. (gdb_bfd_ref_ptr): New typedef. * gdb_bfd.c (gdb_bfd_open, gdb_bfd_fopen, gdb_bfd_openr) (gdb_bfd_openw, gdb_bfd_openr_iovec) (gdb_bfd_openr_next_archived_file, gdb_bfd_fdopenr): Return gdb_bfd_ref_ptr. * gcore.h (create_gcore_bfd): Return gdb_bfd_ref_ptr. * gcore.c (create_gcore_bfd): Return gdb_bfd_ref_ptr. (gcore_command): Update. * exec.c (exec_file_attach): Update. * elfread.c (elf_symfile_read): Update. * dwarf2read.c (dwarf2_get_dwz_file): Update. (try_open_dwop_file, open_dwo_file): Return gdb_bfd_ref_ptr. (open_and_init_dwo_file): Update. (open_dwp_file): Return gdb_bfd_ref_ptr. (open_and_init_dwp_file): Update. * corelow.c (core_open): Update. * compile/compile-object-load.c (compile_object_load): Update. * common/gdb_ref_ptr.h (ref_ptr::operator->): New operator. * coffread.c (coff_symfile_read): Update. * cli/cli-dump.c (bfd_openr_or_error, bfd_openw_or_error): Return gdb_bfd_ref_ptr. Rename. (dump_bfd_file, restore_command): Update. * build-id.h (build_id_to_debug_bfd): Return gdb_bfd_ref_ptr. * build-id.c (build_id_to_debug_bfd): Return gdb_bfd_ref_ptr. (find_separate_debug_file_by_buildid): Update. diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 4377e12..f2a89f5 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,78 @@ 2016-12-13 Tom Tromey <tom@tromey.com> + * windows-tdep.c (windows_xfer_shared_library): Update. + * windows-nat.c (windows_make_so): Update. + * utils.h (make_cleanup_bfd_unref): Remove. + * utils.c (do_bfd_close_cleanup, make_cleanup_bfd_unref): Remove. + * symfile.h (symfile_bfd_open) + (find_separate_debug_file_in_section): Return gdb_bfd_ref_ptr. + * symfile.c (read_symbols, symbol_file_add) + (separate_debug_file_exists): Update. + (symfile_bfd_open): Return gdb_bfd_ref_ptr. + (generic_load, reread_symbols): Update. + * symfile-mem.c (symbol_file_add_from_memory): Update. + * spu-linux-nat.c (spu_bfd_open): Return gdb_bfd_ref_ptr. + (spu_symbol_file_add_from_memory): Update. + * solist.h (struct target_so_ops) <bfd_open>: Return + gdb_bfd_ref_ptr. + (solib_bfd_fopen, solib_bfd_open): Return gdb_bfd_ref_ptr. + * solib.c (solib_bfd_fopen, solib_bfd_open): Return + gdb_bfd_ref_ptr. + (solib_map_sections, reload_shared_libraries_1): Update. + * solib-svr4.c (enable_break): Update. + * solib-spu.c (spu_bfd_fopen): Return gdb_bfd_ref_ptr. + * solib-frv.c (enable_break2): Update. + * solib-dsbt.c (enable_break): Update. + * solib-darwin.c (gdb_bfd_mach_o_fat_extract): Return + gdb_bfd_ref_ptr. + (darwin_solib_get_all_image_info_addr_at_init): Update. + (darwin_bfd_open): Return gdb_bfd_ref_ptr. + * solib-aix.c (solib_aix_bfd_open): Return gdb_bfd_ref_ptr. + * record-full.c (record_full_save): Update. + * python/py-objfile.c (objfpy_add_separate_debug_file): Update. + * procfs.c (insert_dbx_link_bpt_in_file): Update. + * minidebug.c (find_separate_debug_file_in_section): Return + gdb_bfd_ref_ptr. + * machoread.c (macho_add_oso_symfile): Change abfd to + gdb_bfd_ref_ptr. + (macho_symfile_read_all_oso): Update. + (macho_check_dsym): Return gdb_bfd_ref_ptr. + (macho_symfile_read): Update. + * jit.c (bfd_open_from_target_memory): Return gdb_bfd_ref_ptr. + (jit_bfd_try_read_symtab): Update. + * gdb_bfd.h (gdb_bfd_open, gdb_bfd_fopen, gdb_bfd_openr) + (gdb_bfd_openw, gdb_bfd_openr_iovec) + (gdb_bfd_openr_next_archived_file, gdb_bfd_fdopenr): Return + gdb_bfd_ref_ptr. + (gdb_bfd_ref_policy): New struct. + (gdb_bfd_ref_ptr): New typedef. + * gdb_bfd.c (gdb_bfd_open, gdb_bfd_fopen, gdb_bfd_openr) + (gdb_bfd_openw, gdb_bfd_openr_iovec) + (gdb_bfd_openr_next_archived_file, gdb_bfd_fdopenr): Return + gdb_bfd_ref_ptr. + * gcore.h (create_gcore_bfd): Return gdb_bfd_ref_ptr. + * gcore.c (create_gcore_bfd): Return gdb_bfd_ref_ptr. + (gcore_command): Update. + * exec.c (exec_file_attach): Update. + * elfread.c (elf_symfile_read): Update. + * dwarf2read.c (dwarf2_get_dwz_file): Update. + (try_open_dwop_file, open_dwo_file): Return gdb_bfd_ref_ptr. + (open_and_init_dwo_file): Update. + (open_dwp_file): Return gdb_bfd_ref_ptr. + (open_and_init_dwp_file): Update. + * corelow.c (core_open): Update. + * compile/compile-object-load.c (compile_object_load): Update. + * common/gdb_ref_ptr.h (ref_ptr::operator->): New operator. + * coffread.c (coff_symfile_read): Update. + * cli/cli-dump.c (bfd_openr_or_error, bfd_openw_or_error): Return + gdb_bfd_ref_ptr. Rename. + (dump_bfd_file, restore_command): Update. + * build-id.h (build_id_to_debug_bfd): Return gdb_bfd_ref_ptr. + * build-id.c (build_id_to_debug_bfd): Return gdb_bfd_ref_ptr. + (find_separate_debug_file_by_buildid): Update. + +2016-12-13 Tom Tromey <tom@tromey.com> + * common/gdb_ref_ptr.h: New file. * python/py-ref.h (struct gdbpy_ref_policy): New. (gdbpy_ref): Now a typedef. diff --git a/gdb/build-id.c b/gdb/build-id.c index 886f2d7..029cb4d 100644 --- a/gdb/build-id.c +++ b/gdb/build-id.c @@ -67,14 +67,14 @@ build_id_verify (bfd *abfd, size_t check_len, const bfd_byte *check) /* See build-id.h. */ -bfd * +gdb_bfd_ref_ptr build_id_to_debug_bfd (size_t build_id_len, const bfd_byte *build_id) { char *link, *debugdir; VEC (char_ptr) *debugdir_vec; struct cleanup *back_to; int ix; - bfd *abfd = NULL; + gdb_bfd_ref_ptr abfd; int alloc_len; /* DEBUG_FILE_DIRECTORY/.build-id/ab/cdef */ @@ -127,11 +127,10 @@ build_id_to_debug_bfd (size_t build_id_len, const bfd_byte *build_id) if (abfd == NULL) continue; - if (build_id_verify (abfd, build_id_len, build_id)) + if (build_id_verify (abfd.get(), build_id_len, build_id)) break; - gdb_bfd_unref (abfd); - abfd = NULL; + abfd.release (); } do_cleanups (back_to); @@ -148,25 +147,16 @@ find_separate_debug_file_by_buildid (struct objfile *objfile) build_id = build_id_bfd_get (objfile->obfd); if (build_id != NULL) { - bfd *abfd; - - abfd = build_id_to_debug_bfd (build_id->size, build_id->data); + gdb_bfd_ref_ptr abfd (build_id_to_debug_bfd (build_id->size, + build_id->data)); /* Prevent looping on a stripped .debug file. */ if (abfd != NULL - && filename_cmp (bfd_get_filename (abfd), + && filename_cmp (bfd_get_filename (abfd.get ()), objfile_name (objfile)) == 0) - { - warning (_("\"%s\": separate debug info file has no debug info"), - bfd_get_filename (abfd)); - gdb_bfd_unref (abfd); - } + warning (_("\"%s\": separate debug info file has no debug info"), + bfd_get_filename (abfd.get ())); else if (abfd != NULL) - { - char *result = xstrdup (bfd_get_filename (abfd)); - - gdb_bfd_unref (abfd); - return result; - } + return xstrdup (bfd_get_filename (abfd.get ())); } return NULL; } diff --git a/gdb/build-id.h b/gdb/build-id.h index ddf0765..6c37dee 100644 --- a/gdb/build-id.h +++ b/gdb/build-id.h @@ -20,6 +20,8 @@ #ifndef BUILD_ID_H #define BUILD_ID_H +#include "gdb_bfd.h" + /* Locate NT_GNU_BUILD_ID from ABFD and return its content. */ extern const struct bfd_build_id *build_id_bfd_get (bfd *abfd); @@ -35,8 +37,8 @@ extern int build_id_verify (bfd *abfd, return NULL. The returned reference to the BFD must be released by the caller. */ -extern bfd *build_id_to_debug_bfd (size_t build_id_len, - const bfd_byte *build_id); +extern gdb_bfd_ref_ptr build_id_to_debug_bfd (size_t build_id_len, + const bfd_byte *build_id); /* Find the separate debug file for OBJFILE, by using the build-id associated with OBJFILE's BFD. If successful, returns a malloc'd diff --git a/gdb/cli/cli-dump.c b/gdb/cli/cli-dump.c index 781c638..ace721a 100644 --- a/gdb/cli/cli-dump.c +++ b/gdb/cli/cli-dump.c @@ -103,45 +103,40 @@ fopen_with_cleanup (const char *filename, const char *mode) return file; } -static bfd * -bfd_openr_with_cleanup (const char *filename, const char *target) +static gdb_bfd_ref_ptr +bfd_openr_or_error (const char *filename, const char *target) { - bfd *ibfd; - - ibfd = gdb_bfd_openr (filename, target); + gdb_bfd_ref_ptr ibfd (gdb_bfd_openr (filename, target)); if (ibfd == NULL) - error (_("Failed to open %s: %s."), filename, + error (_("Failed to open %s: %s."), filename, bfd_errmsg (bfd_get_error ())); - make_cleanup_bfd_unref (ibfd); - if (!bfd_check_format (ibfd, bfd_object)) + if (!bfd_check_format (ibfd.get (), bfd_object)) error (_("'%s' is not a recognized file format."), filename); return ibfd; } -static bfd * -bfd_openw_with_cleanup (const char *filename, const char *target, - const char *mode) +static gdb_bfd_ref_ptr +bfd_openw_or_error (const char *filename, const char *target, const char *mode) { - bfd *obfd; + gdb_bfd_ref_ptr obfd; if (*mode == 'w') /* Write: create new file */ { obfd = gdb_bfd_openw (filename, target); if (obfd == NULL) - error (_("Failed to open %s: %s."), filename, + error (_("Failed to open %s: %s."), filename, bfd_errmsg (bfd_get_error ())); - make_cleanup_bfd_unref (obfd); - if (!bfd_set_format (obfd, bfd_object)) - error (_("bfd_openw_with_cleanup: %s."), bfd_errmsg (bfd_get_error ())); + if (!bfd_set_format (obfd.get (), bfd_object)) + error (_("bfd_openw_or_error: %s."), bfd_errmsg (bfd_get_error ())); } else if (*mode == 'a') /* Append to existing file. */ { /* FIXME -- doesn't work... */ error (_("bfd_openw does not work with append.")); } else - error (_("bfd_openw_with_cleanup: unknown mode %s."), mode); + error (_("bfd_openw_or_error: unknown mode %s."), mode); return obfd; } @@ -187,20 +182,19 @@ dump_bfd_file (const char *filename, const char *mode, const char *target, CORE_ADDR vaddr, const bfd_byte *buf, ULONGEST len) { - bfd *obfd; asection *osection; - obfd = bfd_openw_with_cleanup (filename, target, mode); - osection = bfd_make_section_anyway (obfd, ".newsec"); - bfd_set_section_size (obfd, osection, len); - bfd_set_section_vma (obfd, osection, vaddr); - bfd_set_section_alignment (obfd, osection, 0); - bfd_set_section_flags (obfd, osection, (SEC_HAS_CONTENTS - | SEC_ALLOC - | SEC_LOAD)); + gdb_bfd_ref_ptr obfd (bfd_openw_or_error (filename, target, mode)); + osection = bfd_make_section_anyway (obfd.get (), ".newsec"); + bfd_set_section_size (obfd.get (), osection, len); + bfd_set_section_vma (obfd.get (), osection, vaddr); + bfd_set_section_alignment (obfd.get (), osection, 0); + bfd_set_section_flags (obfd.get (), osection, (SEC_HAS_CONTENTS + | SEC_ALLOC + | SEC_LOAD)); osection->entsize = 0; - if (!bfd_set_section_contents (obfd, osection, buf, 0, len)) - warning (_("writing dump file '%s' (%s)"), filename, + if (!bfd_set_section_contents (obfd.get (), osection, buf, 0, len)) + warning (_("writing dump file '%s' (%s)"), filename, bfd_errmsg (bfd_get_error ())); } @@ -624,12 +618,11 @@ restore_command (char *args_in, int from_tty) else { /* Open the file for loading. */ - ibfd = bfd_openr_with_cleanup (filename, NULL); + gdb_bfd_ref_ptr ibfd (bfd_openr_or_error (filename, NULL)); /* Process the sections. */ - bfd_map_over_sections (ibfd, restore_section_callback, &data); + bfd_map_over_sections (ibfd.get (), restore_section_callback, &data); } - return; } static void diff --git a/gdb/coffread.c b/gdb/coffread.c index 501e901..db32a92 100644 --- a/gdb/coffread.c +++ b/gdb/coffread.c @@ -742,10 +742,10 @@ coff_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags) if (debugfile) { - bfd *abfd = symfile_bfd_open (debugfile); + gdb_bfd_ref_ptr abfd (symfile_bfd_open (debugfile)); - make_cleanup_bfd_unref (abfd); - symbol_file_add_separate (abfd, debugfile, symfile_flags, objfile); + symbol_file_add_separate (abfd.get (), debugfile, symfile_flags, + objfile); } } diff --git a/gdb/common/gdb_ref_ptr.h b/gdb/common/gdb_ref_ptr.h index fbf4688..0bb77ec 100644 --- a/gdb/common/gdb_ref_ptr.h +++ b/gdb/common/gdb_ref_ptr.h @@ -143,6 +143,12 @@ class ref_ptr return result; } + /* Let users refer to members of the underlying pointer. */ + T *operator-> () const + { + return m_obj; + } + private: T *m_obj; diff --git a/gdb/compile/compile-object-load.c b/gdb/compile/compile-object-load.c index c08aa2b..7351148 100644 --- a/gdb/compile/compile-object-load.c +++ b/gdb/compile/compile-object-load.c @@ -612,7 +612,6 @@ compile_object_load (const compile_file_names &file_names, enum compile_i_scope_types scope, void *scope_data) { struct cleanup *cleanups, *cleanups_free_objfile; - bfd *abfd; struct setup_sections_data setup_sections_data; CORE_ADDR addr, regs_addr, out_value_addr = 0; struct symbol *func_sym; @@ -634,17 +633,16 @@ compile_object_load (const compile_file_names &file_names, filename = tilde_expand (file_names.object_file ()); cleanups = make_cleanup (xfree, filename); - abfd = gdb_bfd_open (filename, gnutarget, -1); + gdb_bfd_ref_ptr abfd (gdb_bfd_open (filename, gnutarget, -1)); if (abfd == NULL) error (_("\"%s\": could not open as compiled module: %s"), filename, bfd_errmsg (bfd_get_error ())); - make_cleanup_bfd_unref (abfd); - if (!bfd_check_format_matches (abfd, bfd_object, &matching)) + if (!bfd_check_format_matches (abfd.get (), bfd_object, &matching)) error (_("\"%s\": not in loadable format: %s"), filename, gdb_bfd_errmsg (bfd_get_error (), matching)); - if ((bfd_get_file_flags (abfd) & (EXEC_P | DYNAMIC)) != 0) + if ((bfd_get_file_flags (abfd.get ()) & (EXEC_P | DYNAMIC)) != 0) error (_("\"%s\": not in object format."), filename); setup_sections_data.last_size = 0; @@ -653,17 +651,17 @@ compile_object_load (const compile_file_names &file_names, setup_sections_data.last_max_alignment = 1; setup_sections_data.munmap_list_headp = &munmap_list_head; make_cleanup (munmap_listp_free_cleanup, &munmap_list_head); - bfd_map_over_sections (abfd, setup_sections, &setup_sections_data); - setup_sections (abfd, NULL, &setup_sections_data); + bfd_map_over_sections (abfd.get (), setup_sections, &setup_sections_data); + setup_sections (abfd.get (), NULL, &setup_sections_data); - storage_needed = bfd_get_symtab_upper_bound (abfd); + storage_needed = bfd_get_symtab_upper_bound (abfd.get ()); if (storage_needed < 0) error (_("Cannot read symbols of compiled module \"%s\": %s"), filename, bfd_errmsg (bfd_get_error ())); /* SYMFILE_VERBOSE is not passed even if FROM_TTY, user is not interested in "Reading symbols from ..." message for automatically generated file. */ - objfile = symbol_file_add_from_bfd (abfd, filename, 0, NULL, 0, NULL); + objfile = symbol_file_add_from_bfd (abfd.get (), filename, 0, NULL, 0, NULL); cleanups_free_objfile = make_cleanup_free_objfile (objfile); func_sym = lookup_global_symbol_from_objfile (objfile, @@ -712,7 +710,7 @@ compile_object_load (const compile_file_names &file_names, called from default_symfile_relocate. */ symbol_table = (asymbol **) obstack_alloc (&objfile->objfile_obstack, storage_needed); - number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table); + number_of_symbols = bfd_canonicalize_symtab (abfd.get (), symbol_table); if (number_of_symbols < 0) error (_("Cannot parse symbols of compiled module \"%s\": %s"), filename, bfd_errmsg (bfd_get_error ())); @@ -771,7 +769,7 @@ compile_object_load (const compile_file_names &file_names, if (missing_symbols) error (_("%ld symbols were missing, cannot continue."), missing_symbols); - bfd_map_over_sections (abfd, copy_sections, symbol_table); + bfd_map_over_sections (abfd.get (), copy_sections, symbol_table); regs_type = get_regs_type (func_sym, objfile); if (regs_type == NULL) diff --git a/gdb/corelow.c b/gdb/corelow.c index 376b7c9..04d2b87 100644 --- a/gdb/corelow.c +++ b/gdb/corelow.c @@ -275,7 +275,6 @@ core_open (const char *arg, int from_tty) int siggy; struct cleanup *old_chain; char *temp; - bfd *temp_bfd; int scratch_chan; int flags; char *filename; @@ -310,20 +309,19 @@ core_open (const char *arg, int from_tty) if (scratch_chan < 0) perror_with_name (filename); - temp_bfd = gdb_bfd_fopen (filename, gnutarget, - write_files ? FOPEN_RUB : FOPEN_RB, - scratch_chan); + gdb_bfd_ref_ptr temp_bfd (gdb_bfd_fopen (filename, gnutarget, + write_files ? FOPEN_RUB : FOPEN_RB, + scratch_chan)); if (temp_bfd == NULL) perror_with_name (filename); - if (!bfd_check_format (temp_bfd, bfd_core) - && !gdb_check_format (temp_bfd)) + if (!bfd_check_format (temp_bfd.get (), bfd_core) + && !gdb_check_format (temp_bfd.get ())) { /* Do it after the err msg */ /* FIXME: should be checking for errors from bfd_close (for one thing, on error it does not free all the storage associated with the bfd). */ - make_cleanup_bfd_unref (temp_bfd); error (_("\"%s\" is not a core dump: %s"), filename, bfd_errmsg (bfd_get_error ())); } @@ -333,7 +331,7 @@ core_open (const char *arg, int from_tty) do_cleanups (old_chain); unpush_target (&core_ops); - core_bfd = temp_bfd; + core_bfd = temp_bfd.release (); old_chain = make_cleanup (core_close_cleanup, 0 /*ignore*/); core_gdbarch = gdbarch_from_bfd (core_bfd); diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 9676d59..8748f7c 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -2479,7 +2479,6 @@ locate_dwz_sections (bfd *abfd, asection *sectp, void *arg) static struct dwz_file * dwarf2_get_dwz_file (void) { - bfd *dwz_bfd; char *data; struct cleanup *cleanup; const char *filename; @@ -2523,14 +2522,11 @@ dwarf2_get_dwz_file (void) /* First try the file name given in the section. If that doesn't work, try to use the build-id instead. */ - dwz_bfd = gdb_bfd_open (filename, gnutarget, -1); + gdb_bfd_ref_ptr dwz_bfd (gdb_bfd_open (filename, gnutarget, -1)); if (dwz_bfd != NULL) { - if (!build_id_verify (dwz_bfd, buildid_len, buildid)) - { - gdb_bfd_unref (dwz_bfd); - dwz_bfd = NULL; - } + if (!build_id_verify (dwz_bfd.get (), buildid_len, buildid)) + dwz_bfd.release (); } if (dwz_bfd == NULL) @@ -2542,13 +2538,13 @@ dwarf2_get_dwz_file (void) result = OBSTACK_ZALLOC (&dwarf2_per_objfile->objfile->objfile_obstack, struct dwz_file); - result->dwz_bfd = dwz_bfd; + result->dwz_bfd = dwz_bfd.release (); - bfd_map_over_sections (dwz_bfd, locate_dwz_sections, result); + bfd_map_over_sections (result->dwz_bfd, locate_dwz_sections, result); do_cleanups (cleanup); - gdb_bfd_record_inclusion (dwarf2_per_objfile->objfile->obfd, dwz_bfd); + gdb_bfd_record_inclusion (dwarf2_per_objfile->objfile->obfd, result->dwz_bfd); dwarf2_per_objfile->dwz_file = result; return result; } @@ -10454,10 +10450,9 @@ lookup_dwo_unit_in_dwp (struct dwp_file *dwp_file, const char *comp_dir, If unable to find/open the file, return NULL. NOTE: This function is derived from symfile_bfd_open. */ -static bfd * +static gdb_bfd_ref_ptr try_open_dwop_file (const char *file_name, int is_dwp, int search_cwd) { - bfd *sym_bfd; int desc, flags; char *absolute_name; /* Blech. OPF_TRY_CWD_FIRST also disables searching the path list if @@ -10486,23 +10481,20 @@ try_open_dwop_file (const char *file_name, int is_dwp, int search_cwd) if (desc < 0) return NULL; - sym_bfd = gdb_bfd_open (absolute_name, gnutarget, desc); + gdb_bfd_ref_ptr sym_bfd (gdb_bfd_open (absolute_name, gnutarget, desc)); xfree (absolute_name); if (sym_bfd == NULL) return NULL; - bfd_set_cacheable (sym_bfd, 1); + bfd_set_cacheable (sym_bfd.get (), 1); - if (!bfd_check_format (sym_bfd, bfd_object)) - { - gdb_bfd_unref (sym_bfd); /* This also closes desc. */ - return NULL; - } + if (!bfd_check_format (sym_bfd.get (), bfd_object)) + return NULL; /* Success. Record the bfd as having been included by the objfile's bfd. This is important because things like demangled_names_hash lives in the objfile's per_bfd space and may have references to things like symbol names that live in the DWO/DWP file's per_bfd space. PR 16426. */ - gdb_bfd_record_inclusion (dwarf2_per_objfile->objfile->obfd, sym_bfd); + gdb_bfd_record_inclusion (dwarf2_per_objfile->objfile->obfd, sym_bfd.get ()); return sym_bfd; } @@ -10514,11 +10506,9 @@ try_open_dwop_file (const char *file_name, int is_dwp, int search_cwd) Upon success, the canonicalized path of the file is stored in the bfd, same as symfile_bfd_open. */ -static bfd * +static gdb_bfd_ref_ptr open_dwo_file (const char *file_name, const char *comp_dir) { - bfd *abfd; - if (IS_ABSOLUTE_PATH (file_name)) return try_open_dwop_file (file_name, 0 /*is_dwp*/, 0 /*search_cwd*/); @@ -10531,7 +10521,8 @@ open_dwo_file (const char *file_name, const char *comp_dir) /* NOTE: If comp_dir is a relative path, this will also try the search path, which seems useful. */ - abfd = try_open_dwop_file (path_to_try, 0 /*is_dwp*/, 1 /*search_cwd*/); + gdb_bfd_ref_ptr abfd (try_open_dwop_file (path_to_try, 0 /*is_dwp*/, + 1 /*search_cwd*/)); xfree (path_to_try); if (abfd != NULL) return abfd; @@ -10617,10 +10608,9 @@ open_and_init_dwo_file (struct dwarf2_per_cu_data *per_cu, { struct objfile *objfile = dwarf2_per_objfile->objfile; struct dwo_file *dwo_file; - bfd *dbfd; struct cleanup *cleanups; - dbfd = open_dwo_file (dwo_name, comp_dir); + gdb_bfd_ref_ptr dbfd (open_dwo_file (dwo_name, comp_dir)); if (dbfd == NULL) { if (dwarf_read_debug) @@ -10630,11 +10620,12 @@ open_and_init_dwo_file (struct dwarf2_per_cu_data *per_cu, dwo_file = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_file); dwo_file->dwo_name = dwo_name; dwo_file->comp_dir = comp_dir; - dwo_file->dbfd = dbfd; + dwo_file->dbfd = dbfd.release (); cleanups = make_cleanup (free_dwo_file_cleanup, dwo_file); - bfd_map_over_sections (dbfd, dwarf2_locate_dwo_sections, &dwo_file->sections); + bfd_map_over_sections (dwo_file->dbfd, dwarf2_locate_dwo_sections, + &dwo_file->sections); dwo_file->cu = create_dwo_cu (dwo_file); @@ -10786,12 +10777,11 @@ allocate_dwp_loaded_cutus_table (struct objfile *objfile) Upon success, the canonicalized path of the file is stored in the bfd, same as symfile_bfd_open. */ -static bfd * +static gdb_bfd_ref_ptr open_dwp_file (const char *file_name) { - bfd *abfd; - - abfd = try_open_dwop_file (file_name, 1 /*is_dwp*/, 1 /*search_cwd*/); + gdb_bfd_ref_ptr abfd (try_open_dwop_file (file_name, 1 /*is_dwp*/, + 1 /*search_cwd*/)); if (abfd != NULL) return abfd; @@ -10825,7 +10815,6 @@ open_and_init_dwp_file (void) struct objfile *objfile = dwarf2_per_objfile->objfile; struct dwp_file *dwp_file; char *dwp_name; - bfd *dbfd; struct cleanup *cleanups = make_cleanup (null_cleanup, 0); /* Try to find first .dwp for the binary file before any symbolic links @@ -10847,7 +10836,7 @@ open_and_init_dwp_file (void) dwp_name = xstrprintf ("%s.dwp", objfile->original_name); make_cleanup (xfree, dwp_name); - dbfd = open_dwp_file (dwp_name); + gdb_bfd_ref_ptr dbfd (open_dwp_file (dwp_name)); if (dbfd == NULL && strcmp (objfile->original_name, objfile_name (objfile)) != 0) { @@ -10865,17 +10854,18 @@ open_and_init_dwp_file (void) return NULL; } dwp_file = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwp_file); - dwp_file->name = bfd_get_filename (dbfd); - dwp_file->dbfd = dbfd; + dwp_file->name = bfd_get_filename (dbfd.get ()); + dwp_file->dbfd = dbfd.release (); do_cleanups (cleanups); /* +1: section 0 is unused */ - dwp_file->num_sections = bfd_count_sections (dbfd) + 1; + dwp_file->num_sections = bfd_count_sections (dwp_file->dbfd) + 1; dwp_file->elf_sections = OBSTACK_CALLOC (&objfile->objfile_obstack, dwp_file->num_sections, asection *); - bfd_map_over_sections (dbfd, dwarf2_locate_common_dwp_sections, dwp_file); + bfd_map_over_sections (dwp_file->dbfd, dwarf2_locate_common_dwp_sections, + dwp_file); dwp_file->cus = create_dwp_hash_table (dwp_file, 0); @@ -10895,7 +10885,8 @@ open_and_init_dwp_file (void) dwp_file->version = dwp_file->cus->version; if (dwp_file->version == 2) - bfd_map_over_sections (dbfd, dwarf2_locate_v2_dwp_sections, dwp_file); + bfd_map_over_sections (dwp_file->dbfd, dwarf2_locate_v2_dwp_sections, + dwp_file); dwp_file->loaded_cus = allocate_dwp_loaded_cutus_table (objfile); dwp_file->loaded_tus = allocate_dwp_loaded_cutus_table (objfile); diff --git a/gdb/elfread.c b/gdb/elfread.c index c6d0fdb..7e2358b 100644 --- a/gdb/elfread.c +++ b/gdb/elfread.c @@ -1265,21 +1265,18 @@ elf_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags) && objfile->separate_debug_objfile == NULL && objfile->separate_debug_objfile_backlink == NULL) { - char *debugfile; - - debugfile = find_separate_debug_file_by_buildid (objfile); + gdb::unique_xmalloc_ptr<char> debugfile + (find_separate_debug_file_by_buildid (objfile)); if (debugfile == NULL) - debugfile = find_separate_debug_file_by_debuglink (objfile); + debugfile.reset (find_separate_debug_file_by_debuglink (objfile)); - if (debugfile) + if (debugfile != NULL) { - struct cleanup *cleanup = make_cleanup (xfree, debugfile); - bfd *abfd = symfile_bfd_open (debugfile); + gdb_bfd_ref_ptr abfd (symfile_bfd_open (debugfile.get ())); - make_cleanup_bfd_unref (abfd); - symbol_file_add_separate (abfd, debugfile, symfile_flags, objfile); - do_cleanups (cleanup); + symbol_file_add_separate (abfd.get (), debugfile.get (), + symfile_flags, objfile); } } } diff --git a/gdb/exec.c b/gdb/exec.c index eeca005..875a675 100644 --- a/gdb/exec.c +++ b/gdb/exec.c @@ -258,7 +258,9 @@ exec_file_attach (const char *filename, int from_tty) this at the end of the function; but acquiring it now lets the BFD cache return it if this call refers to the same file. */ gdb_bfd_ref (exec_bfd); - cleanups = make_cleanup_bfd_unref (exec_bfd); + gdb_bfd_ref_ptr exec_bfd_holder (exec_bfd); + + cleanups = make_cleanup (null_cleanup, NULL); /* Remove any previous exec file. */ exec_close (); @@ -333,11 +335,13 @@ exec_file_attach (const char *filename, int from_tty) make_cleanup (xfree, canonical_pathname); } + gdb_bfd_ref_ptr temp; if (write_files && !load_via_target) - exec_bfd = gdb_bfd_fopen (canonical_pathname, gnutarget, - FOPEN_RUB, scratch_chan); + temp = gdb_bfd_fopen (canonical_pathname, gnutarget, + FOPEN_RUB, scratch_chan); else - exec_bfd = gdb_bfd_open (canonical_pathname, gnutarget, scratch_chan); + temp = gdb_bfd_open (canonical_pathname, gnutarget, scratch_chan); + exec_bfd = temp.release (); if (!exec_bfd) { diff --git a/gdb/gcore.c b/gdb/gcore.c index cb4d703..0b05cf9 100644 --- a/gdb/gcore.c +++ b/gdb/gcore.c @@ -49,15 +49,15 @@ static int gcore_memory_sections (bfd *); /* create_gcore_bfd -- helper for gcore_command (exported). Open a new bfd core file for output, and return the handle. */ -bfd * +gdb_bfd_ref_ptr create_gcore_bfd (const char *filename) { - bfd *obfd = gdb_bfd_openw (filename, default_gcore_target ()); + gdb_bfd_ref_ptr obfd (gdb_bfd_openw (filename, default_gcore_target ())); - if (!obfd) + if (obfd == NULL) error (_("Failed to open '%s' for output."), filename); - bfd_set_format (obfd, bfd_core); - bfd_set_arch_mach (obfd, default_gcore_arch (), default_gcore_mach ()); + bfd_set_format (obfd.get (), bfd_core); + bfd_set_arch_mach (obfd.get (), default_gcore_arch (), default_gcore_mach ()); return obfd; } @@ -174,7 +174,7 @@ gcore_command (char *args, int from_tty) "Opening corefile '%s' for output.\n", corefilename); /* Open the output file. */ - obfd = create_gcore_bfd (corefilename); + obfd = create_gcore_bfd (corefilename).release (); /* Need a cleanup that will close and delete the file. */ bfd_chain = make_cleanup (do_bfd_delete_cleanup, obfd); diff --git a/gdb/gcore.h b/gdb/gcore.h index 91107e0..f4f0545 100644 --- a/gdb/gcore.h +++ b/gdb/gcore.h @@ -20,7 +20,9 @@ #if !defined (GCORE_H) #define GCORE_H 1 -extern bfd *create_gcore_bfd (const char *filename); +#include "gdb_bfd.h" + +extern gdb_bfd_ref_ptr create_gcore_bfd (const char *filename); extern void write_gcore_file (bfd *obfd); extern bfd *load_corefile (char *filename, int from_tty); extern int objfile_find_memory_regions (struct target_ops *self, diff --git a/gdb/gdb_bfd.c b/gdb/gdb_bfd.c index df00f87..c7f02b9 100644 --- a/gdb/gdb_bfd.c +++ b/gdb/gdb_bfd.c @@ -356,7 +356,7 @@ gdb_bfd_iovec_fileio_fstat (struct bfd *abfd, void *stream, /* See gdb_bfd.h. */ -struct bfd * +gdb_bfd_ref_ptr gdb_bfd_open (const char *name, const char *target, int fd) { hashval_t hash; @@ -428,7 +428,7 @@ gdb_bfd_open (const char *name, const char *target, int fd) bfd_get_filename (abfd)); close (fd); gdb_bfd_ref (abfd); - return abfd; + return gdb_bfd_ref_ptr (abfd); } abfd = bfd_fopen (name, target, FOPEN_RB, fd); @@ -449,7 +449,7 @@ gdb_bfd_open (const char *name, const char *target, int fd) } gdb_bfd_ref (abfd); - return abfd; + return gdb_bfd_ref_ptr (abfd); } /* A helper function that releases any section data attached to the @@ -772,7 +772,7 @@ gdb_bfd_crc (struct bfd *abfd, unsigned long *crc_out) /* See gdb_bfd.h. */ -bfd * +gdb_bfd_ref_ptr gdb_bfd_fopen (const char *filename, const char *target, const char *mode, int fd) { @@ -781,12 +781,12 @@ gdb_bfd_fopen (const char *filename, const char *target, const char *mode, if (result) gdb_bfd_ref (result); - return result; + return gdb_bfd_ref_ptr (result); } /* See gdb_bfd.h. */ -bfd * +gdb_bfd_ref_ptr gdb_bfd_openr (const char *filename, const char *target) { bfd *result = bfd_openr (filename, target); @@ -794,12 +794,12 @@ gdb_bfd_openr (const char *filename, const char *target) if (result) gdb_bfd_ref (result); - return result; + return gdb_bfd_ref_ptr (result); } /* See gdb_bfd.h. */ -bfd * +gdb_bfd_ref_ptr gdb_bfd_openw (const char *filename, const char *target) { bfd *result = bfd_openw (filename, target); @@ -807,12 +807,12 @@ gdb_bfd_openw (const char *filename, const char *target) if (result) gdb_bfd_ref (result); - return result; + return gdb_bfd_ref_ptr (result); } /* See gdb_bfd.h. */ -bfd * +gdb_bfd_ref_ptr gdb_bfd_openr_iovec (const char *filename, const char *target, void *(*open_func) (struct bfd *nbfd, void *open_closure), @@ -835,7 +835,7 @@ gdb_bfd_openr_iovec (const char *filename, const char *target, if (result) gdb_bfd_ref (result); - return result; + return gdb_bfd_ref_ptr (result); } /* See gdb_bfd.h. */ @@ -861,7 +861,7 @@ gdb_bfd_mark_parent (bfd *child, bfd *parent) /* See gdb_bfd.h. */ -bfd * +gdb_bfd_ref_ptr gdb_bfd_openr_next_archived_file (bfd *archive, bfd *previous) { bfd *result = bfd_openr_next_archived_file (archive, previous); @@ -869,7 +869,7 @@ gdb_bfd_openr_next_archived_file (bfd *archive, bfd *previous) if (result) gdb_bfd_mark_parent (result, archive); - return result; + return gdb_bfd_ref_ptr (result); } /* See gdb_bfd.h. */ @@ -886,7 +886,7 @@ gdb_bfd_record_inclusion (bfd *includer, bfd *includee) /* See gdb_bfd.h. */ -bfd * +gdb_bfd_ref_ptr gdb_bfd_fdopenr (const char *filename, const char *target, int fd) { bfd *result = bfd_fdopenr (filename, target, fd); @@ -894,7 +894,7 @@ gdb_bfd_fdopenr (const char *filename, const char *target, int fd) if (result) gdb_bfd_ref (result); - return result; + return gdb_bfd_ref_ptr (result); } \f diff --git a/gdb/gdb_bfd.h b/gdb/gdb_bfd.h index a5b5ee9..8c4a60a 100644 --- a/gdb/gdb_bfd.h +++ b/gdb/gdb_bfd.h @@ -21,6 +21,7 @@ #define GDB_BFD_H #include "registry.h" +#include "common/gdb_ref_ptr.h" DECLARE_REGISTRY (bfd); @@ -39,6 +40,34 @@ int is_target_filename (const char *name); int gdb_bfd_has_target_filename (struct bfd *abfd); +/* Increment the reference count of ABFD. It is fine for ABFD to be + NULL; in this case the function does nothing. */ + +void gdb_bfd_ref (struct bfd *abfd); + +/* Decrement the reference count of ABFD. If this is the last + reference, ABFD will be freed. If ABFD is NULL, this function does + nothing. */ + +void gdb_bfd_unref (struct bfd *abfd); + +/* A policy class for gdb::ref_ptr for BFD reference counting. */ +struct gdb_bfd_ref_policy +{ + static void incref (struct bfd *abfd) + { + gdb_bfd_ref (abfd); + } + + static void decref (struct bfd *abfd) + { + gdb_bfd_unref (abfd); + } +}; + +/* A gdb::ref_ptr that has been specialized for BFD objects. */ +typedef gdb::ref_ptr<struct bfd, gdb_bfd_ref_policy> gdb_bfd_ref_ptr; + /* Open a read-only (FOPEN_RB) BFD given arguments like bfd_fopen. If NAME starts with TARGET_SYSROOT_PREFIX then the BFD will be opened using target fileio operations if necessary. Returns NULL @@ -51,18 +80,7 @@ int gdb_bfd_has_target_filename (struct bfd *abfd); not be exactly NAME but rather NAME with TARGET_SYSROOT_PREFIX stripped. */ -struct bfd *gdb_bfd_open (const char *name, const char *target, int fd); - -/* Increment the reference count of ABFD. It is fine for ABFD to be - NULL; in this case the function does nothing. */ - -void gdb_bfd_ref (struct bfd *abfd); - -/* Decrement the reference count of ABFD. If this is the last - reference, ABFD will be freed. If ABFD is NULL, this function does - nothing. */ - -void gdb_bfd_unref (struct bfd *abfd); +gdb_bfd_ref_ptr gdb_bfd_open (const char *name, const char *target, int fd); /* Mark the CHILD BFD as being a member of PARENT. Also, increment the reference count of CHILD. Calling this function ensures that @@ -110,45 +128,46 @@ int gdb_bfd_crc (struct bfd *abfd, unsigned long *crc_out); /* A wrapper for bfd_fopen that initializes the gdb-specific reference count. */ -bfd *gdb_bfd_fopen (const char *, const char *, const char *, int); +gdb_bfd_ref_ptr gdb_bfd_fopen (const char *, const char *, const char *, int); /* A wrapper for bfd_openr that initializes the gdb-specific reference count. */ -bfd *gdb_bfd_openr (const char *, const char *); +gdb_bfd_ref_ptr gdb_bfd_openr (const char *, const char *); /* A wrapper for bfd_openw that initializes the gdb-specific reference count. */ -bfd *gdb_bfd_openw (const char *, const char *); +gdb_bfd_ref_ptr gdb_bfd_openw (const char *, const char *); /* A wrapper for bfd_openr_iovec that initializes the gdb-specific reference count. */ -bfd *gdb_bfd_openr_iovec (const char *filename, const char *target, - void *(*open_func) (struct bfd *nbfd, - void *open_closure), - void *open_closure, - file_ptr (*pread_func) (struct bfd *nbfd, - void *stream, - void *buf, - file_ptr nbytes, - file_ptr offset), - int (*close_func) (struct bfd *nbfd, - void *stream), - int (*stat_func) (struct bfd *abfd, - void *stream, - struct stat *sb)); +gdb_bfd_ref_ptr gdb_bfd_openr_iovec (const char *filename, const char *target, + void *(*open_func) (struct bfd *nbfd, + void *open_closure), + void *open_closure, + file_ptr (*pread_func) (struct bfd *nbfd, + void *stream, + void *buf, + file_ptr nbytes, + file_ptr offset), + int (*close_func) (struct bfd *nbfd, + void *stream), + int (*stat_func) (struct bfd *abfd, + void *stream, + struct stat *sb)); /* A wrapper for bfd_openr_next_archived_file that initializes the gdb-specific reference count. */ -bfd *gdb_bfd_openr_next_archived_file (bfd *archive, bfd *previous); +gdb_bfd_ref_ptr gdb_bfd_openr_next_archived_file (bfd *archive, bfd *previous); /* A wrapper for bfd_fdopenr that initializes the gdb-specific reference count. */ -bfd *gdb_bfd_fdopenr (const char *filename, const char *target, int fd); +gdb_bfd_ref_ptr gdb_bfd_fdopenr (const char *filename, const char *target, + int fd); \f diff --git a/gdb/jit.c b/gdb/jit.c index 03b6bd8..2101115 100644 --- a/gdb/jit.c +++ b/gdb/jit.c @@ -136,7 +136,7 @@ mem_bfd_iovec_stat (struct bfd *abfd, void *stream, struct stat *sb) /* Open a BFD from the target's memory. */ -static struct bfd * +static gdb_bfd_ref_ptr bfd_open_from_target_memory (CORE_ADDR addr, ULONGEST size, char *target) { struct target_buffer *buffer = XNEW (struct target_buffer); @@ -892,7 +892,6 @@ jit_bfd_try_read_symtab (struct jit_code_entry *code_entry, CORE_ADDR entry_addr, struct gdbarch *gdbarch) { - bfd *nbfd; struct section_addr_info *sai; struct bfd_section *sec; struct objfile *objfile; @@ -907,8 +906,9 @@ jit_bfd_try_read_symtab (struct jit_code_entry *code_entry, paddress (gdbarch, code_entry->symfile_addr), pulongest (code_entry->symfile_size)); - nbfd = bfd_open_from_target_memory (code_entry->symfile_addr, - code_entry->symfile_size, gnutarget); + gdb_bfd_ref_ptr nbfd (bfd_open_from_target_memory (code_entry->symfile_addr, + code_entry->symfile_size, + gnutarget)); if (nbfd == NULL) { puts_unfiltered (_("Error opening JITed symbol file, ignoring it.\n")); @@ -917,42 +917,42 @@ jit_bfd_try_read_symtab (struct jit_code_entry *code_entry, /* Check the format. NOTE: This initializes important data that GDB uses! We would segfault later without this line. */ - if (!bfd_check_format (nbfd, bfd_object)) + if (!bfd_check_format (nbfd.get (), bfd_object)) { printf_unfiltered (_("\ JITed symbol file is not an object file, ignoring it.\n")); - gdb_bfd_unref (nbfd); return; } /* Check bfd arch. */ b = gdbarch_bfd_arch_info (gdbarch); - if (b->compatible (b, bfd_get_arch_info (nbfd)) != b) + if (b->compatible (b, bfd_get_arch_info (nbfd.get ())) != b) warning (_("JITed object file architecture %s is not compatible " - "with target architecture %s."), bfd_get_arch_info - (nbfd)->printable_name, b->printable_name); + "with target architecture %s."), + bfd_get_arch_info (nbfd.get ())->printable_name, + b->printable_name); /* Read the section address information out of the symbol file. Since the file is generated by the JIT at runtime, it should all of the absolute addresses that we care about. */ - sai = alloc_section_addr_info (bfd_count_sections (nbfd)); + sai = alloc_section_addr_info (bfd_count_sections (nbfd.get ())); old_cleanups = make_cleanup_free_section_addr_info (sai); i = 0; for (sec = nbfd->sections; sec != NULL; sec = sec->next) - if ((bfd_get_section_flags (nbfd, sec) & (SEC_ALLOC|SEC_LOAD)) != 0) + if ((bfd_get_section_flags (nbfd.get (), sec) & (SEC_ALLOC|SEC_LOAD)) != 0) { /* We assume that these virtual addresses are absolute, and do not treat them as offsets. */ - sai->other[i].addr = bfd_get_section_vma (nbfd, sec); - sai->other[i].name = xstrdup (bfd_get_section_name (nbfd, sec)); + sai->other[i].addr = bfd_get_section_vma (nbfd.get (), sec); + sai->other[i].name = xstrdup (bfd_get_section_name (nbfd.get (), sec)); sai->other[i].sectindex = sec->index; ++i; } sai->num_sections = i; /* This call does not take ownership of SAI. */ - make_cleanup_bfd_unref (nbfd); - objfile = symbol_file_add_from_bfd (nbfd, bfd_get_filename (nbfd), 0, sai, + objfile = symbol_file_add_from_bfd (nbfd.get (), + bfd_get_filename (nbfd.get ()), 0, sai, OBJF_SHARED | OBJF_NOT_FILENAME, NULL); do_cleanups (old_cleanups); diff --git a/gdb/machoread.c b/gdb/machoread.c index 00f25a4..dd99eb7 100644 --- a/gdb/machoread.c +++ b/gdb/machoread.c @@ -429,7 +429,8 @@ macho_resolve_oso_sym_with_minsym (struct objfile *main_objfile, asymbol *sym) /* Add oso file OSO/ABFD as a symbol file. */ static void -macho_add_oso_symfile (oso_el *oso, bfd *abfd, const char *name, +macho_add_oso_symfile (oso_el *oso, const gdb_bfd_ref_ptr &abfd, + const char *name, struct objfile *main_objfile, symfile_add_flags symfile_flags) { @@ -439,7 +440,6 @@ macho_add_oso_symfile (oso_el *oso, bfd *abfd, const char *name, asymbol **symp; struct bfd_hash_table table; int nbr_sections; - struct cleanup *cleanup; /* Per section flag to mark which section have been rebased. */ unsigned char *sections_rebased; @@ -448,18 +448,16 @@ macho_add_oso_symfile (oso_el *oso, bfd *abfd, const char *name, printf_unfiltered (_("Loading debugging symbols from oso: %s\n"), oso->name); - if (!bfd_check_format (abfd, bfd_object)) + if (!bfd_check_format (abfd.get (), bfd_object)) { warning (_("`%s': can't read symbols: %s."), oso->name, bfd_errmsg (bfd_get_error ())); - gdb_bfd_unref (abfd); return; } - if (abfd->my_archive == NULL && oso->mtime != bfd_get_mtime (abfd)) + if (abfd->my_archive == NULL && oso->mtime != bfd_get_mtime (abfd.get ())) { warning (_("`%s': file time stamp mismatch."), oso->name); - gdb_bfd_unref (abfd); return; } @@ -468,19 +466,18 @@ macho_add_oso_symfile (oso_el *oso, bfd *abfd, const char *name, oso->nbr_syms)) { warning (_("`%s': can't create hash table"), oso->name); - gdb_bfd_unref (abfd); return; } - bfd_set_cacheable (abfd, 1); + bfd_set_cacheable (abfd.get (), 1); /* Read symbols table. */ - storage = bfd_get_symtab_upper_bound (abfd); + storage = bfd_get_symtab_upper_bound (abfd.get ()); symbol_table = (asymbol **) xmalloc (storage); - bfd_canonicalize_symtab (abfd, symbol_table); + bfd_canonicalize_symtab (abfd.get (), symbol_table); /* Init section flags. */ - nbr_sections = bfd_count_sections (abfd); + nbr_sections = bfd_count_sections (abfd.get ()); sections_rebased = (unsigned char *) alloca (nbr_sections); for (i = 0; i < nbr_sections; i++) sections_rebased[i] = 0; @@ -601,7 +598,7 @@ macho_add_oso_symfile (oso_el *oso, bfd *abfd, const char *name, sec->name, sym->name, paddress (arch, res)); } - bfd_set_section_vma (abfd, sec, res); + bfd_set_section_vma (abfd.get (), sec, res); sections_rebased[sec->index] = 1; } } @@ -617,13 +614,12 @@ macho_add_oso_symfile (oso_el *oso, bfd *abfd, const char *name, /* We need to clear SYMFILE_MAINLINE to avoid interractive question from symfile.c:symbol_file_add_with_addrs_or_offsets. */ - cleanup = make_cleanup_bfd_unref (abfd); symbol_file_add_from_bfd - (abfd, name, symfile_flags & ~(SYMFILE_MAINLINE | SYMFILE_VERBOSE), NULL, + (abfd.get (), name, symfile_flags & ~(SYMFILE_MAINLINE | SYMFILE_VERBOSE), + NULL, main_objfile->flags & (OBJF_REORDERED | OBJF_SHARED | OBJF_READNOW | OBJF_USERLOADED), main_objfile); - do_cleanups (cleanup); } /* Read symbols from the vector of oso files. @@ -651,8 +647,6 @@ macho_symfile_read_all_oso (VEC (oso_el) **oso_vector_ptr, pfx_len = get_archive_prefix_len (oso->name); if (pfx_len > 0) { - bfd *archive_bfd; - bfd *member_bfd; int last_ix; oso_el *oso2; int ix2; @@ -668,7 +662,8 @@ macho_symfile_read_all_oso (VEC (oso_el) **oso_vector_ptr, } /* Open the archive and check the format. */ - archive_bfd = gdb_bfd_open (archive_name.c_str (), gnutarget, -1); + gdb_bfd_ref_ptr archive_bfd (gdb_bfd_open (archive_name.c_str (), + gnutarget, -1)); if (archive_bfd == NULL) { warning (_("Could not open OSO archive file \"%s\""), @@ -676,22 +671,21 @@ macho_symfile_read_all_oso (VEC (oso_el) **oso_vector_ptr, ix = last_ix; continue; } - if (!bfd_check_format (archive_bfd, bfd_archive)) + if (!bfd_check_format (archive_bfd.get (), bfd_archive)) { warning (_("OSO archive file \"%s\" not an archive."), archive_name.c_str ()); - gdb_bfd_unref (archive_bfd); ix = last_ix; continue; } - member_bfd = gdb_bfd_openr_next_archived_file (archive_bfd, NULL); + gdb_bfd_ref_ptr member_bfd + (gdb_bfd_openr_next_archived_file (archive_bfd.get (), NULL)); if (member_bfd == NULL) { warning (_("Could not read archive members out of " "OSO archive \"%s\""), archive_name.c_str ()); - gdb_bfd_unref (archive_bfd); ix = last_ix; continue; } @@ -699,7 +693,6 @@ macho_symfile_read_all_oso (VEC (oso_el) **oso_vector_ptr, /* Load all oso in this library. */ while (member_bfd != NULL) { - bfd *prev; const char *member_name = member_bfd->filename; int member_len = strlen (member_name); @@ -721,13 +714,8 @@ macho_symfile_read_all_oso (VEC (oso_el) **oso_vector_ptr, } } - prev = member_bfd; - member_bfd = gdb_bfd_openr_next_archived_file (archive_bfd, - member_bfd); - - /* Free previous member if not referenced by an oso. */ - if (ix2 >= last_ix) - gdb_bfd_unref (prev); + member_bfd = gdb_bfd_openr_next_archived_file (archive_bfd.get (), + member_bfd.get ()); } for (ix2 = ix; ix2 < last_ix; ix2++) { @@ -741,10 +729,8 @@ macho_symfile_read_all_oso (VEC (oso_el) **oso_vector_ptr, } else { - bfd *abfd; - - abfd = gdb_bfd_open (oso->name, gnutarget, -1); - if (!abfd) + gdb_bfd_ref_ptr abfd (gdb_bfd_open (oso->name, gnutarget, -1)); + if (abfd == NULL) warning (_("`%s': can't open to read symbols: %s."), oso->name, bfd_errmsg (bfd_get_error ())); else @@ -768,7 +754,7 @@ macho_symfile_read_all_oso (VEC (oso_el) **oso_vector_ptr, Return NULL if no valid dsym file is found (FILENAMEP is not used in such case). */ -static bfd * +static gdb_bfd_ref_ptr macho_check_dsym (struct objfile *objfile, char **filenamep) { size_t name_len = strlen (objfile_name (objfile)); @@ -776,7 +762,6 @@ macho_check_dsym (struct objfile *objfile, char **filenamep) const char *base_name = lbasename (objfile_name (objfile)); size_t base_len = strlen (base_name); char *dsym_filename = (char *) alloca (name_len + dsym_len + base_len + 1); - bfd *dsym_bfd; bfd_mach_o_load_command *main_uuid; bfd_mach_o_load_command *dsym_uuid; @@ -793,25 +778,23 @@ macho_check_dsym (struct objfile *objfile, char **filenamep) warning (_("can't find UUID in %s"), objfile_name (objfile)); return NULL; } - dsym_bfd = gdb_bfd_openr (dsym_filename, gnutarget); + gdb_bfd_ref_ptr dsym_bfd (gdb_bfd_openr (dsym_filename, gnutarget)); if (dsym_bfd == NULL) { warning (_("can't open dsym file %s"), dsym_filename); return NULL; } - if (!bfd_check_format (dsym_bfd, bfd_object)) + if (!bfd_check_format (dsym_bfd.get (), bfd_object)) { - gdb_bfd_unref (dsym_bfd); warning (_("bad dsym file format: %s"), bfd_errmsg (bfd_get_error ())); return NULL; } - if (bfd_mach_o_lookup_command (dsym_bfd, + if (bfd_mach_o_lookup_command (dsym_bfd.get (), BFD_MACH_O_LC_UUID, &dsym_uuid) == 0) { warning (_("can't find UUID in %s"), dsym_filename); - gdb_bfd_unref (dsym_bfd); return NULL; } if (memcmp (dsym_uuid->command.uuid.uuid, main_uuid->command.uuid.uuid, @@ -819,7 +802,6 @@ macho_check_dsym (struct objfile *objfile, char **filenamep) { warning (_("dsym file UUID doesn't match the one in %s"), objfile_name (objfile)); - gdb_bfd_unref (dsym_bfd); return NULL; } *filenamep = xstrdup (dsym_filename); @@ -831,7 +813,6 @@ macho_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags) { bfd *abfd = objfile->obfd; long storage_needed; - bfd *dsym_bfd; VEC (oso_el) *oso_vector = NULL; struct cleanup *old_chain = make_cleanup (VEC_cleanup (oso_el), &oso_vector); @@ -879,7 +860,7 @@ macho_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags) dwarf2_build_frame_info (objfile); /* Check for DSYM file. */ - dsym_bfd = macho_check_dsym (objfile, &dsym_filename); + gdb_bfd_ref_ptr dsym_bfd (macho_check_dsym (objfile, &dsym_filename)); if (dsym_bfd != NULL) { struct bfd_section *asect, *dsect; @@ -896,14 +877,13 @@ macho_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags) { if (strcmp (asect->name, dsect->name) != 0) break; - bfd_set_section_size (dsym_bfd, dsect, + bfd_set_section_size (dsym_bfd.get (), dsect, bfd_get_section_size (asect)); } /* Add the dsym file as a separate file. */ - make_cleanup_bfd_unref (dsym_bfd); - symbol_file_add_separate (dsym_bfd, dsym_filename, symfile_flags, - objfile); + symbol_file_add_separate (dsym_bfd.get (), dsym_filename, + symfile_flags, objfile); /* Don't try to read dwarf2 from main file or shared libraries. */ do_cleanups (old_chain); diff --git a/gdb/minidebug.c b/gdb/minidebug.c index 4323294..61a3971 100644 --- a/gdb/minidebug.c +++ b/gdb/minidebug.c @@ -256,11 +256,11 @@ lzma_stat (struct bfd *abfd, If we find one we create a iovec based bfd that decompresses the object data on demand. If we don't find one, return NULL. */ -bfd * +gdb_bfd_ref_ptr find_separate_debug_file_in_section (struct objfile *objfile) { asection *section; - bfd *abfd; + gdb_bfd_ref_ptr abfd; if (objfile->obfd == NULL) return NULL; @@ -275,16 +275,14 @@ find_separate_debug_file_in_section (struct objfile *objfile) if (abfd == NULL) return NULL; - if (!bfd_check_format (abfd, bfd_object)) + if (!bfd_check_format (abfd.get (), bfd_object)) { warning (_("Cannot parse .gnu_debugdata section; not a BFD object")); - gdb_bfd_unref (abfd); return NULL; } #else warning (_("Cannot parse .gnu_debugdata section; LZMA support was " "disabled at compile time")); - abfd = NULL; #endif /* !HAVE_LIBLZMA */ return abfd; diff --git a/gdb/procfs.c b/gdb/procfs.c index ff814ba..f8fd487 100644 --- a/gdb/procfs.c +++ b/gdb/procfs.c @@ -3413,26 +3413,24 @@ dbx_link_addr (bfd *abfd) static int insert_dbx_link_bpt_in_file (int fd, CORE_ADDR ignored) { - bfd *abfd; long storage_needed; CORE_ADDR sym_addr; - abfd = gdb_bfd_fdopenr ("unamed", 0, fd); + gdb_bfd_ref_ptr abfd (gdb_bfd_fdopenr ("unamed", 0, fd)); if (abfd == NULL) { warning (_("Failed to create a bfd: %s."), bfd_errmsg (bfd_get_error ())); return 0; } - if (!bfd_check_format (abfd, bfd_object)) + if (!bfd_check_format (abfd.get (), bfd_object)) { /* Not the correct format, so we can not possibly find the dbx_link symbol in it. */ - gdb_bfd_unref (abfd); return 0; } - sym_addr = dbx_link_addr (abfd); + sym_addr = dbx_link_addr (abfd.get ()); if (sym_addr != 0) { struct breakpoint *dbx_link_bpt; @@ -3444,14 +3442,11 @@ insert_dbx_link_bpt_in_file (int fd, CORE_ADDR ignored) if (dbx_link_bpt == NULL) { warning (_("Failed to insert dbx_link breakpoint.")); - gdb_bfd_unref (abfd); return 0; } - gdb_bfd_unref (abfd); return 1; } - gdb_bfd_unref (abfd); return 0; } diff --git a/gdb/python/py-objfile.c b/gdb/python/py-objfile.c index 497d0ba..42e26b7 100644 --- a/gdb/python/py-objfile.c +++ b/gdb/python/py-objfile.c @@ -445,9 +445,9 @@ objfpy_add_separate_debug_file (PyObject *self, PyObject *args, PyObject *kw) TRY { - bfd *abfd = symfile_bfd_open (file_name); + gdb_bfd_ref_ptr abfd (symfile_bfd_open (file_name)); - symbol_file_add_separate (abfd, file_name, 0, obj->objfile); + symbol_file_add_separate (abfd.get (), file_name, 0, obj->objfile); } CATCH (except, RETURN_MASK_ALL) { diff --git a/gdb/record-full.c b/gdb/record-full.c index 5608e70..707cb63 100644 --- a/gdb/record-full.c +++ b/gdb/record-full.c @@ -2571,7 +2571,7 @@ record_full_save (struct target_ops *self, const char *recfilename) recfilename); /* Open the output file. */ - obfd = create_gcore_bfd (recfilename); + obfd = create_gcore_bfd (recfilename).release (); old_cleanups = make_cleanup (record_full_save_cleanups, obfd); /* Save the current record entry to "cur_record_full_list". */ diff --git a/gdb/solib-aix.c b/gdb/solib-aix.c index 75634df..6612f20 100644 --- a/gdb/solib-aix.c +++ b/gdb/solib-aix.c @@ -624,7 +624,7 @@ solib_aix_in_dynsym_resolve_code (CORE_ADDR pc) /* Implement the "bfd_open" target_so_ops method. */ -static bfd * +static gdb_bfd_ref_ptr solib_aix_bfd_open (char *pathname) { /* The pathname is actually a synthetic filename with the following @@ -635,11 +635,7 @@ solib_aix_bfd_open (char *pathname) to the solib's lm_info here? */ const int path_len = strlen (pathname); char *sep; - char *filename; int filename_len; - char *member_name; - bfd *archive_bfd, *object_bfd; - struct cleanup *cleanup; int found_file; char *found_pathname; @@ -658,69 +654,57 @@ 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); + 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. */ - found_pathname = solib_find (filename, &found_file); + found_pathname = solib_find (&filename[0], &found_file); if (found_pathname == NULL) perror_with_name (pathname); - archive_bfd = solib_bfd_fopen (found_pathname, found_file); + gdb_bfd_ref_ptr archive_bfd (solib_bfd_fopen (found_pathname, 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; } @@ -728,12 +712,11 @@ solib_aix_bfd_open (char *pathname) 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)); + xfree (bfd_get_filename (object_bfd.get ())); object_bfd->filename = xstrprintf ("%s%s", - bfd_get_filename (archive_bfd), sep); + bfd_get_filename (archive_bfd.get ()), + sep); - gdb_bfd_unref (archive_bfd); - do_cleanups (cleanup); return object_bfd; } diff --git a/gdb/solib-darwin.c b/gdb/solib-darwin.c index 24cf848..51d42c7 100644 --- a/gdb/solib-darwin.c +++ b/gdb/solib-darwin.c @@ -427,7 +427,7 @@ darwin_in_dynsym_resolve_code (CORE_ADDR pc) counting properly. This will either return NULL, or return a new reference to a BFD. */ -static bfd * +static gdb_bfd_ref_ptr gdb_bfd_mach_o_fat_extract (bfd *abfd, bfd_format format, const bfd_arch_info_type *arch) { @@ -441,7 +441,7 @@ gdb_bfd_mach_o_fat_extract (bfd *abfd, bfd_format format, else gdb_bfd_mark_parent (result, abfd); - return result; + return gdb_bfd_ref_ptr (result); } /* Extract dyld_all_image_addr when the process was just created, assuming the @@ -452,8 +452,6 @@ darwin_solib_get_all_image_info_addr_at_init (struct darwin_info *info) { char *interp_name; CORE_ADDR load_addr = 0; - bfd *dyld_bfd = NULL; - struct cleanup *cleanup; /* This method doesn't work with an attached process. */ if (current_inferior ()->attach_flag) @@ -464,42 +462,30 @@ darwin_solib_get_all_image_info_addr_at_init (struct darwin_info *info) if (!interp_name) return; - cleanup = make_cleanup (null_cleanup, NULL); - /* Create a bfd for the interpreter. */ - dyld_bfd = gdb_bfd_open (interp_name, gnutarget, -1); - if (dyld_bfd) + gdb_bfd_ref_ptr dyld_bfd (gdb_bfd_open (interp_name, gnutarget, -1)); + if (dyld_bfd != NULL) { - bfd *sub; - - make_cleanup_bfd_unref (dyld_bfd); - sub = gdb_bfd_mach_o_fat_extract - (dyld_bfd, bfd_object, gdbarch_bfd_arch_info (target_gdbarch ())); - if (sub) - { - dyld_bfd = sub; - make_cleanup_bfd_unref (sub); - } + gdb_bfd_ref_ptr sub + (gdb_bfd_mach_o_fat_extract (dyld_bfd.get (), bfd_object, + gdbarch_bfd_arch_info (target_gdbarch ()))); + if (sub != NULL) + dyld_bfd = sub; else - dyld_bfd = NULL; - } - if (!dyld_bfd) - { - do_cleanups (cleanup); - return; + dyld_bfd.release (); } + if (dyld_bfd == NULL) + return; /* We find the dynamic linker's base address by examining the current pc (which should point at the entry point for the dynamic linker) and subtracting the offset of the entry point. */ load_addr = (regcache_read_pc (get_current_regcache ()) - - bfd_get_start_address (dyld_bfd)); + - bfd_get_start_address (dyld_bfd.get ())); /* Now try to set a breakpoint in the dynamic linker. */ info->all_image_addr = - lookup_symbol_from_bfd (dyld_bfd, "_dyld_all_image_infos"); - - do_cleanups (cleanup); + lookup_symbol_from_bfd (dyld_bfd.get (), "_dyld_all_image_infos"); if (info->all_image_addr == 0) return; @@ -634,13 +620,11 @@ darwin_lookup_lib_symbol (struct objfile *objfile, return (struct block_symbol) {NULL, NULL}; } -static bfd * +static gdb_bfd_ref_ptr darwin_bfd_open (char *pathname) { char *found_pathname; int found_file; - bfd *abfd; - bfd *res; /* Search for shared library file. */ found_pathname = solib_find (pathname, &found_file); @@ -648,24 +632,21 @@ darwin_bfd_open (char *pathname) perror_with_name (pathname); /* Open bfd for shared library. */ - abfd = solib_bfd_fopen (found_pathname, found_file); + gdb_bfd_ref_ptr abfd (solib_bfd_fopen (found_pathname, found_file)); - res = gdb_bfd_mach_o_fat_extract (abfd, bfd_object, - gdbarch_bfd_arch_info (target_gdbarch ())); - if (!res) - { - make_cleanup_bfd_unref (abfd); - error (_("`%s': not a shared-library: %s"), - bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ())); - } + gdb_bfd_ref_ptr res + (gdb_bfd_mach_o_fat_extract (abfd.get (), bfd_object, + gdbarch_bfd_arch_info (target_gdbarch ()))); + if (res == NULL) + error (_("`%s': not a shared-library: %s"), + bfd_get_filename (abfd.get ()), bfd_errmsg (bfd_get_error ())); /* The current filename for fat-binary BFDs is a name generated by BFD, usually a string containing the name of the architecture. Reset its value to the actual filename. */ - xfree (bfd_get_filename (res)); + xfree (bfd_get_filename (res.get ())); res->filename = xstrdup (pathname); - gdb_bfd_unref (abfd); return res; } diff --git a/gdb/solib-dsbt.c b/gdb/solib-dsbt.c index d66fe5d..14cab05 100644 --- a/gdb/solib-dsbt.c +++ b/gdb/solib-dsbt.c @@ -816,7 +816,6 @@ enable_break (void) { unsigned int interp_sect_size; char *buf; - bfd *tmp_bfd = NULL; CORE_ADDR addr; struct int_elf32_dsbt_loadmap *ldm; int ret; @@ -832,6 +831,7 @@ enable_break (void) loaded so that we can load its symbols and place a breakpoint in the dynamic linker itself. */ + gdb_bfd_ref_ptr tmp_bfd; TRY { tmp_bfd = solib_bfd_open (buf); @@ -852,29 +852,31 @@ enable_break (void) /* Record the relocated start and end address of the dynamic linker text and plt section for dsbt_in_dynsym_resolve_code. */ - interp_sect = bfd_get_section_by_name (tmp_bfd, ".text"); + interp_sect = bfd_get_section_by_name (tmp_bfd.get (), ".text"); if (interp_sect) { info->interp_text_sect_low - = bfd_section_vma (tmp_bfd, interp_sect); + = bfd_section_vma (tmp_bfd.get (), interp_sect); info->interp_text_sect_low += displacement_from_map (ldm, info->interp_text_sect_low); info->interp_text_sect_high = info->interp_text_sect_low - + bfd_section_size (tmp_bfd, interp_sect); + + bfd_section_size (tmp_bfd.get (), interp_sect); } - interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt"); + interp_sect = bfd_get_section_by_name (tmp_bfd.get (), ".plt"); if (interp_sect) { info->interp_plt_sect_low = - bfd_section_vma (tmp_bfd, interp_sect); + bfd_section_vma (tmp_bfd.get (), interp_sect); info->interp_plt_sect_low += displacement_from_map (ldm, info->interp_plt_sect_low); info->interp_plt_sect_high = - info->interp_plt_sect_low + bfd_section_size (tmp_bfd, interp_sect); + info->interp_plt_sect_low + bfd_section_size (tmp_bfd.get (), + interp_sect); } - addr = gdb_bfd_lookup_symbol (tmp_bfd, cmp_name, "_dl_debug_state"); + addr = gdb_bfd_lookup_symbol (tmp_bfd.get (), cmp_name, + "_dl_debug_state"); if (addr != 0) { if (solib_dsbt_debug) @@ -901,10 +903,7 @@ enable_break (void) ret = 0; } - /* We're done with the temporary bfd. */ - gdb_bfd_unref (tmp_bfd); - - /* We're also done with the loadmap. */ + /* We're done with the loadmap. */ xfree (ldm); return ret; diff --git a/gdb/solib-frv.c b/gdb/solib-frv.c index 61a4ed0..0387b44 100644 --- a/gdb/solib-frv.c +++ b/gdb/solib-frv.c @@ -532,7 +532,6 @@ enable_break2 (void) { unsigned int interp_sect_size; char *buf; - bfd *tmp_bfd = NULL; int status; CORE_ADDR addr, interp_loadmap_addr; gdb_byte addr_buf[FRV_PTR_SIZE]; @@ -554,6 +553,7 @@ enable_break2 (void) be trivial on GNU/Linux). Therefore, we have to try an alternate mechanism to find the dynamic linker's base address. */ + gdb_bfd_ref_ptr tmp_bfd; TRY { tmp_bfd = solib_bfd_open (buf); @@ -575,7 +575,6 @@ enable_break2 (void) { warning (_("Unable to determine dynamic linker loadmap address.")); enable_break_failure_warning (); - gdb_bfd_unref (tmp_bfd); return 0; } @@ -590,41 +589,41 @@ enable_break2 (void) warning (_("Unable to load dynamic linker loadmap at address %s."), hex_string_custom (interp_loadmap_addr, 8)); enable_break_failure_warning (); - gdb_bfd_unref (tmp_bfd); return 0; } /* Record the relocated start and end address of the dynamic linker text and plt section for svr4_in_dynsym_resolve_code. */ - interp_sect = bfd_get_section_by_name (tmp_bfd, ".text"); + interp_sect = bfd_get_section_by_name (tmp_bfd.get (), ".text"); if (interp_sect) { interp_text_sect_low - = bfd_section_vma (tmp_bfd, interp_sect); + = bfd_section_vma (tmp_bfd.get (), interp_sect); interp_text_sect_low += displacement_from_map (ldm, interp_text_sect_low); interp_text_sect_high - = interp_text_sect_low + bfd_section_size (tmp_bfd, interp_sect); + = interp_text_sect_low + bfd_section_size (tmp_bfd.get (), + interp_sect); } - interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt"); + interp_sect = bfd_get_section_by_name (tmp_bfd.get (), ".plt"); if (interp_sect) { interp_plt_sect_low = - bfd_section_vma (tmp_bfd, interp_sect); + bfd_section_vma (tmp_bfd.get (), interp_sect); interp_plt_sect_low += displacement_from_map (ldm, interp_plt_sect_low); interp_plt_sect_high = - interp_plt_sect_low + bfd_section_size (tmp_bfd, interp_sect); + interp_plt_sect_low + bfd_section_size (tmp_bfd.get (), + interp_sect); } - addr = gdb_bfd_lookup_symbol (tmp_bfd, cmp_name, "_dl_debug_addr"); + addr = gdb_bfd_lookup_symbol (tmp_bfd.get (), cmp_name, "_dl_debug_addr"); if (addr == 0) { warning (_("Could not find symbol _dl_debug_addr " "in dynamic linker")); enable_break_failure_warning (); - gdb_bfd_unref (tmp_bfd); return 0; } @@ -675,7 +674,6 @@ enable_break2 (void) "(at address %s) from dynamic linker"), hex_string_custom (addr + 8, 8)); enable_break_failure_warning (); - gdb_bfd_unref (tmp_bfd); return 0; } addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order); @@ -687,15 +685,11 @@ enable_break2 (void) "(at address %s) from dynamic linker"), hex_string_custom (addr, 8)); enable_break_failure_warning (); - gdb_bfd_unref (tmp_bfd); return 0; } addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order); - /* We're done with the temporary bfd. */ - gdb_bfd_unref (tmp_bfd); - - /* We're also done with the loadmap. */ + /* We're done with the loadmap. */ xfree (ldm); /* Remove all the solib event breakpoints. Their addresses diff --git a/gdb/solib-spu.c b/gdb/solib-spu.c index fa2977e..ab98656 100644 --- a/gdb/solib-spu.c +++ b/gdb/solib-spu.c @@ -319,36 +319,32 @@ spu_bfd_iovec_stat (bfd *abfd, void *stream, struct stat *sb) return 0; } -static bfd * +static gdb_bfd_ref_ptr spu_bfd_fopen (char *name, CORE_ADDR addr) { - bfd *nbfd; CORE_ADDR *open_closure = XNEW (CORE_ADDR); *open_closure = addr; - nbfd = gdb_bfd_openr_iovec (name, "elf32-spu", - spu_bfd_iovec_open, open_closure, - spu_bfd_iovec_pread, spu_bfd_iovec_close, - spu_bfd_iovec_stat); - if (!nbfd) + gdb_bfd_ref_ptr nbfd (gdb_bfd_openr_iovec (name, "elf32-spu", + spu_bfd_iovec_open, open_closure, + spu_bfd_iovec_pread, + spu_bfd_iovec_close, + spu_bfd_iovec_stat)); + if (nbfd == NULL) return NULL; - if (!bfd_check_format (nbfd, bfd_object)) - { - gdb_bfd_unref (nbfd); - return NULL; - } + if (!bfd_check_format (nbfd.get (), bfd_object)) + return NULL; return nbfd; } /* Open shared library BFD. */ -static bfd * +static gdb_bfd_ref_ptr spu_bfd_open (char *pathname) { char *original_name = strrchr (pathname, '@'); - bfd *abfd; asection *spu_name; unsigned long long addr; int fd; @@ -362,22 +358,23 @@ spu_bfd_open (char *pathname) internal_error (__FILE__, __LINE__, "bad object ID"); /* Open BFD representing SPE executable. */ - abfd = spu_bfd_fopen (original_name, (CORE_ADDR) addr); - if (!abfd) + gdb_bfd_ref_ptr abfd (spu_bfd_fopen (original_name, (CORE_ADDR) addr)); + if (abfd == NULL) error (_("Cannot read SPE executable at %s"), original_name); /* Retrieve SPU name note. */ - spu_name = bfd_get_section_by_name (abfd, ".note.spu_name"); + spu_name = bfd_get_section_by_name (abfd.get (), ".note.spu_name"); if (spu_name) { - int sect_size = bfd_section_size (abfd, spu_name); + int sect_size = bfd_section_size (abfd.get (), spu_name); if (sect_size > 20) { char *buf = (char *) alloca (sect_size - 20 + strlen (original_name) + 1); - bfd_get_section_contents (abfd, spu_name, buf, 20, sect_size - 20); + bfd_get_section_contents (abfd.get (), spu_name, buf, 20, + sect_size - 20); buf[sect_size - 20] = '\0'; strcat (buf, original_name); diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c index 0e18292..b801364 100644 --- a/gdb/solib-svr4.c +++ b/gdb/solib-svr4.c @@ -2355,7 +2355,6 @@ enable_break (struct svr4_info *info, int from_tty) int load_addr_found = 0; int loader_found_in_list = 0; struct so_list *so; - bfd *tmp_bfd = NULL; struct target_ops *tmp_bfd_target; sym_addr = 0; @@ -2369,6 +2368,7 @@ enable_break (struct svr4_info *info, int from_tty) be trivial on GNU/Linux). Therefore, we have to try an alternate mechanism to find the dynamic linker's base address. */ + gdb_bfd_ref_ptr tmp_bfd; TRY { tmp_bfd = solib_bfd_open (interp_name); @@ -2382,11 +2382,9 @@ enable_break (struct svr4_info *info, int from_tty) goto bkpt_at_symbol; /* Now convert the TMP_BFD into a target. That way target, as - well as BFD operations can be used. */ - tmp_bfd_target = target_bfd_reopen (tmp_bfd); - /* target_bfd_reopen acquired its own reference, so we can - release ours now. */ - gdb_bfd_unref (tmp_bfd); + well as BFD operations can be used. target_bfd_reopen + acquires its own reference. */ + tmp_bfd_target = target_bfd_reopen (tmp_bfd.get ()); /* On a running target, we can get the dynamic linker's base address from the shared library table. */ @@ -2397,7 +2395,7 @@ enable_break (struct svr4_info *info, int from_tty) { load_addr_found = 1; loader_found_in_list = 1; - load_addr = lm_addr_check (so, tmp_bfd); + load_addr = lm_addr_check (so, tmp_bfd.get ()); break; } so = so->next; @@ -2418,7 +2416,7 @@ enable_break (struct svr4_info *info, int from_tty) if (addr_bit < (sizeof (CORE_ADDR) * HOST_CHAR_BIT)) { CORE_ADDR space_size = (CORE_ADDR) 1 << addr_bit; - CORE_ADDR tmp_entry_point = exec_entry_point (tmp_bfd, + CORE_ADDR tmp_entry_point = exec_entry_point (tmp_bfd.get (), tmp_bfd_target); gdb_assert (load_addr < space_size); @@ -2447,7 +2445,7 @@ enable_break (struct svr4_info *info, int from_tty) = get_thread_arch_regcache (inferior_ptid, target_gdbarch ()); load_addr = (regcache_read_pc (regcache) - - exec_entry_point (tmp_bfd, tmp_bfd_target)); + - exec_entry_point (tmp_bfd.get (), tmp_bfd_target)); } if (!loader_found_in_list) @@ -2460,29 +2458,30 @@ enable_break (struct svr4_info *info, int from_tty) /* Record the relocated start and end address of the dynamic linker text and plt section for svr4_in_dynsym_resolve_code. */ - interp_sect = bfd_get_section_by_name (tmp_bfd, ".text"); + interp_sect = bfd_get_section_by_name (tmp_bfd.get (), ".text"); if (interp_sect) { info->interp_text_sect_low = - bfd_section_vma (tmp_bfd, interp_sect) + load_addr; + bfd_section_vma (tmp_bfd.get (), interp_sect) + load_addr; info->interp_text_sect_high = info->interp_text_sect_low - + bfd_section_size (tmp_bfd, interp_sect); + + bfd_section_size (tmp_bfd.get (), interp_sect); } - interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt"); + interp_sect = bfd_get_section_by_name (tmp_bfd.get (), ".plt"); if (interp_sect) { info->interp_plt_sect_low = - bfd_section_vma (tmp_bfd, interp_sect) + load_addr; + bfd_section_vma (tmp_bfd.get (), interp_sect) + load_addr; info->interp_plt_sect_high = info->interp_plt_sect_low - + bfd_section_size (tmp_bfd, interp_sect); + + bfd_section_size (tmp_bfd.get (), interp_sect); } /* Now try to set a breakpoint in the dynamic linker. */ for (bkpt_namep = solib_break_names; *bkpt_namep != NULL; bkpt_namep++) { - sym_addr = gdb_bfd_lookup_symbol (tmp_bfd, cmp_name_and_sec_flags, + sym_addr = gdb_bfd_lookup_symbol (tmp_bfd.get (), + cmp_name_and_sec_flags, *bkpt_namep); if (sym_addr != 0) break; diff --git a/gdb/solib.c b/gdb/solib.c index c4b2cdc..7fc4463 100644 --- a/gdb/solib.c +++ b/gdb/solib.c @@ -474,15 +474,15 @@ solib_find (char *in_pathname, int *fd) function. If unsuccessful, the FD will be closed (unless FD was -1). */ -bfd * +gdb_bfd_ref_ptr solib_bfd_fopen (char *pathname, int fd) { - bfd *abfd = gdb_bfd_open (pathname, gnutarget, fd); + gdb_bfd_ref_ptr abfd (gdb_bfd_open (pathname, gnutarget, fd)); - if (abfd != NULL && !gdb_bfd_has_target_filename (abfd)) - bfd_set_cacheable (abfd, 1); + if (abfd != NULL && !gdb_bfd_has_target_filename (abfd.get ())) + bfd_set_cacheable (abfd.get (), 1); - if (!abfd) + if (abfd == NULL) { make_cleanup (xfree, pathname); error (_("Could not open `%s' as an executable file: %s"), @@ -496,12 +496,11 @@ solib_bfd_fopen (char *pathname, int fd) /* Find shared library PATHNAME and open a BFD for it. */ -bfd * +gdb_bfd_ref_ptr solib_bfd_open (char *pathname) { char *found_pathname; int found_file; - bfd *abfd; const struct bfd_arch_info *b; /* Search for shared library file. */ @@ -517,22 +516,20 @@ solib_bfd_open (char *pathname) } /* Open bfd for shared library. */ - abfd = solib_bfd_fopen (found_pathname, found_file); + gdb_bfd_ref_ptr abfd (solib_bfd_fopen (found_pathname, found_file)); /* Check bfd format. */ - if (!bfd_check_format (abfd, bfd_object)) - { - make_cleanup_bfd_unref (abfd); - error (_("`%s': not in executable format: %s"), - bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ())); - } + if (!bfd_check_format (abfd.get (), bfd_object)) + error (_("`%s': not in executable format: %s"), + bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ())); /* Check bfd arch. */ b = gdbarch_bfd_arch_info (target_gdbarch ()); - if (!b->compatible (b, bfd_get_arch_info (abfd))) + if (!b->compatible (b, bfd_get_arch_info (abfd.get ()))) warning (_("`%s': Shared library architecture %s is not compatible " "with target architecture %s."), bfd_get_filename (abfd), - bfd_get_arch_info (abfd)->printable_name, b->printable_name); + bfd_get_arch_info (abfd.get ())->printable_name, + b->printable_name); return abfd; } @@ -556,18 +553,17 @@ solib_map_sections (struct so_list *so) char *filename; struct target_section *p; struct cleanup *old_chain; - bfd *abfd; filename = tilde_expand (so->so_name); old_chain = make_cleanup (xfree, filename); - abfd = ops->bfd_open (filename); + gdb_bfd_ref_ptr abfd (ops->bfd_open (filename)); do_cleanups (old_chain); if (abfd == NULL) return 0; /* Leave bfd open, core_xfer_memory and "info files" need it. */ - so->abfd = abfd; + so->abfd = abfd.release (); /* Copy the full path name into so_name, allowing symbol_file_add to find it later. This also affects the =library-loaded GDB/MI @@ -575,14 +571,14 @@ solib_map_sections (struct so_list *so) the library's host-side path. If we let the target dictate that objfile's path, and the target is different from the host, GDB/MI will not provide the correct host-side path. */ - if (strlen (bfd_get_filename (abfd)) >= SO_NAME_MAX_PATH_SIZE) + if (strlen (bfd_get_filename (so->abfd)) >= SO_NAME_MAX_PATH_SIZE) error (_("Shared library file name is too long.")); - strcpy (so->so_name, bfd_get_filename (abfd)); + strcpy (so->so_name, bfd_get_filename (so->abfd)); - if (build_section_table (abfd, &so->sections, &so->sections_end)) + if (build_section_table (so->abfd, &so->sections, &so->sections_end)) { error (_("Can't find the file sections in `%s': %s"), - bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ())); + bfd_get_filename (so->abfd), bfd_errmsg (bfd_get_error ())); } for (p = so->sections; p < so->sections_end; p++) @@ -1351,7 +1347,6 @@ reload_shared_libraries_1 (int from_tty) for (so = so_list_head; so != NULL; so = so->next) { char *filename, *found_pathname = NULL; - bfd *abfd; int was_loaded = so->symbols_loaded; symfile_add_flags add_flags = SYMFILE_DEFER_BP_RESET; @@ -1360,12 +1355,11 @@ reload_shared_libraries_1 (int from_tty) filename = tilde_expand (so->so_original_name); make_cleanup (xfree, filename); - abfd = solib_bfd_open (filename); + gdb_bfd_ref_ptr abfd (solib_bfd_open (filename)); if (abfd != NULL) { - found_pathname = xstrdup (bfd_get_filename (abfd)); + found_pathname = xstrdup (bfd_get_filename (abfd.get ())); make_cleanup (xfree, found_pathname); - gdb_bfd_unref (abfd); } /* If this shared library is no longer associated with its previous diff --git a/gdb/solist.h b/gdb/solist.h index f709483..ca02051 100644 --- a/gdb/solist.h +++ b/gdb/solist.h @@ -22,6 +22,7 @@ #define SO_NAME_MAX_PATH_SIZE 512 /* FIXME: Should be dynamic */ /* For domain_enum domain. */ #include "symtab.h" +#include "gdb_bfd.h" /* Forward declaration for target specific link map information. This struct is opaque to all but the target specific file. */ @@ -121,7 +122,7 @@ struct target_so_ops int (*in_dynsym_resolve_code) (CORE_ADDR pc); /* Find and open shared library binary file. */ - bfd *(*bfd_open) (char *pathname); + gdb_bfd_ref_ptr (*bfd_open) (char *pathname); /* Optional extra hook for finding and opening a solib. If TEMP_PATHNAME is non-NULL: If the file is successfully opened a @@ -178,10 +179,10 @@ extern char *exec_file_find (char *in_pathname, int *fd); extern char *solib_find (char *in_pathname, int *fd); /* Open BFD for shared library file. */ -extern bfd *solib_bfd_fopen (char *pathname, int fd); +extern gdb_bfd_ref_ptr solib_bfd_fopen (char *pathname, int fd); /* Find solib binary file and open it. */ -extern bfd *solib_bfd_open (char *in_pathname); +extern gdb_bfd_ref_ptr solib_bfd_open (char *in_pathname); /* FIXME: gdbarch needs to control this variable. */ extern struct target_so_ops *current_target_so_ops; diff --git a/gdb/spu-linux-nat.c b/gdb/spu-linux-nat.c index f1d58ec..9d333b8 100644 --- a/gdb/spu-linux-nat.c +++ b/gdb/spu-linux-nat.c @@ -318,37 +318,35 @@ spu_bfd_iovec_stat (struct bfd *abfd, void *stream, struct stat *sb) return 0; } -static bfd * +static gdb_bfd_ref_ptr spu_bfd_open (ULONGEST addr) { - struct bfd *nbfd; asection *spu_name; ULONGEST *open_closure = XNEW (ULONGEST); *open_closure = addr; - nbfd = gdb_bfd_openr_iovec ("<in-memory>", "elf32-spu", - spu_bfd_iovec_open, open_closure, - spu_bfd_iovec_pread, spu_bfd_iovec_close, - spu_bfd_iovec_stat); - if (!nbfd) + gdb_bfd_ref_ptr nbfd (gdb_bfd_openr_iovec ("<in-memory>", "elf32-spu", + spu_bfd_iovec_open, open_closure, + spu_bfd_iovec_pread, + spu_bfd_iovec_close, + spu_bfd_iovec_stat)); + if (nbfd == NULL) return NULL; - if (!bfd_check_format (nbfd, bfd_object)) - { - gdb_bfd_unref (nbfd); - return NULL; - } + if (!bfd_check_format (nbfd.get (), bfd_object)) + return NULL; /* Retrieve SPU name note and update BFD name. */ - spu_name = bfd_get_section_by_name (nbfd, ".note.spu_name"); + spu_name = bfd_get_section_by_name (nbfd.get (), ".note.spu_name"); if (spu_name) { - int sect_size = bfd_section_size (nbfd, spu_name); + int sect_size = bfd_section_size (nbfd.get (), spu_name); if (sect_size > 20) { char *buf = (char *)alloca (sect_size - 20 + 1); - bfd_get_section_contents (nbfd, spu_name, buf, 20, sect_size - 20); + bfd_get_section_contents (nbfd.get (), spu_name, buf, 20, + sect_size - 20); buf[sect_size - 20] = '\0'; xfree ((char *)nbfd->filename); @@ -367,7 +365,6 @@ static void spu_symbol_file_add_from_memory (int inferior_fd) { ULONGEST addr; - struct bfd *nbfd; gdb_byte id[128]; char annex[32]; @@ -385,15 +382,12 @@ spu_symbol_file_add_from_memory (int inferior_fd) return; /* Open BFD representing SPE executable and read its symbols. */ - nbfd = spu_bfd_open (addr); - if (nbfd) + gdb_bfd_ref_ptr nbfd (spu_bfd_open (addr)); + if (nbfd != NULL) { - struct cleanup *cleanup = make_cleanup_bfd_unref (nbfd); - - symbol_file_add_from_bfd (nbfd, bfd_get_filename (nbfd), + symbol_file_add_from_bfd (nbfd.get (), bfd_get_filename (nbfd), SYMFILE_VERBOSE | SYMFILE_MAINLINE, NULL, 0, NULL); - do_cleanups (cleanup); } } diff --git a/gdb/symfile-mem.c b/gdb/symfile-mem.c index 58257b9..ec283b2 100644 --- a/gdb/symfile-mem.c +++ b/gdb/symfile-mem.c @@ -102,20 +102,21 @@ symbol_file_add_from_memory (struct bfd *templ, CORE_ADDR addr, error (_("Failed to read a valid object file image from memory.")); gdb_bfd_ref (nbfd); + /* Manage the new reference for the duration of this function. */ + gdb_bfd_ref_ptr nbfd_holder (nbfd); + xfree (bfd_get_filename (nbfd)); if (name == NULL) nbfd->filename = xstrdup ("shared object read from target memory"); else nbfd->filename = name; - cleanup = make_cleanup_bfd_unref (nbfd); - if (!bfd_check_format (nbfd, bfd_object)) error (_("Got object file from memory but can't read symbols: %s."), bfd_errmsg (bfd_get_error ())); sai = alloc_section_addr_info (bfd_count_sections (nbfd)); - make_cleanup (xfree, sai); + cleanup = make_cleanup (xfree, sai); i = 0; for (sec = nbfd->sections; sec != NULL; sec = sec->next) if ((bfd_get_section_flags (nbfd, sec) & (SEC_ALLOC|SEC_LOAD)) != 0) diff --git a/gdb/symfile.c b/gdb/symfile.c index 52f99bf..4775d5b 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -876,8 +876,7 @@ read_symbols (struct objfile *objfile, symfile_add_flags add_flags) && objfile->separate_debug_objfile == NULL && objfile->separate_debug_objfile_backlink == NULL) { - bfd *abfd = find_separate_debug_file_in_section (objfile); - struct cleanup *cleanup = make_cleanup_bfd_unref (abfd); + gdb_bfd_ref_ptr abfd (find_separate_debug_file_in_section (objfile)); if (abfd != NULL) { @@ -885,11 +884,9 @@ read_symbols (struct objfile *objfile, symfile_add_flags add_flags) virtual section-as-bfd like the bfd filename containing the section. Therefore use also non-canonical name form for the same file containing the section. */ - symbol_file_add_separate (abfd, objfile->original_name, add_flags, - objfile); + symbol_file_add_separate (abfd.get (), objfile->original_name, + add_flags, objfile); } - - do_cleanups (cleanup); } if ((add_flags & SYMFILE_NO_READ) == 0) require_partial_symbols (objfile, 0); @@ -1287,13 +1284,10 @@ struct objfile * symbol_file_add (const char *name, symfile_add_flags add_flags, struct section_addr_info *addrs, objfile_flags flags) { - bfd *bfd = symfile_bfd_open (name); - struct cleanup *cleanup = make_cleanup_bfd_unref (bfd); - struct objfile *objf; + gdb_bfd_ref_ptr bfd (symfile_bfd_open (name)); - objf = symbol_file_add_from_bfd (bfd, name, add_flags, addrs, flags, NULL); - do_cleanups (cleanup); - return objf; + return symbol_file_add_from_bfd (bfd.get (), name, add_flags, addrs, + flags, NULL); } /* Call symbol_file_add() with default values and update whatever is @@ -1354,7 +1348,6 @@ separate_debug_file_exists (const char *name, unsigned long crc, { unsigned long file_crc; int file_crc_p; - bfd *abfd; struct stat parent_stat, abfd_stat; int verified_as_different; @@ -1367,9 +1360,9 @@ separate_debug_file_exists (const char *name, unsigned long crc, if (filename_cmp (name, objfile_name (parent_objfile)) == 0) return 0; - abfd = gdb_bfd_open (name, gnutarget, -1); + gdb_bfd_ref_ptr abfd (gdb_bfd_open (name, gnutarget, -1)); - if (!abfd) + if (abfd == NULL) return 0; /* Verify symlinks were not the cause of filename_cmp name difference above. @@ -1383,24 +1376,19 @@ separate_debug_file_exists (const char *name, unsigned long crc, numbers will never set st_ino to zero, this is merely an optimization, so we do not need to worry about false negatives. */ - if (bfd_stat (abfd, &abfd_stat) == 0 + if (bfd_stat (abfd.get (), &abfd_stat) == 0 && abfd_stat.st_ino != 0 && bfd_stat (parent_objfile->obfd, &parent_stat) == 0) { if (abfd_stat.st_dev == parent_stat.st_dev && abfd_stat.st_ino == parent_stat.st_ino) - { - gdb_bfd_unref (abfd); - return 0; - } + return 0; verified_as_different = 1; } else verified_as_different = 0; - file_crc_p = gdb_bfd_crc (abfd, &file_crc); - - gdb_bfd_unref (abfd); + file_crc_p = gdb_bfd_crc (abfd.get (), &file_crc); if (!file_crc_p) return 0; @@ -1721,10 +1709,9 @@ set_initial_language (void) includes a newly malloc'd` copy of NAME (tilde-expanded and made absolute). In case of trouble, error() is called. */ -bfd * +gdb_bfd_ref_ptr symfile_bfd_open (const char *name) { - bfd *sym_bfd; int desc = -1; struct cleanup *back_to = make_cleanup (null_cleanup, 0); @@ -1760,20 +1747,17 @@ symfile_bfd_open (const char *name) name = absolute_name; } - sym_bfd = gdb_bfd_open (name, gnutarget, desc); - if (!sym_bfd) + gdb_bfd_ref_ptr sym_bfd (gdb_bfd_open (name, gnutarget, desc)); + if (sym_bfd == NULL) error (_("`%s': can't open to read symbols: %s."), name, bfd_errmsg (bfd_get_error ())); - if (!gdb_bfd_has_target_filename (sym_bfd)) - bfd_set_cacheable (sym_bfd, 1); + if (!gdb_bfd_has_target_filename (sym_bfd.get ())) + bfd_set_cacheable (sym_bfd.get (), 1); - if (!bfd_check_format (sym_bfd, bfd_object)) - { - make_cleanup_bfd_unref (sym_bfd); - error (_("`%s': can't read symbols: %s."), name, - bfd_errmsg (bfd_get_error ())); - } + if (!bfd_check_format (sym_bfd.get (), bfd_object)) + error (_("`%s': can't read symbols: %s."), name, + bfd_errmsg (bfd_get_error ())); do_cleanups (back_to); @@ -2073,7 +2057,6 @@ static void print_transfer_performance (struct ui_file *stream, void generic_load (const char *args, int from_tty) { - bfd *loadfile_bfd; char *filename; struct cleanup *old_cleanups = make_cleanup (null_cleanup, 0); struct load_section_data cbdata; @@ -2114,25 +2097,23 @@ generic_load (const char *args, int from_tty) } /* Open the file for loading. */ - loadfile_bfd = gdb_bfd_open (filename, gnutarget, -1); + gdb_bfd_ref_ptr loadfile_bfd (gdb_bfd_open (filename, gnutarget, -1)); if (loadfile_bfd == NULL) { perror_with_name (filename); return; } - make_cleanup_bfd_unref (loadfile_bfd); - - if (!bfd_check_format (loadfile_bfd, bfd_object)) + if (!bfd_check_format (loadfile_bfd.get (), bfd_object)) { error (_("\"%s\" is not an object file: %s"), filename, bfd_errmsg (bfd_get_error ())); } - bfd_map_over_sections (loadfile_bfd, add_section_size_callback, + bfd_map_over_sections (loadfile_bfd.get (), add_section_size_callback, (void *) &total_progress.total_size); - bfd_map_over_sections (loadfile_bfd, load_section_callback, &cbdata); + bfd_map_over_sections (loadfile_bfd.get (), load_section_callback, &cbdata); using namespace std::chrono; @@ -2144,7 +2125,7 @@ generic_load (const char *args, int from_tty) steady_clock::time_point end_time = steady_clock::now (); - entry = bfd_get_start_address (loadfile_bfd); + entry = bfd_get_start_address (loadfile_bfd.get ()); entry = gdbarch_addr_bits_remove (target_gdbarch (), entry); ui_out_text (uiout, "Start address "); ui_out_field_fmt (uiout, "address", "%s", paddress (target_gdbarch (), entry)); @@ -2568,22 +2549,16 @@ reread_symbols (void) /* Clean up any state BFD has sitting around. */ { - struct bfd *obfd = objfile->obfd; + gdb_bfd_ref_ptr obfd (objfile->obfd); char *obfd_filename; obfd_filename = bfd_get_filename (objfile->obfd); /* Open the new BFD before freeing the old one, so that the filename remains live. */ - objfile->obfd = gdb_bfd_open (obfd_filename, gnutarget, -1); + gdb_bfd_ref_ptr temp (gdb_bfd_open (obfd_filename, gnutarget, -1)); + objfile->obfd = temp.release (); if (objfile->obfd == NULL) - { - /* We have to make a cleanup and error here, rather - than erroring later, because once we unref OBFD, - OBFD_FILENAME will be freed. */ - make_cleanup_bfd_unref (obfd); - error (_("Can't open %s to read symbols."), obfd_filename); - } - gdb_bfd_unref (obfd); + error (_("Can't open %s to read symbols."), obfd_filename); } original_name = xstrdup (objfile->original_name); diff --git a/gdb/symfile.h b/gdb/symfile.h index 59952cb..7a2e6fb 100644 --- a/gdb/symfile.h +++ b/gdb/symfile.h @@ -25,6 +25,7 @@ #include "probe.h" #include "symfile-add-flags.h" #include "objfile-flags.h" +#include "gdb_bfd.h" /* Opaque declarations. */ struct target_section; @@ -499,7 +500,7 @@ extern void set_initial_language (void); extern void find_lowest_section (bfd *, asection *, void *); -extern bfd *symfile_bfd_open (const char *); +extern gdb_bfd_ref_ptr symfile_bfd_open (const char *); extern int get_section_index (struct objfile *, char *); @@ -646,6 +647,6 @@ extern void elfmdebug_build_psymtabs (struct objfile *, /* From minidebug.c. */ -extern bfd *find_separate_debug_file_in_section (struct objfile *); +extern gdb_bfd_ref_ptr find_separate_debug_file_in_section (struct objfile *); #endif /* !defined(SYMFILE_H) */ diff --git a/gdb/utils.c b/gdb/utils.c index 77c38bf..6ee6fc8 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -151,18 +151,6 @@ make_cleanup_freeargv (char **arg) return make_cleanup (do_freeargv, arg); } -static void -do_bfd_close_cleanup (void *arg) -{ - gdb_bfd_unref ((bfd *) arg); -} - -struct cleanup * -make_cleanup_bfd_unref (bfd *abfd) -{ - return make_cleanup (do_bfd_close_cleanup, abfd); -} - /* Helper function which does the work for make_cleanup_fclose. */ static void diff --git a/gdb/utils.h b/gdb/utils.h index 349530e..4407eeb 100644 --- a/gdb/utils.h +++ b/gdb/utils.h @@ -81,8 +81,6 @@ extern struct cleanup *(make_cleanup_free_section_addr_info extern struct cleanup *make_cleanup_fclose (FILE *file); -extern struct cleanup *make_cleanup_bfd_unref (bfd *abfd); - struct obstack; extern struct cleanup *make_cleanup_obstack_free (struct obstack *obstack); diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c index 5b79f34..efccd71 100644 --- a/gdb/windows-nat.c +++ b/gdb/windows-nat.c @@ -669,32 +669,27 @@ windows_make_so (const char *name, LPVOID load_addr) p = strchr (so->so_name, '\0') - (sizeof ("/cygwin1.dll") - 1); if (p >= so->so_name && strcasecmp (p, "/cygwin1.dll") == 0) { - bfd *abfd; asection *text = NULL; CORE_ADDR text_vma; - abfd = gdb_bfd_open (so->so_name, "pei-i386", -1); + gdb_bfd_ref_ptr abfd (gdb_bfd_open (so->so_name, "pei-i386", -1)); - if (!abfd) + if (abfd == NULL) return so; - if (bfd_check_format (abfd, bfd_object)) - text = bfd_get_section_by_name (abfd, ".text"); + if (bfd_check_format (abfd.get (), bfd_object)) + text = bfd_get_section_by_name (abfd.get (), ".text"); if (!text) - { - gdb_bfd_unref (abfd); - return so; - } + return so; /* The symbols in a dll are offset by 0x1000, which is the offset from 0 of the first byte in an image - because of the file header and the section alignment. */ cygwin_load_start = (CORE_ADDR) (uintptr_t) ((char *) load_addr + 0x1000); - cygwin_load_end = cygwin_load_start + bfd_section_size (abfd, text); - - gdb_bfd_unref (abfd); + cygwin_load_end = cygwin_load_start + bfd_section_size (abfd.get (), + text); } #endif diff --git a/gdb/windows-tdep.c b/gdb/windows-tdep.c index 810607a..2f79d8d 100644 --- a/gdb/windows-tdep.c +++ b/gdb/windows-tdep.c @@ -372,7 +372,6 @@ windows_xfer_shared_library (const char* so_name, CORE_ADDR load_addr, struct gdbarch *gdbarch, struct obstack *obstack) { char *p; - struct bfd * dll; CORE_ADDR text_offset; obstack_grow_str (obstack, "<library name=\""); @@ -380,12 +379,11 @@ windows_xfer_shared_library (const char* so_name, CORE_ADDR load_addr, obstack_grow_str (obstack, p); xfree (p); obstack_grow_str (obstack, "\"><segment address=\""); - dll = gdb_bfd_open (so_name, gnutarget, -1); + gdb_bfd_ref_ptr dll (gdb_bfd_open (so_name, gnutarget, -1)); /* The following calls are OK even if dll is NULL. The default value 0x1000 is returned by pe_text_section_offset in that case. */ - text_offset = pe_text_section_offset (dll); - gdb_bfd_unref (dll); + text_offset = pe_text_section_offset (dll.get ()); obstack_grow_str (obstack, paddress (gdbarch, load_addr + text_offset)); obstack_grow_str (obstack, "\"/></library>"); } ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 2/8] Use class to manage BFD reference counts 2016-12-15 4:12 ` Tom Tromey @ 2016-12-20 18:18 ` Pedro Alves 0 siblings, 0 replies; 50+ messages in thread From: Pedro Alves @ 2016-12-20 18:18 UTC (permalink / raw) To: Tom Tromey; +Cc: gdb-patches On 12/15/2016 03:49 AM, Tom Tromey wrote: >>>>>> "Tom" == Tom Tromey <tom@tromey.com> writes: > > Tom> I'll send a new patch soon. > > Here it is. > This was part of the series I sent through buildbot. Thanks. This LGTM. -- Pedro Alves ^ permalink raw reply [flat|nested] 50+ messages in thread
* [pushed] gdb: Constify solib_find (Re: [RFA 2/8] Use class to manage BFD reference counts) 2016-12-13 13:26 ` Tom Tromey 2016-12-15 4:12 ` Tom Tromey @ 2016-12-20 17:19 ` Pedro Alves 2016-12-20 18:05 ` Tom Tromey 1 sibling, 1 reply; 50+ messages in thread From: Pedro Alves @ 2016-12-20 17:19 UTC (permalink / raw) To: Tom Tromey; +Cc: gdb-patches On 12/13/2016 01:25 PM, Tom Tromey wrote: >>>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes: > >>> - return NULL; >>> + return gdb_bfd_ref_ptr (); > > Pedro> This provides a good reason to have an implicit construction from > Pedro> nullptr_t. You had it in the original gdbpy_reference > Pedro> submission, but I had asked to remove it. If we add it back, > Pedro> these cases could be more clearly written as "return > Pedro> NULL/nullptr". Could you do that, and then drop all the hunks > Pedro> like: > >>> - return NULL; >>> + return gdb_bfd_ref_ptr (); > > Pedro> ? > > I did this. Thanks! > Pedro> I think these could be: > Pedro> std::string filename > Pedro> = string_printf ("%.*s", filename_len, pathname); > Pedro> std::string member_name > Pedro> = string_printf ("%.*s", path_len - filename_len - 2, sep + 1)); > > I did this, but it's a bit ugly as solib_find isn't const-correct. That doesn't look hard to fix. I've pushed in the patch below. What uglification does this allow removing? From 992f1ddc3be1f5195f18beaa801ac50f284b10c5 Mon Sep 17 00:00:00 2001 From: Pedro Alves <palves@redhat.com> Date: Tue, 20 Dec 2016 17:07:19 +0000 Subject: [PATCH] gdb: Constify solib_find gdb/ChangeLog: 2016-12-20 Pedro Alves <palves@redhat.com> * nto-tdep.c (nto_find_and_open_solib): Constify 'solib' parameter. * nto-tdep.h (nto_find_and_open_solib): Constify 'solib' parameter. * solib.c (solib_find_1, exec_file_find, solib_find): Constify in_pathname' parameter. * solist.h (struct target_so_ops) <find_and_open_solib>: Constify 'soname' parameter. (exec_file_find, solib_find): Constify 'in_pathname' parameter. --- gdb/ChangeLog | 12 ++++++++++++ gdb/nto-tdep.c | 3 ++- gdb/nto-tdep.h | 2 +- gdb/solib.c | 8 ++++---- gdb/solist.h | 6 +++--- 5 files changed, 22 insertions(+), 9 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 5f0e6fe..2041dd5 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,4 +1,16 @@ 2016-12-20 Pedro Alves <palves@redhat.com> + + * nto-tdep.c (nto_find_and_open_solib): Constify 'solib' + parameter. + * nto-tdep.h (nto_find_and_open_solib): Constify 'solib' + parameter. + * solib.c (solib_find_1, exec_file_find, solib_find): Constify + in_pathname' parameter. + * solist.h (struct target_so_ops) <find_and_open_solib>: Constify + 'soname' parameter. + (exec_file_find, solib_find): Constify 'in_pathname' parameter. + +2016-12-20 Pedro Alves <palves@redhat.com> Yao Qi <yao.qi@linaro.org> PR gdb/20977 diff --git a/gdb/nto-tdep.c b/gdb/nto-tdep.c index 47d8a2b..1b18de1 100644 --- a/gdb/nto-tdep.c +++ b/gdb/nto-tdep.c @@ -87,7 +87,8 @@ nto_map_arch_to_cputype (const char *arch) } int -nto_find_and_open_solib (char *solib, unsigned o_flags, char **temp_pathname) +nto_find_and_open_solib (const char *solib, unsigned o_flags, + char **temp_pathname) { char *buf, *arch_path, *nto_root; const char *endian; diff --git a/gdb/nto-tdep.h b/gdb/nto-tdep.h index 81ed50c..06a1f9a 100644 --- a/gdb/nto-tdep.h +++ b/gdb/nto-tdep.h @@ -164,7 +164,7 @@ void nto_relocate_section_addresses (struct so_list *, int nto_map_arch_to_cputype (const char *); -int nto_find_and_open_solib (char *, unsigned, char **); +int nto_find_and_open_solib (const char *, unsigned, char **); enum gdb_osabi nto_elf_osabi_sniffer (bfd *abfd); diff --git a/gdb/solib.c b/gdb/solib.c index c4b2cdc..82214d0 100644 --- a/gdb/solib.c +++ b/gdb/solib.c @@ -152,7 +152,7 @@ show_solib_search_path (struct ui_file *file, int from_tty, */ static char * -solib_find_1 (char *in_pathname, int *fd, int is_solib) +solib_find_1 (const char *in_pathname, int *fd, int is_solib) { const struct target_so_ops *ops = solib_ops (target_gdbarch ()); int found_file = -1; @@ -383,7 +383,7 @@ solib_find_1 (char *in_pathname, int *fd, int is_solib) file handle for the main executable. */ char * -exec_file_find (char *in_pathname, int *fd) +exec_file_find (const char *in_pathname, int *fd) { char *result; const char *fskind = effective_target_file_system_kind (); @@ -434,7 +434,7 @@ exec_file_find (char *in_pathname, int *fd) above. */ char * -solib_find (char *in_pathname, int *fd) +solib_find (const char *in_pathname, int *fd) { const char *solib_symbols_extension = gdbarch_solib_symbols_extension (target_gdbarch ()); @@ -443,7 +443,7 @@ solib_find (char *in_pathname, int *fd) extension. */ if (solib_symbols_extension != NULL) { - char *p = in_pathname + strlen (in_pathname); + const char *p = in_pathname + strlen (in_pathname); while (p > in_pathname && *p != '.') p--; diff --git a/gdb/solist.h b/gdb/solist.h index f709483..948ad31 100644 --- a/gdb/solist.h +++ b/gdb/solist.h @@ -127,7 +127,7 @@ struct target_so_ops If TEMP_PATHNAME is non-NULL: If the file is successfully opened a pointer to a malloc'd and realpath'd copy of SONAME is stored there, otherwise NULL is stored there. */ - int (*find_and_open_solib) (char *soname, + int (*find_and_open_solib) (const char *soname, unsigned o_flags, char **temp_pathname); /* Hook for looking up global symbols in a library-specific way. */ @@ -172,10 +172,10 @@ void free_so (struct so_list *so); struct so_list *master_so_list (void); /* Find main executable binary file. */ -extern char *exec_file_find (char *in_pathname, int *fd); +extern char *exec_file_find (const char *in_pathname, int *fd); /* Find shared library binary file. */ -extern char *solib_find (char *in_pathname, int *fd); +extern char *solib_find (const char *in_pathname, int *fd); /* Open BFD for shared library file. */ extern bfd *solib_bfd_fopen (char *pathname, int fd); -- 2.5.5 ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [pushed] gdb: Constify solib_find (Re: [RFA 2/8] Use class to manage BFD reference counts) 2016-12-20 17:19 ` [pushed] gdb: Constify solib_find (Re: [RFA 2/8] Use class to manage BFD reference counts) Pedro Alves @ 2016-12-20 18:05 ` Tom Tromey 0 siblings, 0 replies; 50+ messages in thread From: Tom Tromey @ 2016-12-20 18:05 UTC (permalink / raw) To: Pedro Alves; +Cc: Tom Tromey, gdb-patches >>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes: Tom> I did this, but it's a bit ugly as solib_find isn't const-correct. Pedro> That doesn't look hard to fix. I've pushed in the patch below. Pedro> What uglification does this allow removing? Huh. I had taken a stab at this but I thought I ran into some morass, so I stopped. Oh well. Anyway what this enables is a change from &str[0] to str.c_str(). Tom ^ permalink raw reply [flat|nested] 50+ messages in thread
* [RFA 6/8] Use value_freer in dwarf2_evaluate_loc_desc_full 2016-11-29 5:06 [RFA 0/8] C++-ification series #5 Tom Tromey ` (6 preceding siblings ...) 2016-11-29 5:06 ` [RFA 2/8] Use class to manage BFD reference counts Tom Tromey @ 2016-11-29 5:06 ` Tom Tromey 2016-12-02 14:45 ` Pedro Alves 7 siblings, 1 reply; 50+ messages in thread From: Tom Tromey @ 2016-11-29 5:06 UTC (permalink / raw) To: gdb-patches; +Cc: Tom Tromey This changes dwarf2_evaluate_loc_desc_full to use value_freer. Note that this function previously called do_cleanup using the same cleanup multiple times. I had thought this was buggy, but re-reading make_my_cleanup2 indicates that it is not. Nevertheless it is surprising, and at least one of the calls (the one that is completely removed in this patch) seems to have been done under the assumption that it would still have some effect. 2016-11-28 Tom Tromey <tom@tromey.com> * value.h (value_freer::~value_freer): Call release. (value_freer::release): New method. * dwarf2loc.c (dwarf2_evaluate_loc_desc_full): Use value_freer. --- gdb/ChangeLog | 6 ++++++ gdb/dwarf2loc.c | 27 +++++++++++++-------------- gdb/value.h | 12 +++++++++++- 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 6197bfb..cf61306 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,11 @@ 2016-11-28 Tom Tromey <tom@tromey.com> + * value.h (value_freer::~value_freer): Call release. + (value_freer::release): New method. + * dwarf2loc.c (dwarf2_evaluate_loc_desc_full): Use value_freer. + +2016-11-28 Tom Tromey <tom@tromey.com> + * python/py-value.c (valpy_dereference, valpy_referenced_value) (valpy_reference_value, valpy_const_value, valpy_get_address) (valpy_get_dynamic_type, valpy_lazy_string, valpy_do_cast) diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c index 0d8a47c..43c95b8 100644 --- a/gdb/dwarf2loc.c +++ b/gdb/dwarf2loc.c @@ -2321,7 +2321,6 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, LONGEST byte_offset) { struct value *retval; - struct cleanup *value_chain; struct objfile *objfile = dwarf2_per_cu_objfile (per_cu); if (byte_offset < 0) @@ -2335,7 +2334,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, ctx.per_cu = per_cu; ctx.obj_address = 0; - value_chain = make_cleanup_value_free_to_mark (value_mark ()); + value_freer free_values; ctx.gdbarch = get_objfile_arch (objfile); ctx.addr_size = dwarf2_per_cu_addr_size (per_cu); @@ -2350,7 +2349,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, { if (ex.error == NOT_AVAILABLE_ERROR) { - do_cleanups (value_chain); + free_values.release (); retval = allocate_value (type); mark_value_bytes_unavailable (retval, 0, TYPE_LENGTH (type)); return retval; @@ -2359,7 +2358,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, { if (entry_values_debug) exception_print (gdb_stdout, ex); - do_cleanups (value_chain); + free_values.release (); return allocate_optimized_out_value (type); } else @@ -2382,7 +2381,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, ctx.addr_size, frame); /* We must clean up the value chain after creating the piece closure but before allocating the result. */ - do_cleanups (value_chain); + free_values.release (); retval = allocate_computed_value (type, &pieced_value_funcs, c); set_value_offset (retval, byte_offset); } @@ -2399,7 +2398,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, if (byte_offset != 0) error (_("cannot use offset on synthetic pointer to register")); - do_cleanups (value_chain); + free_values.release (); retval = value_from_register (type, gdb_regnum, frame); if (value_optimized_out (retval)) { @@ -2411,7 +2410,6 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, inspecting a register ($pc, $sp, etc.), return a generic optimized out value instead, so that we show <optimized out> instead of <not saved>. */ - do_cleanups (value_chain); tmp = allocate_value (type); value_contents_copy (tmp, 0, retval, 0, TYPE_LENGTH (type)); retval = tmp; @@ -2445,7 +2443,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, } address = value_as_address (value_from_pointer (ptr_type, address)); - do_cleanups (value_chain); + free_values.release (); retval = value_at_lazy (type, address + byte_offset); if (in_stack_memory) set_value_stack (retval, 1); @@ -2458,6 +2456,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, gdb_byte *contents; const gdb_byte *val_bytes; size_t n = TYPE_LENGTH (value_type (value)); + struct cleanup *cleanup; if (byte_offset + TYPE_LENGTH (type) > n) invalid_synthetic_pointer (); @@ -2470,8 +2469,8 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, to the mark, but we still need the value contents below. */ value_incref (value); - do_cleanups (value_chain); - make_cleanup_value_free (value); + free_values.release (); + cleanup = make_cleanup_value_free (value); retval = allocate_value (type); contents = value_contents_raw (retval); @@ -2484,6 +2483,8 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, n = TYPE_LENGTH (type); } memcpy (contents, val_bytes, n); + + do_cleanups (cleanup); } break; @@ -2496,7 +2497,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, if (byte_offset + TYPE_LENGTH (type) > n) invalid_synthetic_pointer (); - do_cleanups (value_chain); + free_values.release (); retval = allocate_value (type); contents = value_contents_raw (retval); @@ -2516,7 +2517,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, break; case DWARF_VALUE_OPTIMIZED_OUT: - do_cleanups (value_chain); + free_values.release (); retval = allocate_optimized_out_value (type); break; @@ -2532,8 +2533,6 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, set_value_initialized (retval, ctx.initialized); - do_cleanups (value_chain); - return retval; } diff --git a/gdb/value.h b/gdb/value.h index 399bf48..43dfe14 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -728,7 +728,17 @@ class value_freer ~value_freer () { - value_free_to_mark (m_value); + release (); + } + + /* Free the values currently on the value stack. */ + void release () + { + if (m_value != NULL) + { + value_free_to_mark (m_value); + m_value = NULL; + } } private: -- 2.7.4 ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 6/8] Use value_freer in dwarf2_evaluate_loc_desc_full 2016-11-29 5:06 ` [RFA 6/8] Use value_freer in dwarf2_evaluate_loc_desc_full Tom Tromey @ 2016-12-02 14:45 ` Pedro Alves 2016-12-13 13:29 ` Tom Tromey 0 siblings, 1 reply; 50+ messages in thread From: Pedro Alves @ 2016-12-02 14:45 UTC (permalink / raw) To: Tom Tromey, gdb-patches On 11/29/2016 05:05 AM, Tom Tromey wrote: > This changes dwarf2_evaluate_loc_desc_full to use value_freer. > > Note that this function previously called do_cleanup using the same > cleanup multiple times. I had thought this was buggy, but re-reading > make_my_cleanup2 indicates that it is not. Nevertheless it is > surprising, and at least one of the calls (the one that is completely > removed in this patch) seems to have been done under the assumption > that it would still have some effect. > > 2016-11-28 Tom Tromey <tom@tromey.com> > > * value.h (value_freer::~value_freer): Call release. > (value_freer::release): New method. > * dwarf2loc.c (dwarf2_evaluate_loc_desc_full): Use value_freer. > --- > gdb/ChangeLog | 6 ++++++ > gdb/dwarf2loc.c | 27 +++++++++++++-------------- > gdb/value.h | 12 +++++++++++- > 3 files changed, 30 insertions(+), 15 deletions(-) > > diff --git a/gdb/ChangeLog b/gdb/ChangeLog > index 6197bfb..cf61306 100644 > --- a/gdb/ChangeLog > +++ b/gdb/ChangeLog > @@ -1,5 +1,11 @@ > 2016-11-28 Tom Tromey <tom@tromey.com> > > + * value.h (value_freer::~value_freer): Call release. > + (value_freer::release): New method. > + * dwarf2loc.c (dwarf2_evaluate_loc_desc_full): Use value_freer. > + > +2016-11-28 Tom Tromey <tom@tromey.com> > + > * python/py-value.c (valpy_dereference, valpy_referenced_value) > (valpy_reference_value, valpy_const_value, valpy_get_address) > (valpy_get_dynamic_type, valpy_lazy_string, valpy_do_cast) > diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c > index 0d8a47c..43c95b8 100644 > --- a/gdb/dwarf2loc.c > +++ b/gdb/dwarf2loc.c > @@ -2321,7 +2321,6 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, > LONGEST byte_offset) > { > struct value *retval; > - struct cleanup *value_chain; > struct objfile *objfile = dwarf2_per_cu_objfile (per_cu); > > if (byte_offset < 0) > @@ -2335,7 +2334,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, > ctx.per_cu = per_cu; > ctx.obj_address = 0; > > - value_chain = make_cleanup_value_free_to_mark (value_mark ()); > + value_freer free_values; > > ctx.gdbarch = get_objfile_arch (objfile); > ctx.addr_size = dwarf2_per_cu_addr_size (per_cu); > @@ -2350,7 +2349,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, > { > if (ex.error == NOT_AVAILABLE_ERROR) > { > - do_cleanups (value_chain); > + free_values.release (); "release ()" looks potentially confusing to me, if you're in an "unique_ptr" mindset, where release means the opposite -- to stop managing. Can we call that something else? Maybe "free", since the class is called value_freer? Or "reset ()", following the naming used in the standard smart pointers? The latter could be naturally extended to support free_values.reset (value_mark ()); later too, if we need it. Thanks, Pedro Alves ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 6/8] Use value_freer in dwarf2_evaluate_loc_desc_full 2016-12-02 14:45 ` Pedro Alves @ 2016-12-13 13:29 ` Tom Tromey 2016-12-20 14:49 ` Pedro Alves 0 siblings, 1 reply; 50+ messages in thread From: Tom Tromey @ 2016-12-13 13:29 UTC (permalink / raw) To: Pedro Alves; +Cc: Tom Tromey, gdb-patches >>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes: Pedro> Or "reset ()", following the naming used in the standard smart pointers? I went with reset since I think "free" can be a macro sometimes. Or at least it could in C... not actually sure if C++ removed this possibility. Tom ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 6/8] Use value_freer in dwarf2_evaluate_loc_desc_full 2016-12-13 13:29 ` Tom Tromey @ 2016-12-20 14:49 ` Pedro Alves 2016-12-23 19:05 ` Tom Tromey 0 siblings, 1 reply; 50+ messages in thread From: Pedro Alves @ 2016-12-20 14:49 UTC (permalink / raw) To: Tom Tromey; +Cc: gdb-patches On 12/13/2016 01:28 PM, Tom Tromey wrote: >>>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes: > > Pedro> Or "reset ()", following the naming used in the standard smart pointers? > > I went with reset since I think "free" can be a macro sometimes. > Or at least it could in C... not actually sure if C++ removed this > possibility. I always assumed it has, but had never went looking for the specific wording. Looking at the C++14 draft N4140, I see: 17.6.1.2 - Headers: 5 - Names which are defined as macros in C shall be defined as macros in the C ++ standard library, even if C grants license for implementation as functions. [ Note: The names defined as macros in C include the following: assert, offsetof, setjmp, va_arg, va_end, and va_start. - end note ] 6 - Names that are defined as functions in C shall be defined as functions in the C ++ standard library." (175) And then footnote 175 clarifies: "175) This disallows the practice, allowed in C, of providing a masking macro in addition to the function prototype. The only way to achieve equivalent inline behavior in C ++ is to provide a definition as an extern inline function." So I think the answer is yes, C++ removes that possibility. BTW, I meanwhile realized that "release" would also be a naming/concept conflict with release_value / value_release_to_mark too. Really best to avoid it here. In pondering a bit more over this, I wonder whether adding a "scoped_" to go with scoped_restore etc., would make it a bit clearer to readers that this is a RAII type. Then also considering value_release_to_mark, I wonder would an API/naming like this: struct scoped_value_mark { scoped_value_mark () : m_value (value_mark ()) {} ~scoped_value_mark () { free_to_mark ()} void free_to_mark () { if (m_value) value_free_to_mark (m_value); } void release_to_mark () { if (m_value) value_release_to_mark (m_value); } /* Get the mark value. */ struct value *get () { return m_value; } }; Uses would look like: scoped_value_mark value_mark; ... value_mark.free_to_mark (); // some path than wants an explicit "free_to_mark". In eval.c:fetch_subexp_value we'd use it like: /* Evaluate the expression. */ scoped_value_mark mark; [...] result = evaluate_subexp (NULL_TYPE, exp, pc, EVAL_NORMAL); [...] new_mark = value_mark (); if (mark.get () == new_mark) return; /* Make sure it's not lazy, so that after the target stops again we have a non-lazy previous value to compare with. */ [...] if (val_chain) { /* Return the chain of intermediate values. We use this to decide which addresses to watch. */ *val_chain = new_mark; mark.release_to_mark (); } } Would this result in clearer client code? IMHO, yes, but WDYT? Thanks, Pedro Alves ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 6/8] Use value_freer in dwarf2_evaluate_loc_desc_full 2016-12-20 14:49 ` Pedro Alves @ 2016-12-23 19:05 ` Tom Tromey 2016-12-23 19:59 ` Tom Tromey 2016-12-23 19:59 ` Tom Tromey 0 siblings, 2 replies; 50+ messages in thread From: Tom Tromey @ 2016-12-23 19:05 UTC (permalink / raw) To: Pedro Alves; +Cc: Tom Tromey, gdb-patches >>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes: Pedro> In pondering a bit more over this, I wonder whether Pedro> adding a "scoped_" to go with scoped_restore etc., would make Pedro> it a bit clearer to readers that this is a RAII type. Then Pedro> also considering value_release_to_mark, I wonder would an Pedro> API/naming like this: [...] Pedro> Would this result in clearer client code? IMHO, yes, but WDYT? It looks good to me. I've made this change and I'll send the new patches soon. FYI I've only implemented the subset of the proposed API that was needed by the patches I have. Tom ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 6/8] Use value_freer in dwarf2_evaluate_loc_desc_full 2016-12-23 19:05 ` Tom Tromey @ 2016-12-23 19:59 ` Tom Tromey 2017-01-10 17:58 ` Pedro Alves 2016-12-23 19:59 ` Tom Tromey 1 sibling, 1 reply; 50+ messages in thread From: Tom Tromey @ 2016-12-23 19:59 UTC (permalink / raw) To: Tom Tromey; +Cc: Pedro Alves, gdb-patches Tom> It looks good to me. I've made this change and I'll send the new Tom> patches soon. Here's the new version of the patch to use scoped_value_mark in dwarf2_evaluate_loc_desc_full. Tom commit 63b869373e8dff9fd8648c00712459dd18a9798b Author: Tom Tromey <tom@tromey.com> Date: Mon Nov 21 21:04:59 2016 -0700 Use scoped_value_mark in dwarf2_evaluate_loc_desc_full This changes dwarf2_evaluate_loc_desc_full to use scoped_value_mark. Note that this function previously called do_cleanup using the same cleanup multiple times. I had thought this was buggy, but re-reading make_my_cleanup2 indicates that it is not. Nevertheless it is surprising, and at least one of the calls (the one that is completely removed in this patch) seems to have been done under the assumption that it would still have some effect. 2016-12-13 Tom Tromey <tom@tromey.com> * value.h (scoped_value_mark::~scoped_value_mark): Call free_to_mark. (scoped_value_mark::free_to_mark): New method. * dwarf2loc.c (dwarf2_evaluate_loc_desc_full): Use scoped_value_mark. diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 01ef9d6..d402851 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,13 @@ 2016-12-13 Tom Tromey <tom@tromey.com> + * value.h (scoped_value_mark::~scoped_value_mark): Call + free_to_mark. + (scoped_value_mark::free_to_mark): New method. + * dwarf2loc.c (dwarf2_evaluate_loc_desc_full): Use + scoped_value_mark. + +2016-12-13 Tom Tromey <tom@tromey.com> + * python/py-value.c (valpy_dereference, valpy_referenced_value) (valpy_reference_value, valpy_const_value, valpy_get_address) (valpy_get_dynamic_type, valpy_lazy_string, valpy_do_cast) diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c index f5ab371..6e36835 100644 --- a/gdb/dwarf2loc.c +++ b/gdb/dwarf2loc.c @@ -2283,7 +2283,6 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, LONGEST byte_offset) { struct value *retval; - struct cleanup *value_chain; struct objfile *objfile = dwarf2_per_cu_objfile (per_cu); if (byte_offset < 0) @@ -2297,7 +2296,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, ctx.per_cu = per_cu; ctx.obj_address = 0; - value_chain = make_cleanup_value_free_to_mark (value_mark ()); + scoped_value_mark free_values; ctx.gdbarch = get_objfile_arch (objfile); ctx.addr_size = dwarf2_per_cu_addr_size (per_cu); @@ -2312,7 +2311,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, { if (ex.error == NOT_AVAILABLE_ERROR) { - do_cleanups (value_chain); + free_values.free_to_mark (); retval = allocate_value (type); mark_value_bytes_unavailable (retval, 0, TYPE_LENGTH (type)); return retval; @@ -2321,7 +2320,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, { if (entry_values_debug) exception_print (gdb_stdout, ex); - do_cleanups (value_chain); + free_values.free_to_mark (); return allocate_optimized_out_value (type); } else @@ -2344,7 +2343,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, ctx.addr_size, frame); /* We must clean up the value chain after creating the piece closure but before allocating the result. */ - do_cleanups (value_chain); + free_values.free_to_mark (); retval = allocate_computed_value (type, &pieced_value_funcs, c); set_value_offset (retval, byte_offset); } @@ -2361,7 +2360,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, if (byte_offset != 0) error (_("cannot use offset on synthetic pointer to register")); - do_cleanups (value_chain); + free_values.free_to_mark (); retval = value_from_register (type, gdb_regnum, frame); if (value_optimized_out (retval)) { @@ -2373,7 +2372,6 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, inspecting a register ($pc, $sp, etc.), return a generic optimized out value instead, so that we show <optimized out> instead of <not saved>. */ - do_cleanups (value_chain); tmp = allocate_value (type); value_contents_copy (tmp, 0, retval, 0, TYPE_LENGTH (type)); retval = tmp; @@ -2407,7 +2405,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, } address = value_as_address (value_from_pointer (ptr_type, address)); - do_cleanups (value_chain); + free_values.free_to_mark (); retval = value_at_lazy (type, address + byte_offset); if (in_stack_memory) set_value_stack (retval, 1); @@ -2420,6 +2418,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, gdb_byte *contents; const gdb_byte *val_bytes; size_t n = TYPE_LENGTH (value_type (value)); + struct cleanup *cleanup; if (byte_offset + TYPE_LENGTH (type) > n) invalid_synthetic_pointer (); @@ -2432,8 +2431,8 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, to the mark, but we still need the value contents below. */ value_incref (value); - do_cleanups (value_chain); - make_cleanup_value_free (value); + free_values.free_to_mark (); + cleanup = make_cleanup_value_free (value); retval = allocate_value (type); contents = value_contents_raw (retval); @@ -2446,6 +2445,8 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, n = TYPE_LENGTH (type); } memcpy (contents, val_bytes, n); + + do_cleanups (cleanup); } break; @@ -2458,7 +2459,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, if (byte_offset + TYPE_LENGTH (type) > n) invalid_synthetic_pointer (); - do_cleanups (value_chain); + free_values.free_to_mark (); retval = allocate_value (type); contents = value_contents_raw (retval); @@ -2478,7 +2479,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, break; case DWARF_VALUE_OPTIMIZED_OUT: - do_cleanups (value_chain); + free_values.free_to_mark (); retval = allocate_optimized_out_value (type); break; @@ -2494,8 +2495,6 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, set_value_initialized (retval, ctx.initialized); - do_cleanups (value_chain); - return retval; } diff --git a/gdb/value.h b/gdb/value.h index 3a0641a..d261148 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -728,7 +728,17 @@ class scoped_value_mark ~scoped_value_mark () { - value_free_to_mark (m_value); + free_to_mark (); + } + + /* Free the values currently on the value stack. */ + void free_to_mark () + { + if (m_value != NULL) + { + value_free_to_mark (m_value); + m_value = NULL; + } } private: ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 6/8] Use value_freer in dwarf2_evaluate_loc_desc_full 2016-12-23 19:59 ` Tom Tromey @ 2017-01-10 17:58 ` Pedro Alves 0 siblings, 0 replies; 50+ messages in thread From: Pedro Alves @ 2017-01-10 17:58 UTC (permalink / raw) To: Tom Tromey; +Cc: gdb-patches On 12/23/2016 07:59 PM, Tom Tromey wrote: > Tom> It looks good to me. I've made this change and I'll send the new > Tom> patches soon. > > Here's the new version of the patch to use scoped_value_mark in > dwarf2_evaluate_loc_desc_full. OK. Thanks, Pedro Alves ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 6/8] Use value_freer in dwarf2_evaluate_loc_desc_full 2016-12-23 19:05 ` Tom Tromey 2016-12-23 19:59 ` Tom Tromey @ 2016-12-23 19:59 ` Tom Tromey 2017-01-10 17:57 ` Pedro Alves 1 sibling, 1 reply; 50+ messages in thread From: Tom Tromey @ 2016-12-23 19:59 UTC (permalink / raw) To: Tom Tromey; +Cc: Pedro Alves, gdb-patches >>>>> "Tom" == Tom Tromey <tom@tromey.com> writes: Tom> It looks good to me. I've made this change and I'll send the new Tom> patches soon. Here's the new patch to add scoped_value_mark. Tom commit 6f8663e26b0498790d3314f0649c5c9c923a48a0 Author: Tom Tromey <tom@tromey.com> Date: Mon Nov 21 18:02:11 2016 -0700 Add scoped_value_mark This adds a scoped_value_mark class, that records the value mark in the constructor and then calls value_free_to_mark in the destructor. It then updates various spots in gdb to use this class, rather than a cleanup. It would be better overall to replace "struct value *" with a shared_ptr, maybe eliminating the need for this class (watchpoints would perhaps need some new mechanism as well). However, that's difficult to do. 2016-12-13 Tom Tromey <tom@tromey.com> * python/py-value.c (valpy_dereference, valpy_referenced_value) (valpy_reference_value, valpy_const_value, valpy_get_address) (valpy_get_dynamic_type, valpy_lazy_string, valpy_do_cast) (valpy_getitem, valpy_call, valpy_binop_throw, valpy_negative) (valpy_absolute, valpy_richcompare_throw): Use scoped_value_mark. * dwarf2loc.c (dwarf2_loc_desc_get_symbol_read_needs): Use scoped_value_mark. * dwarf2-frame.c (execute_stack_op): Use scoped_value_mark. * value.h (scoped_value_mark): New class. diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 8d3c5b1..01ef9d6 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,17 @@ 2016-12-13 Tom Tromey <tom@tromey.com> + * python/py-value.c (valpy_dereference, valpy_referenced_value) + (valpy_reference_value, valpy_const_value, valpy_get_address) + (valpy_get_dynamic_type, valpy_lazy_string, valpy_do_cast) + (valpy_getitem, valpy_call, valpy_binop_throw, valpy_negative) + (valpy_absolute, valpy_richcompare_throw): Use scoped_value_mark. + * dwarf2loc.c (dwarf2_loc_desc_get_symbol_read_needs): Use + scoped_value_mark. + * dwarf2-frame.c (execute_stack_op): Use scoped_value_mark. + * value.h (scoped_value_mark): New class. + +2016-12-13 Tom Tromey <tom@tromey.com> + * dwarf2read.c (dwarf2_build_psymtabs): Use psymtab_discarder. * psympriv.h (make_cleanup_discard_psymtabs): Don't declare. * psymtab.c (discard_psymtabs_upto): Remove. diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c index beab304..93647ab 100644 --- a/gdb/dwarf2-frame.c +++ b/gdb/dwarf2-frame.c @@ -403,10 +403,9 @@ execute_stack_op (const gdb_byte *exp, ULONGEST len, int addr_size, CORE_ADDR initial, int initial_in_stack_memory) { CORE_ADDR result; - struct cleanup *old_chain; dwarf_expr_executor ctx; - old_chain = make_cleanup_value_free_to_mark (value_mark ()); + scoped_value_mark free_values; ctx.this_frame = this_frame; ctx.gdbarch = get_frame_arch (this_frame); @@ -430,8 +429,6 @@ execute_stack_op (const gdb_byte *exp, ULONGEST len, int addr_size, Not implemented: computing unwound register using explicit value operator")); } - do_cleanups (old_chain); - return result; } \f diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c index d19f6a2..f5ab371 100644 --- a/gdb/dwarf2loc.c +++ b/gdb/dwarf2loc.c @@ -2801,16 +2801,14 @@ dwarf2_loc_desc_get_symbol_read_needs (const gdb_byte *data, size_t size, struct dwarf2_per_cu_data *per_cu) { int in_reg; - struct cleanup *old_chain; struct objfile *objfile = dwarf2_per_cu_objfile (per_cu); + scoped_value_mark free_values; + symbol_needs_eval_context ctx; ctx.needs = SYMBOL_NEEDS_NONE; ctx.per_cu = per_cu; - - old_chain = make_cleanup_value_free_to_mark (value_mark ()); - ctx.gdbarch = get_objfile_arch (objfile); ctx.addr_size = dwarf2_per_cu_addr_size (per_cu); ctx.ref_addr_size = dwarf2_per_cu_ref_addr_size (per_cu); @@ -2831,8 +2829,6 @@ dwarf2_loc_desc_get_symbol_read_needs (const gdb_byte *data, size_t size, in_reg = 1; } - do_cleanups (old_chain); - if (in_reg) ctx.needs = SYMBOL_NEEDS_FRAME; return ctx.needs; diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c index c1f3e16..f7ec202 100644 --- a/gdb/python/py-value.c +++ b/gdb/python/py-value.c @@ -178,11 +178,10 @@ valpy_dereference (PyObject *self, PyObject *args) TRY { struct value *res_val; - struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); + scoped_value_mark free_values; res_val = value_ind (((value_object *) self)->value); result = value_to_value_object (res_val); - do_cleanups (cleanup); } CATCH (except, RETURN_MASK_ALL) { @@ -209,7 +208,7 @@ valpy_referenced_value (PyObject *self, PyObject *args) TRY { struct value *self_val, *res_val; - struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); + scoped_value_mark free_values; self_val = ((value_object *) self)->value; switch (TYPE_CODE (check_typedef (value_type (self_val)))) @@ -226,7 +225,6 @@ valpy_referenced_value (PyObject *self, PyObject *args) } result = value_to_value_object (res_val); - do_cleanups (cleanup); } CATCH (except, RETURN_MASK_ALL) { @@ -247,12 +245,10 @@ valpy_reference_value (PyObject *self, PyObject *args) TRY { struct value *self_val; - struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); + scoped_value_mark free_values; self_val = ((value_object *) self)->value; result = value_to_value_object (value_ref (self_val)); - - do_cleanups (cleanup); } CATCH (except, RETURN_MASK_ALL) { @@ -273,13 +269,11 @@ valpy_const_value (PyObject *self, PyObject *args) TRY { struct value *self_val, *res_val; - struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); + scoped_value_mark free_values; self_val = ((value_object *) self)->value; res_val = make_cv_value (1, 0, self_val); result = value_to_value_object (res_val); - - do_cleanups (cleanup); } CATCH (except, RETURN_MASK_ALL) { @@ -301,12 +295,10 @@ valpy_get_address (PyObject *self, void *closure) TRY { struct value *res_val; - struct cleanup *cleanup - = make_cleanup_value_free_to_mark (value_mark ()); + scoped_value_mark free_values; res_val = value_addr (val_obj->value); val_obj->address = value_to_value_object (res_val); - do_cleanups (cleanup); } CATCH (except, RETURN_MASK_ALL) { @@ -354,7 +346,7 @@ valpy_get_dynamic_type (PyObject *self, void *closure) TRY { struct value *val = obj->value; - struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); + scoped_value_mark free_values; type = value_type (val); type = check_typedef (type); @@ -387,8 +379,6 @@ valpy_get_dynamic_type (PyObject *self, void *closure) /* Re-use object's static type. */ type = NULL; } - - do_cleanups (cleanup); } CATCH (except, RETURN_MASK_ALL) { @@ -428,7 +418,7 @@ valpy_lazy_string (PyObject *self, PyObject *args, PyObject *kw) TRY { - struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); + scoped_value_mark free_values; if (TYPE_CODE (value_type (value)) == TYPE_CODE_PTR) value = value_ind (value); @@ -436,8 +426,6 @@ valpy_lazy_string (PyObject *self, PyObject *args, PyObject *kw) str_obj = gdbpy_create_lazy_string_object (value_address (value), length, user_encoding, value_type (value)); - - do_cleanups (cleanup); } CATCH (except, RETURN_MASK_ALL) { @@ -514,7 +502,7 @@ valpy_do_cast (PyObject *self, PyObject *args, enum exp_opcode op) { struct value *val = ((value_object *) self)->value; struct value *res_val; - struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); + scoped_value_mark free_values; if (op == UNOP_DYNAMIC_CAST) res_val = value_dynamic_cast (type, val); @@ -527,7 +515,6 @@ valpy_do_cast (PyObject *self, PyObject *args, enum exp_opcode op) } result = value_to_value_object (res_val); - do_cleanups (cleanup); } CATCH (except, RETURN_MASK_ALL) { @@ -737,8 +724,8 @@ valpy_getitem (PyObject *self, PyObject *key) TRY { struct value *tmp = self_value->value; - struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); struct value *res_val = NULL; + scoped_value_mark free_values; if (field) res_val = value_struct_elt (&tmp, NULL, field.get (), NULL, @@ -783,7 +770,6 @@ valpy_getitem (PyObject *self, PyObject *key) if (res_val) result = value_to_value_object (res_val); - do_cleanups (cleanup); } CATCH (ex, RETURN_MASK_ALL) { @@ -861,12 +847,11 @@ valpy_call (PyObject *self, PyObject *args, PyObject *keywords) TRY { - struct cleanup *cleanup = make_cleanup_value_free_to_mark (mark); + scoped_value_mark free_values; struct value *return_value; return_value = call_function_by_hand (function, args_count, vargs); result = value_to_value_object (return_value); - do_cleanups (cleanup); } CATCH (except, RETURN_MASK_ALL) { @@ -1014,11 +999,12 @@ valpy_binop_throw (enum valpy_opcode opcode, PyObject *self, PyObject *other) PyObject *result = NULL; struct value *arg1, *arg2; - struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); struct value *res_val = NULL; enum exp_opcode op = OP_NULL; int handled = 0; + scoped_value_mark free_values; + /* If the gdb.Value object is the second operand, then it will be passed to us as the OTHER argument, and SELF will be an entirely different kind of object, altogether. Because of this, we can't @@ -1026,17 +1012,11 @@ valpy_binop_throw (enum valpy_opcode opcode, PyObject *self, PyObject *other) python as well. */ arg1 = convert_value_from_python (self); if (arg1 == NULL) - { - do_cleanups (cleanup); - return NULL; - } + return NULL; arg2 = convert_value_from_python (other); if (arg2 == NULL) - { - do_cleanups (cleanup); - return NULL; - } + return NULL; switch (opcode) { @@ -1130,7 +1110,6 @@ valpy_binop_throw (enum valpy_opcode opcode, PyObject *self, PyObject *other) if (res_val) result = value_to_value_object (res_val); - do_cleanups (cleanup); return result; } @@ -1209,12 +1188,11 @@ valpy_negative (PyObject *self) TRY { /* Perhaps overkill, but consistency has some virtue. */ - struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); + scoped_value_mark free_values; struct value *val; val = value_neg (((value_object *) self)->value); result = value_to_value_object (val); - do_cleanups (cleanup); } CATCH (except, RETURN_MASK_ALL) { @@ -1239,12 +1217,10 @@ valpy_absolute (PyObject *self) TRY { - struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); + scoped_value_mark free_values; if (value_less (value, value_zero (value_type (value), not_lval))) isabs = 0; - - do_cleanups (cleanup); } CATCH (except, RETURN_MASK_ALL) { @@ -1362,15 +1338,14 @@ valpy_richcompare_throw (PyObject *self, PyObject *other, int op) int result; struct value *value_other; struct value *value_self; - struct value *mark = value_mark (); struct cleanup *cleanup; + scoped_value_mark free_values; + value_other = convert_value_from_python (other); if (value_other == NULL) return -1; - cleanup = make_cleanup_value_free_to_mark (mark); - value_self = ((value_object *) self)->value; switch (op) @@ -1403,7 +1378,6 @@ valpy_richcompare_throw (PyObject *self, PyObject *other, int op) break; } - do_cleanups (cleanup); return result; } diff --git a/gdb/value.h b/gdb/value.h index f776323..3a0641a 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -714,6 +714,28 @@ extern struct value *value_mark (void); extern void value_free_to_mark (const struct value *mark); +/* A helper class that uses value_mark at construction time and calls + value_free_to_mark in the destructor. This is used to clear out + temporary values created during the lifetime of this object. */ +class scoped_value_mark +{ + public: + + scoped_value_mark () + : m_value (value_mark ()) + { + } + + ~scoped_value_mark () + { + value_free_to_mark (m_value); + } + + private: + + const struct value *m_value; +}; + extern struct value *value_cstring (const char *ptr, ssize_t len, struct type *char_type); extern struct value *value_string (const char *ptr, ssize_t len, ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RFA 6/8] Use value_freer in dwarf2_evaluate_loc_desc_full 2016-12-23 19:59 ` Tom Tromey @ 2017-01-10 17:57 ` Pedro Alves 0 siblings, 0 replies; 50+ messages in thread From: Pedro Alves @ 2017-01-10 17:57 UTC (permalink / raw) To: Tom Tromey; +Cc: gdb-patches On 12/23/2016 07:58 PM, Tom Tromey wrote: >>>>>> "Tom" == Tom Tromey <tom@tromey.com> writes: > > Tom> It looks good to me. I've made this change and I'll send the new > Tom> patches soon. > > Here's the new patch to add scoped_value_mark. OK, thanks. Thanks, Pedro Alves ^ permalink raw reply [flat|nested] 50+ messages in thread
end of thread, other threads:[~2017-01-10 19:22 UTC | newest] Thread overview: 50+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2016-11-29 5:06 [RFA 0/8] C++-ification series #5 Tom Tromey 2016-11-29 5:06 ` [RFA 8/8] Add constructor and destructor to demangle_parse_info Tom Tromey 2016-12-02 15:04 ` Pedro Alves 2016-12-13 13:50 ` Tom Tromey 2016-11-29 5:06 ` [RFA 7/8] Use unique_xmalloc_ptr in execute_gdb_command Tom Tromey 2016-11-29 5:22 ` Tom Tromey 2016-12-15 3:49 ` Tom Tromey 2016-12-20 17:48 ` Pedro Alves 2016-12-20 18:13 ` Tom Tromey 2016-12-23 20:01 ` Tom Tromey 2017-01-10 17:59 ` Pedro Alves 2017-01-10 19:22 ` Tom Tromey 2016-12-20 23:31 ` Tom Tromey 2016-12-20 23:56 ` Pedro Alves 2016-12-22 14:50 ` Tom Tromey 2016-12-22 15:09 ` Pedro Alves 2016-12-22 15:29 ` Tom Tromey 2016-12-22 15:40 ` Pedro Alves 2016-12-02 14:49 ` Pedro Alves 2016-12-13 13:30 ` Tom Tromey 2016-11-29 5:06 ` [RFA 1/8] Add gdb_ref_ptr.h Tom Tromey 2016-12-02 13:08 ` Pedro Alves 2016-12-02 17:46 ` Tom Tromey 2016-12-02 18:11 ` Pedro Alves 2016-12-02 19:52 ` Tom Tromey 2016-12-02 23:45 ` Pedro Alves 2016-12-03 0:05 ` Pedro Alves 2016-12-13 13:13 ` Tom Tromey 2016-11-29 5:06 ` [RFA 3/8] Introduce and use gdb::unlinker Tom Tromey 2016-12-02 13:17 ` Pedro Alves 2016-11-29 5:06 ` [RFA 4/8] Remove make_cleanup_discard_psymtabs Tom Tromey 2016-12-02 14:21 ` Pedro Alves 2016-11-29 5:06 ` [RFA 5/8] Add value_freer Tom Tromey 2016-12-02 14:24 ` Pedro Alves 2016-11-29 5:06 ` [RFA 2/8] Use class to manage BFD reference counts Tom Tromey 2016-12-02 13:05 ` Pedro Alves 2016-12-13 13:26 ` Tom Tromey 2016-12-15 4:12 ` Tom Tromey 2016-12-20 18:18 ` Pedro Alves 2016-12-20 17:19 ` [pushed] gdb: Constify solib_find (Re: [RFA 2/8] Use class to manage BFD reference counts) Pedro Alves 2016-12-20 18:05 ` Tom Tromey 2016-11-29 5:06 ` [RFA 6/8] Use value_freer in dwarf2_evaluate_loc_desc_full Tom Tromey 2016-12-02 14:45 ` Pedro Alves 2016-12-13 13:29 ` Tom Tromey 2016-12-20 14:49 ` Pedro Alves 2016-12-23 19:05 ` Tom Tromey 2016-12-23 19:59 ` Tom Tromey 2017-01-10 17:58 ` Pedro Alves 2016-12-23 19:59 ` Tom Tromey 2017-01-10 17:57 ` Pedro Alves
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).