1130812Smarcel/* Handle HP SOM shared libraries for GDB, the GNU Debugger. 2130812Smarcel 3130812Smarcel Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 4130812Smarcel 2003, 2004 Free Software Foundation, Inc. 5130812Smarcel 6130812Smarcel This file is part of GDB. 7130812Smarcel 8130812Smarcel This program is free software; you can redistribute it and/or modify 9130812Smarcel it under the terms of the GNU General Public License as published by 10130812Smarcel the Free Software Foundation; either version 2 of the License, or 11130812Smarcel (at your option) any later version. 12130812Smarcel 13130812Smarcel This program is distributed in the hope that it will be useful, 14130812Smarcel but WITHOUT ANY WARRANTY; without even the implied warranty of 15130812Smarcel MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16130812Smarcel GNU General Public License for more details. 17130812Smarcel 18130812Smarcel You should have received a copy of the GNU General Public License 19130812Smarcel along with this program; if not, write to the Free Software 20130812Smarcel Foundation, Inc., 59 Temple Place - Suite 330, 21130812Smarcel Boston, MA 02111-1307, USA. 22130812Smarcel 23130812Smarcel Written by the Center for Software Science at the Univerity of Utah 24130812Smarcel and by Cygnus Support. */ 25130812Smarcel 26130812Smarcel 27130812Smarcel#include "defs.h" 28130812Smarcel 29130812Smarcel#include "frame.h" 30130812Smarcel#include "bfd.h" 31130812Smarcel#include "som.h" 32130812Smarcel#include "libhppa.h" 33130812Smarcel#include "gdbcore.h" 34130812Smarcel#include "symtab.h" 35130812Smarcel#include "breakpoint.h" 36130812Smarcel#include "symfile.h" 37130812Smarcel#include "objfiles.h" 38130812Smarcel#include "inferior.h" 39130812Smarcel#include "gdb-stabs.h" 40130812Smarcel#include "gdb_stat.h" 41130812Smarcel#include "gdbcmd.h" 42130812Smarcel#include "language.h" 43130812Smarcel#include "regcache.h" 44130812Smarcel#include "gdb_assert.h" 45130812Smarcel#include "exec.h" 46130812Smarcel 47130812Smarcel#include <fcntl.h> 48130812Smarcel 49130812Smarcel#ifndef O_BINARY 50130812Smarcel#define O_BINARY 0 51130812Smarcel#endif 52130812Smarcel 53130812Smarcel/* Uncomment this to turn on some debugging output. 54130812Smarcel */ 55130812Smarcel 56130812Smarcel/* #define SOLIB_DEBUG 57130812Smarcel */ 58130812Smarcel 59130812Smarcel/* This lives in hppa-tdep.c. */ 60130812Smarcelextern struct unwind_table_entry *find_unwind_entry (CORE_ADDR pc); 61130812Smarcel 62130812Smarcel/* These ought to be defined in some public interface, but aren't. They 63130812Smarcel define the meaning of the various bits in the distinguished __dld_flags 64130812Smarcel variable that is declared in every debuggable a.out on HP-UX, and that 65130812Smarcel is shared between the debugger and the dynamic linker. 66130812Smarcel */ 67130812Smarcel#define DLD_FLAGS_MAPPRIVATE 0x1 68130812Smarcel#define DLD_FLAGS_HOOKVALID 0x2 69130812Smarcel#define DLD_FLAGS_LISTVALID 0x4 70130812Smarcel#define DLD_FLAGS_BOR_ENABLE 0x8 71130812Smarcel 72130812Smarcel/* TODO: 73130812Smarcel 74130812Smarcel * Support for hpux8 dynamic linker. */ 75130812Smarcel 76130812Smarcel/* The basic structure which describes a dynamically loaded object. This 77130812Smarcel data structure is private to the dynamic linker and isn't found in 78130812Smarcel any HPUX include file. */ 79130812Smarcel 80130812Smarcelstruct som_solib_mapped_entry 81130812Smarcel { 82130812Smarcel /* The name of the library. */ 83130812Smarcel char *name; 84130812Smarcel 85130812Smarcel /* Version of this structure (it is expected to change again in hpux10). */ 86130812Smarcel unsigned char struct_version; 87130812Smarcel 88130812Smarcel /* Binding mode for this library. */ 89130812Smarcel unsigned char bind_mode; 90130812Smarcel 91130812Smarcel /* Version of this library. */ 92130812Smarcel short library_version; 93130812Smarcel 94130812Smarcel /* Start of text address, 95130812Smarcel * link-time text location (length of text area), 96130812Smarcel * end of text address. */ 97130812Smarcel CORE_ADDR text_addr; 98130812Smarcel CORE_ADDR text_link_addr; 99130812Smarcel CORE_ADDR text_end; 100130812Smarcel 101130812Smarcel /* Start of data, start of bss and end of data. */ 102130812Smarcel CORE_ADDR data_start; 103130812Smarcel CORE_ADDR bss_start; 104130812Smarcel CORE_ADDR data_end; 105130812Smarcel 106130812Smarcel /* Value of linkage pointer (%r19). */ 107130812Smarcel CORE_ADDR got_value; 108130812Smarcel 109130812Smarcel /* Next entry. */ 110130812Smarcel struct som_solib_mapped_entry *next; 111130812Smarcel 112130812Smarcel /* There are other fields, but I don't have information as to what is 113130812Smarcel contained in them. */ 114130812Smarcel 115130812Smarcel /* For versions from HPUX-10.30 and up */ 116130812Smarcel 117130812Smarcel /* Address in target of offset from thread-local register of 118130812Smarcel * start of this thread's data. I.e., the first thread-local 119130812Smarcel * variable in this shared library starts at *(tsd_start_addr) 120130812Smarcel * from that area pointed to by cr27 (mpsfu_hi). 121130812Smarcel * 122130812Smarcel * We do the indirection as soon as we read it, so from then 123130812Smarcel * on it's the offset itself. 124130812Smarcel */ 125130812Smarcel CORE_ADDR tsd_start_addr; 126130812Smarcel 127130812Smarcel /* Following this are longwords holding: 128130812Smarcel 129130812Smarcel * ?, ?, ?, ptr to -1, ptr to-1, ptr to lib name (leaf name), 130130812Smarcel * ptr to __data_start, ptr to __data_end 131130812Smarcel */ 132130812Smarcel 133130812Smarcel 134130812Smarcel }; 135130812Smarcel 136130812Smarcel/* A structure to keep track of all the known shared objects. */ 137130812Smarcelstruct so_list 138130812Smarcel { 139130812Smarcel struct som_solib_mapped_entry som_solib; 140130812Smarcel struct objfile *objfile; 141130812Smarcel bfd *abfd; 142130812Smarcel struct section_table *sections; 143130812Smarcel struct section_table *sections_end; 144130812Smarcel/* elz: added this field to store the address in target space (in the 145130812Smarcel library) of the library descriptor (handle) which we read into 146130812Smarcel som_solib_mapped_entry structure */ 147130812Smarcel CORE_ADDR solib_addr; 148130812Smarcel struct so_list *next; 149130812Smarcel 150130812Smarcel }; 151130812Smarcel 152130812Smarcelstatic struct so_list *so_list_head; 153130812Smarcel 154130812Smarcel 155130812Smarcel/* This is the cumulative size in bytes of the symbol tables of all 156130812Smarcel shared objects on the so_list_head list. (When we say size, here 157130812Smarcel we mean of the information before it is brought into memory and 158130812Smarcel potentially expanded by GDB.) When adding a new shlib, this value 159130812Smarcel is compared against the threshold size, held by auto_solib_limit 160130812Smarcel (in megabytes). If adding symbols for the new shlib would cause 161130812Smarcel the total size to exceed the threshold, then the new shlib's 162130812Smarcel symbols are not loaded. */ 163130812Smarcelstatic LONGEST som_solib_total_st_size; 164130812Smarcel 165130812Smarcel/* When the threshold is reached for any shlib, we refuse to add 166130812Smarcel symbols for subsequent shlibs, even if those shlibs' symbols would 167130812Smarcel be small enough to fit under the threshold. (Although this may 168130812Smarcel result in one, early large shlib preventing the loading of later, 169130812Smarcel smalller shlibs' symbols, it allows us to issue one informational 170130812Smarcel message. The alternative, to issue a message for each shlib whose 171130812Smarcel symbols aren't loaded, could be a big annoyance where the threshold 172130812Smarcel is exceeded due to a very large number of shlibs.) 173130812Smarcel */ 174130812Smarcelstatic int som_solib_st_size_threshold_exceeded; 175130812Smarcel 176130812Smarcel/* These addresses should be filled in by som_solib_create_inferior_hook. 177130812Smarcel They are also used elsewhere in this module. 178130812Smarcel */ 179130812Smarceltypedef struct 180130812Smarcel { 181130812Smarcel CORE_ADDR address; 182130812Smarcel struct unwind_table_entry *unwind; 183130812Smarcel } 184130812Smarceladdr_and_unwind_t; 185130812Smarcel 186130812Smarcel/* When adding fields, be sure to clear them in _initialize_som_solib. */ 187130812Smarcelstatic struct 188130812Smarcel { 189130812Smarcel int is_valid; 190130812Smarcel addr_and_unwind_t hook; 191130812Smarcel addr_and_unwind_t hook_stub; 192130812Smarcel addr_and_unwind_t load; 193130812Smarcel addr_and_unwind_t load_stub; 194130812Smarcel addr_and_unwind_t unload; 195130812Smarcel addr_and_unwind_t unload2; 196130812Smarcel addr_and_unwind_t unload_stub; 197130812Smarcel } 198130812Smarceldld_cache; 199130812Smarcel 200130812Smarcel 201130812Smarcel 202130812Smarcelstatic void som_sharedlibrary_info_command (char *, int); 203130812Smarcel 204130812Smarcelstatic void som_solib_sharedlibrary_command (char *, int); 205130812Smarcel 206130812Smarcelstatic LONGEST 207130812Smarcelsom_solib_sizeof_symbol_table (char *filename) 208130812Smarcel{ 209130812Smarcel bfd *abfd; 210130812Smarcel int desc; 211130812Smarcel char *absolute_name; 212130812Smarcel LONGEST st_size = (LONGEST) 0; 213130812Smarcel asection *sect; 214130812Smarcel 215130812Smarcel /* We believe that filename was handed to us by the dynamic linker, and 216130812Smarcel is therefore always an absolute path. 217130812Smarcel */ 218130812Smarcel desc = openp (getenv ("PATH"), 1, filename, O_RDONLY | O_BINARY, 0, &absolute_name); 219130812Smarcel if (desc < 0) 220130812Smarcel { 221130812Smarcel perror_with_name (filename); 222130812Smarcel } 223130812Smarcel filename = absolute_name; 224130812Smarcel 225130812Smarcel abfd = bfd_fdopenr (filename, gnutarget, desc); 226130812Smarcel if (!abfd) 227130812Smarcel { 228130812Smarcel close (desc); 229130812Smarcel make_cleanup (xfree, filename); 230130812Smarcel error ("\"%s\": can't open to read symbols: %s.", filename, 231130812Smarcel bfd_errmsg (bfd_get_error ())); 232130812Smarcel } 233130812Smarcel 234130812Smarcel if (!bfd_check_format (abfd, bfd_object)) /* Reads in section info */ 235130812Smarcel { 236130812Smarcel bfd_close (abfd); /* This also closes desc */ 237130812Smarcel make_cleanup (xfree, filename); 238130812Smarcel error ("\"%s\": can't read symbols: %s.", filename, 239130812Smarcel bfd_errmsg (bfd_get_error ())); 240130812Smarcel } 241130812Smarcel 242130812Smarcel /* Sum the sizes of the various sections that compose debug info. */ 243130812Smarcel 244130812Smarcel /* This contains non-DOC information. */ 245130812Smarcel sect = bfd_get_section_by_name (abfd, "$DEBUG$"); 246130812Smarcel if (sect) 247130812Smarcel st_size += (LONGEST) bfd_section_size (abfd, sect); 248130812Smarcel 249130812Smarcel /* This contains DOC information. */ 250130812Smarcel sect = bfd_get_section_by_name (abfd, "$PINFO$"); 251130812Smarcel if (sect) 252130812Smarcel st_size += (LONGEST) bfd_section_size (abfd, sect); 253130812Smarcel 254130812Smarcel bfd_close (abfd); /* This also closes desc */ 255130812Smarcel xfree (filename); 256130812Smarcel 257130812Smarcel /* Unfortunately, just summing the sizes of various debug info 258130812Smarcel sections isn't a very accurate measurement of how much heap 259130812Smarcel space the debugger will need to hold them. It also doesn't 260130812Smarcel account for space needed by linker (aka "minimal") symbols. 261130812Smarcel 262130812Smarcel Anecdotal evidence suggests that just summing the sizes of 263130812Smarcel debug-info-related sections understates the heap space needed 264130812Smarcel to represent it internally by about an order of magnitude. 265130812Smarcel 266130812Smarcel Since it's not exactly brain surgery we're doing here, rather 267130812Smarcel than attempt to more accurately measure the size of a shlib's 268130812Smarcel symbol table in GDB's heap, we'll just apply a 10x fudge- 269130812Smarcel factor to the debug info sections' size-sum. No, this doesn't 270130812Smarcel account for minimal symbols in non-debuggable shlibs. But it 271130812Smarcel all roughly washes out in the end. 272130812Smarcel */ 273130812Smarcel return st_size * (LONGEST) 10; 274130812Smarcel} 275130812Smarcel 276130812Smarcel 277130812Smarcelstatic void 278130812Smarcelsom_solib_add_solib_objfile (struct so_list *so, char *name, int from_tty, 279130812Smarcel CORE_ADDR text_addr) 280130812Smarcel{ 281130812Smarcel obj_private_data_t *obj_private; 282130812Smarcel struct obj_section *s; 283130812Smarcel 284130812Smarcel so->objfile = symbol_file_add (name, from_tty, NULL, 0, OBJF_SHARED); 285130812Smarcel so->abfd = so->objfile->obfd; 286130812Smarcel 287130812Smarcel /* syms_from_objfile has bizarre section offset code, 288130812Smarcel so I do my own right here. */ 289130812Smarcel for (s = so->objfile->sections; s < so->objfile->sections_end; s++) 290130812Smarcel { 291130812Smarcel flagword aflag = bfd_get_section_flags(so->abfd, s->the_bfd_section); 292130812Smarcel if (aflag & SEC_CODE) 293130812Smarcel { 294130812Smarcel s->addr += so->som_solib.text_addr - so->som_solib.text_link_addr; 295130812Smarcel s->endaddr += so->som_solib.text_addr - so->som_solib.text_link_addr; 296130812Smarcel } 297130812Smarcel else if (aflag & SEC_DATA) 298130812Smarcel { 299130812Smarcel s->addr += so->som_solib.data_start; 300130812Smarcel s->endaddr += so->som_solib.data_start; 301130812Smarcel } 302130812Smarcel else 303130812Smarcel ; 304130812Smarcel } 305130812Smarcel 306130812Smarcel /* Mark this as a shared library and save private data. 307130812Smarcel */ 308130812Smarcel so->objfile->flags |= OBJF_SHARED; 309130812Smarcel 310130812Smarcel if (so->objfile->obj_private == NULL) 311130812Smarcel { 312130812Smarcel obj_private = (obj_private_data_t *) 313130812Smarcel obstack_alloc (&so->objfile->objfile_obstack, 314130812Smarcel sizeof (obj_private_data_t)); 315130812Smarcel obj_private->unwind_info = NULL; 316130812Smarcel obj_private->so_info = NULL; 317130812Smarcel so->objfile->obj_private = obj_private; 318130812Smarcel } 319130812Smarcel 320130812Smarcel obj_private = (obj_private_data_t *) so->objfile->obj_private; 321130812Smarcel obj_private->so_info = so; 322130812Smarcel 323130812Smarcel if (!bfd_check_format (so->abfd, bfd_object)) 324130812Smarcel { 325130812Smarcel error ("\"%s\": not in executable format: %s.", 326130812Smarcel name, bfd_errmsg (bfd_get_error ())); 327130812Smarcel } 328130812Smarcel} 329130812Smarcel 330130812Smarcel 331130812Smarcelstatic void 332130812Smarcelsom_solib_load_symbols (struct so_list *so, char *name, int from_tty, 333130812Smarcel CORE_ADDR text_addr, struct target_ops *target) 334130812Smarcel{ 335130812Smarcel struct section_table *p; 336130812Smarcel int status; 337130812Smarcel char buf[4]; 338130812Smarcel CORE_ADDR presumed_data_start; 339130812Smarcel 340130812Smarcel#ifdef SOLIB_DEBUG 341130812Smarcel printf ("--Adding symbols for shared library \"%s\"\n", name); 342130812Smarcel#endif 343130812Smarcel 344130812Smarcel som_solib_add_solib_objfile (so, name, from_tty, text_addr); 345130812Smarcel 346130812Smarcel /* Now we need to build a section table for this library since 347130812Smarcel we might be debugging a core file from a dynamically linked 348130812Smarcel executable in which the libraries were not privately mapped. */ 349130812Smarcel if (build_section_table (so->abfd, 350130812Smarcel &so->sections, 351130812Smarcel &so->sections_end)) 352130812Smarcel { 353130812Smarcel error ("Unable to build section table for shared library\n."); 354130812Smarcel return; 355130812Smarcel } 356130812Smarcel 357130812Smarcel /* Relocate all the sections based on where they got loaded. */ 358130812Smarcel for (p = so->sections; p < so->sections_end; p++) 359130812Smarcel { 360130812Smarcel if (p->the_bfd_section->flags & SEC_CODE) 361130812Smarcel { 362130812Smarcel p->addr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_TEXT (so->objfile)); 363130812Smarcel p->endaddr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_TEXT (so->objfile)); 364130812Smarcel } 365130812Smarcel else if (p->the_bfd_section->flags & SEC_DATA) 366130812Smarcel { 367130812Smarcel p->addr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_DATA (so->objfile)); 368130812Smarcel p->endaddr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_DATA (so->objfile)); 369130812Smarcel } 370130812Smarcel } 371130812Smarcel 372130812Smarcel /* Now see if we need to map in the text and data for this shared 373130812Smarcel library (for example debugging a core file which does not use 374130812Smarcel private shared libraries.). 375130812Smarcel 376130812Smarcel Carefully peek at the first text address in the library. If the 377130812Smarcel read succeeds, then the libraries were privately mapped and were 378130812Smarcel included in the core dump file. 379130812Smarcel 380130812Smarcel If the peek failed, then the libraries were not privately mapped 381130812Smarcel and are not in the core file, we'll have to read them in ourselves. */ 382130812Smarcel status = target_read_memory (text_addr, buf, 4); 383130812Smarcel if (status != 0) 384130812Smarcel { 385130812Smarcel int old, new; 386130812Smarcel 387130812Smarcel new = so->sections_end - so->sections; 388130812Smarcel 389130812Smarcel old = target_resize_to_sections (target, new); 390130812Smarcel 391130812Smarcel /* Copy over the old data before it gets clobbered. */ 392130812Smarcel memcpy ((char *) (target->to_sections + old), 393130812Smarcel so->sections, 394130812Smarcel ((sizeof (struct section_table)) * new)); 395130812Smarcel } 396130812Smarcel} 397130812Smarcel 398130812Smarcel 399130812Smarcel/* FIXME: cagney/2003-02-01: This just isn't right. Given an address 400130812Smarcel within the target's address space, this converts the value into an 401130812Smarcel address within the host's (i.e., GDB's) address space. Given that 402130812Smarcel the host/target address spaces are separate, this can't be right. */ 403130812Smarcel 404130812Smarcelstatic void * 405130812Smarcelhpux_address_to_host_pointer_hack (CORE_ADDR addr) 406130812Smarcel{ 407130812Smarcel void *ptr; 408130812Smarcel 409130812Smarcel gdb_assert (sizeof (ptr) == TYPE_LENGTH (builtin_type_void_data_ptr)); 410130812Smarcel ADDRESS_TO_POINTER (builtin_type_void_data_ptr, &ptr, addr); 411130812Smarcel return ptr; 412130812Smarcel} 413130812Smarcel 414130812Smarcel/* Add symbols from shared libraries into the symtab list, unless the 415130812Smarcel size threshold specified by auto_solib_limit (in megabytes) would 416130812Smarcel be exceeded. */ 417130812Smarcel 418130812Smarcelvoid 419130812Smarcelsom_solib_add (char *arg_string, int from_tty, struct target_ops *target, int readsyms) 420130812Smarcel{ 421130812Smarcel struct minimal_symbol *msymbol; 422130812Smarcel struct so_list *so_list_tail; 423130812Smarcel CORE_ADDR addr; 424130812Smarcel asection *shlib_info; 425130812Smarcel int status; 426130812Smarcel unsigned int dld_flags; 427130812Smarcel char buf[4], *re_err; 428130812Smarcel int threshold_warning_given = 0; 429130812Smarcel 430130812Smarcel /* First validate our arguments. */ 431130812Smarcel re_err = re_comp (arg_string ? arg_string : "."); 432130812Smarcel if (re_err != NULL) 433130812Smarcel { 434130812Smarcel error ("Invalid regexp: %s", re_err); 435130812Smarcel } 436130812Smarcel 437130812Smarcel /* If we're debugging a core file, or have attached to a running 438130812Smarcel process, then som_solib_create_inferior_hook will not have been 439130812Smarcel called. 440130812Smarcel 441130812Smarcel We need to first determine if we're dealing with a dynamically 442130812Smarcel linked executable. If not, then return without an error or warning. 443130812Smarcel 444130812Smarcel We also need to examine __dld_flags to determine if the shared library 445130812Smarcel list is valid and to determine if the libraries have been privately 446130812Smarcel mapped. */ 447130812Smarcel if (symfile_objfile == NULL) 448130812Smarcel return; 449130812Smarcel 450130812Smarcel /* First see if the objfile was dynamically linked. */ 451130812Smarcel shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, "$SHLIB_INFO$"); 452130812Smarcel if (!shlib_info) 453130812Smarcel return; 454130812Smarcel 455130812Smarcel /* It's got a $SHLIB_INFO$ section, make sure it's not empty. */ 456130812Smarcel if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0) 457130812Smarcel return; 458130812Smarcel 459130812Smarcel msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL); 460130812Smarcel if (msymbol == NULL) 461130812Smarcel { 462130812Smarcel error ("Unable to find __dld_flags symbol in object file.\n"); 463130812Smarcel return; 464130812Smarcel } 465130812Smarcel 466130812Smarcel addr = SYMBOL_VALUE_ADDRESS (msymbol); 467130812Smarcel /* Read the current contents. */ 468130812Smarcel status = target_read_memory (addr, buf, 4); 469130812Smarcel if (status != 0) 470130812Smarcel { 471130812Smarcel error ("Unable to read __dld_flags\n"); 472130812Smarcel return; 473130812Smarcel } 474130812Smarcel dld_flags = extract_unsigned_integer (buf, 4); 475130812Smarcel 476130812Smarcel /* __dld_list may not be valid. If not, then we punt, warning the user if 477130812Smarcel we were called as a result of the add-symfile command. 478130812Smarcel */ 479130812Smarcel if ((dld_flags & DLD_FLAGS_LISTVALID) == 0) 480130812Smarcel { 481130812Smarcel if (from_tty) 482130812Smarcel error ("__dld_list is not valid according to __dld_flags.\n"); 483130812Smarcel return; 484130812Smarcel } 485130812Smarcel 486130812Smarcel /* If the libraries were not mapped private, warn the user. */ 487130812Smarcel if ((dld_flags & DLD_FLAGS_MAPPRIVATE) == 0) 488130812Smarcel warning ("The shared libraries were not privately mapped; setting a\nbreakpoint in a shared library will not work until you rerun the program.\n"); 489130812Smarcel 490130812Smarcel msymbol = lookup_minimal_symbol ("__dld_list", NULL, NULL); 491130812Smarcel if (!msymbol) 492130812Smarcel { 493130812Smarcel /* Older crt0.o files (hpux8) don't have __dld_list as a symbol, 494130812Smarcel but the data is still available if you know where to look. */ 495130812Smarcel msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL); 496130812Smarcel if (!msymbol) 497130812Smarcel { 498130812Smarcel error ("Unable to find dynamic library list.\n"); 499130812Smarcel return; 500130812Smarcel } 501130812Smarcel addr = SYMBOL_VALUE_ADDRESS (msymbol) - 8; 502130812Smarcel } 503130812Smarcel else 504130812Smarcel addr = SYMBOL_VALUE_ADDRESS (msymbol); 505130812Smarcel 506130812Smarcel status = target_read_memory (addr, buf, 4); 507130812Smarcel if (status != 0) 508130812Smarcel { 509130812Smarcel error ("Unable to find dynamic library list.\n"); 510130812Smarcel return; 511130812Smarcel } 512130812Smarcel 513130812Smarcel addr = extract_unsigned_integer (buf, 4); 514130812Smarcel 515130812Smarcel /* If addr is zero, then we're using an old dynamic loader which 516130812Smarcel doesn't maintain __dld_list. We'll have to use a completely 517130812Smarcel different approach to get shared library information. */ 518130812Smarcel if (addr == 0) 519130812Smarcel goto old_dld; 520130812Smarcel 521130812Smarcel /* Using the information in __dld_list is the preferred method 522130812Smarcel to get at shared library information. It doesn't depend on 523130812Smarcel any functions in /opt/langtools/lib/end.o and has a chance of working 524130812Smarcel with hpux10 when it is released. */ 525130812Smarcel status = target_read_memory (addr, buf, 4); 526130812Smarcel if (status != 0) 527130812Smarcel { 528130812Smarcel error ("Unable to find dynamic library list.\n"); 529130812Smarcel return; 530130812Smarcel } 531130812Smarcel 532130812Smarcel /* addr now holds the address of the first entry in the dynamic 533130812Smarcel library list. */ 534130812Smarcel addr = extract_unsigned_integer (buf, 4); 535130812Smarcel 536130812Smarcel /* Now that we have a pointer to the dynamic library list, walk 537130812Smarcel through it and add the symbols for each library. */ 538130812Smarcel 539130812Smarcel so_list_tail = so_list_head; 540130812Smarcel /* Find the end of the list of shared objects. */ 541130812Smarcel while (so_list_tail && so_list_tail->next) 542130812Smarcel so_list_tail = so_list_tail->next; 543130812Smarcel 544130812Smarcel#ifdef SOLIB_DEBUG 545130812Smarcel printf ("--About to read shared library list data\n"); 546130812Smarcel#endif 547130812Smarcel 548130812Smarcel /* "addr" will always point to the base of the 549130812Smarcel * current data entry describing the current 550130812Smarcel * shared library. 551130812Smarcel */ 552130812Smarcel while (1) 553130812Smarcel { 554130812Smarcel CORE_ADDR name_addr, text_addr; 555130812Smarcel unsigned int name_len; 556130812Smarcel char *name; 557130812Smarcel struct so_list *new_so; 558130812Smarcel struct so_list *so_list = so_list_head; 559130812Smarcel struct stat statbuf; 560130812Smarcel LONGEST st_size; 561130812Smarcel int is_main_program; 562130812Smarcel 563130812Smarcel if (addr == 0) 564130812Smarcel break; 565130812Smarcel 566130812Smarcel /* Get a pointer to the name of this library. */ 567130812Smarcel status = target_read_memory (addr, buf, 4); 568130812Smarcel if (status != 0) 569130812Smarcel goto err; 570130812Smarcel 571130812Smarcel name_addr = extract_unsigned_integer (buf, 4); 572130812Smarcel name_len = 0; 573130812Smarcel while (1) 574130812Smarcel { 575130812Smarcel target_read_memory (name_addr + name_len, buf, 1); 576130812Smarcel if (status != 0) 577130812Smarcel goto err; 578130812Smarcel 579130812Smarcel name_len++; 580130812Smarcel if (*buf == '\0') 581130812Smarcel break; 582130812Smarcel } 583130812Smarcel name = alloca (name_len); 584130812Smarcel status = target_read_memory (name_addr, name, name_len); 585130812Smarcel if (status != 0) 586130812Smarcel goto err; 587130812Smarcel 588130812Smarcel /* See if we've already loaded something with this name. */ 589130812Smarcel while (so_list) 590130812Smarcel { 591130812Smarcel if (!strcmp (so_list->som_solib.name, name)) 592130812Smarcel break; 593130812Smarcel so_list = so_list->next; 594130812Smarcel } 595130812Smarcel 596130812Smarcel /* See if the file exists. If not, give a warning, but don't 597130812Smarcel die. */ 598130812Smarcel status = stat (name, &statbuf); 599130812Smarcel if (status == -1) 600130812Smarcel { 601130812Smarcel warning ("Can't find file %s referenced in dld_list.", name); 602130812Smarcel 603130812Smarcel status = target_read_memory (addr + 36, buf, 4); 604130812Smarcel if (status != 0) 605130812Smarcel goto err; 606130812Smarcel 607130812Smarcel addr = (CORE_ADDR) extract_unsigned_integer (buf, 4); 608130812Smarcel continue; 609130812Smarcel } 610130812Smarcel 611130812Smarcel /* If we've already loaded this one or it's the main program, skip it. */ 612130812Smarcel is_main_program = (strcmp (name, symfile_objfile->name) == 0); 613130812Smarcel if (so_list || is_main_program) 614130812Smarcel { 615130812Smarcel /* This is the "next" pointer in the strcuture. 616130812Smarcel */ 617130812Smarcel status = target_read_memory (addr + 36, buf, 4); 618130812Smarcel if (status != 0) 619130812Smarcel goto err; 620130812Smarcel 621130812Smarcel addr = (CORE_ADDR) extract_unsigned_integer (buf, 4); 622130812Smarcel 623130812Smarcel /* Record the main program's symbol table size. */ 624130812Smarcel if (is_main_program && !so_list) 625130812Smarcel { 626130812Smarcel st_size = som_solib_sizeof_symbol_table (name); 627130812Smarcel som_solib_total_st_size += st_size; 628130812Smarcel } 629130812Smarcel 630130812Smarcel /* Was this a shlib that we noted but didn't load the symbols for? 631130812Smarcel If so, were we invoked this time from the command-line, via 632130812Smarcel a 'sharedlibrary' or 'add-symbol-file' command? If yes to 633130812Smarcel both, we'd better load the symbols this time. 634130812Smarcel */ 635130812Smarcel if (from_tty && so_list && !is_main_program && (so_list->objfile == NULL)) 636130812Smarcel som_solib_load_symbols (so_list, 637130812Smarcel name, 638130812Smarcel from_tty, 639130812Smarcel so_list->som_solib.text_addr, 640130812Smarcel target); 641130812Smarcel 642130812Smarcel continue; 643130812Smarcel } 644130812Smarcel 645130812Smarcel name = obsavestring (name, name_len - 1, 646130812Smarcel &symfile_objfile->objfile_obstack); 647130812Smarcel 648130812Smarcel status = target_read_memory (addr + 8, buf, 4); 649130812Smarcel if (status != 0) 650130812Smarcel goto err; 651130812Smarcel 652130812Smarcel text_addr = extract_unsigned_integer (buf, 4); 653130812Smarcel 654130812Smarcel new_so = (struct so_list *) xmalloc (sizeof (struct so_list)); 655130812Smarcel memset ((char *) new_so, 0, sizeof (struct so_list)); 656130812Smarcel if (so_list_head == NULL) 657130812Smarcel { 658130812Smarcel so_list_head = new_so; 659130812Smarcel so_list_tail = new_so; 660130812Smarcel } 661130812Smarcel else 662130812Smarcel { 663130812Smarcel so_list_tail->next = new_so; 664130812Smarcel so_list_tail = new_so; 665130812Smarcel } 666130812Smarcel 667130812Smarcel /* Fill in all the entries in GDB's shared library list. 668130812Smarcel */ 669130812Smarcel 670130812Smarcel new_so->solib_addr = addr; 671130812Smarcel new_so->som_solib.name = name; 672130812Smarcel status = target_read_memory (addr + 4, buf, 4); 673130812Smarcel if (status != 0) 674130812Smarcel goto err; 675130812Smarcel 676130812Smarcel new_so->som_solib.struct_version = extract_unsigned_integer (buf + 3, 1); 677130812Smarcel new_so->som_solib.bind_mode = extract_unsigned_integer (buf + 2, 1); 678130812Smarcel /* Following is "high water mark", highest version number 679130812Smarcel * seen, rather than plain version number. 680130812Smarcel */ 681130812Smarcel new_so->som_solib.library_version = extract_unsigned_integer (buf, 2); 682130812Smarcel new_so->som_solib.text_addr = text_addr; 683130812Smarcel 684130812Smarcel /* Q: What about longword at "addr + 8"? 685130812Smarcel * A: It's read above, out of order, into "text_addr". 686130812Smarcel */ 687130812Smarcel 688130812Smarcel status = target_read_memory (addr + 12, buf, 4); 689130812Smarcel if (status != 0) 690130812Smarcel goto err; 691130812Smarcel 692130812Smarcel new_so->som_solib.text_link_addr = extract_unsigned_integer (buf, 4); 693130812Smarcel 694130812Smarcel status = target_read_memory (addr + 16, buf, 4); 695130812Smarcel if (status != 0) 696130812Smarcel goto err; 697130812Smarcel 698130812Smarcel new_so->som_solib.text_end = extract_unsigned_integer (buf, 4); 699130812Smarcel 700130812Smarcel status = target_read_memory (addr + 20, buf, 4); 701130812Smarcel if (status != 0) 702130812Smarcel goto err; 703130812Smarcel 704130812Smarcel new_so->som_solib.data_start = extract_unsigned_integer (buf, 4); 705130812Smarcel 706130812Smarcel status = target_read_memory (addr + 24, buf, 4); 707130812Smarcel if (status != 0) 708130812Smarcel goto err; 709130812Smarcel 710130812Smarcel new_so->som_solib.bss_start = extract_unsigned_integer (buf, 4); 711130812Smarcel 712130812Smarcel status = target_read_memory (addr + 28, buf, 4); 713130812Smarcel if (status != 0) 714130812Smarcel goto err; 715130812Smarcel 716130812Smarcel new_so->som_solib.data_end = extract_unsigned_integer (buf, 4); 717130812Smarcel 718130812Smarcel status = target_read_memory (addr + 32, buf, 4); 719130812Smarcel if (status != 0) 720130812Smarcel goto err; 721130812Smarcel 722130812Smarcel new_so->som_solib.got_value = extract_unsigned_integer (buf, 4); 723130812Smarcel 724130812Smarcel status = target_read_memory (addr + 36, buf, 4); 725130812Smarcel if (status != 0) 726130812Smarcel goto err; 727130812Smarcel 728130812Smarcel /* FIXME: cagney/2003-02-01: I think som_solib.next should be a 729130812Smarcel CORE_ADDR. */ 730130812Smarcel new_so->som_solib.next = 731130812Smarcel hpux_address_to_host_pointer_hack (extract_unsigned_integer (buf, 4)); 732130812Smarcel 733130812Smarcel /* Note that we don't re-set "addr" to the next pointer 734130812Smarcel * until after we've read the trailing data. 735130812Smarcel */ 736130812Smarcel 737130812Smarcel status = target_read_memory (addr + 40, buf, 4); 738130812Smarcel new_so->som_solib.tsd_start_addr = extract_unsigned_integer (buf, 4); 739130812Smarcel if (status != 0) 740130812Smarcel goto err; 741130812Smarcel 742130812Smarcel /* Now indirect via that value! 743130812Smarcel */ 744130812Smarcel status = target_read_memory (new_so->som_solib.tsd_start_addr, buf, 4); 745130812Smarcel new_so->som_solib.tsd_start_addr = extract_unsigned_integer (buf, 4); 746130812Smarcel if (status != 0) 747130812Smarcel goto err; 748130812Smarcel#ifdef SOLIB_DEBUG 749130812Smarcel printf ("\n+ library \"%s\" is described at 0x%x\n", name, addr); 750130812Smarcel printf (" 'version' is %d\n", new_so->som_solib.struct_version); 751130812Smarcel printf (" 'bind_mode' is %d\n", new_so->som_solib.bind_mode); 752130812Smarcel printf (" 'library_version' is %d\n", new_so->som_solib.library_version); 753130812Smarcel printf (" 'text_addr' is 0x%x\n", new_so->som_solib.text_addr); 754130812Smarcel printf (" 'text_link_addr' is 0x%x\n", new_so->som_solib.text_link_addr); 755130812Smarcel printf (" 'text_end' is 0x%x\n", new_so->som_solib.text_end); 756130812Smarcel printf (" 'data_start' is 0x%x\n", new_so->som_solib.data_start); 757130812Smarcel printf (" 'bss_start' is 0x%x\n", new_so->som_solib.bss_start); 758130812Smarcel printf (" 'data_end' is 0x%x\n", new_so->som_solib.data_end); 759130812Smarcel printf (" 'got_value' is %x\n", new_so->som_solib.got_value); 760130812Smarcel printf (" 'next' is 0x%x\n", new_so->som_solib.next); 761130812Smarcel printf (" 'tsd_start_addr' is 0x%x\n", new_so->som_solib.tsd_start_addr); 762130812Smarcel#endif 763130812Smarcel 764130812Smarcel /* Go on to the next shared library descriptor. 765130812Smarcel */ 766130812Smarcel addr = (CORE_ADDR) new_so->som_solib.next; 767130812Smarcel 768130812Smarcel 769130812Smarcel 770130812Smarcel /* At this point, we have essentially hooked the shlib into the 771130812Smarcel "info share" command. However, we haven't yet loaded its 772130812Smarcel symbol table. We must now decide whether we ought to, i.e., 773130812Smarcel whether doing so would exceed the symbol table size threshold. 774130812Smarcel 775130812Smarcel If the threshold has just now been exceeded, then we'll issue 776130812Smarcel a warning message (which explains how to load symbols manually, 777130812Smarcel if the user so desires). 778130812Smarcel 779130812Smarcel If the threshold has just now or previously been exceeded, 780130812Smarcel we'll just add the shlib to the list of object files, but won't 781130812Smarcel actually load its symbols. (This is more useful than it might 782130812Smarcel sound, for it allows us to e.g., still load and use the shlibs' 783130812Smarcel unwind information for stack tracebacks.) 784130812Smarcel */ 785130812Smarcel 786130812Smarcel /* Note that we DON'T want to preclude the user from using the 787130812Smarcel add-symbol-file command! Thus, we only worry about the threshold 788130812Smarcel when we're invoked for other reasons. 789130812Smarcel */ 790130812Smarcel st_size = som_solib_sizeof_symbol_table (name); 791130812Smarcel som_solib_st_size_threshold_exceeded = 792130812Smarcel !from_tty && 793130812Smarcel auto_solib_limit > 0 && 794130812Smarcel readsyms && 795130812Smarcel ((st_size + som_solib_total_st_size) > (auto_solib_limit * (LONGEST) (1024 * 1024))); 796130812Smarcel 797130812Smarcel if (som_solib_st_size_threshold_exceeded) 798130812Smarcel { 799130812Smarcel if (!threshold_warning_given) 800130812Smarcel warning ("Symbols for some libraries have not been loaded, because\ndoing so would exceed the size threshold specified by auto-solib-limit.\nTo manually load symbols, use the 'sharedlibrary' command.\nTo raise the threshold, set auto-solib-limit to a larger value and rerun\nthe program.\n"); 801130812Smarcel threshold_warning_given = 1; 802130812Smarcel 803130812Smarcel /* We'll still make note of this shlib, even if we don't 804130812Smarcel read its symbols. This allows us to use its unwind 805130812Smarcel information well enough to know how to e.g., correctly 806130812Smarcel do a traceback from a PC within the shlib, even if we 807130812Smarcel can't symbolize those PCs... 808130812Smarcel */ 809130812Smarcel som_solib_add_solib_objfile (new_so, name, from_tty, text_addr); 810130812Smarcel continue; 811130812Smarcel } 812130812Smarcel 813130812Smarcel som_solib_total_st_size += st_size; 814130812Smarcel 815130812Smarcel /* This fills in new_so->objfile, among others. */ 816130812Smarcel som_solib_load_symbols (new_so, name, from_tty, text_addr, target); 817130812Smarcel } 818130812Smarcel 819130812Smarcel#ifdef SOLIB_DEBUG 820130812Smarcel printf ("--Done reading shared library data\n"); 821130812Smarcel#endif 822130812Smarcel 823130812Smarcel /* Getting new symbols may change our opinion about what is 824130812Smarcel frameless. */ 825130812Smarcel reinit_frame_cache (); 826130812Smarcel return; 827130812Smarcel 828130812Smarcelold_dld: 829130812Smarcel error ("Debugging dynamic executables loaded via the hpux8 dld.sl is not supported.\n"); 830130812Smarcel return; 831130812Smarcel 832130812Smarcelerr: 833130812Smarcel error ("Error while reading dynamic library list.\n"); 834130812Smarcel return; 835130812Smarcel} 836130812Smarcel 837130812Smarcel 838130812Smarcel/* This hook gets called just before the first instruction in the 839130812Smarcel inferior process is executed. 840130812Smarcel 841130812Smarcel This is our opportunity to set magic flags in the inferior so 842130812Smarcel that GDB can be notified when a shared library is mapped in and 843130812Smarcel to tell the dynamic linker that a private copy of the library is 844130812Smarcel needed (so GDB can set breakpoints in the library). 845130812Smarcel 846130812Smarcel __dld_flags is the location of the magic flags; as of this implementation 847130812Smarcel there are 3 flags of interest: 848130812Smarcel 849130812Smarcel bit 0 when set indicates that private copies of the libraries are needed 850130812Smarcel bit 1 when set indicates that the callback hook routine is valid 851130812Smarcel bit 2 when set indicates that the dynamic linker should maintain the 852130812Smarcel __dld_list structure when loading/unloading libraries. 853130812Smarcel 854130812Smarcel Note that shared libraries are not mapped in at this time, so we have 855130812Smarcel run the inferior until the libraries are mapped in. Typically this 856130812Smarcel means running until the "_start" is called. */ 857130812Smarcel 858130812Smarcelvoid 859130812Smarcelsom_solib_create_inferior_hook (void) 860130812Smarcel{ 861130812Smarcel struct minimal_symbol *msymbol; 862130812Smarcel unsigned int dld_flags, status, have_endo; 863130812Smarcel asection *shlib_info; 864130812Smarcel char buf[4]; 865130812Smarcel struct objfile *objfile; 866130812Smarcel CORE_ADDR anaddr; 867130812Smarcel 868130812Smarcel /* First, remove all the solib event breakpoints. Their addresses 869130812Smarcel may have changed since the last time we ran the program. */ 870130812Smarcel remove_solib_event_breakpoints (); 871130812Smarcel 872130812Smarcel if (symfile_objfile == NULL) 873130812Smarcel return; 874130812Smarcel 875130812Smarcel /* First see if the objfile was dynamically linked. */ 876130812Smarcel shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, "$SHLIB_INFO$"); 877130812Smarcel if (!shlib_info) 878130812Smarcel return; 879130812Smarcel 880130812Smarcel /* It's got a $SHLIB_INFO$ section, make sure it's not empty. */ 881130812Smarcel if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0) 882130812Smarcel return; 883130812Smarcel 884130812Smarcel have_endo = 0; 885130812Smarcel /* Slam the pid of the process into __d_pid. 886130812Smarcel 887130812Smarcel We used to warn when this failed, but that warning is only useful 888130812Smarcel on very old HP systems (hpux9 and older). The warnings are an 889130812Smarcel annoyance to users of modern systems and foul up the testsuite as 890130812Smarcel well. As a result, the warnings have been disabled. */ 891130812Smarcel msymbol = lookup_minimal_symbol ("__d_pid", NULL, symfile_objfile); 892130812Smarcel if (msymbol == NULL) 893130812Smarcel goto keep_going; 894130812Smarcel 895130812Smarcel anaddr = SYMBOL_VALUE_ADDRESS (msymbol); 896130812Smarcel store_unsigned_integer (buf, 4, PIDGET (inferior_ptid)); 897130812Smarcel status = target_write_memory (anaddr, buf, 4); 898130812Smarcel if (status != 0) 899130812Smarcel { 900130812Smarcel warning ("Unable to write __d_pid"); 901130812Smarcel warning ("Suggest linking with /opt/langtools/lib/end.o."); 902130812Smarcel warning ("GDB will be unable to track shl_load/shl_unload calls"); 903130812Smarcel goto keep_going; 904130812Smarcel } 905130812Smarcel 906130812Smarcel /* Get the value of _DLD_HOOK (an export stub) and put it in __dld_hook; 907130812Smarcel This will force the dynamic linker to call __d_trap when significant 908130812Smarcel events occur. 909130812Smarcel 910130812Smarcel Note that the above is the pre-HP-UX 9.0 behaviour. At 9.0 and above, 911130812Smarcel the dld provides an export stub named "__d_trap" as well as the 912130812Smarcel function named "__d_trap" itself, but doesn't provide "_DLD_HOOK". 913130812Smarcel We'll look first for the old flavor and then the new. 914130812Smarcel */ 915130812Smarcel msymbol = lookup_minimal_symbol ("_DLD_HOOK", NULL, symfile_objfile); 916130812Smarcel if (msymbol == NULL) 917130812Smarcel msymbol = lookup_minimal_symbol ("__d_trap", NULL, symfile_objfile); 918130812Smarcel if (msymbol == NULL) 919130812Smarcel { 920130812Smarcel warning ("Unable to find _DLD_HOOK symbol in object file."); 921130812Smarcel warning ("Suggest linking with /opt/langtools/lib/end.o."); 922130812Smarcel warning ("GDB will be unable to track shl_load/shl_unload calls"); 923130812Smarcel goto keep_going; 924130812Smarcel } 925130812Smarcel anaddr = SYMBOL_VALUE_ADDRESS (msymbol); 926130812Smarcel dld_cache.hook.address = anaddr; 927130812Smarcel 928130812Smarcel /* Grrr, this might not be an export symbol! We have to find the 929130812Smarcel export stub. */ 930130812Smarcel ALL_OBJFILES (objfile) 931130812Smarcel { 932130812Smarcel struct unwind_table_entry *u; 933130812Smarcel struct minimal_symbol *msymbol2; 934130812Smarcel 935130812Smarcel /* What a crock. */ 936130812Smarcel msymbol2 = lookup_minimal_symbol_solib_trampoline (DEPRECATED_SYMBOL_NAME (msymbol), 937130812Smarcel objfile); 938130812Smarcel /* Found a symbol with the right name. */ 939130812Smarcel if (msymbol2) 940130812Smarcel { 941130812Smarcel struct unwind_table_entry *u; 942130812Smarcel /* It must be a shared library trampoline. */ 943130812Smarcel if (SYMBOL_TYPE (msymbol2) != mst_solib_trampoline) 944130812Smarcel continue; 945130812Smarcel 946130812Smarcel /* It must also be an export stub. */ 947130812Smarcel u = find_unwind_entry (SYMBOL_VALUE (msymbol2)); 948130812Smarcel if (!u || u->stub_unwind.stub_type != EXPORT) 949130812Smarcel continue; 950130812Smarcel 951130812Smarcel /* OK. Looks like the correct import stub. */ 952130812Smarcel anaddr = SYMBOL_VALUE (msymbol2); 953130812Smarcel dld_cache.hook_stub.address = anaddr; 954130812Smarcel } 955130812Smarcel } 956130812Smarcel store_unsigned_integer (buf, 4, anaddr); 957130812Smarcel 958130812Smarcel msymbol = lookup_minimal_symbol ("__dld_hook", NULL, symfile_objfile); 959130812Smarcel if (msymbol == NULL) 960130812Smarcel { 961130812Smarcel warning ("Unable to find __dld_hook symbol in object file."); 962130812Smarcel warning ("Suggest linking with /opt/langtools/lib/end.o."); 963130812Smarcel warning ("GDB will be unable to track shl_load/shl_unload calls"); 964130812Smarcel goto keep_going; 965130812Smarcel } 966130812Smarcel anaddr = SYMBOL_VALUE_ADDRESS (msymbol); 967130812Smarcel status = target_write_memory (anaddr, buf, 4); 968130812Smarcel 969130812Smarcel /* Now set a shlib_event breakpoint at __d_trap so we can track 970130812Smarcel significant shared library events. */ 971130812Smarcel msymbol = lookup_minimal_symbol ("__d_trap", NULL, symfile_objfile); 972130812Smarcel if (msymbol == NULL) 973130812Smarcel { 974130812Smarcel warning ("Unable to find __dld_d_trap symbol in object file."); 975130812Smarcel warning ("Suggest linking with /opt/langtools/lib/end.o."); 976130812Smarcel warning ("GDB will be unable to track shl_load/shl_unload calls"); 977130812Smarcel goto keep_going; 978130812Smarcel } 979130812Smarcel create_solib_event_breakpoint (SYMBOL_VALUE_ADDRESS (msymbol)); 980130812Smarcel 981130812Smarcel /* We have all the support usually found in end.o, so we can track 982130812Smarcel shl_load and shl_unload calls. */ 983130812Smarcel have_endo = 1; 984130812Smarcel 985130812Smarcelkeep_going: 986130812Smarcel 987130812Smarcel /* Get the address of __dld_flags, if no such symbol exists, then we can 988130812Smarcel not debug the shared code. */ 989130812Smarcel msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL); 990130812Smarcel if (msymbol == NULL) 991130812Smarcel { 992130812Smarcel error ("Unable to find __dld_flags symbol in object file.\n"); 993130812Smarcel } 994130812Smarcel 995130812Smarcel anaddr = SYMBOL_VALUE_ADDRESS (msymbol); 996130812Smarcel 997130812Smarcel /* Read the current contents. */ 998130812Smarcel status = target_read_memory (anaddr, buf, 4); 999130812Smarcel if (status != 0) 1000130812Smarcel { 1001130812Smarcel error ("Unable to read __dld_flags\n"); 1002130812Smarcel } 1003130812Smarcel dld_flags = extract_unsigned_integer (buf, 4); 1004130812Smarcel 1005130812Smarcel /* Turn on the flags we care about. */ 1006130812Smarcel dld_flags |= DLD_FLAGS_MAPPRIVATE; 1007130812Smarcel if (have_endo) 1008130812Smarcel dld_flags |= DLD_FLAGS_HOOKVALID; 1009130812Smarcel store_unsigned_integer (buf, 4, dld_flags); 1010130812Smarcel status = target_write_memory (anaddr, buf, 4); 1011130812Smarcel if (status != 0) 1012130812Smarcel { 1013130812Smarcel error ("Unable to write __dld_flags\n"); 1014130812Smarcel } 1015130812Smarcel 1016130812Smarcel /* Now find the address of _start and set a breakpoint there. 1017130812Smarcel We still need this code for two reasons: 1018130812Smarcel 1019130812Smarcel * Not all sites have /opt/langtools/lib/end.o, so it's not always 1020130812Smarcel possible to track the dynamic linker's events. 1021130812Smarcel 1022130812Smarcel * At this time no events are triggered for shared libraries 1023130812Smarcel loaded at startup time (what a crock). */ 1024130812Smarcel 1025130812Smarcel msymbol = lookup_minimal_symbol ("_start", NULL, symfile_objfile); 1026130812Smarcel if (msymbol == NULL) 1027130812Smarcel { 1028130812Smarcel error ("Unable to find _start symbol in object file.\n"); 1029130812Smarcel } 1030130812Smarcel 1031130812Smarcel anaddr = SYMBOL_VALUE_ADDRESS (msymbol); 1032130812Smarcel 1033130812Smarcel /* Make the breakpoint at "_start" a shared library event breakpoint. */ 1034130812Smarcel create_solib_event_breakpoint (anaddr); 1035130812Smarcel 1036130812Smarcel /* Wipe out all knowledge of old shared libraries since their 1037130812Smarcel mapping can change from one exec to another! */ 1038130812Smarcel while (so_list_head) 1039130812Smarcel { 1040130812Smarcel struct so_list *temp; 1041130812Smarcel 1042130812Smarcel temp = so_list_head; 1043130812Smarcel xfree (so_list_head); 1044130812Smarcel so_list_head = temp->next; 1045130812Smarcel } 1046130812Smarcel clear_symtab_users (); 1047130812Smarcel} 1048130812Smarcel 1049130812Smarcel/* This operation removes the "hook" between GDB and the dynamic linker, 1050130812Smarcel which causes the dld to notify GDB of shared library events. 1051130812Smarcel 1052130812Smarcel After this operation completes, the dld will no longer notify GDB of 1053130812Smarcel shared library events. To resume notifications, GDB must call 1054130812Smarcel som_solib_create_inferior_hook. 1055130812Smarcel 1056130812Smarcel This operation does not remove any knowledge of shared libraries which 1057130812Smarcel GDB may already have been notified of. 1058130812Smarcel */ 1059130812Smarcelvoid 1060130812Smarcelsom_solib_remove_inferior_hook (int pid) 1061130812Smarcel{ 1062130812Smarcel CORE_ADDR addr; 1063130812Smarcel struct minimal_symbol *msymbol; 1064130812Smarcel int status; 1065130812Smarcel char dld_flags_buffer[4]; 1066130812Smarcel unsigned int dld_flags_value; 1067130812Smarcel struct cleanup *old_cleanups = save_inferior_ptid (); 1068130812Smarcel 1069130812Smarcel /* Ensure that we're really operating on the specified process. */ 1070130812Smarcel inferior_ptid = pid_to_ptid (pid); 1071130812Smarcel 1072130812Smarcel /* We won't bother to remove the solib breakpoints from this process. 1073130812Smarcel 1074130812Smarcel In fact, on PA64 the breakpoint is hard-coded into the dld callback, 1075130812Smarcel and thus we're not supposed to remove it. 1076130812Smarcel 1077130812Smarcel Rather, we'll merely clear the dld_flags bit that enables callbacks. 1078130812Smarcel */ 1079130812Smarcel msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL); 1080130812Smarcel 1081130812Smarcel addr = SYMBOL_VALUE_ADDRESS (msymbol); 1082130812Smarcel status = target_read_memory (addr, dld_flags_buffer, 4); 1083130812Smarcel 1084130812Smarcel dld_flags_value = extract_unsigned_integer (dld_flags_buffer, 4); 1085130812Smarcel 1086130812Smarcel dld_flags_value &= ~DLD_FLAGS_HOOKVALID; 1087130812Smarcel store_unsigned_integer (dld_flags_buffer, 4, dld_flags_value); 1088130812Smarcel status = target_write_memory (addr, dld_flags_buffer, 4); 1089130812Smarcel 1090130812Smarcel do_cleanups (old_cleanups); 1091130812Smarcel} 1092130812Smarcel 1093130812Smarcel 1094130812Smarcel/* This function creates a breakpoint on the dynamic linker hook, which 1095130812Smarcel is called when e.g., a shl_load or shl_unload call is made. This 1096130812Smarcel breakpoint will only trigger when a shl_load call is made. 1097130812Smarcel 1098130812Smarcel If filename is NULL, then loads of any dll will be caught. Else, 1099130812Smarcel only loads of the file whose pathname is the string contained by 1100130812Smarcel filename will be caught. 1101130812Smarcel 1102130812Smarcel Undefined behaviour is guaranteed if this function is called before 1103130812Smarcel som_solib_create_inferior_hook. 1104130812Smarcel */ 1105130812Smarcelvoid 1106130812Smarcelsom_solib_create_catch_load_hook (int pid, int tempflag, char *filename, 1107130812Smarcel char *cond_string) 1108130812Smarcel{ 1109130812Smarcel create_solib_load_event_breakpoint ("__d_trap", tempflag, filename, cond_string); 1110130812Smarcel} 1111130812Smarcel 1112130812Smarcel/* This function creates a breakpoint on the dynamic linker hook, which 1113130812Smarcel is called when e.g., a shl_load or shl_unload call is made. This 1114130812Smarcel breakpoint will only trigger when a shl_unload call is made. 1115130812Smarcel 1116130812Smarcel If filename is NULL, then unloads of any dll will be caught. Else, 1117130812Smarcel only unloads of the file whose pathname is the string contained by 1118130812Smarcel filename will be caught. 1119130812Smarcel 1120130812Smarcel Undefined behaviour is guaranteed if this function is called before 1121130812Smarcel som_solib_create_inferior_hook. 1122130812Smarcel */ 1123130812Smarcelvoid 1124130812Smarcelsom_solib_create_catch_unload_hook (int pid, int tempflag, char *filename, 1125130812Smarcel char *cond_string) 1126130812Smarcel{ 1127130812Smarcel create_solib_unload_event_breakpoint ("__d_trap", tempflag, filename, cond_string); 1128130812Smarcel} 1129130812Smarcel 1130130812Smarcelint 1131130812Smarcelsom_solib_have_load_event (int pid) 1132130812Smarcel{ 1133130812Smarcel CORE_ADDR event_kind; 1134130812Smarcel 1135130812Smarcel event_kind = read_register (ARG0_REGNUM); 1136130812Smarcel return (event_kind == SHL_LOAD); 1137130812Smarcel} 1138130812Smarcel 1139130812Smarcelint 1140130812Smarcelsom_solib_have_unload_event (int pid) 1141130812Smarcel{ 1142130812Smarcel CORE_ADDR event_kind; 1143130812Smarcel 1144130812Smarcel event_kind = read_register (ARG0_REGNUM); 1145130812Smarcel return (event_kind == SHL_UNLOAD); 1146130812Smarcel} 1147130812Smarcel 1148130812Smarcelstatic char * 1149130812Smarcelsom_solib_library_pathname (int pid) 1150130812Smarcel{ 1151130812Smarcel CORE_ADDR dll_handle_address; 1152130812Smarcel CORE_ADDR dll_pathname_address; 1153130812Smarcel struct som_solib_mapped_entry dll_descriptor; 1154130812Smarcel char *p; 1155130812Smarcel static char dll_pathname[1024]; 1156130812Smarcel 1157130812Smarcel /* Read the descriptor of this newly-loaded library. */ 1158130812Smarcel dll_handle_address = read_register (ARG1_REGNUM); 1159130812Smarcel read_memory (dll_handle_address, (char *) &dll_descriptor, sizeof (dll_descriptor)); 1160130812Smarcel 1161130812Smarcel /* We can find a pointer to the dll's pathname within the descriptor. */ 1162130812Smarcel dll_pathname_address = (CORE_ADDR) dll_descriptor.name; 1163130812Smarcel 1164130812Smarcel /* Read the pathname, one byte at a time. */ 1165130812Smarcel p = dll_pathname; 1166130812Smarcel for (;;) 1167130812Smarcel { 1168130812Smarcel char b; 1169130812Smarcel read_memory (dll_pathname_address++, (char *) &b, 1); 1170130812Smarcel *p++ = b; 1171130812Smarcel if (b == '\0') 1172130812Smarcel break; 1173130812Smarcel } 1174130812Smarcel 1175130812Smarcel return dll_pathname; 1176130812Smarcel} 1177130812Smarcel 1178130812Smarcelchar * 1179130812Smarcelsom_solib_loaded_library_pathname (int pid) 1180130812Smarcel{ 1181130812Smarcel if (!som_solib_have_load_event (pid)) 1182130812Smarcel error ("Must have a load event to use this query"); 1183130812Smarcel 1184130812Smarcel return som_solib_library_pathname (pid); 1185130812Smarcel} 1186130812Smarcel 1187130812Smarcelchar * 1188130812Smarcelsom_solib_unloaded_library_pathname (int pid) 1189130812Smarcel{ 1190130812Smarcel if (!som_solib_have_unload_event (pid)) 1191130812Smarcel error ("Must have an unload event to use this query"); 1192130812Smarcel 1193130812Smarcel return som_solib_library_pathname (pid); 1194130812Smarcel} 1195130812Smarcel 1196130812Smarcelstatic void 1197130812Smarcelsom_solib_desire_dynamic_linker_symbols (void) 1198130812Smarcel{ 1199130812Smarcel struct objfile *objfile; 1200130812Smarcel struct unwind_table_entry *u; 1201130812Smarcel struct minimal_symbol *dld_msymbol; 1202130812Smarcel 1203130812Smarcel /* Do we already know the value of these symbols? If so, then 1204130812Smarcel we've no work to do. 1205130812Smarcel 1206130812Smarcel (If you add clauses to this test, be sure to likewise update the 1207130812Smarcel test within the loop.) 1208130812Smarcel */ 1209130812Smarcel if (dld_cache.is_valid) 1210130812Smarcel return; 1211130812Smarcel 1212130812Smarcel ALL_OBJFILES (objfile) 1213130812Smarcel { 1214130812Smarcel dld_msymbol = lookup_minimal_symbol ("shl_load", NULL, objfile); 1215130812Smarcel if (dld_msymbol != NULL) 1216130812Smarcel { 1217130812Smarcel dld_cache.load.address = SYMBOL_VALUE (dld_msymbol); 1218130812Smarcel dld_cache.load.unwind = find_unwind_entry (dld_cache.load.address); 1219130812Smarcel } 1220130812Smarcel 1221130812Smarcel dld_msymbol = lookup_minimal_symbol_solib_trampoline ("shl_load", 1222130812Smarcel objfile); 1223130812Smarcel if (dld_msymbol != NULL) 1224130812Smarcel { 1225130812Smarcel if (SYMBOL_TYPE (dld_msymbol) == mst_solib_trampoline) 1226130812Smarcel { 1227130812Smarcel u = find_unwind_entry (SYMBOL_VALUE (dld_msymbol)); 1228130812Smarcel if ((u != NULL) && (u->stub_unwind.stub_type == EXPORT)) 1229130812Smarcel { 1230130812Smarcel dld_cache.load_stub.address = SYMBOL_VALUE (dld_msymbol); 1231130812Smarcel dld_cache.load_stub.unwind = u; 1232130812Smarcel } 1233130812Smarcel } 1234130812Smarcel } 1235130812Smarcel 1236130812Smarcel dld_msymbol = lookup_minimal_symbol ("shl_unload", NULL, objfile); 1237130812Smarcel if (dld_msymbol != NULL) 1238130812Smarcel { 1239130812Smarcel dld_cache.unload.address = SYMBOL_VALUE (dld_msymbol); 1240130812Smarcel dld_cache.unload.unwind = find_unwind_entry (dld_cache.unload.address); 1241130812Smarcel 1242130812Smarcel /* ??rehrauer: I'm not sure exactly what this is, but it appears 1243130812Smarcel that on some HPUX 10.x versions, there's two unwind regions to 1244130812Smarcel cover the body of "shl_unload", the second being 4 bytes past 1245130812Smarcel the end of the first. This is a large hack to handle that 1246130812Smarcel case, but since I don't seem to have any legitimate way to 1247130812Smarcel look for this thing via the symbol table... 1248130812Smarcel */ 1249130812Smarcel if (dld_cache.unload.unwind != NULL) 1250130812Smarcel { 1251130812Smarcel u = find_unwind_entry (dld_cache.unload.unwind->region_end + 4); 1252130812Smarcel if (u != NULL) 1253130812Smarcel { 1254130812Smarcel dld_cache.unload2.address = u->region_start; 1255130812Smarcel dld_cache.unload2.unwind = u; 1256130812Smarcel } 1257130812Smarcel } 1258130812Smarcel } 1259130812Smarcel 1260130812Smarcel dld_msymbol = lookup_minimal_symbol_solib_trampoline ("shl_unload", 1261130812Smarcel objfile); 1262130812Smarcel if (dld_msymbol != NULL) 1263130812Smarcel { 1264130812Smarcel if (SYMBOL_TYPE (dld_msymbol) == mst_solib_trampoline) 1265130812Smarcel { 1266130812Smarcel u = find_unwind_entry (SYMBOL_VALUE (dld_msymbol)); 1267130812Smarcel if ((u != NULL) && (u->stub_unwind.stub_type == EXPORT)) 1268130812Smarcel { 1269130812Smarcel dld_cache.unload_stub.address = SYMBOL_VALUE (dld_msymbol); 1270130812Smarcel dld_cache.unload_stub.unwind = u; 1271130812Smarcel } 1272130812Smarcel } 1273130812Smarcel } 1274130812Smarcel 1275130812Smarcel /* Did we find everything we were looking for? If so, stop. */ 1276130812Smarcel if ((dld_cache.load.address != 0) 1277130812Smarcel && (dld_cache.load_stub.address != 0) 1278130812Smarcel && (dld_cache.unload.address != 0) 1279130812Smarcel && (dld_cache.unload_stub.address != 0)) 1280130812Smarcel { 1281130812Smarcel dld_cache.is_valid = 1; 1282130812Smarcel break; 1283130812Smarcel } 1284130812Smarcel } 1285130812Smarcel 1286130812Smarcel dld_cache.hook.unwind = find_unwind_entry (dld_cache.hook.address); 1287130812Smarcel dld_cache.hook_stub.unwind = find_unwind_entry (dld_cache.hook_stub.address); 1288130812Smarcel 1289130812Smarcel /* We're prepared not to find some of these symbols, which is why 1290130812Smarcel this function is a "desire" operation, and not a "require". 1291130812Smarcel */ 1292130812Smarcel} 1293130812Smarcel 1294130812Smarcelint 1295130812Smarcelsom_solib_in_dynamic_linker (int pid, CORE_ADDR pc) 1296130812Smarcel{ 1297130812Smarcel struct unwind_table_entry *u_pc; 1298130812Smarcel 1299130812Smarcel /* Are we in the dld itself? 1300130812Smarcel 1301130812Smarcel ??rehrauer: Large hack -- We'll assume that any address in a 1302130812Smarcel shared text region is the dld's text. This would obviously 1303130812Smarcel fall down if the user attached to a process, whose shlibs 1304130812Smarcel weren't mapped to a (writeable) private region. However, in 1305130812Smarcel that case the debugger probably isn't able to set the fundamental 1306130812Smarcel breakpoint in the dld callback anyways, so this hack should be 1307130812Smarcel safe. 1308130812Smarcel */ 1309130812Smarcel if ((pc & (CORE_ADDR) 0xc0000000) == (CORE_ADDR) 0xc0000000) 1310130812Smarcel return 1; 1311130812Smarcel 1312130812Smarcel /* Cache the address of some symbols that are part of the dynamic 1313130812Smarcel linker, if not already known. 1314130812Smarcel */ 1315130812Smarcel som_solib_desire_dynamic_linker_symbols (); 1316130812Smarcel 1317130812Smarcel /* Are we in the dld callback? Or its export stub? */ 1318130812Smarcel u_pc = find_unwind_entry (pc); 1319130812Smarcel if (u_pc == NULL) 1320130812Smarcel return 0; 1321130812Smarcel 1322130812Smarcel if ((u_pc == dld_cache.hook.unwind) || (u_pc == dld_cache.hook_stub.unwind)) 1323130812Smarcel return 1; 1324130812Smarcel 1325130812Smarcel /* Or the interface of the dld (i.e., "shl_load" or friends)? */ 1326130812Smarcel if ((u_pc == dld_cache.load.unwind) 1327130812Smarcel || (u_pc == dld_cache.unload.unwind) 1328130812Smarcel || (u_pc == dld_cache.unload2.unwind) 1329130812Smarcel || (u_pc == dld_cache.load_stub.unwind) 1330130812Smarcel || (u_pc == dld_cache.unload_stub.unwind)) 1331130812Smarcel return 1; 1332130812Smarcel 1333130812Smarcel /* Apparently this address isn't part of the dld's text. */ 1334130812Smarcel return 0; 1335130812Smarcel} 1336130812Smarcel 1337130812Smarcel 1338130812Smarcel/* Return the GOT value for the shared library in which ADDR belongs. If 1339130812Smarcel ADDR isn't in any known shared library, return zero. */ 1340130812Smarcel 1341130812SmarcelCORE_ADDR 1342130812Smarcelsom_solib_get_got_by_pc (CORE_ADDR addr) 1343130812Smarcel{ 1344130812Smarcel struct so_list *so_list = so_list_head; 1345130812Smarcel CORE_ADDR got_value = 0; 1346130812Smarcel 1347130812Smarcel while (so_list) 1348130812Smarcel { 1349130812Smarcel if (so_list->som_solib.text_addr <= addr 1350130812Smarcel && so_list->som_solib.text_end > addr) 1351130812Smarcel { 1352130812Smarcel got_value = so_list->som_solib.got_value; 1353130812Smarcel break; 1354130812Smarcel } 1355130812Smarcel so_list = so_list->next; 1356130812Smarcel } 1357130812Smarcel return got_value; 1358130812Smarcel} 1359130812Smarcel 1360130812Smarcel/* elz: 1361130812Smarcel Return the address of the handle of the shared library 1362130812Smarcel in which ADDR belongs. If 1363130812Smarcel ADDR isn't in any known shared library, return zero. */ 1364130812Smarcel/* this function is used in hppa_fix_call_dummy in hppa-tdep.c */ 1365130812Smarcel 1366130812SmarcelCORE_ADDR 1367130812Smarcelsom_solib_get_solib_by_pc (CORE_ADDR addr) 1368130812Smarcel{ 1369130812Smarcel struct so_list *so_list = so_list_head; 1370130812Smarcel 1371130812Smarcel while (so_list) 1372130812Smarcel { 1373130812Smarcel if (so_list->som_solib.text_addr <= addr 1374130812Smarcel && so_list->som_solib.text_end > addr) 1375130812Smarcel { 1376130812Smarcel break; 1377130812Smarcel } 1378130812Smarcel so_list = so_list->next; 1379130812Smarcel } 1380130812Smarcel if (so_list) 1381130812Smarcel return so_list->solib_addr; 1382130812Smarcel else 1383130812Smarcel return 0; 1384130812Smarcel} 1385130812Smarcel 1386130812Smarcel 1387130812Smarcelint 1388130812Smarcelsom_solib_section_offsets (struct objfile *objfile, 1389130812Smarcel struct section_offsets *offsets) 1390130812Smarcel{ 1391130812Smarcel struct so_list *so_list = so_list_head; 1392130812Smarcel 1393130812Smarcel while (so_list) 1394130812Smarcel { 1395130812Smarcel /* Oh what a pain! We need the offsets before so_list->objfile 1396130812Smarcel is valid. The BFDs will never match. Make a best guess. */ 1397130812Smarcel if (strstr (objfile->name, so_list->som_solib.name)) 1398130812Smarcel { 1399130812Smarcel asection *private_section; 1400130812Smarcel 1401130812Smarcel /* The text offset is easy. */ 1402130812Smarcel offsets->offsets[SECT_OFF_TEXT (objfile)] 1403130812Smarcel = (so_list->som_solib.text_addr 1404130812Smarcel - so_list->som_solib.text_link_addr); 1405130812Smarcel offsets->offsets[SECT_OFF_RODATA (objfile)] 1406130812Smarcel = ANOFFSET (offsets, SECT_OFF_TEXT (objfile)); 1407130812Smarcel 1408130812Smarcel /* We should look at presumed_dp in the SOM header, but 1409130812Smarcel that's not easily available. This should be OK though. */ 1410130812Smarcel private_section = bfd_get_section_by_name (objfile->obfd, 1411130812Smarcel "$PRIVATE$"); 1412130812Smarcel if (!private_section) 1413130812Smarcel { 1414130812Smarcel warning ("Unable to find $PRIVATE$ in shared library!"); 1415130812Smarcel offsets->offsets[SECT_OFF_DATA (objfile)] = 0; 1416130812Smarcel offsets->offsets[SECT_OFF_BSS (objfile)] = 0; 1417130812Smarcel return 1; 1418130812Smarcel } 1419130812Smarcel offsets->offsets[SECT_OFF_DATA (objfile)] 1420130812Smarcel = (so_list->som_solib.data_start - private_section->vma); 1421130812Smarcel offsets->offsets[SECT_OFF_BSS (objfile)] 1422130812Smarcel = ANOFFSET (offsets, SECT_OFF_DATA (objfile)); 1423130812Smarcel return 1; 1424130812Smarcel } 1425130812Smarcel so_list = so_list->next; 1426130812Smarcel } 1427130812Smarcel return 0; 1428130812Smarcel} 1429130812Smarcel 1430130812Smarcel/* Dump information about all the currently loaded shared libraries. */ 1431130812Smarcel 1432130812Smarcelstatic void 1433130812Smarcelsom_sharedlibrary_info_command (char *ignore, int from_tty) 1434130812Smarcel{ 1435130812Smarcel struct so_list *so_list = so_list_head; 1436130812Smarcel 1437130812Smarcel if (exec_bfd == NULL) 1438130812Smarcel { 1439130812Smarcel printf_unfiltered ("No executable file.\n"); 1440130812Smarcel return; 1441130812Smarcel } 1442130812Smarcel 1443130812Smarcel if (so_list == NULL) 1444130812Smarcel { 1445130812Smarcel printf_unfiltered ("No shared libraries loaded at this time.\n"); 1446130812Smarcel return; 1447130812Smarcel } 1448130812Smarcel 1449130812Smarcel printf_unfiltered ("Shared Object Libraries\n"); 1450130812Smarcel printf_unfiltered (" %-12s%-12s%-12s%-12s%-12s%-12s\n", 1451130812Smarcel " flags", " tstart", " tend", " dstart", " dend", " dlt"); 1452130812Smarcel while (so_list) 1453130812Smarcel { 1454130812Smarcel unsigned int flags; 1455130812Smarcel 1456130812Smarcel flags = so_list->som_solib.struct_version << 24; 1457130812Smarcel flags |= so_list->som_solib.bind_mode << 16; 1458130812Smarcel flags |= so_list->som_solib.library_version; 1459130812Smarcel printf_unfiltered ("%s", so_list->som_solib.name); 1460130812Smarcel if (so_list->objfile == NULL) 1461130812Smarcel printf_unfiltered (" (symbols not loaded)"); 1462130812Smarcel printf_unfiltered ("\n"); 1463130812Smarcel printf_unfiltered (" %-12s", local_hex_string_custom (flags, "08l")); 1464130812Smarcel printf_unfiltered ("%-12s", 1465130812Smarcel local_hex_string_custom (so_list->som_solib.text_addr, "08l")); 1466130812Smarcel printf_unfiltered ("%-12s", 1467130812Smarcel local_hex_string_custom (so_list->som_solib.text_end, "08l")); 1468130812Smarcel printf_unfiltered ("%-12s", 1469130812Smarcel local_hex_string_custom (so_list->som_solib.data_start, "08l")); 1470130812Smarcel printf_unfiltered ("%-12s", 1471130812Smarcel local_hex_string_custom (so_list->som_solib.data_end, "08l")); 1472130812Smarcel printf_unfiltered ("%-12s\n", 1473130812Smarcel local_hex_string_custom (so_list->som_solib.got_value, "08l")); 1474130812Smarcel so_list = so_list->next; 1475130812Smarcel } 1476130812Smarcel} 1477130812Smarcel 1478130812Smarcelstatic void 1479130812Smarcelsom_solib_sharedlibrary_command (char *args, int from_tty) 1480130812Smarcel{ 1481130812Smarcel dont_repeat (); 1482130812Smarcel som_solib_add (args, from_tty, (struct target_ops *) 0, 1); 1483130812Smarcel} 1484130812Smarcel 1485130812Smarcel 1486130812Smarcel 1487130812Smarcelchar * 1488130812Smarcelsom_solib_address (CORE_ADDR addr) 1489130812Smarcel{ 1490130812Smarcel struct so_list *so = so_list_head; 1491130812Smarcel 1492130812Smarcel while (so) 1493130812Smarcel { 1494130812Smarcel /* Is this address within this shlib's text range? If so, 1495130812Smarcel return the shlib's name. 1496130812Smarcel */ 1497130812Smarcel if ((addr >= so->som_solib.text_addr) && (addr <= so->som_solib.text_end)) 1498130812Smarcel return so->som_solib.name; 1499130812Smarcel 1500130812Smarcel /* Nope, keep looking... */ 1501130812Smarcel so = so->next; 1502130812Smarcel } 1503130812Smarcel 1504130812Smarcel /* No, we couldn't prove that the address is within a shlib. */ 1505130812Smarcel return NULL; 1506130812Smarcel} 1507130812Smarcel 1508130812Smarcel 1509130812Smarcelvoid 1510130812Smarcelsom_solib_restart (void) 1511130812Smarcel{ 1512130812Smarcel struct so_list *sl = so_list_head; 1513130812Smarcel 1514130812Smarcel /* Before the shlib info vanishes, use it to disable any breakpoints 1515130812Smarcel that may still be active in those shlibs. 1516130812Smarcel */ 1517130812Smarcel disable_breakpoints_in_shlibs (0); 1518130812Smarcel 1519130812Smarcel /* Discard all the shlib descriptors. 1520130812Smarcel */ 1521130812Smarcel while (sl) 1522130812Smarcel { 1523130812Smarcel struct so_list *next_sl = sl->next; 1524130812Smarcel xfree (sl); 1525130812Smarcel sl = next_sl; 1526130812Smarcel } 1527130812Smarcel so_list_head = NULL; 1528130812Smarcel 1529130812Smarcel som_solib_total_st_size = (LONGEST) 0; 1530130812Smarcel som_solib_st_size_threshold_exceeded = 0; 1531130812Smarcel 1532130812Smarcel dld_cache.is_valid = 0; 1533130812Smarcel 1534130812Smarcel dld_cache.hook.address = 0; 1535130812Smarcel dld_cache.hook.unwind = NULL; 1536130812Smarcel 1537130812Smarcel dld_cache.hook_stub.address = 0; 1538130812Smarcel dld_cache.hook_stub.unwind = NULL; 1539130812Smarcel 1540130812Smarcel dld_cache.load.address = 0; 1541130812Smarcel dld_cache.load.unwind = NULL; 1542130812Smarcel 1543130812Smarcel dld_cache.load_stub.address = 0; 1544130812Smarcel dld_cache.load_stub.unwind = NULL; 1545130812Smarcel 1546130812Smarcel dld_cache.unload.address = 0; 1547130812Smarcel dld_cache.unload.unwind = NULL; 1548130812Smarcel 1549130812Smarcel dld_cache.unload2.address = 0; 1550130812Smarcel dld_cache.unload2.unwind = NULL; 1551130812Smarcel 1552130812Smarcel dld_cache.unload_stub.address = 0; 1553130812Smarcel dld_cache.unload_stub.unwind = NULL; 1554130812Smarcel} 1555130812Smarcel 1556130812Smarcel 1557130812Smarcel/* LOCAL FUNCTION 1558130812Smarcel 1559130812Smarcel no_shared_libraries -- handle command to explicitly discard symbols 1560130812Smarcel from shared libraries. 1561130812Smarcel 1562130812Smarcel DESCRIPTION 1563130812Smarcel 1564130812Smarcel Implements the command "nosharedlibrary", which discards symbols 1565130812Smarcel that have been auto-loaded from shared libraries. Symbols from 1566130812Smarcel shared libraries that were added by explicit request of the user 1567130812Smarcel are not discarded. Also called from remote.c. */ 1568130812Smarcel 1569130812Smarcelvoid 1570130812Smarcelno_shared_libraries (char *ignored, int from_tty) 1571130812Smarcel{ 1572130812Smarcel /* FIXME */ 1573130812Smarcel} 1574130812Smarcel 1575130812Smarcel 1576130812Smarcelvoid 1577130812Smarcel_initialize_som_solib (void) 1578130812Smarcel{ 1579130812Smarcel add_com ("sharedlibrary", class_files, som_solib_sharedlibrary_command, 1580130812Smarcel "Load shared object library symbols for files matching REGEXP."); 1581130812Smarcel add_info ("sharedlibrary", som_sharedlibrary_info_command, 1582130812Smarcel "Status of loaded shared object libraries."); 1583130812Smarcel 1584130812Smarcel add_show_from_set 1585130812Smarcel (add_set_cmd ("auto-solib-add", class_support, var_boolean, 1586130812Smarcel (char *) &auto_solib_add, 1587130812Smarcel "Set autoloading of shared library symbols.\n\ 1588130812SmarcelIf \"on\", symbols from all shared object libraries will be loaded\n\ 1589130812Smarcelautomatically when the inferior begins execution, when the dynamic linker\n\ 1590130812Smarcelinforms gdb that a new library has been loaded, or when attaching to the\n\ 1591130812Smarcelinferior. Otherwise, symbols must be loaded manually, using `sharedlibrary'.", 1592130812Smarcel &setlist), 1593130812Smarcel &showlist); 1594130812Smarcel 1595130812Smarcel add_show_from_set 1596130812Smarcel (add_set_cmd ("auto-solib-limit", class_support, var_zinteger, 1597130812Smarcel (char *) &auto_solib_limit, 1598130812Smarcel "Set threshold (in Mb) for autoloading shared library symbols.\n\ 1599130812SmarcelWhen shared library autoloading is enabled, new libraries will be loaded\n\ 1600130812Smarcelonly until the total size of shared library symbols exceeds this\n\ 1601130812Smarcelthreshold in megabytes. Is ignored when using `sharedlibrary'.", 1602130812Smarcel &setlist), 1603130812Smarcel &showlist); 1604130812Smarcel 1605130812Smarcel /* ??rehrauer: On HP-UX, the kernel parameter MAXDSIZ limits how 1606130812Smarcel much data space a process can use. We ought to be reading 1607130812Smarcel MAXDSIZ and setting auto_solib_limit to some large fraction of 1608130812Smarcel that value. If not that, we maybe ought to be setting it smaller 1609130812Smarcel than the default for MAXDSIZ (that being 64Mb, I believe). 1610130812Smarcel However, [1] this threshold is only crudely approximated rather 1611130812Smarcel than actually measured, and [2] 50 Mbytes is too small for 1612130812Smarcel debugging gdb itself. Thus, the arbitrary 100 figure. */ 1613130812Smarcel auto_solib_limit = 100; /* Megabytes */ 1614130812Smarcel 1615130812Smarcel som_solib_restart (); 1616130812Smarcel} 1617130812Smarcel 1618130812Smarcel/* Get some HPUX-specific data from a shared lib. 1619130812Smarcel */ 1620130812SmarcelCORE_ADDR 1621130812Smarcelso_lib_thread_start_addr (struct so_list *so) 1622130812Smarcel{ 1623130812Smarcel return so->som_solib.tsd_start_addr; 1624130812Smarcel} 1625