xref: /openbsd-src/gnu/usr.bin/binutils/gdb/solib-irix.c (revision 11efff7f3ac2b3cfeff0c0cddc14294d9b3aca4f)
1b725ae77Skettenis /* Shared library support for IRIX.
2b725ae77Skettenis    Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2004
3b725ae77Skettenis    Free Software Foundation, Inc.
4b725ae77Skettenis 
5b725ae77Skettenis    This file was created using portions of irix5-nat.c originally
6b725ae77Skettenis    contributed to GDB by Ian Lance Taylor.
7b725ae77Skettenis 
8b725ae77Skettenis    This file is part of GDB.
9b725ae77Skettenis 
10b725ae77Skettenis    This program is free software; you can redistribute it and/or modify
11b725ae77Skettenis    it under the terms of the GNU General Public License as published by
12b725ae77Skettenis    the Free Software Foundation; either version 2 of the License, or
13b725ae77Skettenis    (at your option) any later version.
14b725ae77Skettenis 
15b725ae77Skettenis    This program is distributed in the hope that it will be useful,
16b725ae77Skettenis    but WITHOUT ANY WARRANTY; without even the implied warranty of
17b725ae77Skettenis    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18b725ae77Skettenis    GNU General Public License for more details.
19b725ae77Skettenis 
20b725ae77Skettenis    You should have received a copy of the GNU General Public License
21b725ae77Skettenis    along with this program; if not, write to the Free Software
22b725ae77Skettenis    Foundation, Inc., 59 Temple Place - Suite 330,
23b725ae77Skettenis    Boston, MA 02111-1307, USA.  */
24b725ae77Skettenis 
25b725ae77Skettenis #include "defs.h"
26b725ae77Skettenis 
27b725ae77Skettenis #include "symtab.h"
28b725ae77Skettenis #include "bfd.h"
29b725ae77Skettenis /* FIXME: ezannoni/2004-02-13 Verify that the include below is
30b725ae77Skettenis    really needed.  */
31b725ae77Skettenis #include "symfile.h"
32b725ae77Skettenis #include "objfiles.h"
33b725ae77Skettenis #include "gdbcore.h"
34b725ae77Skettenis #include "target.h"
35b725ae77Skettenis #include "inferior.h"
36b725ae77Skettenis 
37b725ae77Skettenis #include "solist.h"
38b725ae77Skettenis 
39b725ae77Skettenis /* Link map info to include in an allocate so_list entry.  Unlike some
40b725ae77Skettenis    of the other solib backends, this (Irix) backend chooses to decode
41b725ae77Skettenis    the link map info obtained from the target and store it as (mostly)
42b725ae77Skettenis    CORE_ADDRs which need no further decoding.  This is more convenient
43b725ae77Skettenis    because there are three different link map formats to worry about.
44b725ae77Skettenis    We use a single routine (fetch_lm_info) to read (and decode) the target
45b725ae77Skettenis    specific link map data.  */
46b725ae77Skettenis 
47b725ae77Skettenis struct lm_info
48b725ae77Skettenis {
49b725ae77Skettenis   CORE_ADDR addr;		/* address of obj_info or obj_list
50b725ae77Skettenis 				   struct on target (from which the
51b725ae77Skettenis 				   following information is obtained).  */
52b725ae77Skettenis   CORE_ADDR next;		/* address of next item in list.  */
53b725ae77Skettenis   CORE_ADDR reloc_offset;	/* amount to relocate by  */
54b725ae77Skettenis   CORE_ADDR pathname_addr;	/* address of pathname  */
55b725ae77Skettenis   int pathname_len;		/* length of pathname */
56b725ae77Skettenis };
57b725ae77Skettenis 
58b725ae77Skettenis /* It's not desirable to use the system header files to obtain the
59b725ae77Skettenis    structure of the obj_list or obj_info structs.  Therefore, we use a
60b725ae77Skettenis    platform neutral representation which has been derived from the IRIX
61b725ae77Skettenis    header files.  */
62b725ae77Skettenis 
63b725ae77Skettenis typedef struct
64b725ae77Skettenis {
65b725ae77Skettenis   char b[4];
66b725ae77Skettenis }
67b725ae77Skettenis gdb_int32_bytes;
68b725ae77Skettenis typedef struct
69b725ae77Skettenis {
70b725ae77Skettenis   char b[8];
71b725ae77Skettenis }
72b725ae77Skettenis gdb_int64_bytes;
73b725ae77Skettenis 
74b725ae77Skettenis /* The "old" obj_list struct.  This is used with old (o32) binaries.
75b725ae77Skettenis    The ``data'' member points at a much larger and more complicated
76b725ae77Skettenis    struct which we will only refer to by offsets.  See
77b725ae77Skettenis    fetch_lm_info().  */
78b725ae77Skettenis 
79b725ae77Skettenis struct irix_obj_list
80b725ae77Skettenis {
81b725ae77Skettenis   gdb_int32_bytes data;
82b725ae77Skettenis   gdb_int32_bytes next;
83b725ae77Skettenis   gdb_int32_bytes prev;
84b725ae77Skettenis };
85b725ae77Skettenis 
86b725ae77Skettenis /* The ELF32 and ELF64 versions of the above struct.  The oi_magic value
87b725ae77Skettenis    corresponds to the ``data'' value in the "old" struct.  When this value
88b725ae77Skettenis    is 0xffffffff, the data will be in one of the following formats.  The
89b725ae77Skettenis    ``oi_size'' field is used to decide which one we actually have.  */
90b725ae77Skettenis 
91b725ae77Skettenis struct irix_elf32_obj_info
92b725ae77Skettenis {
93b725ae77Skettenis   gdb_int32_bytes oi_magic;
94b725ae77Skettenis   gdb_int32_bytes oi_size;
95b725ae77Skettenis   gdb_int32_bytes oi_next;
96b725ae77Skettenis   gdb_int32_bytes oi_prev;
97b725ae77Skettenis   gdb_int32_bytes oi_ehdr;
98b725ae77Skettenis   gdb_int32_bytes oi_orig_ehdr;
99b725ae77Skettenis   gdb_int32_bytes oi_pathname;
100b725ae77Skettenis   gdb_int32_bytes oi_pathname_len;
101b725ae77Skettenis };
102b725ae77Skettenis 
103b725ae77Skettenis struct irix_elf64_obj_info
104b725ae77Skettenis {
105b725ae77Skettenis   gdb_int32_bytes oi_magic;
106b725ae77Skettenis   gdb_int32_bytes oi_size;
107b725ae77Skettenis   gdb_int64_bytes oi_next;
108b725ae77Skettenis   gdb_int64_bytes oi_prev;
109b725ae77Skettenis   gdb_int64_bytes oi_ehdr;
110b725ae77Skettenis   gdb_int64_bytes oi_orig_ehdr;
111b725ae77Skettenis   gdb_int64_bytes oi_pathname;
112b725ae77Skettenis   gdb_int32_bytes oi_pathname_len;
113b725ae77Skettenis   gdb_int32_bytes padding;
114b725ae77Skettenis };
115b725ae77Skettenis 
116b725ae77Skettenis /* Union of all of the above (plus a split out magic field).  */
117b725ae77Skettenis 
118b725ae77Skettenis union irix_obj_info
119b725ae77Skettenis {
120b725ae77Skettenis   gdb_int32_bytes magic;
121b725ae77Skettenis   struct irix_obj_list ol32;
122b725ae77Skettenis   struct irix_elf32_obj_info oi32;
123b725ae77Skettenis   struct irix_elf64_obj_info oi64;
124b725ae77Skettenis };
125b725ae77Skettenis 
126b725ae77Skettenis /* MIPS sign extends its 32 bit addresses.  We could conceivably use
127b725ae77Skettenis    extract_typed_address here, but to do so, we'd have to construct an
128b725ae77Skettenis    appropriate type.  Calling extract_signed_integer seems simpler.  */
129b725ae77Skettenis 
130b725ae77Skettenis static CORE_ADDR
extract_mips_address(void * addr,int len)131b725ae77Skettenis extract_mips_address (void *addr, int len)
132b725ae77Skettenis {
133b725ae77Skettenis   return extract_signed_integer (addr, len);
134b725ae77Skettenis }
135b725ae77Skettenis 
136b725ae77Skettenis /* Fetch and return the link map data associated with ADDR.  Note that
137b725ae77Skettenis    this routine automatically determines which (of three) link map
138b725ae77Skettenis    formats is in use by the target.  */
139b725ae77Skettenis 
140b725ae77Skettenis struct lm_info
fetch_lm_info(CORE_ADDR addr)141b725ae77Skettenis fetch_lm_info (CORE_ADDR addr)
142b725ae77Skettenis {
143b725ae77Skettenis   struct lm_info li;
144b725ae77Skettenis   union irix_obj_info buf;
145b725ae77Skettenis 
146b725ae77Skettenis   li.addr = addr;
147b725ae77Skettenis 
148b725ae77Skettenis   /* The smallest region that we'll need is for buf.ol32.  We'll read
149b725ae77Skettenis      that first.  We'll read more of the buffer later if we have to deal
150b725ae77Skettenis      with one of the other cases.  (We don't want to incur a memory error
151b725ae77Skettenis      if we were to read a larger region that generates an error due to
152b725ae77Skettenis      being at the end of a page or the like.)  */
153b725ae77Skettenis   read_memory (addr, (char *) &buf, sizeof (buf.ol32));
154b725ae77Skettenis 
155b725ae77Skettenis   if (extract_unsigned_integer (&buf.magic, sizeof (buf.magic)) != 0xffffffff)
156b725ae77Skettenis     {
157b725ae77Skettenis       /* Use buf.ol32... */
158b725ae77Skettenis       char obj_buf[432];
159b725ae77Skettenis       CORE_ADDR obj_addr = extract_mips_address (&buf.ol32.data,
160b725ae77Skettenis 						 sizeof (buf.ol32.data));
161b725ae77Skettenis       li.next = extract_mips_address (&buf.ol32.next, sizeof (buf.ol32.next));
162b725ae77Skettenis 
163b725ae77Skettenis       read_memory (obj_addr, obj_buf, sizeof (obj_buf));
164b725ae77Skettenis 
165b725ae77Skettenis       li.pathname_addr = extract_mips_address (&obj_buf[236], 4);
166b725ae77Skettenis       li.pathname_len = 0;	/* unknown */
167b725ae77Skettenis       li.reloc_offset = extract_mips_address (&obj_buf[196], 4)
168b725ae77Skettenis 	- extract_mips_address (&obj_buf[248], 4);
169b725ae77Skettenis 
170b725ae77Skettenis     }
171b725ae77Skettenis   else if (extract_unsigned_integer (&buf.oi32.oi_size,
172b725ae77Skettenis 				     sizeof (buf.oi32.oi_size))
173b725ae77Skettenis 	   == sizeof (buf.oi32))
174b725ae77Skettenis     {
175b725ae77Skettenis       /* Use buf.oi32...  */
176b725ae77Skettenis 
177b725ae77Skettenis       /* Read rest of buffer.  */
178b725ae77Skettenis       read_memory (addr + sizeof (buf.ol32),
179b725ae77Skettenis 		   ((char *) &buf) + sizeof (buf.ol32),
180b725ae77Skettenis 		   sizeof (buf.oi32) - sizeof (buf.ol32));
181b725ae77Skettenis 
182b725ae77Skettenis       /* Fill in fields using buffer contents.  */
183b725ae77Skettenis       li.next = extract_mips_address (&buf.oi32.oi_next,
184b725ae77Skettenis 				      sizeof (buf.oi32.oi_next));
185b725ae77Skettenis       li.reloc_offset = extract_mips_address (&buf.oi32.oi_ehdr,
186b725ae77Skettenis 					      sizeof (buf.oi32.oi_ehdr))
187b725ae77Skettenis 	- extract_mips_address (&buf.oi32.oi_orig_ehdr,
188b725ae77Skettenis 				sizeof (buf.oi32.oi_orig_ehdr));
189b725ae77Skettenis       li.pathname_addr = extract_mips_address (&buf.oi32.oi_pathname,
190b725ae77Skettenis 					       sizeof (buf.oi32.oi_pathname));
191b725ae77Skettenis       li.pathname_len = extract_unsigned_integer (&buf.oi32.oi_pathname_len,
192b725ae77Skettenis 						  sizeof (buf.oi32.
193b725ae77Skettenis 							  oi_pathname_len));
194b725ae77Skettenis     }
195b725ae77Skettenis   else if (extract_unsigned_integer (&buf.oi64.oi_size,
196b725ae77Skettenis 				     sizeof (buf.oi64.oi_size))
197b725ae77Skettenis 	   == sizeof (buf.oi64))
198b725ae77Skettenis     {
199b725ae77Skettenis       /* Use buf.oi64...  */
200b725ae77Skettenis 
201b725ae77Skettenis       /* Read rest of buffer.  */
202b725ae77Skettenis       read_memory (addr + sizeof (buf.ol32),
203b725ae77Skettenis 		   ((char *) &buf) + sizeof (buf.ol32),
204b725ae77Skettenis 		   sizeof (buf.oi64) - sizeof (buf.ol32));
205b725ae77Skettenis 
206b725ae77Skettenis       /* Fill in fields using buffer contents.  */
207b725ae77Skettenis       li.next = extract_mips_address (&buf.oi64.oi_next,
208b725ae77Skettenis 				      sizeof (buf.oi64.oi_next));
209b725ae77Skettenis       li.reloc_offset = extract_mips_address (&buf.oi64.oi_ehdr,
210b725ae77Skettenis 					      sizeof (buf.oi64.oi_ehdr))
211b725ae77Skettenis 	- extract_mips_address (&buf.oi64.oi_orig_ehdr,
212b725ae77Skettenis 				sizeof (buf.oi64.oi_orig_ehdr));
213b725ae77Skettenis       li.pathname_addr = extract_mips_address (&buf.oi64.oi_pathname,
214b725ae77Skettenis 					       sizeof (buf.oi64.oi_pathname));
215b725ae77Skettenis       li.pathname_len = extract_unsigned_integer (&buf.oi64.oi_pathname_len,
216b725ae77Skettenis 						  sizeof (buf.oi64.
217b725ae77Skettenis 							  oi_pathname_len));
218b725ae77Skettenis     }
219b725ae77Skettenis   else
220b725ae77Skettenis     {
221b725ae77Skettenis       error ("Unable to fetch shared library obj_info or obj_list info.");
222b725ae77Skettenis     }
223b725ae77Skettenis 
224b725ae77Skettenis   return li;
225b725ae77Skettenis }
226b725ae77Skettenis 
227b725ae77Skettenis /* The symbol which starts off the list of shared libraries.  */
228b725ae77Skettenis #define DEBUG_BASE "__rld_obj_head"
229b725ae77Skettenis 
230b725ae77Skettenis char shadow_contents[BREAKPOINT_MAX];	/* Stash old bkpt addr contents */
231b725ae77Skettenis 
232b725ae77Skettenis static CORE_ADDR debug_base;	/* Base of dynamic linker structures */
233b725ae77Skettenis static CORE_ADDR breakpoint_addr;	/* Address where end bkpt is set */
234b725ae77Skettenis 
235b725ae77Skettenis /*
236b725ae77Skettenis 
237b725ae77Skettenis    LOCAL FUNCTION
238b725ae77Skettenis 
239b725ae77Skettenis    locate_base -- locate the base address of dynamic linker structs
240b725ae77Skettenis 
241b725ae77Skettenis    SYNOPSIS
242b725ae77Skettenis 
243b725ae77Skettenis    CORE_ADDR locate_base (void)
244b725ae77Skettenis 
245b725ae77Skettenis    DESCRIPTION
246b725ae77Skettenis 
247b725ae77Skettenis    For both the SunOS and SVR4 shared library implementations, if the
248b725ae77Skettenis    inferior executable has been linked dynamically, there is a single
249b725ae77Skettenis    address somewhere in the inferior's data space which is the key to
250b725ae77Skettenis    locating all of the dynamic linker's runtime structures.  This
251b725ae77Skettenis    address is the value of the symbol defined by the macro DEBUG_BASE.
252b725ae77Skettenis    The job of this function is to find and return that address, or to
253b725ae77Skettenis    return 0 if there is no such address (the executable is statically
254b725ae77Skettenis    linked for example).
255b725ae77Skettenis 
256b725ae77Skettenis    For SunOS, the job is almost trivial, since the dynamic linker and
257b725ae77Skettenis    all of it's structures are statically linked to the executable at
258b725ae77Skettenis    link time.  Thus the symbol for the address we are looking for has
259b725ae77Skettenis    already been added to the minimal symbol table for the executable's
260b725ae77Skettenis    objfile at the time the symbol file's symbols were read, and all we
261b725ae77Skettenis    have to do is look it up there.  Note that we explicitly do NOT want
262b725ae77Skettenis    to find the copies in the shared library.
263b725ae77Skettenis 
264b725ae77Skettenis    The SVR4 version is much more complicated because the dynamic linker
265b725ae77Skettenis    and it's structures are located in the shared C library, which gets
266b725ae77Skettenis    run as the executable's "interpreter" by the kernel.  We have to go
267b725ae77Skettenis    to a lot more work to discover the address of DEBUG_BASE.  Because
268b725ae77Skettenis    of this complexity, we cache the value we find and return that value
269b725ae77Skettenis    on subsequent invocations.  Note there is no copy in the executable
270b725ae77Skettenis    symbol tables.
271b725ae77Skettenis 
272b725ae77Skettenis    Irix 5 is basically like SunOS.
273b725ae77Skettenis 
274b725ae77Skettenis    Note that we can assume nothing about the process state at the time
275b725ae77Skettenis    we need to find this address.  We may be stopped on the first instruc-
276b725ae77Skettenis    tion of the interpreter (C shared library), the first instruction of
277b725ae77Skettenis    the executable itself, or somewhere else entirely (if we attached
278b725ae77Skettenis    to the process for example).
279b725ae77Skettenis 
280b725ae77Skettenis  */
281b725ae77Skettenis 
282b725ae77Skettenis static CORE_ADDR
locate_base(void)283b725ae77Skettenis locate_base (void)
284b725ae77Skettenis {
285b725ae77Skettenis   struct minimal_symbol *msymbol;
286b725ae77Skettenis   CORE_ADDR address = 0;
287b725ae77Skettenis 
288b725ae77Skettenis   msymbol = lookup_minimal_symbol (DEBUG_BASE, NULL, symfile_objfile);
289b725ae77Skettenis   if ((msymbol != NULL) && (SYMBOL_VALUE_ADDRESS (msymbol) != 0))
290b725ae77Skettenis     {
291b725ae77Skettenis       address = SYMBOL_VALUE_ADDRESS (msymbol);
292b725ae77Skettenis     }
293b725ae77Skettenis   return (address);
294b725ae77Skettenis }
295b725ae77Skettenis 
296b725ae77Skettenis /*
297b725ae77Skettenis 
298b725ae77Skettenis    LOCAL FUNCTION
299b725ae77Skettenis 
300b725ae77Skettenis    disable_break -- remove the "mapping changed" breakpoint
301b725ae77Skettenis 
302b725ae77Skettenis    SYNOPSIS
303b725ae77Skettenis 
304b725ae77Skettenis    static int disable_break ()
305b725ae77Skettenis 
306b725ae77Skettenis    DESCRIPTION
307b725ae77Skettenis 
308b725ae77Skettenis    Removes the breakpoint that gets hit when the dynamic linker
309b725ae77Skettenis    completes a mapping change.
310b725ae77Skettenis 
311b725ae77Skettenis  */
312b725ae77Skettenis 
313b725ae77Skettenis static int
disable_break(void)314b725ae77Skettenis disable_break (void)
315b725ae77Skettenis {
316b725ae77Skettenis   int status = 1;
317b725ae77Skettenis 
318b725ae77Skettenis 
319b725ae77Skettenis   /* Note that breakpoint address and original contents are in our address
320b725ae77Skettenis      space, so we just need to write the original contents back. */
321b725ae77Skettenis 
322b725ae77Skettenis   if (memory_remove_breakpoint (breakpoint_addr, shadow_contents) != 0)
323b725ae77Skettenis     {
324b725ae77Skettenis       status = 0;
325b725ae77Skettenis     }
326b725ae77Skettenis 
327*11efff7fSkettenis   /* Note that it is possible that we have stopped at a location that
328*11efff7fSkettenis      is different from the location where we inserted our breakpoint.
329*11efff7fSkettenis      On mips-irix, we can actually land in __dbx_init(), so we should
330*11efff7fSkettenis      not check the PC against our breakpoint address here.  See procfs.c
331*11efff7fSkettenis      for more details.  */
332b725ae77Skettenis 
333b725ae77Skettenis   return (status);
334b725ae77Skettenis }
335b725ae77Skettenis 
336b725ae77Skettenis /*
337b725ae77Skettenis 
338b725ae77Skettenis    LOCAL FUNCTION
339b725ae77Skettenis 
340b725ae77Skettenis    enable_break -- arrange for dynamic linker to hit breakpoint
341b725ae77Skettenis 
342b725ae77Skettenis    SYNOPSIS
343b725ae77Skettenis 
344b725ae77Skettenis    int enable_break (void)
345b725ae77Skettenis 
346b725ae77Skettenis    DESCRIPTION
347b725ae77Skettenis 
348b725ae77Skettenis    This functions inserts a breakpoint at the entry point of the
349b725ae77Skettenis    main executable, where all shared libraries are mapped in.
350b725ae77Skettenis  */
351b725ae77Skettenis 
352b725ae77Skettenis static int
enable_break(void)353b725ae77Skettenis enable_break (void)
354b725ae77Skettenis {
355b725ae77Skettenis   if (symfile_objfile != NULL
356b725ae77Skettenis       && target_insert_breakpoint (entry_point_address (),
357b725ae77Skettenis 				   shadow_contents) == 0)
358b725ae77Skettenis     {
359b725ae77Skettenis       breakpoint_addr = entry_point_address ();
360b725ae77Skettenis       return 1;
361b725ae77Skettenis     }
362b725ae77Skettenis 
363b725ae77Skettenis   return 0;
364b725ae77Skettenis }
365b725ae77Skettenis 
366b725ae77Skettenis /*
367b725ae77Skettenis 
368b725ae77Skettenis    LOCAL FUNCTION
369b725ae77Skettenis 
370b725ae77Skettenis    irix_solib_create_inferior_hook -- shared library startup support
371b725ae77Skettenis 
372b725ae77Skettenis    SYNOPSIS
373b725ae77Skettenis 
374b725ae77Skettenis    void solib_create_inferior_hook()
375b725ae77Skettenis 
376b725ae77Skettenis    DESCRIPTION
377b725ae77Skettenis 
378b725ae77Skettenis    When gdb starts up the inferior, it nurses it along (through the
379b725ae77Skettenis    shell) until it is ready to execute it's first instruction.  At this
380b725ae77Skettenis    point, this function gets called via expansion of the macro
381b725ae77Skettenis    SOLIB_CREATE_INFERIOR_HOOK.
382b725ae77Skettenis 
383b725ae77Skettenis    For SunOS executables, this first instruction is typically the
384b725ae77Skettenis    one at "_start", or a similar text label, regardless of whether
385b725ae77Skettenis    the executable is statically or dynamically linked.  The runtime
386b725ae77Skettenis    startup code takes care of dynamically linking in any shared
387b725ae77Skettenis    libraries, once gdb allows the inferior to continue.
388b725ae77Skettenis 
389b725ae77Skettenis    For SVR4 executables, this first instruction is either the first
390b725ae77Skettenis    instruction in the dynamic linker (for dynamically linked
391b725ae77Skettenis    executables) or the instruction at "start" for statically linked
392b725ae77Skettenis    executables.  For dynamically linked executables, the system
393b725ae77Skettenis    first exec's /lib/libc.so.N, which contains the dynamic linker,
394b725ae77Skettenis    and starts it running.  The dynamic linker maps in any needed
395b725ae77Skettenis    shared libraries, maps in the actual user executable, and then
396b725ae77Skettenis    jumps to "start" in the user executable.
397b725ae77Skettenis 
398b725ae77Skettenis    For both SunOS shared libraries, and SVR4 shared libraries, we
399b725ae77Skettenis    can arrange to cooperate with the dynamic linker to discover the
400b725ae77Skettenis    names of shared libraries that are dynamically linked, and the
401b725ae77Skettenis    base addresses to which they are linked.
402b725ae77Skettenis 
403b725ae77Skettenis    This function is responsible for discovering those names and
404b725ae77Skettenis    addresses, and saving sufficient information about them to allow
405b725ae77Skettenis    their symbols to be read at a later time.
406b725ae77Skettenis 
407b725ae77Skettenis    FIXME
408b725ae77Skettenis 
409b725ae77Skettenis    Between enable_break() and disable_break(), this code does not
410b725ae77Skettenis    properly handle hitting breakpoints which the user might have
411b725ae77Skettenis    set in the startup code or in the dynamic linker itself.  Proper
412b725ae77Skettenis    handling will probably have to wait until the implementation is
413b725ae77Skettenis    changed to use the "breakpoint handler function" method.
414b725ae77Skettenis 
415b725ae77Skettenis    Also, what if child has exit()ed?  Must exit loop somehow.
416b725ae77Skettenis  */
417b725ae77Skettenis 
418b725ae77Skettenis static void
irix_solib_create_inferior_hook(void)419b725ae77Skettenis irix_solib_create_inferior_hook (void)
420b725ae77Skettenis {
421b725ae77Skettenis   if (!enable_break ())
422b725ae77Skettenis     {
423b725ae77Skettenis       warning ("shared library handler failed to enable breakpoint");
424b725ae77Skettenis       return;
425b725ae77Skettenis     }
426b725ae77Skettenis 
427b725ae77Skettenis   /* Now run the target.  It will eventually hit the breakpoint, at
428b725ae77Skettenis      which point all of the libraries will have been mapped in and we
429b725ae77Skettenis      can go groveling around in the dynamic linker structures to find
430b725ae77Skettenis      out what we need to know about them. */
431b725ae77Skettenis 
432b725ae77Skettenis   clear_proceed_status ();
433b725ae77Skettenis   stop_soon = STOP_QUIETLY;
434b725ae77Skettenis   stop_signal = TARGET_SIGNAL_0;
435b725ae77Skettenis   do
436b725ae77Skettenis     {
437b725ae77Skettenis       target_resume (pid_to_ptid (-1), 0, stop_signal);
438b725ae77Skettenis       wait_for_inferior ();
439b725ae77Skettenis     }
440b725ae77Skettenis   while (stop_signal != TARGET_SIGNAL_TRAP);
441b725ae77Skettenis 
442b725ae77Skettenis   /* We are now either at the "mapping complete" breakpoint (or somewhere
443b725ae77Skettenis      else, a condition we aren't prepared to deal with anyway), so adjust
444b725ae77Skettenis      the PC as necessary after a breakpoint, disable the breakpoint, and
445b725ae77Skettenis      add any shared libraries that were mapped in. */
446b725ae77Skettenis 
447b725ae77Skettenis   if (!disable_break ())
448b725ae77Skettenis     {
449b725ae77Skettenis       warning ("shared library handler failed to disable breakpoint");
450b725ae77Skettenis     }
451b725ae77Skettenis 
452b725ae77Skettenis   /* solib_add will call reinit_frame_cache.
453b725ae77Skettenis      But we are stopped in the startup code and we might not have symbols
454b725ae77Skettenis      for the startup code, so heuristic_proc_start could be called
455b725ae77Skettenis      and will put out an annoying warning.
456b725ae77Skettenis      Delaying the resetting of stop_soon until after symbol loading
457b725ae77Skettenis      suppresses the warning.  */
458b725ae77Skettenis   solib_add ((char *) 0, 0, (struct target_ops *) 0, auto_solib_add);
459b725ae77Skettenis   stop_soon = NO_STOP_QUIETLY;
460b725ae77Skettenis   re_enable_breakpoints_in_shlibs ();
461b725ae77Skettenis }
462b725ae77Skettenis 
463b725ae77Skettenis /* LOCAL FUNCTION
464b725ae77Skettenis 
465b725ae77Skettenis    current_sos -- build a list of currently loaded shared objects
466b725ae77Skettenis 
467b725ae77Skettenis    SYNOPSIS
468b725ae77Skettenis 
469b725ae77Skettenis    struct so_list *current_sos ()
470b725ae77Skettenis 
471b725ae77Skettenis    DESCRIPTION
472b725ae77Skettenis 
473b725ae77Skettenis    Build a list of `struct so_list' objects describing the shared
474b725ae77Skettenis    objects currently loaded in the inferior.  This list does not
475b725ae77Skettenis    include an entry for the main executable file.
476b725ae77Skettenis 
477b725ae77Skettenis    Note that we only gather information directly available from the
478b725ae77Skettenis    inferior --- we don't examine any of the shared library files
479b725ae77Skettenis    themselves.  The declaration of `struct so_list' says which fields
480b725ae77Skettenis    we provide values for.  */
481b725ae77Skettenis 
482b725ae77Skettenis static struct so_list *
irix_current_sos(void)483b725ae77Skettenis irix_current_sos (void)
484b725ae77Skettenis {
485b725ae77Skettenis   CORE_ADDR lma;
486b725ae77Skettenis   char addr_buf[8];
487b725ae77Skettenis   struct so_list *head = 0;
488b725ae77Skettenis   struct so_list **link_ptr = &head;
489b725ae77Skettenis   int is_first = 1;
490b725ae77Skettenis   struct lm_info lm;
491b725ae77Skettenis 
492b725ae77Skettenis   /* Make sure we've looked up the inferior's dynamic linker's base
493b725ae77Skettenis      structure.  */
494b725ae77Skettenis   if (!debug_base)
495b725ae77Skettenis     {
496b725ae77Skettenis       debug_base = locate_base ();
497b725ae77Skettenis 
498b725ae77Skettenis       /* If we can't find the dynamic linker's base structure, this
499b725ae77Skettenis          must not be a dynamically linked executable.  Hmm.  */
500b725ae77Skettenis       if (!debug_base)
501b725ae77Skettenis 	return 0;
502b725ae77Skettenis     }
503b725ae77Skettenis 
504b725ae77Skettenis   read_memory (debug_base, addr_buf, TARGET_ADDR_BIT / TARGET_CHAR_BIT);
505b725ae77Skettenis   lma = extract_mips_address (addr_buf, TARGET_ADDR_BIT / TARGET_CHAR_BIT);
506b725ae77Skettenis 
507b725ae77Skettenis   while (lma)
508b725ae77Skettenis     {
509b725ae77Skettenis       lm = fetch_lm_info (lma);
510b725ae77Skettenis       if (!is_first)
511b725ae77Skettenis 	{
512b725ae77Skettenis 	  int errcode;
513b725ae77Skettenis 	  char *name_buf;
514b725ae77Skettenis 	  int name_size;
515b725ae77Skettenis 	  struct so_list *new
516b725ae77Skettenis 	    = (struct so_list *) xmalloc (sizeof (struct so_list));
517b725ae77Skettenis 	  struct cleanup *old_chain = make_cleanup (xfree, new);
518b725ae77Skettenis 
519b725ae77Skettenis 	  memset (new, 0, sizeof (*new));
520b725ae77Skettenis 
521b725ae77Skettenis 	  new->lm_info = xmalloc (sizeof (struct lm_info));
522b725ae77Skettenis 	  make_cleanup (xfree, new->lm_info);
523b725ae77Skettenis 
524b725ae77Skettenis 	  *new->lm_info = lm;
525b725ae77Skettenis 
526b725ae77Skettenis 	  /* Extract this shared object's name.  */
527b725ae77Skettenis 	  name_size = lm.pathname_len;
528b725ae77Skettenis 	  if (name_size == 0)
529b725ae77Skettenis 	    name_size = SO_NAME_MAX_PATH_SIZE - 1;
530b725ae77Skettenis 
531b725ae77Skettenis 	  if (name_size >= SO_NAME_MAX_PATH_SIZE)
532b725ae77Skettenis 	    {
533b725ae77Skettenis 	      name_size = SO_NAME_MAX_PATH_SIZE - 1;
534b725ae77Skettenis 	      warning
535b725ae77Skettenis 		("current_sos: truncating name of %d characters to only %d characters",
536b725ae77Skettenis 		 lm.pathname_len, name_size);
537b725ae77Skettenis 	    }
538b725ae77Skettenis 
539b725ae77Skettenis 	  target_read_string (lm.pathname_addr, &name_buf,
540b725ae77Skettenis 			      name_size, &errcode);
541b725ae77Skettenis 	  if (errcode != 0)
542b725ae77Skettenis 	    {
543b725ae77Skettenis 	      warning ("current_sos: Can't read pathname for load map: %s\n",
544b725ae77Skettenis 		       safe_strerror (errcode));
545b725ae77Skettenis 	    }
546b725ae77Skettenis 	  else
547b725ae77Skettenis 	    {
548b725ae77Skettenis 	      strncpy (new->so_name, name_buf, name_size);
549b725ae77Skettenis 	      new->so_name[name_size] = '\0';
550b725ae77Skettenis 	      xfree (name_buf);
551b725ae77Skettenis 	      strcpy (new->so_original_name, new->so_name);
552b725ae77Skettenis 	    }
553b725ae77Skettenis 
554b725ae77Skettenis 	  new->next = 0;
555b725ae77Skettenis 	  *link_ptr = new;
556b725ae77Skettenis 	  link_ptr = &new->next;
557b725ae77Skettenis 
558b725ae77Skettenis 	  discard_cleanups (old_chain);
559b725ae77Skettenis 	}
560b725ae77Skettenis       is_first = 0;
561b725ae77Skettenis       lma = lm.next;
562b725ae77Skettenis     }
563b725ae77Skettenis 
564b725ae77Skettenis   return head;
565b725ae77Skettenis }
566b725ae77Skettenis 
567b725ae77Skettenis /*
568b725ae77Skettenis 
569b725ae77Skettenis   LOCAL FUNCTION
570b725ae77Skettenis 
571b725ae77Skettenis   irix_open_symbol_file_object
572b725ae77Skettenis 
573b725ae77Skettenis   SYNOPSIS
574b725ae77Skettenis 
575b725ae77Skettenis   void irix_open_symbol_file_object (void *from_tty)
576b725ae77Skettenis 
577b725ae77Skettenis   DESCRIPTION
578b725ae77Skettenis 
579b725ae77Skettenis   If no open symbol file, attempt to locate and open the main symbol
580b725ae77Skettenis   file.  On IRIX, this is the first link map entry.  If its name is
581b725ae77Skettenis   here, we can open it.  Useful when attaching to a process without
582b725ae77Skettenis   first loading its symbol file.
583b725ae77Skettenis 
584b725ae77Skettenis   If FROM_TTYP dereferences to a non-zero integer, allow messages to
585b725ae77Skettenis   be printed.  This parameter is a pointer rather than an int because
586b725ae77Skettenis   open_symbol_file_object() is called via catch_errors() and
587b725ae77Skettenis   catch_errors() requires a pointer argument. */
588b725ae77Skettenis 
589b725ae77Skettenis static int
irix_open_symbol_file_object(void * from_ttyp)590b725ae77Skettenis irix_open_symbol_file_object (void *from_ttyp)
591b725ae77Skettenis {
592b725ae77Skettenis   CORE_ADDR lma;
593b725ae77Skettenis   char addr_buf[8];
594b725ae77Skettenis   struct lm_info lm;
595b725ae77Skettenis   struct cleanup *cleanups;
596b725ae77Skettenis   int errcode;
597b725ae77Skettenis   int from_tty = *(int *) from_ttyp;
598b725ae77Skettenis   char *filename;
599b725ae77Skettenis 
600b725ae77Skettenis   if (symfile_objfile)
601b725ae77Skettenis     if (!query ("Attempt to reload symbols from process? "))
602b725ae77Skettenis       return 0;
603b725ae77Skettenis 
604b725ae77Skettenis   if ((debug_base = locate_base ()) == 0)
605b725ae77Skettenis     return 0;			/* failed somehow...  */
606b725ae77Skettenis 
607b725ae77Skettenis   /* First link map member should be the executable.  */
608b725ae77Skettenis   read_memory (debug_base, addr_buf, TARGET_ADDR_BIT / TARGET_CHAR_BIT);
609b725ae77Skettenis   lma = extract_mips_address (addr_buf, TARGET_ADDR_BIT / TARGET_CHAR_BIT);
610b725ae77Skettenis   if (lma == 0)
611b725ae77Skettenis     return 0;			/* failed somehow...  */
612b725ae77Skettenis 
613b725ae77Skettenis   lm = fetch_lm_info (lma);
614b725ae77Skettenis 
615b725ae77Skettenis   if (lm.pathname_addr == 0)
616b725ae77Skettenis     return 0;			/* No filename.  */
617b725ae77Skettenis 
618b725ae77Skettenis   /* Now fetch the filename from target memory.  */
619b725ae77Skettenis   target_read_string (lm.pathname_addr, &filename, SO_NAME_MAX_PATH_SIZE - 1,
620b725ae77Skettenis 		      &errcode);
621b725ae77Skettenis 
622b725ae77Skettenis   if (errcode)
623b725ae77Skettenis     {
624b725ae77Skettenis       warning ("failed to read exec filename from attached file: %s",
625b725ae77Skettenis 	       safe_strerror (errcode));
626b725ae77Skettenis       return 0;
627b725ae77Skettenis     }
628b725ae77Skettenis 
629b725ae77Skettenis   cleanups = make_cleanup (xfree, filename);
630b725ae77Skettenis   /* Have a pathname: read the symbol file.  */
631b725ae77Skettenis   symbol_file_add_main (filename, from_tty);
632b725ae77Skettenis 
633b725ae77Skettenis   do_cleanups (cleanups);
634b725ae77Skettenis 
635b725ae77Skettenis   return 1;
636b725ae77Skettenis }
637b725ae77Skettenis 
638b725ae77Skettenis 
639b725ae77Skettenis /*
640b725ae77Skettenis 
641b725ae77Skettenis    LOCAL FUNCTION
642b725ae77Skettenis 
643b725ae77Skettenis    irix_special_symbol_handling -- additional shared library symbol handling
644b725ae77Skettenis 
645b725ae77Skettenis    SYNOPSIS
646b725ae77Skettenis 
647b725ae77Skettenis    void irix_special_symbol_handling ()
648b725ae77Skettenis 
649b725ae77Skettenis    DESCRIPTION
650b725ae77Skettenis 
651b725ae77Skettenis    Once the symbols from a shared object have been loaded in the usual
652b725ae77Skettenis    way, we are called to do any system specific symbol handling that
653b725ae77Skettenis    is needed.
654b725ae77Skettenis 
655b725ae77Skettenis    For SunOS4, this consisted of grunging around in the dynamic
656b725ae77Skettenis    linkers structures to find symbol definitions for "common" symbols
657b725ae77Skettenis    and adding them to the minimal symbol table for the runtime common
658b725ae77Skettenis    objfile.
659b725ae77Skettenis 
660b725ae77Skettenis    However, for IRIX, there's nothing to do.
661b725ae77Skettenis 
662b725ae77Skettenis  */
663b725ae77Skettenis 
664b725ae77Skettenis static void
irix_special_symbol_handling(void)665b725ae77Skettenis irix_special_symbol_handling (void)
666b725ae77Skettenis {
667b725ae77Skettenis }
668b725ae77Skettenis 
669b725ae77Skettenis /* Using the solist entry SO, relocate the addresses in SEC.  */
670b725ae77Skettenis 
671b725ae77Skettenis static void
irix_relocate_section_addresses(struct so_list * so,struct section_table * sec)672b725ae77Skettenis irix_relocate_section_addresses (struct so_list *so,
673b725ae77Skettenis 				 struct section_table *sec)
674b725ae77Skettenis {
675b725ae77Skettenis   sec->addr += so->lm_info->reloc_offset;
676b725ae77Skettenis   sec->endaddr += so->lm_info->reloc_offset;
677b725ae77Skettenis }
678b725ae77Skettenis 
679b725ae77Skettenis /* Free the lm_info struct.  */
680b725ae77Skettenis 
681b725ae77Skettenis static void
irix_free_so(struct so_list * so)682b725ae77Skettenis irix_free_so (struct so_list *so)
683b725ae77Skettenis {
684b725ae77Skettenis   xfree (so->lm_info);
685b725ae77Skettenis }
686b725ae77Skettenis 
687b725ae77Skettenis /* Clear backend specific state.  */
688b725ae77Skettenis 
689b725ae77Skettenis static void
irix_clear_solib(void)690b725ae77Skettenis irix_clear_solib (void)
691b725ae77Skettenis {
692b725ae77Skettenis   debug_base = 0;
693b725ae77Skettenis }
694b725ae77Skettenis 
695b725ae77Skettenis /* Return 1 if PC lies in the dynamic symbol resolution code of the
696b725ae77Skettenis    run time loader.  */
697b725ae77Skettenis static int
irix_in_dynsym_resolve_code(CORE_ADDR pc)698b725ae77Skettenis irix_in_dynsym_resolve_code (CORE_ADDR pc)
699b725ae77Skettenis {
700b725ae77Skettenis   return 0;
701b725ae77Skettenis }
702b725ae77Skettenis 
703b725ae77Skettenis static struct target_so_ops irix_so_ops;
704b725ae77Skettenis 
705b725ae77Skettenis void
_initialize_irix_solib(void)706b725ae77Skettenis _initialize_irix_solib (void)
707b725ae77Skettenis {
708b725ae77Skettenis   irix_so_ops.relocate_section_addresses = irix_relocate_section_addresses;
709b725ae77Skettenis   irix_so_ops.free_so = irix_free_so;
710b725ae77Skettenis   irix_so_ops.clear_solib = irix_clear_solib;
711b725ae77Skettenis   irix_so_ops.solib_create_inferior_hook = irix_solib_create_inferior_hook;
712b725ae77Skettenis   irix_so_ops.special_symbol_handling = irix_special_symbol_handling;
713b725ae77Skettenis   irix_so_ops.current_sos = irix_current_sos;
714b725ae77Skettenis   irix_so_ops.open_symbol_file_object = irix_open_symbol_file_object;
715b725ae77Skettenis   irix_so_ops.in_dynsym_resolve_code = irix_in_dynsym_resolve_code;
716b725ae77Skettenis 
717b725ae77Skettenis   /* FIXME: Don't do this here.  *_gdbarch_init() should set so_ops. */
718b725ae77Skettenis   current_target_so_ops = &irix_so_ops;
719b725ae77Skettenis }
720