* symfile.c (auto_solib_add): Renamed from auto_solib_add_at_startup.
authorJeff Law <law@redhat.com>
Tue, 23 Jan 1996 21:06:34 +0000 (21:06 +0000)
committerJeff Law <law@redhat.com>
Tue, 23 Jan 1996 21:06:34 +0000 (21:06 +0000)
        All references changed.
        * breakpoint.c (bpstat_what): Add shlib_event to the class types.
        Update state table.  Reformat so that it's still readable.
        When we hit the shlib_event breakpoint, set the calss of shlib_event.
        (breakpoint_1): Add "shlib events" as a breakpoint type.
        Print the shlib_event breakpoint like other breakpoints.
        (create_solib_event_breakpoint): New function.
        (breakpoint_re_set_one): Handle solib_event breakpoints.
        * breakpoint.h (enum bytype): Add bp_shlib_event breakpoint type.
        (enum bpstat_what_main_action): Add BPSTAT_WHAT_CHECK_SHLIBS
        action.
        (create_solib_event_breakpoint): Declare.
        * infrun.c (wait_for_inferior): Handle CHECK_SHLIBS bpstat.
        (normal_stop): Inform the user when the inferior stoped due
        to a shared library event.
        (_initialize_infrun): Add new set/show variable "stop_on-solib-events"
        to control whether or not gdb continues the inferior or stops it when
        a shared library event occurs.
        * minsyms.c (lookup_minimal_symbol_solib_trampoline): New function.
        * somsolib.c (TODO list): Update.
        (som_solib_create_inferior_hook): Arrange for gdb to be notified
        when significant shared library events occur.
        * hppa-tdep.c (find_unwind_entry): No longer static.
First cut at the machine independent changes for 7363.  Also includes
code to automatically track shl_load/shl_unload calls on hpux.

gdb/ChangeLog
gdb/NEWS
gdb/hppa-tdep.c
gdb/infrun.c
gdb/irix5-nat.c
gdb/minsyms.c
gdb/osfsolib.c
gdb/somsolib.c

index 861c03dcbc046c17c865736beaaa12fe73a04a16..a0c947f64854adfe38877eacabcbfe104d85b790 100644 (file)
@@ -1,3 +1,30 @@
+Tue Jan 23 13:08:26 1996  Jeffrey A Law  (law@cygnus.com)
+
+       * symfile.c (auto_solib_add): Renamed from auto_solib_add_at_startup.
+       All references changed.
+       * breakpoint.c (bpstat_what): Add shlib_event to the class types.
+       Update state table.  Reformat so that it's still readable.
+       When we hit the shlib_event breakpoint, set the calss of shlib_event.
+       (breakpoint_1): Add "shlib events" as a breakpoint type.
+       Print the shlib_event breakpoint like other breakpoints.
+       (create_solib_event_breakpoint): New function.
+       (breakpoint_re_set_one): Handle solib_event breakpoints.
+       * breakpoint.h (enum bytype): Add bp_shlib_event breakpoint type.
+       (enum bpstat_what_main_action): Add BPSTAT_WHAT_CHECK_SHLIBS
+       action.
+       (create_solib_event_breakpoint): Declare.
+       * infrun.c (wait_for_inferior): Handle CHECK_SHLIBS bpstat.
+       (normal_stop): Inform the user when the inferior stoped due
+       to a shared library event.
+       (_initialize_infrun): Add new set/show variable "stop_on-solib-events"
+       to control whether or not gdb continues the inferior or stops it when
+       a shared library event occurs.
+       * minsyms.c (lookup_minimal_symbol_solib_trampoline): New function.
+       * somsolib.c (TODO list): Update.
+       (som_solib_create_inferior_hook): Arrange for gdb to be notified
+       when significant shared library events occur.
+       * hppa-tdep.c (find_unwind_entry): No longer static.
+
 Tue Jan 23 09:00:48 1996  Doug Evans  <dje@charmed.cygnus.com>
 
        * gdbtk.c (gdb_disassemble): Rework disassemble_info initialization.
index 1d754cd5e7160714809ba61ec75ec882191d0961..0867bde4c7849434a64507dd1bea7cf6dca1d545 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -19,6 +19,19 @@ The standard remote protocol now includes an option to send a break
 rather than a ^C to the target in order to interrupt it.  By default,
 GDB will send ^C; to send a break, set the variable `remotebreak' to 1.
 
+* Automatic tracking of dynamic object loading (HPUX only at the moment).
+
+By default GDB will automatically keep track of objects as they are
+loaded and unloaded by the dynamic linker.  By using the command
+"set stop-on-solib-events 1" you can arrange for GDB to stop the
+inferior when shared library events occur, thus allowing you to
+set breakpoints in shared libraries which are explicitly loaded by
+the inferior.
+
+Note this feature does not work on hpux8.  On hpux9 you must link 
+/usr/lib/end.o into your program.  This feature should work automatically
+on hpux10.
+
 *** Changes in GDB-4.15:
 
 * Psymtabs for XCOFF
index 4fee8b078d197310d74770e9784bd7ca7c401e3a..544d72665e975b5a3fe1b791426cbf2b23df30f0 100644 (file)
@@ -1,5 +1,5 @@
 /* Target-dependent code for the HP PA architecture, for GDB.
-   Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995
+   Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
    Free Software Foundation, Inc.
 
    Contributed by the Center for Software Science at the
@@ -487,7 +487,7 @@ read_unwind_info (objfile)
    contains a sorted list of struct unwind_table_entry.  Since we do a binary
    search of the unwind tables, we depend upon them to be sorted.  */
 
-static struct unwind_table_entry *
+struct unwind_table_entry *
 find_unwind_entry(pc)
      CORE_ADDR pc;
 {
index 73647aa35d205448dc5e95e62ad9efe51bdf2fd5..19ff2d3dd66e374f76083ca1efed2b8100704047 100644 (file)
@@ -1,5 +1,5 @@
 /* Target-struct-independent code to start (run) and stop an inferior process.
-   Copyright 1986, 1987, 1988, 1989, 1991, 1992, 1993, 1994
+   Copyright 1986, 1987, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996
    Free Software Foundation, Inc.
 
 This file is part of GDB.
@@ -72,6 +72,21 @@ static int hook_stop_stub PARAMS ((char *));
 #define        SKIP_TRAMPOLINE_CODE(pc)        0
 #endif
 
+/* Dynamic function trampolines are similar to solib trampolines in that they
+   are between the caller and the callee.  The difference is that when you
+   enter a dynamic trampoline, you can't determine the callee's address.  Some
+   (usually complex) code needs to run in the dynamic trampoline to figure out
+   the callee's address.  This macro is usually called twice.  First, when we
+   enter the trampoline (looks like a normal function call at that point).  It
+   should return the PC of a point within the trampoline where the callee's
+   address is known.  Second, when we hit the breakpoint, this routine returns
+   the callee's address.  At that point, things proceed as per a step resume
+   breakpoint.  */
+
+#ifndef DYNAMIC_TRAMPOLINE_NEXTPC
+#define DYNAMIC_TRAMPOLINE_NEXTPC(pc) 0
+#endif
+
 /* For SVR4 shared libraries, each call goes through a small piece of
    trampoline code in the ".plt" section.  IN_SOLIB_CALL_TRAMPOLINE evaluates
    to nonzero if we are current stopped in one of these. */
@@ -136,6 +151,10 @@ static struct symbol *step_start_function;
 
 static int trap_expected;
 
+/* Nonzero if we want to give control to the user when we're notified
+   of shared library events by the dynamic linker.  */
+static int stop_on_solib_events;
+
 #ifdef HP_OS_BUG
 /* Nonzero if the next time we try to continue the inferior, it will
    step one instruction and generate a spurious trace trap.
@@ -1015,6 +1034,35 @@ wait_for_inferior ()
              another_trap = 1;
            break;
 
+#ifdef SOLIB_ADD
+         case BPSTAT_WHAT_CHECK_SHLIBS:
+           {
+             extern int auto_solib_add;
+
+             /* Check for any newly added shared libraries if we're
+                supposed to be adding them automatically.  */
+             if (auto_solib_add)
+               SOLIB_ADD (NULL, 0, NULL);
+
+             /* If requested, stop when the dynamic linker notifies
+                gdb of events.  This allows the user to get control
+                and place breakpoints in initializer routines for
+                dynamically loaded objects (among other things).  */
+             if (stop_on_solib_events)
+               {
+                 stop_print_frame = 0;
+                 goto stop_stepping;
+               }
+             else
+               {
+                 /* We want to step over this breakpoint, then keep going.  */
+                 another_trap = 1;
+                 remove_breakpoints_on_following_step = 1;
+                 break;
+               }
+           }
+#endif
+
          case BPSTAT_WHAT_LAST:
            /* Not a real code, but listed here to shut up gcc -Wall.  */
 
@@ -1208,8 +1256,9 @@ wait_for_inferior ()
                 handling_longjmp stuff is working.  */
              ))
 #else
-/* This is experimental code which greatly simplifies the subroutine call
-   test.  I've actually tested on the Alpha, and it works great. -Stu */
+       /* This test is a much more streamlined, (but hopefully correct)
+          replacement for the code above.  It's been tested on the Sparc,
+          Mips, PA, and Power architectures with good results.  */
 
        if (stop_pc == stop_func_start /* Quick test */
            || in_prologue (stop_pc, stop_func_start)
@@ -1241,6 +1290,22 @@ wait_for_inferior ()
          tmp = SKIP_TRAMPOLINE_CODE (stop_pc);
          if (tmp != 0)
            stop_func_start = tmp;
+         else
+           {
+             tmp = DYNAMIC_TRAMPOLINE_NEXTPC (stop_pc);
+             if (tmp)
+               {
+                 struct symtab_and_line xxx;
+
+                 xxx.pc = tmp;
+                 xxx.symtab = NULL;
+                 xxx.line = 0;
+                 step_resume_breakpoint = 
+                   set_momentary_breakpoint (xxx, NULL, bp_step_resume);
+                 insert_breakpoints ();
+                 goto keep_going;
+               }
+           }
 
          /* If we have line number information for the function we
             are thinking of stepping into, step into it.
@@ -1593,6 +1658,9 @@ Further execution is probably impossible.\n");
 
   target_terminal_ours ();
 
+  if (stop_bpstat && stop_bpstat->breakpoint_at->type == bp_shlib_event)
+    printf_filtered ("Stopped due to shared library event\n");
+
   /* Look up the hook_stop and run it if it exists.  */
 
   if (stop_command->hook)
@@ -2121,4 +2189,16 @@ of the program stops.", &cmdlist);
   signal_print[TARGET_SIGNAL_POLL] = 0;
   signal_stop[TARGET_SIGNAL_URG] = 0;
   signal_print[TARGET_SIGNAL_URG] = 0;
+
+#ifdef SOLIB_ADD
+  add_show_from_set
+    (add_set_cmd ("stop-on-solib-events", class_support, var_zinteger,
+                  (char *) &stop_on_solib_events,
+                 "Set stopping for shared library events.\n\
+If nonzero, gdb will give control to the user when the dynamic linker\n\
+notifies gdb of shared library events.  The most common event of interest\n\
+to the user would be loading/unloading of a new library.\n",
+                  &setlist),
+     &showlist);
+#endif
 }
index 1be5d4d829a75250da93d6938ca4163e74680275..fc4c8cb10425a149da7d002fb8c02ca4c27733f8 100644 (file)
@@ -1,5 +1,5 @@
 /* Native support for the SGI Iris running IRIX version 5, for GDB.
-   Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995
+   Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
    Free Software Foundation, Inc.
    Contributed by Alessandro Forin(af@cs.cmu.edu) at CMU
    and by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin.
@@ -1001,7 +1001,7 @@ solib_create_inferior_hook()
       and will put out an annoying warning.
       Delaying the resetting of stop_soon_quietly until after symbol loading
       suppresses the warning.  */
-  if (auto_solib_add_at_startup)
+  if (auto_solib_add)
     solib_add ((char *) 0, 0, (struct target_ops *) 0);
   stop_soon_quietly = 0;
 }
@@ -1039,10 +1039,11 @@ _initialize_solib()
 
   add_show_from_set
     (add_set_cmd ("auto-solib-add", class_support, var_zinteger,
-                 (char *) &auto_solib_add_at_startup,
-                 "Set autoloading of shared library symbols at startup.\n\
+                 (char *) &auto_solib_add,
+                 "Set autoloading of shared library symbols.\n\
 If nonzero, symbols from all shared object libraries will be loaded\n\
-automatically when the inferior begins execution.  Otherwise, symbols\n\
+automatically when the inferior begins execution or when the dynamic linker\n\
+informs gdb that a new library has been loaded.  Otherwise, symbols\n\
 must be loaded manually, using `sharedlibrary'.",
                  &setlist),
      &showlist);
index e36302ea8ed92c80d74ae0b40eec52d261adf49f..6ef709a734968d4f017f1d87e33b510e46959283 100644 (file)
@@ -1,5 +1,5 @@
 /* GDB routines for manipulating the minimal symbol tables.
-   Copyright 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+   Copyright 1992, 1993, 1994, 1996, 1996 Free Software Foundation, Inc.
    Contributed by Cygnus Support, using pieces from other GDB modules.
 
 This file is part of GDB.
@@ -253,6 +253,56 @@ lookup_minimal_symbol_text (name, sfile, objf)
   return NULL;
 }
 
+/* Look through all the current minimal symbol tables and find the
+   first minimal symbol that matches NAME and of solib trampoline type.  
+   If OBJF is non-NULL, limit
+   the search to that objfile.  If SFILE is non-NULL, limit the search
+   to that source file.  Returns a pointer to the minimal symbol that
+   matches, or NULL if no match is found.
+*/
+   
+struct minimal_symbol *
+lookup_minimal_symbol_solib_trampoline (name, sfile, objf)
+     register const char *name;
+     const char *sfile;
+     struct objfile *objf;
+{
+  struct objfile *objfile;
+  struct minimal_symbol *msymbol;
+  struct minimal_symbol *found_symbol = NULL;
+  struct minimal_symbol *found_file_symbol = NULL;
+
+#ifdef SOFUN_ADDRESS_MAYBE_MISSING
+  if (sfile != NULL)
+    {
+      char *p = strrchr (sfile, '/');
+      if (p != NULL)
+       sfile = p + 1;
+    }
+#endif
+
+  for (objfile = object_files;
+       objfile != NULL && found_symbol == NULL;
+       objfile = objfile -> next)
+    {
+      if (objf == NULL || objf == objfile)
+       {
+         for (msymbol = objfile -> msymbols;
+              msymbol != NULL && SYMBOL_NAME (msymbol) != NULL &&
+              found_symbol == NULL;
+              msymbol++)
+           {
+             if (SYMBOL_MATCHES_NAME (msymbol, name) && 
+                 MSYMBOL_TYPE (msymbol) == mst_solib_trampoline)
+               return msymbol;
+           }
+       }
+    }
+
+  return NULL;
+}
+
+
 /* Search through the minimal symbol table for each objfile and find the
    symbol whose address is the largest address that is still less than or
    equal to PC.  Returns a pointer to the minimal symbol if such a symbol
index b97e683968d30904bb68ba9c73c1d607cce334f4..85afa24211c73566a555d0550ca5ebf948a0c903 100644 (file)
@@ -1,5 +1,5 @@
 /* Handle OSF/1 shared libraries for GDB, the GNU Debugger.
-   Copyright 1993, 1994, 1995 Free Software Foundation, Inc.
+   Copyright 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
    
 This file is part of GDB.
 
@@ -905,7 +905,7 @@ solib_create_inferior_hook()
       and will put out an annoying warning.
       Delaying the resetting of stop_soon_quietly until after symbol loading
       suppresses the warning.  */
-  if (auto_solib_add_at_startup)
+  if (auto_solib_add)
     solib_add ((char *) 0, 0, (struct target_ops *) 0);
   stop_soon_quietly = 0;
 }
@@ -944,10 +944,11 @@ _initialize_solib()
 
   add_show_from_set
     (add_set_cmd ("auto-solib-add", class_support, var_zinteger,
-                 (char *) &auto_solib_add_at_startup,
-                 "Set autoloading of shared library symbols at startup.\n\
+                 (char *) &auto_solib_add,
+                 "Set autoloading of shared library symbols.\n\
 If nonzero, symbols from all shared object libraries will be loaded\n\
-automatically when the inferior begins execution.  Otherwise, symbols\n\
+automatically when the inferior begins execution or when the dynamic linker\n\
+informs gdb that a new library has been loaded.  Otherwise, symbols\n\
 must be loaded manually, using `sharedlibrary'.",
                  &setlist),
      &showlist);
index 595752c203ea00226f1e3379ee24e53854e6bdb4..2d232b3801ee8451db2ed1d5a9c44813d5df9f73 100644 (file)
@@ -1,5 +1,5 @@
 /* Handle HP SOM shared libraries for GDB, the GNU Debugger.
-   Copyright 1993 Free Software Foundation, Inc.
+   Copyright 1993, 1996 Free Software Foundation, Inc.
 
 This file is part of GDB.
 
@@ -41,11 +41,7 @@ and by Cygnus Support.  */
    * Most of this code should work for hp300 shared libraries.  Does
    anyone care enough to weed out any SOM-isms.
 
-   * Do we need/want a command to load a shared library?
-
-   * Support for hpux8 dynamic linker.
-
-   * Support for tracking user calls to dld_load, dld_unload.  */
+   * Support for hpux8 dynamic linker.  */
 
 /* The basic structure which describes a dynamically loaded object.  This
    data structure is private to the dynamic linker and isn't found in
@@ -499,9 +495,10 @@ void
 som_solib_create_inferior_hook()
 {
   struct minimal_symbol *msymbol;
-  unsigned int dld_flags, status;
+  unsigned int dld_flags, status, have_endo;
   asection *shlib_info;
   char shadow_contents[BREAKPOINT_MAX], buf[4];
+  struct objfile *objfile;
   CORE_ADDR anaddr;
 
   if (symfile_objfile == NULL)
@@ -516,12 +513,106 @@ som_solib_create_inferior_hook()
   if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0)
     return;
 
+  have_endo = 0;
+  /* Slam the pid of the process into __d_pid; failing is only a warning!  */
+  msymbol = lookup_minimal_symbol ("__d_pid", NULL, symfile_objfile);
+  if (msymbol == NULL)
+    {
+      warning ("Unable to find __d_pid symbol in object file.\n");
+      warning ("Suggest linking with /usr/lib/end.o.\n");
+      warning ("GDB will be unable to track shl_load/shl_unload calls\n");
+      goto keep_going;
+    }
+
+  anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
+  store_unsigned_integer (buf, 4, inferior_pid);
+  status = target_write_memory (anaddr, buf, 4);
+  if (status != 0)
+    {
+      warning ("Unable to write __d_pid\n");
+      warning ("Suggest linking with /usr/lib/end.o.\n");
+      warning ("GDB will be unable to track shl_load/shl_unload calls\n");
+      goto keep_going;
+    }
+
+  /* Get the value of _DLD_HOOK (an export stub) and put it in __dld_hook;
+     This will force the dynamic linker to call __d_trap when significant
+     events occur.  */
+  msymbol = lookup_minimal_symbol ("_DLD_HOOK", NULL, symfile_objfile);
+  if (msymbol == NULL)
+    {
+      warning ("Unable to find _DLD_HOOK symbol in object file.\n");
+      warning ("Suggest linking with /usr/lib/end.o.\n");
+      warning ("GDB will be unable to track shl_load/shl_unload calls\n");
+      goto keep_going;
+    }
+  anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
+
+  /* Grrr, this might not be an export symbol!  We have to find the
+     export stub.  */
+  ALL_OBJFILES (objfile)
+    {
+      struct unwind_table_entry *u;
+
+      /* What a crock.  */
+      msymbol = lookup_minimal_symbol_solib_trampoline (SYMBOL_NAME (msymbol),
+                                                       NULL, objfile);
+      /* Found a symbol with the right name.  */
+      if (msymbol)
+       {
+         struct unwind_table_entry *u;
+         /* It must be a shared library trampoline.  */
+         if (SYMBOL_TYPE (msymbol) != mst_solib_trampoline)
+           continue;
+
+         /* It must also be an export stub.  */
+         u = find_unwind_entry (SYMBOL_VALUE (msymbol));
+         if (!u || u->stub_type != EXPORT)
+           continue;
+
+         /* OK.  Looks like the correct import stub.  */
+         anaddr = SYMBOL_VALUE (msymbol);
+         break;
+       }
+     }
+  store_unsigned_integer (buf, 4, anaddr);
+
+  msymbol = lookup_minimal_symbol ("__dld_hook", NULL, symfile_objfile);
+  if (msymbol == NULL)
+    {
+      warning ("Unable to find __dld_hook symbol in object file.\n");
+      warning ("Suggest linking with /usr/lib/end.o.\n");
+      warning ("GDB will be unable to track shl_load/shl_unload calls\n");
+      goto keep_going;
+    }
+  anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
+  status = target_write_memory (anaddr, buf, 4);
+  
+  /* Now set a shlib_event breakpoint at __d_trap so we can track
+     significant shared library events.  */
+  msymbol = lookup_minimal_symbol ("__d_trap", NULL, symfile_objfile);
+  if (msymbol == NULL)
+    {
+      warning ("Unable to find __dld_d_trap symbol in object file.\n");
+      warning ("Suggest linking with /usr/lib/end.o.\n");
+      warning ("GDB will be unable to track shl_load/shl_unload calls\n");
+      goto keep_going;
+    }
+  create_solib_event_breakpoint (SYMBOL_VALUE_ADDRESS (msymbol));
+
+  /* We have all the support usually found in end.o, so we can track
+     shl_load and shl_unload calls.  */
+  have_endo = 1;
+
+keep_going:
+
   /* Get the address of __dld_flags, if no such symbol exists, then we can
      not debug the shared code.  */
   msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL);
   if (msymbol == NULL)
     {
       error ("Unable to find __dld_flags symbol in object file.\n");
+      goto keep_going;
       return;
     }
 
@@ -536,7 +627,7 @@ som_solib_create_inferior_hook()
   dld_flags = extract_unsigned_integer (buf, 4);
 
   /* Turn on the flags we care about.  */
-  dld_flags |= 0x5;
+  dld_flags |= (0x5 | (have_endo << 1));
   store_unsigned_integer (buf, 4, dld_flags);
   status = target_write_memory (anaddr, buf, 4);
   if (status != 0)
@@ -545,7 +636,15 @@ som_solib_create_inferior_hook()
       return;
     }
 
-  /* Now find the address of _start and set a breakpoint there.  */
+  /* Now find the address of _start and set a breakpoint there. 
+     We still need this code for two reasons:
+
+       * Not all sites have /usr/lib/end.o, so it's not always
+       possible to track the dynamic linker's events.
+
+       * At this time no events are triggered for shared libraries
+       loaded at startup time (what a crock).  */
+       
   msymbol = lookup_minimal_symbol ("_start", NULL, symfile_objfile);
   if (msymbol == NULL)
     {
@@ -592,7 +691,7 @@ som_solib_create_inferior_hook()
       return;
     }
 
-  if (auto_solib_add_at_startup)
+  if (auto_solib_add)
     som_solib_add ((char *) 0, 0, (struct target_ops *) 0);
 }
 
@@ -728,10 +827,11 @@ _initialize_som_solib ()
            "Status of loaded shared object libraries.");
   add_show_from_set
     (add_set_cmd ("auto-solib-add", class_support, var_zinteger,
-                 (char *) &auto_solib_add_at_startup,
+                 (char *) &auto_solib_add,
                  "Set autoloading of shared library symbols at startup.\n\
 If nonzero, symbols from all shared object libraries will be loaded\n\
-automatically when the inferior begins execution.  Otherwise, symbols\n\
+automatically when the inferior begins execution or when the dynamic linker\n\
+informs gdb that a new library has been loaded.  Otherwise, symbols\n\
 must be loaded manually, using `sharedlibrary'.",
                  &setlist),
      &showlist);