Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [PING] [rfc]: Framework for looking up multiply defined global symbols  in shared libraries
@ 2007-05-10 12:33 Markus Deuling
  2007-05-10 13:00 ` Daniel Jacobowitz
  2007-05-14 18:25 ` Daniel Jacobowitz
  0 siblings, 2 replies; 24+ messages in thread
From: Markus Deuling @ 2007-05-10 12:33 UTC (permalink / raw)
  To: GDB Patches; +Cc: Ulrich Weigand

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

Hi,


this patch introduces a framework for looking up multiply defined global symbols 
from shared libraries. Solib handler like for example solib-svr4.c can now install a callback 
to implement a library-specific routine for looking up global symbols.


As an example I implemented a special lookup routine for ELF shared libraries
linked with -Bsymbolic. While the focus is within such a library, the global 
symbol lookup shall first search for the symbol within this library and then
go through the main executable if not found.

The patch also includes a testcase for this new feature. The testsuite
showed no regressions.

I would appreciate your comment on this patch. Would this be ok for mainline?
Thanks in advance.

ChangeLog:
	* cp-namespace.c (lookup_symbol_file): Add block
	to call for lookup_symbol_global.
	* Makefile.in (solist_h): Update dependencies.
	(solib.o): Likewise.
	(symtab.o): Likewise.
	* solib.c: New include "symtab.h".
	(solib_global_lookup): New function.
	* solib-svr4.c (has_SYMBOLIC): New function.
	(elf_lookup_lib_symbol): New function.
	(_initialize_svr4_solib): Add elf_lookup_lib_symbol
	to svr4_so_ops.
	* solist.h: New include "symtab.h".
	(target_so_ops): New member lookup_lib_global_symbol.
	(solib_global_lookup): Declare.
	* symtab.c: New include "solist.h".
	(lookup_objfile_from_block): New function.
	(lookup_global_symbol_from_objfile): New function.
	(basic_lookup_symbol_nonlocal): Add block to call
	for lookup_symbol_global.
	(lookup_symbol_global): Change lookup order. First
	call solib_global_lookup then lookup global symbol
	in both symtab and psymtab.
	* symtab.h (lookup_symbol_global): Add block to
	declaration.
	(lookup_objfile_from_block): Declare.
	(lookup_global_symbol_from_objfile): Declare.
	* gdb.base/libmd.c: New file for testcase.
	* gdb.base/libmd.h: Likewise.
	* gdb.base/solib_symbol.c: Likewise.
	* gdb.base/solib_symbol.exp: New testcase for
	multiply defined global symbol lookup.


-- 
Markus Deuling
GNU Toolchain for Linux on Cell BE
deuling@de.ibm.com


[-- Attachment #2: diff-gdb-multiple-symbols-mainline --]
[-- Type: text/plain, Size: 17094 bytes --]

diff -urN src/gdb/cp-namespace.c dev/gdb/cp-namespace.c
--- src/gdb/cp-namespace.c	2007-01-09 18:58:50.000000000 +0100
+++ dev/gdb/cp-namespace.c	2007-04-26 07:18:49.000000000 +0200
@@ -491,7 +491,7 @@
     }
   else
     {
-      sym = lookup_symbol_global (name, linkage_name, domain, symtab);
+      sym = lookup_symbol_global (name, linkage_name, block, domain, symtab);
     }
 
   if (sym != NULL)
diff -urN src/gdb/Makefile.in dev/gdb/Makefile.in
--- src/gdb/Makefile.in	2007-04-26 06:53:55.000000000 +0200
+++ dev/gdb/Makefile.in	2007-04-26 07:18:50.000000000 +0200
@@ -797,7 +797,7 @@
 solib_pa64_h = solib-pa64.h
 solib_som_h = solib-som.h
 solib_svr4_h = solib-svr4.h
-solist_h = solist.h
+solist_h = solist.h $(symtab_h)
 source_h = source.h
 sparc64_tdep_h = sparc64-tdep.h $(sparc_tdep_h)
 sparc_nat_h = sparc-nat.h
@@ -2574,7 +2574,7 @@
 	$(objfiles_h) $(exceptions_h) $(gdbcore_h) $(command_h) $(target_h) \
 	$(frame_h) $(gdb_regex_h) $(inferior_h) $(environ_h) $(language_h) \
 	$(gdbcmd_h) $(completer_h) $(filenames_h) $(exec_h) $(solist_h) \
-	$(observer_h) $(readline_h)
+	$(observer_h) $(readline_h) $(symtab_h)
 solib-frv.o: solib-frv.c $(defs_h) $(gdb_string_h) $(inferior_h) \
 	$(gdbcore_h) $(solist_h) $(frv_tdep_h) $(objfiles_h) $(symtab_h) \
 	$(language_h) $(command_h) $(gdbcmd_h) $(elf_frv_h) $(solib_h)
@@ -2721,7 +2721,8 @@
 	$(language_h) $(demangle_h) $(inferior_h) $(linespec_h) $(source_h) \
 	$(filenames_h) $(objc_lang_h) $(ada_lang_h) $(hashtab_h) \
 	$(gdb_obstack_h) $(block_h) $(dictionary_h) $(gdb_string_h) \
-	$(gdb_stat_h) $(cp_abi_h) $(observer_h) $(gdb_assert_h)
+	$(gdb_stat_h) $(cp_abi_h) $(observer_h) $(gdb_assert_h) \
+	$(solist_h)
 target.o: target.c $(defs_h) $(gdb_string_h) $(target_h) $(gdbcmd_h) \
 	$(symtab_h) $(inferior_h) $(bfd_h) $(symfile_h) $(objfiles_h) \
 	$(gdb_wait_h) $(dcache_h) $(regcache_h) $(gdb_assert_h) $(gdbcore_h) \
diff -urN src/gdb/solib.c dev/gdb/solib.c
--- src/gdb/solib.c	2007-01-09 18:58:58.000000000 +0100
+++ dev/gdb/solib.c	2007-04-26 07:18:50.000000000 +0200
@@ -45,6 +45,7 @@
 #include "solist.h"
 #include "observer.h"
 #include "readline/readline.h"
+#include "symtab.h"
 
 /* Architecture-specific operations.  */
 
@@ -945,6 +946,32 @@
 }
 
 
+/* Handler for library-specific lookup of global symbol
+   NAME in BLOCK.  Detect objfile corresponding to BLOCK
+   and call the library-specific handler if it is installed
+   for the current target.  */
+
+struct symbol *
+solib_global_lookup (const struct block *block,
+		     const char *name,
+		     const char *linkage_name,
+		     const domain_enum domain,
+		     struct symtab **symtab)
+{
+  struct objfile *objfile;
+
+  objfile = lookup_objfile_from_block (block);
+  if (objfile == NULL)
+    return NULL;
+
+  if (current_target_so_ops->lookup_lib_global_symbol != NULL)
+    return current_target_so_ops->lookup_lib_global_symbol (objfile,
+				name, linkage_name, domain, symtab);
+
+  return NULL;
+}
+
+
 extern initialize_file_ftype _initialize_solib; /* -Wmissing-prototypes */
 
 void
diff -urN src/gdb/solib-svr4.c dev/gdb/solib-svr4.c
--- src/gdb/solib-svr4.c	2007-04-16 13:51:29.000000000 +0200
+++ dev/gdb/solib-svr4.c	2007-04-26 07:18:50.000000000 +0200
@@ -378,6 +378,72 @@
 
  */
 
+/* Scan OBFD for a SYMBOLIC flag
+   in the .dynamic section. If it is set then
+   OBFD is a dso with a special rule for symbol
+   lookup. The lookup then starts in the dso before
+   searching in the executable.  */
+static int
+has_SYMBOLIC (bfd *obfd)
+{
+  CORE_ADDR dyn_ptr = 0;
+  int sect_size, arch_size;
+  gdb_byte *buf, *bufstart, *bufend, *p;
+  asection *sect;
+
+  if (obfd == NULL)
+    return -1;
+  arch_size = bfd_get_arch_size (obfd);
+  if (arch_size == -1)
+    return -1;
+
+  /* Retrieve information about .dynamic section.  */
+  sect = bfd_get_section_by_name (obfd, ".dynamic");
+  if (!sect)
+    return -1;
+
+  /* Read the .dynamic section.  */
+  sect_size = bfd_section_size (obfd, sect);
+  buf = alloca (sect_size);
+  if (!bfd_get_section_contents (obfd, sect,
+				 buf, 0, sect_size))
+    return -1;
+
+  if (arch_size == 32)
+    { /* 32-bit elf */
+      for (bufend = buf + sect_size;
+	   buf < bufend;
+	   buf += sizeof (Elf32_External_Dyn))
+	{
+	  Elf32_External_Dyn *x_dynp = (Elf32_External_Dyn *) buf;
+	  long dyn_tag;
+	  dyn_tag = extract_unsigned_integer ((gdb_byte *) x_dynp->d_tag, 4);
+	  if (dyn_tag == DT_NULL)
+	    break;
+	  else if (dyn_tag == DT_SYMBOLIC)
+	    return 1;
+	}
+    }
+  else
+    { /* 64-bit elf */
+      for (bufend = buf + sect_size;
+	   buf < bufend;
+	   buf += sizeof (Elf64_External_Dyn))
+	{
+	  Elf64_External_Dyn *x_dynp = (Elf64_External_Dyn *) buf;
+	  long dyn_tag;
+
+	  dyn_tag = extract_unsigned_integer ((gdb_byte *) x_dynp->d_tag, 8);
+	  if (dyn_tag == DT_NULL)
+	    break;
+	  else if (dyn_tag == DT_SYMBOLIC)
+	    return 1;
+	}
+    }
+
+  return 0;
+}
+
 static CORE_ADDR
 elf_locate_base (void)
 {
@@ -1558,6 +1624,24 @@
 
 static struct target_so_ops svr4_so_ops;
 
+/* Lookup global symbol for ELF dso's linked with -Bsymbolic.
+   Those dso's have a different rule for symbol lookup. The lookup
+   begins here in the dso, not in the main executable.  */
+
+static struct symbol *
+elf_lookup_lib_symbol (struct objfile *objfile,
+		       const char *name,
+		       const char *linkage_name,
+		       const domain_enum domain, struct symtab **symtab)
+{
+  if (objfile->obfd == NULL
+     || has_SYMBOLIC (objfile->obfd) != 1)
+    return NULL;
+
+  return  lookup_global_symbol_from_objfile
+		(objfile, name, linkage_name, domain, symtab);
+}
+
 extern initialize_file_ftype _initialize_svr4_solib; /* -Wmissing-prototypes */
 
 void
@@ -1573,6 +1657,7 @@
   svr4_so_ops.current_sos = svr4_current_sos;
   svr4_so_ops.open_symbol_file_object = open_symbol_file_object;
   svr4_so_ops.in_dynsym_resolve_code = svr4_in_dynsym_resolve_code;
+  svr4_so_ops.lookup_lib_global_symbol = elf_lookup_lib_symbol;
 
   /* FIXME: Don't do this here.  *_gdbarch_init() should set so_ops. */
   current_target_so_ops = &svr4_so_ops;
diff -urN src/gdb/solist.h dev/gdb/solist.h
--- src/gdb/solist.h	2007-01-09 18:58:58.000000000 +0100
+++ dev/gdb/solist.h	2007-04-26 07:18:50.000000000 +0200
@@ -23,6 +23,7 @@
 #define SOLIST_H
 
 #define SO_NAME_MAX_PATH_SIZE 512	/* FIXME: Should be dynamic */
+#include "symtab.h"
 
 /* Forward declaration for target specific link map information.  This
    struct is opaque to all but the target specific file.  */
@@ -103,7 +104,14 @@
        Convenience function for remote debuggers finding host libs.  */
     int (*find_and_open_solib) (char *soname,
         unsigned o_flags, char **temp_pathname);
-    
+
+    /* Hook for looking up global symbols in a library-specific way.  */
+    struct symbol * (*lookup_lib_global_symbol) (struct objfile *objfile,
+						 const char *name,
+						 const char *linkage_name,
+						 const domain_enum domain,
+						 struct symtab **symtab);
+
   };
 
 /* Free the memory associated with a (so_list *).  */
@@ -125,4 +133,13 @@
 #define TARGET_SO_IN_DYNSYM_RESOLVE_CODE \
   (current_target_so_ops->in_dynsym_resolve_code)
 
+/* Handler for library-specific global symbol lookup
+   in solib.c.  */
+struct symbol *
+solib_global_lookup (const struct block *block,
+		     const char *name,
+		     const char *linkage_name,
+		     const domain_enum domain,
+		     struct symtab **symtab);
+
 #endif
diff -urN src/gdb/symtab.c dev/gdb/symtab.c
--- src/gdb/symtab.c	2007-04-18 13:12:57.000000000 +0200
+++ dev/gdb/symtab.c	2007-04-26 07:18:50.000000000 +0200
@@ -57,6 +57,7 @@
 #include "cp-abi.h"
 #include "observer.h"
 #include "gdb_assert.h"
+#include "solist.h"
 
 /* Prototypes for local functions */
 
@@ -1265,6 +1266,44 @@
   return NULL;
 }
 
+/* Look up objfile to BLOCK.  */
+
+struct objfile *
+lookup_objfile_from_block (const struct block *block)
+{
+  struct objfile *obj = NULL;
+  struct blockvector *bv;
+  struct block *b;
+  struct symtab *s;
+  struct partial_symtab *ps;
+
+  if (block == NULL)
+    return NULL;
+
+  /* Go through SYMTABS.  */
+  ALL_SYMTABS (obj, s)
+  {
+    bv = BLOCKVECTOR (s);
+    b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+    if (BLOCK_START (b) <= BLOCK_START (block)
+	&& BLOCK_END (b) > BLOCK_START (block))
+      return obj;
+  }
+
+  /* Go through PSYMTABS.  */
+  ALL_PSYMTABS (obj, ps)
+  {
+    s = PSYMTAB_TO_SYMTAB (ps);
+    bv = BLOCKVECTOR (s);
+    b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+    if (BLOCK_START (b) <= BLOCK_START (block)
+	&& BLOCK_END (b) > BLOCK_START (block))
+      return obj;
+  }
+
+  return NULL;
+}
+
 /* Look up a symbol in a block; if found, locate its symtab, fixup the
    symbol, and set block_found appropriately.  */
 
@@ -1306,6 +1345,57 @@
   return NULL;
 }
 
+/* Check all global symbols in OBJFILE in symtabs and
+   psymtabs.  */
+
+struct symbol *
+lookup_global_symbol_from_objfile (struct objfile *objfile,
+				   const char *name,
+				   const char *linkage_name,
+				   const domain_enum domain,
+				   struct symtab **symtab)
+{
+  struct symbol *sym;
+  struct blockvector *bv;
+  const struct block *block;
+  struct symtab *s;
+  struct partial_symtab *ps;
+
+  /* Go through symtabs.  */
+  ALL_OBJFILE_SYMTABS (objfile, s)
+  {
+    bv = BLOCKVECTOR (s);
+    block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+    sym = lookup_block_symbol (block, name, linkage_name, domain);
+    if (sym)
+      {
+	block_found = block;
+	if (symtab != NULL)
+	  *symtab = s;
+	return fixup_symbol_section (sym, objfile);
+      }
+  }
+
+  /* Now go through psymtabs.  */
+  ALL_OBJFILE_PSYMTABS (objfile, ps)
+  {
+    if (!ps->readin
+	&& lookup_partial_symbol (ps, name, linkage_name,
+				  1, domain))
+      {
+	s = PSYMTAB_TO_SYMTAB (ps);
+	bv = BLOCKVECTOR (s);
+	block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+	sym = lookup_block_symbol (block, name, linkage_name, domain);
+	if (symtab != NULL)
+	  *symtab = s;
+	return fixup_symbol_section (sym, 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,
    depending on whether or not we want to search global symbols or
@@ -1571,7 +1661,7 @@
   if (sym != NULL)
     return sym;
 
-  return lookup_symbol_global (name, linkage_name, domain, symtab);
+  return lookup_symbol_global (name, linkage_name, block, domain, symtab);
 }
 
 /* Lookup a symbol in the static block associated to BLOCK, if there
@@ -1599,18 +1689,28 @@
 struct symbol *
 lookup_symbol_global (const char *name,
 		      const char *linkage_name,
+		      const struct block *block,
 		      const domain_enum domain,
 		      struct symtab **symtab)
 {
   struct symbol *sym;
+  struct objfile *objfile;
 
-  sym = lookup_symbol_aux_symtabs (GLOBAL_BLOCK, name, linkage_name,
-				   domain, symtab);
+  /* Call library-specific lookup procedure.  */
+  sym = solib_global_lookup (block, name, linkage_name, domain, symtab);
   if (sym != NULL)
     return sym;
 
-  return lookup_symbol_aux_psymtabs (GLOBAL_BLOCK, name, linkage_name,
-				     domain, symtab);
+  /* Lookup global symbol in all objfiles in symtab and psymtab.  */
+  ALL_OBJFILES (objfile)
+  {
+    sym = lookup_global_symbol_from_objfile (objfile, name, linkage_name,
+					     domain, symtab);
+    if (sym != NULL)
+      return sym;
+  }
+
+  return NULL;
 }
 
 /* Look, in partial_symtab PST, for symbol whose natural name is NAME.
diff -urN src/gdb/symtab.h dev/gdb/symtab.h
--- src/gdb/symtab.h	2007-03-28 05:42:54.000000000 +0200
+++ dev/gdb/symtab.h	2007-04-26 07:18:50.000000000 +0200
@@ -1050,6 +1050,7 @@
 
 extern struct symbol *lookup_symbol_global (const char *name,
 					    const char *linkage_name,
+					    const struct block *block,
 					    const domain_enum domain,
 					    struct symtab **symtab);
 
@@ -1403,4 +1404,17 @@
    Defined in symtab.c, used in hppa-tdep.c. */
 extern int deprecated_hp_som_som_object_present;
 
+/* Lookup objfile to a block.  */
+extern struct objfile *
+lookup_objfile_from_block (const struct block *block);
+
+/* Check global symbols in objfile.  */
+struct symbol *
+lookup_global_symbol_from_objfile (struct objfile *objfile,
+				   const char *name,
+				   const char *linkage_name,
+				   const domain_enum domain,
+				   struct symtab **symtab);
+
+
 #endif /* !defined(SYMTAB_H) */
diff -urN src/gdb/testsuite/gdb.base/libmd.c dev/gdb/testsuite/gdb.base/libmd.c
--- src/gdb/testsuite/gdb.base/libmd.c	1970-01-01 01:00:00.000000000 +0100
+++ dev/gdb/testsuite/gdb.base/libmd.c	2007-04-26 07:18:50.000000000 +0200
@@ -0,0 +1,18 @@
+#include <stdio.h>
+#include "libmd.h"
+
+void foo2 ();
+
+void
+foo ()
+{
+  printf ("foo in lib\n");
+  return;
+}
+
+void
+foo2()
+{
+  printf ("foo2 in lib\n");
+  return;
+}
diff -urN src/gdb/testsuite/gdb.base/libmd.h dev/gdb/testsuite/gdb.base/libmd.h
--- src/gdb/testsuite/gdb.base/libmd.h	1970-01-01 01:00:00.000000000 +0100
+++ dev/gdb/testsuite/gdb.base/libmd.h	2007-04-26 07:18:50.000000000 +0200
@@ -0,0 +1 @@
+extern void foo();
diff -urN src/gdb/testsuite/gdb.base/solib_symbol.c dev/gdb/testsuite/gdb.base/solib_symbol.c
--- src/gdb/testsuite/gdb.base/solib_symbol.c	1970-01-01 01:00:00.000000000 +0100
+++ dev/gdb/testsuite/gdb.base/solib_symbol.c	2007-04-26 07:18:50.000000000 +0200
@@ -0,0 +1,27 @@
+#include <stdio.h>
+#include "libmd.h"
+
+extern void foo();
+void foo3();
+void foo2();
+
+int main ()
+{
+  printf ("in main\n");
+  foo ();
+  foo3 ();
+  return 0;
+}
+
+void foo3()
+{
+  printf ("foo3 in main\n");
+  return;
+}
+
+void foo2()
+{
+  printf ("foo2 in main\n");
+  return;
+}
+
diff -urN src/gdb/testsuite/gdb.base/solib_symbol.exp dev/gdb/testsuite/gdb.base/solib_symbol.exp
--- src/gdb/testsuite/gdb.base/solib_symbol.exp	1970-01-01 01:00:00.000000000 +0100
+++ dev/gdb/testsuite/gdb.base/solib_symbol.exp	2007-04-26 07:18:50.000000000 +0200
@@ -0,0 +1,110 @@
+# Copyright 2007 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 2 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+#
+# Contributed by Markus Deuling <deuling@de.ibm.com>.
+#
+
+set prms_id 0
+set bug_id 0
+set timeout 5
+
+if { [istarget "spu-*"] } then {
+  unsupported "Skipping shared libraries testcase."
+  return -1
+}
+
+# Library file.
+set libfile "libmd"
+set srcfile_lib ${libfile}.c
+set binfile_lib ${objdir}/${subdir}/${libfile}.so
+# Binary file.
+set testfile "solib_symbol"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+# Build a solib with -Bsymbolic.
+set compile_flags {debug}
+set compile_flags "$compile_flags additional_flags=-fPIC"
+set compile_flags "$compile_flags additional_flags=-Wl,-Bsymbolic"
+set compile_flags "$compile_flags additional_flags=-shared"
+set sources ${srcdir}/${subdir}/${srcfile_lib}
+if { [gdb_compile $sources ${binfile_lib} executable $compile_flags] != "" } {
+  return -1
+}
+
+# Build binary.
+set compile_flags {debug}
+set compile_flags "$compile_flags additional_flags=-L${objdir}/${subdir}/"
+set compile_flags "$compile_flags additional_flags=-Wl,-rpath=${objdir}/${subdir}/"
+set compile_flags "$compile_flags additional_flags=-lmd"
+set sources ${srcdir}/${subdir}/${srcfile}
+if { [gdb_compile $sources ${binfile} executable $compile_flags] != "" } {
+  return -1
+}
+
+if [get_compiler_info ${binfile}] {
+  return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] then {
+  fail "Can't run to main"
+  return 0
+}
+
+# Set a breakpoint in the binary.
+gdb_test "br foo2" \
+	 "Breakpoint.*file.*${srcdir}/${subdir}/${srcfile}.*" \
+	 "foo2 in main"
+
+# Delete all breakpoints.
+send_gdb "delete breakpoints\n"
+gdb_expect {
+  -re "Delete.*all.*breakpoints.*\(y or n\).*" {
+    send_gdb "y\n"
+    gdb_expect {
+      -re "$gdb_prompt.*" { pass "Delete all breakpoints" }
+      timeout             { fail "Delete all breakpoints (timeout)" }
+    }
+  }
+  -re "$gdb_prompt"       { fail "Delete all breakpoints" }
+  timeout                 { fail "Delete all breakpoints (timeout)" }
+}
+
+
+# Break in the library.
+gdb_test "br foo" \
+	 "" \
+	 "foo in libmd"
+
+gdb_test "continue" \
+	 "Continuing.*" \
+	 "continue"
+
+# This symbol is now looked up in the ELF library.
+gdb_test "br foo2" \
+	 "Breakpoint.*file.*${srcdir}/${subdir}/${srcfile_lib}.*" \
+	 "foo2 in mdlib"
+
+
+gdb_exit
+
+return 0
+
+


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PING] [rfc]: Framework for looking up multiply defined global  symbols  in shared libraries
  2007-05-10 12:33 [PING] [rfc]: Framework for looking up multiply defined global symbols in shared libraries Markus Deuling
@ 2007-05-10 13:00 ` Daniel Jacobowitz
  2007-05-10 14:52   ` Markus Deuling
  2007-05-14 18:25 ` Daniel Jacobowitz
  1 sibling, 1 reply; 24+ messages in thread
From: Daniel Jacobowitz @ 2007-05-10 13:00 UTC (permalink / raw)
  To: Markus Deuling; +Cc: GDB Patches, Ulrich Weigand

On Thu, May 10, 2007 at 02:32:10PM +0200, Markus Deuling wrote:
> Hi,
> 
> 
> this patch introduces a framework for looking up multiply defined global 
> symbols from shared libraries. Solib handler like for example solib-svr4.c can 
> now install a callback to implement a library-specific routine for looking up 
> global symbols.
> 
> 
> As an example I implemented a special lookup routine for ELF shared libraries
> linked with -Bsymbolic. While the focus is within such a library, the global 
> symbol lookup shall first search for the symbol within this library and then
> go through the main executable if not found.

Is this the point of the patch, or just an example?  I mean, what else
would you use this for besides -Bsymbolic?

There's some benefit to looking up the right symbol, e.g. for "print
foo()".  But for breakpoints, I still think the way to go is to
breakpoint all functions with the same name and/or allow the user to
specify a copy explicitly (apparently DBX does the latter).

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PING] [rfc]: Framework for looking up multiply defined global   symbols  in shared libraries
  2007-05-10 13:00 ` Daniel Jacobowitz
@ 2007-05-10 14:52   ` Markus Deuling
  2007-05-14 17:53     ` Daniel Jacobowitz
  0 siblings, 1 reply; 24+ messages in thread
From: Markus Deuling @ 2007-05-10 14:52 UTC (permalink / raw)
  To: Daniel Jacobowitz, GDB Patches; +Cc: Ulrich Weigand

Daniel Jacobowitz wrote:
>> As an example I implemented a special lookup routine for ELF shared libraries
>> linked with -Bsymbolic. While the focus is within such a library, the global 
>> symbol lookup shall first search for the symbol within this library and then
>> go through the main executable if not found.
> 
> Is this the point of the patch, or just an example?  I mean, what else
> would you use this for besides -Bsymbolic?
> 
> There's some benefit to looking up the right symbol, e.g. for "print
> foo()".  But for breakpoints, I still think the way to go is to
> breakpoint all functions with the same name and/or allow the user to
> specify a copy explicitly (apparently DBX does the latter).
> 

The lookup for the '-Bsymbolic' library is just one example.

ELF says that the symbol resolution algorithm for that kind of library shall start
within the library instead of the main executable. If this lookup fails the "normal"
lookup starting in the main executable shall take place.

There'll be another patch using that lookup framework for the combined debugger for Cell.
If GDB debugs a Cell binary and stands in a SPU thread (which GDB thinks of as a library) 
then the lookup of a symbol would prefer the symbol in the main executable (in the PPE thread)
if available. The second patch using that framework makes sure that a symbol lookup within
a SPU thread prefers symbols from that SPU thread.

This framework also makes it possible for other library handlers (sorry, I don't know any examples now) to 
install their own callbacks if the want to have own algorithms for symbol lookup.


-- 
Markus Deuling
GNU Toolchain for Linux on Cell BE
deuling@de.ibm.com


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PING] [rfc]: Framework for looking up multiply defined global  symbols  in shared libraries
  2007-05-10 14:52   ` Markus Deuling
@ 2007-05-14 17:53     ` Daniel Jacobowitz
  0 siblings, 0 replies; 24+ messages in thread
From: Daniel Jacobowitz @ 2007-05-14 17:53 UTC (permalink / raw)
  To: Markus Deuling; +Cc: GDB Patches, Ulrich Weigand

On Thu, May 10, 2007 at 04:51:11PM +0200, Markus Deuling wrote:
> The lookup for the '-Bsymbolic' library is just one example.
> 
> ELF says that the symbol resolution algorithm for that kind of library shall 
> start
> within the library instead of the main executable. If this lookup fails the 
> "normal"
> lookup starting in the main executable shall take place.

Supporting -Bsymbolic this way seems like a nice idea.

> There'll be another patch using that lookup framework for the combined debugger 
> for Cell.
> If GDB debugs a Cell binary and stands in a SPU thread (which GDB thinks of as 
> a library) then the lookup of a symbol would prefer the symbol in the main 
> executable (in the PPE thread)
> if available. The second patch using that framework makes sure that a symbol 
> lookup within
> a SPU thread prefers symbols from that SPU thread.

OK, we can talk about this a little later when GDB is ready to handle
two architectures at once.

I'll look at the patch.  I was really hoping someone else would; I
need help with patch review.

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PING] [rfc]: Framework for looking up multiply defined global  symbols  in shared libraries
  2007-05-10 12:33 [PING] [rfc]: Framework for looking up multiply defined global symbols in shared libraries Markus Deuling
  2007-05-10 13:00 ` Daniel Jacobowitz
@ 2007-05-14 18:25 ` Daniel Jacobowitz
  2007-05-15  5:49   ` Markus Deuling
  1 sibling, 1 reply; 24+ messages in thread
From: Daniel Jacobowitz @ 2007-05-14 18:25 UTC (permalink / raw)
  To: Markus Deuling; +Cc: GDB Patches, Ulrich Weigand

On Thu, May 10, 2007 at 02:32:10PM +0200, Markus Deuling wrote:
> @@ -945,6 +946,32 @@
>  }
>  
>  
> +/* Handler for library-specific lookup of global symbol
> +   NAME in BLOCK.  Detect objfile corresponding to BLOCK
> +   and call the library-specific handler if it is installed
> +   for the current target.  */
> +
> +struct symbol *
> +solib_global_lookup (const struct block *block,
> +		     const char *name,
> +		     const char *linkage_name,
> +		     const domain_enum domain,
> +		     struct symtab **symtab)

Since all this does with the block is convert it to an objfile, it
should probably be passed an objfile instead of a block.

> diff -urN src/gdb/solib-svr4.c dev/gdb/solib-svr4.c
> --- src/gdb/solib-svr4.c	2007-04-16 13:51:29.000000000 +0200
> +++ dev/gdb/solib-svr4.c	2007-04-26 07:18:50.000000000 +0200
> @@ -378,6 +378,72 @@
>  
>   */
>  
> +/* Scan OBFD for a SYMBOLIC flag
> +   in the .dynamic section. If it is set then
> +   OBFD is a dso with a special rule for symbol
> +   lookup. The lookup then starts in the dso before
> +   searching in the executable.  */

Could you wrap comments around 72 columns (or 79 if you prefer)
instead of this short?  It's harder to read in my humble opinion.

Also, DSO is an acronym so it should be capitalized, and please use
two spaces between each sentence.

> @@ -125,4 +133,13 @@
>  #define TARGET_SO_IN_DYNSYM_RESOLVE_CODE \
>    (current_target_so_ops->in_dynsym_resolve_code)
>  
> +/* Handler for library-specific global symbol lookup
> +   in solib.c.  */
> +struct symbol *
> +solib_global_lookup (const struct block *block,
> +		     const char *name,
> +		     const char *linkage_name,
> +		     const domain_enum domain,
> +		     struct symtab **symtab);
> +

Since this is a prototype, not a definition, the function name should
not be on its own line; grep "^solib_global_lookup" should find only
the definition.

> @@ -1265,6 +1266,44 @@
>    return NULL;
>  }
>  
> +/* Look up objfile to BLOCK.  */
> +
> +struct objfile *
> +lookup_objfile_from_block (const struct block *block)
> +{
> +  struct objfile *obj = NULL;
> +  struct blockvector *bv;
> +  struct block *b;
> +  struct symtab *s;
> +  struct partial_symtab *ps;
> +
> +  if (block == NULL)
> +    return NULL;
> +
> +  /* Go through SYMTABS.  */
> +  ALL_SYMTABS (obj, s)
> +  {
> +    bv = BLOCKVECTOR (s);
> +    b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
> +    if (BLOCK_START (b) <= BLOCK_START (block)
> +	&& BLOCK_END (b) > BLOCK_START (block))
> +      return obj;
> +  }
> +
> +  /* Go through PSYMTABS.  */
> +  ALL_PSYMTABS (obj, ps)
> +  {
> +    s = PSYMTAB_TO_SYMTAB (ps);
> +    bv = BLOCKVECTOR (s);
> +    b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
> +    if (BLOCK_START (b) <= BLOCK_START (block)
> +	&& BLOCK_END (b) > BLOCK_START (block))
> +      return obj;
> +  }
> +
> +  return NULL;
> +}

There's a much easier way to do this.  Use "block = block_global_block
(block);" at the top, and then compare for equality with
BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK).  You don't need to check the
psymtabs; if it's not already read in, then we wouldn't have read in
BLOCK either, which is impossible.

> @@ -1599,18 +1689,28 @@
>  struct symbol *
>  lookup_symbol_global (const char *name,
>  		      const char *linkage_name,
> +		      const struct block *block,
>  		      const domain_enum domain,
>  		      struct symtab **symtab)
>  {
>    struct symbol *sym;
> +  struct objfile *objfile;
>  
> -  sym = lookup_symbol_aux_symtabs (GLOBAL_BLOCK, name, linkage_name,
> -				   domain, symtab);
> +  /* Call library-specific lookup procedure.  */
> +  sym = solib_global_lookup (block, name, linkage_name, domain, symtab);
>    if (sym != NULL)
>      return sym;
>  
> -  return lookup_symbol_aux_psymtabs (GLOBAL_BLOCK, name, linkage_name,
> -				     domain, symtab);
> +  /* Lookup global symbol in all objfiles in symtab and psymtab.  */
> +  ALL_OBJFILES (objfile)
> +  {
> +    sym = lookup_global_symbol_from_objfile (objfile, name, linkage_name,
> +					     domain, symtab);
> +    if (sym != NULL)
> +      return sym;
> +  }
> +
> +  return NULL;
>  }
>  
>  /* Look, in partial_symtab PST, for symbol whose natural name is NAME.

Why change the search order?  If you do this, you'll find a static
symbol in the second objfile when you should have found a global
symbol in the third objfile first.

> +/* Lookup objfile to a block.  */
> +extern struct objfile *
> +lookup_objfile_from_block (const struct block *block);
> +
> +/* Check global symbols in objfile.  */
> +struct symbol *
> +lookup_global_symbol_from_objfile (struct objfile *objfile,
> +				   const char *name,
> +				   const char *linkage_name,
> +				   const domain_enum domain,
> +				   struct symtab **symtab);

Same comment about formatting.

> diff -urN src/gdb/testsuite/gdb.base/libmd.c dev/gdb/testsuite/gdb.base/libmd.c
> --- src/gdb/testsuite/gdb.base/libmd.c	1970-01-01 01:00:00.000000000 +0100
> +++ dev/gdb/testsuite/gdb.base/libmd.c	2007-04-26 07:18:50.000000000 +0200
> @@ -0,0 +1,18 @@
> +#include <stdio.h>
> +#include "libmd.h"

All test files should get copyright notices, please, unless it would
invalidate whatever is being tested.

> +set prms_id 0
> +set bug_id 0

I think it's safe to omit these.

> +set timeout 5

And please don't adjust the timeout :-)

> +if { [istarget "spu-*"] } then {
> +  unsupported "Skipping shared libraries testcase."
> +  return -1
> +}

Please use skip_shlib_tests instead.  You will probably also need to
exclude a list of targets where -Bsymbolic won't work.

(I realize skip_shlib_tests doesn't exist yet.  Gimme a day or so and
it will, I'll be working on those patches next.)

> +# Build a solib with -Bsymbolic.
> +set compile_flags {debug}
> +set compile_flags "$compile_flags additional_flags=-fPIC"
> +set compile_flags "$compile_flags additional_flags=-Wl,-Bsymbolic"
> +set compile_flags "$compile_flags additional_flags=-shared"
> +set sources ${srcdir}/${subdir}/${srcfile_lib}
> +if { [gdb_compile $sources ${binfile_lib} executable $compile_flags] != "" } {
> +  return -1
> +}

There's a gdb_compile_shlib; if you use that, you won't need to handle
-fPIC or -shared.

> +# Build binary.
> +set compile_flags {debug}
> +set compile_flags "$compile_flags additional_flags=-L${objdir}/${subdir}/"
> +set compile_flags "$compile_flags additional_flags=-Wl,-rpath=${objdir}/${subdir}/"
> +set compile_flags "$compile_flags additional_flags=-lmd"
> +set sources ${srcdir}/${subdir}/${srcfile}

Using shlib= will make this simpler.

> +gdb_exit
> +gdb_start
> +gdb_reinitialize_dir $srcdir/$subdir
> +gdb_load ${binfile}

Once I check in the other patch, gdb_load_shlibs here.  That doesn't
exist yet either :-)  Just warning you.

> +# Delete all breakpoints.
> +send_gdb "delete breakpoints\n"
> +gdb_expect {
> +  -re "Delete.*all.*breakpoints.*\(y or n\).*" {
> +    send_gdb "y\n"
> +    gdb_expect {
> +      -re "$gdb_prompt.*" { pass "Delete all breakpoints" }
> +      timeout             { fail "Delete all breakpoints (timeout)" }
> +    }
> +  }
> +  -re "$gdb_prompt"       { fail "Delete all breakpoints" }
> +  timeout                 { fail "Delete all breakpoints (timeout)" }
> +}

This is just delete_breakpoints.

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PING] [rfc]: Framework for looking up multiply defined global   symbols  in shared libraries
  2007-05-14 18:25 ` Daniel Jacobowitz
@ 2007-05-15  5:49   ` Markus Deuling
  2007-05-18  4:13     ` Markus Deuling
  0 siblings, 1 reply; 24+ messages in thread
From: Markus Deuling @ 2007-05-15  5:49 UTC (permalink / raw)
  To: Daniel Jacobowitz, GDB Patches, Ulrich Weigand

Hi Daniel,

Daniel Jacobowitz wrote:
> Please use skip_shlib_tests instead.  You will probably also need to
> exclude a list of targets where -Bsymbolic won't work.
> 
> (I realize skip_shlib_tests doesn't exist yet.  Gimme a day or so and
> it will, I'll be working on those patches next.)

thank you very much for your effort and your very valuable input. I'll rework the patch and come up with it 
when you're done with that patch that includes skip_shlib_tests.
 

-- 
Markus Deuling
GNU Toolchain for Linux on Cell BE
deuling@de.ibm.com


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PING] [rfc]: Framework for looking up multiply defined global    symbols  in shared libraries
  2007-05-15  5:49   ` Markus Deuling
@ 2007-05-18  4:13     ` Markus Deuling
  2007-05-31 21:40       ` Ulrich Weigand
  0 siblings, 1 reply; 24+ messages in thread
From: Markus Deuling @ 2007-05-18  4:13 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: GDB Patches, Ulrich Weigand

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

Markus Deuling wrote:
> Hi Daniel,
> 
> Daniel Jacobowitz wrote:
>> Please use skip_shlib_tests instead.  You will probably also need to
>> exclude a list of targets where -Bsymbolic won't work.
>>
>> (I realize skip_shlib_tests doesn't exist yet.  Gimme a day or so and
>> it will, I'll be working on those patches next.)
> 
> thank you very much for your effort and your very valuable input. I'll 
> rework the patch and come up with it when you're done with that patch 
> that includes skip_shlib_tests.
> 
> 

This is the reworked patch for multiply defined symbols in shared libraries. I included
your input including the new skip_shlib_tests and gdb_load_shlibs. Again thank you very much
for reviewing.

The testsuite showed no regressions. The ChangeLog also had to be changed. Would this be ok to commit?

ChangeLog:
	* cp-namespace.c (lookup_symbol_file): Add block to call for 
	lookup_symbol_global.
	* Makefile.in (solist_h): Update dependencies.
	(solib.o): Likewise.
	(symtab.o): Likewise.
	* solib.c (solib_global_lookup): New function.
	* solib-svr4.c (has_SYMBOLIC): New function.
	(elf_lookup_lib_symbol): New function.
	(_initialize_svr4_solib): Add elf_lookup_lib_symbol to svr4_so_ops.
	* solist.h: New include "symtab.h".
	(target_so_ops): New member lookup_lib_global_symbol.
	(solib_global_lookup): Declare.
	* symtab.c: New include "solist.h".
	(lookup_objfile_from_block): New function.
	(lookup_global_symbol_from_objfile): New function.
	(basic_lookup_symbol_nonlocal): Add block to call for 
	lookup_symbol_global.
	(lookup_symbol_global): Call solib_global_lookup first.
	* symtab.h (lookup_symbol_global): Add block to declaration.
	(lookup_objfile_from_block): Declare.
	(lookup_global_symbol_from_objfile): Declare.
	* gdb.base/libmd.c: New file for testcase.
	* gdb.base/libmd.h: Likewise.
	* gdb.base/solib_symbol.c: Likewise.
	* gdb.base/solib_symbol.exp: New testcase for multiply defined global
	symbol lookup.


-- 
Markus Deuling
GNU Toolchain for Linux on Cell BE
deuling@de.ibm.com


[-- Attachment #2: diff-gdb-multiple-symbols-mainline --]
[-- Type: text/plain, Size: 17712 bytes --]

diff -urN src/gdb/cp-namespace.c dev/gdb/cp-namespace.c
--- src/gdb/cp-namespace.c	2007-01-09 18:58:50.000000000 +0100
+++ dev/gdb/cp-namespace.c	2007-05-18 05:40:42.000000000 +0200
@@ -491,7 +491,7 @@
     }
   else
     {
-      sym = lookup_symbol_global (name, linkage_name, domain, symtab);
+      sym = lookup_symbol_global (name, linkage_name, block, domain, symtab);
     }
 
   if (sym != NULL)
diff -urN src/gdb/Makefile.in dev/gdb/Makefile.in
--- src/gdb/Makefile.in	2007-05-18 05:34:55.000000000 +0200
+++ dev/gdb/Makefile.in	2007-05-18 05:40:42.000000000 +0200
@@ -797,7 +797,7 @@
 solib_pa64_h = solib-pa64.h
 solib_som_h = solib-som.h
 solib_svr4_h = solib-svr4.h
-solist_h = solist.h
+solist_h = solist.h $(symtab_h)
 source_h = source.h
 sparc64_tdep_h = sparc64-tdep.h $(sparc_tdep_h)
 sparc_nat_h = sparc-nat.h
@@ -2572,7 +2572,7 @@
 	$(objfiles_h) $(exceptions_h) $(gdbcore_h) $(command_h) $(target_h) \
 	$(frame_h) $(gdb_regex_h) $(inferior_h) $(environ_h) $(language_h) \
 	$(gdbcmd_h) $(completer_h) $(filenames_h) $(exec_h) $(solist_h) \
-	$(observer_h) $(readline_h)
+	$(observer_h) $(readline_h) $(objfiles_h)
 solib-frv.o: solib-frv.c $(defs_h) $(gdb_string_h) $(inferior_h) \
 	$(gdbcore_h) $(solist_h) $(frv_tdep_h) $(objfiles_h) $(symtab_h) \
 	$(language_h) $(command_h) $(gdbcmd_h) $(elf_frv_h) $(solib_h)
@@ -2719,7 +2719,8 @@
 	$(language_h) $(demangle_h) $(inferior_h) $(linespec_h) $(source_h) \
 	$(filenames_h) $(objc_lang_h) $(ada_lang_h) $(hashtab_h) \
 	$(gdb_obstack_h) $(block_h) $(dictionary_h) $(gdb_string_h) \
-	$(gdb_stat_h) $(cp_abi_h) $(observer_h) $(gdb_assert_h)
+	$(gdb_stat_h) $(cp_abi_h) $(observer_h) $(gdb_assert_h) \
+	$(solist_h)
 target.o: target.c $(defs_h) $(gdb_string_h) $(target_h) $(gdbcmd_h) \
 	$(symtab_h) $(inferior_h) $(bfd_h) $(symfile_h) $(objfiles_h) \
 	$(gdb_wait_h) $(dcache_h) $(regcache_h) $(gdb_assert_h) $(gdbcore_h) \
diff -urN src/gdb/solib.c dev/gdb/solib.c
--- src/gdb/solib.c	2007-05-18 05:34:56.000000000 +0200
+++ dev/gdb/solib.c	2007-05-18 05:40:42.000000000 +0200
@@ -955,6 +955,26 @@
 }
 
 
+/* Handler for library-specific lookup of global symbol
+   NAME in BLOCK.  Detect objfile corresponding to BLOCK
+   and call the library-specific handler if it is installed
+   for the current target.  */
+
+struct symbol *
+solib_global_lookup (const struct objfile *objfile,
+		     const char *name,
+		     const char *linkage_name,
+		     const domain_enum domain,
+		     struct symtab **symtab)
+{
+  if (current_target_so_ops->lookup_lib_global_symbol != NULL)
+    return current_target_so_ops->lookup_lib_global_symbol (objfile,
+				name, linkage_name, domain, symtab);
+
+  return NULL;
+}
+
+
 extern initialize_file_ftype _initialize_solib; /* -Wmissing-prototypes */
 
 void
diff -urN src/gdb/solib-svr4.c dev/gdb/solib-svr4.c
--- src/gdb/solib-svr4.c	2007-05-18 05:34:56.000000000 +0200
+++ dev/gdb/solib-svr4.c	2007-05-18 05:58:33.000000000 +0200
@@ -378,6 +378,71 @@
 
  */
 
+/* Scan OBFD for a SYMBOLIC flag in the .dynamic section.  If it is set then
+   OBFD is a DSO with a special rule for symbol lookup.  The lookup then starts
+   in the DSO before searching in the executable.  */
+
+static int
+has_SYMBOLIC (bfd *obfd)
+{
+  CORE_ADDR dyn_ptr = 0;
+  int sect_size, arch_size;
+  gdb_byte *buf, *bufstart, *bufend, *p;
+  asection *sect;
+
+  if (obfd == NULL)
+    return -1;
+  arch_size = bfd_get_arch_size (obfd);
+  if (arch_size == -1)
+    return -1;
+
+  /* Retrieve information about .dynamic section.  */
+  sect = bfd_get_section_by_name (obfd, ".dynamic");
+  if (!sect)
+    return -1;
+
+  /* Read the .dynamic section.  */
+  sect_size = bfd_section_size (obfd, sect);
+  buf = alloca (sect_size);
+  if (!bfd_get_section_contents (obfd, sect,
+				 buf, 0, sect_size))
+    return -1;
+
+  if (arch_size == 32)
+    { /* 32-bit elf */
+      for (bufend = buf + sect_size;
+	   buf < bufend;
+	   buf += sizeof (Elf32_External_Dyn))
+	{
+	  Elf32_External_Dyn *x_dynp = (Elf32_External_Dyn *) buf;
+	  long dyn_tag;
+	  dyn_tag = extract_unsigned_integer ((gdb_byte *) x_dynp->d_tag, 4);
+	  if (dyn_tag == DT_NULL)
+	    break;
+	  else if (dyn_tag == DT_SYMBOLIC)
+	    return 1;
+	}
+    }
+  else
+    { /* 64-bit elf */
+      for (bufend = buf + sect_size;
+	   buf < bufend;
+	   buf += sizeof (Elf64_External_Dyn))
+	{
+	  Elf64_External_Dyn *x_dynp = (Elf64_External_Dyn *) buf;
+	  long dyn_tag;
+
+	  dyn_tag = extract_unsigned_integer ((gdb_byte *) x_dynp->d_tag, 8);
+	  if (dyn_tag == DT_NULL)
+	    break;
+	  else if (dyn_tag == DT_SYMBOLIC)
+	    return 1;
+	}
+    }
+
+  return 0;
+}
+
 static CORE_ADDR
 elf_locate_base (void)
 {
@@ -1558,6 +1623,24 @@
 
 struct target_so_ops svr4_so_ops;
 
+/* Lookup global symbol for ELF DSOs linked with -Bsymbolic.
+   Those DSOs have a different rule for symbol lookup. The lookup
+   begins here in the DSO, not in the main executable.  */
+
+static struct symbol *
+elf_lookup_lib_symbol (const struct objfile *objfile,
+		       const char *name,
+		       const char *linkage_name,
+		       const domain_enum domain, struct symtab **symtab)
+{
+  if (objfile->obfd == NULL
+     || has_SYMBOLIC (objfile->obfd) != 1)
+    return NULL;
+
+  return  lookup_global_symbol_from_objfile
+		(objfile, name, linkage_name, domain, symtab);
+}
+
 extern initialize_file_ftype _initialize_svr4_solib; /* -Wmissing-prototypes */
 
 void
@@ -1573,6 +1656,7 @@
   svr4_so_ops.current_sos = svr4_current_sos;
   svr4_so_ops.open_symbol_file_object = open_symbol_file_object;
   svr4_so_ops.in_dynsym_resolve_code = svr4_in_dynsym_resolve_code;
+  svr4_so_ops.lookup_lib_global_symbol = elf_lookup_lib_symbol;
 
   /* FIXME: Don't do this here.  *_gdbarch_init() should set so_ops. */
   current_target_so_ops = &svr4_so_ops;
diff -urN src/gdb/solist.h dev/gdb/solist.h
--- src/gdb/solist.h	2007-01-09 18:58:58.000000000 +0100
+++ dev/gdb/solist.h	2007-05-18 05:40:42.000000000 +0200
@@ -23,6 +23,8 @@
 #define SOLIST_H
 
 #define SO_NAME_MAX_PATH_SIZE 512	/* FIXME: Should be dynamic */
+/* For domain_enum domain.  */
+#include "symtab.h"
 
 /* Forward declaration for target specific link map information.  This
    struct is opaque to all but the target specific file.  */
@@ -103,7 +105,14 @@
        Convenience function for remote debuggers finding host libs.  */
     int (*find_and_open_solib) (char *soname,
         unsigned o_flags, char **temp_pathname);
-    
+
+    /* Hook for looking up global symbols in a library-specific way.  */
+    struct symbol * (*lookup_lib_global_symbol) (const struct objfile *objfile,
+						 const char *name,
+						 const char *linkage_name,
+						 const domain_enum domain,
+						 struct symtab **symtab);
+
   };
 
 /* Free the memory associated with a (so_list *).  */
@@ -125,4 +134,11 @@
 #define TARGET_SO_IN_DYNSYM_RESOLVE_CODE \
   (current_target_so_ops->in_dynsym_resolve_code)
 
+/* Handler for library-specific global symbol lookup in solib.c.  */
+struct symbol *solib_global_lookup (const struct objfile *objfile,
+				    const char *name,
+				    const char *linkage_name,
+				    const domain_enum domain,
+				    struct symtab **symtab);
+
 #endif
diff -urN src/gdb/symtab.c dev/gdb/symtab.c
--- src/gdb/symtab.c	2007-04-18 13:12:57.000000000 +0200
+++ dev/gdb/symtab.c	2007-05-18 05:55:54.000000000 +0200
@@ -57,6 +57,7 @@
 #include "cp-abi.h"
 #include "observer.h"
 #include "gdb_assert.h"
+#include "solist.h"
 
 /* Prototypes for local functions */
 
@@ -1265,6 +1266,26 @@
   return NULL;
 }
 
+/* Look up OBJFILE to BLOCK.  */
+
+struct objfile *
+lookup_objfile_from_block (const struct block *block)
+{
+  struct objfile *obj;
+  struct symtab *s;
+
+  if (block == NULL)
+    return NULL;
+
+  block = block_global_block (block);
+  /* Go through SYMTABS.  */
+  ALL_SYMTABS (obj, s)
+    if (block == BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK))
+      return obj;
+
+  return NULL;
+}
+
 /* Look up a symbol in a block; if found, locate its symtab, fixup the
    symbol, and set block_found appropriately.  */
 
@@ -1306,6 +1327,57 @@
   return NULL;
 }
 
+/* Check all global symbols in OBJFILE in symtabs and
+   psymtabs.  */
+
+struct symbol *
+lookup_global_symbol_from_objfile (const struct objfile *objfile,
+				   const char *name,
+				   const char *linkage_name,
+				   const domain_enum domain,
+				   struct symtab **symtab)
+{
+  struct symbol *sym;
+  struct blockvector *bv;
+  const struct block *block;
+  struct symtab *s;
+  struct partial_symtab *ps;
+
+  /* Go through symtabs.  */
+  ALL_OBJFILE_SYMTABS (objfile, s)
+  {
+    bv = BLOCKVECTOR (s);
+    block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+    sym = lookup_block_symbol (block, name, linkage_name, domain);
+    if (sym)
+      {
+	block_found = block;
+	if (symtab != NULL)
+	  *symtab = s;
+	return fixup_symbol_section (sym, (struct objfile *)objfile);
+      }
+  }
+
+  /* Now go through psymtabs.  */
+  ALL_OBJFILE_PSYMTABS (objfile, ps)
+  {
+    if (!ps->readin
+	&& lookup_partial_symbol (ps, name, linkage_name,
+				  1, domain))
+      {
+	s = PSYMTAB_TO_SYMTAB (ps);
+	bv = BLOCKVECTOR (s);
+	block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+	sym = lookup_block_symbol (block, name, linkage_name, domain);
+	if (symtab != NULL)
+	  *symtab = s;
+	return fixup_symbol_section (sym, (struct objfile *)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,
    depending on whether or not we want to search global symbols or
@@ -1571,7 +1643,7 @@
   if (sym != NULL)
     return sym;
 
-  return lookup_symbol_global (name, linkage_name, domain, symtab);
+  return lookup_symbol_global (name, linkage_name, block, domain, symtab);
 }
 
 /* Lookup a symbol in the static block associated to BLOCK, if there
@@ -1599,10 +1671,19 @@
 struct symbol *
 lookup_symbol_global (const char *name,
 		      const char *linkage_name,
+		      const struct block *block,
 		      const domain_enum domain,
 		      struct symtab **symtab)
 {
-  struct symbol *sym;
+  struct symbol *sym = NULL;
+  struct objfile *objfile = NULL;
+
+  /* Call library-specific lookup procedure.  */
+  objfile = lookup_objfile_from_block (block);
+  if (objfile != NULL)
+    sym = solib_global_lookup (objfile, name, linkage_name, domain, symtab);
+  if (sym != NULL)
+    return sym;
 
   sym = lookup_symbol_aux_symtabs (GLOBAL_BLOCK, name, linkage_name,
 				   domain, symtab);
diff -urN src/gdb/symtab.h dev/gdb/symtab.h
--- src/gdb/symtab.h	2007-03-28 05:42:54.000000000 +0200
+++ dev/gdb/symtab.h	2007-05-18 05:40:42.000000000 +0200
@@ -1050,6 +1050,7 @@
 
 extern struct symbol *lookup_symbol_global (const char *name,
 					    const char *linkage_name,
+					    const struct block *block,
 					    const domain_enum domain,
 					    struct symtab **symtab);
 
@@ -1403,4 +1404,16 @@
    Defined in symtab.c, used in hppa-tdep.c. */
 extern int deprecated_hp_som_som_object_present;
 
+/* Lookup objfile to a block.  */
+extern struct objfile *
+lookup_objfile_from_block (const struct block *block);
+
+/* Check global symbols in objfile.  */
+struct symbol *lookup_global_symbol_from_objfile (const struct objfile *objfile,
+						  const char *name,
+						  const char *linkage_name,
+						  const domain_enum domain,
+						  struct symtab **symtab);
+
+
 #endif /* !defined(SYMTAB_H) */
diff -urN src/gdb/testsuite/gdb.base/libmd.c dev/gdb/testsuite/gdb.base/libmd.c
--- src/gdb/testsuite/gdb.base/libmd.c	1970-01-01 01:00:00.000000000 +0100
+++ dev/gdb/testsuite/gdb.base/libmd.c	2007-05-18 05:40:42.000000000 +0200
@@ -0,0 +1,36 @@
+/* Copyright 2007 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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+   Contributed by Markus Deuling <deuling@de.ibm.com>.
+*/
+extern void foo();
+#include <stdio.h>
+#include "libmd.h"
+
+void foo2 ();
+
+void
+foo ()
+{
+  printf ("foo in lib\n");
+  return;
+}
+
+void
+foo2()
+{
+  printf ("foo2 in lib\n");
+  return;
+}
diff -urN src/gdb/testsuite/gdb.base/libmd.h dev/gdb/testsuite/gdb.base/libmd.h
--- src/gdb/testsuite/gdb.base/libmd.h	1970-01-01 01:00:00.000000000 +0100
+++ dev/gdb/testsuite/gdb.base/libmd.h	2007-05-18 05:40:42.000000000 +0200
@@ -0,0 +1,18 @@
+/* Copyright 2007 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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+   Contributed by Markus Deuling <deuling@de.ibm.com>.
+*/
+extern void foo();
diff -urN src/gdb/testsuite/gdb.base/solib_symbol.c dev/gdb/testsuite/gdb.base/solib_symbol.c
--- src/gdb/testsuite/gdb.base/solib_symbol.c	1970-01-01 01:00:00.000000000 +0100
+++ dev/gdb/testsuite/gdb.base/solib_symbol.c	2007-05-18 05:40:42.000000000 +0200
@@ -0,0 +1,45 @@
+/* Copyright 2007 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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+   Contributed by Markus Deuling <deuling@de.ibm.com>.
+*/
+extern void foo();
+#include <stdio.h>
+#include "libmd.h"
+
+extern void foo();
+void foo3();
+void foo2();
+
+int main ()
+{
+  printf ("in main\n");
+  foo ();
+  foo3 ();
+  return 0;
+}
+
+void foo3()
+{
+  printf ("foo3 in main\n");
+  return;
+}
+
+void foo2()
+{
+  printf ("foo2 in main\n");
+  return;
+}
+
diff -urN src/gdb/testsuite/gdb.base/solib_symbol.exp dev/gdb/testsuite/gdb.base/solib_symbol.exp
--- src/gdb/testsuite/gdb.base/solib_symbol.exp	1970-01-01 01:00:00.000000000 +0100
+++ dev/gdb/testsuite/gdb.base/solib_symbol.exp	2007-05-18 05:50:44.000000000 +0200
@@ -0,0 +1,80 @@
+# Copyright 2007 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 2 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+#
+# Contributed by Markus Deuling <deuling@de.ibm.com>.
+#
+
+if {[skip_shlib_tests]} {
+    return 0
+}
+
+# Library file.
+set libname "libmd"
+set srcfile_lib ${srcdir}/${subdir}/${libname}.c
+set binfile_lib ${objdir}/${subdir}/${libname}.so
+set lib_flags [list debug ldflags=-Wl,-Bsymbolic]
+# Binary file.
+set testfile "solib_symbol"
+set srcfile ${srcdir}/${subdir}/${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+set bin_flags [list debug shlib=${binfile_lib}]
+
+if [get_compiler_info ${binfile}] {
+    return -1
+}
+
+if { [gdb_compile_shlib ${srcfile_lib} ${binfile_lib} $lib_flags] != ""
+     || [gdb_compile ${srcfile} ${binfile} executable $bin_flags] != "" } {
+  untested "Could not compile $binfile_lib or $binfile."
+  return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+gdb_load_shlibs $binfile_lib
+
+if ![runto_main] then {
+  fail "Can't run to main"
+  return 0
+}
+
+# Set a breakpoint in the binary.
+gdb_test "br foo2" \
+	 "Breakpoint.*file.*${srcfile}.*" \
+	 "foo2 in main"
+
+delete_breakpoints
+
+# Break in the library.
+gdb_test "br foo" \
+	 "" \
+	 "foo in libmd"
+
+gdb_test "continue" \
+	 "Continuing.*" \
+	 "continue"
+
+# This symbol is now looked up in the ELF library.
+gdb_test "br foo2" \
+	 "Breakpoint.*file.*${srcfile_lib}.*" \
+	 "foo2 in mdlib"
+
+gdb_exit
+
+return 0
+
+

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PING] [rfc]: Framework for looking up multiply defined global      symbols  in shared libraries
  2007-05-18  4:13     ` Markus Deuling
@ 2007-05-31 21:40       ` Ulrich Weigand
  2007-06-05  3:46         ` Markus Deuling
  0 siblings, 1 reply; 24+ messages in thread
From: Ulrich Weigand @ 2007-05-31 21:40 UTC (permalink / raw)
  To: Markus Deuling; +Cc: Daniel Jacobowitz, GDB Patches

Markus Deuling wrote:

> +/* Handler for library-specific lookup of global symbol
> +   NAME in BLOCK.  Detect objfile corresponding to BLOCK
> +   and call the library-specific handler if it is installed
> +   for the current target.  */

Comment no longer matches the prototype ...

> +struct symbol *
> +solib_global_lookup (const struct objfile *objfile,
> +		     const char *name,
> +		     const char *linkage_name,
> +		     const domain_enum domain,
> +		     struct symtab **symtab)


> +has_SYMBOLIC (bfd *obfd)
> +{
> +  CORE_ADDR dyn_ptr = 0;
> +  int sect_size, arch_size;
> +  gdb_byte *buf, *bufstart, *bufend, *p;
> +  asection *sect;
> +
> +  if (obfd == NULL)
> +    return -1;
> +  arch_size = bfd_get_arch_size (obfd);
> +  if (arch_size == -1)
> +    return -1;
> +
> +  /* Retrieve information about .dynamic section.  */
> +  sect = bfd_get_section_by_name (obfd, ".dynamic");
> +  if (!sect)
> +    return -1;
> +
> +  /* Read the .dynamic section.  */
> +  sect_size = bfd_section_size (obfd, sect);
> +  buf = alloca (sect_size);
> +  if (!bfd_get_section_contents (obfd, sect,
> +				 buf, 0, sect_size))
> +    return -1;
> +
> +  if (arch_size == 32)
> +    { /* 32-bit elf */
> +      for (bufend = buf + sect_size;
> +	   buf < bufend;
> +	   buf += sizeof (Elf32_External_Dyn))
> +	{
> +	  Elf32_External_Dyn *x_dynp = (Elf32_External_Dyn *) buf;
> +	  long dyn_tag;
> +	  dyn_tag = extract_unsigned_integer ((gdb_byte *) x_dynp->d_tag, 4);
> +	  if (dyn_tag == DT_NULL)
> +	    break;
> +	  else if (dyn_tag == DT_SYMBOLIC)
> +	    return 1;
> +	}
> +    }
> +  else
> +    { /* 64-bit elf */
> +      for (bufend = buf + sect_size;
> +	   buf < bufend;
> +	   buf += sizeof (Elf64_External_Dyn))
> +	{
> +	  Elf64_External_Dyn *x_dynp = (Elf64_External_Dyn *) buf;
> +	  long dyn_tag;
> +
> +	  dyn_tag = extract_unsigned_integer ((gdb_byte *) x_dynp->d_tag, 8);
> +	  if (dyn_tag == DT_NULL)
> +	    break;
> +	  else if (dyn_tag == DT_SYMBOLIC)
> +	    return 1;
> +	}
> +    }

It looks like this duplicates a whole bunch of code from elf_locate_base.
Maybe we should extract a helper routine that retrieves a given DT_ tag
from the .dynamic section?


> +/* Look up OBJFILE to BLOCK.  */
> +
> +struct objfile *
> +lookup_objfile_from_block (const struct block *block)

I guess this could be static now.

> +/* Lookup objfile to a block.  */
> +extern struct objfile *
> +lookup_objfile_from_block (const struct block *block);

If we make it static, this should go away.  Otherwise, the function name
should again not start in the first column for the prototype.


Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PING] [rfc]: Framework for looking up multiply defined global       symbols  in shared libraries
  2007-05-31 21:40       ` Ulrich Weigand
@ 2007-06-05  3:46         ` Markus Deuling
  2007-06-20  6:58           ` [PING 2] " Markus Deuling
  2007-06-25 21:48           ` [PING] " Kevin Buettner
  0 siblings, 2 replies; 24+ messages in thread
From: Markus Deuling @ 2007-06-05  3:46 UTC (permalink / raw)
  To: GDB Patches; +Cc: Daniel Jacobowitz, Ulrich Weigand, Kevin Buettner

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

Hello,

Ulrich Weigand wrote:
> Markus Deuling wrote:
> 
> It looks like this duplicates a whole bunch of code from elf_locate_base.
> Maybe we should extract a helper routine that retrieves a given DT_ tag
> from the .dynamic section?
> 
> 
>> +/* Look up OBJFILE to BLOCK.  */
>> +
>> +struct objfile *
>> +lookup_objfile_from_block (const struct block *block)
> 
> I guess this could be static now.
> 
>> +/* Lookup objfile to a block.  */
>> +extern struct objfile *
>> +lookup_objfile_from_block (const struct block *block);
> 
> If we make it static, this should go away.  Otherwise, the function name
> should again not start in the first column for the prototype.
> 
> 
> Bye,
> Ulrich
> 

thank you very much for your input. I reworked the patch. There is now a helper routine to extract DT_ tags from
.dynamic section called scan_dyntag. Testsuite on x86 showed no regression.

Is this ok to commit?

ChangeLog:

	* cp-namespace.c (lookup_symbol_file): Add block to
	lookup_symbol_global call.
	* Makefile.in (solist_h): Add dependency on symtab header.
	(solib.o): Add dependency on objfiles header.
	(symtab.o): Add dependency on solist header.
	* solib.c (solib_global_lookup): New function.
	* solib-svr4.c (scan_dyntag): Likewise.
	(elf_locate_base): Call helper routine scan_dyntag.
	(elf_lookup_lib_symbol): New function.
	(_initialize_svr4_solib): Add elf_lookup_lib_symbol to svr4_so_ops.
	* solist.h (symtab.h): New include.
	(lookup_lib_global_symbol): New prototype.
	(solib_global_lookup): Likewise.
	* symtab.c: New include solist.h.
	(lookup_objfile_from_block): New function.
	(lookup_global_symbol_from_objfile): New function.
	(basic_lookup_symbol_nonlocal): Add block to lookup_symbol_global call.
	(lookup_symbol_global): Call library-specific lookup procedure.
	* symtab.h (lookup_global_symbol_from_objfile): New prototype.
	* gdb.base/libmd.c: New file (testcase multiple symbol lookup).
	* gdb.base/libmd.h: Likewise.
	* gdb.base/solib_symbol.c: Likewise.
	* gdb.base/solib_symbol.exp: Likewise.

-- 
Markus Deuling
GNU Toolchain for Linux on Cell BE
deuling@de.ibm.com


[-- Attachment #2: diff-gdb-multiple-symbols-mainline --]
[-- Type: text/plain, Size: 22148 bytes --]

diff -urN src/gdb/cp-namespace.c dev/gdb/cp-namespace.c
--- src/gdb/cp-namespace.c	2007-01-09 18:58:50.000000000 +0100
+++ dev/gdb/cp-namespace.c	2007-06-05 05:30:07.000000000 +0200
@@ -491,7 +491,7 @@
     }
   else
     {
-      sym = lookup_symbol_global (name, linkage_name, domain, symtab);
+      sym = lookup_symbol_global (name, linkage_name, block, domain, symtab);
     }
 
   if (sym != NULL)
diff -urN src/gdb/Makefile.in dev/gdb/Makefile.in
--- src/gdb/Makefile.in	2007-05-29 08:01:14.000000000 +0200
+++ dev/gdb/Makefile.in	2007-06-05 05:30:07.000000000 +0200
@@ -797,7 +797,7 @@
 solib_pa64_h = solib-pa64.h
 solib_som_h = solib-som.h
 solib_svr4_h = solib-svr4.h
-solist_h = solist.h
+solist_h = solist.h $(symtab_h)
 source_h = source.h
 sparc64_tdep_h = sparc64-tdep.h $(sparc_tdep_h)
 sparc_nat_h = sparc-nat.h
@@ -2568,7 +2568,7 @@
 	$(objfiles_h) $(exceptions_h) $(gdbcore_h) $(command_h) $(target_h) \
 	$(frame_h) $(gdb_regex_h) $(inferior_h) $(environ_h) $(language_h) \
 	$(gdbcmd_h) $(completer_h) $(filenames_h) $(exec_h) $(solist_h) \
-	$(observer_h) $(readline_h)
+	$(observer_h) $(readline_h) $(objfiles_h)
 solib-frv.o: solib-frv.c $(defs_h) $(gdb_string_h) $(inferior_h) \
 	$(gdbcore_h) $(solist_h) $(frv_tdep_h) $(objfiles_h) $(symtab_h) \
 	$(language_h) $(command_h) $(gdbcmd_h) $(elf_frv_h) $(solib_h)
@@ -2715,7 +2715,8 @@
 	$(language_h) $(demangle_h) $(inferior_h) $(linespec_h) $(source_h) \
 	$(filenames_h) $(objc_lang_h) $(ada_lang_h) $(hashtab_h) \
 	$(gdb_obstack_h) $(block_h) $(dictionary_h) $(gdb_string_h) \
-	$(gdb_stat_h) $(cp_abi_h) $(observer_h) $(gdb_assert_h)
+	$(gdb_stat_h) $(cp_abi_h) $(observer_h) $(gdb_assert_h) \
+	$(solist_h)
 target.o: target.c $(defs_h) $(gdb_string_h) $(target_h) $(gdbcmd_h) \
 	$(symtab_h) $(inferior_h) $(bfd_h) $(symfile_h) $(objfiles_h) \
 	$(gdb_wait_h) $(dcache_h) $(regcache_h) $(gdb_assert_h) $(gdbcore_h) \
diff -urN src/gdb/solib.c dev/gdb/solib.c
--- src/gdb/solib.c	2007-05-16 16:07:56.000000000 +0200
+++ dev/gdb/solib.c	2007-06-05 05:30:07.000000000 +0200
@@ -955,6 +955,24 @@
 }
 
 
+/* Handler for library-specific lookup of global symbol NAME in OBJFILE.  Call
+   the library-specific handler if it is installed for the current target.  */
+
+struct symbol *
+solib_global_lookup (const struct objfile *objfile,
+		     const char *name,
+		     const char *linkage_name,
+		     const domain_enum domain,
+		     struct symtab **symtab)
+{
+  if (current_target_so_ops->lookup_lib_global_symbol != NULL)
+    return current_target_so_ops->lookup_lib_global_symbol (objfile,
+				name, linkage_name, domain, symtab);
+
+  return NULL;
+}
+
+
 extern initialize_file_ftype _initialize_solib; /* -Wmissing-prototypes */
 
 void
diff -urN src/gdb/solib-svr4.c dev/gdb/solib-svr4.c
--- src/gdb/solib-svr4.c	2007-06-04 05:41:43.000000000 +0200
+++ dev/gdb/solib-svr4.c	2007-06-05 05:35:58.000000000 +0200
@@ -354,6 +354,76 @@
   return symaddr;
 }
 
+/* Scan for DYNTAG in .dynamic section of ABFD. If DYNTAG is found 1 is
+   returned and the corresponding PTR is set.  */
+
+static int
+scan_dyntag (int dyntag, bfd *abfd, CORE_ADDR *ptr)
+{
+  int arch_size, step, sect_size;
+  long dyn_tag;
+  CORE_ADDR dyn_ptr, dyn_addr;
+  gdb_byte *bufend, *buf;
+  Elf32_External_Dyn *x_dynp_32;
+  Elf64_External_Dyn *x_dynp_64;
+  struct bfd_section *sect;
+
+  if (abfd == NULL)
+    return 0;
+  arch_size = bfd_get_arch_size (abfd);
+  if (arch_size == -1)
+   return 0;
+
+  /* Find the start address of the .dynamic section.  */
+  sect = bfd_get_section_by_name (abfd, ".dynamic");
+  if (sect == NULL)
+    return 0;
+  dyn_addr = bfd_section_vma (abfd, sect);
+
+  /* Read in .dynamic section, silently ignore errors.  */
+  sect_size = bfd_section_size (abfd, sect);
+  buf = alloca (sect_size);
+  if (target_read_memory (dyn_addr, buf, sect_size))
+    {
+      /* If target_read_memory fails, try reading the BFD file.  */
+      if (!bfd_get_section_contents (abfd, sect,
+				     buf, 0, sect_size))
+	return 0;
+    }
+
+  /* Iterate over BUF and scan for DYNTAG.  If found, set PTR and return.  */
+  step = (arch_size == 32) ? sizeof (Elf32_External_Dyn)
+			   : sizeof (Elf64_External_Dyn);
+  for (bufend = buf + sect_size;
+       buf < bufend;
+       buf += step)
+  {
+    if (arch_size == 32)
+      {
+	x_dynp_32 = (Elf32_External_Dyn *) buf;
+	dyn_tag = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_tag);
+	dyn_ptr = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_un.d_ptr);
+      }
+      else
+      {
+	x_dynp_64 = (Elf64_External_Dyn *) buf;
+	dyn_tag = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_tag);
+	dyn_ptr = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_un.d_ptr);
+      }
+     if (dyn_tag == DT_NULL)
+       return 0;
+     if (dyn_tag == dyntag)
+       {
+	 if (ptr)
+	   *ptr = dyn_ptr;
+         return 1;
+       }
+  }
+
+  return 0;
+}
+
+
 /*
 
    LOCAL FUNCTION
@@ -381,114 +451,31 @@
 static CORE_ADDR
 elf_locate_base (void)
 {
-  struct bfd_section *dyninfo_sect;
-  int dyninfo_sect_size;
-  CORE_ADDR dyninfo_addr;
-  gdb_byte *buf;
-  gdb_byte *bufend;
-  int arch_size;
+  struct minimal_symbol *msymbol;
+  CORE_ADDR dyn_ptr;
 
-  /* Find the start address of the .dynamic section.  */
-  dyninfo_sect = bfd_get_section_by_name (exec_bfd, ".dynamic");
-  if (dyninfo_sect == NULL)
+  /* Find DT_DEBUG.  */
+  if (scan_dyntag (DT_DEBUG, exec_bfd, &dyn_ptr))
+    return dyn_ptr;
+
+  /* Find DT_MIPS_RLD_MAP.  */
+  if (scan_dyntag (DT_MIPS_RLD_MAP, exec_bfd, &dyn_ptr))
     {
-      /* This may be a static executable.  Look for the symbol
-	 conventionally named _r_debug, as a last resort.  */
-      struct minimal_symbol *msymbol;
-
-      msymbol = lookup_minimal_symbol ("_r_debug", NULL, symfile_objfile);
-      if (msymbol != NULL)
-	return SYMBOL_VALUE_ADDRESS (msymbol);
-      else
+      gdb_byte *pbuf;
+      int pbuf_size = TYPE_LENGTH (builtin_type_void_data_ptr);
+      pbuf = alloca (pbuf_size);
+      /* DT_MIPS_RLD_MAP contains a pointer to the address
+	 of the dynamic link structure.  */
+      if (target_read_memory (dyn_ptr, pbuf, pbuf_size))
 	return 0;
+      return extract_typed_address (pbuf, builtin_type_void_data_ptr);
     }
 
-  dyninfo_addr = bfd_section_vma (exec_bfd, dyninfo_sect);
-
-  /* Read in .dynamic section, silently ignore errors.  */
-  dyninfo_sect_size = bfd_section_size (exec_bfd, dyninfo_sect);
-  buf = alloca (dyninfo_sect_size);
-  if (target_read_memory (dyninfo_addr, buf, dyninfo_sect_size))
-    return 0;
-
-  /* Find the DT_DEBUG entry in the the .dynamic section.
-     For mips elf we look for DT_MIPS_RLD_MAP, mips elf apparently has
-     no DT_DEBUG entries.  */
-
-  arch_size = bfd_get_arch_size (exec_bfd);
-  if (arch_size == -1)	/* failure */
-    return 0;
-
-  if (arch_size == 32)
-    { /* 32-bit elf */
-      for (bufend = buf + dyninfo_sect_size;
-	   buf < bufend;
-	   buf += sizeof (Elf32_External_Dyn))
-	{
-	  Elf32_External_Dyn *x_dynp = (Elf32_External_Dyn *) buf;
-	  long dyn_tag;
-	  CORE_ADDR dyn_ptr;
-
-	  dyn_tag = bfd_h_get_32 (exec_bfd, (bfd_byte *) x_dynp->d_tag);
-	  if (dyn_tag == DT_NULL)
-	    break;
-	  else if (dyn_tag == DT_DEBUG)
-	    {
-	      dyn_ptr = bfd_h_get_32 (exec_bfd, 
-				      (bfd_byte *) x_dynp->d_un.d_ptr);
-	      return dyn_ptr;
-	    }
-	  else if (dyn_tag == DT_MIPS_RLD_MAP)
-	    {
-	      gdb_byte *pbuf;
-	      int pbuf_size = TYPE_LENGTH (builtin_type_void_data_ptr);
-
-	      pbuf = alloca (pbuf_size);
-	      /* DT_MIPS_RLD_MAP contains a pointer to the address
-		 of the dynamic link structure.  */
-	      dyn_ptr = bfd_h_get_32 (exec_bfd, 
-				      (bfd_byte *) x_dynp->d_un.d_ptr);
-	      if (target_read_memory (dyn_ptr, pbuf, pbuf_size))
-		return 0;
-	      return extract_typed_address (pbuf, builtin_type_void_data_ptr);
-	    }
-	}
-    }
-  else /* 64-bit elf */
-    {
-      for (bufend = buf + dyninfo_sect_size;
-	   buf < bufend;
-	   buf += sizeof (Elf64_External_Dyn))
-	{
-	  Elf64_External_Dyn *x_dynp = (Elf64_External_Dyn *) buf;
-	  long dyn_tag;
-	  CORE_ADDR dyn_ptr;
-
-	  dyn_tag = bfd_h_get_64 (exec_bfd, (bfd_byte *) x_dynp->d_tag);
-	  if (dyn_tag == DT_NULL)
-	    break;
-	  else if (dyn_tag == DT_DEBUG)
-	    {
-	      dyn_ptr = bfd_h_get_64 (exec_bfd, 
-				      (bfd_byte *) x_dynp->d_un.d_ptr);
-	      return dyn_ptr;
-	    }
-	  else if (dyn_tag == DT_MIPS_RLD_MAP)
-	    {
-	      gdb_byte *pbuf;
-	      int pbuf_size = TYPE_LENGTH (builtin_type_void_data_ptr);
-
-	      pbuf = alloca (pbuf_size);
-	      /* DT_MIPS_RLD_MAP contains a pointer to the address
-		 of the dynamic link structure.  */
-	      dyn_ptr = bfd_h_get_64 (exec_bfd, 
-				      (bfd_byte *) x_dynp->d_un.d_ptr);
-	      if (target_read_memory (dyn_ptr, pbuf, pbuf_size))
-		return 0;
-	      return extract_typed_address (pbuf, builtin_type_void_data_ptr);
-	    }
-	}
-    }
+  /* This may be a static executable.  Look for the symbol
+     conventionally named _r_debug, as a last resort.  */
+  msymbol = lookup_minimal_symbol ("_r_debug", NULL, symfile_objfile);
+  if (msymbol != NULL)
+    return SYMBOL_VALUE_ADDRESS (msymbol);
 
   /* DT_DEBUG entry not found.  */
   return 0;
@@ -1554,6 +1541,24 @@
 
 struct target_so_ops svr4_so_ops;
 
+/* Lookup global symbol for ELF DSOs linked with -Bsymbolic. Those DSOs have a
+   different rule for symbol lookup.  The lookup begins here in the DSO, not in
+   the main executable.  */
+
+static struct symbol *
+elf_lookup_lib_symbol (const struct objfile *objfile,
+		       const char *name,
+		       const char *linkage_name,
+		       const domain_enum domain, struct symtab **symtab)
+{
+  if (objfile->obfd == NULL
+     || scan_dyntag (DT_SYMBOLIC, objfile->obfd, NULL) != 1)
+    return NULL;
+
+  return  lookup_global_symbol_from_objfile
+		(objfile, name, linkage_name, domain, symtab);
+}
+
 extern initialize_file_ftype _initialize_svr4_solib; /* -Wmissing-prototypes */
 
 void
@@ -1569,6 +1574,7 @@
   svr4_so_ops.current_sos = svr4_current_sos;
   svr4_so_ops.open_symbol_file_object = open_symbol_file_object;
   svr4_so_ops.in_dynsym_resolve_code = svr4_in_dynsym_resolve_code;
+  svr4_so_ops.lookup_lib_global_symbol = elf_lookup_lib_symbol;
 
   /* FIXME: Don't do this here.  *_gdbarch_init() should set so_ops. */
   current_target_so_ops = &svr4_so_ops;
diff -urN src/gdb/solist.h dev/gdb/solist.h
--- src/gdb/solist.h	2007-01-09 18:58:58.000000000 +0100
+++ dev/gdb/solist.h	2007-06-05 05:30:07.000000000 +0200
@@ -23,6 +23,8 @@
 #define SOLIST_H
 
 #define SO_NAME_MAX_PATH_SIZE 512	/* FIXME: Should be dynamic */
+/* For domain_enum domain.  */
+#include "symtab.h"
 
 /* Forward declaration for target specific link map information.  This
    struct is opaque to all but the target specific file.  */
@@ -103,7 +105,14 @@
        Convenience function for remote debuggers finding host libs.  */
     int (*find_and_open_solib) (char *soname,
         unsigned o_flags, char **temp_pathname);
-    
+
+    /* Hook for looking up global symbols in a library-specific way.  */
+    struct symbol * (*lookup_lib_global_symbol) (const struct objfile *objfile,
+						 const char *name,
+						 const char *linkage_name,
+						 const domain_enum domain,
+						 struct symtab **symtab);
+
   };
 
 /* Free the memory associated with a (so_list *).  */
@@ -125,4 +134,11 @@
 #define TARGET_SO_IN_DYNSYM_RESOLVE_CODE \
   (current_target_so_ops->in_dynsym_resolve_code)
 
+/* Handler for library-specific global symbol lookup in solib.c.  */
+struct symbol *solib_global_lookup (const struct objfile *objfile,
+				    const char *name,
+				    const char *linkage_name,
+				    const domain_enum domain,
+				    struct symtab **symtab);
+
 #endif
diff -urN src/gdb/symtab.c dev/gdb/symtab.c
--- src/gdb/symtab.c	2007-04-17 17:07:21.000000000 +0200
+++ dev/gdb/symtab.c	2007-06-05 05:30:07.000000000 +0200
@@ -57,6 +57,7 @@
 #include "cp-abi.h"
 #include "observer.h"
 #include "gdb_assert.h"
+#include "solist.h"
 
 /* Prototypes for local functions */
 
@@ -1265,6 +1266,26 @@
   return NULL;
 }
 
+/* Look up OBJFILE to BLOCK.  */
+
+static struct objfile *
+lookup_objfile_from_block (const struct block *block)
+{
+  struct objfile *obj;
+  struct symtab *s;
+
+  if (block == NULL)
+    return NULL;
+
+  block = block_global_block (block);
+  /* Go through SYMTABS.  */
+  ALL_SYMTABS (obj, s)
+    if (block == BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK))
+      return obj;
+
+  return NULL;
+}
+
 /* Look up a symbol in a block; if found, locate its symtab, fixup the
    symbol, and set block_found appropriately.  */
 
@@ -1306,6 +1327,57 @@
   return NULL;
 }
 
+/* Check all global symbols in OBJFILE in symtabs and
+   psymtabs.  */
+
+struct symbol *
+lookup_global_symbol_from_objfile (const struct objfile *objfile,
+				   const char *name,
+				   const char *linkage_name,
+				   const domain_enum domain,
+				   struct symtab **symtab)
+{
+  struct symbol *sym;
+  struct blockvector *bv;
+  const struct block *block;
+  struct symtab *s;
+  struct partial_symtab *ps;
+
+  /* Go through symtabs.  */
+  ALL_OBJFILE_SYMTABS (objfile, s)
+  {
+    bv = BLOCKVECTOR (s);
+    block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+    sym = lookup_block_symbol (block, name, linkage_name, domain);
+    if (sym)
+      {
+	block_found = block;
+	if (symtab != NULL)
+	  *symtab = s;
+	return fixup_symbol_section (sym, (struct objfile *)objfile);
+      }
+  }
+
+  /* Now go through psymtabs.  */
+  ALL_OBJFILE_PSYMTABS (objfile, ps)
+  {
+    if (!ps->readin
+	&& lookup_partial_symbol (ps, name, linkage_name,
+				  1, domain))
+      {
+	s = PSYMTAB_TO_SYMTAB (ps);
+	bv = BLOCKVECTOR (s);
+	block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+	sym = lookup_block_symbol (block, name, linkage_name, domain);
+	if (symtab != NULL)
+	  *symtab = s;
+	return fixup_symbol_section (sym, (struct objfile *)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,
    depending on whether or not we want to search global symbols or
@@ -1571,7 +1643,7 @@
   if (sym != NULL)
     return sym;
 
-  return lookup_symbol_global (name, linkage_name, domain, symtab);
+  return lookup_symbol_global (name, linkage_name, block, domain, symtab);
 }
 
 /* Lookup a symbol in the static block associated to BLOCK, if there
@@ -1599,10 +1671,19 @@
 struct symbol *
 lookup_symbol_global (const char *name,
 		      const char *linkage_name,
+		      const struct block *block,
 		      const domain_enum domain,
 		      struct symtab **symtab)
 {
-  struct symbol *sym;
+  struct symbol *sym = NULL;
+  struct objfile *objfile = NULL;
+
+  /* Call library-specific lookup procedure.  */
+  objfile = lookup_objfile_from_block (block);
+  if (objfile != NULL)
+    sym = solib_global_lookup (objfile, name, linkage_name, domain, symtab);
+  if (sym != NULL)
+    return sym;
 
   sym = lookup_symbol_aux_symtabs (GLOBAL_BLOCK, name, linkage_name,
 				   domain, symtab);
diff -urN src/gdb/symtab.h dev/gdb/symtab.h
--- src/gdb/symtab.h	2007-03-28 02:12:15.000000000 +0200
+++ dev/gdb/symtab.h	2007-06-05 05:30:07.000000000 +0200
@@ -1050,6 +1050,7 @@
 
 extern struct symbol *lookup_symbol_global (const char *name,
 					    const char *linkage_name,
+					    const struct block *block,
 					    const domain_enum domain,
 					    struct symtab **symtab);
 
@@ -1403,4 +1404,12 @@
    Defined in symtab.c, used in hppa-tdep.c. */
 extern int deprecated_hp_som_som_object_present;
 
+/* Check global symbols in objfile.  */
+struct symbol *lookup_global_symbol_from_objfile (const struct objfile *objfile,
+						  const char *name,
+						  const char *linkage_name,
+						  const domain_enum domain,
+						  struct symtab **symtab);
+
+
 #endif /* !defined(SYMTAB_H) */
diff -urN src/gdb/testsuite/gdb.base/libmd.c dev/gdb/testsuite/gdb.base/libmd.c
--- src/gdb/testsuite/gdb.base/libmd.c	1970-01-01 01:00:00.000000000 +0100
+++ dev/gdb/testsuite/gdb.base/libmd.c	2007-06-05 05:30:07.000000000 +0200
@@ -0,0 +1,36 @@
+/* Copyright 2007 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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+   Contributed by Markus Deuling <deuling@de.ibm.com>.
+*/
+extern void foo();
+#include <stdio.h>
+#include "libmd.h"
+
+void foo2 ();
+
+void
+foo ()
+{
+  printf ("foo in lib\n");
+  return;
+}
+
+void
+foo2()
+{
+  printf ("foo2 in lib\n");
+  return;
+}
diff -urN src/gdb/testsuite/gdb.base/libmd.h dev/gdb/testsuite/gdb.base/libmd.h
--- src/gdb/testsuite/gdb.base/libmd.h	1970-01-01 01:00:00.000000000 +0100
+++ dev/gdb/testsuite/gdb.base/libmd.h	2007-06-05 05:30:07.000000000 +0200
@@ -0,0 +1,18 @@
+/* Copyright 2007 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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+   Contributed by Markus Deuling <deuling@de.ibm.com>.
+*/
+extern void foo();
diff -urN src/gdb/testsuite/gdb.base/solib_symbol.c dev/gdb/testsuite/gdb.base/solib_symbol.c
--- src/gdb/testsuite/gdb.base/solib_symbol.c	1970-01-01 01:00:00.000000000 +0100
+++ dev/gdb/testsuite/gdb.base/solib_symbol.c	2007-06-05 05:30:07.000000000 +0200
@@ -0,0 +1,45 @@
+/* Copyright 2007 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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+   Contributed by Markus Deuling <deuling@de.ibm.com>.
+*/
+extern void foo();
+#include <stdio.h>
+#include "libmd.h"
+
+extern void foo();
+void foo3();
+void foo2();
+
+int main ()
+{
+  printf ("in main\n");
+  foo ();
+  foo3 ();
+  return 0;
+}
+
+void foo3()
+{
+  printf ("foo3 in main\n");
+  return;
+}
+
+void foo2()
+{
+  printf ("foo2 in main\n");
+  return;
+}
+
diff -urN src/gdb/testsuite/gdb.base/solib_symbol.exp dev/gdb/testsuite/gdb.base/solib_symbol.exp
--- src/gdb/testsuite/gdb.base/solib_symbol.exp	1970-01-01 01:00:00.000000000 +0100
+++ dev/gdb/testsuite/gdb.base/solib_symbol.exp	2007-06-05 05:30:07.000000000 +0200
@@ -0,0 +1,80 @@
+# Copyright 2007 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 2 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+#
+# Contributed by Markus Deuling <deuling@de.ibm.com>.
+#
+
+if {[skip_shlib_tests]} {
+    return 0
+}
+
+# Library file.
+set libname "libmd"
+set srcfile_lib ${srcdir}/${subdir}/${libname}.c
+set binfile_lib ${objdir}/${subdir}/${libname}.so
+set lib_flags [list debug ldflags=-Wl,-Bsymbolic]
+# Binary file.
+set testfile "solib_symbol"
+set srcfile ${srcdir}/${subdir}/${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+set bin_flags [list debug shlib=${binfile_lib}]
+
+if [get_compiler_info ${binfile}] {
+    return -1
+}
+
+if { [gdb_compile_shlib ${srcfile_lib} ${binfile_lib} $lib_flags] != ""
+     || [gdb_compile ${srcfile} ${binfile} executable $bin_flags] != "" } {
+  untested "Could not compile $binfile_lib or $binfile."
+  return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+gdb_load_shlibs $binfile_lib
+
+if ![runto_main] then {
+  fail "Can't run to main"
+  return 0
+}
+
+# Set a breakpoint in the binary.
+gdb_test "br foo2" \
+	 "Breakpoint.*file.*${srcfile}.*" \
+	 "foo2 in main"
+
+delete_breakpoints
+
+# Break in the library.
+gdb_test "br foo" \
+	 "" \
+	 "foo in libmd"
+
+gdb_test "continue" \
+	 "Continuing.*" \
+	 "continue"
+
+# This symbol is now looked up in the ELF library.
+gdb_test "br foo2" \
+	 "Breakpoint.*file.*${srcfile_lib}.*" \
+	 "foo2 in mdlib"
+
+gdb_exit
+
+return 0
+
+

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PING 2] [rfc]: Framework for looking up multiply defined global        symbols  in shared libraries
  2007-06-05  3:46         ` Markus Deuling
@ 2007-06-20  6:58           ` Markus Deuling
  2007-06-26 18:31             ` Joel Brobecker
  2007-06-26 18:35             ` Joel Brobecker
  2007-06-25 21:48           ` [PING] " Kevin Buettner
  1 sibling, 2 replies; 24+ messages in thread
From: Markus Deuling @ 2007-06-20  6:58 UTC (permalink / raw)
  To: GDB Patches, Ulrich Weigand; +Cc: Daniel Jacobowitz, Kevin Buettner


> Ulrich Weigand wrote:
>> Markus Deuling wrote:
>>
>> It looks like this duplicates a whole bunch of code from elf_locate_base.
>> Maybe we should extract a helper routine that retrieves a given DT_ tag
>> from the .dynamic section?
>>
>>
>>> +/* Look up OBJFILE to BLOCK.  */
>>> +
>>> +struct objfile *
>>> +lookup_objfile_from_block (const struct block *block)
>>
>> I guess this could be static now.
>>
>>> +/* Lookup objfile to a block.  */
>>> +extern struct objfile *
>>> +lookup_objfile_from_block (const struct block *block);
>>
>> If we make it static, this should go away.  Otherwise, the function name
>> should again not start in the first column for the prototype.
>>
>>
>> Bye,
>> Ulrich
>>
> 
> thank you very much for your input. I reworked the patch. There is now a 
> helper routine to extract DT_ tags from
> .dynamic section called scan_dyntag. Testsuite on x86 showed no regression.
> 
> Is this ok to commit?

Hello,
it would be great to have that one in for 6.7 :-) Is this ok ?


> 
> ChangeLog:
> 
>     * cp-namespace.c (lookup_symbol_file): Add block to
>     lookup_symbol_global call.
>     * Makefile.in (solist_h): Add dependency on symtab header.
>     (solib.o): Add dependency on objfiles header.
>     (symtab.o): Add dependency on solist header.
>     * solib.c (solib_global_lookup): New function.
>     * solib-svr4.c (scan_dyntag): Likewise.
>     (elf_locate_base): Call helper routine scan_dyntag.
>     (elf_lookup_lib_symbol): New function.
>     (_initialize_svr4_solib): Add elf_lookup_lib_symbol to svr4_so_ops.
>     * solist.h (symtab.h): New include.
>     (lookup_lib_global_symbol): New prototype.
>     (solib_global_lookup): Likewise.
>     * symtab.c: New include solist.h.
>     (lookup_objfile_from_block): New function.
>     (lookup_global_symbol_from_objfile): New function.
>     (basic_lookup_symbol_nonlocal): Add block to lookup_symbol_global call.
>     (lookup_symbol_global): Call library-specific lookup procedure.
>     * symtab.h (lookup_global_symbol_from_objfile): New prototype.
>     * gdb.base/libmd.c: New file (testcase multiple symbol lookup).
>     * gdb.base/libmd.h: Likewise.
>     * gdb.base/solib_symbol.c: Likewise.
>     * gdb.base/solib_symbol.exp: Likewise.
> 
> 
> ------------------------------------------------------------------------
> 
> diff -urN src/gdb/cp-namespace.c dev/gdb/cp-namespace.c
> --- src/gdb/cp-namespace.c	2007-01-09 18:58:50.000000000 +0100
> +++ dev/gdb/cp-namespace.c	2007-06-05 05:30:07.000000000 +0200
> @@ -491,7 +491,7 @@
>      }
>    else
>      {
> -      sym = lookup_symbol_global (name, linkage_name, domain, symtab);
> +      sym = lookup_symbol_global (name, linkage_name, block, domain, symtab);
>      }
>  
>    if (sym != NULL)
> diff -urN src/gdb/Makefile.in dev/gdb/Makefile.in
> --- src/gdb/Makefile.in	2007-05-29 08:01:14.000000000 +0200
> +++ dev/gdb/Makefile.in	2007-06-05 05:30:07.000000000 +0200
> @@ -797,7 +797,7 @@
>  solib_pa64_h = solib-pa64.h
>  solib_som_h = solib-som.h
>  solib_svr4_h = solib-svr4.h
> -solist_h = solist.h
> +solist_h = solist.h $(symtab_h)
>  source_h = source.h
>  sparc64_tdep_h = sparc64-tdep.h $(sparc_tdep_h)
>  sparc_nat_h = sparc-nat.h
> @@ -2568,7 +2568,7 @@
>  	$(objfiles_h) $(exceptions_h) $(gdbcore_h) $(command_h) $(target_h) \
>  	$(frame_h) $(gdb_regex_h) $(inferior_h) $(environ_h) $(language_h) \
>  	$(gdbcmd_h) $(completer_h) $(filenames_h) $(exec_h) $(solist_h) \
> -	$(observer_h) $(readline_h)
> +	$(observer_h) $(readline_h) $(objfiles_h)
>  solib-frv.o: solib-frv.c $(defs_h) $(gdb_string_h) $(inferior_h) \
>  	$(gdbcore_h) $(solist_h) $(frv_tdep_h) $(objfiles_h) $(symtab_h) \
>  	$(language_h) $(command_h) $(gdbcmd_h) $(elf_frv_h) $(solib_h)
> @@ -2715,7 +2715,8 @@
>  	$(language_h) $(demangle_h) $(inferior_h) $(linespec_h) $(source_h) \
>  	$(filenames_h) $(objc_lang_h) $(ada_lang_h) $(hashtab_h) \
>  	$(gdb_obstack_h) $(block_h) $(dictionary_h) $(gdb_string_h) \
> -	$(gdb_stat_h) $(cp_abi_h) $(observer_h) $(gdb_assert_h)
> +	$(gdb_stat_h) $(cp_abi_h) $(observer_h) $(gdb_assert_h) \
> +	$(solist_h)
>  target.o: target.c $(defs_h) $(gdb_string_h) $(target_h) $(gdbcmd_h) \
>  	$(symtab_h) $(inferior_h) $(bfd_h) $(symfile_h) $(objfiles_h) \
>  	$(gdb_wait_h) $(dcache_h) $(regcache_h) $(gdb_assert_h) $(gdbcore_h) \
> diff -urN src/gdb/solib.c dev/gdb/solib.c
> --- src/gdb/solib.c	2007-05-16 16:07:56.000000000 +0200
> +++ dev/gdb/solib.c	2007-06-05 05:30:07.000000000 +0200
> @@ -955,6 +955,24 @@
>  }
>  
>  
> +/* Handler for library-specific lookup of global symbol NAME in OBJFILE.  Call
> +   the library-specific handler if it is installed for the current target.  */
> +
> +struct symbol *
> +solib_global_lookup (const struct objfile *objfile,
> +		     const char *name,
> +		     const char *linkage_name,
> +		     const domain_enum domain,
> +		     struct symtab **symtab)
> +{
> +  if (current_target_so_ops->lookup_lib_global_symbol != NULL)
> +    return current_target_so_ops->lookup_lib_global_symbol (objfile,
> +				name, linkage_name, domain, symtab);
> +
> +  return NULL;
> +}
> +
> +
>  extern initialize_file_ftype _initialize_solib; /* -Wmissing-prototypes */
>  
>  void
> diff -urN src/gdb/solib-svr4.c dev/gdb/solib-svr4.c
> --- src/gdb/solib-svr4.c	2007-06-04 05:41:43.000000000 +0200
> +++ dev/gdb/solib-svr4.c	2007-06-05 05:35:58.000000000 +0200
> @@ -354,6 +354,76 @@
>    return symaddr;
>  }
>  
> +/* Scan for DYNTAG in .dynamic section of ABFD. If DYNTAG is found 1 is
> +   returned and the corresponding PTR is set.  */
> +
> +static int
> +scan_dyntag (int dyntag, bfd *abfd, CORE_ADDR *ptr)
> +{
> +  int arch_size, step, sect_size;
> +  long dyn_tag;
> +  CORE_ADDR dyn_ptr, dyn_addr;
> +  gdb_byte *bufend, *buf;
> +  Elf32_External_Dyn *x_dynp_32;
> +  Elf64_External_Dyn *x_dynp_64;
> +  struct bfd_section *sect;
> +
> +  if (abfd == NULL)
> +    return 0;
> +  arch_size = bfd_get_arch_size (abfd);
> +  if (arch_size == -1)
> +   return 0;
> +
> +  /* Find the start address of the .dynamic section.  */
> +  sect = bfd_get_section_by_name (abfd, ".dynamic");
> +  if (sect == NULL)
> +    return 0;
> +  dyn_addr = bfd_section_vma (abfd, sect);
> +
> +  /* Read in .dynamic section, silently ignore errors.  */
> +  sect_size = bfd_section_size (abfd, sect);
> +  buf = alloca (sect_size);
> +  if (target_read_memory (dyn_addr, buf, sect_size))
> +    {
> +      /* If target_read_memory fails, try reading the BFD file.  */
> +      if (!bfd_get_section_contents (abfd, sect,
> +				     buf, 0, sect_size))
> +	return 0;
> +    }
> +
> +  /* Iterate over BUF and scan for DYNTAG.  If found, set PTR and return.  */
> +  step = (arch_size == 32) ? sizeof (Elf32_External_Dyn)
> +			   : sizeof (Elf64_External_Dyn);
> +  for (bufend = buf + sect_size;
> +       buf < bufend;
> +       buf += step)
> +  {
> +    if (arch_size == 32)
> +      {
> +	x_dynp_32 = (Elf32_External_Dyn *) buf;
> +	dyn_tag = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_tag);
> +	dyn_ptr = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_un.d_ptr);
> +      }
> +      else
> +      {
> +	x_dynp_64 = (Elf64_External_Dyn *) buf;
> +	dyn_tag = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_tag);
> +	dyn_ptr = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_un.d_ptr);
> +      }
> +     if (dyn_tag == DT_NULL)
> +       return 0;
> +     if (dyn_tag == dyntag)
> +       {
> +	 if (ptr)
> +	   *ptr = dyn_ptr;
> +         return 1;
> +       }
> +  }
> +
> +  return 0;
> +}
> +
> +
>  /*
>  
>     LOCAL FUNCTION
> @@ -381,114 +451,31 @@
>  static CORE_ADDR
>  elf_locate_base (void)
>  {
> -  struct bfd_section *dyninfo_sect;
> -  int dyninfo_sect_size;
> -  CORE_ADDR dyninfo_addr;
> -  gdb_byte *buf;
> -  gdb_byte *bufend;
> -  int arch_size;
> +  struct minimal_symbol *msymbol;
> +  CORE_ADDR dyn_ptr;
>  
> -  /* Find the start address of the .dynamic section.  */
> -  dyninfo_sect = bfd_get_section_by_name (exec_bfd, ".dynamic");
> -  if (dyninfo_sect == NULL)
> +  /* Find DT_DEBUG.  */
> +  if (scan_dyntag (DT_DEBUG, exec_bfd, &dyn_ptr))
> +    return dyn_ptr;
> +
> +  /* Find DT_MIPS_RLD_MAP.  */
> +  if (scan_dyntag (DT_MIPS_RLD_MAP, exec_bfd, &dyn_ptr))
>      {
> -      /* This may be a static executable.  Look for the symbol
> -	 conventionally named _r_debug, as a last resort.  */
> -      struct minimal_symbol *msymbol;
> -
> -      msymbol = lookup_minimal_symbol ("_r_debug", NULL, symfile_objfile);
> -      if (msymbol != NULL)
> -	return SYMBOL_VALUE_ADDRESS (msymbol);
> -      else
> +      gdb_byte *pbuf;
> +      int pbuf_size = TYPE_LENGTH (builtin_type_void_data_ptr);
> +      pbuf = alloca (pbuf_size);
> +      /* DT_MIPS_RLD_MAP contains a pointer to the address
> +	 of the dynamic link structure.  */
> +      if (target_read_memory (dyn_ptr, pbuf, pbuf_size))
>  	return 0;
> +      return extract_typed_address (pbuf, builtin_type_void_data_ptr);
>      }
>  
> -  dyninfo_addr = bfd_section_vma (exec_bfd, dyninfo_sect);
> -
> -  /* Read in .dynamic section, silently ignore errors.  */
> -  dyninfo_sect_size = bfd_section_size (exec_bfd, dyninfo_sect);
> -  buf = alloca (dyninfo_sect_size);
> -  if (target_read_memory (dyninfo_addr, buf, dyninfo_sect_size))
> -    return 0;
> -
> -  /* Find the DT_DEBUG entry in the the .dynamic section.
> -     For mips elf we look for DT_MIPS_RLD_MAP, mips elf apparently has
> -     no DT_DEBUG entries.  */
> -
> -  arch_size = bfd_get_arch_size (exec_bfd);
> -  if (arch_size == -1)	/* failure */
> -    return 0;
> -
> -  if (arch_size == 32)
> -    { /* 32-bit elf */
> -      for (bufend = buf + dyninfo_sect_size;
> -	   buf < bufend;
> -	   buf += sizeof (Elf32_External_Dyn))
> -	{
> -	  Elf32_External_Dyn *x_dynp = (Elf32_External_Dyn *) buf;
> -	  long dyn_tag;
> -	  CORE_ADDR dyn_ptr;
> -
> -	  dyn_tag = bfd_h_get_32 (exec_bfd, (bfd_byte *) x_dynp->d_tag);
> -	  if (dyn_tag == DT_NULL)
> -	    break;
> -	  else if (dyn_tag == DT_DEBUG)
> -	    {
> -	      dyn_ptr = bfd_h_get_32 (exec_bfd, 
> -				      (bfd_byte *) x_dynp->d_un.d_ptr);
> -	      return dyn_ptr;
> -	    }
> -	  else if (dyn_tag == DT_MIPS_RLD_MAP)
> -	    {
> -	      gdb_byte *pbuf;
> -	      int pbuf_size = TYPE_LENGTH (builtin_type_void_data_ptr);
> -
> -	      pbuf = alloca (pbuf_size);
> -	      /* DT_MIPS_RLD_MAP contains a pointer to the address
> -		 of the dynamic link structure.  */
> -	      dyn_ptr = bfd_h_get_32 (exec_bfd, 
> -				      (bfd_byte *) x_dynp->d_un.d_ptr);
> -	      if (target_read_memory (dyn_ptr, pbuf, pbuf_size))
> -		return 0;
> -	      return extract_typed_address (pbuf, builtin_type_void_data_ptr);
> -	    }
> -	}
> -    }
> -  else /* 64-bit elf */
> -    {
> -      for (bufend = buf + dyninfo_sect_size;
> -	   buf < bufend;
> -	   buf += sizeof (Elf64_External_Dyn))
> -	{
> -	  Elf64_External_Dyn *x_dynp = (Elf64_External_Dyn *) buf;
> -	  long dyn_tag;
> -	  CORE_ADDR dyn_ptr;
> -
> -	  dyn_tag = bfd_h_get_64 (exec_bfd, (bfd_byte *) x_dynp->d_tag);
> -	  if (dyn_tag == DT_NULL)
> -	    break;
> -	  else if (dyn_tag == DT_DEBUG)
> -	    {
> -	      dyn_ptr = bfd_h_get_64 (exec_bfd, 
> -				      (bfd_byte *) x_dynp->d_un.d_ptr);
> -	      return dyn_ptr;
> -	    }
> -	  else if (dyn_tag == DT_MIPS_RLD_MAP)
> -	    {
> -	      gdb_byte *pbuf;
> -	      int pbuf_size = TYPE_LENGTH (builtin_type_void_data_ptr);
> -
> -	      pbuf = alloca (pbuf_size);
> -	      /* DT_MIPS_RLD_MAP contains a pointer to the address
> -		 of the dynamic link structure.  */
> -	      dyn_ptr = bfd_h_get_64 (exec_bfd, 
> -				      (bfd_byte *) x_dynp->d_un.d_ptr);
> -	      if (target_read_memory (dyn_ptr, pbuf, pbuf_size))
> -		return 0;
> -	      return extract_typed_address (pbuf, builtin_type_void_data_ptr);
> -	    }
> -	}
> -    }
> +  /* This may be a static executable.  Look for the symbol
> +     conventionally named _r_debug, as a last resort.  */
> +  msymbol = lookup_minimal_symbol ("_r_debug", NULL, symfile_objfile);
> +  if (msymbol != NULL)
> +    return SYMBOL_VALUE_ADDRESS (msymbol);
>  
>    /* DT_DEBUG entry not found.  */
>    return 0;
> @@ -1554,6 +1541,24 @@
>  
>  struct target_so_ops svr4_so_ops;
>  
> +/* Lookup global symbol for ELF DSOs linked with -Bsymbolic. Those DSOs have a
> +   different rule for symbol lookup.  The lookup begins here in the DSO, not in
> +   the main executable.  */
> +
> +static struct symbol *
> +elf_lookup_lib_symbol (const struct objfile *objfile,
> +		       const char *name,
> +		       const char *linkage_name,
> +		       const domain_enum domain, struct symtab **symtab)
> +{
> +  if (objfile->obfd == NULL
> +     || scan_dyntag (DT_SYMBOLIC, objfile->obfd, NULL) != 1)
> +    return NULL;
> +
> +  return  lookup_global_symbol_from_objfile
> +		(objfile, name, linkage_name, domain, symtab);
> +}
> +
>  extern initialize_file_ftype _initialize_svr4_solib; /* -Wmissing-prototypes */
>  
>  void
> @@ -1569,6 +1574,7 @@
>    svr4_so_ops.current_sos = svr4_current_sos;
>    svr4_so_ops.open_symbol_file_object = open_symbol_file_object;
>    svr4_so_ops.in_dynsym_resolve_code = svr4_in_dynsym_resolve_code;
> +  svr4_so_ops.lookup_lib_global_symbol = elf_lookup_lib_symbol;
>  
>    /* FIXME: Don't do this here.  *_gdbarch_init() should set so_ops. */
>    current_target_so_ops = &svr4_so_ops;
> diff -urN src/gdb/solist.h dev/gdb/solist.h
> --- src/gdb/solist.h	2007-01-09 18:58:58.000000000 +0100
> +++ dev/gdb/solist.h	2007-06-05 05:30:07.000000000 +0200
> @@ -23,6 +23,8 @@
>  #define SOLIST_H
>  
>  #define SO_NAME_MAX_PATH_SIZE 512	/* FIXME: Should be dynamic */
> +/* For domain_enum domain.  */
> +#include "symtab.h"
>  
>  /* Forward declaration for target specific link map information.  This
>     struct is opaque to all but the target specific file.  */
> @@ -103,7 +105,14 @@
>         Convenience function for remote debuggers finding host libs.  */
>      int (*find_and_open_solib) (char *soname,
>          unsigned o_flags, char **temp_pathname);
> -    
> +
> +    /* Hook for looking up global symbols in a library-specific way.  */
> +    struct symbol * (*lookup_lib_global_symbol) (const struct objfile *objfile,
> +						 const char *name,
> +						 const char *linkage_name,
> +						 const domain_enum domain,
> +						 struct symtab **symtab);
> +
>    };
>  
>  /* Free the memory associated with a (so_list *).  */
> @@ -125,4 +134,11 @@
>  #define TARGET_SO_IN_DYNSYM_RESOLVE_CODE \
>    (current_target_so_ops->in_dynsym_resolve_code)
>  
> +/* Handler for library-specific global symbol lookup in solib.c.  */
> +struct symbol *solib_global_lookup (const struct objfile *objfile,
> +				    const char *name,
> +				    const char *linkage_name,
> +				    const domain_enum domain,
> +				    struct symtab **symtab);
> +
>  #endif
> diff -urN src/gdb/symtab.c dev/gdb/symtab.c
> --- src/gdb/symtab.c	2007-04-17 17:07:21.000000000 +0200
> +++ dev/gdb/symtab.c	2007-06-05 05:30:07.000000000 +0200
> @@ -57,6 +57,7 @@
>  #include "cp-abi.h"
>  #include "observer.h"
>  #include "gdb_assert.h"
> +#include "solist.h"
>  
>  /* Prototypes for local functions */
>  
> @@ -1265,6 +1266,26 @@
>    return NULL;
>  }
>  
> +/* Look up OBJFILE to BLOCK.  */
> +
> +static struct objfile *
> +lookup_objfile_from_block (const struct block *block)
> +{
> +  struct objfile *obj;
> +  struct symtab *s;
> +
> +  if (block == NULL)
> +    return NULL;
> +
> +  block = block_global_block (block);
> +  /* Go through SYMTABS.  */
> +  ALL_SYMTABS (obj, s)
> +    if (block == BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK))
> +      return obj;
> +
> +  return NULL;
> +}
> +
>  /* Look up a symbol in a block; if found, locate its symtab, fixup the
>     symbol, and set block_found appropriately.  */
>  
> @@ -1306,6 +1327,57 @@
>    return NULL;
>  }
>  
> +/* Check all global symbols in OBJFILE in symtabs and
> +   psymtabs.  */
> +
> +struct symbol *
> +lookup_global_symbol_from_objfile (const struct objfile *objfile,
> +				   const char *name,
> +				   const char *linkage_name,
> +				   const domain_enum domain,
> +				   struct symtab **symtab)
> +{
> +  struct symbol *sym;
> +  struct blockvector *bv;
> +  const struct block *block;
> +  struct symtab *s;
> +  struct partial_symtab *ps;
> +
> +  /* Go through symtabs.  */
> +  ALL_OBJFILE_SYMTABS (objfile, s)
> +  {
> +    bv = BLOCKVECTOR (s);
> +    block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
> +    sym = lookup_block_symbol (block, name, linkage_name, domain);
> +    if (sym)
> +      {
> +	block_found = block;
> +	if (symtab != NULL)
> +	  *symtab = s;
> +	return fixup_symbol_section (sym, (struct objfile *)objfile);
> +      }
> +  }
> +
> +  /* Now go through psymtabs.  */
> +  ALL_OBJFILE_PSYMTABS (objfile, ps)
> +  {
> +    if (!ps->readin
> +	&& lookup_partial_symbol (ps, name, linkage_name,
> +				  1, domain))
> +      {
> +	s = PSYMTAB_TO_SYMTAB (ps);
> +	bv = BLOCKVECTOR (s);
> +	block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
> +	sym = lookup_block_symbol (block, name, linkage_name, domain);
> +	if (symtab != NULL)
> +	  *symtab = s;
> +	return fixup_symbol_section (sym, (struct objfile *)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,
>     depending on whether or not we want to search global symbols or
> @@ -1571,7 +1643,7 @@
>    if (sym != NULL)
>      return sym;
>  
> -  return lookup_symbol_global (name, linkage_name, domain, symtab);
> +  return lookup_symbol_global (name, linkage_name, block, domain, symtab);
>  }
>  
>  /* Lookup a symbol in the static block associated to BLOCK, if there
> @@ -1599,10 +1671,19 @@
>  struct symbol *
>  lookup_symbol_global (const char *name,
>  		      const char *linkage_name,
> +		      const struct block *block,
>  		      const domain_enum domain,
>  		      struct symtab **symtab)
>  {
> -  struct symbol *sym;
> +  struct symbol *sym = NULL;
> +  struct objfile *objfile = NULL;
> +
> +  /* Call library-specific lookup procedure.  */
> +  objfile = lookup_objfile_from_block (block);
> +  if (objfile != NULL)
> +    sym = solib_global_lookup (objfile, name, linkage_name, domain, symtab);
> +  if (sym != NULL)
> +    return sym;
>  
>    sym = lookup_symbol_aux_symtabs (GLOBAL_BLOCK, name, linkage_name,
>  				   domain, symtab);
> diff -urN src/gdb/symtab.h dev/gdb/symtab.h
> --- src/gdb/symtab.h	2007-03-28 02:12:15.000000000 +0200
> +++ dev/gdb/symtab.h	2007-06-05 05:30:07.000000000 +0200
> @@ -1050,6 +1050,7 @@
>  
>  extern struct symbol *lookup_symbol_global (const char *name,
>  					    const char *linkage_name,
> +					    const struct block *block,
>  					    const domain_enum domain,
>  					    struct symtab **symtab);
>  
> @@ -1403,4 +1404,12 @@
>     Defined in symtab.c, used in hppa-tdep.c. */
>  extern int deprecated_hp_som_som_object_present;
>  
> +/* Check global symbols in objfile.  */
> +struct symbol *lookup_global_symbol_from_objfile (const struct objfile *objfile,
> +						  const char *name,
> +						  const char *linkage_name,
> +						  const domain_enum domain,
> +						  struct symtab **symtab);
> +
> +
>  #endif /* !defined(SYMTAB_H) */
> diff -urN src/gdb/testsuite/gdb.base/libmd.c dev/gdb/testsuite/gdb.base/libmd.c
> --- src/gdb/testsuite/gdb.base/libmd.c	1970-01-01 01:00:00.000000000 +0100
> +++ dev/gdb/testsuite/gdb.base/libmd.c	2007-06-05 05:30:07.000000000 +0200
> @@ -0,0 +1,36 @@
> +/* Copyright 2007 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 2 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, write to the Free Software
> +   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
> +
> +   Contributed by Markus Deuling <deuling@de.ibm.com>.
> +*/
> +extern void foo();
> +#include <stdio.h>
> +#include "libmd.h"
> +
> +void foo2 ();
> +
> +void
> +foo ()
> +{
> +  printf ("foo in lib\n");
> +  return;
> +}
> +
> +void
> +foo2()
> +{
> +  printf ("foo2 in lib\n");
> +  return;
> +}
> diff -urN src/gdb/testsuite/gdb.base/libmd.h dev/gdb/testsuite/gdb.base/libmd.h
> --- src/gdb/testsuite/gdb.base/libmd.h	1970-01-01 01:00:00.000000000 +0100
> +++ dev/gdb/testsuite/gdb.base/libmd.h	2007-06-05 05:30:07.000000000 +0200
> @@ -0,0 +1,18 @@
> +/* Copyright 2007 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 2 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, write to the Free Software
> +   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
> +
> +   Contributed by Markus Deuling <deuling@de.ibm.com>.
> +*/
> +extern void foo();
> diff -urN src/gdb/testsuite/gdb.base/solib_symbol.c dev/gdb/testsuite/gdb.base/solib_symbol.c
> --- src/gdb/testsuite/gdb.base/solib_symbol.c	1970-01-01 01:00:00.000000000 +0100
> +++ dev/gdb/testsuite/gdb.base/solib_symbol.c	2007-06-05 05:30:07.000000000 +0200
> @@ -0,0 +1,45 @@
> +/* Copyright 2007 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 2 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, write to the Free Software
> +   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
> +
> +   Contributed by Markus Deuling <deuling@de.ibm.com>.
> +*/
> +extern void foo();
> +#include <stdio.h>
> +#include "libmd.h"
> +
> +extern void foo();
> +void foo3();
> +void foo2();
> +
> +int main ()
> +{
> +  printf ("in main\n");
> +  foo ();
> +  foo3 ();
> +  return 0;
> +}
> +
> +void foo3()
> +{
> +  printf ("foo3 in main\n");
> +  return;
> +}
> +
> +void foo2()
> +{
> +  printf ("foo2 in main\n");
> +  return;
> +}
> +
> diff -urN src/gdb/testsuite/gdb.base/solib_symbol.exp dev/gdb/testsuite/gdb.base/solib_symbol.exp
> --- src/gdb/testsuite/gdb.base/solib_symbol.exp	1970-01-01 01:00:00.000000000 +0100
> +++ dev/gdb/testsuite/gdb.base/solib_symbol.exp	2007-06-05 05:30:07.000000000 +0200
> @@ -0,0 +1,80 @@
> +# Copyright 2007 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 2 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, write to the Free Software
> +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
> +#
> +# Contributed by Markus Deuling <deuling@de.ibm.com>.
> +#
> +
> +if {[skip_shlib_tests]} {
> +    return 0
> +}
> +
> +# Library file.
> +set libname "libmd"
> +set srcfile_lib ${srcdir}/${subdir}/${libname}.c
> +set binfile_lib ${objdir}/${subdir}/${libname}.so
> +set lib_flags [list debug ldflags=-Wl,-Bsymbolic]
> +# Binary file.
> +set testfile "solib_symbol"
> +set srcfile ${srcdir}/${subdir}/${testfile}.c
> +set binfile ${objdir}/${subdir}/${testfile}
> +set bin_flags [list debug shlib=${binfile_lib}]
> +
> +if [get_compiler_info ${binfile}] {
> +    return -1
> +}
> +
> +if { [gdb_compile_shlib ${srcfile_lib} ${binfile_lib} $lib_flags] != ""
> +     || [gdb_compile ${srcfile} ${binfile} executable $bin_flags] != "" } {
> +  untested "Could not compile $binfile_lib or $binfile."
> +  return -1
> +}
> +
> +gdb_exit
> +gdb_start
> +gdb_reinitialize_dir $srcdir/$subdir
> +gdb_load ${binfile}
> +gdb_load_shlibs $binfile_lib
> +
> +if ![runto_main] then {
> +  fail "Can't run to main"
> +  return 0
> +}
> +
> +# Set a breakpoint in the binary.
> +gdb_test "br foo2" \
> +	 "Breakpoint.*file.*${srcfile}.*" \
> +	 "foo2 in main"
> +
> +delete_breakpoints
> +
> +# Break in the library.
> +gdb_test "br foo" \
> +	 "" \
> +	 "foo in libmd"
> +
> +gdb_test "continue" \
> +	 "Continuing.*" \
> +	 "continue"
> +
> +# This symbol is now looked up in the ELF library.
> +gdb_test "br foo2" \
> +	 "Breakpoint.*file.*${srcfile_lib}.*" \
> +	 "foo2 in mdlib"
> +
> +gdb_exit
> +
> +return 0
> +
> +


-- 
Markus Deuling
GNU Toolchain for Linux on Cell BE
deuling@de.ibm.com


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PING] [rfc]: Framework for looking up multiply defined global       symbols  in shared libraries
  2007-06-05  3:46         ` Markus Deuling
  2007-06-20  6:58           ` [PING 2] " Markus Deuling
@ 2007-06-25 21:48           ` Kevin Buettner
  1 sibling, 0 replies; 24+ messages in thread
From: Kevin Buettner @ 2007-06-25 21:48 UTC (permalink / raw)
  To: gdb-patches

On Tue, 05 Jun 2007 05:44:35 +0200
Markus Deuling <deuling@de.ibm.com> wrote:

> Is this ok to commit?
> 
> ChangeLog:
> 
> 	* cp-namespace.c (lookup_symbol_file): Add block to
> 	lookup_symbol_global call.
> 	* Makefile.in (solist_h): Add dependency on symtab header.
> 	(solib.o): Add dependency on objfiles header.
> 	(symtab.o): Add dependency on solist header.
> 	* solib.c (solib_global_lookup): New function.
> 	* solib-svr4.c (scan_dyntag): Likewise.
> 	(elf_locate_base): Call helper routine scan_dyntag.
> 	(elf_lookup_lib_symbol): New function.
> 	(_initialize_svr4_solib): Add elf_lookup_lib_symbol to svr4_so_ops.
> 	* solist.h (symtab.h): New include.
> 	(lookup_lib_global_symbol): New prototype.
> 	(solib_global_lookup): Likewise.
> 	* symtab.c: New include solist.h.
> 	(lookup_objfile_from_block): New function.
> 	(lookup_global_symbol_from_objfile): New function.
> 	(basic_lookup_symbol_nonlocal): Add block to lookup_symbol_global call.
> 	(lookup_symbol_global): Call library-specific lookup procedure.
> 	* symtab.h (lookup_global_symbol_from_objfile): New prototype.
> 	* gdb.base/libmd.c: New file (testcase multiple symbol lookup).
> 	* gdb.base/libmd.h: Likewise.
> 	* gdb.base/solib_symbol.c: Likewise.
> 	* gdb.base/solib_symbol.exp: Likewise.

Your changes to solib.c, solib-svr.c, and solist.h are approved.

Kevin


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PING 2] [rfc]: Framework for looking up multiply defined global        symbols  in shared libraries
  2007-06-20  6:58           ` [PING 2] " Markus Deuling
@ 2007-06-26 18:31             ` Joel Brobecker
  2007-06-26 18:35             ` Joel Brobecker
  1 sibling, 0 replies; 24+ messages in thread
From: Joel Brobecker @ 2007-06-26 18:31 UTC (permalink / raw)
  To: Markus Deuling
  Cc: GDB Patches, Ulrich Weigand, Daniel Jacobowitz, Kevin Buettner

Marcus,

> it would be great to have that one in for 6.7 :-) Is this ok ?

If your changes make it before the branch cutoff point, then they will
be part of GDB 6.7. Otherwise, I am not comfortable having this ported
to the branch. I still haven't completely finished reviewing the
release-critical items for 6.7, so the cutoff point is still undecided,
but I think it will be very soon.

-- 
Joel


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PING 2] [rfc]: Framework for looking up multiply defined global        symbols  in shared libraries
  2007-06-20  6:58           ` [PING 2] " Markus Deuling
  2007-06-26 18:31             ` Joel Brobecker
@ 2007-06-26 18:35             ` Joel Brobecker
  2007-06-26 20:34               ` Markus Deuling
  1 sibling, 1 reply; 24+ messages in thread
From: Joel Brobecker @ 2007-06-26 18:35 UTC (permalink / raw)
  To: Markus Deuling
  Cc: GDB Patches, Ulrich Weigand, Daniel Jacobowitz, Kevin Buettner

> >ChangeLog:
> >
> >    * cp-namespace.c (lookup_symbol_file): Add block to
> >    lookup_symbol_global call.
> >    * Makefile.in (solist_h): Add dependency on symtab header.
> >    (solib.o): Add dependency on objfiles header.
> >    (symtab.o): Add dependency on solist header.
> >    * solib.c (solib_global_lookup): New function.
> >    * solib-svr4.c (scan_dyntag): Likewise.
> >    (elf_locate_base): Call helper routine scan_dyntag.
> >    (elf_lookup_lib_symbol): New function.
> >    (_initialize_svr4_solib): Add elf_lookup_lib_symbol to svr4_so_ops.
> >    * solist.h (symtab.h): New include.
> >    (lookup_lib_global_symbol): New prototype.
> >    (solib_global_lookup): Likewise.
> >    * symtab.c: New include solist.h.
> >    (lookup_objfile_from_block): New function.
> >    (lookup_global_symbol_from_objfile): New function.
> >    (basic_lookup_symbol_nonlocal): Add block to lookup_symbol_global call.
> >    (lookup_symbol_global): Call library-specific lookup procedure.
> >    * symtab.h (lookup_global_symbol_from_objfile): New prototype.
> >    * gdb.base/libmd.c: New file (testcase multiple symbol lookup).
> >    * gdb.base/libmd.h: Likewise.
> >    * gdb.base/solib_symbol.c: Likewise.
> >    * gdb.base/solib_symbol.exp: Likewise.

Would this be worthy of a NEWs entry?

-- 
Joel


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PING 2] [rfc]: Framework for looking up multiply defined global         symbols  in shared libraries
  2007-06-26 18:35             ` Joel Brobecker
@ 2007-06-26 20:34               ` Markus Deuling
  2007-06-28 15:32                 ` Ulrich Weigand
  0 siblings, 1 reply; 24+ messages in thread
From: Markus Deuling @ 2007-06-26 20:34 UTC (permalink / raw)
  To: Joel Brobecker
  Cc: GDB Patches, Ulrich Weigand, Daniel Jacobowitz, Kevin Buettner

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

Joel Brobecker wrote:
>>> ChangeLog:
>>>
>>>    * cp-namespace.c (lookup_symbol_file): Add block to
>>>    lookup_symbol_global call.
>>>    * Makefile.in (solist_h): Add dependency on symtab header.
>>>    (solib.o): Add dependency on objfiles header.
>>>    (symtab.o): Add dependency on solist header.
>>>    * solib.c (solib_global_lookup): New function.
>>>    * solib-svr4.c (scan_dyntag): Likewise.
>>>    (elf_locate_base): Call helper routine scan_dyntag.
>>>    (elf_lookup_lib_symbol): New function.
>>>    (_initialize_svr4_solib): Add elf_lookup_lib_symbol to svr4_so_ops.
>>>    * solist.h (symtab.h): New include.
>>>    (lookup_lib_global_symbol): New prototype.
>>>    (solib_global_lookup): Likewise.
>>>    * symtab.c: New include solist.h.
>>>    (lookup_objfile_from_block): New function.
>>>    (lookup_global_symbol_from_objfile): New function.
>>>    (basic_lookup_symbol_nonlocal): Add block to lookup_symbol_global call.
>>>    (lookup_symbol_global): Call library-specific lookup procedure.
>>>    * symtab.h (lookup_global_symbol_from_objfile): New prototype.
>>>    * gdb.base/libmd.c: New file (testcase multiple symbol lookup).
>>>    * gdb.base/libmd.h: Likewise.
>>>    * gdb.base/solib_symbol.c: Likewise.
>>>    * gdb.base/solib_symbol.exp: Likewise.
> 
> Would this be worthy of a NEWs entry?
> 

Thank you, I now added an entry to NEWS file. Attached is the new patch.

ChangeLog:

	* cp-namespace.c (lookup_symbol_file): Add block to
	lookup_symbol_global call.
	* Makefile.in (solist_h): Add dependency on symtab header.
	(solib.o): Add dependency on objfiles header.
	(symtab.o): Add dependency on solist header.
	* solib.c (solib_global_lookup): New function.
	* solib-svr4.c (scan_dyntag): Likewise.
	(elf_locate_base): Call helper routine scan_dyntag.
	(elf_lookup_lib_symbol): New function.
	(_initialize_svr4_solib): Add elf_lookup_lib_symbol to svr4_so_ops.
	* solist.h (symtab.h): New include.
	(lookup_lib_global_symbol): New prototype.
	(solib_global_lookup): Likewise.
	* symtab.c: New include solist.h.
	(lookup_objfile_from_block): New function.
	(lookup_global_symbol_from_objfile): New function.
	(basic_lookup_symbol_nonlocal): Add block to lookup_symbol_global call.
	(lookup_symbol_global): Call library-specific lookup procedure.
	* symtab.h (lookup_global_symbol_from_objfile): New prototype.
	* gdb.base/libmd.c: New file (testcase multiple symbol lookup).
	* gdb.base/libmd.h: Likewise.
	* gdb.base/solib_symbol.c: Likewise.
	* gdb.base/solib_symbol.exp: Likewise.
	* NEWS: Document framework.

Is this now ok to commit? 


-- 
Markus Deuling
GNU Toolchain for Linux on Cell BE
deuling@de.ibm.com


[-- Attachment #2: diff-gdb-multiple-symbols-mainline --]
[-- Type: text/plain, Size: 22652 bytes --]

Binary files src/gdb/.ChangeLog.swp and dev/gdb/.ChangeLog.swp differ
diff -urN src/gdb/cp-namespace.c dev/gdb/cp-namespace.c
--- src/gdb/cp-namespace.c	2007-01-09 18:58:50.000000000 +0100
+++ dev/gdb/cp-namespace.c	2007-06-26 21:03:32.000000000 +0200
@@ -491,7 +491,7 @@
     }
   else
     {
-      sym = lookup_symbol_global (name, linkage_name, domain, symtab);
+      sym = lookup_symbol_global (name, linkage_name, block, domain, symtab);
     }
 
   if (sym != NULL)
diff -urN src/gdb/Makefile.in dev/gdb/Makefile.in
--- src/gdb/Makefile.in	2007-06-19 05:22:03.000000000 +0200
+++ dev/gdb/Makefile.in	2007-06-26 21:03:32.000000000 +0200
@@ -798,7 +798,7 @@
 solib_pa64_h = solib-pa64.h
 solib_som_h = solib-som.h
 solib_svr4_h = solib-svr4.h
-solist_h = solist.h
+solist_h = solist.h $(symtab_h)
 source_h = source.h
 sparc64_tdep_h = sparc64-tdep.h $(sparc_tdep_h)
 sparc_nat_h = sparc-nat.h
@@ -2572,7 +2572,7 @@
 	$(objfiles_h) $(exceptions_h) $(gdbcore_h) $(command_h) $(target_h) \
 	$(frame_h) $(gdb_regex_h) $(inferior_h) $(environ_h) $(language_h) \
 	$(gdbcmd_h) $(completer_h) $(filenames_h) $(exec_h) $(solist_h) \
-	$(observer_h) $(readline_h)
+	$(observer_h) $(readline_h) $(objfiles_h)
 solib-frv.o: solib-frv.c $(defs_h) $(gdb_string_h) $(inferior_h) \
 	$(gdbcore_h) $(solist_h) $(frv_tdep_h) $(objfiles_h) $(symtab_h) \
 	$(language_h) $(command_h) $(gdbcmd_h) $(elf_frv_h) $(solib_h)
@@ -2719,7 +2719,8 @@
 	$(language_h) $(demangle_h) $(inferior_h) $(linespec_h) $(source_h) \
 	$(filenames_h) $(objc_lang_h) $(ada_lang_h) $(hashtab_h) \
 	$(gdb_obstack_h) $(block_h) $(dictionary_h) $(gdb_string_h) \
-	$(gdb_stat_h) $(cp_abi_h) $(observer_h) $(gdb_assert_h)
+	$(gdb_stat_h) $(cp_abi_h) $(observer_h) $(gdb_assert_h) \
+	$(solist_h)
 target.o: target.c $(defs_h) $(gdb_string_h) $(target_h) $(gdbcmd_h) \
 	$(symtab_h) $(inferior_h) $(bfd_h) $(symfile_h) $(objfiles_h) \
 	$(gdb_wait_h) $(dcache_h) $(regcache_h) $(gdb_assert_h) $(gdbcore_h) \
diff -urN src/gdb/NEWS dev/gdb/NEWS
--- src/gdb/NEWS	2007-06-21 19:00:43.000000000 +0200
+++ dev/gdb/NEWS	2007-06-26 21:06:05.000000000 +0200
@@ -3,6 +3,9 @@
 
 *** Changes since GDB 6.6
 
+* New framework for looking up multiply defined global symbols from shared
+  libraries.
+
 * When the Text User Interface (TUI) is not configured, GDB will now
 recognize the -tui command-line option and print a message that the TUI
 is not supported.
diff -urN src/gdb/solib.c dev/gdb/solib.c
--- src/gdb/solib.c	2007-06-13 19:52:44.000000000 +0200
+++ dev/gdb/solib.c	2007-06-26 21:03:32.000000000 +0200
@@ -955,6 +955,24 @@
 }
 
 
+/* Handler for library-specific lookup of global symbol NAME in OBJFILE.  Call
+   the library-specific handler if it is installed for the current target.  */
+
+struct symbol *
+solib_global_lookup (const struct objfile *objfile,
+		     const char *name,
+		     const char *linkage_name,
+		     const domain_enum domain,
+		     struct symtab **symtab)
+{
+  if (current_target_so_ops->lookup_lib_global_symbol != NULL)
+    return current_target_so_ops->lookup_lib_global_symbol (objfile,
+				name, linkage_name, domain, symtab);
+
+  return NULL;
+}
+
+
 extern initialize_file_ftype _initialize_solib; /* -Wmissing-prototypes */
 
 void
diff -urN src/gdb/solib-svr4.c dev/gdb/solib-svr4.c
--- src/gdb/solib-svr4.c	2007-06-13 19:52:44.000000000 +0200
+++ dev/gdb/solib-svr4.c	2007-06-26 21:03:32.000000000 +0200
@@ -354,6 +354,76 @@
   return symaddr;
 }
 
+/* Scan for DYNTAG in .dynamic section of ABFD. If DYNTAG is found 1 is
+   returned and the corresponding PTR is set.  */
+
+static int
+scan_dyntag (int dyntag, bfd *abfd, CORE_ADDR *ptr)
+{
+  int arch_size, step, sect_size;
+  long dyn_tag;
+  CORE_ADDR dyn_ptr, dyn_addr;
+  gdb_byte *bufend, *buf;
+  Elf32_External_Dyn *x_dynp_32;
+  Elf64_External_Dyn *x_dynp_64;
+  struct bfd_section *sect;
+
+  if (abfd == NULL)
+    return 0;
+  arch_size = bfd_get_arch_size (abfd);
+  if (arch_size == -1)
+   return 0;
+
+  /* Find the start address of the .dynamic section.  */
+  sect = bfd_get_section_by_name (abfd, ".dynamic");
+  if (sect == NULL)
+    return 0;
+  dyn_addr = bfd_section_vma (abfd, sect);
+
+  /* Read in .dynamic section, silently ignore errors.  */
+  sect_size = bfd_section_size (abfd, sect);
+  buf = alloca (sect_size);
+  if (target_read_memory (dyn_addr, buf, sect_size))
+    {
+      /* If target_read_memory fails, try reading the BFD file.  */
+      if (!bfd_get_section_contents (abfd, sect,
+				     buf, 0, sect_size))
+	return 0;
+    }
+
+  /* Iterate over BUF and scan for DYNTAG.  If found, set PTR and return.  */
+  step = (arch_size == 32) ? sizeof (Elf32_External_Dyn)
+			   : sizeof (Elf64_External_Dyn);
+  for (bufend = buf + sect_size;
+       buf < bufend;
+       buf += step)
+  {
+    if (arch_size == 32)
+      {
+	x_dynp_32 = (Elf32_External_Dyn *) buf;
+	dyn_tag = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_tag);
+	dyn_ptr = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_un.d_ptr);
+      }
+      else
+      {
+	x_dynp_64 = (Elf64_External_Dyn *) buf;
+	dyn_tag = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_tag);
+	dyn_ptr = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_un.d_ptr);
+      }
+     if (dyn_tag == DT_NULL)
+       return 0;
+     if (dyn_tag == dyntag)
+       {
+	 if (ptr)
+	   *ptr = dyn_ptr;
+         return 1;
+       }
+  }
+
+  return 0;
+}
+
+
 /*
 
    LOCAL FUNCTION
@@ -381,114 +451,31 @@
 static CORE_ADDR
 elf_locate_base (void)
 {
-  struct bfd_section *dyninfo_sect;
-  int dyninfo_sect_size;
-  CORE_ADDR dyninfo_addr;
-  gdb_byte *buf;
-  gdb_byte *bufend;
-  int arch_size;
+  struct minimal_symbol *msymbol;
+  CORE_ADDR dyn_ptr;
 
-  /* Find the start address of the .dynamic section.  */
-  dyninfo_sect = bfd_get_section_by_name (exec_bfd, ".dynamic");
-  if (dyninfo_sect == NULL)
+  /* Find DT_DEBUG.  */
+  if (scan_dyntag (DT_DEBUG, exec_bfd, &dyn_ptr))
+    return dyn_ptr;
+
+  /* Find DT_MIPS_RLD_MAP.  */
+  if (scan_dyntag (DT_MIPS_RLD_MAP, exec_bfd, &dyn_ptr))
     {
-      /* This may be a static executable.  Look for the symbol
-	 conventionally named _r_debug, as a last resort.  */
-      struct minimal_symbol *msymbol;
-
-      msymbol = lookup_minimal_symbol ("_r_debug", NULL, symfile_objfile);
-      if (msymbol != NULL)
-	return SYMBOL_VALUE_ADDRESS (msymbol);
-      else
+      gdb_byte *pbuf;
+      int pbuf_size = TYPE_LENGTH (builtin_type_void_data_ptr);
+      pbuf = alloca (pbuf_size);
+      /* DT_MIPS_RLD_MAP contains a pointer to the address
+	 of the dynamic link structure.  */
+      if (target_read_memory (dyn_ptr, pbuf, pbuf_size))
 	return 0;
+      return extract_typed_address (pbuf, builtin_type_void_data_ptr);
     }
 
-  dyninfo_addr = bfd_section_vma (exec_bfd, dyninfo_sect);
-
-  /* Read in .dynamic section, silently ignore errors.  */
-  dyninfo_sect_size = bfd_section_size (exec_bfd, dyninfo_sect);
-  buf = alloca (dyninfo_sect_size);
-  if (target_read_memory (dyninfo_addr, buf, dyninfo_sect_size))
-    return 0;
-
-  /* Find the DT_DEBUG entry in the the .dynamic section.
-     For mips elf we look for DT_MIPS_RLD_MAP, mips elf apparently has
-     no DT_DEBUG entries.  */
-
-  arch_size = bfd_get_arch_size (exec_bfd);
-  if (arch_size == -1)	/* failure */
-    return 0;
-
-  if (arch_size == 32)
-    { /* 32-bit elf */
-      for (bufend = buf + dyninfo_sect_size;
-	   buf < bufend;
-	   buf += sizeof (Elf32_External_Dyn))
-	{
-	  Elf32_External_Dyn *x_dynp = (Elf32_External_Dyn *) buf;
-	  long dyn_tag;
-	  CORE_ADDR dyn_ptr;
-
-	  dyn_tag = bfd_h_get_32 (exec_bfd, (bfd_byte *) x_dynp->d_tag);
-	  if (dyn_tag == DT_NULL)
-	    break;
-	  else if (dyn_tag == DT_DEBUG)
-	    {
-	      dyn_ptr = bfd_h_get_32 (exec_bfd, 
-				      (bfd_byte *) x_dynp->d_un.d_ptr);
-	      return dyn_ptr;
-	    }
-	  else if (dyn_tag == DT_MIPS_RLD_MAP)
-	    {
-	      gdb_byte *pbuf;
-	      int pbuf_size = TYPE_LENGTH (builtin_type_void_data_ptr);
-
-	      pbuf = alloca (pbuf_size);
-	      /* DT_MIPS_RLD_MAP contains a pointer to the address
-		 of the dynamic link structure.  */
-	      dyn_ptr = bfd_h_get_32 (exec_bfd, 
-				      (bfd_byte *) x_dynp->d_un.d_ptr);
-	      if (target_read_memory (dyn_ptr, pbuf, pbuf_size))
-		return 0;
-	      return extract_typed_address (pbuf, builtin_type_void_data_ptr);
-	    }
-	}
-    }
-  else /* 64-bit elf */
-    {
-      for (bufend = buf + dyninfo_sect_size;
-	   buf < bufend;
-	   buf += sizeof (Elf64_External_Dyn))
-	{
-	  Elf64_External_Dyn *x_dynp = (Elf64_External_Dyn *) buf;
-	  long dyn_tag;
-	  CORE_ADDR dyn_ptr;
-
-	  dyn_tag = bfd_h_get_64 (exec_bfd, (bfd_byte *) x_dynp->d_tag);
-	  if (dyn_tag == DT_NULL)
-	    break;
-	  else if (dyn_tag == DT_DEBUG)
-	    {
-	      dyn_ptr = bfd_h_get_64 (exec_bfd, 
-				      (bfd_byte *) x_dynp->d_un.d_ptr);
-	      return dyn_ptr;
-	    }
-	  else if (dyn_tag == DT_MIPS_RLD_MAP)
-	    {
-	      gdb_byte *pbuf;
-	      int pbuf_size = TYPE_LENGTH (builtin_type_void_data_ptr);
-
-	      pbuf = alloca (pbuf_size);
-	      /* DT_MIPS_RLD_MAP contains a pointer to the address
-		 of the dynamic link structure.  */
-	      dyn_ptr = bfd_h_get_64 (exec_bfd, 
-				      (bfd_byte *) x_dynp->d_un.d_ptr);
-	      if (target_read_memory (dyn_ptr, pbuf, pbuf_size))
-		return 0;
-	      return extract_typed_address (pbuf, builtin_type_void_data_ptr);
-	    }
-	}
-    }
+  /* This may be a static executable.  Look for the symbol
+     conventionally named _r_debug, as a last resort.  */
+  msymbol = lookup_minimal_symbol ("_r_debug", NULL, symfile_objfile);
+  if (msymbol != NULL)
+    return SYMBOL_VALUE_ADDRESS (msymbol);
 
   /* DT_DEBUG entry not found.  */
   return 0;
@@ -1554,6 +1541,24 @@
 
 struct target_so_ops svr4_so_ops;
 
+/* Lookup global symbol for ELF DSOs linked with -Bsymbolic. Those DSOs have a
+   different rule for symbol lookup.  The lookup begins here in the DSO, not in
+   the main executable.  */
+
+static struct symbol *
+elf_lookup_lib_symbol (const struct objfile *objfile,
+		       const char *name,
+		       const char *linkage_name,
+		       const domain_enum domain, struct symtab **symtab)
+{
+  if (objfile->obfd == NULL
+     || scan_dyntag (DT_SYMBOLIC, objfile->obfd, NULL) != 1)
+    return NULL;
+
+  return  lookup_global_symbol_from_objfile
+		(objfile, name, linkage_name, domain, symtab);
+}
+
 extern initialize_file_ftype _initialize_svr4_solib; /* -Wmissing-prototypes */
 
 void
@@ -1569,6 +1574,7 @@
   svr4_so_ops.current_sos = svr4_current_sos;
   svr4_so_ops.open_symbol_file_object = open_symbol_file_object;
   svr4_so_ops.in_dynsym_resolve_code = svr4_in_dynsym_resolve_code;
+  svr4_so_ops.lookup_lib_global_symbol = elf_lookup_lib_symbol;
 
   /* FIXME: Don't do this here.  *_gdbarch_init() should set so_ops. */
   current_target_so_ops = &svr4_so_ops;
diff -urN src/gdb/solist.h dev/gdb/solist.h
--- src/gdb/solist.h	2007-01-09 18:58:58.000000000 +0100
+++ dev/gdb/solist.h	2007-06-26 21:03:32.000000000 +0200
@@ -23,6 +23,8 @@
 #define SOLIST_H
 
 #define SO_NAME_MAX_PATH_SIZE 512	/* FIXME: Should be dynamic */
+/* For domain_enum domain.  */
+#include "symtab.h"
 
 /* Forward declaration for target specific link map information.  This
    struct is opaque to all but the target specific file.  */
@@ -103,7 +105,14 @@
        Convenience function for remote debuggers finding host libs.  */
     int (*find_and_open_solib) (char *soname,
         unsigned o_flags, char **temp_pathname);
-    
+
+    /* Hook for looking up global symbols in a library-specific way.  */
+    struct symbol * (*lookup_lib_global_symbol) (const struct objfile *objfile,
+						 const char *name,
+						 const char *linkage_name,
+						 const domain_enum domain,
+						 struct symtab **symtab);
+
   };
 
 /* Free the memory associated with a (so_list *).  */
@@ -125,4 +134,11 @@
 #define TARGET_SO_IN_DYNSYM_RESOLVE_CODE \
   (current_target_so_ops->in_dynsym_resolve_code)
 
+/* Handler for library-specific global symbol lookup in solib.c.  */
+struct symbol *solib_global_lookup (const struct objfile *objfile,
+				    const char *name,
+				    const char *linkage_name,
+				    const domain_enum domain,
+				    struct symtab **symtab);
+
 #endif
diff -urN src/gdb/symtab.c dev/gdb/symtab.c
--- src/gdb/symtab.c	2007-06-19 05:22:05.000000000 +0200
+++ dev/gdb/symtab.c	2007-06-26 21:03:32.000000000 +0200
@@ -57,6 +57,7 @@
 #include "cp-abi.h"
 #include "observer.h"
 #include "gdb_assert.h"
+#include "solist.h"
 
 /* Prototypes for local functions */
 
@@ -1261,6 +1262,26 @@
   return NULL;
 }
 
+/* Look up OBJFILE to BLOCK.  */
+
+static struct objfile *
+lookup_objfile_from_block (const struct block *block)
+{
+  struct objfile *obj;
+  struct symtab *s;
+
+  if (block == NULL)
+    return NULL;
+
+  block = block_global_block (block);
+  /* Go through SYMTABS.  */
+  ALL_SYMTABS (obj, s)
+    if (block == BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK))
+      return obj;
+
+  return NULL;
+}
+
 /* Look up a symbol in a block; if found, locate its symtab, fixup the
    symbol, and set block_found appropriately.  */
 
@@ -1302,6 +1323,57 @@
   return NULL;
 }
 
+/* Check all global symbols in OBJFILE in symtabs and
+   psymtabs.  */
+
+struct symbol *
+lookup_global_symbol_from_objfile (const struct objfile *objfile,
+				   const char *name,
+				   const char *linkage_name,
+				   const domain_enum domain,
+				   struct symtab **symtab)
+{
+  struct symbol *sym;
+  struct blockvector *bv;
+  const struct block *block;
+  struct symtab *s;
+  struct partial_symtab *ps;
+
+  /* Go through symtabs.  */
+  ALL_OBJFILE_SYMTABS (objfile, s)
+  {
+    bv = BLOCKVECTOR (s);
+    block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+    sym = lookup_block_symbol (block, name, linkage_name, domain);
+    if (sym)
+      {
+	block_found = block;
+	if (symtab != NULL)
+	  *symtab = s;
+	return fixup_symbol_section (sym, (struct objfile *)objfile);
+      }
+  }
+
+  /* Now go through psymtabs.  */
+  ALL_OBJFILE_PSYMTABS (objfile, ps)
+  {
+    if (!ps->readin
+	&& lookup_partial_symbol (ps, name, linkage_name,
+				  1, domain))
+      {
+	s = PSYMTAB_TO_SYMTAB (ps);
+	bv = BLOCKVECTOR (s);
+	block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+	sym = lookup_block_symbol (block, name, linkage_name, domain);
+	if (symtab != NULL)
+	  *symtab = s;
+	return fixup_symbol_section (sym, (struct objfile *)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,
    depending on whether or not we want to search global symbols or
@@ -1567,7 +1639,7 @@
   if (sym != NULL)
     return sym;
 
-  return lookup_symbol_global (name, linkage_name, domain, symtab);
+  return lookup_symbol_global (name, linkage_name, block, domain, symtab);
 }
 
 /* Lookup a symbol in the static block associated to BLOCK, if there
@@ -1595,10 +1667,19 @@
 struct symbol *
 lookup_symbol_global (const char *name,
 		      const char *linkage_name,
+		      const struct block *block,
 		      const domain_enum domain,
 		      struct symtab **symtab)
 {
-  struct symbol *sym;
+  struct symbol *sym = NULL;
+  struct objfile *objfile = NULL;
+
+  /* Call library-specific lookup procedure.  */
+  objfile = lookup_objfile_from_block (block);
+  if (objfile != NULL)
+    sym = solib_global_lookup (objfile, name, linkage_name, domain, symtab);
+  if (sym != NULL)
+    return sym;
 
   sym = lookup_symbol_aux_symtabs (GLOBAL_BLOCK, name, linkage_name,
 				   domain, symtab);
diff -urN src/gdb/symtab.h dev/gdb/symtab.h
--- src/gdb/symtab.h	2007-06-18 05:36:44.000000000 +0200
+++ dev/gdb/symtab.h	2007-06-26 21:03:32.000000000 +0200
@@ -1050,6 +1050,7 @@
 
 extern struct symbol *lookup_symbol_global (const char *name,
 					    const char *linkage_name,
+					    const struct block *block,
 					    const domain_enum domain,
 					    struct symtab **symtab);
 
@@ -1398,4 +1399,12 @@
 extern void set_main_name (const char *name);
 extern /*const */ char *main_name (void);
 
+/* Check global symbols in objfile.  */
+struct symbol *lookup_global_symbol_from_objfile (const struct objfile *objfile,
+						  const char *name,
+						  const char *linkage_name,
+						  const domain_enum domain,
+						  struct symtab **symtab);
+
+
 #endif /* !defined(SYMTAB_H) */
diff -urN src/gdb/testsuite/gdb.base/libmd.c dev/gdb/testsuite/gdb.base/libmd.c
--- src/gdb/testsuite/gdb.base/libmd.c	1970-01-01 01:00:00.000000000 +0100
+++ dev/gdb/testsuite/gdb.base/libmd.c	2007-06-26 21:03:32.000000000 +0200
@@ -0,0 +1,36 @@
+/* Copyright 2007 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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+   Contributed by Markus Deuling <deuling@de.ibm.com>.
+*/
+extern void foo();
+#include <stdio.h>
+#include "libmd.h"
+
+void foo2 ();
+
+void
+foo ()
+{
+  printf ("foo in lib\n");
+  return;
+}
+
+void
+foo2()
+{
+  printf ("foo2 in lib\n");
+  return;
+}
diff -urN src/gdb/testsuite/gdb.base/libmd.h dev/gdb/testsuite/gdb.base/libmd.h
--- src/gdb/testsuite/gdb.base/libmd.h	1970-01-01 01:00:00.000000000 +0100
+++ dev/gdb/testsuite/gdb.base/libmd.h	2007-06-26 21:03:32.000000000 +0200
@@ -0,0 +1,18 @@
+/* Copyright 2007 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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+   Contributed by Markus Deuling <deuling@de.ibm.com>.
+*/
+extern void foo();
diff -urN src/gdb/testsuite/gdb.base/solib_symbol.c dev/gdb/testsuite/gdb.base/solib_symbol.c
--- src/gdb/testsuite/gdb.base/solib_symbol.c	1970-01-01 01:00:00.000000000 +0100
+++ dev/gdb/testsuite/gdb.base/solib_symbol.c	2007-06-26 21:03:32.000000000 +0200
@@ -0,0 +1,45 @@
+/* Copyright 2007 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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+   Contributed by Markus Deuling <deuling@de.ibm.com>.
+*/
+extern void foo();
+#include <stdio.h>
+#include "libmd.h"
+
+extern void foo();
+void foo3();
+void foo2();
+
+int main ()
+{
+  printf ("in main\n");
+  foo ();
+  foo3 ();
+  return 0;
+}
+
+void foo3()
+{
+  printf ("foo3 in main\n");
+  return;
+}
+
+void foo2()
+{
+  printf ("foo2 in main\n");
+  return;
+}
+
diff -urN src/gdb/testsuite/gdb.base/solib_symbol.exp dev/gdb/testsuite/gdb.base/solib_symbol.exp
--- src/gdb/testsuite/gdb.base/solib_symbol.exp	1970-01-01 01:00:00.000000000 +0100
+++ dev/gdb/testsuite/gdb.base/solib_symbol.exp	2007-06-26 21:03:32.000000000 +0200
@@ -0,0 +1,80 @@
+# Copyright 2007 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 2 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+#
+# Contributed by Markus Deuling <deuling@de.ibm.com>.
+#
+
+if {[skip_shlib_tests]} {
+    return 0
+}
+
+# Library file.
+set libname "libmd"
+set srcfile_lib ${srcdir}/${subdir}/${libname}.c
+set binfile_lib ${objdir}/${subdir}/${libname}.so
+set lib_flags [list debug ldflags=-Wl,-Bsymbolic]
+# Binary file.
+set testfile "solib_symbol"
+set srcfile ${srcdir}/${subdir}/${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+set bin_flags [list debug shlib=${binfile_lib}]
+
+if [get_compiler_info ${binfile}] {
+    return -1
+}
+
+if { [gdb_compile_shlib ${srcfile_lib} ${binfile_lib} $lib_flags] != ""
+     || [gdb_compile ${srcfile} ${binfile} executable $bin_flags] != "" } {
+  untested "Could not compile $binfile_lib or $binfile."
+  return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+gdb_load_shlibs $binfile_lib
+
+if ![runto_main] then {
+  fail "Can't run to main"
+  return 0
+}
+
+# Set a breakpoint in the binary.
+gdb_test "br foo2" \
+	 "Breakpoint.*file.*${srcfile}.*" \
+	 "foo2 in main"
+
+delete_breakpoints
+
+# Break in the library.
+gdb_test "br foo" \
+	 "" \
+	 "foo in libmd"
+
+gdb_test "continue" \
+	 "Continuing.*" \
+	 "continue"
+
+# This symbol is now looked up in the ELF library.
+gdb_test "br foo2" \
+	 "Breakpoint.*file.*${srcfile_lib}.*" \
+	 "foo2 in mdlib"
+
+gdb_exit
+
+return 0
+
+

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PING 2] [rfc]: Framework for looking up multiply defined global         symbols  in shared libraries
  2007-06-26 20:34               ` Markus Deuling
@ 2007-06-28 15:32                 ` Ulrich Weigand
  2007-06-28 15:33                   ` Joel Brobecker
                                     ` (2 more replies)
  0 siblings, 3 replies; 24+ messages in thread
From: Ulrich Weigand @ 2007-06-28 15:32 UTC (permalink / raw)
  To: Markus Deuling
  Cc: Joel Brobecker, GDB Patches, Daniel Jacobowitz, Kevin Buettner, eliz

Markus Deuling wrote:

> diff -urN src/gdb/NEWS dev/gdb/NEWS
> --- src/gdb/NEWS	2007-06-21 19:00:43.000000000 +0200
> +++ dev/gdb/NEWS	2007-06-26 21:06:05.000000000 +0200
> @@ -3,6 +3,9 @@
>  
>  *** Changes since GDB 6.6
>  
> +* New framework for looking up multiply defined global symbols from shared
> +  libraries.
> +


It's up to Eli to approve NEWS entries, but it has been my understanding that
NEWS should be about user-visible features, not internal infrastructure changes.
I'd reword to this something like:
"When looking up multiply-defined global symbols, GDB will now prefer
the symbol definition in the current shared library if it was built
using the -Bsymbolic linker option." 


I've noticed a couple of minor issues in the test case:

> diff -urN src/gdb/testsuite/gdb.base/libmd.c dev/gdb/testsuite/gdb.base/libmd.c

What is libmd supposed to stand for?

> --- src/gdb/testsuite/gdb.base/libmd.c	1970-01-01 01:00:00.000000000 +0100
> +++ dev/gdb/testsuite/gdb.base/libmd.c	2007-06-26 21:03:32.000000000 +0200

> +extern void foo();

This doesn't appear to be necessary; foo isn't even referred to ...

+void foo2 ();

Likewise.

> diff -urN src/gdb/testsuite/gdb.base/libmd.h dev/gdb/testsuite/gdb.base/libmd.h
> --- src/gdb/testsuite/gdb.base/libmd.h	1970-01-01 01:00:00.000000000 +0100
> +++ dev/gdb/testsuite/gdb.base/libmd.h	2007-06-26 21:03:32.000000000 +0200

In fact, this whole header file looks unnecessary to me.

> diff -urN src/gdb/testsuite/gdb.base/solib_symbol.c dev/gdb/testsuite/gdb.base/solib_symbol.c
> --- src/gdb/testsuite/gdb.base/solib_symbol.c	1970-01-01 01:00:00.000000000 +0100
> +++ dev/gdb/testsuite/gdb.base/solib_symbol.c	2007-06-26 21:03:32.000000000 +0200

> +extern void foo();
> +#include <stdio.h>
> +#include "libmd.h"
> +
> +extern void foo();

Here we have the declaration three times ;-)  Once is enough ...


Otherwise, this looks OK to me now.


-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PING 2] [rfc]: Framework for looking up multiply defined global         symbols  in shared libraries
  2007-06-28 15:32                 ` Ulrich Weigand
@ 2007-06-28 15:33                   ` Joel Brobecker
  2007-06-28 18:20                   ` Markus Deuling
  2007-06-29 17:15                   ` Eli Zaretskii
  2 siblings, 0 replies; 24+ messages in thread
From: Joel Brobecker @ 2007-06-28 15:33 UTC (permalink / raw)
  To: Ulrich Weigand
  Cc: Markus Deuling, GDB Patches, Daniel Jacobowitz, Kevin Buettner, eliz

> It's up to Eli to approve NEWS entries, but it has been my
> understanding that NEWS should be about user-visible features, not
> internal infrastructure changes.  I'd reword to this something like:
> "When looking up multiply-defined global symbols, GDB will now prefer
> the symbol definition in the current shared library if it was built
> using the -Bsymbolic linker option." 

I personally agree.

-- 
Joel


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PING 2] [rfc]: Framework for looking up multiply defined global          symbols  in shared libraries
  2007-06-28 15:32                 ` Ulrich Weigand
  2007-06-28 15:33                   ` Joel Brobecker
@ 2007-06-28 18:20                   ` Markus Deuling
  2007-06-29 17:03                     ` Eli Zaretskii
  2007-07-02 18:24                     ` Ulrich Weigand
  2007-06-29 17:15                   ` Eli Zaretskii
  2 siblings, 2 replies; 24+ messages in thread
From: Markus Deuling @ 2007-06-28 18:20 UTC (permalink / raw)
  To: Ulrich Weigand
  Cc: Markus Deuling, Joel Brobecker, GDB Patches, Daniel Jacobowitz,
	Kevin Buettner, eliz

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

Ulrich Weigand wrote:
> Markus Deuling wrote:
> 
>> diff -urN src/gdb/NEWS dev/gdb/NEWS
>> --- src/gdb/NEWS	2007-06-21 19:00:43.000000000 +0200
>> +++ dev/gdb/NEWS	2007-06-26 21:06:05.000000000 +0200
>> @@ -3,6 +3,9 @@
>>  
>>  *** Changes since GDB 6.6
>>  
>> +* New framework for looking up multiply defined global symbols from shared
>> +  libraries.
>> +
> 
> 
> It's up to Eli to approve NEWS entries, but it has been my understanding that
> NEWS should be about user-visible features, not internal infrastructure changes.
> I'd reword to this something like:
> "When looking up multiply-defined global symbols, GDB will now prefer
> the symbol definition in the current shared library if it was built
> using the -Bsymbolic linker option." 
> 
> 
> I've noticed a couple of minor issues in the test case:
> 
>> diff -urN src/gdb/testsuite/gdb.base/libmd.c dev/gdb/testsuite/gdb.base/libmd.c
> 
> What is libmd supposed to stand for?
> 
>> --- src/gdb/testsuite/gdb.base/libmd.c	1970-01-01 01:00:00.000000000 +0100
>> +++ dev/gdb/testsuite/gdb.base/libmd.c	2007-06-26 21:03:32.000000000 +0200
> 
>> +extern void foo();
> 
> This doesn't appear to be necessary; foo isn't even referred to ...
> 
> +void foo2 ();
> 
> Likewise.
> 
>> diff -urN src/gdb/testsuite/gdb.base/libmd.h dev/gdb/testsuite/gdb.base/libmd.h
>> --- src/gdb/testsuite/gdb.base/libmd.h	1970-01-01 01:00:00.000000000 +0100
>> +++ dev/gdb/testsuite/gdb.base/libmd.h	2007-06-26 21:03:32.000000000 +0200
> 
> In fact, this whole header file looks unnecessary to me.
> 
>> diff -urN src/gdb/testsuite/gdb.base/solib_symbol.c dev/gdb/testsuite/gdb.base/solib_symbol.c
>> --- src/gdb/testsuite/gdb.base/solib_symbol.c	1970-01-01 01:00:00.000000000 +0100
>> +++ dev/gdb/testsuite/gdb.base/solib_symbol.c	2007-06-26 21:03:32.000000000 +0200
> 
>> +extern void foo();
>> +#include <stdio.h>
>> +#include "libmd.h"
>> +
>> +extern void foo();
> 
> Here we have the declaration three times ;-)  Once is enough ...
> 
> 
> Otherwise, this looks OK to me now.
> 
> 


Ok, I renamed the testsuite files to solib-symbol.exp and solib-symbol-{main,lib}.c The header has been removed.

I also changed the NEWS entry. Eli, is this ok ?



-- 
Markus Deuling
GNU Toolchain for Linux on Cell BE
deuling@de.ibm.com


[-- Attachment #2: diff-gdb-multiple-symbols-mainline --]
[-- Type: text/plain, Size: 21557 bytes --]

diff -urN src/gdb/cp-namespace.c dev/gdb/cp-namespace.c
--- src/gdb/cp-namespace.c	2007-01-09 18:58:50.000000000 +0100
+++ dev/gdb/cp-namespace.c	2007-06-28 17:09:38.000000000 +0200
@@ -491,7 +491,7 @@
     }
   else
     {
-      sym = lookup_symbol_global (name, linkage_name, domain, symtab);
+      sym = lookup_symbol_global (name, linkage_name, block, domain, symtab);
     }
 
   if (sym != NULL)
diff -urN src/gdb/Makefile.in dev/gdb/Makefile.in
--- src/gdb/Makefile.in	2007-06-19 05:22:03.000000000 +0200
+++ dev/gdb/Makefile.in	2007-06-28 17:09:38.000000000 +0200
@@ -798,7 +798,7 @@
 solib_pa64_h = solib-pa64.h
 solib_som_h = solib-som.h
 solib_svr4_h = solib-svr4.h
-solist_h = solist.h
+solist_h = solist.h $(symtab_h)
 source_h = source.h
 sparc64_tdep_h = sparc64-tdep.h $(sparc_tdep_h)
 sparc_nat_h = sparc-nat.h
@@ -2572,7 +2572,7 @@
 	$(objfiles_h) $(exceptions_h) $(gdbcore_h) $(command_h) $(target_h) \
 	$(frame_h) $(gdb_regex_h) $(inferior_h) $(environ_h) $(language_h) \
 	$(gdbcmd_h) $(completer_h) $(filenames_h) $(exec_h) $(solist_h) \
-	$(observer_h) $(readline_h)
+	$(observer_h) $(readline_h) $(objfiles_h)
 solib-frv.o: solib-frv.c $(defs_h) $(gdb_string_h) $(inferior_h) \
 	$(gdbcore_h) $(solist_h) $(frv_tdep_h) $(objfiles_h) $(symtab_h) \
 	$(language_h) $(command_h) $(gdbcmd_h) $(elf_frv_h) $(solib_h)
@@ -2719,7 +2719,8 @@
 	$(language_h) $(demangle_h) $(inferior_h) $(linespec_h) $(source_h) \
 	$(filenames_h) $(objc_lang_h) $(ada_lang_h) $(hashtab_h) \
 	$(gdb_obstack_h) $(block_h) $(dictionary_h) $(gdb_string_h) \
-	$(gdb_stat_h) $(cp_abi_h) $(observer_h) $(gdb_assert_h)
+	$(gdb_stat_h) $(cp_abi_h) $(observer_h) $(gdb_assert_h) \
+	$(solist_h)
 target.o: target.c $(defs_h) $(gdb_string_h) $(target_h) $(gdbcmd_h) \
 	$(symtab_h) $(inferior_h) $(bfd_h) $(symfile_h) $(objfiles_h) \
 	$(gdb_wait_h) $(dcache_h) $(regcache_h) $(gdb_assert_h) $(gdbcore_h) \
diff -urN src/gdb/NEWS dev/gdb/NEWS
--- src/gdb/NEWS	2007-06-21 19:00:43.000000000 +0200
+++ dev/gdb/NEWS	2007-06-28 17:10:39.000000000 +0200
@@ -3,6 +3,10 @@
 
 *** Changes since GDB 6.6
 
+* When looking up multiply-defined global symbols, GDB will now prefer the
+  symbol definition in the current shared library if it was built using the
+   -Bsymbolic linker option.
+
 * When the Text User Interface (TUI) is not configured, GDB will now
 recognize the -tui command-line option and print a message that the TUI
 is not supported.
diff -urN src/gdb/solib.c dev/gdb/solib.c
--- src/gdb/solib.c	2007-06-13 19:52:44.000000000 +0200
+++ dev/gdb/solib.c	2007-06-28 17:09:38.000000000 +0200
@@ -955,6 +955,24 @@
 }
 
 
+/* Handler for library-specific lookup of global symbol NAME in OBJFILE.  Call
+   the library-specific handler if it is installed for the current target.  */
+
+struct symbol *
+solib_global_lookup (const struct objfile *objfile,
+		     const char *name,
+		     const char *linkage_name,
+		     const domain_enum domain,
+		     struct symtab **symtab)
+{
+  if (current_target_so_ops->lookup_lib_global_symbol != NULL)
+    return current_target_so_ops->lookup_lib_global_symbol (objfile,
+				name, linkage_name, domain, symtab);
+
+  return NULL;
+}
+
+
 extern initialize_file_ftype _initialize_solib; /* -Wmissing-prototypes */
 
 void
diff -urN src/gdb/solib-svr4.c dev/gdb/solib-svr4.c
--- src/gdb/solib-svr4.c	2007-06-13 19:52:44.000000000 +0200
+++ dev/gdb/solib-svr4.c	2007-06-28 17:09:38.000000000 +0200
@@ -354,6 +354,76 @@
   return symaddr;
 }
 
+/* Scan for DYNTAG in .dynamic section of ABFD. If DYNTAG is found 1 is
+   returned and the corresponding PTR is set.  */
+
+static int
+scan_dyntag (int dyntag, bfd *abfd, CORE_ADDR *ptr)
+{
+  int arch_size, step, sect_size;
+  long dyn_tag;
+  CORE_ADDR dyn_ptr, dyn_addr;
+  gdb_byte *bufend, *buf;
+  Elf32_External_Dyn *x_dynp_32;
+  Elf64_External_Dyn *x_dynp_64;
+  struct bfd_section *sect;
+
+  if (abfd == NULL)
+    return 0;
+  arch_size = bfd_get_arch_size (abfd);
+  if (arch_size == -1)
+   return 0;
+
+  /* Find the start address of the .dynamic section.  */
+  sect = bfd_get_section_by_name (abfd, ".dynamic");
+  if (sect == NULL)
+    return 0;
+  dyn_addr = bfd_section_vma (abfd, sect);
+
+  /* Read in .dynamic section, silently ignore errors.  */
+  sect_size = bfd_section_size (abfd, sect);
+  buf = alloca (sect_size);
+  if (target_read_memory (dyn_addr, buf, sect_size))
+    {
+      /* If target_read_memory fails, try reading the BFD file.  */
+      if (!bfd_get_section_contents (abfd, sect,
+				     buf, 0, sect_size))
+	return 0;
+    }
+
+  /* Iterate over BUF and scan for DYNTAG.  If found, set PTR and return.  */
+  step = (arch_size == 32) ? sizeof (Elf32_External_Dyn)
+			   : sizeof (Elf64_External_Dyn);
+  for (bufend = buf + sect_size;
+       buf < bufend;
+       buf += step)
+  {
+    if (arch_size == 32)
+      {
+	x_dynp_32 = (Elf32_External_Dyn *) buf;
+	dyn_tag = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_tag);
+	dyn_ptr = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_un.d_ptr);
+      }
+      else
+      {
+	x_dynp_64 = (Elf64_External_Dyn *) buf;
+	dyn_tag = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_tag);
+	dyn_ptr = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_un.d_ptr);
+      }
+     if (dyn_tag == DT_NULL)
+       return 0;
+     if (dyn_tag == dyntag)
+       {
+	 if (ptr)
+	   *ptr = dyn_ptr;
+         return 1;
+       }
+  }
+
+  return 0;
+}
+
+
 /*
 
    LOCAL FUNCTION
@@ -381,114 +451,31 @@
 static CORE_ADDR
 elf_locate_base (void)
 {
-  struct bfd_section *dyninfo_sect;
-  int dyninfo_sect_size;
-  CORE_ADDR dyninfo_addr;
-  gdb_byte *buf;
-  gdb_byte *bufend;
-  int arch_size;
+  struct minimal_symbol *msymbol;
+  CORE_ADDR dyn_ptr;
 
-  /* Find the start address of the .dynamic section.  */
-  dyninfo_sect = bfd_get_section_by_name (exec_bfd, ".dynamic");
-  if (dyninfo_sect == NULL)
+  /* Find DT_DEBUG.  */
+  if (scan_dyntag (DT_DEBUG, exec_bfd, &dyn_ptr))
+    return dyn_ptr;
+
+  /* Find DT_MIPS_RLD_MAP.  */
+  if (scan_dyntag (DT_MIPS_RLD_MAP, exec_bfd, &dyn_ptr))
     {
-      /* This may be a static executable.  Look for the symbol
-	 conventionally named _r_debug, as a last resort.  */
-      struct minimal_symbol *msymbol;
-
-      msymbol = lookup_minimal_symbol ("_r_debug", NULL, symfile_objfile);
-      if (msymbol != NULL)
-	return SYMBOL_VALUE_ADDRESS (msymbol);
-      else
+      gdb_byte *pbuf;
+      int pbuf_size = TYPE_LENGTH (builtin_type_void_data_ptr);
+      pbuf = alloca (pbuf_size);
+      /* DT_MIPS_RLD_MAP contains a pointer to the address
+	 of the dynamic link structure.  */
+      if (target_read_memory (dyn_ptr, pbuf, pbuf_size))
 	return 0;
+      return extract_typed_address (pbuf, builtin_type_void_data_ptr);
     }
 
-  dyninfo_addr = bfd_section_vma (exec_bfd, dyninfo_sect);
-
-  /* Read in .dynamic section, silently ignore errors.  */
-  dyninfo_sect_size = bfd_section_size (exec_bfd, dyninfo_sect);
-  buf = alloca (dyninfo_sect_size);
-  if (target_read_memory (dyninfo_addr, buf, dyninfo_sect_size))
-    return 0;
-
-  /* Find the DT_DEBUG entry in the the .dynamic section.
-     For mips elf we look for DT_MIPS_RLD_MAP, mips elf apparently has
-     no DT_DEBUG entries.  */
-
-  arch_size = bfd_get_arch_size (exec_bfd);
-  if (arch_size == -1)	/* failure */
-    return 0;
-
-  if (arch_size == 32)
-    { /* 32-bit elf */
-      for (bufend = buf + dyninfo_sect_size;
-	   buf < bufend;
-	   buf += sizeof (Elf32_External_Dyn))
-	{
-	  Elf32_External_Dyn *x_dynp = (Elf32_External_Dyn *) buf;
-	  long dyn_tag;
-	  CORE_ADDR dyn_ptr;
-
-	  dyn_tag = bfd_h_get_32 (exec_bfd, (bfd_byte *) x_dynp->d_tag);
-	  if (dyn_tag == DT_NULL)
-	    break;
-	  else if (dyn_tag == DT_DEBUG)
-	    {
-	      dyn_ptr = bfd_h_get_32 (exec_bfd, 
-				      (bfd_byte *) x_dynp->d_un.d_ptr);
-	      return dyn_ptr;
-	    }
-	  else if (dyn_tag == DT_MIPS_RLD_MAP)
-	    {
-	      gdb_byte *pbuf;
-	      int pbuf_size = TYPE_LENGTH (builtin_type_void_data_ptr);
-
-	      pbuf = alloca (pbuf_size);
-	      /* DT_MIPS_RLD_MAP contains a pointer to the address
-		 of the dynamic link structure.  */
-	      dyn_ptr = bfd_h_get_32 (exec_bfd, 
-				      (bfd_byte *) x_dynp->d_un.d_ptr);
-	      if (target_read_memory (dyn_ptr, pbuf, pbuf_size))
-		return 0;
-	      return extract_typed_address (pbuf, builtin_type_void_data_ptr);
-	    }
-	}
-    }
-  else /* 64-bit elf */
-    {
-      for (bufend = buf + dyninfo_sect_size;
-	   buf < bufend;
-	   buf += sizeof (Elf64_External_Dyn))
-	{
-	  Elf64_External_Dyn *x_dynp = (Elf64_External_Dyn *) buf;
-	  long dyn_tag;
-	  CORE_ADDR dyn_ptr;
-
-	  dyn_tag = bfd_h_get_64 (exec_bfd, (bfd_byte *) x_dynp->d_tag);
-	  if (dyn_tag == DT_NULL)
-	    break;
-	  else if (dyn_tag == DT_DEBUG)
-	    {
-	      dyn_ptr = bfd_h_get_64 (exec_bfd, 
-				      (bfd_byte *) x_dynp->d_un.d_ptr);
-	      return dyn_ptr;
-	    }
-	  else if (dyn_tag == DT_MIPS_RLD_MAP)
-	    {
-	      gdb_byte *pbuf;
-	      int pbuf_size = TYPE_LENGTH (builtin_type_void_data_ptr);
-
-	      pbuf = alloca (pbuf_size);
-	      /* DT_MIPS_RLD_MAP contains a pointer to the address
-		 of the dynamic link structure.  */
-	      dyn_ptr = bfd_h_get_64 (exec_bfd, 
-				      (bfd_byte *) x_dynp->d_un.d_ptr);
-	      if (target_read_memory (dyn_ptr, pbuf, pbuf_size))
-		return 0;
-	      return extract_typed_address (pbuf, builtin_type_void_data_ptr);
-	    }
-	}
-    }
+  /* This may be a static executable.  Look for the symbol
+     conventionally named _r_debug, as a last resort.  */
+  msymbol = lookup_minimal_symbol ("_r_debug", NULL, symfile_objfile);
+  if (msymbol != NULL)
+    return SYMBOL_VALUE_ADDRESS (msymbol);
 
   /* DT_DEBUG entry not found.  */
   return 0;
@@ -1554,6 +1541,24 @@
 
 struct target_so_ops svr4_so_ops;
 
+/* Lookup global symbol for ELF DSOs linked with -Bsymbolic. Those DSOs have a
+   different rule for symbol lookup.  The lookup begins here in the DSO, not in
+   the main executable.  */
+
+static struct symbol *
+elf_lookup_lib_symbol (const struct objfile *objfile,
+		       const char *name,
+		       const char *linkage_name,
+		       const domain_enum domain, struct symtab **symtab)
+{
+  if (objfile->obfd == NULL
+     || scan_dyntag (DT_SYMBOLIC, objfile->obfd, NULL) != 1)
+    return NULL;
+
+  return  lookup_global_symbol_from_objfile
+		(objfile, name, linkage_name, domain, symtab);
+}
+
 extern initialize_file_ftype _initialize_svr4_solib; /* -Wmissing-prototypes */
 
 void
@@ -1569,6 +1574,7 @@
   svr4_so_ops.current_sos = svr4_current_sos;
   svr4_so_ops.open_symbol_file_object = open_symbol_file_object;
   svr4_so_ops.in_dynsym_resolve_code = svr4_in_dynsym_resolve_code;
+  svr4_so_ops.lookup_lib_global_symbol = elf_lookup_lib_symbol;
 
   /* FIXME: Don't do this here.  *_gdbarch_init() should set so_ops. */
   current_target_so_ops = &svr4_so_ops;
diff -urN src/gdb/solist.h dev/gdb/solist.h
--- src/gdb/solist.h	2007-01-09 18:58:58.000000000 +0100
+++ dev/gdb/solist.h	2007-06-28 17:09:38.000000000 +0200
@@ -23,6 +23,8 @@
 #define SOLIST_H
 
 #define SO_NAME_MAX_PATH_SIZE 512	/* FIXME: Should be dynamic */
+/* For domain_enum domain.  */
+#include "symtab.h"
 
 /* Forward declaration for target specific link map information.  This
    struct is opaque to all but the target specific file.  */
@@ -103,7 +105,14 @@
        Convenience function for remote debuggers finding host libs.  */
     int (*find_and_open_solib) (char *soname,
         unsigned o_flags, char **temp_pathname);
-    
+
+    /* Hook for looking up global symbols in a library-specific way.  */
+    struct symbol * (*lookup_lib_global_symbol) (const struct objfile *objfile,
+						 const char *name,
+						 const char *linkage_name,
+						 const domain_enum domain,
+						 struct symtab **symtab);
+
   };
 
 /* Free the memory associated with a (so_list *).  */
@@ -125,4 +134,11 @@
 #define TARGET_SO_IN_DYNSYM_RESOLVE_CODE \
   (current_target_so_ops->in_dynsym_resolve_code)
 
+/* Handler for library-specific global symbol lookup in solib.c.  */
+struct symbol *solib_global_lookup (const struct objfile *objfile,
+				    const char *name,
+				    const char *linkage_name,
+				    const domain_enum domain,
+				    struct symtab **symtab);
+
 #endif
diff -urN src/gdb/symtab.c dev/gdb/symtab.c
--- src/gdb/symtab.c	2007-06-19 05:22:05.000000000 +0200
+++ dev/gdb/symtab.c	2007-06-28 17:09:38.000000000 +0200
@@ -57,6 +57,7 @@
 #include "cp-abi.h"
 #include "observer.h"
 #include "gdb_assert.h"
+#include "solist.h"
 
 /* Prototypes for local functions */
 
@@ -1261,6 +1262,26 @@
   return NULL;
 }
 
+/* Look up OBJFILE to BLOCK.  */
+
+static struct objfile *
+lookup_objfile_from_block (const struct block *block)
+{
+  struct objfile *obj;
+  struct symtab *s;
+
+  if (block == NULL)
+    return NULL;
+
+  block = block_global_block (block);
+  /* Go through SYMTABS.  */
+  ALL_SYMTABS (obj, s)
+    if (block == BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK))
+      return obj;
+
+  return NULL;
+}
+
 /* Look up a symbol in a block; if found, locate its symtab, fixup the
    symbol, and set block_found appropriately.  */
 
@@ -1302,6 +1323,57 @@
   return NULL;
 }
 
+/* Check all global symbols in OBJFILE in symtabs and
+   psymtabs.  */
+
+struct symbol *
+lookup_global_symbol_from_objfile (const struct objfile *objfile,
+				   const char *name,
+				   const char *linkage_name,
+				   const domain_enum domain,
+				   struct symtab **symtab)
+{
+  struct symbol *sym;
+  struct blockvector *bv;
+  const struct block *block;
+  struct symtab *s;
+  struct partial_symtab *ps;
+
+  /* Go through symtabs.  */
+  ALL_OBJFILE_SYMTABS (objfile, s)
+  {
+    bv = BLOCKVECTOR (s);
+    block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+    sym = lookup_block_symbol (block, name, linkage_name, domain);
+    if (sym)
+      {
+	block_found = block;
+	if (symtab != NULL)
+	  *symtab = s;
+	return fixup_symbol_section (sym, (struct objfile *)objfile);
+      }
+  }
+
+  /* Now go through psymtabs.  */
+  ALL_OBJFILE_PSYMTABS (objfile, ps)
+  {
+    if (!ps->readin
+	&& lookup_partial_symbol (ps, name, linkage_name,
+				  1, domain))
+      {
+	s = PSYMTAB_TO_SYMTAB (ps);
+	bv = BLOCKVECTOR (s);
+	block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+	sym = lookup_block_symbol (block, name, linkage_name, domain);
+	if (symtab != NULL)
+	  *symtab = s;
+	return fixup_symbol_section (sym, (struct objfile *)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,
    depending on whether or not we want to search global symbols or
@@ -1567,7 +1639,7 @@
   if (sym != NULL)
     return sym;
 
-  return lookup_symbol_global (name, linkage_name, domain, symtab);
+  return lookup_symbol_global (name, linkage_name, block, domain, symtab);
 }
 
 /* Lookup a symbol in the static block associated to BLOCK, if there
@@ -1595,10 +1667,19 @@
 struct symbol *
 lookup_symbol_global (const char *name,
 		      const char *linkage_name,
+		      const struct block *block,
 		      const domain_enum domain,
 		      struct symtab **symtab)
 {
-  struct symbol *sym;
+  struct symbol *sym = NULL;
+  struct objfile *objfile = NULL;
+
+  /* Call library-specific lookup procedure.  */
+  objfile = lookup_objfile_from_block (block);
+  if (objfile != NULL)
+    sym = solib_global_lookup (objfile, name, linkage_name, domain, symtab);
+  if (sym != NULL)
+    return sym;
 
   sym = lookup_symbol_aux_symtabs (GLOBAL_BLOCK, name, linkage_name,
 				   domain, symtab);
diff -urN src/gdb/symtab.h dev/gdb/symtab.h
--- src/gdb/symtab.h	2007-06-18 05:36:44.000000000 +0200
+++ dev/gdb/symtab.h	2007-06-28 17:09:38.000000000 +0200
@@ -1050,6 +1050,7 @@
 
 extern struct symbol *lookup_symbol_global (const char *name,
 					    const char *linkage_name,
+					    const struct block *block,
 					    const domain_enum domain,
 					    struct symtab **symtab);
 
@@ -1398,4 +1399,12 @@
 extern void set_main_name (const char *name);
 extern /*const */ char *main_name (void);
 
+/* Check global symbols in objfile.  */
+struct symbol *lookup_global_symbol_from_objfile (const struct objfile *objfile,
+						  const char *name,
+						  const char *linkage_name,
+						  const domain_enum domain,
+						  struct symtab **symtab);
+
+
 #endif /* !defined(SYMTAB_H) */
diff -urN src/gdb/testsuite/gdb.base/solib-symbol.exp dev/gdb/testsuite/gdb.base/solib-symbol.exp
--- src/gdb/testsuite/gdb.base/solib-symbol.exp	1970-01-01 01:00:00.000000000 +0100
+++ dev/gdb/testsuite/gdb.base/solib-symbol.exp	2007-06-28 17:28:08.000000000 +0200
@@ -0,0 +1,80 @@
+# Copyright 2007 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 2 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+#
+# Contributed by Markus Deuling <deuling@de.ibm.com>.
+#
+
+if {[skip_shlib_tests]} {
+    return 0
+}
+
+# Library file.
+set libname "solib-symbol-lib"
+set srcfile_lib ${srcdir}/${subdir}/${libname}.c
+set binfile_lib ${objdir}/${subdir}/${libname}.so
+set lib_flags [list debug ldflags=-Wl,-Bsymbolic]
+# Binary file.
+set testfile "solib-symbol-main"
+set srcfile ${srcdir}/${subdir}/${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+set bin_flags [list debug shlib=${binfile_lib}]
+
+if [get_compiler_info ${binfile}] {
+    return -1
+}
+
+if { [gdb_compile_shlib ${srcfile_lib} ${binfile_lib} $lib_flags] != ""
+     || [gdb_compile ${srcfile} ${binfile} executable $bin_flags] != "" } {
+  untested "Could not compile $binfile_lib or $binfile."
+  return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+gdb_load_shlibs $binfile_lib
+
+if ![runto_main] then {
+  fail "Can't run to main"
+  return 0
+}
+
+# Set a breakpoint in the binary.
+gdb_test "br foo2" \
+	 "Breakpoint.*file.*${srcfile}.*" \
+	 "foo2 in main"
+
+delete_breakpoints
+
+# Break in the library.
+gdb_test "br foo" \
+	 "" \
+	 "foo in libmd"
+
+gdb_test "continue" \
+	 "Continuing.*" \
+	 "continue"
+
+# This symbol is now looked up in the ELF library.
+gdb_test "br foo2" \
+	 "Breakpoint.*file.*${srcfile_lib}.*" \
+	 "foo2 in mdlib"
+
+gdb_exit
+
+return 0
+
+
diff -urN src/gdb/testsuite/gdb.base/solib-symbol-lib.c dev/gdb/testsuite/gdb.base/solib-symbol-lib.c
--- src/gdb/testsuite/gdb.base/solib-symbol-lib.c	1970-01-01 01:00:00.000000000 +0100
+++ dev/gdb/testsuite/gdb.base/solib-symbol-lib.c	2007-06-28 17:16:38.000000000 +0200
@@ -0,0 +1,32 @@
+/* Copyright 2007 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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+   Contributed by Markus Deuling <deuling@de.ibm.com>.
+*/
+#include <stdio.h>
+
+void
+foo ()
+{
+  printf ("foo in lib\n");
+  return;
+}
+
+void
+foo2()
+{
+  printf ("foo2 in lib\n");
+  return;
+}
diff -urN src/gdb/testsuite/gdb.base/solib-symbol-main.c dev/gdb/testsuite/gdb.base/solib-symbol-main.c
--- src/gdb/testsuite/gdb.base/solib-symbol-main.c	1970-01-01 01:00:00.000000000 +0100
+++ dev/gdb/testsuite/gdb.base/solib-symbol-main.c	2007-06-28 17:16:25.000000000 +0200
@@ -0,0 +1,43 @@
+/* Copyright 2007 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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+   Contributed by Markus Deuling <deuling@de.ibm.com>.
+*/
+#include <stdio.h>
+
+extern void foo();
+void foo3();
+void foo2();
+
+int main ()
+{
+  printf ("in main\n");
+  foo ();
+  foo3 ();
+  return 0;
+}
+
+void foo3()
+{
+  printf ("foo3 in main\n");
+  return;
+}
+
+void foo2()
+{
+  printf ("foo2 in main\n");
+  return;
+}
+

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PING 2] [rfc]: Framework for looking up multiply defined global          symbols  in shared libraries
  2007-06-28 18:20                   ` Markus Deuling
@ 2007-06-29 17:03                     ` Eli Zaretskii
  2007-07-02 18:24                     ` Ulrich Weigand
  1 sibling, 0 replies; 24+ messages in thread
From: Eli Zaretskii @ 2007-06-29 17:03 UTC (permalink / raw)
  To: Markus Deuling; +Cc: uweigand, deuling, brobecker, gdb-patches, drow, kevinb

> Date: Thu, 28 Jun 2007 17:31:52 +0200
> From: Markus Deuling <deuling@de.ibm.com>
> CC: Markus Deuling <deuling@de.ibm.com>,
>         Joel Brobecker <brobecker@adacore.com>,
>         GDB Patches <gdb-patches@sourceware.org>,
>         Daniel Jacobowitz <drow@false.org>, Kevin Buettner <kevinb@redhat.com>,
>         eliz@gnu.org
> 
> I also changed the NEWS entry. Eli, is this ok ?

Yes, thanks.


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PING 2] [rfc]: Framework for looking up multiply defined global         symbols  in shared libraries
  2007-06-28 15:32                 ` Ulrich Weigand
  2007-06-28 15:33                   ` Joel Brobecker
  2007-06-28 18:20                   ` Markus Deuling
@ 2007-06-29 17:15                   ` Eli Zaretskii
  2 siblings, 0 replies; 24+ messages in thread
From: Eli Zaretskii @ 2007-06-29 17:15 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: deuling, brobecker, gdb-patches, drow, kevinb

> Date: Thu, 28 Jun 2007 14:44:42 +0200 (CEST)
> From: "Ulrich Weigand" <uweigand@de.ibm.com>
> Cc: brobecker@adacore.com (Joel Brobecker),
>         gdb-patches@sourceware.org (GDB Patches),
>         drow@false.org (Daniel Jacobowitz), kevinb@redhat.com (Kevin Buettner),
>         eliz@gnu.org
> 
> it has been my understanding that NEWS should be about user-visible
> features, not internal infrastructure changes.

Yes, that's right.


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PING 2] [rfc]: Framework for looking up multiply defined global          symbols  in shared libraries
  2007-06-28 18:20                   ` Markus Deuling
  2007-06-29 17:03                     ` Eli Zaretskii
@ 2007-07-02 18:24                     ` Ulrich Weigand
  2007-07-03  4:04                       ` Markus Deuling
  1 sibling, 1 reply; 24+ messages in thread
From: Ulrich Weigand @ 2007-07-02 18:24 UTC (permalink / raw)
  To: Markus Deuling
  Cc: Markus Deuling, Joel Brobecker, GDB Patches, Daniel Jacobowitz,
	Kevin Buettner, eliz

Markus Deuling wrote:

> Ok, I renamed the testsuite files to solib-symbol.exp and solib-symbol-{main,lib}.c The header has been removed.
> 
> I also changed the NEWS entry. Eli, is this ok ?

Thanks, Markus.


> @@ -2572,7 +2572,7 @@
>  	$(objfiles_h) $(exceptions_h) $(gdbcore_h) $(command_h) $(target_h) \
>  	$(frame_h) $(gdb_regex_h) $(inferior_h) $(environ_h) $(language_h) \
>  	$(gdbcmd_h) $(completer_h) $(filenames_h) $(exec_h) $(solist_h) \
> -	$(observer_h) $(readline_h)
> +	$(observer_h) $(readline_h) $(objfiles_h)
>  solib-frv.o: solib-frv.c $(defs_h) $(gdb_string_h) $(inferior_h) \
>  	$(gdbcore_h) $(solist_h) $(frv_tdep_h) $(objfiles_h) $(symtab_h) \
>  	$(language_h) $(command_h) $(gdbcmd_h) $(elf_frv_h) $(solib_h)

This part of the Makefile.in change does not appear to be necessary -- there is
no corresponding source code change to the solib-svr4.c file in the patch.

Please verify this, and re-send the patch with an up-to-date ChangeLog
entry -- I'll check it in then.


Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PING 2] [rfc]: Framework for looking up multiply defined global           symbols  in shared libraries
  2007-07-02 18:24                     ` Ulrich Weigand
@ 2007-07-03  4:04                       ` Markus Deuling
  2007-07-03 12:17                         ` Ulrich Weigand
  0 siblings, 1 reply; 24+ messages in thread
From: Markus Deuling @ 2007-07-03  4:04 UTC (permalink / raw)
  To: Ulrich Weigand
  Cc: Joel Brobecker, GDB Patches, Daniel Jacobowitz, Kevin Buettner, eliz

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

Ulrich Weigand schrieb:
> Markus Deuling wrote:
> 
>> Ok, I renamed the testsuite files to solib-symbol.exp and solib-symbol-{main,lib}.c The header has been removed.
>>
>> I also changed the NEWS entry. Eli, is this ok ?
> 
> Thanks, Markus.
> 
> 
>> @@ -2572,7 +2572,7 @@
>>  	$(objfiles_h) $(exceptions_h) $(gdbcore_h) $(command_h) $(target_h) \
>>  	$(frame_h) $(gdb_regex_h) $(inferior_h) $(environ_h) $(language_h) \
>>  	$(gdbcmd_h) $(completer_h) $(filenames_h) $(exec_h) $(solist_h) \
>> -	$(observer_h) $(readline_h)
>> +	$(observer_h) $(readline_h) $(objfiles_h)
>>  solib-frv.o: solib-frv.c $(defs_h) $(gdb_string_h) $(inferior_h) \
>>  	$(gdbcore_h) $(solist_h) $(frv_tdep_h) $(objfiles_h) $(symtab_h) \
>>  	$(language_h) $(command_h) $(gdbcmd_h) $(elf_frv_h) $(solib_h)
> 
> This part of the Makefile.in change does not appear to be necessary -- there is
> no corresponding source code change to the solib-svr4.c file in the patch.
> 
> Please verify this, and re-send the patch with an up-to-date ChangeLog
> entry -- I'll check it in then.
> 

Done. I attached a new version of the patch, rebased and without the above Makefile entry.
Thank you.

ChangeLog:

	* cp-namespace.c (lookup_symbol_file): Add block to
	lookup_symbol_global call.
	* Makefile.in (solist_h): Add dependency on symtab header.
	(symtab.o): Add dependency on solist header.
	* solib.c (solib_global_lookup): New function.
	* solib-svr4.c (scan_dyntag): Likewise.
	(elf_locate_base): Call helper routine scan_dyntag.
	(elf_lookup_lib_symbol): New function.
	(_initialize_svr4_solib): Add elf_lookup_lib_symbol to svr4_so_ops.
	* solist.h (symtab.h): New include.
	(lookup_lib_global_symbol): New prototype.
	(solib_global_lookup): Likewise.
	* symtab.c: New include solist.h.
	(lookup_objfile_from_block): New function.
	(lookup_global_symbol_from_objfile): New function.
	(basic_lookup_symbol_nonlocal): Add block to lookup_symbol_global call.
	(lookup_symbol_global): Call library-specific lookup procedure.
	* symtab.h (lookup_global_symbol_from_objfile): New prototype.
	* gdb.base/libmd.c: New file (testcase multiple symbol lookup).
	* gdb.base/libmd.h: Likewise.
	* gdb.base/solib_symbol.c: Likewise.
	* gdb.base/solib_symbol.exp: Likewise.
	* NEWS: Document framework.



-- 
Markus Deuling
GNU Toolchain for Linux on Cell BE
deuling@de.ibm.com


[-- Attachment #2: diff-gdb-multiple-symbols-mainline --]
[-- Type: text/plain, Size: 21048 bytes --]

diff -urN src/gdb/cp-namespace.c dev/gdb/cp-namespace.c
--- src/gdb/cp-namespace.c	2007-01-09 18:58:50.000000000 +0100
+++ dev/gdb/cp-namespace.c	2007-07-03 05:55:51.000000000 +0200
@@ -491,7 +491,7 @@
     }
   else
     {
-      sym = lookup_symbol_global (name, linkage_name, domain, symtab);
+      sym = lookup_symbol_global (name, linkage_name, block, domain, symtab);
     }
 
   if (sym != NULL)
diff -urN src/gdb/Makefile.in dev/gdb/Makefile.in
--- src/gdb/Makefile.in	2007-07-03 05:52:18.000000000 +0200
+++ dev/gdb/Makefile.in	2007-07-03 05:55:51.000000000 +0200
@@ -799,7 +799,7 @@
 solib_pa64_h = solib-pa64.h
 solib_som_h = solib-som.h
 solib_svr4_h = solib-svr4.h
-solist_h = solist.h
+solist_h = solist.h $(symtab_h)
 source_h = source.h
 sparc64_tdep_h = sparc64-tdep.h $(sparc_tdep_h)
 sparc_nat_h = sparc-nat.h
@@ -2724,7 +2724,8 @@
 	$(language_h) $(demangle_h) $(inferior_h) $(linespec_h) $(source_h) \
 	$(filenames_h) $(objc_lang_h) $(ada_lang_h) $(hashtab_h) \
 	$(gdb_obstack_h) $(block_h) $(dictionary_h) $(gdb_string_h) \
-	$(gdb_stat_h) $(cp_abi_h) $(observer_h) $(gdb_assert_h)
+	$(gdb_stat_h) $(cp_abi_h) $(observer_h) $(gdb_assert_h) \
+	$(solist_h)
 target.o: target.c $(defs_h) $(gdb_string_h) $(target_h) $(gdbcmd_h) \
 	$(symtab_h) $(inferior_h) $(bfd_h) $(symfile_h) $(objfiles_h) \
 	$(gdb_wait_h) $(dcache_h) $(regcache_h) $(gdb_assert_h) $(gdbcore_h) \
diff -urN src/gdb/NEWS dev/gdb/NEWS
--- src/gdb/NEWS	2007-07-03 05:52:19.000000000 +0200
+++ dev/gdb/NEWS	2007-07-03 05:55:51.000000000 +0200
@@ -3,6 +3,10 @@
 
 *** Changes since GDB 6.6
 
+* When looking up multiply-defined global symbols, GDB will now prefer the
+  symbol definition in the current shared library if it was built using the
+   -Bsymbolic linker option.
+
 * When the Text User Interface (TUI) is not configured, GDB will now
 recognize the -tui command-line option and print a message that the TUI
 is not supported.
diff -urN src/gdb/solib.c dev/gdb/solib.c
--- src/gdb/solib.c	2007-07-03 05:52:19.000000000 +0200
+++ dev/gdb/solib.c	2007-07-03 05:55:51.000000000 +0200
@@ -961,6 +961,24 @@
 }
 
 
+/* Handler for library-specific lookup of global symbol NAME in OBJFILE.  Call
+   the library-specific handler if it is installed for the current target.  */
+
+struct symbol *
+solib_global_lookup (const struct objfile *objfile,
+		     const char *name,
+		     const char *linkage_name,
+		     const domain_enum domain,
+		     struct symtab **symtab)
+{
+  if (current_target_so_ops->lookup_lib_global_symbol != NULL)
+    return current_target_so_ops->lookup_lib_global_symbol (objfile,
+				name, linkage_name, domain, symtab);
+
+  return NULL;
+}
+
+
 extern initialize_file_ftype _initialize_solib; /* -Wmissing-prototypes */
 
 void
diff -urN src/gdb/solib-svr4.c dev/gdb/solib-svr4.c
--- src/gdb/solib-svr4.c	2007-06-13 19:52:44.000000000 +0200
+++ dev/gdb/solib-svr4.c	2007-07-03 05:55:51.000000000 +0200
@@ -354,6 +354,76 @@
   return symaddr;
 }
 
+/* Scan for DYNTAG in .dynamic section of ABFD. If DYNTAG is found 1 is
+   returned and the corresponding PTR is set.  */
+
+static int
+scan_dyntag (int dyntag, bfd *abfd, CORE_ADDR *ptr)
+{
+  int arch_size, step, sect_size;
+  long dyn_tag;
+  CORE_ADDR dyn_ptr, dyn_addr;
+  gdb_byte *bufend, *buf;
+  Elf32_External_Dyn *x_dynp_32;
+  Elf64_External_Dyn *x_dynp_64;
+  struct bfd_section *sect;
+
+  if (abfd == NULL)
+    return 0;
+  arch_size = bfd_get_arch_size (abfd);
+  if (arch_size == -1)
+   return 0;
+
+  /* Find the start address of the .dynamic section.  */
+  sect = bfd_get_section_by_name (abfd, ".dynamic");
+  if (sect == NULL)
+    return 0;
+  dyn_addr = bfd_section_vma (abfd, sect);
+
+  /* Read in .dynamic section, silently ignore errors.  */
+  sect_size = bfd_section_size (abfd, sect);
+  buf = alloca (sect_size);
+  if (target_read_memory (dyn_addr, buf, sect_size))
+    {
+      /* If target_read_memory fails, try reading the BFD file.  */
+      if (!bfd_get_section_contents (abfd, sect,
+				     buf, 0, sect_size))
+	return 0;
+    }
+
+  /* Iterate over BUF and scan for DYNTAG.  If found, set PTR and return.  */
+  step = (arch_size == 32) ? sizeof (Elf32_External_Dyn)
+			   : sizeof (Elf64_External_Dyn);
+  for (bufend = buf + sect_size;
+       buf < bufend;
+       buf += step)
+  {
+    if (arch_size == 32)
+      {
+	x_dynp_32 = (Elf32_External_Dyn *) buf;
+	dyn_tag = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_tag);
+	dyn_ptr = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_un.d_ptr);
+      }
+      else
+      {
+	x_dynp_64 = (Elf64_External_Dyn *) buf;
+	dyn_tag = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_tag);
+	dyn_ptr = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_un.d_ptr);
+      }
+     if (dyn_tag == DT_NULL)
+       return 0;
+     if (dyn_tag == dyntag)
+       {
+	 if (ptr)
+	   *ptr = dyn_ptr;
+         return 1;
+       }
+  }
+
+  return 0;
+}
+
+
 /*
 
    LOCAL FUNCTION
@@ -381,114 +451,31 @@
 static CORE_ADDR
 elf_locate_base (void)
 {
-  struct bfd_section *dyninfo_sect;
-  int dyninfo_sect_size;
-  CORE_ADDR dyninfo_addr;
-  gdb_byte *buf;
-  gdb_byte *bufend;
-  int arch_size;
+  struct minimal_symbol *msymbol;
+  CORE_ADDR dyn_ptr;
 
-  /* Find the start address of the .dynamic section.  */
-  dyninfo_sect = bfd_get_section_by_name (exec_bfd, ".dynamic");
-  if (dyninfo_sect == NULL)
+  /* Find DT_DEBUG.  */
+  if (scan_dyntag (DT_DEBUG, exec_bfd, &dyn_ptr))
+    return dyn_ptr;
+
+  /* Find DT_MIPS_RLD_MAP.  */
+  if (scan_dyntag (DT_MIPS_RLD_MAP, exec_bfd, &dyn_ptr))
     {
-      /* This may be a static executable.  Look for the symbol
-	 conventionally named _r_debug, as a last resort.  */
-      struct minimal_symbol *msymbol;
-
-      msymbol = lookup_minimal_symbol ("_r_debug", NULL, symfile_objfile);
-      if (msymbol != NULL)
-	return SYMBOL_VALUE_ADDRESS (msymbol);
-      else
+      gdb_byte *pbuf;
+      int pbuf_size = TYPE_LENGTH (builtin_type_void_data_ptr);
+      pbuf = alloca (pbuf_size);
+      /* DT_MIPS_RLD_MAP contains a pointer to the address
+	 of the dynamic link structure.  */
+      if (target_read_memory (dyn_ptr, pbuf, pbuf_size))
 	return 0;
+      return extract_typed_address (pbuf, builtin_type_void_data_ptr);
     }
 
-  dyninfo_addr = bfd_section_vma (exec_bfd, dyninfo_sect);
-
-  /* Read in .dynamic section, silently ignore errors.  */
-  dyninfo_sect_size = bfd_section_size (exec_bfd, dyninfo_sect);
-  buf = alloca (dyninfo_sect_size);
-  if (target_read_memory (dyninfo_addr, buf, dyninfo_sect_size))
-    return 0;
-
-  /* Find the DT_DEBUG entry in the the .dynamic section.
-     For mips elf we look for DT_MIPS_RLD_MAP, mips elf apparently has
-     no DT_DEBUG entries.  */
-
-  arch_size = bfd_get_arch_size (exec_bfd);
-  if (arch_size == -1)	/* failure */
-    return 0;
-
-  if (arch_size == 32)
-    { /* 32-bit elf */
-      for (bufend = buf + dyninfo_sect_size;
-	   buf < bufend;
-	   buf += sizeof (Elf32_External_Dyn))
-	{
-	  Elf32_External_Dyn *x_dynp = (Elf32_External_Dyn *) buf;
-	  long dyn_tag;
-	  CORE_ADDR dyn_ptr;
-
-	  dyn_tag = bfd_h_get_32 (exec_bfd, (bfd_byte *) x_dynp->d_tag);
-	  if (dyn_tag == DT_NULL)
-	    break;
-	  else if (dyn_tag == DT_DEBUG)
-	    {
-	      dyn_ptr = bfd_h_get_32 (exec_bfd, 
-				      (bfd_byte *) x_dynp->d_un.d_ptr);
-	      return dyn_ptr;
-	    }
-	  else if (dyn_tag == DT_MIPS_RLD_MAP)
-	    {
-	      gdb_byte *pbuf;
-	      int pbuf_size = TYPE_LENGTH (builtin_type_void_data_ptr);
-
-	      pbuf = alloca (pbuf_size);
-	      /* DT_MIPS_RLD_MAP contains a pointer to the address
-		 of the dynamic link structure.  */
-	      dyn_ptr = bfd_h_get_32 (exec_bfd, 
-				      (bfd_byte *) x_dynp->d_un.d_ptr);
-	      if (target_read_memory (dyn_ptr, pbuf, pbuf_size))
-		return 0;
-	      return extract_typed_address (pbuf, builtin_type_void_data_ptr);
-	    }
-	}
-    }
-  else /* 64-bit elf */
-    {
-      for (bufend = buf + dyninfo_sect_size;
-	   buf < bufend;
-	   buf += sizeof (Elf64_External_Dyn))
-	{
-	  Elf64_External_Dyn *x_dynp = (Elf64_External_Dyn *) buf;
-	  long dyn_tag;
-	  CORE_ADDR dyn_ptr;
-
-	  dyn_tag = bfd_h_get_64 (exec_bfd, (bfd_byte *) x_dynp->d_tag);
-	  if (dyn_tag == DT_NULL)
-	    break;
-	  else if (dyn_tag == DT_DEBUG)
-	    {
-	      dyn_ptr = bfd_h_get_64 (exec_bfd, 
-				      (bfd_byte *) x_dynp->d_un.d_ptr);
-	      return dyn_ptr;
-	    }
-	  else if (dyn_tag == DT_MIPS_RLD_MAP)
-	    {
-	      gdb_byte *pbuf;
-	      int pbuf_size = TYPE_LENGTH (builtin_type_void_data_ptr);
-
-	      pbuf = alloca (pbuf_size);
-	      /* DT_MIPS_RLD_MAP contains a pointer to the address
-		 of the dynamic link structure.  */
-	      dyn_ptr = bfd_h_get_64 (exec_bfd, 
-				      (bfd_byte *) x_dynp->d_un.d_ptr);
-	      if (target_read_memory (dyn_ptr, pbuf, pbuf_size))
-		return 0;
-	      return extract_typed_address (pbuf, builtin_type_void_data_ptr);
-	    }
-	}
-    }
+  /* This may be a static executable.  Look for the symbol
+     conventionally named _r_debug, as a last resort.  */
+  msymbol = lookup_minimal_symbol ("_r_debug", NULL, symfile_objfile);
+  if (msymbol != NULL)
+    return SYMBOL_VALUE_ADDRESS (msymbol);
 
   /* DT_DEBUG entry not found.  */
   return 0;
@@ -1554,6 +1541,24 @@
 
 struct target_so_ops svr4_so_ops;
 
+/* Lookup global symbol for ELF DSOs linked with -Bsymbolic. Those DSOs have a
+   different rule for symbol lookup.  The lookup begins here in the DSO, not in
+   the main executable.  */
+
+static struct symbol *
+elf_lookup_lib_symbol (const struct objfile *objfile,
+		       const char *name,
+		       const char *linkage_name,
+		       const domain_enum domain, struct symtab **symtab)
+{
+  if (objfile->obfd == NULL
+     || scan_dyntag (DT_SYMBOLIC, objfile->obfd, NULL) != 1)
+    return NULL;
+
+  return  lookup_global_symbol_from_objfile
+		(objfile, name, linkage_name, domain, symtab);
+}
+
 extern initialize_file_ftype _initialize_svr4_solib; /* -Wmissing-prototypes */
 
 void
@@ -1569,6 +1574,7 @@
   svr4_so_ops.current_sos = svr4_current_sos;
   svr4_so_ops.open_symbol_file_object = open_symbol_file_object;
   svr4_so_ops.in_dynsym_resolve_code = svr4_in_dynsym_resolve_code;
+  svr4_so_ops.lookup_lib_global_symbol = elf_lookup_lib_symbol;
 
   /* FIXME: Don't do this here.  *_gdbarch_init() should set so_ops. */
   current_target_so_ops = &svr4_so_ops;
diff -urN src/gdb/solist.h dev/gdb/solist.h
--- src/gdb/solist.h	2007-07-03 05:52:19.000000000 +0200
+++ dev/gdb/solist.h	2007-07-03 05:55:51.000000000 +0200
@@ -23,6 +23,8 @@
 #define SOLIST_H
 
 #define SO_NAME_MAX_PATH_SIZE 512	/* FIXME: Should be dynamic */
+/* For domain_enum domain.  */
+#include "symtab.h"
 
 /* Forward declaration for target specific link map information.  This
    struct is opaque to all but the target specific file.  */
@@ -107,7 +109,14 @@
        Convenience function for remote debuggers finding host libs.  */
     int (*find_and_open_solib) (char *soname,
         unsigned o_flags, char **temp_pathname);
-    
+
+    /* Hook for looking up global symbols in a library-specific way.  */
+    struct symbol * (*lookup_lib_global_symbol) (const struct objfile *objfile,
+						 const char *name,
+						 const char *linkage_name,
+						 const domain_enum domain,
+						 struct symtab **symtab);
+
   };
 
 /* Free the memory associated with a (so_list *).  */
@@ -129,4 +138,11 @@
 #define TARGET_SO_IN_DYNSYM_RESOLVE_CODE \
   (current_target_so_ops->in_dynsym_resolve_code)
 
+/* Handler for library-specific global symbol lookup in solib.c.  */
+struct symbol *solib_global_lookup (const struct objfile *objfile,
+				    const char *name,
+				    const char *linkage_name,
+				    const domain_enum domain,
+				    struct symtab **symtab);
+
 #endif
diff -urN src/gdb/symtab.c dev/gdb/symtab.c
--- src/gdb/symtab.c	2007-06-19 05:22:05.000000000 +0200
+++ dev/gdb/symtab.c	2007-07-03 05:55:51.000000000 +0200
@@ -57,6 +57,7 @@
 #include "cp-abi.h"
 #include "observer.h"
 #include "gdb_assert.h"
+#include "solist.h"
 
 /* Prototypes for local functions */
 
@@ -1261,6 +1262,26 @@
   return NULL;
 }
 
+/* Look up OBJFILE to BLOCK.  */
+
+static struct objfile *
+lookup_objfile_from_block (const struct block *block)
+{
+  struct objfile *obj;
+  struct symtab *s;
+
+  if (block == NULL)
+    return NULL;
+
+  block = block_global_block (block);
+  /* Go through SYMTABS.  */
+  ALL_SYMTABS (obj, s)
+    if (block == BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK))
+      return obj;
+
+  return NULL;
+}
+
 /* Look up a symbol in a block; if found, locate its symtab, fixup the
    symbol, and set block_found appropriately.  */
 
@@ -1302,6 +1323,57 @@
   return NULL;
 }
 
+/* Check all global symbols in OBJFILE in symtabs and
+   psymtabs.  */
+
+struct symbol *
+lookup_global_symbol_from_objfile (const struct objfile *objfile,
+				   const char *name,
+				   const char *linkage_name,
+				   const domain_enum domain,
+				   struct symtab **symtab)
+{
+  struct symbol *sym;
+  struct blockvector *bv;
+  const struct block *block;
+  struct symtab *s;
+  struct partial_symtab *ps;
+
+  /* Go through symtabs.  */
+  ALL_OBJFILE_SYMTABS (objfile, s)
+  {
+    bv = BLOCKVECTOR (s);
+    block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+    sym = lookup_block_symbol (block, name, linkage_name, domain);
+    if (sym)
+      {
+	block_found = block;
+	if (symtab != NULL)
+	  *symtab = s;
+	return fixup_symbol_section (sym, (struct objfile *)objfile);
+      }
+  }
+
+  /* Now go through psymtabs.  */
+  ALL_OBJFILE_PSYMTABS (objfile, ps)
+  {
+    if (!ps->readin
+	&& lookup_partial_symbol (ps, name, linkage_name,
+				  1, domain))
+      {
+	s = PSYMTAB_TO_SYMTAB (ps);
+	bv = BLOCKVECTOR (s);
+	block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+	sym = lookup_block_symbol (block, name, linkage_name, domain);
+	if (symtab != NULL)
+	  *symtab = s;
+	return fixup_symbol_section (sym, (struct objfile *)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,
    depending on whether or not we want to search global symbols or
@@ -1567,7 +1639,7 @@
   if (sym != NULL)
     return sym;
 
-  return lookup_symbol_global (name, linkage_name, domain, symtab);
+  return lookup_symbol_global (name, linkage_name, block, domain, symtab);
 }
 
 /* Lookup a symbol in the static block associated to BLOCK, if there
@@ -1595,10 +1667,19 @@
 struct symbol *
 lookup_symbol_global (const char *name,
 		      const char *linkage_name,
+		      const struct block *block,
 		      const domain_enum domain,
 		      struct symtab **symtab)
 {
-  struct symbol *sym;
+  struct symbol *sym = NULL;
+  struct objfile *objfile = NULL;
+
+  /* Call library-specific lookup procedure.  */
+  objfile = lookup_objfile_from_block (block);
+  if (objfile != NULL)
+    sym = solib_global_lookup (objfile, name, linkage_name, domain, symtab);
+  if (sym != NULL)
+    return sym;
 
   sym = lookup_symbol_aux_symtabs (GLOBAL_BLOCK, name, linkage_name,
 				   domain, symtab);
diff -urN src/gdb/symtab.h dev/gdb/symtab.h
--- src/gdb/symtab.h	2007-06-18 05:36:44.000000000 +0200
+++ dev/gdb/symtab.h	2007-07-03 05:55:51.000000000 +0200
@@ -1050,6 +1050,7 @@
 
 extern struct symbol *lookup_symbol_global (const char *name,
 					    const char *linkage_name,
+					    const struct block *block,
 					    const domain_enum domain,
 					    struct symtab **symtab);
 
@@ -1398,4 +1399,12 @@
 extern void set_main_name (const char *name);
 extern /*const */ char *main_name (void);
 
+/* Check global symbols in objfile.  */
+struct symbol *lookup_global_symbol_from_objfile (const struct objfile *objfile,
+						  const char *name,
+						  const char *linkage_name,
+						  const domain_enum domain,
+						  struct symtab **symtab);
+
+
 #endif /* !defined(SYMTAB_H) */
diff -urN src/gdb/testsuite/gdb.base/solib-symbol.exp dev/gdb/testsuite/gdb.base/solib-symbol.exp
--- src/gdb/testsuite/gdb.base/solib-symbol.exp	1970-01-01 01:00:00.000000000 +0100
+++ dev/gdb/testsuite/gdb.base/solib-symbol.exp	2007-07-03 05:55:51.000000000 +0200
@@ -0,0 +1,80 @@
+# Copyright 2007 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 2 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+#
+# Contributed by Markus Deuling <deuling@de.ibm.com>.
+#
+
+if {[skip_shlib_tests]} {
+    return 0
+}
+
+# Library file.
+set libname "solib-symbol-lib"
+set srcfile_lib ${srcdir}/${subdir}/${libname}.c
+set binfile_lib ${objdir}/${subdir}/${libname}.so
+set lib_flags [list debug ldflags=-Wl,-Bsymbolic]
+# Binary file.
+set testfile "solib-symbol-main"
+set srcfile ${srcdir}/${subdir}/${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+set bin_flags [list debug shlib=${binfile_lib}]
+
+if [get_compiler_info ${binfile}] {
+    return -1
+}
+
+if { [gdb_compile_shlib ${srcfile_lib} ${binfile_lib} $lib_flags] != ""
+     || [gdb_compile ${srcfile} ${binfile} executable $bin_flags] != "" } {
+  untested "Could not compile $binfile_lib or $binfile."
+  return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+gdb_load_shlibs $binfile_lib
+
+if ![runto_main] then {
+  fail "Can't run to main"
+  return 0
+}
+
+# Set a breakpoint in the binary.
+gdb_test "br foo2" \
+	 "Breakpoint.*file.*${srcfile}.*" \
+	 "foo2 in main"
+
+delete_breakpoints
+
+# Break in the library.
+gdb_test "br foo" \
+	 "" \
+	 "foo in libmd"
+
+gdb_test "continue" \
+	 "Continuing.*" \
+	 "continue"
+
+# This symbol is now looked up in the ELF library.
+gdb_test "br foo2" \
+	 "Breakpoint.*file.*${srcfile_lib}.*" \
+	 "foo2 in mdlib"
+
+gdb_exit
+
+return 0
+
+
diff -urN src/gdb/testsuite/gdb.base/solib-symbol-lib.c dev/gdb/testsuite/gdb.base/solib-symbol-lib.c
--- src/gdb/testsuite/gdb.base/solib-symbol-lib.c	1970-01-01 01:00:00.000000000 +0100
+++ dev/gdb/testsuite/gdb.base/solib-symbol-lib.c	2007-07-03 05:55:51.000000000 +0200
@@ -0,0 +1,32 @@
+/* Copyright 2007 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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+   Contributed by Markus Deuling <deuling@de.ibm.com>.
+*/
+#include <stdio.h>
+
+void
+foo ()
+{
+  printf ("foo in lib\n");
+  return;
+}
+
+void
+foo2()
+{
+  printf ("foo2 in lib\n");
+  return;
+}
diff -urN src/gdb/testsuite/gdb.base/solib-symbol-main.c dev/gdb/testsuite/gdb.base/solib-symbol-main.c
--- src/gdb/testsuite/gdb.base/solib-symbol-main.c	1970-01-01 01:00:00.000000000 +0100
+++ dev/gdb/testsuite/gdb.base/solib-symbol-main.c	2007-07-03 05:55:51.000000000 +0200
@@ -0,0 +1,43 @@
+/* Copyright 2007 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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+   Contributed by Markus Deuling <deuling@de.ibm.com>.
+*/
+#include <stdio.h>
+
+extern void foo();
+void foo3();
+void foo2();
+
+int main ()
+{
+  printf ("in main\n");
+  foo ();
+  foo3 ();
+  return 0;
+}
+
+void foo3()
+{
+  printf ("foo3 in main\n");
+  return;
+}
+
+void foo2()
+{
+  printf ("foo2 in main\n");
+  return;
+}
+

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PING 2] [rfc]: Framework for looking up multiply defined global           symbols  in shared libraries
  2007-07-03  4:04                       ` Markus Deuling
@ 2007-07-03 12:17                         ` Ulrich Weigand
  2007-07-03 12:28                           ` Daniel Jacobowitz
  2007-07-04  3:50                           ` Markus Deuling
  0 siblings, 2 replies; 24+ messages in thread
From: Ulrich Weigand @ 2007-07-03 12:17 UTC (permalink / raw)
  To: Markus Deuling
  Cc: Joel Brobecker, GDB Patches, Daniel Jacobowitz, Kevin Buettner, eliz

Markus Deuling wrote:

> 	* cp-namespace.c (lookup_symbol_file): Add block to
> 	lookup_symbol_global call.
> 	* Makefile.in (solist_h): Add dependency on symtab header.
> 	(symtab.o): Add dependency on solist header.
> 	* solib.c (solib_global_lookup): New function.
> 	* solib-svr4.c (scan_dyntag): Likewise.
> 	(elf_locate_base): Call helper routine scan_dyntag.
> 	(elf_lookup_lib_symbol): New function.
> 	(_initialize_svr4_solib): Add elf_lookup_lib_symbol to svr4_so_ops.
> 	* solist.h (symtab.h): New include.
> 	(lookup_lib_global_symbol): New prototype.

I guess this should read:
	(struct target_so_ops): New member lookup_lib_global_symbol.

> 	(solib_global_lookup): Likewise.
> 	* symtab.c: New include solist.h.
> 	(lookup_objfile_from_block): New function.
> 	(lookup_global_symbol_from_objfile): New function.
> 	(basic_lookup_symbol_nonlocal): Add block to lookup_symbol_global call.
> 	(lookup_symbol_global): Call library-specific lookup procedure.
> 	* symtab.h (lookup_global_symbol_from_objfile): New prototype.

> 	* gdb.base/libmd.c: New file (testcase multiple symbol lookup).
> 	* gdb.base/libmd.h: Likewise.
> 	* gdb.base/solib_symbol.c: Likewise.
> 	* gdb.base/solib_symbol.exp: Likewise.

And those file names have changed in the latest version:
	* gdb.base/solib-symbol.exp: New file (testcase multiple symbol lookup).
	* gdb.base/solib-symbol-lib.c: Likewise.
	* gdb.base/solib-symbol-main.c: Likewise.

I've committed the patch with the above ChangeLog changes now.

Thanks,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PING 2] [rfc]: Framework for looking up multiply defined  global           symbols  in shared libraries
  2007-07-03 12:17                         ` Ulrich Weigand
@ 2007-07-03 12:28                           ` Daniel Jacobowitz
  2007-07-04  3:50                           ` Markus Deuling
  1 sibling, 0 replies; 24+ messages in thread
From: Daniel Jacobowitz @ 2007-07-03 12:28 UTC (permalink / raw)
  To: GDB Patches

On Tue, Jul 03, 2007 at 02:17:19PM +0200, Ulrich Weigand wrote:
> I've committed the patch with the above ChangeLog changes now.

Thanks for taking care of this!

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PING 2] [rfc]: Framework for looking up multiply defined global            symbols  in shared libraries
  2007-07-03 12:17                         ` Ulrich Weigand
  2007-07-03 12:28                           ` Daniel Jacobowitz
@ 2007-07-04  3:50                           ` Markus Deuling
  1 sibling, 0 replies; 24+ messages in thread
From: Markus Deuling @ 2007-07-04  3:50 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: GDB Patches

Ulrich Weigand schrieb:
> Markus Deuling wrote:
> 
>> 	* cp-namespace.c (lookup_symbol_file): Add block to
>> 	lookup_symbol_global call.
>> 	* Makefile.in (solist_h): Add dependency on symtab header.
>> 	(symtab.o): Add dependency on solist header.
>> 	* solib.c (solib_global_lookup): New function.
>> 	* solib-svr4.c (scan_dyntag): Likewise.
>> 	(elf_locate_base): Call helper routine scan_dyntag.
>> 	(elf_lookup_lib_symbol): New function.
>> 	(_initialize_svr4_solib): Add elf_lookup_lib_symbol to svr4_so_ops.
>> 	* solist.h (symtab.h): New include.
>> 	(lookup_lib_global_symbol): New prototype.
> 
> I guess this should read:
> 	(struct target_so_ops): New member lookup_lib_global_symbol.
> 
>> 	(solib_global_lookup): Likewise.
>> 	* symtab.c: New include solist.h.
>> 	(lookup_objfile_from_block): New function.
>> 	(lookup_global_symbol_from_objfile): New function.
>> 	(basic_lookup_symbol_nonlocal): Add block to lookup_symbol_global call.
>> 	(lookup_symbol_global): Call library-specific lookup procedure.
>> 	* symtab.h (lookup_global_symbol_from_objfile): New prototype.
> 
>> 	* gdb.base/libmd.c: New file (testcase multiple symbol lookup).
>> 	* gdb.base/libmd.h: Likewise.
>> 	* gdb.base/solib_symbol.c: Likewise.
>> 	* gdb.base/solib_symbol.exp: Likewise.
> 
> And those file names have changed in the latest version:
> 	* gdb.base/solib-symbol.exp: New file (testcase multiple symbol lookup).
> 	* gdb.base/solib-symbol-lib.c: Likewise.
> 	* gdb.base/solib-symbol-main.c: Likewise.
> 
> I've committed the patch with the above ChangeLog changes now.
> 
> Thanks,
> Ulrich
> 

Thank you very much.

-- 
Markus Deuling
GNU Toolchain for Linux on Cell BE
deuling@de.ibm.com


^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2007-07-04  3:50 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-05-10 12:33 [PING] [rfc]: Framework for looking up multiply defined global symbols in shared libraries Markus Deuling
2007-05-10 13:00 ` Daniel Jacobowitz
2007-05-10 14:52   ` Markus Deuling
2007-05-14 17:53     ` Daniel Jacobowitz
2007-05-14 18:25 ` Daniel Jacobowitz
2007-05-15  5:49   ` Markus Deuling
2007-05-18  4:13     ` Markus Deuling
2007-05-31 21:40       ` Ulrich Weigand
2007-06-05  3:46         ` Markus Deuling
2007-06-20  6:58           ` [PING 2] " Markus Deuling
2007-06-26 18:31             ` Joel Brobecker
2007-06-26 18:35             ` Joel Brobecker
2007-06-26 20:34               ` Markus Deuling
2007-06-28 15:32                 ` Ulrich Weigand
2007-06-28 15:33                   ` Joel Brobecker
2007-06-28 18:20                   ` Markus Deuling
2007-06-29 17:03                     ` Eli Zaretskii
2007-07-02 18:24                     ` Ulrich Weigand
2007-07-03  4:04                       ` Markus Deuling
2007-07-03 12:17                         ` Ulrich Weigand
2007-07-03 12:28                           ` Daniel Jacobowitz
2007-07-04  3:50                           ` Markus Deuling
2007-06-29 17:15                   ` Eli Zaretskii
2007-06-25 21:48           ` [PING] " Kevin Buettner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox