Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Joel Brobecker <brobecker@adacore.com>
To: Jan Kratochvil <jan.kratochvil@redhat.com>
Cc: Pedro Alves <palves@redhat.com>, Tom Tromey <tromey@redhat.com>,
	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.]"
Date: Wed, 16 May 2012 19:57:00 -0000	[thread overview]
Message-ID: <20120516195718.GA10253@adacore.com> (raw)
In-Reply-To: <20120515130851.GP10253@adacore.com>

[-- Attachment #1: Type: text/plain, Size: 1050 bytes --]

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

[-- Attachment #2: 0001-WIP.patch --]
[-- Type: text/x-diff, Size: 12550 bytes --]

From da06bff34e77513ee10b664e009cd0c871ad5f82 Mon Sep 17 00:00:00 2001
From: Joel Brobecker <brobecker@adacore.com>
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);
 \f
 
 /* 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 <http://www.gnu.org/licenses/>.  */
+
+#include <stdlib.h>
+
+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 <http://www.gnu.org/licenses/>.  */
+
+#include <stdlib.h>
+
+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 <http://www.gnu.org/licenses/>.  */
+
+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


  reply	other threads:[~2012-05-16 19:57 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-05-07 22:43 [RFC] choose symbol from given block's objfile first Joel Brobecker
2012-05-08 17:19 ` Tom Tromey
2012-05-09 19:05   ` [RFA] " Joel Brobecker
2012-05-09 19:08     ` Joel Brobecker
2012-05-09 20:15       ` Tom Tromey
2012-05-09 20:40         ` Joel Brobecker
2012-05-09 20:57           ` Tom Tromey
2012-05-09 21:06             ` Joel Brobecker
2012-05-10 13:42               ` Tom Tromey
2012-05-10 16:27                 ` checked in: " Joel Brobecker
2012-05-10 17:19               ` Joel Brobecker
2012-05-09 21:48       ` Joel Brobecker
2012-05-09 21:49         ` Joel Brobecker
2012-05-18 16:10           ` gdb.base/print-file-var.exp false PASS [Re: [RFA] choose symbol from given block's objfile first.] Jan Kratochvil
2012-05-18 17:17             ` Joel Brobecker
2012-05-18 17:37               ` Jan Kratochvil
2012-05-09 20:08     ` [RFA] choose symbol from given block's objfile first Tom Tromey
2012-05-11  7:26     ` Regression for gdb.fortran/library-module.exp [Re: [RFA] choose symbol from given block's objfile first.] Jan Kratochvil
2012-05-11 12:25       ` Joel Brobecker
2012-05-14 14:39       ` Joel Brobecker
2012-05-14 14:52         ` Jan Kratochvil
2012-05-14 15:06           ` Joel Brobecker
2012-05-14 15:15             ` Jan Kratochvil
2012-05-14 16:57               ` Joel Brobecker
2012-05-14 17:05                 ` Jan Kratochvil
2012-05-14 17:49           ` Pedro Alves
2012-05-14 17:59             ` Joel Brobecker
2012-05-14 18:07               ` Jan Kratochvil
2012-05-15 13:09                 ` Joel Brobecker
2012-05-16 19:57                   ` Joel Brobecker [this message]
2012-05-18 17:46                     ` RFC for: "Re: Regression for gdb.fortran/library-module.exp [Re: [RFA] choose symbol from given block's objfile first.]" Jan Kratochvil
2012-05-28 14:27                       ` Joel Brobecker
2012-05-28 16:12                         ` Jan Kratochvil
2012-05-29 15:44                           ` Joel Brobecker
2012-05-29 15:49                             ` Joel Brobecker
2012-05-29 15:56                             ` Jan Kratochvil
2012-05-29 16:02                               ` Joel Brobecker
2012-05-29 16:12                                 ` Jan Kratochvil
2012-05-29 16:31                                   ` Pedro Alves
2012-05-10 14:14 ` [RFC] choose symbol from given block's objfile first Pedro Alves
2012-05-10 14:32   ` Tom Tromey
2012-05-10 14:50     ` Matt Rice
2012-05-10 15:07       ` Pedro Alves

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20120516195718.GA10253@adacore.com \
    --to=brobecker@adacore.com \
    --cc=gdb-patches@sourceware.org \
    --cc=jan.kratochvil@redhat.com \
    --cc=palves@redhat.com \
    --cc=tromey@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox