#include "objfiles.h"
#include "inferior.h"
#include "gdb-stabs.h"
+#include "gdb_stat.h"
#include "gdbcmd.h"
+#include "language.h"
/* TODO:
static void som_sharedlibrary_info_command PARAMS ((char *, int));
+static void som_solib_sharedlibrary_command PARAMS ((char *, int));
+
/* Add symbols from shared libraries into the symtab list. */
void
struct minimal_symbol *msymbol;
unsigned int dld_flags, status, have_endo;
asection *shlib_info;
- char shadow_contents[BREAKPOINT_MAX], buf[4];
+ char buf[4];
struct objfile *objfile;
CORE_ADDR anaddr;
+ /* First, remove all the solib event breakpoints. Their addresses
+ may have changed since the last time we ran the program. */
+ remove_solib_event_breakpoints ();
+
if (symfile_objfile == NULL)
return;
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;
- }
+ /* If __d_pid is present, then put the inferior's pid into __d_pid. hpux9
+ requires __d_pid to be set. hpux10 doesn't require __d_pid to be set
+ and the symbol may not be available.
- anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
- store_unsigned_integer (buf, 4, inferior_pid);
- status = target_write_memory (anaddr, buf, 4);
- if (status != 0)
+ Never warn about __d_pid. */
+ msymbol = lookup_minimal_symbol ("__d_pid", NULL, symfile_objfile);
+ if (msymbol != NULL)
{
- 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;
+ 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");
+ 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)
+ /* If __d_trap_fptr exists, then load whatever's at that address
+ and put it into __dld_hook. */
+ msymbol = lookup_minimal_symbol ("__d_trap_fptr", 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_read_memory (anaddr, buf, 4);
+ anaddr = extract_unsigned_integer (buf, 4);
+
+ /* If it's a plabel, then get the address of the real function.
+ Egad. This is just the opposite of how hpux9 and _DLD_HOOK
+ works. */
+ if (anaddr | 0x2)
+ {
+ status = target_read_memory (anaddr & ~0x2, buf, 4);
+ anaddr = extract_unsigned_integer (buf, 4);
+ }
}
- anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
-
- /* Grrr, this might not be an export symbol! We have to find the
- export stub. */
- ALL_OBJFILES (objfile)
+ else
{
- 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)
+ /* 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)
{
- 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;
+ warning ("Unable to find _DLD_HOOK symbol in object file.");
+ warning ("Suggest linking with /usr/lib/end.o.");
+ warning ("GDB will be unable to track shl_load/shl_unload calls");
+ 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)
+ {
+ extern struct unwind_table_entry *find_unwind_entry PARAMS ((CORE_ADDR pc));
+
+ /* 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 (MSYMBOL_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");
+ warning ("Unable to find __dld_hook symbol in object file.");
+ warning ("Suggest linking with /usr/lib/end.o.");
+ warning ("GDB will be unable to track shl_load/shl_unload calls");
goto keep_going;
}
anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
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");
+ warning ("Unable to find __dld_d_trap symbol in object file.");
+ warning ("Suggest linking with /usr/lib/end.o.");
+ warning ("GDB will be unable to track shl_load/shl_unload calls");
goto keep_going;
}
create_solib_event_breakpoint (SYMBOL_VALUE_ADDRESS (msymbol));
}
anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
- if (target_insert_breakpoint (anaddr, shadow_contents))
- {
- error ("Unable to set breakpoint at _start.\n");
- return;
- }
+
+ /* Make the breakpoint at "_start" a shared library event breakpoint. */
+ create_solib_event_breakpoint (anaddr);
/* Wipe out all knowledge of old shared libraries since their
mapping can change from one exec to another! */
free (so_list_head);
so_list_head = temp->next;
}
-
- /* Start the process again and wait for it to hit our breakpoint. */
- clear_proceed_status ();
- stop_soon_quietly = 1;
- stop_signal = TARGET_SIGNAL_0;
- do
- {
- target_resume (-1, 0, stop_signal);
- wait_for_inferior ();
- }
- while (stop_signal != TARGET_SIGNAL_TRAP);
- stop_soon_quietly = 0;
-
- /* All the libraries should be mapped in now. Remove our breakpoint and
- read in the symbol tables from the shared libraries. */
- if (target_remove_breakpoint (anaddr, shadow_contents))
- {
- error ("Unable to remove breakpoint at _start.\n");
- return;
- }
-
- if (auto_solib_add)
- som_solib_add ((char *) 0, 0, (struct target_ops *) 0);
+ clear_symtab_users ();
}
/* Return the GOT value for the shared library in which ADDR belongs. If