/* Handle HP ELF shared libraries for GDB, the GNU Debugger.
- Copyright 1999 Free Software Foundation, Inc.
+
+ Copyright 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation,
+ Inc.
This file is part of GDB.
#include "gdb-stabs.h"
#include "gdb_stat.h"
#include "gdbcmd.h"
-#include "assert.h"
#include "language.h"
+#include "regcache.h"
+#include "exec.h"
#include <fcntl.h>
#define O_BINARY 0
#endif
-/* Defined in exec.c; used to prevent dangling pointer bug. */
-extern struct target_ops exec_ops;
-
-static CORE_ADDR
- bfd_lookup_symbol PARAMS ((bfd *, char *));
+static CORE_ADDR bfd_lookup_symbol (bfd *, char *);
/* This lives in hppa-tdep.c. */
-extern struct unwind_table_entry *find_unwind_entry PARAMS ((CORE_ADDR pc));
+extern struct unwind_table_entry *find_unwind_entry (CORE_ADDR pc);
/* These ought to be defined in some public interface, but aren't. They
identify dynamic linker events. */
struct load_module_desc pa64_solib_desc;
struct section_table *sections;
struct section_table *sections_end;
- boolean loaded;
+ int loaded;
};
static struct so_list *so_list_head;
shared objects on the so_list_head list. (When we say size, here
we mean of the information before it is brought into memory and
potentially expanded by GDB.) When adding a new shlib, this value
- is compared against the threshold size, held by auto_solib_add
- (in megabytes). If adding symbols for the new shlib would cause
- the total size to exceed the threshold, then the new shlib's symbols
- are not loaded. */
+ is compared against a threshold size, held by auto_solib_limit (in
+ megabytes). If adding symbols for the new shlib would cause the
+ total size to exceed the threshold, then the new shlib's symbols
+ are not loaded. */
static LONGEST pa64_solib_total_st_size;
/* When the threshold is reached for any shlib, we refuse to add
symbols for subsequent shlibs, even if those shlibs' symbols would
- be small enough to fit under the threshold. (Although this may
+ be small enough to fit under the threshold. Although this may
result in one, early large shlib preventing the loading of later,
- smalller shlibs' symbols, it allows us to issue one informational
+ smaller shlibs' symbols, it allows us to issue one informational
message. The alternative, to issue a message for each shlib whose
symbols aren't loaded, could be a big annoyance where the threshold
- is exceeded due to a very large number of shlibs.) */
+ is exceeded due to a very large number of shlibs. */
static int pa64_solib_st_size_threshold_exceeded;
/* When adding fields, be sure to clear them in _initialize_pa64_solib. */
typedef struct
{
CORE_ADDR dld_flags_addr;
- long long dld_flags;
- sec_ptr dyninfo_sect;
- boolean have_read_dld_descriptor;
- boolean is_valid;
+ LONGEST dld_flags;
+ struct bfd_section *dyninfo_sect;
+ int have_read_dld_descriptor;
+ int is_valid;
CORE_ADDR load_map;
CORE_ADDR load_map_addr;
struct load_module_desc dld_desc;
static dld_cache_t dld_cache;
-static void pa64_sharedlibrary_info_command PARAMS ((char *, int));
+static void pa64_sharedlibrary_info_command (char *, int);
-static void pa64_solib_sharedlibrary_command PARAMS ((char *, int));
+static void pa64_solib_sharedlibrary_command (char *, int);
-static void * pa64_target_read_memory PARAMS ((void *, CORE_ADDR, size_t, int));
+static void *pa64_target_read_memory (void *, CORE_ADDR, size_t, int);
-static boolean read_dld_descriptor PARAMS ((struct target_ops *));
+static int read_dld_descriptor (struct target_ops *, int readsyms);
-static boolean read_dynamic_info PARAMS ((asection *, dld_cache_t *));
+static int read_dynamic_info (asection *, dld_cache_t *);
-static void add_to_solist PARAMS ((boolean, char *, struct load_module_desc *,
- CORE_ADDR, struct target_ops *));
+static void add_to_solist (int, char *, int, struct load_module_desc *,
+ CORE_ADDR, struct target_ops *);
/* When examining the shared library for debugging information we have to
look for HP debug symbols, stabs and dwarf2 debug symbols. */
/* Return a ballbark figure for the amount of memory GDB will need to
allocate to read in the debug symbols from FILENAME. */
static LONGEST
-pa64_solib_sizeof_symbol_table (filename)
- char *filename;
+pa64_solib_sizeof_symbol_table (char *filename)
{
bfd *abfd;
int i;
if (!abfd)
{
close (desc);
- make_cleanup (free, filename);
+ make_cleanup (xfree, filename);
error ("\"%s\": can't open to read symbols: %s.", filename,
bfd_errmsg (bfd_get_error ()));
}
if (!bfd_check_format (abfd, bfd_object))
{
bfd_close (abfd);
- make_cleanup (free, filename);
+ make_cleanup (xfree, filename);
error ("\"%s\": can't read symbols: %s.", filename,
bfd_errmsg (bfd_get_error ()));
}
}
bfd_close (abfd);
- free (filename);
+ xfree (filename);
/* Unfortunately, just summing the sizes of various debug info
sections isn't a very accurate measurement of how much heap
/* Add a shared library to the objfile list and load its symbols into
GDB's symbol table. */
static void
-pa64_solib_add_solib_objfile (so, name, from_tty, text_addr)
- struct so_list *so;
- char *name;
- int from_tty;
- CORE_ADDR text_addr;
+pa64_solib_add_solib_objfile (struct so_list *so, char *name, int from_tty,
+ CORE_ADDR text_addr)
{
bfd *tmp_bfd;
asection *sec;
obj_private_data_t *obj_private;
- struct section_addr_info section_addrs;
+ struct section_addr_info *section_addrs;
+ struct cleanup *my_cleanups;
- memset (§ion_addrs, 0, sizeof (section_addrs));
/* We need the BFD so that we can look at its sections. We open up the
file temporarily, then close it when we are done. */
tmp_bfd = bfd_openr (name, gnutarget);
/* Now find the true lowest section in the shared library. */
sec = NULL;
- bfd_map_over_sections (tmp_bfd, find_lowest_section, (PTR) &sec);
+ bfd_map_over_sections (tmp_bfd, find_lowest_section, &sec);
if (sec)
{
text_addr += sec->filepos;
}
+ section_addrs = alloc_section_addr_info (bfd_count_sections (tmp_bfd));
+ my_cleanups = make_cleanup (xfree, section_addrs);
+
/* We are done with the temporary bfd. Get rid of it and make sure
nobody else can us it. */
bfd_close (tmp_bfd);
tmp_bfd = NULL;
/* Now let the generic code load up symbols for this library. */
- section_addrs.text_addr = text_addr;
- so->objfile = symbol_file_add (name, from_tty, §ion_addrs, 0, OBJF_SHARED);
+ section_addrs->other[0].addr = text_addr;
+ section_addrs->other[0].name = ".text";
+ so->objfile = symbol_file_add (name, from_tty, section_addrs, 0, OBJF_SHARED);
so->abfd = so->objfile->obfd;
/* Mark this as a shared library and save private data. */
if (so->objfile->obj_private == NULL)
{
obj_private = (obj_private_data_t *)
- obstack_alloc (&so->objfile->psymbol_obstack,
+ obstack_alloc (&so->objfile->objfile_obstack,
sizeof (obj_private_data_t));
obj_private->unwind_info = NULL;
obj_private->so_info = NULL;
- so->objfile->obj_private = (PTR) obj_private;
+ so->objfile->obj_private = obj_private;
}
obj_private = (obj_private_data_t *) so->objfile->obj_private;
obj_private->so_info = so;
obj_private->dp = so->pa64_solib_desc.linkage_ptr;
+ do_cleanups (my_cleanups);
}
/* Load debugging information for a shared library. TARGET may be
NULL if we are not attaching to a process or reading a core file. */
static void
-pa64_solib_load_symbols (so, name, from_tty, text_addr, target)
- struct so_list *so;
- char *name;
- int from_tty;
- CORE_ADDR text_addr;
- struct target_ops *target;
+pa64_solib_load_symbols (struct so_list *so, char *name, int from_tty,
+ CORE_ADDR text_addr, struct target_ops *target)
{
struct section_table *p;
asection *sec;
return;
}
- ANOFFSET (so->objfile->section_offsets, SECT_OFF_TEXT)
+ (so->objfile->section_offsets)->offsets[SECT_OFF_TEXT (so->objfile)]
= so->pa64_solib_desc.text_base;
- ANOFFSET (so->objfile->section_offsets, SECT_OFF_DATA)
+ (so->objfile->section_offsets)->offsets[SECT_OFF_DATA (so->objfile)]
= so->pa64_solib_desc.data_base;
/* Relocate all the sections based on where they got loaded. */
{
if (p->the_bfd_section->flags & SEC_CODE)
{
- p->addr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_TEXT);
- p->endaddr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_TEXT);
+ p->addr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_TEXT (so->objfile));
+ p->endaddr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_TEXT (so->objfile));
}
else if (p->the_bfd_section->flags & SEC_DATA)
{
- p->addr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_DATA);
- p->endaddr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_DATA);
+ p->addr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_DATA (so->objfile));
+ p->endaddr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_DATA (so->objfile));
}
}
/* Add symbols from shared libraries into the symtab list, unless the
- size threshold (specified by auto_solib_add, in megabytes) would
+ size threshold specified by auto_solib_limit (in megabytes) would
be exceeded. */
void
-pa64_solib_add (arg_string, from_tty, target)
- char *arg_string;
- int from_tty;
- struct target_ops *target;
+pa64_solib_add (char *arg_string, int from_tty, struct target_ops *target, int readsyms)
{
struct minimal_symbol *msymbol;
CORE_ADDR addr;
/* Read in the load map pointer if we have not done so already. */
if (! dld_cache.have_read_dld_descriptor)
- if (! read_dld_descriptor (target))
+ if (! read_dld_descriptor (target, readsyms))
return;
/* If the libraries were not mapped private, warn the user. */
if (!dll_path)
error ("pa64_solib_add, unable to read shared library path.");
- add_to_solist (from_tty, dll_path, &dll_desc, 0, target);
+ add_to_solist (from_tty, dll_path, readsyms, &dll_desc, 0, target);
}
}
call the breakpoint routine for significant events. */
void
-pa64_solib_create_inferior_hook ()
+pa64_solib_create_inferior_hook (void)
{
struct minimal_symbol *msymbol;
unsigned int dld_flags, status;
struct so_list *temp;
temp = so_list_head;
- free (so_list_head);
+ xfree (so_list_head);
so_list_head = temp->next;
}
clear_symtab_users ();
GDB may already have been notified of. */
void
-pa64_solib_remove_inferior_hook (pid)
- int pid;
+pa64_solib_remove_inferior_hook (int pid)
{
/* Turn off the DT_HP_DEBUG_CALLBACK bit in the dynamic linker flags. */
dld_cache.dld_flags &= ~DT_HP_DEBUG_CALLBACK;
pa64_solib_create_inferior_hook. */
void
-pa64_solib_create_catch_load_hook (pid, tempflag, filename, cond_string)
- int pid;
- int tempflag;
- char *filename;
- char *cond_string;
+pa64_solib_create_catch_load_hook (int pid, int tempflag, char *filename,
+ char *cond_string)
{
create_solib_load_event_breakpoint ("", tempflag, filename, cond_string);
}
pa64_solib_create_inferior_hook. */
void
-pa64_solib_create_catch_unload_hook (pid, tempflag, filename, cond_string)
- int pid;
- int tempflag;
- char *filename;
- char *cond_string;
+pa64_solib_create_catch_unload_hook (int pid, int tempflag, char *filename,
+ char *cond_string)
{
create_solib_unload_event_breakpoint ("", tempflag, filename, cond_string);
}
has been loaded. */
int
-pa64_solib_have_load_event (pid)
- int pid;
+pa64_solib_have_load_event (int pid)
{
CORE_ADDR event_kind;
/* Return nonzero if the dynamic linker has reproted that a library
has been unloaded. */
int
-pa64_solib_have_unload_event (pid)
- int pid;
+pa64_solib_have_unload_event (int pid)
{
CORE_ADDR event_kind;
restarted. */
char *
-pa64_solib_loaded_library_pathname (pid)
- int pid;
+pa64_solib_loaded_library_pathname (int pid)
{
static char dll_path[MAXPATHLEN];
CORE_ADDR dll_path_addr = read_register (ARG3_REGNUM);
restarted. */
char *
-pa64_solib_unloaded_library_pathname (pid)
- int pid;
+pa64_solib_unloaded_library_pathname (int pid)
{
static char dll_path[MAXPATHLEN];
CORE_ADDR dll_path_addr = read_register (ARG3_REGNUM);
/* Return nonzero if PC is an address inside the dynamic linker. */
int
-pa64_solib_in_dynamic_linker (pid, pc)
- int pid;
- CORE_ADDR pc;
+pa64_solib_in_dynamic_linker (int pid, CORE_ADDR pc)
{
asection *shlib_info;
return 0;
if (!dld_cache.have_read_dld_descriptor)
- if (!read_dld_descriptor (¤t_target))
+ if (!read_dld_descriptor (¤t_target, auto_solib_add))
return 0;
return (pc >= dld_cache.dld_desc.text_base
ADDR isn't in any known shared library, return zero. */
CORE_ADDR
-pa64_solib_get_got_by_pc (addr)
- CORE_ADDR addr;
+pa64_solib_get_got_by_pc (CORE_ADDR addr)
{
struct so_list *so_list = so_list_head;
CORE_ADDR got_value = 0;
This function is used in hppa_fix_call_dummy in hppa-tdep.c. */
CORE_ADDR
-pa64_solib_get_solib_by_pc (addr)
- CORE_ADDR addr;
+pa64_solib_get_solib_by_pc (CORE_ADDR addr)
{
struct so_list *so_list = so_list_head;
CORE_ADDR retval = 0;
/* Dump information about all the currently loaded shared libraries. */
static void
-pa64_sharedlibrary_info_command (ignore, from_tty)
- char *ignore;
- int from_tty;
+pa64_sharedlibrary_info_command (char *ignore, int from_tty)
{
struct so_list *so_list = so_list_head;
/* Load up one or more shared libraries as directed by the user. */
static void
-pa64_solib_sharedlibrary_command (args, from_tty)
- char *args;
- int from_tty;
+pa64_solib_sharedlibrary_command (char *args, int from_tty)
{
dont_repeat ();
- pa64_solib_add (args, from_tty, (struct target_ops *) 0);
+ pa64_solib_add (args, from_tty, (struct target_ops *) 0, 1);
}
/* Return the name of the shared library containing ADDR or NULL if ADDR
is not contained in any known shared library. */
char *
-pa64_solib_address (addr)
- CORE_ADDR addr;
+pa64_solib_address (CORE_ADDR addr)
{
struct so_list *so = so_list_head;
/* We are killing the inferior and restarting the program. */
void
-pa64_solib_restart ()
+pa64_solib_restart (void)
{
struct so_list *sl = so_list_head;
while (sl)
{
struct so_list *next_sl = sl->next;
- free (sl);
+ xfree (sl);
sl = next_sl;
}
so_list_head = NULL;
}
void
-_initialize_pa64_solib ()
+_initialize_pa64_solib (void)
{
add_com ("sharedlibrary", class_files, pa64_solib_sharedlibrary_command,
"Load shared object library symbols for files matching REGEXP.");
add_info ("sharedlibrary", pa64_sharedlibrary_info_command,
"Status of loaded shared object libraries.");
+
add_show_from_set
- (add_set_cmd ("auto-solib-add", class_support, var_zinteger,
+ (add_set_cmd ("auto-solib-add", class_support, var_boolean,
(char *) &auto_solib_add,
- "Set autoloading size threshold (in megabytes) of shared library symbols.\n\
-If nonzero, symbols from all shared object libraries will be loaded\n\
-automatically when the inferior begins execution or when the dynamic linker\n\
-informs gdb that a new library has been loaded, until the symbol table\n\
-of the program and libraries exceeds this threshold.\n\
-Otherwise, symbols must be loaded manually, using `sharedlibrary'.",
+ "Set autoloading of shared library symbols.\n\
+If \"on\", symbols from all shared object libraries will be loaded\n\
+automatically when the inferior begins execution, when the dynamic linker\n\
+informs gdb that a new library has been loaded, or when attaching to the\n\
+inferior. Otherwise, symbols must be loaded manually, using `sharedlibrary'.",
+ &setlist),
+ &showlist);
+
+ add_show_from_set
+ (add_set_cmd ("auto-solib-limit", class_support, var_zinteger,
+ (char *) &auto_solib_limit,
+ "Set threshold (in Mb) for autoloading shared library symbols.\n\
+When shared library autoloading is enabled, new libraries will be loaded\n\
+only until the total size of shared library symbols exceeds this\n\
+threshold in megabytes. Is ignored when using `sharedlibrary'.",
&setlist),
&showlist);
- /* ??rehrauer: On HP-UX, the kernel parameter MAXDSIZ limits how much
- data space a process can use. We ought to be reading MAXDSIZ and
- setting auto_solib_add to some large fraction of that value. If
- not that, we maybe ought to be setting it smaller than the default
- for MAXDSIZ (that being 64Mb, I believe). However, [1] this threshold
- is only crudely approximated rather than actually measured, and [2]
- 50 Mbytes is too small for debugging gdb itself. Thus, the arbitrary
- 100 figure.
- */
- auto_solib_add = 100; /* Megabytes */
+ /* ??rehrauer: On HP-UX, the kernel parameter MAXDSIZ limits how
+ much data space a process can use. We ought to be reading
+ MAXDSIZ and setting auto_solib_limit to some large fraction of
+ that value. If not that, we maybe ought to be setting it smaller
+ than the default for MAXDSIZ (that being 64Mb, I believe).
+ However, [1] this threshold is only crudely approximated rather
+ than actually measured, and [2] 50 Mbytes is too small for
+ debugging gdb itself. Thus, the arbitrary 100 figure. */
+ auto_solib_limit = 100; /* Megabytes */
pa64_solib_restart ();
}
/* Get some HPUX-specific data from a shared lib. */
CORE_ADDR
-so_lib_thread_start_addr (so)
- struct so_list *so;
+so_lib_thread_start_addr (struct so_list *so)
{
return so->pa64_solib_desc.tls_start_addr;
}
descriptor. If the library is archive bound, then return zero, else
return nonzero. */
-static boolean
-read_dld_descriptor (target)
- struct target_ops *target;
+static int
+read_dld_descriptor (struct target_ops *target, int readsyms)
{
char *dll_path;
asection *dyninfo_sect;
pa64_target_read_memory,
0,
dld_cache.load_map);
- add_to_solist(0, dll_path, &dld_cache.dld_desc, 0, target);
+ add_to_solist(0, dll_path, readsyms, &dld_cache.dld_desc, 0, target);
return 1;
}
which is stored in dld_cache. The routine elf_locate_base in solib.c
was used as a model for this. */
-static boolean
-read_dynamic_info (dyninfo_sect, dld_cache_p)
- asection *dyninfo_sect;
- dld_cache_t *dld_cache_p;
+static int
+read_dynamic_info (asection *dyninfo_sect, dld_cache_t *dld_cache_p)
{
char *buf;
char *bufend;
Elf64_Dyn *x_dynp = (Elf64_Dyn*)buf;
Elf64_Sxword dyn_tag;
CORE_ADDR dyn_ptr;
- char pbuf[TARGET_PTR_BIT / HOST_CHAR_BIT];
+ char *pbuf;
+ pbuf = alloca (TARGET_PTR_BIT / HOST_CHAR_BIT);
dyn_tag = bfd_h_get_64 (symfile_objfile->obfd,
(bfd_byte*) &x_dynp->d_tag);
/* Wrapper for target_read_memory to make dlgetmodinfo happy. */
static void *
-pa64_target_read_memory (buffer, ptr, bufsiz, ident)
- void *buffer;
- CORE_ADDR ptr;
- size_t bufsiz;
- int ident;
+pa64_target_read_memory (void *buffer, CORE_ADDR ptr, size_t bufsiz, int ident)
{
if (target_read_memory (ptr, buffer, bufsiz) != 0)
return 0;
be read from the inferior process at the address load_module_desc_addr. */
static void
-add_to_solist (from_tty, dll_path, load_module_desc_p,
- load_module_desc_addr, target)
- boolean from_tty;
- char *dll_path;
- struct load_module_desc *load_module_desc_p;
- CORE_ADDR load_module_desc_addr;
- struct target_ops *target;
+add_to_solist (int from_tty, char *dll_path, int readsyms,
+ struct load_module_desc *load_module_desc_p,
+ CORE_ADDR load_module_desc_addr, struct target_ops *target)
{
struct so_list *new_so, *so_list_tail;
int pa64_solib_st_size_threshhold_exceeded;
new_so->pa64_solib_desc_addr = load_module_desc_addr;
new_so->loaded = 1;
new_so->name = obsavestring (dll_path, strlen(dll_path),
- &symfile_objfile->symbol_obstack);
+ &symfile_objfile->objfile_obstack);
/* If we are not going to load the library, tell the user if we
haven't already and return. */
st_size = pa64_solib_sizeof_symbol_table (dll_path);
pa64_solib_st_size_threshhold_exceeded =
!from_tty
+ && readsyms
&& ( (st_size + pa64_solib_total_st_size)
- > (auto_solib_add * (LONGEST)1000000));
+ > (auto_solib_limit * (LONGEST) (1024 * 1024)));
if (pa64_solib_st_size_threshhold_exceeded)
{
pa64_solib_add_solib_objfile (new_so, dll_path, from_tty, 1);
pa64_solib_load_symbols (new_so,
dll_path,
from_tty,
- 0);
+ 0,
+ target);
return;
}
*/
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;
if (storage_needed > 0)
{
symbol_table = (asymbol **) xmalloc (storage_needed);
- back_to = make_cleanup (free, (PTR) symbol_table);
+ back_to = make_cleanup (xfree, symbol_table);
number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
for (i = 0; i < number_of_symbols; i++)
{
sym = *symbol_table++;
- if (STREQ (sym->name, symname))
+ if (strcmp (sym->name, symname) == 0)
{
/* Bfd symbols are section relative. */
symaddr = sym->value + sym->section->vma;