[RFA] Introduce solib_loaded observer

Mark Kettenis
2005-01-08T23:14:34Z

This patch introduces a new solib_loaded observer that parallels the
solub_unloaded observer that we already have. I need this observer to
properly implement a threads stratum for FreeBSD and OpenBSD
user-space threads library support. With this observer I'll also be
able to fix the problems we're having with statically linked programs
that use the threading library on Linux. If you think about it a bit,
the problems with static thread libraries stem from the fact that we
abuse the now deprecated target_new_objfile_hook to get notified about
newly loaded libraries. Unfortunately that hook is also called when
the main executable is loaded, which causes all kinds of trouble.

The patch below doesn't only implement the new observer. The reason
for that is that when the solib_loaded observer is called, the symbols
for the new library haven't been loaded yet. So I've split out the
code to read in those symbols out from solib_add() into a seperate
function, and made that public.

OK?

Mark

Index: ChangeLog
from Mark Kettenis <kettenis@gnu.org>

* solib.h (struct so_list): Forward declaration.
(solib_read_symbols): New prototype.
* solib.c (solib_read_symbols): New function.
(solib_add): Call solib_read_symbols to read in symbols.
(update_solib_list): Call observer_notify_solib_loaded.

Index: doc/ChangeLog
from Mark Kettenis <kettenis@gnu.org>

* observer.texi (GDB Observers): Document "solib_loaded".

Index: solib.c
===================================================================
RCS file: /cvs/src/src/gdb/solib.c,v
retrieving revision 1.68
diff -u -p -r1.68 solib.c
--- solib.c 11 Sep 2004 10:24:50 -0000 1.68
+++ solib.c 8 Jan 2005 23:10:34 -0000
@@ -1,7 +1,8 @@
/* Handle shared libraries for GDB, the GNU Debugger.

Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2005
+ Free Software Foundation, Inc.

This file is part of GDB.

@@ -369,6 +370,33 @@ symbol_add_stub (void *arg)
return (1);
}

+/* Read in symbols for shared object SO. If FROM_TTY is non-zero, be
+ chatty about it. Return non-zero if any symbols were actually
+ loaded. */
+
+int
+solib_read_symbols (struct so_list *so, int from_tty)
+{
+ if (so->symbols_loaded)
+ {
+ if (from_tty)
+ printf_unfiltered ("Symbols already loaded for %s\n", so->so_name);
+ }
+ else
+ {
+ if (catch_errors (symbol_add_stub, so,
+ "Error while reading shared library symbols:\n",
+ RETURN_MASK_ALL))
+ {
+ if (from_tty)
+ printf_unfiltered ("Loaded symbols for %s\n", so->so_name);
+ so->symbols_loaded = 1;
+ return 1;
+ }
+ }
+
+ return 0;
+}

/* LOCAL FUNCTION

@@ -479,8 +507,8 @@ update_solib_list (int from_tty, struct
/* If it's not on the inferior's list, remove it from GDB's tables. */
else
{
- /* Notify any observer that the SO has been unloaded
- before we remove it from the gdb tables. */
+ /* Notify any observer that the shared object has been
+ unloaded before we remove it from GDB's tables. */
observer_notify_solib_unloaded (gdb);

*gdb_link = gdb->next;
@@ -533,6 +561,10 @@ update_solib_list (int from_tty, struct
count * sizeof (i->sections[0]));
}
}
+
+ /* Notify any observer that the shared object has been
+ loaded now that we've added it to GDB's tables. */
+ observer_notify_solib_loaded (i);
}
}
}
@@ -584,27 +616,8 @@ solib_add (char *pattern, int from_tty,
if (! pattern || re_exec (gdb->so_name))
{
any_matches = 1;
-
- if (gdb->symbols_loaded)
- {
- if (from_tty)
- printf_unfiltered ("Symbols already loaded for %s\n",
- gdb->so_name);
- }
- else if (readsyms)
- {
- if (catch_errors
- (symbol_add_stub, gdb,
- "Error while reading shared library symbols:\n",
- RETURN_MASK_ALL))
- {
- if (from_tty)
- printf_unfiltered ("Loaded symbols for %s\n",
- gdb->so_name);
- gdb->symbols_loaded = 1;
- loaded_any_symbols = 1;
- }
- }
+ if (readsyms && solib_read_symbols (gdb, from_tty))
+ loaded_any_symbols = 1;
}

if (from_tty && pattern && ! any_matches)
Index: solib.h
===================================================================
RCS file: /cvs/src/src/gdb/solib.h,v
retrieving revision 1.12
diff -u -p -r1.12 solib.h
--- solib.h 16 Dec 2003 21:46:10 -0000 1.12
+++ solib.h 8 Jan 2005 23:10:34 -0000
@@ -23,6 +23,7 @@
#define SOLIB_H

/* Forward decl's for prototypes */
+struct so_list;
struct target_ops;

/* Called when we free all symtabs, to free the shared library information
@@ -38,6 +39,7 @@ extern void clear_solib (void);
solib_add (filename, from_tty, targ, readsyms)

extern void solib_add (char *, int, struct target_ops *, int);
+extern int solib_read_symbols (struct so_list *, int);

/* Function to be called when the inferior starts up, to discover the names
of shared libraries that are dynamically linked, the base addresses to
Index: doc/observer.texi
===================================================================
RCS file: /cvs/src/src/gdb/doc/observer.texi,v
retrieving revision 1.8
diff -u -p -r1.8 observer.texi
--- doc/observer.texi 1 Sep 2004 17:59:37 -0000 1.8
+++ doc/observer.texi 8 Jan 2005 23:10:38 -0000
@@ -91,6 +91,12 @@ at the entry-point instruction. For @sa
inferior, and before any information on the inferior has been printed.
@end deftypefun

+@deftypefun void solib_loaded (struct so_list *@var{solib})
+The specified shared library has been discovered to be loaded. Note
+that when @value{GDBN} calls this observer, the library's symbols
+probably haven't been loaded yet.
+@end deftypefun
+
@deftypefun void solib_unloaded (struct so_list *@var{solib})
The specified shared library has been discovered to be unloaded.
@end deftypefun