gdb/solib-pa64.c - gdb
Global variables defined
Data types defined
Functions defined
Macros defined
Source code
- #include "defs.h"
- #include "symtab.h"
- #include "bfd.h"
- #include "symfile.h"
- #include "objfiles.h"
- #include "gdbcore.h"
- #include "target.h"
- #include "inferior.h"
- #include "regcache.h"
- #include "gdb_bfd.h"
- #include "hppa-tdep.h"
- #include "solist.h"
- #include "solib.h"
- #include "solib-pa64.h"
- #undef SOLIB_PA64_DBG
- #if defined(HAVE_ELF_HP_H) && defined(__LP64__)
- FIXME
- #include <dlfcn.h>
- #include <elf.h>
- #include <elf_hp.h>
- struct lm_info {
- struct load_module_desc desc;
- CORE_ADDR desc_addr;
- };
- typedef struct
- {
- CORE_ADDR dld_flags_addr;
- 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;
- }
- dld_cache_t;
- static dld_cache_t dld_cache;
- static int read_dynamic_info (asection *dyninfo_sect,
- dld_cache_t *dld_cache_p);
- static void
- pa64_relocate_section_addresses (struct so_list *so,
- struct target_section *sec)
- {
- asection *asec = sec->the_bfd_section;
- CORE_ADDR load_offset;
-
- load_offset = bfd_section_vma (so->abfd, asec) - asec->filepos;
- if (asec->flags & SEC_CODE)
- {
- sec->addr += so->lm_info->desc.text_base - load_offset;
- sec->endaddr += so->lm_info->desc.text_base - load_offset;
- }
- else if (asec->flags & SEC_DATA)
- {
- sec->addr += so->lm_info->desc.data_base - load_offset;
- sec->endaddr += so->lm_info->desc.data_base - load_offset;
- }
- }
- static void
- pa64_free_so (struct so_list *so)
- {
- xfree (so->lm_info);
- }
- static void
- pa64_clear_solib (void)
- {
- }
- static void *
- pa64_target_read_memory (void *buffer, CORE_ADDR ptr, size_t bufsiz, int ident)
- {
- if (target_read_memory (ptr, buffer, bufsiz) != 0)
- return 0;
- return buffer;
- }
- static int
- read_dld_descriptor (void)
- {
- char *dll_path;
- asection *dyninfo_sect;
-
- if (!dld_cache.is_valid)
- {
- if (symfile_objfile == NULL)
- error (_("No object file symbols."));
- dyninfo_sect = bfd_get_section_by_name (symfile_objfile->obfd,
- ".dynamic");
- if (!dyninfo_sect)
- {
- return 0;
- }
- if (!read_dynamic_info (dyninfo_sect, &dld_cache))
- error (_("Unable to read in .dynamic section information."));
- }
-
- if (target_read_memory (dld_cache.load_map_addr,
- (char *) &dld_cache.load_map,
- sizeof (dld_cache.load_map))
- != 0)
- {
- error (_("Error while reading in load map pointer."));
- }
- if (!dld_cache.load_map)
- return 0;
-
- if (dlgetmodinfo (-1,
- &dld_cache.dld_desc,
- sizeof (dld_cache.dld_desc),
- pa64_target_read_memory,
- 0,
- dld_cache.load_map)
- == 0)
- {
- error (_("Error trying to get information about dynamic linker."));
- }
-
- dld_cache.have_read_dld_descriptor = 1;
- return 1;
- }
- static int
- read_dynamic_info (asection *dyninfo_sect, dld_cache_t *dld_cache_p)
- {
- char *buf;
- char *bufend;
- CORE_ADDR dyninfo_addr;
- int dyninfo_sect_size;
- CORE_ADDR entry_addr;
-
- dyninfo_addr = bfd_section_vma (symfile_objfile->obfd, dyninfo_sect);
- dyninfo_sect_size = bfd_section_size (exec_bfd, dyninfo_sect);
- buf = alloca (dyninfo_sect_size);
- if (target_read_memory (dyninfo_addr, buf, dyninfo_sect_size))
- return 0;
-
- for (bufend = buf + dyninfo_sect_size, entry_addr = dyninfo_addr;
- buf < bufend;
- buf += sizeof (Elf64_Dyn), entry_addr += sizeof (Elf64_Dyn))
- {
- Elf64_Dyn *x_dynp = (Elf64_Dyn*)buf;
- Elf64_Sxword dyn_tag;
- CORE_ADDR dyn_ptr;
- dyn_tag = bfd_h_get_64 (symfile_objfile->obfd,
- (bfd_byte*) &x_dynp->d_tag);
-
- if (dyn_tag == DT_NULL)
- break;
- else if (dyn_tag == DT_HP_DLD_FLAGS)
- {
-
- dld_cache_p->dld_flags_addr = entry_addr + offsetof(Elf64_Dyn, d_un);
- if (target_read_memory (dld_cache_p->dld_flags_addr,
- (char*) &dld_cache_p->dld_flags,
- sizeof (dld_cache_p->dld_flags))
- != 0)
- {
- error (_("Error while reading in "
- ".dynamic section of the program."));
- }
- }
- else if (dyn_tag == DT_HP_LOAD_MAP)
- {
-
- if (target_read_memory (entry_addr + offsetof(Elf64_Dyn,
- d_un.d_ptr),
- (char*) &dld_cache_p->load_map_addr,
- sizeof (dld_cache_p->load_map_addr))
- != 0)
- {
- error (_("Error while reading in "
- ".dynamic section of the program."));
- }
- }
- else
- {
-
- }
- }
-
- dld_cache_p->dyninfo_sect = dyninfo_sect;
-
- if (dld_cache_p->dld_flags_addr != 0 && dld_cache_p->load_map_addr != 0)
- dld_cache_p->is_valid = 1;
- else
- return 0;
- return 1;
- }
- static int
- cmp_name (asymbol *sym, void *data)
- {
- return (strcmp (sym->name, (const char *) data) == 0);
- }
- static void
- pa64_solib_create_inferior_hook (int from_tty)
- {
- struct minimal_symbol *msymbol;
- unsigned int dld_flags, status;
- asection *shlib_info, *interp_sect;
- struct objfile *objfile;
- CORE_ADDR anaddr;
- if (symfile_objfile == NULL)
- return;
-
- shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, ".dynamic");
- if (!shlib_info)
- return;
-
- if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0)
- return;
-
- if (! read_dynamic_info (shlib_info, &dld_cache))
- error (_("Unable to read the .dynamic section."));
-
- if ((dld_cache.dld_flags & DT_HP_DEBUG_PRIVATE) == 0)
- warning
- (_("\
- Private mapping of shared library text was not specified\n\
- by the executable; setting a breakpoint in a shared library which\n\
- is not privately mapped will not work. See the HP-UX 11i v3 chatr\n\
- manpage for methods to privately map shared library text."));
-
- dld_cache.dld_flags |= DT_HP_DEBUG_CALLBACK;
- status = target_write_memory (dld_cache.dld_flags_addr,
- (char *) &dld_cache.dld_flags,
- sizeof (dld_cache.dld_flags));
- if (status != 0)
- error (_("Unable to modify dynamic linker flags."));
-
- interp_sect = bfd_get_section_by_name (exec_bfd, ".interp");
- if (interp_sect)
- {
- unsigned int interp_sect_size;
- char *buf;
- CORE_ADDR load_addr;
- bfd *tmp_bfd;
- CORE_ADDR sym_addr = 0;
-
- interp_sect_size = bfd_section_size (exec_bfd, interp_sect);
- buf = alloca (interp_sect_size);
- bfd_get_section_contents (exec_bfd, interp_sect,
- buf, 0, interp_sect_size);
-
- tmp_bfd = gdb_bfd_open (buf, gnutarget, -1);
- if (tmp_bfd == NULL)
- return;
-
- if (!bfd_check_format (tmp_bfd, bfd_object))
- {
- warning (_("Unable to grok dynamic linker %s as an object file"),
- buf);
- gdb_bfd_unref (tmp_bfd);
- return;
- }
-
- load_addr = regcache_read_pc (get_current_regcache ())
- - tmp_bfd->start_address;
- sym_addr = gdb_bfd_lookup_symbol_from_symtab (tmp_bfd, cmp_name,
- "__dld_break");
- sym_addr = load_addr + sym_addr + 4;
-
- {
- struct breakpoint *b
- = create_solib_event_breakpoint (target_gdbarch (), sym_addr);
-
- make_breakpoint_permanent (b);
- }
-
- gdb_bfd_unref (tmp_bfd);
- }
- }
- static void
- pa64_special_symbol_handling (void)
- {
- }
- static struct so_list *
- pa64_current_sos (void)
- {
- struct so_list *head = 0;
- struct so_list **link_ptr = &head;
- int dll_index;
-
- if (! dld_cache.have_read_dld_descriptor)
- if (! read_dld_descriptor ())
- return NULL;
- for (dll_index = -1; ; dll_index++)
- {
- struct load_module_desc dll_desc;
- char *dll_path;
- struct so_list *new;
- struct cleanup *old_chain;
- if (dll_index == 0)
- continue;
-
- if (dlgetmodinfo (dll_index, &dll_desc, sizeof (dll_desc),
- pa64_target_read_memory, 0, dld_cache.load_map)
- == 0)
- break;
-
- dll_path = (char *)dlgetname (&dll_desc, sizeof (dll_desc),
- pa64_target_read_memory,
- 0, dld_cache.load_map);
- new = (struct so_list *) xmalloc (sizeof (struct so_list));
- memset (new, 0, sizeof (struct so_list));
- new->lm_info = (struct lm_info *) xmalloc (sizeof (struct lm_info));
- memset (new->lm_info, 0, sizeof (struct lm_info));
- strncpy (new->so_name, dll_path, SO_NAME_MAX_PATH_SIZE - 1);
- new->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
- strcpy (new->so_original_name, new->so_name);
- memcpy (&new->lm_info->desc, &dll_desc, sizeof (dll_desc));
- #ifdef SOLIB_PA64_DBG
- {
- struct load_module_desc *d = &new->lm_info->desc;
- printf ("\n+ library \"%s\" is described at index %d\n", new->so_name,
- dll_index);
- printf (" text_base = %s\n", hex_string (d->text_base));
- printf (" text_size = %s\n", hex_string (d->text_size));
- printf (" data_base = %s\n", hex_string (d->data_base));
- printf (" data_size = %s\n", hex_string (d->data_size));
- printf (" unwind_base = %s\n", hex_string (d->unwind_base));
- printf (" linkage_ptr = %s\n", hex_string (d->linkage_ptr));
- printf (" phdr_base = %s\n", hex_string (d->phdr_base));
- printf (" tls_size = %s\n", hex_string (d->tls_size));
- printf (" tls_start_addr = %s\n", hex_string (d->tls_start_addr));
- printf (" unwind_size = %s\n", hex_string (d->unwind_size));
- printf (" tls_index = %s\n", hex_string (d->tls_index));
- }
- #endif
-
- new->next = NULL;
- *link_ptr = new;
- link_ptr = &new->next;
- }
- return head;
- }
- static int
- pa64_open_symbol_file_object (void *from_ttyp)
- {
- int from_tty = *(int *)from_ttyp;
- struct load_module_desc dll_desc;
- char *dll_path;
- if (symfile_objfile)
- if (!query (_("Attempt to reload symbols from process? ")))
- return 0;
-
- if (! dld_cache.have_read_dld_descriptor)
- if (! read_dld_descriptor ())
- return 0;
-
- if (dlgetmodinfo (0, &dll_desc, sizeof (dll_desc),
- pa64_target_read_memory, 0, dld_cache.load_map) == 0)
- return 0;
-
- dll_path = (char *)dlgetname (&dll_desc, sizeof (dll_desc),
- pa64_target_read_memory,
- 0, dld_cache.load_map);
-
- symbol_file_add_main (dll_path, from_tty);
- return 1;
- }
- static int
- pa64_in_dynsym_resolve_code (CORE_ADDR pc)
- {
- asection *shlib_info;
- if (symfile_objfile == NULL)
- return 0;
- if (!dld_cache.have_read_dld_descriptor)
- if (!read_dld_descriptor ())
- return 0;
- return (pc >= dld_cache.dld_desc.text_base
- && pc < dld_cache.dld_desc.text_base + dld_cache.dld_desc.text_size);
- }
- static CORE_ADDR
- pa64_solib_get_got_by_pc (CORE_ADDR addr)
- {
- struct so_list *so_list = master_so_list ();
- CORE_ADDR got_value = 0;
- while (so_list)
- {
- if (so_list->lm_info->desc.text_base <= addr
- && ((so_list->lm_info->desc.text_base
- + so_list->lm_info->desc.text_size)
- > addr))
- {
- got_value = so_list->lm_info->desc.linkage_ptr;
- break;
- }
- so_list = so_list->next;
- }
- return got_value;
- }
- static CORE_ADDR
- pa64_solib_thread_start_addr (struct so_list *so)
- {
- return so->lm_info->desc.tls_start_addr;
- }
- static CORE_ADDR
- pa64_solib_get_solib_by_pc (CORE_ADDR addr)
- {
- struct so_list *so_list = master_so_list ();
- CORE_ADDR retval = 0;
- while (so_list)
- {
- if (so_list->lm_info->desc.text_base <= addr
- && ((so_list->lm_info->desc.text_base
- + so_list->lm_info->desc.text_size)
- > addr))
- {
- retval = so_list->lm_info->desc_addr;
- break;
- }
- so_list = so_list->next;
- }
- return retval;
- }
- static CORE_ADDR
- pa64_solib_get_text_base (struct objfile *objfile)
- {
- struct so_list *so;
- for (so = master_so_list (); so; so = so->next)
- if (so->objfile == objfile)
- return so->lm_info->desc.text_base;
- return 0;
- }
- static struct target_so_ops pa64_so_ops;
- extern initialize_file_ftype _initialize_pa64_solib;
- void
- _initialize_pa64_solib (void)
- {
- pa64_so_ops.relocate_section_addresses = pa64_relocate_section_addresses;
- pa64_so_ops.free_so = pa64_free_so;
- pa64_so_ops.clear_solib = pa64_clear_solib;
- pa64_so_ops.solib_create_inferior_hook = pa64_solib_create_inferior_hook;
- pa64_so_ops.special_symbol_handling = pa64_special_symbol_handling;
- pa64_so_ops.current_sos = pa64_current_sos;
- pa64_so_ops.open_symbol_file_object = pa64_open_symbol_file_object;
- pa64_so_ops.in_dynsym_resolve_code = pa64_in_dynsym_resolve_code;
- pa64_so_ops.bfd_open = solib_bfd_open;
- memset (&dld_cache, 0, sizeof (dld_cache));
- }
- void pa64_solib_select (struct gdbarch *gdbarch)
- {
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- set_solib_ops (gdbarch, &pa64_so_ops);
- tdep->solib_thread_start_addr = pa64_solib_thread_start_addr;
- tdep->solib_get_got_by_pc = pa64_solib_get_got_by_pc;
- tdep->solib_get_solib_by_pc = pa64_solib_get_solib_by_pc;
- tdep->solib_get_text_base = pa64_solib_get_text_base;
- }
- #else
- extern initialize_file_ftype _initialize_pa64_solib;
- void
- _initialize_pa64_solib (void)
- {
- }
- void pa64_solib_select (struct gdbarch *gdbarch)
- {
-
- error (_("Cannot select pa64 solib support for this configuration."));
- }
- #endif