198944Sobrien/* Handle SVR4 shared libraries for GDB, the GNU Debugger. 2130803Smarcel 3130803Smarcel Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 4130803Smarcel 2000, 2001, 2003, 2004 598944Sobrien Free Software Foundation, Inc. 698944Sobrien 798944Sobrien This file is part of GDB. 898944Sobrien 998944Sobrien This program is free software; you can redistribute it and/or modify 1098944Sobrien it under the terms of the GNU General Public License as published by 1198944Sobrien the Free Software Foundation; either version 2 of the License, or 1298944Sobrien (at your option) any later version. 1398944Sobrien 1498944Sobrien This program is distributed in the hope that it will be useful, 1598944Sobrien but WITHOUT ANY WARRANTY; without even the implied warranty of 1698944Sobrien MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1798944Sobrien GNU General Public License for more details. 1898944Sobrien 1998944Sobrien You should have received a copy of the GNU General Public License 2098944Sobrien along with this program; if not, write to the Free Software 2198944Sobrien Foundation, Inc., 59 Temple Place - Suite 330, 2298944Sobrien Boston, MA 02111-1307, USA. */ 2398944Sobrien 2498944Sobrien#include "defs.h" 2598944Sobrien 2698944Sobrien#include "elf/external.h" 2798944Sobrien#include "elf/common.h" 2898944Sobrien#include "elf/mips.h" 2998944Sobrien 3098944Sobrien#include "symtab.h" 3198944Sobrien#include "bfd.h" 3298944Sobrien#include "symfile.h" 3398944Sobrien#include "objfiles.h" 3498944Sobrien#include "gdbcore.h" 3598944Sobrien#include "target.h" 3698944Sobrien#include "inferior.h" 3798944Sobrien 3898944Sobrien#include "solist.h" 3998944Sobrien#include "solib-svr4.h" 4098944Sobrien 41130803Smarcel#include "bfd-target.h" 42130803Smarcel#include "exec.h" 43130803Smarcel 4498944Sobrien#ifndef SVR4_FETCH_LINK_MAP_OFFSETS 4598944Sobrien#define SVR4_FETCH_LINK_MAP_OFFSETS() svr4_fetch_link_map_offsets () 4698944Sobrien#endif 4798944Sobrien 4898944Sobrienstatic struct link_map_offsets *svr4_fetch_link_map_offsets (void); 4998944Sobrienstatic struct link_map_offsets *legacy_fetch_link_map_offsets (void); 50130803Smarcelstatic int svr4_have_link_map_offsets (void); 5198944Sobrien 5298944Sobrien/* fetch_link_map_offsets_gdbarch_data is a handle used to obtain the 5398944Sobrien architecture specific link map offsets fetching function. */ 5498944Sobrien 5598944Sobrienstatic struct gdbarch_data *fetch_link_map_offsets_gdbarch_data; 5698944Sobrien 5798944Sobrien/* legacy_svr4_fetch_link_map_offsets_hook is a pointer to a function 5898944Sobrien which is used to fetch link map offsets. It will only be set 5998944Sobrien by solib-legacy.c, if at all. */ 6098944Sobrien 6198944Sobrienstruct link_map_offsets *(*legacy_svr4_fetch_link_map_offsets_hook)(void) = 0; 6298944Sobrien 6398944Sobrien/* Link map info to include in an allocated so_list entry */ 6498944Sobrien 6598944Sobrienstruct lm_info 6698944Sobrien { 6798944Sobrien /* Pointer to copy of link map from inferior. The type is char * 6898944Sobrien rather than void *, so that we may use byte offsets to find the 6998944Sobrien various fields without the need for a cast. */ 7098944Sobrien char *lm; 7198944Sobrien }; 7298944Sobrien 7398944Sobrien/* On SVR4 systems, a list of symbols in the dynamic linker where 7498944Sobrien GDB can try to place a breakpoint to monitor shared library 7598944Sobrien events. 7698944Sobrien 7798944Sobrien If none of these symbols are found, or other errors occur, then 7898944Sobrien SVR4 systems will fall back to using a symbol as the "startup 7998944Sobrien mapping complete" breakpoint address. */ 8098944Sobrien 8198944Sobrienstatic char *solib_break_names[] = 8298944Sobrien{ 8398944Sobrien "r_debug_state", 8498944Sobrien "_r_debug_state", 8598944Sobrien "_dl_debug_state", 8698944Sobrien "rtld_db_dlactivity", 8798944Sobrien "_rtld_debug_state", 88130803Smarcel 89130803Smarcel /* On the 64-bit PowerPC, the linker symbol with the same name as 90130803Smarcel the C function points to a function descriptor, not to the entry 91130803Smarcel point. The linker symbol whose name is the C function name 92130803Smarcel prefixed with a '.' points to the function's entry point. So 93130803Smarcel when we look through this table, we ignore symbols that point 94130803Smarcel into the data section (thus skipping the descriptor's symbol), 95130803Smarcel and eventually try this one, giving us the real entry point 96130803Smarcel address. */ 97209867Snwhitehorn ".r_debug_state", 98130803Smarcel "._dl_debug_state", 99130803Smarcel 10098944Sobrien NULL 10198944Sobrien}; 10298944Sobrien 10398944Sobrien#define BKPT_AT_SYMBOL 1 10498944Sobrien 10598944Sobrien#if defined (BKPT_AT_SYMBOL) 10698944Sobrienstatic char *bkpt_names[] = 10798944Sobrien{ 10898944Sobrien#ifdef SOLIB_BKPT_NAME 10998944Sobrien SOLIB_BKPT_NAME, /* Prefer configured name if it exists. */ 11098944Sobrien#endif 11198944Sobrien "_start", 112130803Smarcel "__start", 11398944Sobrien "main", 11498944Sobrien NULL 11598944Sobrien}; 11698944Sobrien#endif 11798944Sobrien 11898944Sobrienstatic char *main_name_list[] = 11998944Sobrien{ 12098944Sobrien "main_$main", 12198944Sobrien NULL 12298944Sobrien}; 12398944Sobrien 124130803Smarcel/* Macro to extract an address from a solib structure. When GDB is 125130803Smarcel configured for some 32-bit targets (e.g. Solaris 2.7 sparc), BFD is 126130803Smarcel configured to handle 64-bit targets, so CORE_ADDR is 64 bits. We 127130803Smarcel have to extract only the significant bits of addresses to get the 128130803Smarcel right address when accessing the core file BFD. 12998944Sobrien 130130803Smarcel Assume that the address is unsigned. */ 131130803Smarcel 13298944Sobrien#define SOLIB_EXTRACT_ADDRESS(MEMBER) \ 133130803Smarcel extract_unsigned_integer (&(MEMBER), sizeof (MEMBER)) 13498944Sobrien 13598944Sobrien/* local data declarations */ 13698944Sobrien 13798944Sobrien/* link map access functions */ 13898944Sobrien 13998944Sobrienstatic CORE_ADDR 14098944SobrienLM_ADDR (struct so_list *so) 14198944Sobrien{ 14298944Sobrien struct link_map_offsets *lmo = SVR4_FETCH_LINK_MAP_OFFSETS (); 14398944Sobrien 14498944Sobrien return (CORE_ADDR) extract_signed_integer (so->lm_info->lm + lmo->l_addr_offset, 14598944Sobrien lmo->l_addr_size); 14698944Sobrien} 14798944Sobrien 14898944Sobrienstatic CORE_ADDR 14998944SobrienLM_NEXT (struct so_list *so) 15098944Sobrien{ 15198944Sobrien struct link_map_offsets *lmo = SVR4_FETCH_LINK_MAP_OFFSETS (); 15298944Sobrien 153130803Smarcel /* Assume that the address is unsigned. */ 154130803Smarcel return extract_unsigned_integer (so->lm_info->lm + lmo->l_next_offset, 155130803Smarcel lmo->l_next_size); 15698944Sobrien} 15798944Sobrien 15898944Sobrienstatic CORE_ADDR 15998944SobrienLM_NAME (struct so_list *so) 16098944Sobrien{ 16198944Sobrien struct link_map_offsets *lmo = SVR4_FETCH_LINK_MAP_OFFSETS (); 16298944Sobrien 163130803Smarcel /* Assume that the address is unsigned. */ 164130803Smarcel return extract_unsigned_integer (so->lm_info->lm + lmo->l_name_offset, 165130803Smarcel lmo->l_name_size); 16698944Sobrien} 16798944Sobrien 16898944Sobrienstatic int 16998944SobrienIGNORE_FIRST_LINK_MAP_ENTRY (struct so_list *so) 17098944Sobrien{ 17198944Sobrien struct link_map_offsets *lmo = SVR4_FETCH_LINK_MAP_OFFSETS (); 17298944Sobrien 173130803Smarcel /* Assume that the address is unsigned. */ 174130803Smarcel return extract_unsigned_integer (so->lm_info->lm + lmo->l_prev_offset, 175130803Smarcel lmo->l_prev_size) == 0; 17698944Sobrien} 17798944Sobrien 17898944Sobrienstatic CORE_ADDR debug_base; /* Base of dynamic linker structures */ 17998944Sobrienstatic CORE_ADDR breakpoint_addr; /* Address where end bkpt is set */ 18098944Sobrien 18198944Sobrien/* Local function prototypes */ 18298944Sobrien 18398944Sobrienstatic int match_main (char *); 18498944Sobrien 185130803Smarcelstatic CORE_ADDR bfd_lookup_symbol (bfd *, char *, flagword); 18698944Sobrien 18798944Sobrien/* 18898944Sobrien 18998944Sobrien LOCAL FUNCTION 19098944Sobrien 19198944Sobrien bfd_lookup_symbol -- lookup the value for a specific symbol 19298944Sobrien 19398944Sobrien SYNOPSIS 19498944Sobrien 195130803Smarcel CORE_ADDR bfd_lookup_symbol (bfd *abfd, char *symname, flagword sect_flags) 19698944Sobrien 19798944Sobrien DESCRIPTION 19898944Sobrien 19998944Sobrien An expensive way to lookup the value of a single symbol for 20098944Sobrien bfd's that are only temporary anyway. This is used by the 20198944Sobrien shared library support to find the address of the debugger 20298944Sobrien interface structures in the shared library. 20398944Sobrien 204130803Smarcel If SECT_FLAGS is non-zero, only match symbols in sections whose 205130803Smarcel flags include all those in SECT_FLAGS. 206130803Smarcel 20798944Sobrien Note that 0 is specifically allowed as an error return (no 20898944Sobrien such symbol). 20998944Sobrien */ 21098944Sobrien 21198944Sobrienstatic CORE_ADDR 212130803Smarcelbfd_lookup_symbol (bfd *abfd, char *symname, flagword sect_flags) 21398944Sobrien{ 21498944Sobrien long storage_needed; 21598944Sobrien asymbol *sym; 21698944Sobrien asymbol **symbol_table; 21798944Sobrien unsigned int number_of_symbols; 21898944Sobrien unsigned int i; 21998944Sobrien struct cleanup *back_to; 22098944Sobrien CORE_ADDR symaddr = 0; 22198944Sobrien 22298944Sobrien storage_needed = bfd_get_symtab_upper_bound (abfd); 22398944Sobrien 22498944Sobrien if (storage_needed > 0) 22598944Sobrien { 22698944Sobrien symbol_table = (asymbol **) xmalloc (storage_needed); 227130803Smarcel back_to = make_cleanup (xfree, symbol_table); 22898944Sobrien number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table); 22998944Sobrien 23098944Sobrien for (i = 0; i < number_of_symbols; i++) 23198944Sobrien { 23298944Sobrien sym = *symbol_table++; 233130803Smarcel if (strcmp (sym->name, symname) == 0 234130803Smarcel && (sym->section->flags & sect_flags) == sect_flags) 23598944Sobrien { 23698944Sobrien /* Bfd symbols are section relative. */ 23798944Sobrien symaddr = sym->value + sym->section->vma; 23898944Sobrien break; 23998944Sobrien } 24098944Sobrien } 24198944Sobrien do_cleanups (back_to); 24298944Sobrien } 24398944Sobrien 24498944Sobrien if (symaddr) 24598944Sobrien return symaddr; 24698944Sobrien 24798944Sobrien /* On FreeBSD, the dynamic linker is stripped by default. So we'll 24898944Sobrien have to check the dynamic string table too. */ 24998944Sobrien 25098944Sobrien storage_needed = bfd_get_dynamic_symtab_upper_bound (abfd); 25198944Sobrien 25298944Sobrien if (storage_needed > 0) 25398944Sobrien { 25498944Sobrien symbol_table = (asymbol **) xmalloc (storage_needed); 255130803Smarcel back_to = make_cleanup (xfree, symbol_table); 25698944Sobrien number_of_symbols = bfd_canonicalize_dynamic_symtab (abfd, symbol_table); 25798944Sobrien 25898944Sobrien for (i = 0; i < number_of_symbols; i++) 25998944Sobrien { 26098944Sobrien sym = *symbol_table++; 261130803Smarcel 262130803Smarcel if (strcmp (sym->name, symname) == 0 263130803Smarcel && (sym->section->flags & sect_flags) == sect_flags) 26498944Sobrien { 26598944Sobrien /* Bfd symbols are section relative. */ 26698944Sobrien symaddr = sym->value + sym->section->vma; 26798944Sobrien break; 26898944Sobrien } 26998944Sobrien } 27098944Sobrien do_cleanups (back_to); 27198944Sobrien } 27298944Sobrien 27398944Sobrien return symaddr; 27498944Sobrien} 27598944Sobrien 27698944Sobrien#ifdef HANDLE_SVR4_EXEC_EMULATORS 27798944Sobrien 27898944Sobrien/* 27998944Sobrien Solaris BCP (the part of Solaris which allows it to run SunOS4 28098944Sobrien a.out files) throws in another wrinkle. Solaris does not fill 28198944Sobrien in the usual a.out link map structures when running BCP programs, 28298944Sobrien the only way to get at them is via groping around in the dynamic 28398944Sobrien linker. 28498944Sobrien The dynamic linker and it's structures are located in the shared 28598944Sobrien C library, which gets run as the executable's "interpreter" by 28698944Sobrien the kernel. 28798944Sobrien 28898944Sobrien Note that we can assume nothing about the process state at the time 28998944Sobrien we need to find these structures. We may be stopped on the first 29098944Sobrien instruction of the interpreter (C shared library), the first 29198944Sobrien instruction of the executable itself, or somewhere else entirely 29298944Sobrien (if we attached to the process for example). 29398944Sobrien */ 29498944Sobrien 29598944Sobrienstatic char *debug_base_symbols[] = 29698944Sobrien{ 29798944Sobrien "r_debug", /* Solaris 2.3 */ 29898944Sobrien "_r_debug", /* Solaris 2.1, 2.2 */ 29998944Sobrien NULL 30098944Sobrien}; 30198944Sobrien 30298944Sobrienstatic int look_for_base (int, CORE_ADDR); 30398944Sobrien 30498944Sobrien/* 30598944Sobrien 30698944Sobrien LOCAL FUNCTION 30798944Sobrien 30898944Sobrien look_for_base -- examine file for each mapped address segment 30998944Sobrien 31098944Sobrien SYNOPSYS 31198944Sobrien 31298944Sobrien static int look_for_base (int fd, CORE_ADDR baseaddr) 31398944Sobrien 31498944Sobrien DESCRIPTION 31598944Sobrien 31698944Sobrien This function is passed to proc_iterate_over_mappings, which 31798944Sobrien causes it to get called once for each mapped address space, with 31898944Sobrien an open file descriptor for the file mapped to that space, and the 31998944Sobrien base address of that mapped space. 32098944Sobrien 32198944Sobrien Our job is to find the debug base symbol in the file that this 32298944Sobrien fd is open on, if it exists, and if so, initialize the dynamic 32398944Sobrien linker structure base address debug_base. 32498944Sobrien 32598944Sobrien Note that this is a computationally expensive proposition, since 32698944Sobrien we basically have to open a bfd on every call, so we specifically 32798944Sobrien avoid opening the exec file. 32898944Sobrien */ 32998944Sobrien 33098944Sobrienstatic int 33198944Sobrienlook_for_base (int fd, CORE_ADDR baseaddr) 33298944Sobrien{ 33398944Sobrien bfd *interp_bfd; 33498944Sobrien CORE_ADDR address = 0; 33598944Sobrien char **symbolp; 33698944Sobrien 33798944Sobrien /* If the fd is -1, then there is no file that corresponds to this 33898944Sobrien mapped memory segment, so skip it. Also, if the fd corresponds 33998944Sobrien to the exec file, skip it as well. */ 34098944Sobrien 34198944Sobrien if (fd == -1 34298944Sobrien || (exec_bfd != NULL 34398944Sobrien && fdmatch (fileno ((FILE *) (exec_bfd->iostream)), fd))) 34498944Sobrien { 34598944Sobrien return (0); 34698944Sobrien } 34798944Sobrien 34898944Sobrien /* Try to open whatever random file this fd corresponds to. Note that 34998944Sobrien we have no way currently to find the filename. Don't gripe about 35098944Sobrien any problems we might have, just fail. */ 35198944Sobrien 35298944Sobrien if ((interp_bfd = bfd_fdopenr ("unnamed", gnutarget, fd)) == NULL) 35398944Sobrien { 35498944Sobrien return (0); 35598944Sobrien } 35698944Sobrien if (!bfd_check_format (interp_bfd, bfd_object)) 35798944Sobrien { 35898944Sobrien /* FIXME-leak: on failure, might not free all memory associated with 35998944Sobrien interp_bfd. */ 36098944Sobrien bfd_close (interp_bfd); 36198944Sobrien return (0); 36298944Sobrien } 36398944Sobrien 36498944Sobrien /* Now try to find our debug base symbol in this file, which we at 36598944Sobrien least know to be a valid ELF executable or shared library. */ 36698944Sobrien 36798944Sobrien for (symbolp = debug_base_symbols; *symbolp != NULL; symbolp++) 36898944Sobrien { 369130803Smarcel address = bfd_lookup_symbol (interp_bfd, *symbolp, 0); 37098944Sobrien if (address != 0) 37198944Sobrien { 37298944Sobrien break; 37398944Sobrien } 37498944Sobrien } 37598944Sobrien if (address == 0) 37698944Sobrien { 37798944Sobrien /* FIXME-leak: on failure, might not free all memory associated with 37898944Sobrien interp_bfd. */ 37998944Sobrien bfd_close (interp_bfd); 38098944Sobrien return (0); 38198944Sobrien } 38298944Sobrien 38398944Sobrien /* Eureka! We found the symbol. But now we may need to relocate it 38498944Sobrien by the base address. If the symbol's value is less than the base 38598944Sobrien address of the shared library, then it hasn't yet been relocated 38698944Sobrien by the dynamic linker, and we have to do it ourself. FIXME: Note 38798944Sobrien that we make the assumption that the first segment that corresponds 38898944Sobrien to the shared library has the base address to which the library 38998944Sobrien was relocated. */ 39098944Sobrien 39198944Sobrien if (address < baseaddr) 39298944Sobrien { 39398944Sobrien address += baseaddr; 39498944Sobrien } 39598944Sobrien debug_base = address; 39698944Sobrien /* FIXME-leak: on failure, might not free all memory associated with 39798944Sobrien interp_bfd. */ 39898944Sobrien bfd_close (interp_bfd); 39998944Sobrien return (1); 40098944Sobrien} 40198944Sobrien#endif /* HANDLE_SVR4_EXEC_EMULATORS */ 40298944Sobrien 40398944Sobrien/* 40498944Sobrien 40598944Sobrien LOCAL FUNCTION 40698944Sobrien 40798944Sobrien elf_locate_base -- locate the base address of dynamic linker structs 40898944Sobrien for SVR4 elf targets. 40998944Sobrien 41098944Sobrien SYNOPSIS 41198944Sobrien 41298944Sobrien CORE_ADDR elf_locate_base (void) 41398944Sobrien 41498944Sobrien DESCRIPTION 41598944Sobrien 41698944Sobrien For SVR4 elf targets the address of the dynamic linker's runtime 41798944Sobrien structure is contained within the dynamic info section in the 41898944Sobrien executable file. The dynamic section is also mapped into the 41998944Sobrien inferior address space. Because the runtime loader fills in the 42098944Sobrien real address before starting the inferior, we have to read in the 42198944Sobrien dynamic info section from the inferior address space. 42298944Sobrien If there are any errors while trying to find the address, we 42398944Sobrien silently return 0, otherwise the found address is returned. 42498944Sobrien 42598944Sobrien */ 42698944Sobrien 42798944Sobrienstatic CORE_ADDR 42898944Sobrienelf_locate_base (void) 42998944Sobrien{ 430130803Smarcel struct bfd_section *dyninfo_sect; 43198944Sobrien int dyninfo_sect_size; 43298944Sobrien CORE_ADDR dyninfo_addr; 43398944Sobrien char *buf; 43498944Sobrien char *bufend; 43598944Sobrien int arch_size; 43698944Sobrien 43798944Sobrien /* Find the start address of the .dynamic section. */ 43898944Sobrien dyninfo_sect = bfd_get_section_by_name (exec_bfd, ".dynamic"); 43998944Sobrien if (dyninfo_sect == NULL) 44098944Sobrien return 0; 44198944Sobrien dyninfo_addr = bfd_section_vma (exec_bfd, dyninfo_sect); 44298944Sobrien 44398944Sobrien /* Read in .dynamic section, silently ignore errors. */ 44498944Sobrien dyninfo_sect_size = bfd_section_size (exec_bfd, dyninfo_sect); 44598944Sobrien buf = alloca (dyninfo_sect_size); 44698944Sobrien if (target_read_memory (dyninfo_addr, buf, dyninfo_sect_size)) 44798944Sobrien return 0; 44898944Sobrien 44998944Sobrien /* Find the DT_DEBUG entry in the the .dynamic section. 45098944Sobrien For mips elf we look for DT_MIPS_RLD_MAP, mips elf apparently has 45198944Sobrien no DT_DEBUG entries. */ 45298944Sobrien 45398944Sobrien arch_size = bfd_get_arch_size (exec_bfd); 45498944Sobrien if (arch_size == -1) /* failure */ 45598944Sobrien return 0; 45698944Sobrien 45798944Sobrien if (arch_size == 32) 45898944Sobrien { /* 32-bit elf */ 45998944Sobrien for (bufend = buf + dyninfo_sect_size; 46098944Sobrien buf < bufend; 46198944Sobrien buf += sizeof (Elf32_External_Dyn)) 46298944Sobrien { 46398944Sobrien Elf32_External_Dyn *x_dynp = (Elf32_External_Dyn *) buf; 46498944Sobrien long dyn_tag; 46598944Sobrien CORE_ADDR dyn_ptr; 46698944Sobrien 46798944Sobrien dyn_tag = bfd_h_get_32 (exec_bfd, (bfd_byte *) x_dynp->d_tag); 46898944Sobrien if (dyn_tag == DT_NULL) 46998944Sobrien break; 47098944Sobrien else if (dyn_tag == DT_DEBUG) 47198944Sobrien { 47298944Sobrien dyn_ptr = bfd_h_get_32 (exec_bfd, 47398944Sobrien (bfd_byte *) x_dynp->d_un.d_ptr); 47498944Sobrien return dyn_ptr; 47598944Sobrien } 47698944Sobrien else if (dyn_tag == DT_MIPS_RLD_MAP) 47798944Sobrien { 47898944Sobrien char *pbuf; 479130803Smarcel int pbuf_size = TARGET_PTR_BIT / HOST_CHAR_BIT; 48098944Sobrien 481130803Smarcel pbuf = alloca (pbuf_size); 48298944Sobrien /* DT_MIPS_RLD_MAP contains a pointer to the address 48398944Sobrien of the dynamic link structure. */ 48498944Sobrien dyn_ptr = bfd_h_get_32 (exec_bfd, 48598944Sobrien (bfd_byte *) x_dynp->d_un.d_ptr); 486130803Smarcel if (target_read_memory (dyn_ptr, pbuf, pbuf_size)) 48798944Sobrien return 0; 488130803Smarcel return extract_unsigned_integer (pbuf, pbuf_size); 48998944Sobrien } 49098944Sobrien } 49198944Sobrien } 49298944Sobrien else /* 64-bit elf */ 49398944Sobrien { 49498944Sobrien for (bufend = buf + dyninfo_sect_size; 49598944Sobrien buf < bufend; 49698944Sobrien buf += sizeof (Elf64_External_Dyn)) 49798944Sobrien { 49898944Sobrien Elf64_External_Dyn *x_dynp = (Elf64_External_Dyn *) buf; 49998944Sobrien long dyn_tag; 50098944Sobrien CORE_ADDR dyn_ptr; 50198944Sobrien 50298944Sobrien dyn_tag = bfd_h_get_64 (exec_bfd, (bfd_byte *) x_dynp->d_tag); 50398944Sobrien if (dyn_tag == DT_NULL) 50498944Sobrien break; 50598944Sobrien else if (dyn_tag == DT_DEBUG) 50698944Sobrien { 50798944Sobrien dyn_ptr = bfd_h_get_64 (exec_bfd, 50898944Sobrien (bfd_byte *) x_dynp->d_un.d_ptr); 50998944Sobrien return dyn_ptr; 51098944Sobrien } 511130803Smarcel else if (dyn_tag == DT_MIPS_RLD_MAP) 512130803Smarcel { 513130803Smarcel char *pbuf; 514130803Smarcel int pbuf_size = TARGET_PTR_BIT / HOST_CHAR_BIT; 515130803Smarcel 516130803Smarcel pbuf = alloca (pbuf_size); 517130803Smarcel /* DT_MIPS_RLD_MAP contains a pointer to the address 518130803Smarcel of the dynamic link structure. */ 519130803Smarcel dyn_ptr = bfd_h_get_64 (exec_bfd, 520130803Smarcel (bfd_byte *) x_dynp->d_un.d_ptr); 521130803Smarcel if (target_read_memory (dyn_ptr, pbuf, pbuf_size)) 522130803Smarcel return 0; 523130803Smarcel return extract_unsigned_integer (pbuf, pbuf_size); 524130803Smarcel } 52598944Sobrien } 52698944Sobrien } 52798944Sobrien 52898944Sobrien /* DT_DEBUG entry not found. */ 52998944Sobrien return 0; 53098944Sobrien} 53198944Sobrien 53298944Sobrien/* 53398944Sobrien 53498944Sobrien LOCAL FUNCTION 53598944Sobrien 53698944Sobrien locate_base -- locate the base address of dynamic linker structs 53798944Sobrien 53898944Sobrien SYNOPSIS 53998944Sobrien 54098944Sobrien CORE_ADDR locate_base (void) 54198944Sobrien 54298944Sobrien DESCRIPTION 54398944Sobrien 54498944Sobrien For both the SunOS and SVR4 shared library implementations, if the 54598944Sobrien inferior executable has been linked dynamically, there is a single 54698944Sobrien address somewhere in the inferior's data space which is the key to 54798944Sobrien locating all of the dynamic linker's runtime structures. This 54898944Sobrien address is the value of the debug base symbol. The job of this 54998944Sobrien function is to find and return that address, or to return 0 if there 55098944Sobrien is no such address (the executable is statically linked for example). 55198944Sobrien 55298944Sobrien For SunOS, the job is almost trivial, since the dynamic linker and 55398944Sobrien all of it's structures are statically linked to the executable at 55498944Sobrien link time. Thus the symbol for the address we are looking for has 55598944Sobrien already been added to the minimal symbol table for the executable's 55698944Sobrien objfile at the time the symbol file's symbols were read, and all we 55798944Sobrien have to do is look it up there. Note that we explicitly do NOT want 55898944Sobrien to find the copies in the shared library. 55998944Sobrien 56098944Sobrien The SVR4 version is a bit more complicated because the address 56198944Sobrien is contained somewhere in the dynamic info section. We have to go 56298944Sobrien to a lot more work to discover the address of the debug base symbol. 56398944Sobrien Because of this complexity, we cache the value we find and return that 56498944Sobrien value on subsequent invocations. Note there is no copy in the 56598944Sobrien executable symbol tables. 56698944Sobrien 56798944Sobrien */ 56898944Sobrien 56998944Sobrienstatic CORE_ADDR 57098944Sobrienlocate_base (void) 57198944Sobrien{ 57298944Sobrien /* Check to see if we have a currently valid address, and if so, avoid 57398944Sobrien doing all this work again and just return the cached address. If 57498944Sobrien we have no cached address, try to locate it in the dynamic info 575130803Smarcel section for ELF executables. There's no point in doing any of this 576130803Smarcel though if we don't have some link map offsets to work with. */ 57798944Sobrien 578130803Smarcel if (debug_base == 0 && svr4_have_link_map_offsets ()) 57998944Sobrien { 58098944Sobrien if (exec_bfd != NULL 58198944Sobrien && bfd_get_flavour (exec_bfd) == bfd_target_elf_flavour) 58298944Sobrien debug_base = elf_locate_base (); 58398944Sobrien#ifdef HANDLE_SVR4_EXEC_EMULATORS 58498944Sobrien /* Try it the hard way for emulated executables. */ 58598944Sobrien else if (!ptid_equal (inferior_ptid, null_ptid) && target_has_execution) 58698944Sobrien proc_iterate_over_mappings (look_for_base); 58798944Sobrien#endif 58898944Sobrien } 58998944Sobrien return (debug_base); 59098944Sobrien} 59198944Sobrien 59298944Sobrien/* 59398944Sobrien 59498944Sobrien LOCAL FUNCTION 59598944Sobrien 59698944Sobrien first_link_map_member -- locate first member in dynamic linker's map 59798944Sobrien 59898944Sobrien SYNOPSIS 59998944Sobrien 60098944Sobrien static CORE_ADDR first_link_map_member (void) 60198944Sobrien 60298944Sobrien DESCRIPTION 60398944Sobrien 60498944Sobrien Find the first element in the inferior's dynamic link map, and 60598944Sobrien return its address in the inferior. This function doesn't copy the 60698944Sobrien link map entry itself into our address space; current_sos actually 60798944Sobrien does the reading. */ 60898944Sobrien 60998944Sobrienstatic CORE_ADDR 61098944Sobrienfirst_link_map_member (void) 61198944Sobrien{ 61298944Sobrien CORE_ADDR lm = 0; 61398944Sobrien struct link_map_offsets *lmo = SVR4_FETCH_LINK_MAP_OFFSETS (); 61498944Sobrien char *r_map_buf = xmalloc (lmo->r_map_size); 61598944Sobrien struct cleanup *cleanups = make_cleanup (xfree, r_map_buf); 61698944Sobrien 61798944Sobrien read_memory (debug_base + lmo->r_map_offset, r_map_buf, lmo->r_map_size); 61898944Sobrien 619130803Smarcel /* Assume that the address is unsigned. */ 620130803Smarcel lm = extract_unsigned_integer (r_map_buf, lmo->r_map_size); 62198944Sobrien 62298944Sobrien /* FIXME: Perhaps we should validate the info somehow, perhaps by 62398944Sobrien checking r_version for a known version number, or r_state for 62498944Sobrien RT_CONSISTENT. */ 62598944Sobrien 62698944Sobrien do_cleanups (cleanups); 62798944Sobrien 62898944Sobrien return (lm); 62998944Sobrien} 63098944Sobrien 63198944Sobrien/* 63298944Sobrien 63398944Sobrien LOCAL FUNCTION 63498944Sobrien 63598944Sobrien open_symbol_file_object 63698944Sobrien 63798944Sobrien SYNOPSIS 63898944Sobrien 63998944Sobrien void open_symbol_file_object (void *from_tty) 64098944Sobrien 64198944Sobrien DESCRIPTION 64298944Sobrien 64398944Sobrien If no open symbol file, attempt to locate and open the main symbol 64498944Sobrien file. On SVR4 systems, this is the first link map entry. If its 64598944Sobrien name is here, we can open it. Useful when attaching to a process 64698944Sobrien without first loading its symbol file. 64798944Sobrien 64898944Sobrien If FROM_TTYP dereferences to a non-zero integer, allow messages to 64998944Sobrien be printed. This parameter is a pointer rather than an int because 65098944Sobrien open_symbol_file_object() is called via catch_errors() and 65198944Sobrien catch_errors() requires a pointer argument. */ 65298944Sobrien 65398944Sobrienstatic int 65498944Sobrienopen_symbol_file_object (void *from_ttyp) 65598944Sobrien{ 65698944Sobrien CORE_ADDR lm, l_name; 65798944Sobrien char *filename; 65898944Sobrien int errcode; 65998944Sobrien int from_tty = *(int *)from_ttyp; 66098944Sobrien struct link_map_offsets *lmo = SVR4_FETCH_LINK_MAP_OFFSETS (); 66198944Sobrien char *l_name_buf = xmalloc (lmo->l_name_size); 66298944Sobrien struct cleanup *cleanups = make_cleanup (xfree, l_name_buf); 66398944Sobrien 66498944Sobrien if (symfile_objfile) 66598944Sobrien if (!query ("Attempt to reload symbols from process? ")) 66698944Sobrien return 0; 66798944Sobrien 66898944Sobrien if ((debug_base = locate_base ()) == 0) 66998944Sobrien return 0; /* failed somehow... */ 67098944Sobrien 67198944Sobrien /* First link map member should be the executable. */ 67298944Sobrien if ((lm = first_link_map_member ()) == 0) 67398944Sobrien return 0; /* failed somehow... */ 67498944Sobrien 67598944Sobrien /* Read address of name from target memory to GDB. */ 67698944Sobrien read_memory (lm + lmo->l_name_offset, l_name_buf, lmo->l_name_size); 67798944Sobrien 678130803Smarcel /* Convert the address to host format. Assume that the address is 679130803Smarcel unsigned. */ 680130803Smarcel l_name = extract_unsigned_integer (l_name_buf, lmo->l_name_size); 68198944Sobrien 68298944Sobrien /* Free l_name_buf. */ 68398944Sobrien do_cleanups (cleanups); 68498944Sobrien 68598944Sobrien if (l_name == 0) 68698944Sobrien return 0; /* No filename. */ 68798944Sobrien 68898944Sobrien /* Now fetch the filename from target memory. */ 68998944Sobrien target_read_string (l_name, &filename, SO_NAME_MAX_PATH_SIZE - 1, &errcode); 69098944Sobrien 69198944Sobrien if (errcode) 69298944Sobrien { 69398944Sobrien warning ("failed to read exec filename from attached file: %s", 69498944Sobrien safe_strerror (errcode)); 69598944Sobrien return 0; 69698944Sobrien } 69798944Sobrien 69898944Sobrien make_cleanup (xfree, filename); 69998944Sobrien /* Have a pathname: read the symbol file. */ 70098944Sobrien symbol_file_add_main (filename, from_tty); 70198944Sobrien 70298944Sobrien return 1; 70398944Sobrien} 70498944Sobrien 70598944Sobrien/* LOCAL FUNCTION 70698944Sobrien 70798944Sobrien current_sos -- build a list of currently loaded shared objects 70898944Sobrien 70998944Sobrien SYNOPSIS 71098944Sobrien 71198944Sobrien struct so_list *current_sos () 71298944Sobrien 71398944Sobrien DESCRIPTION 71498944Sobrien 71598944Sobrien Build a list of `struct so_list' objects describing the shared 71698944Sobrien objects currently loaded in the inferior. This list does not 71798944Sobrien include an entry for the main executable file. 71898944Sobrien 71998944Sobrien Note that we only gather information directly available from the 72098944Sobrien inferior --- we don't examine any of the shared library files 72198944Sobrien themselves. The declaration of `struct so_list' says which fields 72298944Sobrien we provide values for. */ 72398944Sobrien 72498944Sobrienstatic struct so_list * 72598944Sobriensvr4_current_sos (void) 72698944Sobrien{ 72798944Sobrien CORE_ADDR lm; 72898944Sobrien struct so_list *head = 0; 72998944Sobrien struct so_list **link_ptr = &head; 73098944Sobrien 73198944Sobrien /* Make sure we've looked up the inferior's dynamic linker's base 73298944Sobrien structure. */ 73398944Sobrien if (! debug_base) 73498944Sobrien { 73598944Sobrien debug_base = locate_base (); 73698944Sobrien 73798944Sobrien /* If we can't find the dynamic linker's base structure, this 73898944Sobrien must not be a dynamically linked executable. Hmm. */ 73998944Sobrien if (! debug_base) 74098944Sobrien return 0; 74198944Sobrien } 74298944Sobrien 74398944Sobrien /* Walk the inferior's link map list, and build our list of 74498944Sobrien `struct so_list' nodes. */ 74598944Sobrien lm = first_link_map_member (); 74698944Sobrien while (lm) 74798944Sobrien { 74898944Sobrien struct link_map_offsets *lmo = SVR4_FETCH_LINK_MAP_OFFSETS (); 74998944Sobrien struct so_list *new 75098944Sobrien = (struct so_list *) xmalloc (sizeof (struct so_list)); 75198944Sobrien struct cleanup *old_chain = make_cleanup (xfree, new); 75298944Sobrien 75398944Sobrien memset (new, 0, sizeof (*new)); 75498944Sobrien 75598944Sobrien new->lm_info = xmalloc (sizeof (struct lm_info)); 75698944Sobrien make_cleanup (xfree, new->lm_info); 75798944Sobrien 75898944Sobrien new->lm_info->lm = xmalloc (lmo->link_map_size); 75998944Sobrien make_cleanup (xfree, new->lm_info->lm); 76098944Sobrien memset (new->lm_info->lm, 0, lmo->link_map_size); 76198944Sobrien 76298944Sobrien read_memory (lm, new->lm_info->lm, lmo->link_map_size); 76398944Sobrien 76498944Sobrien lm = LM_NEXT (new); 76598944Sobrien 76698944Sobrien /* For SVR4 versions, the first entry in the link map is for the 76798944Sobrien inferior executable, so we must ignore it. For some versions of 76898944Sobrien SVR4, it has no name. For others (Solaris 2.3 for example), it 76998944Sobrien does have a name, so we can no longer use a missing name to 77098944Sobrien decide when to ignore it. */ 77198944Sobrien if (IGNORE_FIRST_LINK_MAP_ENTRY (new)) 77298944Sobrien free_so (new); 77398944Sobrien else 77498944Sobrien { 77598944Sobrien int errcode; 77698944Sobrien char *buffer; 77798944Sobrien 77898944Sobrien /* Extract this shared object's name. */ 77998944Sobrien target_read_string (LM_NAME (new), &buffer, 78098944Sobrien SO_NAME_MAX_PATH_SIZE - 1, &errcode); 78198944Sobrien if (errcode != 0) 78298944Sobrien { 78398944Sobrien warning ("current_sos: Can't read pathname for load map: %s\n", 78498944Sobrien safe_strerror (errcode)); 78598944Sobrien } 78698944Sobrien else 78798944Sobrien { 78898944Sobrien strncpy (new->so_name, buffer, SO_NAME_MAX_PATH_SIZE - 1); 78998944Sobrien new->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; 79098944Sobrien xfree (buffer); 79198944Sobrien strcpy (new->so_original_name, new->so_name); 79298944Sobrien } 79398944Sobrien 79498944Sobrien /* If this entry has no name, or its name matches the name 79598944Sobrien for the main executable, don't include it in the list. */ 79698944Sobrien if (! new->so_name[0] 79798944Sobrien || match_main (new->so_name)) 79898944Sobrien free_so (new); 79998944Sobrien else 80098944Sobrien { 80198944Sobrien new->next = 0; 80298944Sobrien *link_ptr = new; 80398944Sobrien link_ptr = &new->next; 80498944Sobrien } 80598944Sobrien } 80698944Sobrien 80798944Sobrien discard_cleanups (old_chain); 80898944Sobrien } 80998944Sobrien 81098944Sobrien return head; 81198944Sobrien} 81298944Sobrien 813130803Smarcel/* Get the address of the link_map for a given OBJFILE. Loop through 814130803Smarcel the link maps, and return the address of the one corresponding to 815130803Smarcel the given objfile. Note that this function takes into account that 816130803Smarcel objfile can be the main executable, not just a shared library. The 817130803Smarcel main executable has always an empty name field in the linkmap. */ 81898944Sobrien 819130803SmarcelCORE_ADDR 820130803Smarcelsvr4_fetch_objfile_link_map (struct objfile *objfile) 821130803Smarcel{ 822130803Smarcel CORE_ADDR lm; 823130803Smarcel 824130803Smarcel if ((debug_base = locate_base ()) == 0) 825130803Smarcel return 0; /* failed somehow... */ 826130803Smarcel 827130803Smarcel /* Position ourselves on the first link map. */ 828130803Smarcel lm = first_link_map_member (); 829130803Smarcel while (lm) 830130803Smarcel { 831130803Smarcel /* Get info on the layout of the r_debug and link_map structures. */ 832130803Smarcel struct link_map_offsets *lmo = SVR4_FETCH_LINK_MAP_OFFSETS (); 833130803Smarcel int errcode; 834130803Smarcel char *buffer; 835130803Smarcel struct lm_info objfile_lm_info; 836130803Smarcel struct cleanup *old_chain; 837130803Smarcel CORE_ADDR name_address; 838130803Smarcel char *l_name_buf = xmalloc (lmo->l_name_size); 839130803Smarcel old_chain = make_cleanup (xfree, l_name_buf); 840130803Smarcel 841130803Smarcel /* Set up the buffer to contain the portion of the link_map 842130803Smarcel structure that gdb cares about. Note that this is not the 843130803Smarcel whole link_map structure. */ 844130803Smarcel objfile_lm_info.lm = xmalloc (lmo->link_map_size); 845130803Smarcel make_cleanup (xfree, objfile_lm_info.lm); 846130803Smarcel memset (objfile_lm_info.lm, 0, lmo->link_map_size); 847130803Smarcel 848130803Smarcel /* Read the link map into our internal structure. */ 849130803Smarcel read_memory (lm, objfile_lm_info.lm, lmo->link_map_size); 850130803Smarcel 851130803Smarcel /* Read address of name from target memory to GDB. */ 852130803Smarcel read_memory (lm + lmo->l_name_offset, l_name_buf, lmo->l_name_size); 853130803Smarcel 854130803Smarcel /* Extract this object's name. Assume that the address is 855130803Smarcel unsigned. */ 856130803Smarcel name_address = extract_unsigned_integer (l_name_buf, lmo->l_name_size); 857130803Smarcel target_read_string (name_address, &buffer, 858130803Smarcel SO_NAME_MAX_PATH_SIZE - 1, &errcode); 859130803Smarcel make_cleanup (xfree, buffer); 860130803Smarcel if (errcode != 0) 861130803Smarcel { 862130803Smarcel warning ("svr4_fetch_objfile_link_map: Can't read pathname for load map: %s\n", 863130803Smarcel safe_strerror (errcode)); 864130803Smarcel } 865130803Smarcel else 866130803Smarcel { 867130803Smarcel /* Is this the linkmap for the file we want? */ 868130803Smarcel /* If the file is not a shared library and has no name, 869130803Smarcel we are sure it is the main executable, so we return that. */ 870130803Smarcel if ((buffer && strcmp (buffer, objfile->name) == 0) 871130803Smarcel || (!(objfile->flags & OBJF_SHARED) && (strcmp (buffer, "") == 0))) 872130803Smarcel { 873130803Smarcel do_cleanups (old_chain); 874130803Smarcel return lm; 875130803Smarcel } 876130803Smarcel } 877130803Smarcel /* Not the file we wanted, continue checking. Assume that the 878130803Smarcel address is unsigned. */ 879130803Smarcel lm = extract_unsigned_integer (objfile_lm_info.lm + lmo->l_next_offset, 880130803Smarcel lmo->l_next_size); 881130803Smarcel do_cleanups (old_chain); 882130803Smarcel } 883130803Smarcel return 0; 884130803Smarcel} 885130803Smarcel 88698944Sobrien/* On some systems, the only way to recognize the link map entry for 88798944Sobrien the main executable file is by looking at its name. Return 88898944Sobrien non-zero iff SONAME matches one of the known main executable names. */ 88998944Sobrien 89098944Sobrienstatic int 89198944Sobrienmatch_main (char *soname) 89298944Sobrien{ 89398944Sobrien char **mainp; 89498944Sobrien 89598944Sobrien for (mainp = main_name_list; *mainp != NULL; mainp++) 89698944Sobrien { 89798944Sobrien if (strcmp (soname, *mainp) == 0) 89898944Sobrien return (1); 89998944Sobrien } 90098944Sobrien 90198944Sobrien return (0); 90298944Sobrien} 90398944Sobrien 90498944Sobrien/* Return 1 if PC lies in the dynamic symbol resolution code of the 90598944Sobrien SVR4 run time loader. */ 90698944Sobrienstatic CORE_ADDR interp_text_sect_low; 90798944Sobrienstatic CORE_ADDR interp_text_sect_high; 90898944Sobrienstatic CORE_ADDR interp_plt_sect_low; 90998944Sobrienstatic CORE_ADDR interp_plt_sect_high; 91098944Sobrien 91198944Sobrienstatic int 91298944Sobriensvr4_in_dynsym_resolve_code (CORE_ADDR pc) 91398944Sobrien{ 91498944Sobrien return ((pc >= interp_text_sect_low && pc < interp_text_sect_high) 91598944Sobrien || (pc >= interp_plt_sect_low && pc < interp_plt_sect_high) 91698944Sobrien || in_plt_section (pc, NULL)); 91798944Sobrien} 91898944Sobrien 919130803Smarcel/* Given an executable's ABFD and target, compute the entry-point 920130803Smarcel address. */ 92198944Sobrien 922130803Smarcelstatic CORE_ADDR 923130803Smarcelexec_entry_point (struct bfd *abfd, struct target_ops *targ) 924130803Smarcel{ 925130803Smarcel /* KevinB wrote ... for most targets, the address returned by 926130803Smarcel bfd_get_start_address() is the entry point for the start 927130803Smarcel function. But, for some targets, bfd_get_start_address() returns 928130803Smarcel the address of a function descriptor from which the entry point 929130803Smarcel address may be extracted. This address is extracted by 930130803Smarcel gdbarch_convert_from_func_ptr_addr(). The method 931130803Smarcel gdbarch_convert_from_func_ptr_addr() is the merely the identify 932130803Smarcel function for targets which don't use function descriptors. */ 933130803Smarcel return gdbarch_convert_from_func_ptr_addr (current_gdbarch, 934130803Smarcel bfd_get_start_address (abfd), 935130803Smarcel targ); 936130803Smarcel} 937130803Smarcel 93898944Sobrien/* 93998944Sobrien 94098944Sobrien LOCAL FUNCTION 94198944Sobrien 94298944Sobrien enable_break -- arrange for dynamic linker to hit breakpoint 94398944Sobrien 94498944Sobrien SYNOPSIS 94598944Sobrien 94698944Sobrien int enable_break (void) 94798944Sobrien 94898944Sobrien DESCRIPTION 94998944Sobrien 95098944Sobrien Both the SunOS and the SVR4 dynamic linkers have, as part of their 95198944Sobrien debugger interface, support for arranging for the inferior to hit 95298944Sobrien a breakpoint after mapping in the shared libraries. This function 95398944Sobrien enables that breakpoint. 95498944Sobrien 95598944Sobrien For SunOS, there is a special flag location (in_debugger) which we 95698944Sobrien set to 1. When the dynamic linker sees this flag set, it will set 95798944Sobrien a breakpoint at a location known only to itself, after saving the 95898944Sobrien original contents of that place and the breakpoint address itself, 95998944Sobrien in it's own internal structures. When we resume the inferior, it 96098944Sobrien will eventually take a SIGTRAP when it runs into the breakpoint. 96198944Sobrien We handle this (in a different place) by restoring the contents of 96298944Sobrien the breakpointed location (which is only known after it stops), 96398944Sobrien chasing around to locate the shared libraries that have been 96498944Sobrien loaded, then resuming. 96598944Sobrien 96698944Sobrien For SVR4, the debugger interface structure contains a member (r_brk) 96798944Sobrien which is statically initialized at the time the shared library is 96898944Sobrien built, to the offset of a function (_r_debug_state) which is guaran- 96998944Sobrien teed to be called once before mapping in a library, and again when 97098944Sobrien the mapping is complete. At the time we are examining this member, 97198944Sobrien it contains only the unrelocated offset of the function, so we have 97298944Sobrien to do our own relocation. Later, when the dynamic linker actually 97398944Sobrien runs, it relocates r_brk to be the actual address of _r_debug_state(). 97498944Sobrien 97598944Sobrien The debugger interface structure also contains an enumeration which 97698944Sobrien is set to either RT_ADD or RT_DELETE prior to changing the mapping, 97798944Sobrien depending upon whether or not the library is being mapped or unmapped, 97898944Sobrien and then set to RT_CONSISTENT after the library is mapped/unmapped. 97998944Sobrien */ 98098944Sobrien 98198944Sobrienstatic int 98298944Sobrienenable_break (void) 98398944Sobrien{ 98498944Sobrien int success = 0; 98598944Sobrien 98698944Sobrien#ifdef BKPT_AT_SYMBOL 98798944Sobrien 98898944Sobrien struct minimal_symbol *msymbol; 98998944Sobrien char **bkpt_namep; 99098944Sobrien asection *interp_sect; 99198944Sobrien 99298944Sobrien /* First, remove all the solib event breakpoints. Their addresses 99398944Sobrien may have changed since the last time we ran the program. */ 99498944Sobrien remove_solib_event_breakpoints (); 99598944Sobrien 99698944Sobrien interp_text_sect_low = interp_text_sect_high = 0; 99798944Sobrien interp_plt_sect_low = interp_plt_sect_high = 0; 99898944Sobrien 99998944Sobrien /* Find the .interp section; if not found, warn the user and drop 100098944Sobrien into the old breakpoint at symbol code. */ 100198944Sobrien interp_sect = bfd_get_section_by_name (exec_bfd, ".interp"); 100298944Sobrien if (interp_sect) 100398944Sobrien { 100498944Sobrien unsigned int interp_sect_size; 100598944Sobrien char *buf; 100698944Sobrien CORE_ADDR load_addr = 0; 100798944Sobrien int load_addr_found = 0; 100898944Sobrien struct so_list *inferior_sos; 100998944Sobrien bfd *tmp_bfd = NULL; 1010130803Smarcel struct target_ops *tmp_bfd_target; 101198944Sobrien int tmp_fd = -1; 101298944Sobrien char *tmp_pathname = NULL; 101398944Sobrien CORE_ADDR sym_addr = 0; 101498944Sobrien 101598944Sobrien /* Read the contents of the .interp section into a local buffer; 101698944Sobrien the contents specify the dynamic linker this program uses. */ 101798944Sobrien interp_sect_size = bfd_section_size (exec_bfd, interp_sect); 101898944Sobrien buf = alloca (interp_sect_size); 101998944Sobrien bfd_get_section_contents (exec_bfd, interp_sect, 102098944Sobrien buf, 0, interp_sect_size); 102198944Sobrien 102298944Sobrien /* Now we need to figure out where the dynamic linker was 102398944Sobrien loaded so that we can load its symbols and place a breakpoint 102498944Sobrien in the dynamic linker itself. 102598944Sobrien 102698944Sobrien This address is stored on the stack. However, I've been unable 102798944Sobrien to find any magic formula to find it for Solaris (appears to 102898944Sobrien be trivial on GNU/Linux). Therefore, we have to try an alternate 102998944Sobrien mechanism to find the dynamic linker's base address. */ 103098944Sobrien 103198944Sobrien tmp_fd = solib_open (buf, &tmp_pathname); 103298944Sobrien if (tmp_fd >= 0) 103398944Sobrien tmp_bfd = bfd_fdopenr (tmp_pathname, gnutarget, tmp_fd); 103498944Sobrien 103598944Sobrien if (tmp_bfd == NULL) 103698944Sobrien goto bkpt_at_symbol; 103798944Sobrien 103898944Sobrien /* Make sure the dynamic linker's really a useful object. */ 103998944Sobrien if (!bfd_check_format (tmp_bfd, bfd_object)) 104098944Sobrien { 104198944Sobrien warning ("Unable to grok dynamic linker %s as an object file", buf); 104298944Sobrien bfd_close (tmp_bfd); 104398944Sobrien goto bkpt_at_symbol; 104498944Sobrien } 104598944Sobrien 1046130803Smarcel /* Now convert the TMP_BFD into a target. That way target, as 1047130803Smarcel well as BFD operations can be used. Note that closing the 1048130803Smarcel target will also close the underlying bfd. */ 1049130803Smarcel tmp_bfd_target = target_bfd_reopen (tmp_bfd); 1050130803Smarcel 105198944Sobrien /* If the entry in _DYNAMIC for the dynamic linker has already 105298944Sobrien been filled in, we can read its base address from there. */ 105398944Sobrien inferior_sos = svr4_current_sos (); 105498944Sobrien if (inferior_sos) 105598944Sobrien { 105698944Sobrien /* Connected to a running target. Update our shared library table. */ 105798944Sobrien solib_add (NULL, 0, NULL, auto_solib_add); 105898944Sobrien } 105998944Sobrien while (inferior_sos) 106098944Sobrien { 106198944Sobrien if (strcmp (buf, inferior_sos->so_original_name) == 0) 106298944Sobrien { 106398944Sobrien load_addr_found = 1; 106498944Sobrien load_addr = LM_ADDR (inferior_sos); 106598944Sobrien break; 106698944Sobrien } 106798944Sobrien inferior_sos = inferior_sos->next; 106898944Sobrien } 106998944Sobrien 107098944Sobrien /* Otherwise we find the dynamic linker's base address by examining 107198944Sobrien the current pc (which should point at the entry point for the 107298944Sobrien dynamic linker) and subtracting the offset of the entry point. */ 107398944Sobrien if (!load_addr_found) 1074130803Smarcel load_addr = (read_pc () 1075130803Smarcel - exec_entry_point (tmp_bfd, tmp_bfd_target)); 107698944Sobrien 107798944Sobrien /* Record the relocated start and end address of the dynamic linker 107898944Sobrien text and plt section for svr4_in_dynsym_resolve_code. */ 107998944Sobrien interp_sect = bfd_get_section_by_name (tmp_bfd, ".text"); 108098944Sobrien if (interp_sect) 108198944Sobrien { 108298944Sobrien interp_text_sect_low = 108398944Sobrien bfd_section_vma (tmp_bfd, interp_sect) + load_addr; 108498944Sobrien interp_text_sect_high = 108598944Sobrien interp_text_sect_low + bfd_section_size (tmp_bfd, interp_sect); 108698944Sobrien } 108798944Sobrien interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt"); 108898944Sobrien if (interp_sect) 108998944Sobrien { 109098944Sobrien interp_plt_sect_low = 109198944Sobrien bfd_section_vma (tmp_bfd, interp_sect) + load_addr; 109298944Sobrien interp_plt_sect_high = 109398944Sobrien interp_plt_sect_low + bfd_section_size (tmp_bfd, interp_sect); 109498944Sobrien } 109598944Sobrien 109698944Sobrien /* Now try to set a breakpoint in the dynamic linker. */ 109798944Sobrien for (bkpt_namep = solib_break_names; *bkpt_namep != NULL; bkpt_namep++) 109898944Sobrien { 1099130803Smarcel /* On ABI's that use function descriptors, there are usually 1100130803Smarcel two linker symbols associated with each C function: one 1101130803Smarcel pointing at the actual entry point of the machine code, 1102130803Smarcel and one pointing at the function's descriptor. The 1103130803Smarcel latter symbol has the same name as the C function. 1104130803Smarcel 1105130803Smarcel What we're looking for here is the machine code entry 1106130803Smarcel point, so we are only interested in symbols in code 1107130803Smarcel sections. */ 1108130803Smarcel sym_addr = bfd_lookup_symbol (tmp_bfd, *bkpt_namep, SEC_CODE); 110998944Sobrien if (sym_addr != 0) 111098944Sobrien break; 111198944Sobrien } 111298944Sobrien 1113130803Smarcel /* We're done with both the temporary bfd and target. Remember, 1114130803Smarcel closing the target closes the underlying bfd. */ 1115130803Smarcel target_close (tmp_bfd_target, 0); 111698944Sobrien 111798944Sobrien if (sym_addr != 0) 111898944Sobrien { 111998944Sobrien create_solib_event_breakpoint (load_addr + sym_addr); 112098944Sobrien return 1; 112198944Sobrien } 112298944Sobrien 112398944Sobrien /* For whatever reason we couldn't set a breakpoint in the dynamic 112498944Sobrien linker. Warn and drop into the old code. */ 112598944Sobrien bkpt_at_symbol: 112698944Sobrien warning ("Unable to find dynamic linker breakpoint function.\nGDB will be unable to debug shared library initializers\nand track explicitly loaded dynamic code."); 112798944Sobrien } 112898944Sobrien 112998944Sobrien /* Scan through the list of symbols, trying to look up the symbol and 113098944Sobrien set a breakpoint there. Terminate loop when we/if we succeed. */ 113198944Sobrien 113298944Sobrien breakpoint_addr = 0; 113398944Sobrien for (bkpt_namep = bkpt_names; *bkpt_namep != NULL; bkpt_namep++) 113498944Sobrien { 113598944Sobrien msymbol = lookup_minimal_symbol (*bkpt_namep, NULL, symfile_objfile); 113698944Sobrien if ((msymbol != NULL) && (SYMBOL_VALUE_ADDRESS (msymbol) != 0)) 113798944Sobrien { 113898944Sobrien create_solib_event_breakpoint (SYMBOL_VALUE_ADDRESS (msymbol)); 113998944Sobrien return 1; 114098944Sobrien } 114198944Sobrien } 114298944Sobrien 114398944Sobrien /* Nothing good happened. */ 114498944Sobrien success = 0; 114598944Sobrien 114698944Sobrien#endif /* BKPT_AT_SYMBOL */ 114798944Sobrien 114898944Sobrien return (success); 114998944Sobrien} 115098944Sobrien 115198944Sobrien/* 115298944Sobrien 115398944Sobrien LOCAL FUNCTION 115498944Sobrien 115598944Sobrien special_symbol_handling -- additional shared library symbol handling 115698944Sobrien 115798944Sobrien SYNOPSIS 115898944Sobrien 115998944Sobrien void special_symbol_handling () 116098944Sobrien 116198944Sobrien DESCRIPTION 116298944Sobrien 116398944Sobrien Once the symbols from a shared object have been loaded in the usual 116498944Sobrien way, we are called to do any system specific symbol handling that 116598944Sobrien is needed. 116698944Sobrien 116798944Sobrien For SunOS4, this consisted of grunging around in the dynamic 116898944Sobrien linkers structures to find symbol definitions for "common" symbols 116998944Sobrien and adding them to the minimal symbol table for the runtime common 117098944Sobrien objfile. 117198944Sobrien 117298944Sobrien However, for SVR4, there's nothing to do. 117398944Sobrien 117498944Sobrien */ 117598944Sobrien 117698944Sobrienstatic void 117798944Sobriensvr4_special_symbol_handling (void) 117898944Sobrien{ 117998944Sobrien} 118098944Sobrien 118198944Sobrien/* Relocate the main executable. This function should be called upon 118298944Sobrien stopping the inferior process at the entry point to the program. 118398944Sobrien The entry point from BFD is compared to the PC and if they are 118498944Sobrien different, the main executable is relocated by the proper amount. 118598944Sobrien 118698944Sobrien As written it will only attempt to relocate executables which 118798944Sobrien lack interpreter sections. It seems likely that only dynamic 118898944Sobrien linker executables will get relocated, though it should work 118998944Sobrien properly for a position-independent static executable as well. */ 119098944Sobrien 119198944Sobrienstatic void 119298944Sobriensvr4_relocate_main_executable (void) 119398944Sobrien{ 119498944Sobrien asection *interp_sect; 119598944Sobrien CORE_ADDR pc = read_pc (); 119698944Sobrien 119798944Sobrien /* Decide if the objfile needs to be relocated. As indicated above, 119898944Sobrien we will only be here when execution is stopped at the beginning 119998944Sobrien of the program. Relocation is necessary if the address at which 120098944Sobrien we are presently stopped differs from the start address stored in 120198944Sobrien the executable AND there's no interpreter section. The condition 120298944Sobrien regarding the interpreter section is very important because if 120398944Sobrien there *is* an interpreter section, execution will begin there 120498944Sobrien instead. When there is an interpreter section, the start address 120598944Sobrien is (presumably) used by the interpreter at some point to start 120698944Sobrien execution of the program. 120798944Sobrien 120898944Sobrien If there is an interpreter, it is normal for it to be set to an 120998944Sobrien arbitrary address at the outset. The job of finding it is 121098944Sobrien handled in enable_break(). 121198944Sobrien 121298944Sobrien So, to summarize, relocations are necessary when there is no 121398944Sobrien interpreter section and the start address obtained from the 121498944Sobrien executable is different from the address at which GDB is 121598944Sobrien currently stopped. 121698944Sobrien 121798944Sobrien [ The astute reader will note that we also test to make sure that 121898944Sobrien the executable in question has the DYNAMIC flag set. It is my 121998944Sobrien opinion that this test is unnecessary (undesirable even). It 122098944Sobrien was added to avoid inadvertent relocation of an executable 122198944Sobrien whose e_type member in the ELF header is not ET_DYN. There may 122298944Sobrien be a time in the future when it is desirable to do relocations 122398944Sobrien on other types of files as well in which case this condition 122498944Sobrien should either be removed or modified to accomodate the new file 122598944Sobrien type. (E.g, an ET_EXEC executable which has been built to be 122698944Sobrien position-independent could safely be relocated by the OS if 122798944Sobrien desired. It is true that this violates the ABI, but the ABI 122898944Sobrien has been known to be bent from time to time.) - Kevin, Nov 2000. ] 122998944Sobrien */ 123098944Sobrien 123198944Sobrien interp_sect = bfd_get_section_by_name (exec_bfd, ".interp"); 123298944Sobrien if (interp_sect == NULL 123398944Sobrien && (bfd_get_file_flags (exec_bfd) & DYNAMIC) != 0 1234130803Smarcel && (exec_entry_point (exec_bfd, &exec_ops) != pc)) 123598944Sobrien { 123698944Sobrien struct cleanup *old_chain; 123798944Sobrien struct section_offsets *new_offsets; 123898944Sobrien int i, changed; 123998944Sobrien CORE_ADDR displacement; 124098944Sobrien 124198944Sobrien /* It is necessary to relocate the objfile. The amount to 124298944Sobrien relocate by is simply the address at which we are stopped 124398944Sobrien minus the starting address from the executable. 124498944Sobrien 124598944Sobrien We relocate all of the sections by the same amount. This 124698944Sobrien behavior is mandated by recent editions of the System V ABI. 124798944Sobrien According to the System V Application Binary Interface, 124898944Sobrien Edition 4.1, page 5-5: 124998944Sobrien 125098944Sobrien ... Though the system chooses virtual addresses for 125198944Sobrien individual processes, it maintains the segments' relative 125298944Sobrien positions. Because position-independent code uses relative 125398944Sobrien addressesing between segments, the difference between 125498944Sobrien virtual addresses in memory must match the difference 125598944Sobrien between virtual addresses in the file. The difference 125698944Sobrien between the virtual address of any segment in memory and 125798944Sobrien the corresponding virtual address in the file is thus a 125898944Sobrien single constant value for any one executable or shared 125998944Sobrien object in a given process. This difference is the base 126098944Sobrien address. One use of the base address is to relocate the 126198944Sobrien memory image of the program during dynamic linking. 126298944Sobrien 126398944Sobrien The same language also appears in Edition 4.0 of the System V 126498944Sobrien ABI and is left unspecified in some of the earlier editions. */ 126598944Sobrien 1266130803Smarcel displacement = pc - exec_entry_point (exec_bfd, &exec_ops); 126798944Sobrien changed = 0; 126898944Sobrien 126998944Sobrien new_offsets = xcalloc (symfile_objfile->num_sections, 127098944Sobrien sizeof (struct section_offsets)); 127198944Sobrien old_chain = make_cleanup (xfree, new_offsets); 127298944Sobrien 127398944Sobrien for (i = 0; i < symfile_objfile->num_sections; i++) 127498944Sobrien { 127598944Sobrien if (displacement != ANOFFSET (symfile_objfile->section_offsets, i)) 127698944Sobrien changed = 1; 127798944Sobrien new_offsets->offsets[i] = displacement; 127898944Sobrien } 127998944Sobrien 128098944Sobrien if (changed) 128198944Sobrien objfile_relocate (symfile_objfile, new_offsets); 128298944Sobrien 128398944Sobrien do_cleanups (old_chain); 128498944Sobrien } 128598944Sobrien} 128698944Sobrien 128798944Sobrien/* 128898944Sobrien 128998944Sobrien GLOBAL FUNCTION 129098944Sobrien 129198944Sobrien svr4_solib_create_inferior_hook -- shared library startup support 129298944Sobrien 129398944Sobrien SYNOPSIS 129498944Sobrien 129598944Sobrien void svr4_solib_create_inferior_hook() 129698944Sobrien 129798944Sobrien DESCRIPTION 129898944Sobrien 129998944Sobrien When gdb starts up the inferior, it nurses it along (through the 130098944Sobrien shell) until it is ready to execute it's first instruction. At this 130198944Sobrien point, this function gets called via expansion of the macro 130298944Sobrien SOLIB_CREATE_INFERIOR_HOOK. 130398944Sobrien 130498944Sobrien For SunOS executables, this first instruction is typically the 130598944Sobrien one at "_start", or a similar text label, regardless of whether 130698944Sobrien the executable is statically or dynamically linked. The runtime 130798944Sobrien startup code takes care of dynamically linking in any shared 130898944Sobrien libraries, once gdb allows the inferior to continue. 130998944Sobrien 131098944Sobrien For SVR4 executables, this first instruction is either the first 131198944Sobrien instruction in the dynamic linker (for dynamically linked 131298944Sobrien executables) or the instruction at "start" for statically linked 131398944Sobrien executables. For dynamically linked executables, the system 131498944Sobrien first exec's /lib/libc.so.N, which contains the dynamic linker, 131598944Sobrien and starts it running. The dynamic linker maps in any needed 131698944Sobrien shared libraries, maps in the actual user executable, and then 131798944Sobrien jumps to "start" in the user executable. 131898944Sobrien 131998944Sobrien For both SunOS shared libraries, and SVR4 shared libraries, we 132098944Sobrien can arrange to cooperate with the dynamic linker to discover the 132198944Sobrien names of shared libraries that are dynamically linked, and the 132298944Sobrien base addresses to which they are linked. 132398944Sobrien 132498944Sobrien This function is responsible for discovering those names and 132598944Sobrien addresses, and saving sufficient information about them to allow 132698944Sobrien their symbols to be read at a later time. 132798944Sobrien 132898944Sobrien FIXME 132998944Sobrien 133098944Sobrien Between enable_break() and disable_break(), this code does not 133198944Sobrien properly handle hitting breakpoints which the user might have 133298944Sobrien set in the startup code or in the dynamic linker itself. Proper 133398944Sobrien handling will probably have to wait until the implementation is 133498944Sobrien changed to use the "breakpoint handler function" method. 133598944Sobrien 133698944Sobrien Also, what if child has exit()ed? Must exit loop somehow. 133798944Sobrien */ 133898944Sobrien 133998944Sobrienstatic void 134098944Sobriensvr4_solib_create_inferior_hook (void) 134198944Sobrien{ 134298944Sobrien /* Relocate the main executable if necessary. */ 134398944Sobrien svr4_relocate_main_executable (); 134498944Sobrien 1345130803Smarcel if (!svr4_have_link_map_offsets ()) 1346130803Smarcel { 1347130803Smarcel warning ("no shared library support for this OS / ABI"); 1348130803Smarcel return; 1349130803Smarcel 1350130803Smarcel } 1351130803Smarcel 135298944Sobrien if (!enable_break ()) 135398944Sobrien { 135498944Sobrien warning ("shared library handler failed to enable breakpoint"); 135598944Sobrien return; 135698944Sobrien } 135798944Sobrien 135898944Sobrien#if defined(_SCO_DS) 135998944Sobrien /* SCO needs the loop below, other systems should be using the 136098944Sobrien special shared library breakpoints and the shared library breakpoint 136198944Sobrien service routine. 136298944Sobrien 136398944Sobrien Now run the target. It will eventually hit the breakpoint, at 136498944Sobrien which point all of the libraries will have been mapped in and we 136598944Sobrien can go groveling around in the dynamic linker structures to find 136698944Sobrien out what we need to know about them. */ 136798944Sobrien 136898944Sobrien clear_proceed_status (); 1369130803Smarcel stop_soon = STOP_QUIETLY; 137098944Sobrien stop_signal = TARGET_SIGNAL_0; 137198944Sobrien do 137298944Sobrien { 137398944Sobrien target_resume (pid_to_ptid (-1), 0, stop_signal); 137498944Sobrien wait_for_inferior (); 137598944Sobrien } 137698944Sobrien while (stop_signal != TARGET_SIGNAL_TRAP); 1377130803Smarcel stop_soon = NO_STOP_QUIETLY; 137898944Sobrien#endif /* defined(_SCO_DS) */ 137998944Sobrien} 138098944Sobrien 138198944Sobrienstatic void 138298944Sobriensvr4_clear_solib (void) 138398944Sobrien{ 138498944Sobrien debug_base = 0; 138598944Sobrien} 138698944Sobrien 138798944Sobrienstatic void 138898944Sobriensvr4_free_so (struct so_list *so) 138998944Sobrien{ 139098944Sobrien xfree (so->lm_info->lm); 139198944Sobrien xfree (so->lm_info); 139298944Sobrien} 139398944Sobrien 139498944Sobrien 139598944Sobrien/* Clear any bits of ADDR that wouldn't fit in a target-format 139698944Sobrien data pointer. "Data pointer" here refers to whatever sort of 139798944Sobrien address the dynamic linker uses to manage its sections. At the 139898944Sobrien moment, we don't support shared libraries on any processors where 139998944Sobrien code and data pointers are different sizes. 140098944Sobrien 140198944Sobrien This isn't really the right solution. What we really need here is 140298944Sobrien a way to do arithmetic on CORE_ADDR values that respects the 140398944Sobrien natural pointer/address correspondence. (For example, on the MIPS, 140498944Sobrien converting a 32-bit pointer to a 64-bit CORE_ADDR requires you to 140598944Sobrien sign-extend the value. There, simply truncating the bits above 140698944Sobrien TARGET_PTR_BIT, as we do below, is no good.) This should probably 140798944Sobrien be a new gdbarch method or something. */ 140898944Sobrienstatic CORE_ADDR 140998944Sobriensvr4_truncate_ptr (CORE_ADDR addr) 141098944Sobrien{ 141198944Sobrien if (TARGET_PTR_BIT == sizeof (CORE_ADDR) * 8) 141298944Sobrien /* We don't need to truncate anything, and the bit twiddling below 141398944Sobrien will fail due to overflow problems. */ 141498944Sobrien return addr; 141598944Sobrien else 141698944Sobrien return addr & (((CORE_ADDR) 1 << TARGET_PTR_BIT) - 1); 141798944Sobrien} 141898944Sobrien 141998944Sobrien 142098944Sobrienstatic void 142198944Sobriensvr4_relocate_section_addresses (struct so_list *so, 142298944Sobrien struct section_table *sec) 142398944Sobrien{ 142498944Sobrien sec->addr = svr4_truncate_ptr (sec->addr + LM_ADDR (so)); 142598944Sobrien sec->endaddr = svr4_truncate_ptr (sec->endaddr + LM_ADDR (so)); 142698944Sobrien} 142798944Sobrien 142898944Sobrien 142998944Sobrien/* Fetch a link_map_offsets structure for native targets using struct 143098944Sobrien definitions from link.h. See solib-legacy.c for the function 143198944Sobrien which does the actual work. 143298944Sobrien 143398944Sobrien Note: For non-native targets (i.e. cross-debugging situations), 143498944Sobrien a target specific fetch_link_map_offsets() function should be 143598944Sobrien defined and registered via set_solib_svr4_fetch_link_map_offsets(). */ 143698944Sobrien 143798944Sobrienstatic struct link_map_offsets * 143898944Sobrienlegacy_fetch_link_map_offsets (void) 143998944Sobrien{ 144098944Sobrien if (legacy_svr4_fetch_link_map_offsets_hook) 144198944Sobrien return legacy_svr4_fetch_link_map_offsets_hook (); 144298944Sobrien else 144398944Sobrien { 144498944Sobrien internal_error (__FILE__, __LINE__, 144598944Sobrien "legacy_fetch_link_map_offsets called without legacy " 144698944Sobrien "link_map support enabled."); 144798944Sobrien return 0; 144898944Sobrien } 144998944Sobrien} 145098944Sobrien 145198944Sobrien/* Fetch a link_map_offsets structure using the method registered in the 145298944Sobrien architecture vector. */ 145398944Sobrien 145498944Sobrienstatic struct link_map_offsets * 145598944Sobriensvr4_fetch_link_map_offsets (void) 145698944Sobrien{ 145798944Sobrien struct link_map_offsets *(*flmo)(void) = 1458130803Smarcel gdbarch_data (current_gdbarch, fetch_link_map_offsets_gdbarch_data); 145998944Sobrien 146098944Sobrien if (flmo == NULL) 146198944Sobrien { 146298944Sobrien internal_error (__FILE__, __LINE__, 146398944Sobrien "svr4_fetch_link_map_offsets: fetch_link_map_offsets " 146498944Sobrien "method not defined for this architecture."); 146598944Sobrien return 0; 146698944Sobrien } 146798944Sobrien else 146898944Sobrien return (flmo ()); 146998944Sobrien} 147098944Sobrien 1471130803Smarcel/* Return 1 if a link map offset fetcher has been defined, 0 otherwise. */ 1472130803Smarcelstatic int 1473130803Smarcelsvr4_have_link_map_offsets (void) 1474130803Smarcel{ 1475130803Smarcel struct link_map_offsets *(*flmo)(void) = 1476130803Smarcel gdbarch_data (current_gdbarch, fetch_link_map_offsets_gdbarch_data); 1477130803Smarcel if (flmo == NULL 1478130803Smarcel || (flmo == legacy_fetch_link_map_offsets 1479130803Smarcel && legacy_svr4_fetch_link_map_offsets_hook == NULL)) 1480130803Smarcel return 0; 1481130803Smarcel else 1482130803Smarcel return 1; 1483130803Smarcel} 1484130803Smarcel 148598944Sobrien/* set_solib_svr4_fetch_link_map_offsets() is intended to be called by 148698944Sobrien a <arch>_gdbarch_init() function. It is used to establish an 148798944Sobrien architecture specific link_map_offsets fetcher for the architecture 148898944Sobrien being defined. */ 148998944Sobrien 149098944Sobrienvoid 149198944Sobrienset_solib_svr4_fetch_link_map_offsets (struct gdbarch *gdbarch, 149298944Sobrien struct link_map_offsets *(*flmo) (void)) 149398944Sobrien{ 149498944Sobrien set_gdbarch_data (gdbarch, fetch_link_map_offsets_gdbarch_data, flmo); 149598944Sobrien} 149698944Sobrien 1497130803Smarcel/* Initialize the architecture-specific link_map_offsets fetcher. 1498130803Smarcel This is called after <arch>_gdbarch_init() has set up its `struct 1499130803Smarcel gdbarch' for the new architecture, and is only called if the 1500130803Smarcel link_map_offsets fetcher isn't already initialized (which is 1501130803Smarcel usually done by calling set_solib_svr4_fetch_link_map_offsets() 1502130803Smarcel above in <arch>_gdbarch_init()). Therefore we attempt to provide a 1503130803Smarcel reasonable alternative (for native targets anyway) if the 1504130803Smarcel <arch>_gdbarch_init() fails to call 150598944Sobrien set_solib_svr4_fetch_link_map_offsets(). */ 150698944Sobrien 150798944Sobrienstatic void * 150898944Sobrieninit_fetch_link_map_offsets (struct gdbarch *gdbarch) 150998944Sobrien{ 1510130803Smarcel return legacy_fetch_link_map_offsets; 1511130803Smarcel} 151298944Sobrien 1513130803Smarcel/* Most OS'es that have SVR4-style ELF dynamic libraries define a 1514130803Smarcel `struct r_debug' and a `struct link_map' that are binary compatible 1515130803Smarcel with the origional SVR4 implementation. */ 1516130803Smarcel 1517130803Smarcel/* Fetch (and possibly build) an appropriate `struct link_map_offsets' 1518130803Smarcel for an ILP32 SVR4 system. */ 1519130803Smarcel 1520130803Smarcelstruct link_map_offsets * 1521130803Smarcelsvr4_ilp32_fetch_link_map_offsets (void) 1522130803Smarcel{ 1523130803Smarcel static struct link_map_offsets lmo; 1524130803Smarcel static struct link_map_offsets *lmp = NULL; 1525130803Smarcel 1526130803Smarcel if (lmp == NULL) 1527130803Smarcel { 1528130803Smarcel lmp = &lmo; 1529130803Smarcel 1530130803Smarcel /* Everything we need is in the first 8 bytes. */ 1531130803Smarcel lmo.r_debug_size = 8; 1532130803Smarcel lmo.r_map_offset = 4; 1533130803Smarcel lmo.r_map_size = 4; 1534130803Smarcel 1535130803Smarcel /* Everything we need is in the first 20 bytes. */ 1536130803Smarcel lmo.link_map_size = 20; 1537130803Smarcel lmo.l_addr_offset = 0; 1538130803Smarcel lmo.l_addr_size = 4; 1539130803Smarcel lmo.l_name_offset = 4; 1540130803Smarcel lmo.l_name_size = 4; 1541130803Smarcel lmo.l_next_offset = 12; 1542130803Smarcel lmo.l_next_size = 4; 1543130803Smarcel lmo.l_prev_offset = 16; 1544130803Smarcel lmo.l_prev_size = 4; 1545130803Smarcel } 1546130803Smarcel 1547130803Smarcel return lmp; 154898944Sobrien} 154998944Sobrien 1550130803Smarcel/* Fetch (and possibly build) an appropriate `struct link_map_offsets' 1551130803Smarcel for an LP64 SVR4 system. */ 1552130803Smarcel 1553130803Smarcelstruct link_map_offsets * 1554130803Smarcelsvr4_lp64_fetch_link_map_offsets (void) 1555130803Smarcel{ 1556130803Smarcel static struct link_map_offsets lmo; 1557130803Smarcel static struct link_map_offsets *lmp = NULL; 1558130803Smarcel 1559130803Smarcel if (lmp == NULL) 1560130803Smarcel { 1561130803Smarcel lmp = &lmo; 1562130803Smarcel 1563130803Smarcel /* Everything we need is in the first 16 bytes. */ 1564130803Smarcel lmo.r_debug_size = 16; 1565130803Smarcel lmo.r_map_offset = 8; 1566130803Smarcel lmo.r_map_size = 8; 1567130803Smarcel 1568130803Smarcel /* Everything we need is in the first 40 bytes. */ 1569130803Smarcel lmo.link_map_size = 40; 1570130803Smarcel lmo.l_addr_offset = 0; 1571130803Smarcel lmo.l_addr_size = 8; 1572130803Smarcel lmo.l_name_offset = 8; 1573130803Smarcel lmo.l_name_size = 8; 1574130803Smarcel lmo.l_next_offset = 24; 1575130803Smarcel lmo.l_next_size = 8; 1576130803Smarcel lmo.l_prev_offset = 32; 1577130803Smarcel lmo.l_prev_size = 8; 1578130803Smarcel } 1579130803Smarcel 1580130803Smarcel return lmp; 1581130803Smarcel} 1582130803Smarcel 1583130803Smarcel 158498944Sobrienstatic struct target_so_ops svr4_so_ops; 158598944Sobrien 1586130803Smarcelextern initialize_file_ftype _initialize_svr4_solib; /* -Wmissing-prototypes */ 1587130803Smarcel 158898944Sobrienvoid 158998944Sobrien_initialize_svr4_solib (void) 159098944Sobrien{ 159198944Sobrien fetch_link_map_offsets_gdbarch_data = 1592130803Smarcel register_gdbarch_data (init_fetch_link_map_offsets); 159398944Sobrien 159498944Sobrien svr4_so_ops.relocate_section_addresses = svr4_relocate_section_addresses; 159598944Sobrien svr4_so_ops.free_so = svr4_free_so; 159698944Sobrien svr4_so_ops.clear_solib = svr4_clear_solib; 159798944Sobrien svr4_so_ops.solib_create_inferior_hook = svr4_solib_create_inferior_hook; 159898944Sobrien svr4_so_ops.special_symbol_handling = svr4_special_symbol_handling; 159998944Sobrien svr4_so_ops.current_sos = svr4_current_sos; 160098944Sobrien svr4_so_ops.open_symbol_file_object = open_symbol_file_object; 160198944Sobrien svr4_so_ops.in_dynsym_resolve_code = svr4_in_dynsym_resolve_code; 160298944Sobrien 160398944Sobrien /* FIXME: Don't do this here. *_gdbarch_init() should set so_ops. */ 160498944Sobrien current_target_so_ops = &svr4_so_ops; 160598944Sobrien} 1606