From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20875 invoked by alias); 16 May 2012 19:57:49 -0000 Received: (qmail 20865 invoked by uid 22791); 16 May 2012 19:57:46 -0000 X-SWARE-Spam-Status: No, hits=-2.8 required=5.0 tests=AWL,BAYES_00,KAM_STOCKGEN,KHOP_RCVD_UNTRUST,RCVD_IN_HOSTKARMA_NO,RCVD_IN_HOSTKARMA_W,RCVD_IN_HOSTKARMA_WL,SUBJ_OBFU_PUNCT_FEW,TW_BJ X-Spam-Check-By: sourceware.org Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 16 May 2012 19:57:31 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id B3A901C6F91; Wed, 16 May 2012 15:57:30 -0400 (EDT) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 2OS5xqP+JZhV; Wed, 16 May 2012 15:57:30 -0400 (EDT) Received: from joel.gnat.com (localhost.localdomain [127.0.0.1]) by rock.gnat.com (Postfix) with ESMTP id 5D9371C6F90; Wed, 16 May 2012 15:57:30 -0400 (EDT) Received: by joel.gnat.com (Postfix, from userid 1000) id CFF29145616; Wed, 16 May 2012 12:57:18 -0700 (PDT) Date: Wed, 16 May 2012 19:57:00 -0000 From: Joel Brobecker To: Jan Kratochvil Cc: Pedro Alves , Tom Tromey , gdb-patches@sourceware.org Subject: RFC for: "Re: Regression for gdb.fortran/library-module.exp [Re: [RFA] choose symbol from given block's objfile first.]" Message-ID: <20120516195718.GA10253@adacore.com> References: <1336430581-11262-1-git-send-email-brobecker@adacore.com> <874nrqvbeh.fsf@fleche.redhat.com> <20120509190529.GI15555@adacore.com> <20120511072606.GA25458@host2.jankratochvil.net> <20120514143927.GB10253@adacore.com> <20120514145151.GA30451@host2.jankratochvil.net> <4FB1459E.60208@redhat.com> <20120514175913.GM10253@adacore.com> <20120514180624.GA16368@host2.jankratochvil.net> <20120515130851.GP10253@adacore.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="H+4ONPRPur6+Ovig" Content-Disposition: inline In-Reply-To: <20120515130851.GP10253@adacore.com> User-Agent: Mutt/1.5.20 (2009-06-14) Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2012-05/txt/msg00622.txt.bz2 --H+4ONPRPur6+Ovig Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-length: 1050 Hello everyone, Here is something that implements a compromise between the previous behavior, and the new behavior in terms of objfile search order. The gist of the patch is that it introduces an iterator that can take a "context" objfile into account for the iteration order. The rest are small adjustements to use the iterator. Long term, I think we are opening the door for more arch-dependency by adjusting the body of the iterator. I'll leave that part to someone else who's motivated (I think it's a can of worms). This patch assumes that my other patch has been reverted. This way, it allows us to start from the initial code, and see how I am changing it this time. It also includes a C testcase, which hopefully reproduces the same issue as gdb.fortran/library-module.exp, but in C, to widen the number of people testing this feature. For now, it's only a prototype, so I'm seeking comments. I will document the code when we're happy with the approach. Tested on x86_64-linux, no regression. Fixes the new testcase. Thanks, -- Joel --H+4ONPRPur6+Ovig Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0001-WIP.patch" Content-length: 12551 >From da06bff34e77513ee10b664e009cd0c871ad5f82 Mon Sep 17 00:00:00 2001 From: Joel Brobecker Date: Wed, 16 May 2012 11:33:26 -0700 Subject: [PATCH] WIP. --- gdb/findvar.c | 29 +++++++++- gdb/objfiles.c | 46 ++++++++++++++ gdb/objfiles.h | 8 +++ gdb/symtab.c | 104 ++++++++++++++++++++++---------- gdb/testsuite/gdb.base/cp-rel-lib.c | 29 +++++++++ gdb/testsuite/gdb.base/cp-rel-var.c | 36 +++++++++++ gdb/testsuite/gdb.base/cp-rel-var.exp | 48 +++++++++++++++ 7 files changed, 266 insertions(+), 34 deletions(-) create mode 100644 gdb/testsuite/gdb.base/cp-rel-lib.c create mode 100644 gdb/testsuite/gdb.base/cp-rel-var.c create mode 100644 gdb/testsuite/gdb.base/cp-rel-var.exp diff --git a/gdb/findvar.c b/gdb/findvar.c index 9009e6f..2f6fb29 100644 --- a/gdb/findvar.c +++ b/gdb/findvar.c @@ -406,6 +406,25 @@ symbol_read_needs_frame (struct symbol *sym) return 1; } +struct minsym_lookup_data +{ + const char *name; + struct minimal_symbol *result; +}; + +static int +minsym_lookup_iterator_cb (struct objfile *objfile, void *cb_data) +{ + struct minsym_lookup_data *data = (struct minsym_lookup_data *)cb_data; + + gdb_assert (data->result == NULL); + + data->result = lookup_minimal_symbol (data->name, NULL, objfile); + + /* The iterator should stop iff a match was found. */ + return (data->result != NULL); +} + /* A default implementation for the "la_read_var_value" hook in the language vector which should work in most situations. */ @@ -559,10 +578,18 @@ default_read_var_value (struct symbol *var, struct frame_info *frame) case LOC_UNRESOLVED: { + struct minsym_lookup_data lookup_data; struct minimal_symbol *msym; struct obj_section *obj_section; - msym = lookup_minimal_symbol (SYMBOL_LINKAGE_NAME (var), NULL, NULL); + memset (&lookup_data, 0, sizeof (lookup_data)); + lookup_data.name = SYMBOL_LINKAGE_NAME (var); + + iterate_over_objfiles_in_search_order (minsym_lookup_iterator_cb, + &lookup_data, + SYMBOL_SYMTAB (var)->objfile); + msym = lookup_data.result; + if (msym == NULL) error (_("No global symbol \"%s\"."), SYMBOL_LINKAGE_NAME (var)); if (overlay_debugging) diff --git a/gdb/objfiles.c b/gdb/objfiles.c index 8d9f8a5..8dffac5 100644 --- a/gdb/objfiles.c +++ b/gdb/objfiles.c @@ -1525,6 +1525,52 @@ gdb_bfd_unref (struct bfd *abfd) xfree (name); } +/* FIXME: Document. */ + +void +iterate_over_objfiles_in_search_order + (iterate_over_objfiles_in_search_order_cb cb, + void *cb_data, + struct objfile *context_objfile) +{ + int stop = 0; + struct objfile *objfile; + + if (context_objfile && context_objfile->flags & OBJF_MAINLINE) + { + stop = cb (context_objfile, cb_data); + if (stop) + return; + } + + ALL_OBJFILES (objfile) + { + if (objfile->flags & OBJF_MAINLINE && objfile != context_objfile) + { + stop = cb (objfile, cb_data); + if (stop) + return; + } + } + + if (context_objfile && !(context_objfile->flags & OBJF_MAINLINE)) + { + stop = cb (context_objfile, cb_data); + if (stop) + return; + } + + ALL_OBJFILES (objfile) + { + if (!(objfile->flags & OBJF_MAINLINE) && objfile != context_objfile) + { + stop = cb (objfile, cb_data); + if (stop) + return; + } + } +} + /* Provide a prototype to silence -Wmissing-prototypes. */ extern initialize_file_ftype _initialize_objfiles; diff --git a/gdb/objfiles.h b/gdb/objfiles.h index d5c807f..ca204db 100644 --- a/gdb/objfiles.h +++ b/gdb/objfiles.h @@ -525,6 +525,14 @@ extern void *objfile_data (struct objfile *objfile, extern struct bfd *gdb_bfd_ref (struct bfd *abfd); extern void gdb_bfd_unref (struct bfd *abfd); extern int gdb_bfd_close_or_warn (struct bfd *abfd); + +typedef int (*iterate_over_objfiles_in_search_order_cb) + (struct objfile *objfile, void *cb_data); + +extern void iterate_over_objfiles_in_search_order + (iterate_over_objfiles_in_search_order_cb cb, + void *cb_data, + struct objfile *context_objfile); /* Traverse all object files in the current program space. diff --git a/gdb/symtab.c b/gdb/symtab.c index 0ed42fd..2486c9a 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -1500,40 +1500,55 @@ lookup_global_symbol_from_objfile (const struct objfile *main_objfile, return NULL; } -/* Check to see if the symbol is defined in one of the symtabs. - BLOCK_INDEX should be either GLOBAL_BLOCK or STATIC_BLOCK, +/* Check to see if the symbol is defined in one of the OBJFILE's + symtabs. BLOCK_INDEX should be either GLOBAL_BLOCK or STATIC_BLOCK, depending on whether or not we want to search global symbols or static symbols. */ static struct symbol * +lookup_symbol_aux_objfile (struct objfile *objfile, int block_index, + const char *name, const domain_enum domain) +{ + struct symbol *sym = NULL; + struct blockvector *bv; + const struct block *block; + struct symtab *s; + + if (objfile->sf) + objfile->sf->qf->pre_expand_symtabs_matching (objfile, block_index, + name, domain); + + ALL_OBJFILE_SYMTABS (objfile, s) + if (s->primary) + { + bv = BLOCKVECTOR (s); + block = BLOCKVECTOR_BLOCK (bv, block_index); + sym = lookup_block_symbol (block, name, domain); + if (sym) + { + block_found = block; + return fixup_symbol_section (sym, objfile); + } + } + + return NULL; +} + +/* Same as lookup_symbol_aux_objfile, except that it searches all + objfiles. Return the first match found. */ + +static struct symbol * lookup_symbol_aux_symtabs (int block_index, const char *name, const domain_enum domain) { struct symbol *sym; struct objfile *objfile; - struct blockvector *bv; - const struct block *block; - struct symtab *s; ALL_OBJFILES (objfile) { - if (objfile->sf) - objfile->sf->qf->pre_expand_symtabs_matching (objfile, - block_index, - name, domain); - - ALL_OBJFILE_SYMTABS (objfile, s) - if (s->primary) - { - bv = BLOCKVECTOR (s); - block = BLOCKVECTOR_BLOCK (bv, block_index); - sym = lookup_block_symbol (block, name, domain); - if (sym) - { - block_found = block; - return fixup_symbol_section (sym, objfile); - } - } + sym = lookup_symbol_aux_objfile (objfile, block_index, name, domain); + if (sym) + return sym; } return NULL; @@ -1650,6 +1665,33 @@ lookup_symbol_static (const char *name, return NULL; } +struct global_sym_lookup_data +{ + const char *name; + domain_enum domain; + struct symbol *result; +}; + +static int +lookup_symbol_global_iterator_cb (struct objfile *objfile, + void *cb_data) +{ + struct global_sym_lookup_data *data = + (struct global_sym_lookup_data *) cb_data; + + gdb_assert (data->result == NULL); + + data->result = lookup_symbol_aux_objfile (objfile, GLOBAL_BLOCK, + data->name, data->domain); + if (data->result == NULL) + data->result = lookup_symbol_aux_quick (objfile, GLOBAL_BLOCK, + data->name, data->domain); + + /* If we found a match, tell the iterator to stop. Otherwise, + keep going. */ + return (data->result != NULL); +} + /* Lookup a symbol in all files' global blocks (searching psymtabs if necessary). */ @@ -1660,6 +1702,7 @@ lookup_symbol_global (const char *name, { struct symbol *sym = NULL; struct objfile *objfile = NULL; + struct global_sym_lookup_data lookup_data; /* Call library-specific lookup procedure. */ objfile = lookup_objfile_from_block (block); @@ -1668,18 +1711,13 @@ lookup_symbol_global (const char *name, if (sym != NULL) return sym; - sym = lookup_symbol_aux_symtabs (GLOBAL_BLOCK, name, domain); - if (sym != NULL) - return sym; + memset (&lookup_data, 0, sizeof (lookup_data)); + lookup_data.name = name; + lookup_data.domain = domain; + iterate_over_objfiles_in_search_order (lookup_symbol_global_iterator_cb, + &lookup_data, objfile); - ALL_OBJFILES (objfile) - { - sym = lookup_symbol_aux_quick (objfile, GLOBAL_BLOCK, name, domain); - if (sym) - return sym; - } - - return NULL; + return lookup_data.result; } int diff --git a/gdb/testsuite/gdb.base/cp-rel-lib.c b/gdb/testsuite/gdb.base/cp-rel-lib.c new file mode 100644 index 0000000..d2c6984 --- /dev/null +++ b/gdb/testsuite/gdb.base/cp-rel-lib.c @@ -0,0 +1,29 @@ +/* This testcase is part of GDB, the GNU debugger. + Copyright 2012 Free Software Foundation, Inc. + + 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 . */ + +#include + +int cp_rel_var = 1; + +int +get_cp_rel_var (void) +{ + if (cp_rel_var != 1) + abort (); + + cp_rel_var = 2; + return cp_rel_var; /* LIB_STOP */ +} diff --git a/gdb/testsuite/gdb.base/cp-rel-var.c b/gdb/testsuite/gdb.base/cp-rel-var.c new file mode 100644 index 0000000..fd7f751 --- /dev/null +++ b/gdb/testsuite/gdb.base/cp-rel-var.c @@ -0,0 +1,36 @@ +/* This testcase is part of GDB, the GNU debugger. + Copyright 2012 Free Software Foundation, Inc. + + 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 . */ + +#include + +int cp_rel_var; + +extern int get_cp_rel_var (void); + +int +main (void) +{ + int tmp; + + if (cp_rel_var != 1) + abort (); + + tmp = get_cp_rel_var (); + if (cp_rel_var != 2) /* VAR_STOP */ + abort (); + + return (tmp != cp_rel_var); +} diff --git a/gdb/testsuite/gdb.base/cp-rel-var.exp b/gdb/testsuite/gdb.base/cp-rel-var.exp new file mode 100644 index 0000000..aa99379 --- /dev/null +++ b/gdb/testsuite/gdb.base/cp-rel-var.exp @@ -0,0 +1,48 @@ +# Copyright 2012 Free Software Foundation, Inc. + +# 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 . */ + +set executable cp-rel-var + +set libsrc "${srcdir}/${subdir}/cp-rel-lib.c" +set libobj "${objdir}/${subdir}/libcp-rel-lib.so" +set libobj_opts { debug additional_flags=-fPIC } + +if { [gdb_compile_shlib $libsrc $libobj $libobj_opts ] != "" } { + return -1 +} + +if { [gdb_compile "${srcdir}/${subdir}/${executable}.c" \ + "${objdir}/${subdir}/${executable}" \ + executable \ + [list debug shlib=${libobj}]] + != ""} { + return -1 +} + +clean_restart $executable + +if ![runto_main] { + untested "could not run to main" + return -1 +} + +gdb_breakpoint $libsrc:[gdb_get_line_number "STOP" $libsrc] +gdb_continue_to_breakpoint "LIB_STOP" ".*LIB_STOP.*" +gdb_test "print cp_rel_var" " = 2" "print cp_rel_var from lib" + +gdb_breakpoint ${executable}.c:[gdb_get_line_number "STOP" ${executable}.c] +gdb_continue_to_breakpoint "VAR_STOP" ".*VAR_STOP.*" +gdb_test "print cp_rel_var" " = 2" "print cp_rel_var from main" + -- 1.7.1 --H+4ONPRPur6+Ovig--