X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fsolib-pa64.c;h=bf736a279e59cf0f17e0b11bf1e664aadb53a6be;hb=e52d501632e2c9c117e14ba1b2a52c75f2d6f353;hp=9f541049538518ab0bfb5aa06da34e011f1fb1c0;hpb=419b8bfb232845d92d913a1fed31c8a9b86ca936;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/solib-pa64.c b/gdb/solib-pa64.c index 9f54104953..bf736a279e 100644 --- a/gdb/solib-pa64.c +++ b/gdb/solib-pa64.c @@ -1,12 +1,12 @@ /* Handle PA64 shared libraries for GDB, the GNU Debugger. - Copyright 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of GDB. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,9 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. + along with this program. If not, see . HP in their infinite stupidity choose not to use standard ELF dynamic linker interfaces. They also choose not to make their ELF dymamic @@ -31,9 +29,6 @@ same functionality in all their libraries! */ #include "defs.h" -#include -#include -#include #include "symtab.h" #include "bfd.h" #include "symfile.h" @@ -41,15 +36,23 @@ #include "gdbcore.h" #include "target.h" #include "inferior.h" +#include "regcache.h" #include "hppa-tdep.h" #include "solist.h" +#include "solib.h" #include "solib-pa64.h" #undef SOLIB_PA64_DBG -/* If we are building for a SOM-only target, then we don't need this. */ -#ifndef PA_SOM_ONLY +/* We can build this file only when running natively on 64-bit HP/UX. + We check for that by checking for the elf_hp.h header file. */ +#if defined(HAVE_ELF_HP_H) && defined(__LP64__) + +/* FIXME: kettenis/20041213: These includes should be eliminated. */ +#include +#include +#include struct lm_info { struct load_module_desc desc; @@ -77,8 +80,25 @@ read_dynamic_info (asection *dyninfo_sect, dld_cache_t *dld_cache_p); static void pa64_relocate_section_addresses (struct so_list *so, - struct section_table *sec) + struct target_section *sec) { + asection *asec = sec->the_bfd_section; + CORE_ADDR load_offset; + + /* Relocate all the sections based on where they got loaded. */ + + 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 @@ -106,8 +126,8 @@ pa64_target_read_memory (void *buffer, CORE_ADDR ptr, size_t bufsiz, int ident) This must happen after dld starts running, so we can't do it in read_dynamic_info. Record the fact that we have loaded the - descriptor. If the library is archive bound, then return zero, else - return nonzero. */ + descriptor. If the library is archive bound or the load map + hasn't been setup, then return zero; else return nonzero. */ static int read_dld_descriptor (void) @@ -120,7 +140,7 @@ read_dld_descriptor (void) if (!dld_cache.is_valid) { if (symfile_objfile == NULL) - error ("No object file symbols."); + error (_("No object file symbols.")); dyninfo_sect = bfd_get_section_by_name (symfile_objfile->obfd, ".dynamic"); @@ -130,7 +150,7 @@ read_dld_descriptor (void) } if (!read_dynamic_info (dyninfo_sect, &dld_cache)) - error ("Unable to read in .dynamic section information."); + error (_("Unable to read in .dynamic section information.")); } /* Read the load map pointer. */ @@ -139,9 +159,12 @@ read_dld_descriptor (void) sizeof (dld_cache.load_map)) != 0) { - error ("Error while reading in load map pointer."); + error (_("Error while reading in load map pointer.")); } + if (!dld_cache.load_map) + return 0; + /* Read in the dld load module descriptor */ if (dlgetmodinfo (-1, &dld_cache.dld_desc, @@ -151,7 +174,7 @@ read_dld_descriptor (void) dld_cache.load_map) == 0) { - error ("Error trying to get information about dynamic linker."); + error (_("Error trying to get information about dynamic linker.")); } /* Indicate that we have loaded the dld descriptor. */ @@ -190,9 +213,7 @@ read_dynamic_info (asection *dyninfo_sect, dld_cache_t *dld_cache_p) Elf64_Dyn *x_dynp = (Elf64_Dyn*)buf; Elf64_Sxword dyn_tag; CORE_ADDR dyn_ptr; - 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); @@ -209,7 +230,7 @@ read_dynamic_info (asection *dyninfo_sect, dld_cache_t *dld_cache_p) sizeof (dld_cache_p->dld_flags)) != 0) { - error ("Error while reading in .dynamic section of the program."); + error (_("Error while reading in .dynamic section of the program.")); } } else if (dyn_tag == DT_HP_LOAD_MAP) @@ -222,7 +243,7 @@ read_dynamic_info (asection *dyninfo_sect, dld_cache_t *dld_cache_p) sizeof (dld_cache_p->load_map_addr)) != 0) { - error ("Error while reading in .dynamic section of the program."); + error (_("Error while reading in .dynamic section of the program.")); } } else @@ -300,16 +321,15 @@ bfd_lookup_symbol (bfd *abfd, char *symname) to tell the dynamic linker that a private copy of the library is needed (so GDB can set breakpoints in the library). - We need to set two flag bits in this routine. - - DT_HP_DEBUG_PRIVATE to indicate that shared libraries should be - mapped private. - - DT_HP_DEBUG_CALLBACK to indicate that we want the dynamic linker to - call the breakpoint routine for significant events. */ + We need to set DT_HP_DEBUG_CALLBACK to indicate that we want the + dynamic linker to call the breakpoint routine for significant events. + We used to set DT_HP_DEBUG_PRIVATE to indicate that shared libraries + should be mapped private. However, this flag can be set using + "chatr +dbg enable". Not setting DT_HP_DEBUG_PRIVATE allows debugging + with shared libraries mapped shareable. */ static void -pa64_solib_create_inferior_hook (void) +pa64_solib_create_inferior_hook (int from_tty) { struct minimal_symbol *msymbol; unsigned int dld_flags, status; @@ -318,10 +338,6 @@ pa64_solib_create_inferior_hook (void) 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; @@ -336,16 +352,23 @@ pa64_solib_create_inferior_hook (void) /* Read in the .dynamic section. */ if (! read_dynamic_info (shlib_info, &dld_cache)) - error ("Unable to read the .dynamic section."); + error (_("Unable to read the .dynamic section.")); + + /* If the libraries were not mapped private, warn the user. */ + 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.")); /* Turn on the flags we care about. */ - dld_cache.dld_flags |= DT_HP_DEBUG_PRIVATE; 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."); + error (_("Unable to modify dynamic linker flags.")); /* Now we have to create a shared library breakpoint in the dynamic linker. This can be somewhat tricky since the symbol is inside @@ -382,7 +405,7 @@ pa64_solib_create_inferior_hook (void) /* Make sure the dynamic linker's really a useful object. */ if (!bfd_check_format (tmp_bfd, bfd_object)) { - warning ("Unable to grok dynamic linker %s as an object file", buf); + warning (_("Unable to grok dynamic linker %s as an object file"), buf); bfd_close (tmp_bfd); return; } @@ -393,14 +416,15 @@ pa64_solib_create_inferior_hook (void) Also note the breakpoint is the second instruction in the routine. */ - load_addr = read_pc () - tmp_bfd->start_address; + load_addr = regcache_read_pc (get_current_regcache ()) + - tmp_bfd->start_address; sym_addr = bfd_lookup_symbol (tmp_bfd, "__dld_break"); sym_addr = load_addr + sym_addr + 4; /* Create the shared library breakpoint. */ { struct breakpoint *b - = create_solib_event_breakpoint (sym_addr); + = create_solib_event_breakpoint (target_gdbarch, sym_addr); /* The breakpoint is actually hard-coded into the dynamic linker, so we don't need to actually insert a breakpoint instruction @@ -432,19 +456,16 @@ pa64_current_sos (void) if (! read_dld_descriptor ()) return NULL; - /* If the libraries were not mapped private, warn the user. */ - if ((dld_cache.dld_flags & DT_HP_DEBUG_PRIVATE) == 0) - warning ("The shared libraries were not privately mapped; setting a\n" - "breakpoint in a shared library will not work until you rerun " - "the program.\n"); - - for (dll_index = 1; ; dll_index++) + 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; + /* Read in the load module descriptor. */ if (dlgetmodinfo (dll_index, &dll_desc, sizeof (dll_desc), pa64_target_read_memory, 0, dld_cache.load_map) @@ -456,9 +477,6 @@ pa64_current_sos (void) pa64_target_read_memory, 0, dld_cache.load_map); - if (dll_path == NULL) - dll_path = ""; - 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)); @@ -473,19 +491,20 @@ pa64_current_sos (void) #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 = 0x%llx\n", d->text_base); - printf (" text_size = 0x%llx\n", d->text_size); - printf (" data_base = 0x%llx\n", d->data_base); - printf (" data_size = 0x%llx\n", d->data_size); - printf (" unwind_base = 0x%llx\n", d->unwind_base); - printf (" linkage_ptr = 0x%llx\n", d->linkage_ptr); - printf (" phdr_base = 0x%llx\n", d->phdr_base); - printf (" tls_size = 0x%llx\n", d->tls_size); - printf (" tls_start_addr = 0x%llx\n", d->tls_start_addr); - printf (" unwind_size = 0x%llx\n", d->unwind_size); - printf (" tls_index = 0x%llx\n", d->tls_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 @@ -507,7 +526,7 @@ pa64_open_symbol_file_object (void *from_ttyp) char *dll_path; if (symfile_objfile) - if (!query ("Attempt to reload symbols from process? ")) + if (!query (_("Attempt to reload symbols from process? "))) return 0; /* Read in the load map pointer if we have not done so already. */ @@ -564,9 +583,9 @@ pa64_solib_get_got_by_pc (CORE_ADDR 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; + break; } so_list = so_list->next; } @@ -582,9 +601,7 @@ pa64_solib_thread_start_addr (struct so_list *so) /* Return the address of the handle of the shared library in which ADDR - belongs. If ADDR isn't in any known shared library, return zero. - - This function is used in hppa_fix_call_dummy in hppa-tdep.c. */ + belongs. If ADDR isn't in any known shared library, return zero. */ static CORE_ADDR pa64_solib_get_solib_by_pc (CORE_ADDR addr) @@ -607,6 +624,22 @@ pa64_solib_get_solib_by_pc (CORE_ADDR addr) return retval; } +/* pa64 libraries do not seem to set the section offsets in a standard (i.e. + SVr4) way; the text section offset stored in the file doesn't correspond + to the place where the library is actually loaded into memory. Instead, + we rely on the dll descriptor to tell us where things were loaded. */ +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; /* -Wmissing-prototypes */ @@ -622,20 +655,23 @@ _initialize_pa64_solib (void) 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_tdep *tdep) +void pa64_solib_select (struct gdbarch *gdbarch) { - current_target_so_ops = &pa64_so_ops; + 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 /* PA_SOM_ONLY */ +#else /* HAVE_ELF_HP_H */ extern initialize_file_ftype _initialize_pa64_solib; /* -Wmissing-prototypes */ @@ -644,10 +680,10 @@ _initialize_pa64_solib (void) { } -void pa64_solib_select (struct gdbarch_tdep *tdep) +void pa64_solib_select (struct gdbarch *gdbarch) { /* For a SOM-only target, there is no pa64 solib support. This is needed for hppa-hpux-tdep.c to build. */ - error ("Cannot select pa64 solib support for this configuration.\n"); + error (_("Cannot select pa64 solib support for this configuration.")); } #endif