/* Handle SunOS and SVR4 shared libraries for GDB, the GNU Debugger.
- Copyright 1990, 91, 92, 93, 94, 95, 96, 98, 1999
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 98, 1999, 2000
Free Software Foundation, Inc.
This file is part of GDB.
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-
+#define _SYSCALL32 /* for Sparc64 cross Sparc32 */
#include "defs.h"
/* This file is only compilable if link.h is available. */
#include "command.h"
#include "target.h"
#include "frame.h"
-#include "gnu-regex.h"
+#include "gdb_regex.h"
#include "inferior.h"
#include "environ.h"
#include "language.h"
NULL
};
-/* local data declarations */
-
-/* Macro to extract an address from a solib structure.
+/* Function to extract an address from a solib structure.
When GDB is configured for some 32-bit targets (e.g. Solaris 2.7
sparc), BFD is configured to handle 64-bit targets, so CORE_ADDR is
64 bits. We have to extract only the significant bits of addresses
- to get the right address when accessing the core file BFD. */
+ to get the right address when accessing the core file BFD.
+
+ We'll use the BFD itself to determine the number of significant bits.
+ MVS, June 2000 */
+
+static CORE_ADDR
+solib_extract_address (void *memberp)
+{
+ return extract_address (memberp,
+ bfd_get_arch_size (exec_bfd) / 8);
+}
-#define SOLIB_EXTRACT_ADDRESS(member) \
- extract_address (&member, sizeof (member))
+#define SOLIB_EXTRACT_ADDRESS(MEMBER) \
+ solib_extract_address (&MEMBER)
+
+/* local data declarations */
#ifndef SVR4_SHARED_LIBS
-#define LM_ADDR(so) (SOLIB_EXTRACT_ADDRESS ((so) -> lm.lm_addr))
-#define LM_NEXT(so) (SOLIB_EXTRACT_ADDRESS ((so) -> lm.lm_next))
-#define LM_NAME(so) (SOLIB_EXTRACT_ADDRESS ((so) -> lm.lm_name))
-/* Test for first link map entry; first entry is a shared library. */
-#define IGNORE_FIRST_LINK_MAP_ENTRY(so) (0)
+/* NOTE: converted the macros LM_ADDR, LM_NEXT, LM_NAME and
+ IGNORE_FIRST_LINK_MAP_ENTRY into functions (see below).
+ MVS, June 2000 */
+
static struct link_dynamic dynamic_copy;
static struct link_dynamic_2 ld_2_copy;
static struct ld_debug debug_copy;
#else /* SVR4_SHARED_LIBS */
-#define LM_ADDR(so) (SOLIB_EXTRACT_ADDRESS ((so) -> lm.l_addr))
-#define LM_NEXT(so) (SOLIB_EXTRACT_ADDRESS ((so) -> lm.l_next))
-#define LM_NAME(so) (SOLIB_EXTRACT_ADDRESS ((so) -> lm.l_name))
-/* Test for first link map entry; first entry is the exec-file. */
-#define IGNORE_FIRST_LINK_MAP_ENTRY(so) \
- (SOLIB_EXTRACT_ADDRESS ((so) -> lm.l_prev) == 0)
static struct r_debug debug_copy;
+#if defined (HAVE_STRUCT_LINK_MAP32)
+static struct r_debug32 debug32_copy; /* Sparc64 cross Sparc32 */
+#endif
+
char shadow_contents[BREAKPOINT_MAX]; /* Stash old bkpt addr contents */
#endif /* !SVR4_SHARED_LIBS */
struct so_list *next; /* next structure in linked list */
struct link_map lm; /* copy of link map from inferior */
+#if defined (HAVE_STRUCT_LINK_MAP32)
+ struct link_map32 lm32; /* copy of link map from 32-bit inferior */
+#endif
CORE_ADDR lmaddr; /* addr in inferior lm was read from */
/* Shared object file name, exactly as it appears in the
};
static struct so_list *so_list_head; /* List of known shared objects */
+
+/* link map access functions */
+
+#ifndef SVR4_SHARED_LIBS
+
+static CORE_ADDR
+LM_ADDR (so)
+ struct so_list *so;
+{
+#if defined (HAVE_STRUCT_LINK_MAP32)
+ if (bfd_get_arch_size (exec_bfd) == 32)
+ return extract_address (&so->lm32.lm_addr, sizeof (so->lm32.lm_addr));
+ else
+#endif
+ return extract_address (&so->lm.lm_addr, sizeof (so->lm.lm_addr));
+}
+
+static CORE_ADDR
+LM_NEXT (so)
+ struct so_list *so;
+{
+#if defined (HAVE_STRUCT_LINK_MAP32)
+ if (bfd_get_arch_size (exec_bfd) == 32)
+ return extract_address (&so->lm32.lm_next, sizeof (so->lm32.lm_next));
+ else
+#endif
+ return extract_address (&so->lm.lm_next, sizeof (so->lm.lm_next));
+}
+
+static CORE_ADDR
+LM_NAME (so)
+ struct so_list *so;
+{
+#if defined (HAVE_STRUCT_LINK_MAP32)
+ if (bfd_get_arch_size (exec_bfd) == 32)
+ return extract_address (&so->lm32.lm_name, sizeof (so->lm32.lm_name));
+ else
+#endif
+ return extract_address (&so->lm.lm_name, sizeof (so->lm.lm_name));
+}
+
+static int
+IGNORE_FIRST_LINK_MAP_ENTRY (so)
+ struct so_list *so;
+{
+ return 0;
+}
+
+#else /* SVR4_SHARED_LIBS */
+
+static CORE_ADDR
+LM_ADDR (so)
+ struct so_list *so;
+{
+#if defined (HAVE_STRUCT_LINK_MAP32)
+ if (bfd_get_arch_size (exec_bfd) == 32)
+ return extract_address (&so->lm32.l_addr, sizeof (so->lm32.l_addr));
+ else
+#endif
+ return extract_address (&so->lm.l_addr, sizeof (so->lm.l_addr));
+}
+
+static CORE_ADDR
+LM_NEXT (so)
+ struct so_list *so;
+{
+#if defined (HAVE_STRUCT_LINK_MAP32)
+ if (bfd_get_arch_size (exec_bfd) == 32)
+ return extract_address (&so->lm32.l_next, sizeof (so->lm32.l_next));
+ else
+#endif
+ return extract_address (&so->lm.l_next, sizeof (so->lm.l_next));
+}
+
+static CORE_ADDR
+LM_NAME (so)
+ struct so_list *so;
+{
+#if defined (HAVE_STRUCT_LINK_MAP32)
+ if (bfd_get_arch_size (exec_bfd) == 32)
+ return extract_address (&so->lm32.l_name, sizeof (so->lm32.l_name));
+ else
+#endif
+ return extract_address (&so->lm.l_name, sizeof (so->lm.l_name));
+}
+
+static int
+IGNORE_FIRST_LINK_MAP_ENTRY (so)
+ struct so_list *so;
+{
+#if defined (HAVE_STRUCT_LINK_MAP32)
+ if (bfd_get_arch_size (exec_bfd) == 32)
+ return (solib_extract_address (&(so) -> lm32.l_prev) == 0);
+ else
+#endif
+ return (solib_extract_address (&(so) -> lm.l_prev) == 0);
+}
+
+#endif /* !SVR4_SHARED_LIBS */
+
+
static CORE_ADDR debug_base; /* Base of dynamic linker structures */
static CORE_ADDR breakpoint_addr; /* Address where end bkpt is set */
static int solib_cleanup_queued = 0; /* make_run_cleanup called */
-extern int
-fdmatch PARAMS ((int, int)); /* In libiberty */
+extern int fdmatch (int, int); /* In libiberty */
/* Local function prototypes */
-static void
-do_clear_solib PARAMS ((PTR));
+static void do_clear_solib (PTR);
-static int
-match_main PARAMS ((char *));
+static int match_main (char *);
-static void
-special_symbol_handling PARAMS ((void));
+static void special_symbol_handling (void);
-static void
-sharedlibrary_command PARAMS ((char *, int));
+static void sharedlibrary_command (char *, int);
-static int
-enable_break PARAMS ((void));
+static int enable_break (void);
-static void
-info_sharedlibrary_command PARAMS ((char *, int));
+static void info_sharedlibrary_command (char *, int);
-static int symbol_add_stub PARAMS ((PTR));
+static int symbol_add_stub (PTR);
-static CORE_ADDR
- first_link_map_member PARAMS ((void));
+static CORE_ADDR first_link_map_member (void);
-static CORE_ADDR
- locate_base PARAMS ((void));
+static CORE_ADDR locate_base (void);
-static int solib_map_sections PARAMS ((PTR));
+static int solib_map_sections (PTR);
#ifdef SVR4_SHARED_LIBS
-static CORE_ADDR
- elf_locate_base PARAMS ((void));
+static CORE_ADDR elf_locate_base (void);
#else
static struct so_list *current_sos (void);
static void free_so (struct so_list *node);
-static int
-disable_break PARAMS ((void));
+static int disable_break (void);
-static void
-allocate_rt_common_objfile PARAMS ((void));
+static void allocate_rt_common_objfile (void);
static void
solib_add_common_symbols (CORE_ADDR);
#endif
-void _initialize_solib PARAMS ((void));
+void _initialize_solib (void);
/* If non-zero, this is a prefix that will be added to the front of the name
shared libraries with an absolute filename for loading. */
*/
static int
-solib_map_sections (arg)
- PTR arg;
+solib_map_sections (PTR arg)
{
struct so_list *so = (struct so_list *) arg; /* catch_errors bogon */
char *filename;
/* Allocate the runtime common object file. */
static void
-allocate_rt_common_objfile ()
+allocate_rt_common_objfile (void)
{
struct objfile *objfile;
struct objfile *last_one;
objfile. */
static void
-solib_add_common_symbols (rtc_symp)
- CORE_ADDR rtc_symp;
+solib_add_common_symbols (CORE_ADDR rtc_symp)
{
struct rtc_symb inferior_rtc_symb;
struct nlist inferior_rtc_nlist;
}
init_minimal_symbol_collection ();
- make_cleanup ((make_cleanup_func) discard_minimal_symbols, 0);
+ make_cleanup_discard_minimal_symbols ();
while (rtc_symp)
{
#ifdef SVR4_SHARED_LIBS
-static CORE_ADDR
- bfd_lookup_symbol PARAMS ((bfd *, char *));
+static CORE_ADDR bfd_lookup_symbol (bfd *, char *);
/*
*/
static CORE_ADDR
-bfd_lookup_symbol (abfd, symname)
- bfd *abfd;
- char *symname;
+bfd_lookup_symbol (bfd *abfd, char *symname)
{
unsigned int storage_needed;
asymbol *sym;
}
do_cleanups (back_to);
}
- return (symaddr);
+
+ if (symaddr)
+ return symaddr;
+
+ /* On FreeBSD, the dynamic linker is stripped by default. So we'll
+ have to check the dynamic string table too. */
+
+ storage_needed = bfd_get_dynamic_symtab_upper_bound (abfd);
+
+ if (storage_needed > 0)
+ {
+ symbol_table = (asymbol **) xmalloc (storage_needed);
+ back_to = make_cleanup (free, (PTR) symbol_table);
+ number_of_symbols = bfd_canonicalize_dynamic_symtab (abfd, symbol_table);
+
+ for (i = 0; i < number_of_symbols; i++)
+ {
+ sym = *symbol_table++;
+ if (STREQ (sym->name, symname))
+ {
+ /* Bfd symbols are section relative. */
+ symaddr = sym->value + sym->section->vma;
+ break;
+ }
+ }
+ do_cleanups (back_to);
+ }
+
+ return symaddr;
}
#ifdef HANDLE_SVR4_EXEC_EMULATORS
NULL
};
-static int
-look_for_base PARAMS ((int, CORE_ADDR));
+static int look_for_base (int, CORE_ADDR);
/*
*/
static int
-look_for_base (fd, baseaddr)
- int fd;
- CORE_ADDR baseaddr;
+look_for_base (int fd, CORE_ADDR baseaddr)
{
bfd *interp_bfd;
CORE_ADDR address = 0;
*/
static CORE_ADDR
-elf_locate_base ()
+elf_locate_base (void)
{
sec_ptr dyninfo_sect;
int dyninfo_sect_size;
CORE_ADDR dyninfo_addr;
char *buf;
char *bufend;
+ int arch_size;
/* Find the start address of the .dynamic section. */
dyninfo_sect = bfd_get_section_by_name (exec_bfd, ".dynamic");
/* 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. */
-#ifndef TARGET_ELF64
- 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)
+
+ 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))
{
- dyn_ptr = bfd_h_get_32 (exec_bfd, (bfd_byte *) x_dynp->d_un.d_ptr);
- return dyn_ptr;
- }
+ 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;
+ }
#ifdef DT_MIPS_RLD_MAP
- else if (dyn_tag == DT_MIPS_RLD_MAP)
- {
- char pbuf[TARGET_PTR_BIT / HOST_CHAR_BIT];
-
- /* 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, sizeof (pbuf)))
- return 0;
- return extract_unsigned_integer (pbuf, sizeof (pbuf));
- }
+ else if (dyn_tag == DT_MIPS_RLD_MAP)
+ {
+ char *pbuf;
+
+ pbuf = alloca (TARGET_PTR_BIT / HOST_CHAR_BIT);
+ /* 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, sizeof (pbuf)))
+ return 0;
+ return extract_unsigned_integer (pbuf, sizeof (pbuf));
+ }
#endif
+ }
}
-#else /* ELF64 */
- for (bufend = buf + dyninfo_sect_size;
- buf < bufend;
- buf += sizeof (Elf64_External_Dyn))
+ else /* 64-bit elf */
{
- 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)
+ for (bufend = buf + dyninfo_sect_size;
+ buf < bufend;
+ buf += sizeof (Elf64_External_Dyn))
{
- dyn_ptr = bfd_h_get_64 (exec_bfd, (bfd_byte *) x_dynp->d_un.d_ptr);
- return dyn_ptr;
+ 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;
+ }
}
}
-#endif
/* DT_DEBUG entry not found. */
return 0;
*/
static CORE_ADDR
-locate_base ()
+locate_base (void)
{
#ifndef SVR4_SHARED_LIBS
does the reading. */
static CORE_ADDR
-first_link_map_member ()
+first_link_map_member (void)
{
CORE_ADDR lm = 0;
}
#else /* SVR4_SHARED_LIBS */
-
- read_memory (debug_base, (char *) &debug_copy, sizeof (struct r_debug));
+#if defined (HAVE_STRUCT_LINK_MAP32)
+ if (bfd_get_arch_size (exec_bfd) == 32)
+ {
+ read_memory (debug_base, (char *) &debug32_copy,
+ sizeof (struct r_debug32));
+ lm = SOLIB_EXTRACT_ADDRESS (debug32_copy.r_map);
+ }
+ else
+#endif
+ {
+ read_memory (debug_base, (char *) &debug_copy,
+ sizeof (struct r_debug));
+ lm = SOLIB_EXTRACT_ADDRESS (debug_copy.r_map);
+ }
/* FIXME: Perhaps we should validate the info somehow, perhaps by
checking r_version for a known version number, or r_state for
RT_CONSISTENT. */
- lm = SOLIB_EXTRACT_ADDRESS (debug_copy.r_map);
#endif /* !SVR4_SHARED_LIBS */
LOCAL FUNCTION
- open_exec_file_object
+ open_symbol_file_object
SYNOPSIS
*/
-int
-open_symbol_file_object (arg)
- PTR arg;
+static int
+open_symbol_file_object (from_ttyp)
+ int *from_ttyp; /* sneak past catch_errors */
{
- int from_tty = (int) arg; /* sneak past catch_errors */
CORE_ADDR lm;
- struct link_map lmcopy;
char *filename;
int errcode;
if ((lm = first_link_map_member ()) == 0)
return 0; /* failed somehow... */
- /* Read from target memory to GDB. */
- read_memory (lm, (void *) &lmcopy, sizeof (lmcopy));
+#if defined (HAVE_STRUCT_LINK_MAP32)
+ if (bfd_get_arch_size (exec_bfd) == 32)
+ {
+ struct link_map32 lmcopy;
+ /* Read from target memory to GDB. */
+ read_memory (lm, (void *) &lmcopy, sizeof (lmcopy));
+
+ if (lmcopy.l_name == 0)
+ return 0; /* no filename. */
- if (lmcopy.l_name == 0)
- return 0; /* no filename. */
+ /* Now fetch the filename from target memory. */
+ target_read_string (SOLIB_EXTRACT_ADDRESS (lmcopy.l_name),
+ &filename, MAX_PATH_SIZE - 1, &errcode);
+ }
+ else
+#endif /* HAVE_STRUCT_LINK_MAP32 */
+ {
+ struct link_map lmcopy;
+ /* Read from target memory to GDB. */
+ read_memory (lm, (void *) &lmcopy, sizeof (lmcopy));
+
+ if (lmcopy.l_name == 0)
+ return 0; /* no filename. */
+
+ /* Now fetch the filename from target memory. */
+ target_read_string (SOLIB_EXTRACT_ADDRESS (lmcopy.l_name), &filename,
+ MAX_PATH_SIZE - 1, &errcode);
+ }
- /* Now fetch the filename from target memory. */
- target_read_string (SOLIB_EXTRACT_ADDRESS (lmcopy.l_name), &filename,
- MAX_PATH_SIZE - 1, &errcode);
if (errcode)
{
warning ("failed to read exec filename from attached file: %s",
return 0;
}
- make_cleanup ((make_cleanup_func) free, (void *) filename);
+ make_cleanup (free, filename);
/* Have a pathname: read the symbol file. */
- symbol_file_command (filename, from_tty);
+ symbol_file_command (filename, *from_ttyp);
return 1;
}
non-zero iff SONAME matches one of the known main executable names. */
static int
-match_main (soname)
- char *soname;
+match_main (char *soname)
{
char **mainp;
we provide values for. */
static struct so_list *
-current_sos ()
+current_sos (void)
{
CORE_ADDR lm;
struct so_list *head = 0;
memset (new, 0, sizeof (*new));
new->lmaddr = lm;
- read_memory (lm, (char *) &(new->lm), sizeof (struct link_map));
+
+#if defined (HAVE_STRUCT_LINK_MAP32)
+ if (bfd_get_arch_size (exec_bfd) == 32)
+ read_memory (lm, (char *) &(new->lm32), sizeof (struct link_map32));
+ else
+#endif
+ read_memory (lm, (char *) &(new->lm), sizeof (struct link_map));
lm = LM_NEXT (new);
/* A small stub to get us past the arg-passing pinhole of catch_errors. */
static int
-symbol_add_stub (arg)
- PTR arg;
+symbol_add_stub (PTR arg)
{
register struct so_list *so = (struct so_list *) arg; /* catch_errs bogon */
- CORE_ADDR text_addr = 0;
+ struct section_addr_info *sap;
+ CORE_ADDR lowest_addr = 0;
+ int lowest_index;
+ asection *lowest_sect = NULL;
/* Have we already loaded this shared object? */
ALL_OBJFILES (so->objfile)
/* Find the shared object's text segment. */
if (so->textsection)
- text_addr = so->textsection->addr;
+ {
+ lowest_addr = so->textsection->addr;
+ lowest_sect = bfd_get_section_by_name (so->abfd, ".text");
+ lowest_index = lowest_sect->index;
+ }
else if (so->abfd != NULL)
{
- asection *lowest_sect;
-
- /* If we didn't find a mapped non zero sized .text section, set up
- text_addr so that the relocation in symbol_file_add does no harm. */
+ /* If we didn't find a mapped non zero sized .text section, set
+ up lowest_addr so that the relocation in symbol_file_add does
+ no harm. */
lowest_sect = bfd_get_section_by_name (so->abfd, ".text");
if (lowest_sect == NULL)
bfd_map_over_sections (so->abfd, find_lowest_section,
(PTR) &lowest_sect);
if (lowest_sect)
- text_addr = bfd_section_vma (so->abfd, lowest_sect)
- + LM_ADDR (so);
+ {
+ lowest_addr = bfd_section_vma (so->abfd, lowest_sect)
+ + LM_ADDR (so);
+ lowest_index = lowest_sect->index;
+ }
}
- {
- struct section_addr_info section_addrs;
+ sap = build_section_addr_info_from_section_table (so->sections,
+ so->sections_end);
- memset (§ion_addrs, 0, sizeof (section_addrs));
- section_addrs.text_addr = text_addr;
+ sap->other[lowest_index].addr = lowest_addr;
- so->objfile = symbol_file_add (so->so_name, so->from_tty,
- §ion_addrs, 0, OBJF_SHARED);
- }
+ so->objfile = symbol_file_add (so->so_name, so->from_tty,
+ sap, 0, OBJF_SHARED);
+ free_section_addr_info (sap);
return (1);
}
/* LOCAL FUNCTION
- solib_add -- synchronize GDB's shared object list with the inferior's
+ update_solib_list --- synchronize GDB's shared object list with inferior's
SYNOPSIS
- void solib_add (char *pattern, int from_tty, struct target_ops *TARGET)
-
- DESCRIPTION
+ void update_solib_list (int from_tty, struct target_ops *TARGET)
Extract the list of currently loaded shared objects from the
- inferior, and compare it with the list of shared objects for which
- GDB has currently loaded symbolic information. If new shared
- objects have been loaded, or old shared objects have disappeared,
- make the appropriate changes to GDB's tables.
+ inferior, and compare it with the list of shared objects currently
+ in GDB's so_list_head list. Edit so_list_head to bring it in sync
+ with the inferior's new list.
+
+ If we notice that the inferior has unloaded some shared objects,
+ free any symbolic info GDB had read about those shared objects.
- If PATTERN is non-null, read symbols only for shared objects
- whose names match PATTERN.
+ Don't load symbolic info for any new shared objects; just add them
+ to the list, and leave their symbols_loaded flag clear.
If FROM_TTY is non-null, feel free to print messages about what
we're doing.
processes we've just attached to, so that's okay. */
void
-solib_add (char *pattern, int from_tty, struct target_ops *target)
+update_solib_list (int from_tty, struct target_ops *target)
{
struct so_list *inferior = current_sos ();
struct so_list *gdb, **gdb_link;
- /* #define JIMB_DEBUG */
-#ifdef JIMB_DEBUG
- printf ("GDB's shared library list:\n");
- for (gdb = so_list_head; gdb; gdb = gdb->next)
- printf (" %s\n", gdb->so_original_name);
- printf ("inferior's shared library list:\n");
- for (gdb = inferior; gdb; gdb = gdb->next)
- printf (" %s\n", gdb->so_original_name);
-#endif
-
#ifdef SVR4_SHARED_LIBS
/* If we are attaching to a running process for which we
have not opened a symbol file, we may be able to get its
symbols now! */
if (attach_flag &&
symfile_objfile == NULL)
- catch_errors (open_symbol_file_object, (PTR) from_tty,
+ catch_errors (open_symbol_file_object, (PTR) &from_tty,
"Error reading attached process's symbol file.\n",
RETURN_MASK_ALL);
#endif SVR4_SHARED_LIBS
- if (pattern)
- {
- char *re_err = re_comp (pattern);
-
- if (re_err)
- error ("Invalid regexp: %s", re_err);
- }
-
/* Since this function might actually add some elements to the
so_list_head list, arrange for it to be cleaned up when
appropriate. */
shared objects appear where. There are three cases:
- A shared object appears on both lists. This means that GDB
- knows about it already, and it's still loaded in the inferior.
- Nothing needs to happen.
+ knows about it already, and it's still loaded in the inferior.
+ Nothing needs to happen.
- A shared object appears only on GDB's list. This means that
- the inferior has unloaded it. We should remove the shared
- object from GDB's tables.
+ the inferior has unloaded it. We should remove the shared
+ object from GDB's tables.
- A shared object appears only on the inferior's list. This
- means that it's just been loaded. We should add it to GDB's
- tables.
+ means that it's just been loaded. We should add it to GDB's
+ tables.
So we walk GDB's list, checking each entry to see if it appears
in the inferior's list too. If it does, no action is needed, and
if (i)
{
*i_link = i->next;
-#ifdef JIMB_DEBUG
- printf ("unchanged: %s\n", i->so_name);
-#endif
free_so (i);
gdb_link = &gdb->next;
gdb = *gdb_link;
else
{
*gdb_link = gdb->next;
-#ifdef JIMB_DEBUG
- printf ("removed: %s\n", gdb->so_name);
-#endif
/* Unless the user loaded it explicitly, free SO's objfile. */
- if (! (gdb->objfile->flags & OBJF_USERLOADED))
+ if (gdb->objfile && ! (gdb->objfile->flags & OBJF_USERLOADED))
free_objfile (gdb->objfile);
/* Some targets' section tables might be referring to
/* Now the inferior's list contains only shared objects that don't
appear in GDB's list --- those that are newly loaded. Add them
- to GDB's shared object list, and read in their symbols, if
- appropriate. */
+ to GDB's shared object list. */
if (inferior)
{
struct so_list *i;
/* Add the new shared objects to GDB's list. */
*gdb_link = inferior;
- /* Fill in the rest of each of the `struct so_list' nodes, and
- read symbols for those files whose names match PATTERN. */
+ /* Fill in the rest of each of the `struct so_list' nodes. */
for (i = inferior; i; i = i->next)
{
i->from_tty = from_tty;
catch_errors (solib_map_sections, i,
"Error while mapping shared library sections:\n",
RETURN_MASK_ALL);
-
- if (! pattern || re_exec (i->so_name))
- {
- if (i->symbols_loaded)
- {
- if (from_tty)
- printf_unfiltered ("Symbols already loaded for %s\n",
- i->so_name);
- }
- else
- {
-#ifdef JIMB_DEBUG
- printf ("added: %s\n", i->so_name);
-#endif
- if (catch_errors
- (symbol_add_stub, i,
- "Error while reading shared library symbols:\n",
- RETURN_MASK_ALL))
- {
- if (from_tty)
- printf_unfiltered ("Loaded symbols for %s\n",
- i->so_name);
- i->symbols_loaded = 1;
- }
- }
- }
}
/* If requested, add the shared objects' sections to the the
}
}
}
+ }
+}
+
+
+/* GLOBAL FUNCTION
+
+ solib_add -- read in symbol info for newly added shared libraries
- /* Getting new symbols may change our opinion about what is
- frameless. */
- reinit_frame_cache ();
+ SYNOPSIS
+
+ void solib_add (char *pattern, int from_tty, struct target_ops *TARGET)
+
+ DESCRIPTION
+
+ Read in symbolic information for any shared objects whose names
+ match PATTERN. (If we've already read a shared object's symbol
+ info, leave it alone.) If PATTERN is zero, read them all.
+
+ FROM_TTY and TARGET are as described for update_solib_list, above. */
+
+void
+solib_add (char *pattern, int from_tty, struct target_ops *target)
+{
+ struct so_list *gdb;
+
+ if (pattern)
+ {
+ char *re_err = re_comp (pattern);
- special_symbol_handling ();
+ if (re_err)
+ error ("Invalid regexp: %s", re_err);
}
-#ifdef JIMB_DEBUG
- putchar ('\n');
-#endif
+ update_solib_list (from_tty, target);
+
+ /* Walk the list of currently loaded shared libraries, and read
+ symbols for any that match the pattern --- or any whose symbols
+ aren't already loaded, if no pattern was given. */
+ {
+ int any_matches = 0;
+ int loaded_any_symbols = 0;
+
+ for (gdb = so_list_head; gdb; gdb = gdb->next)
+ 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 (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 (from_tty && pattern && ! any_matches)
+ printf_unfiltered
+ ("No loaded shared libraries match the pattern `%s'.\n", pattern);
+
+ if (loaded_any_symbols)
+ {
+ /* Getting new symbols may change our opinion about what is
+ frameless. */
+ reinit_frame_cache ();
+
+ special_symbol_handling ();
+ }
+ }
}
*/
static void
-info_sharedlibrary_command (ignore, from_tty)
- char *ignore;
- int from_tty;
+info_sharedlibrary_command (char *ignore, int from_tty)
{
register struct so_list *so = NULL; /* link map state variable */
int header_done = 0;
int addr_width;
char *addr_fmt;
+ int arch_size;
if (exec_bfd == NULL)
{
return;
}
-#ifndef TARGET_ELF64
- addr_width = 8 + 4;
- addr_fmt = "08l";
-#else
- addr_width = 16 + 4;
- addr_fmt = "016l";
-#endif
+ arch_size = bfd_get_arch_size (exec_bfd);
+ /* Default to 32-bit in case of failure (non-elf). */
+ if (arch_size == 32 || arch_size == -1)
+ {
+ addr_width = 8 + 4;
+ addr_fmt = "08l";
+ }
+ else if (arch_size == 64)
+ {
+ addr_width = 16 + 4;
+ addr_fmt = "016l";
+ }
- solib_add (0, 0, 0);
+ update_solib_list (from_tty, 0);
for (so = so_list_head; so; so = so->next)
{
*/
char *
-solib_address (address)
- CORE_ADDR address;
+solib_address (CORE_ADDR address)
{
register struct so_list *so = 0; /* link map state variable */
/* Called by free_all_symtabs */
void
-clear_solib ()
+clear_solib (void)
{
/* This function is expected to handle ELF shared libraries. It is
also used on Solaris, which can run either ELF or a.out binaries
}
static void
-do_clear_solib (dummy)
- PTR dummy;
+do_clear_solib (PTR dummy)
{
solib_cleanup_queued = 0;
clear_solib ();
static CORE_ADDR interp_plt_sect_high;
int
-in_svr4_dynsym_resolve_code (pc)
- CORE_ADDR pc;
+in_svr4_dynsym_resolve_code (CORE_ADDR pc)
{
return ((pc >= interp_text_sect_low && pc < interp_text_sect_high)
|| (pc >= interp_plt_sect_low && pc < interp_plt_sect_high)
#ifndef SVR4_SHARED_LIBS
static int
-disable_break ()
+disable_break (void)
{
int status = 1;
*/
static int
-enable_break ()
+enable_break (void)
{
int success = 0;
*/
void
-solib_create_inferior_hook ()
+solib_create_inferior_hook (void)
{
/* If we are using the BKPT_AT_SYMBOL code, then we don't need the base
yet. In fact, in the case of a SunOS4 executable being run on
*/
static void
-special_symbol_handling ()
+special_symbol_handling (void)
{
#ifndef SVR4_SHARED_LIBS
int j;
*/
static void
-sharedlibrary_command (args, from_tty)
- char *args;
- int from_tty;
+sharedlibrary_command (char *args, int from_tty)
{
dont_repeat ();
solib_add (args, from_tty, (struct target_ops *) 0);
#endif /* HAVE_LINK_H */
void
-_initialize_solib ()
+_initialize_solib (void)
{
#ifdef HAVE_LINK_H