198944Sobrien/* Handle OSF/1, Digital UNIX, and Tru64 shared libraries 298944Sobrien for GDB, the GNU Debugger. 398944Sobrien Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 498944Sobrien Free Software Foundation, Inc. 598944Sobrien 698944Sobrien This file is part of GDB. 798944Sobrien 898944Sobrien This program is free software; you can redistribute it and/or modify 998944Sobrien it under the terms of the GNU General Public License as published by 1098944Sobrien the Free Software Foundation; either version 2 of the License, or 1198944Sobrien (at your option) any later version. 1298944Sobrien 1398944Sobrien This program is distributed in the hope that it will be useful, 1498944Sobrien but WITHOUT ANY WARRANTY; without even the implied warranty of 1598944Sobrien MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1698944Sobrien GNU General Public License for more details. 1798944Sobrien 1898944Sobrien You should have received a copy of the GNU General Public License 1998944Sobrien along with this program; if not, write to the Free Software 2098944Sobrien Foundation, Inc., 59 Temple Place - Suite 330, 2198944Sobrien Boston, MA 02111-1307, USA. */ 2298944Sobrien 2398944Sobrien/* When handling shared libraries, GDB has to find out the pathnames 2498944Sobrien of all shared libraries that are currently loaded (to read in their 2598944Sobrien symbols) and where the shared libraries are loaded in memory 2698944Sobrien (to relocate them properly from their prelinked addresses to the 2798944Sobrien current load address). 2898944Sobrien 2998944Sobrien Under OSF/1 there are two possibilities to get at this information: 3098944Sobrien 3198944Sobrien 1) Peek around in the runtime loader structures. 3298944Sobrien These are not documented, and they are not defined in the system 3398944Sobrien header files. The definitions below were obtained by experimentation, 3498944Sobrien but they seem stable enough. 3598944Sobrien 3698944Sobrien 2) Use the libxproc.a library, which contains the equivalent ldr_* 3798944Sobrien routines. The library is documented in Tru64 5.x, but as of 5.1, it 3898944Sobrien only allows a process to examine itself. On earlier versions, it 3998944Sobrien may require that the GDB executable be dynamically linked and that 4098944Sobrien NAT_CLIBS include -lxproc -Wl,-expect_unresolved,ldr_process_context 4198944Sobrien for GDB and all applications that are using libgdb. 4298944Sobrien 4398944Sobrien We will use the peeking approach until libxproc.a works for other 4498944Sobrien processes. */ 4598944Sobrien 4698944Sobrien#include "defs.h" 4798944Sobrien 4898944Sobrien#include <sys/types.h> 4998944Sobrien#include <signal.h> 5098944Sobrien#include "gdb_string.h" 5198944Sobrien 5298944Sobrien#include "bfd.h" 5398944Sobrien#include "symtab.h" 5498944Sobrien#include "symfile.h" 5598944Sobrien#include "objfiles.h" 5698944Sobrien#include "target.h" 5798944Sobrien#include "inferior.h" 5898944Sobrien#include "solist.h" 5998944Sobrien 6098944Sobrien#ifdef USE_LDR_ROUTINES 6198944Sobrien# include <loader.h> 6298944Sobrien#endif 6398944Sobrien 6498944Sobrien#ifndef USE_LDR_ROUTINES 6598944Sobrien/* Definition of runtime loader structures, found by experimentation. */ 6698944Sobrien#define RLD_CONTEXT_ADDRESS 0x3ffc0000000 6798944Sobrien 6898944Sobrien/* Per-module information structure referenced by ldr_context_t.head. */ 6998944Sobrien 7098944Sobrientypedef struct 7198944Sobrien { 7298944Sobrien CORE_ADDR next; 7398944Sobrien CORE_ADDR previous; 7498944Sobrien CORE_ADDR unknown1; 7598944Sobrien CORE_ADDR module_name; 7698944Sobrien CORE_ADDR modinfo_addr; /* used by next_link_map_member() to detect 7798944Sobrien the end of the shared module list */ 7898944Sobrien long module_id; 7998944Sobrien CORE_ADDR unknown2; 8098944Sobrien CORE_ADDR unknown3; 8198944Sobrien long region_count; 8298944Sobrien CORE_ADDR regioninfo_addr; 8398944Sobrien } 8498944Sobrienldr_module_info_t; 8598944Sobrien 8698944Sobrien/* Per-region structure referenced by ldr_module_info_t.regioninfo_addr. */ 8798944Sobrien 8898944Sobrientypedef struct 8998944Sobrien { 9098944Sobrien long unknown1; 9198944Sobrien CORE_ADDR regionname_addr; 9298944Sobrien long protection; 9398944Sobrien CORE_ADDR vaddr; 9498944Sobrien CORE_ADDR mapaddr; 9598944Sobrien long size; 9698944Sobrien long unknown2[5]; 9798944Sobrien } 9898944Sobrienldr_region_info_t; 9998944Sobrien 10098944Sobrien/* Structure at RLD_CONTEXT_ADDRESS specifying the start and finish addresses 10198944Sobrien of the shared module list. */ 10298944Sobrien 10398944Sobrientypedef struct 10498944Sobrien { 10598944Sobrien CORE_ADDR unknown1; 10698944Sobrien CORE_ADDR unknown2; 10798944Sobrien CORE_ADDR head; 10898944Sobrien CORE_ADDR tail; 10998944Sobrien } 11098944Sobrienldr_context_t; 11198944Sobrien#endif /* !USE_LDR_ROUTINES */ 11298944Sobrien 11398944Sobrien/* Per-section information, stored in struct lm_info.secs. */ 11498944Sobrien 11598944Sobrienstruct lm_sec 11698944Sobrien { 11798944Sobrien CORE_ADDR offset; /* difference between default and actual 11898944Sobrien virtual addresses of section .name */ 11998944Sobrien CORE_ADDR nameaddr; /* address in inferior of section name */ 12098944Sobrien const char *name; /* name of section, null if not fetched */ 12198944Sobrien }; 12298944Sobrien 12398944Sobrien/* Per-module information, stored in struct so_list.lm_info. */ 12498944Sobrien 12598944Sobrienstruct lm_info 12698944Sobrien { 12798944Sobrien int isloader; /* whether the module is /sbin/loader */ 12898944Sobrien int nsecs; /* length of .secs */ 12998944Sobrien struct lm_sec secs[1]; /* variable-length array of sections, sorted 13098944Sobrien by name */ 13198944Sobrien }; 13298944Sobrien 13398944Sobrien/* Context for iterating through the inferior's shared module list. */ 13498944Sobrien 13598944Sobrienstruct read_map_ctxt 13698944Sobrien { 13798944Sobrien#ifdef USE_LDR_ROUTINES 13898944Sobrien ldr_process_t proc; 13998944Sobrien ldr_module_t next; 14098944Sobrien#else 14198944Sobrien CORE_ADDR next; /* next element in module list */ 14298944Sobrien CORE_ADDR tail; /* last element in module list */ 14398944Sobrien#endif 14498944Sobrien }; 14598944Sobrien 14698944Sobrien/* Forward declaration for this module's autoinit function. */ 14798944Sobrien 14898944Sobrienextern void _initialize_osf_solib (void); 14998944Sobrien 15098944Sobrien#ifdef USE_LDR_ROUTINES 15198944Sobrien# if 0 15298944Sobrien/* This routine is intended to be called by ldr_* routines to read memory from 15398944Sobrien the current target. Usage: 15498944Sobrien 15598944Sobrien ldr_process = ldr_core_process (); 15698944Sobrien ldr_set_core_reader (ldr_read_memory); 15798944Sobrien ldr_xdetach (ldr_process); 15898944Sobrien ldr_xattach (ldr_process); 15998944Sobrien 16098944Sobrien ldr_core_process() and ldr_read_memory() are neither documented nor 16198944Sobrien declared in system header files. They work with OSF/1 2.x, and they might 16298944Sobrien work with later versions as well. */ 16398944Sobrien 16498944Sobrienstatic int 16598944Sobrienldr_read_memory (CORE_ADDR memaddr, char *myaddr, int len, int readstring) 16698944Sobrien{ 16798944Sobrien int result; 16898944Sobrien char *buffer; 16998944Sobrien 17098944Sobrien if (readstring) 17198944Sobrien { 17298944Sobrien target_read_string (memaddr, &buffer, len, &result); 17398944Sobrien if (result == 0) 17498944Sobrien strcpy (myaddr, buffer); 17598944Sobrien xfree (buffer); 17698944Sobrien } 17798944Sobrien else 17898944Sobrien result = target_read_memory (memaddr, myaddr, len); 17998944Sobrien 18098944Sobrien if (result != 0) 18198944Sobrien result = -result; 18298944Sobrien return result; 18398944Sobrien} 18498944Sobrien# endif /* 0 */ 18598944Sobrien#endif /* USE_LDR_ROUTINES */ 18698944Sobrien 18798944Sobrien/* Comparison for qsort() and bsearch(): return -1, 0, or 1 according to 18898944Sobrien whether lm_sec *P1's name is lexically less than, equal to, or greater 18998944Sobrien than that of *P2. */ 19098944Sobrien 19198944Sobrienstatic int 19298944Sobrienlm_sec_cmp (const void *p1, const void *p2) 19398944Sobrien{ 19498944Sobrien const struct lm_sec *lms1 = p1, *lms2 = p2; 19598944Sobrien return strcmp (lms1->name, lms2->name); 19698944Sobrien} 19798944Sobrien 19898944Sobrien/* Sort LMI->secs so that osf_relocate_section_addresses() can binary-search 19998944Sobrien it. */ 20098944Sobrien 20198944Sobrienstatic void 20298944Sobrienlm_secs_sort (struct lm_info *lmi) 20398944Sobrien{ 20498944Sobrien qsort (lmi->secs, lmi->nsecs, sizeof *lmi->secs, lm_sec_cmp); 20598944Sobrien} 20698944Sobrien 20798944Sobrien/* Populate name fields of LMI->secs. */ 20898944Sobrien 20998944Sobrienstatic void 21098944Sobrienfetch_sec_names (struct lm_info *lmi) 21198944Sobrien{ 21298944Sobrien#ifndef USE_LDR_ROUTINES 21398944Sobrien int i, errcode; 21498944Sobrien struct lm_sec *lms; 21598944Sobrien char *name; 21698944Sobrien 21798944Sobrien for (i = 0; i < lmi->nsecs; i++) 21898944Sobrien { 21998944Sobrien lms = lmi->secs + i; 22098944Sobrien target_read_string (lms->nameaddr, &name, PATH_MAX, &errcode); 22198944Sobrien if (errcode != 0) 22298944Sobrien { 22398944Sobrien warning ("unable to read shared sec name at 0x%lx", lms->nameaddr); 22498944Sobrien name = xstrdup (""); 22598944Sobrien } 22698944Sobrien lms->name = name; 22798944Sobrien } 22898944Sobrien lm_secs_sort (lmi); 22998944Sobrien#endif 23098944Sobrien} 23198944Sobrien 23298944Sobrien/* target_so_ops callback. Adjust SEC's addresses after it's been mapped into 23398944Sobrien the process. */ 23498944Sobrien 23598944Sobrienstatic void 23698944Sobrienosf_relocate_section_addresses (struct so_list *so, 23798944Sobrien struct section_table *sec) 23898944Sobrien{ 23998944Sobrien struct lm_info *lmi; 24098944Sobrien struct lm_sec lms_key, *lms; 24198944Sobrien 24298944Sobrien /* Fetch SO's section names if we haven't done so already. */ 24398944Sobrien lmi = so->lm_info; 24498944Sobrien if (lmi->nsecs && !lmi->secs[0].name) 24598944Sobrien fetch_sec_names (lmi); 24698944Sobrien 24798944Sobrien /* Binary-search for offset information corresponding to SEC. */ 24898944Sobrien lms_key.name = sec->the_bfd_section->name; 24998944Sobrien lms = bsearch (&lms_key, lmi->secs, lmi->nsecs, sizeof *lms, lm_sec_cmp); 25098944Sobrien if (lms) 25198944Sobrien { 25298944Sobrien sec->addr += lms->offset; 25398944Sobrien sec->endaddr += lms->offset; 25498944Sobrien } 25598944Sobrien} 25698944Sobrien 25798944Sobrien/* target_so_ops callback. Free parts of SO allocated by this file. */ 25898944Sobrien 25998944Sobrienstatic void 26098944Sobrienosf_free_so (struct so_list *so) 26198944Sobrien{ 26298944Sobrien int i; 26398944Sobrien const char *name; 26498944Sobrien 26598944Sobrien for (i = 0; i < so->lm_info->nsecs; i++) 26698944Sobrien { 26798944Sobrien name = so->lm_info->secs[i].name; 26898944Sobrien if (name) 26998944Sobrien xfree ((void *) name); 27098944Sobrien } 27198944Sobrien xfree (so->lm_info); 27298944Sobrien} 27398944Sobrien 27498944Sobrien/* target_so_ops callback. Discard information accumulated by this file and 27598944Sobrien not freed by osf_free_so(). */ 27698944Sobrien 27798944Sobrienstatic void 27898944Sobrienosf_clear_solib (void) 27998944Sobrien{ 28098944Sobrien return; 28198944Sobrien} 28298944Sobrien 28398944Sobrien/* target_so_ops callback. Prepare to handle shared libraries after the 28498944Sobrien inferior process has been created but before it's executed any 28598944Sobrien instructions. 28698944Sobrien 28798944Sobrien For a statically bound executable, the inferior's first instruction is the 28898944Sobrien one at "_start", or a similar text label. No further processing is needed 28998944Sobrien in that case. 29098944Sobrien 29198944Sobrien For a dynamically bound executable, this first instruction is somewhere 29298944Sobrien in the rld, and the actual user executable is not yet mapped in. 29398944Sobrien We continue the inferior again, rld then maps in the actual user 29498944Sobrien executable and any needed shared libraries and then sends 29598944Sobrien itself a SIGTRAP. 29698944Sobrien 29798944Sobrien At that point we discover the names of all shared libraries and 29898944Sobrien read their symbols in. 29998944Sobrien 30098944Sobrien FIXME 30198944Sobrien 30298944Sobrien This code does not properly handle hitting breakpoints which the 30398944Sobrien user might have set in the rld itself. Proper handling would have 30498944Sobrien to check if the SIGTRAP happened due to a kill call. 30598944Sobrien 30698944Sobrien Also, what if child has exit()ed? Must exit loop somehow. */ 30798944Sobrien 30898944Sobrienstatic void 30998944Sobrienosf_solib_create_inferior_hook (void) 31098944Sobrien{ 31198944Sobrien /* Nothing to do for statically bound executables. */ 31298944Sobrien 31398944Sobrien if (symfile_objfile == NULL 31498944Sobrien || symfile_objfile->obfd == NULL 31598944Sobrien || ((bfd_get_file_flags (symfile_objfile->obfd) & DYNAMIC) == 0)) 31698944Sobrien return; 31798944Sobrien 31898944Sobrien /* Now run the target. It will eventually get a SIGTRAP, at 31998944Sobrien which point all of the libraries will have been mapped in and we 32098944Sobrien can go groveling around in the rld structures to find 32198944Sobrien out what we need to know about them. */ 32298944Sobrien 32398944Sobrien clear_proceed_status (); 324130803Smarcel stop_soon = STOP_QUIETLY; 32598944Sobrien stop_signal = TARGET_SIGNAL_0; 32698944Sobrien do 32798944Sobrien { 32898944Sobrien target_resume (minus_one_ptid, 0, stop_signal); 32998944Sobrien wait_for_inferior (); 33098944Sobrien } 33198944Sobrien while (stop_signal != TARGET_SIGNAL_TRAP); 33298944Sobrien 33398944Sobrien /* solib_add will call reinit_frame_cache. 33498944Sobrien But we are stopped in the runtime loader and we do not have symbols 33598944Sobrien for the runtime loader. So heuristic_proc_start will be called 33698944Sobrien and will put out an annoying warning. 337130803Smarcel Delaying the resetting of stop_soon until after symbol loading 33898944Sobrien suppresses the warning. */ 33998944Sobrien solib_add ((char *) 0, 0, (struct target_ops *) 0, auto_solib_add); 340130803Smarcel stop_soon = NO_STOP_QUIETLY; 34198944Sobrien 34298944Sobrien /* Enable breakpoints disabled (unnecessarily) by clear_solib(). */ 34398944Sobrien re_enable_breakpoints_in_shlibs (); 34498944Sobrien} 34598944Sobrien 34698944Sobrien/* target_so_ops callback. Do additional symbol handling, lookup, etc. after 34798944Sobrien symbols for a shared object have been loaded. */ 34898944Sobrien 34998944Sobrienstatic void 35098944Sobrienosf_special_symbol_handling (void) 35198944Sobrien{ 35298944Sobrien return; 35398944Sobrien} 35498944Sobrien 35598944Sobrien/* Initialize CTXT in preparation for iterating through the inferior's module 35698944Sobrien list using read_map(). Return success. */ 35798944Sobrien 35898944Sobrienstatic int 35998944Sobrienopen_map (struct read_map_ctxt *ctxt) 36098944Sobrien{ 36198944Sobrien#ifdef USE_LDR_ROUTINES 362130803Smarcel /* Note: As originally written, ldr_my_process() was used to obtain 363130803Smarcel the value for ctxt->proc. This is incorrect, however, since 364130803Smarcel ldr_my_process() retrieves the "unique identifier" associated 365130803Smarcel with the current process (i.e. GDB) and not the one being 366130803Smarcel debugged. Presumably, the pid of the process being debugged is 367130803Smarcel compatible with the "unique identifier" used by the ldr_ 368130803Smarcel routines, so we use that. */ 369130803Smarcel ctxt->proc = ptid_get_pid (inferior_ptid); 37098944Sobrien if (ldr_xattach (ctxt->proc) != 0) 37198944Sobrien return 0; 37298944Sobrien ctxt->next = LDR_NULL_MODULE; 37398944Sobrien#else 37498944Sobrien CORE_ADDR ldr_context_addr, prev, next; 37598944Sobrien ldr_context_t ldr_context; 37698944Sobrien 37798944Sobrien if (target_read_memory ((CORE_ADDR) RLD_CONTEXT_ADDRESS, 37898944Sobrien (char *) &ldr_context_addr, 37998944Sobrien sizeof (CORE_ADDR)) != 0) 38098944Sobrien return 0; 38198944Sobrien if (target_read_memory (ldr_context_addr, 38298944Sobrien (char *) &ldr_context, 38398944Sobrien sizeof (ldr_context_t)) != 0) 38498944Sobrien return 0; 38598944Sobrien ctxt->next = ldr_context.head; 38698944Sobrien ctxt->tail = ldr_context.tail; 38798944Sobrien#endif 38898944Sobrien return 1; 38998944Sobrien} 39098944Sobrien 39198944Sobrien/* Initialize SO to have module NAME, /sbin/loader indicator ISLOADR, and 39298944Sobrien space for NSECS sections. */ 39398944Sobrien 39498944Sobrienstatic void 39598944Sobrieninit_so (struct so_list *so, char *name, int isloader, int nsecs) 39698944Sobrien{ 39798944Sobrien int namelen, i; 39898944Sobrien 39998944Sobrien /* solib.c requires various fields to be initialized to 0. */ 40098944Sobrien memset (so, 0, sizeof *so); 40198944Sobrien 40298944Sobrien /* Copy the name. */ 40398944Sobrien namelen = strlen (name); 40498944Sobrien if (namelen >= SO_NAME_MAX_PATH_SIZE) 40598944Sobrien namelen = SO_NAME_MAX_PATH_SIZE - 1; 40698944Sobrien 40798944Sobrien memcpy (so->so_original_name, name, namelen); 40898944Sobrien so->so_original_name[namelen] = '\0'; 40998944Sobrien memcpy (so->so_name, so->so_original_name, namelen + 1); 41098944Sobrien 41198944Sobrien /* Allocate section space. */ 41298944Sobrien so->lm_info = xmalloc ((unsigned) &(((struct lm_info *)0)->secs) + 41398944Sobrien nsecs * sizeof *so->lm_info); 41498944Sobrien so->lm_info->isloader = isloader; 41598944Sobrien so->lm_info->nsecs = nsecs; 41698944Sobrien for (i = 0; i < nsecs; i++) 41798944Sobrien so->lm_info->secs[i].name = NULL; 41898944Sobrien} 41998944Sobrien 42098944Sobrien/* Initialize SO's section SECIDX with name address NAMEADDR, name string 42198944Sobrien NAME, default virtual address VADDR, and actual virtual address 42298944Sobrien MAPADDR. */ 42398944Sobrien 42498944Sobrienstatic void 42598944Sobrieninit_sec (struct so_list *so, int secidx, CORE_ADDR nameaddr, 42698944Sobrien const char *name, CORE_ADDR vaddr, CORE_ADDR mapaddr) 42798944Sobrien{ 42898944Sobrien struct lm_sec *lms; 42998944Sobrien 43098944Sobrien lms = so->lm_info->secs + secidx; 43198944Sobrien lms->nameaddr = nameaddr; 43298944Sobrien lms->name = name; 43398944Sobrien lms->offset = mapaddr - vaddr; 43498944Sobrien} 43598944Sobrien 43698944Sobrien/* If there are more elements starting at CTXT in inferior's module list, 43798944Sobrien store the next element in SO, advance CTXT to the next element, and return 43898944Sobrien 1, else return 0. */ 43998944Sobrien 44098944Sobrienstatic int 44198944Sobrienread_map (struct read_map_ctxt *ctxt, struct so_list *so) 44298944Sobrien{ 44398944Sobrien ldr_module_info_t minf; 44498944Sobrien ldr_region_info_t rinf; 44598944Sobrien 44698944Sobrien#ifdef USE_LDR_ROUTINES 44798944Sobrien size_t size; 44898944Sobrien ldr_region_t i; 44998944Sobrien 45098944Sobrien /* Retrieve the next element. */ 45198944Sobrien if (ldr_next_module (ctxt->proc, &ctxt->next) != 0) 45298944Sobrien return 0; 45398944Sobrien if (ctxt->next == LDR_NULL_MODULE) 45498944Sobrien return 0; 45598944Sobrien if (ldr_inq_module (ctxt->proc, ctxt->next, &minf, sizeof minf, &size) != 0) 45698944Sobrien return 0; 45798944Sobrien 45898944Sobrien /* Initialize the module name and section count. */ 45998944Sobrien init_so (so, minf.lmi_name, 0, minf.lmi_nregion); 46098944Sobrien 46198944Sobrien /* Retrieve section names and offsets. */ 46298944Sobrien for (i = 0; i < minf.lmi_nregion; i++) 46398944Sobrien { 46498944Sobrien if (ldr_inq_region (ctxt->proc, ctxt->next, i, &rinf, 46598944Sobrien sizeof rinf, &size) != 0) 46698944Sobrien goto err; 46798944Sobrien init_sec (so, (int) i, 0, xstrdup (rinf.lri_name), 46898944Sobrien (CORE_ADDR) rinf.lri_vaddr, (CORE_ADDR) rinf.lri_mapaddr); 46998944Sobrien } 47098944Sobrien lm_secs_sort (so->lm_info); 47198944Sobrien#else 47298944Sobrien char *name; 47398944Sobrien int errcode, i; 47498944Sobrien 47598944Sobrien /* Retrieve the next element. */ 47698944Sobrien if (!ctxt->next) 47798944Sobrien return 0; 47898944Sobrien if (target_read_memory (ctxt->next, (char *) &minf, sizeof minf) != 0) 47998944Sobrien return 0; 48098944Sobrien if (ctxt->next == ctxt->tail) 48198944Sobrien ctxt->next = 0; 48298944Sobrien else 48398944Sobrien ctxt->next = minf.next; 48498944Sobrien 48598944Sobrien /* Initialize the module name and section count. */ 48698944Sobrien target_read_string (minf.module_name, &name, PATH_MAX, &errcode); 48798944Sobrien if (errcode != 0) 48898944Sobrien return 0; 48998944Sobrien init_so (so, name, !minf.modinfo_addr, minf.region_count); 49098944Sobrien xfree (name); 49198944Sobrien 49298944Sobrien /* Retrieve section names and offsets. */ 49398944Sobrien for (i = 0; i < minf.region_count; i++) 49498944Sobrien { 49598944Sobrien if (target_read_memory (minf.regioninfo_addr + i * sizeof rinf, 49698944Sobrien (char *) &rinf, sizeof rinf) != 0) 49798944Sobrien goto err; 49898944Sobrien init_sec (so, i, rinf.regionname_addr, NULL, rinf.vaddr, rinf.mapaddr); 49998944Sobrien } 50098944Sobrien#endif /* !USE_LDR_ROUTINES */ 50198944Sobrien return 1; 50298944Sobrien 50398944Sobrien err: 50498944Sobrien osf_free_so (so); 50598944Sobrien return 0; 50698944Sobrien} 50798944Sobrien 50898944Sobrien/* Free resources allocated by open_map (CTXT). */ 50998944Sobrien 51098944Sobrienstatic void 51198944Sobrienclose_map (struct read_map_ctxt *ctxt) 51298944Sobrien{ 51398944Sobrien#ifdef USE_LDR_ROUTINES 51498944Sobrien ldr_xdetach (ctxt->proc); 51598944Sobrien#endif 51698944Sobrien} 51798944Sobrien 51898944Sobrien/* target_so_ops callback. Return a list of shared objects currently loaded 51998944Sobrien in the inferior. */ 52098944Sobrien 52198944Sobrienstatic struct so_list * 52298944Sobrienosf_current_sos (void) 52398944Sobrien{ 52498944Sobrien struct so_list *head = NULL, *tail, *newtail, so; 52598944Sobrien struct read_map_ctxt ctxt; 52698944Sobrien int skipped_main; 52798944Sobrien 52898944Sobrien if (!open_map (&ctxt)) 52998944Sobrien return NULL; 53098944Sobrien 53198944Sobrien /* Read subsequent elements. */ 53298944Sobrien for (skipped_main = 0;;) 53398944Sobrien { 53498944Sobrien if (!read_map (&ctxt, &so)) 53598944Sobrien break; 53698944Sobrien 53798944Sobrien /* Skip the main program module, which is first in the list after 53898944Sobrien /sbin/loader. */ 53998944Sobrien if (!so.lm_info->isloader && !skipped_main) 54098944Sobrien { 54198944Sobrien osf_free_so (&so); 54298944Sobrien skipped_main = 1; 54398944Sobrien continue; 54498944Sobrien } 54598944Sobrien 54698944Sobrien newtail = xmalloc (sizeof *newtail); 54798944Sobrien if (!head) 54898944Sobrien head = newtail; 54998944Sobrien else 55098944Sobrien tail->next = newtail; 55198944Sobrien tail = newtail; 55298944Sobrien 55398944Sobrien memcpy (tail, &so, sizeof so); 55498944Sobrien tail->next = NULL; 55598944Sobrien } 55698944Sobrien 55798944Sobrien done: 55898944Sobrien close_map (&ctxt); 55998944Sobrien return head; 56098944Sobrien} 56198944Sobrien 56298944Sobrien/* target_so_ops callback. Attempt to locate and open the main symbol 56398944Sobrien file. */ 56498944Sobrien 56598944Sobrienstatic int 56698944Sobrienosf_open_symbol_file_object (void *from_ttyp) 56798944Sobrien{ 56898944Sobrien struct read_map_ctxt ctxt; 56998944Sobrien struct so_list so; 57098944Sobrien int found; 57198944Sobrien 57298944Sobrien if (symfile_objfile) 57398944Sobrien if (!query ("Attempt to reload symbols from process? ")) 57498944Sobrien return 0; 57598944Sobrien 57698944Sobrien /* The first module after /sbin/loader is the main program. */ 57798944Sobrien if (!open_map (&ctxt)) 57898944Sobrien return 0; 57998944Sobrien for (found = 0; !found;) 58098944Sobrien { 58198944Sobrien if (!read_map (&ctxt, &so)) 58298944Sobrien break; 58398944Sobrien found = !so.lm_info->isloader; 58498944Sobrien osf_free_so (&so); 58598944Sobrien } 58698944Sobrien close_map (&ctxt); 58798944Sobrien 58898944Sobrien if (found) 58998944Sobrien symbol_file_add_main (so.so_name, *(int *) from_ttyp); 59098944Sobrien return found; 59198944Sobrien} 59298944Sobrien 59398944Sobrien/* target_so_ops callback. Return whether PC is in the dynamic linker. */ 59498944Sobrien 59598944Sobrienstatic int 59698944Sobrienosf_in_dynsym_resolve_code (CORE_ADDR pc) 59798944Sobrien{ 59898944Sobrien /* This function currently always return False. This is a temporary 59998944Sobrien solution which only consequence is to introduce a minor incovenience 60098944Sobrien for the user: When stepping inside a subprogram located in a shared 60198944Sobrien library, gdb might stop inside the dynamic loader code instead of 60298944Sobrien inside the subprogram itself. See the explanations in infrun.c about 60398944Sobrien the IN_SOLIB_DYNSYM_RESOLVE_CODE macro for more details. */ 60498944Sobrien return 0; 60598944Sobrien} 60698944Sobrien 60798944Sobrienstatic struct target_so_ops osf_so_ops; 60898944Sobrien 60998944Sobrienvoid 61098944Sobrien_initialize_osf_solib (void) 61198944Sobrien{ 61298944Sobrien osf_so_ops.relocate_section_addresses = osf_relocate_section_addresses; 61398944Sobrien osf_so_ops.free_so = osf_free_so; 61498944Sobrien osf_so_ops.clear_solib = osf_clear_solib; 61598944Sobrien osf_so_ops.solib_create_inferior_hook = osf_solib_create_inferior_hook; 61698944Sobrien osf_so_ops.special_symbol_handling = osf_special_symbol_handling; 61798944Sobrien osf_so_ops.current_sos = osf_current_sos; 61898944Sobrien osf_so_ops.open_symbol_file_object = osf_open_symbol_file_object; 61998944Sobrien osf_so_ops.in_dynsym_resolve_code = osf_in_dynsym_resolve_code; 62098944Sobrien 62198944Sobrien /* FIXME: Don't do this here. *_gdbarch_init() should set so_ops. */ 62298944Sobrien current_target_so_ops = &osf_so_ops; 62398944Sobrien} 624