-static void
-fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
- char *core_reg_sect;
- unsigned core_reg_size;
- int which; /* Unused */
- CORE_ADDR reg_addr; /* Unused */
-{
- if (core_reg_size == REGISTER_BYTES)
- {
- memcpy ((char *)registers, core_reg_sect, core_reg_size);
- }
- else if (MIPS_REGSIZE == 4 &&
- core_reg_size == (2 * MIPS_REGSIZE) * NUM_REGS)
- {
- /* This is a core file from a N32 executable, 64 bits are saved
- for all registers. */
- char *srcp = core_reg_sect;
- char *dstp = registers;
- int regno;
-
- for (regno = 0; regno < NUM_REGS; regno++)
- {
- if (regno >= FP0_REGNUM && regno < (FP0_REGNUM + 32))
- {
- /* FIXME, this is wrong, N32 has 64 bit FP regs, but GDB
- currently assumes that they are 32 bit. */
- *dstp++ = *srcp++;
- *dstp++ = *srcp++;
- *dstp++ = *srcp++;
- *dstp++ = *srcp++;
- if (REGISTER_RAW_SIZE(regno) == 4)
- {
- /* copying 4 bytes from eight bytes?
- I don't see how this can be right... */
- srcp += 4;
- }
- else
- {
- /* copy all 8 bytes (sizeof(double)) */
- *dstp++ = *srcp++;
- *dstp++ = *srcp++;
- *dstp++ = *srcp++;
- *dstp++ = *srcp++;
- }
- }
- else
- {
- srcp += 4;
- *dstp++ = *srcp++;
- *dstp++ = *srcp++;
- *dstp++ = *srcp++;
- *dstp++ = *srcp++;
- }
- }
- }
- else
- {
- warning ("wrong size gregset struct in core file");
- return;
- }
-
- registers_fetched ();
-}
-\f
-/* Irix 5 uses what appears to be a unique form of shared library
- support. This is a copy of solib.c modified for Irix 5. */
-/* FIXME: Most of this code could be merged with osfsolib.c and solib.c
- by using next_link_map_member and xfer_link_map_member in solib.c. */
-
-#include <sys/types.h>
-#include <signal.h>
-#include <sys/param.h>
-#include <fcntl.h>
-
-/* <obj.h> includes <sym.h> and <symconst.h>, which causes conflicts
- with our versions of those files included by tm-mips.h. Prevent
- <obj.h> from including them with some appropriate defines. */
-#define __SYM_H__
-#define __SYMCONST_H__
-#include <obj.h>
-#ifdef HAVE_OBJLIST_H
-#include <objlist.h>
-#endif
-
-#ifdef NEW_OBJ_INFO_MAGIC
-#define HANDLE_NEW_OBJ_LIST
-#endif
-
-#include "symtab.h"
-#include "bfd.h"
-#include "symfile.h"
-#include "objfiles.h"
-#include "command.h"
-#include "frame.h"
-#include "gnu-regex.h"
-#include "inferior.h"
-#include "language.h"
-#include "gdbcmd.h"
-
-/* The symbol which starts off the list of shared libraries. */
-#define DEBUG_BASE "__rld_obj_head"
-
-/* Irix 6.x introduces a new variant of object lists.
- To be able to debug O32 executables under Irix 6, we have to handle both
- variants. */
-
-typedef enum
-{
- OBJ_LIST_OLD, /* Pre Irix 6.x object list. */
- OBJ_LIST_32, /* 32 Bit Elf32_Obj_Info. */
- OBJ_LIST_64 /* 64 Bit Elf64_Obj_Info, FIXME not yet implemented. */
-} obj_list_variant;
-
-/* Define our own link_map structure.
- This will help to share code with osfsolib.c and solib.c. */
-
-struct link_map {
- obj_list_variant l_variant; /* which variant of object list */
- CORE_ADDR l_lladdr; /* addr in inferior list was read from */
- CORE_ADDR l_next; /* address of next object list entry */
-};
-
-/* Irix 5 shared objects are pre-linked to particular addresses
- although the dynamic linker may have to relocate them if the
- address ranges of the libraries used by the main program clash.
- The offset is the difference between the address where the object
- is mapped and the binding address of the shared library. */
-#define LM_OFFSET(so) ((so) -> offset)
-/* Loaded address of shared library. */
-#define LM_ADDR(so) ((so) -> lmstart)
-
-char shadow_contents[BREAKPOINT_MAX]; /* Stash old bkpt addr contents */
-
-struct so_list {
- struct so_list *next; /* next structure in linked list */
- struct link_map lm;
- CORE_ADDR offset; /* prelink to load address offset */
- char *so_name; /* shared object lib name */
- CORE_ADDR lmstart; /* lower addr bound of mapped object */
- CORE_ADDR lmend; /* upper addr bound of mapped object */
- char symbols_loaded; /* flag: symbols read in yet? */
- char from_tty; /* flag: print msgs? */
- struct objfile *objfile; /* objfile for loaded lib */
- struct section_table *sections;
- struct section_table *sections_end;
- struct section_table *textsection;
- bfd *abfd;
-};
-
-static struct so_list *so_list_head; /* List of known shared objects */
-static CORE_ADDR debug_base; /* Base of dynamic linker structures */
-static CORE_ADDR breakpoint_addr; /* Address where end bkpt is set */
-
-/* Local function prototypes */
-
-static void
-sharedlibrary_command PARAMS ((char *, int));
-
-static int
-enable_break PARAMS ((void));
-
-static int
-disable_break PARAMS ((void));
-
-static void
-info_sharedlibrary_command PARAMS ((char *, int));
-
-static int
-symbol_add_stub PARAMS ((char *));
-
-static struct so_list *
-find_solib PARAMS ((struct so_list *));
-
-static struct link_map *
-first_link_map_member PARAMS ((void));
-
-static struct link_map *
-next_link_map_member PARAMS ((struct so_list *));
-
-static void
-xfer_link_map_member PARAMS ((struct so_list *, struct link_map *));
-
-static CORE_ADDR
-locate_base PARAMS ((void));
-
-static int
-solib_map_sections PARAMS ((char *));
-
-/*
-
-LOCAL FUNCTION
-
- solib_map_sections -- open bfd and build sections for shared lib
-
-SYNOPSIS
-
- static int solib_map_sections (struct so_list *so)
-
-DESCRIPTION
-
- Given a pointer to one of the shared objects in our list
- of mapped objects, use the recorded name to open a bfd
- descriptor for the object, build a section table, and then
- relocate all the section addresses by the base address at
- which the shared object was mapped.
-
-FIXMES
-
- In most (all?) cases the shared object file name recorded in the
- dynamic linkage tables will be a fully qualified pathname. For
- cases where it isn't, do we really mimic the systems search
- mechanism correctly in the below code (particularly the tilde
- expansion stuff?).
- */
-
-static int
-solib_map_sections (arg)
- char *arg;
-{
- struct so_list *so = (struct so_list *) arg; /* catch_errors bogon */
- char *filename;
- char *scratch_pathname;
- int scratch_chan;
- struct section_table *p;
- struct cleanup *old_chain;
- bfd *abfd;
-
- filename = tilde_expand (so -> so_name);
- old_chain = make_cleanup (free, filename);
-
- scratch_chan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
- &scratch_pathname);
- if (scratch_chan < 0)
- {
- scratch_chan = openp (getenv ("LD_LIBRARY_PATH"), 1, filename,
- O_RDONLY, 0, &scratch_pathname);
- }
- if (scratch_chan < 0)
- {
- perror_with_name (filename);
- }
- /* Leave scratch_pathname allocated. abfd->name will point to it. */
-
- abfd = bfd_fdopenr (scratch_pathname, gnutarget, scratch_chan);
- if (!abfd)
- {
- close (scratch_chan);
- error ("Could not open `%s' as an executable file: %s",
- scratch_pathname, bfd_errmsg (bfd_get_error ()));
- }
- /* Leave bfd open, core_xfer_memory and "info files" need it. */
- so -> abfd = abfd;
- abfd -> cacheable = true;
-
- if (!bfd_check_format (abfd, bfd_object))
- {
- error ("\"%s\": not in executable format: %s.",
- scratch_pathname, bfd_errmsg (bfd_get_error ()));
- }
- if (build_section_table (abfd, &so -> sections, &so -> sections_end))
- {
- error ("Can't find the file sections in `%s': %s",
- bfd_get_filename (exec_bfd), bfd_errmsg (bfd_get_error ()));
- }
-
- for (p = so -> sections; p < so -> sections_end; p++)
- {
- /* Relocate the section binding addresses as recorded in the shared
- object's file by the offset to get the address to which the
- object was actually mapped. */
- p -> addr += LM_OFFSET (so);
- p -> endaddr += LM_OFFSET (so);
- so -> lmend = (CORE_ADDR) max (p -> endaddr, so -> lmend);
- if (STREQ (p -> the_bfd_section -> name, ".text"))
- {
- so -> textsection = p;
- }
- }
-
- /* Free the file names, close the file now. */
- do_cleanups (old_chain);
-
- return (1);
-}
-
-/*
-
-LOCAL FUNCTION
-
- locate_base -- locate the base address of dynamic linker structs
-
-SYNOPSIS
-
- CORE_ADDR locate_base (void)
-
-DESCRIPTION
-
- For both the SunOS and SVR4 shared library implementations, if the
- inferior executable has been linked dynamically, there is a single
- address somewhere in the inferior's data space which is the key to
- locating all of the dynamic linker's runtime structures. This
- address is the value of the symbol defined by the macro DEBUG_BASE.
- The job of this function is to find and return that address, or to
- return 0 if there is no such address (the executable is statically
- linked for example).
-
- For SunOS, the job is almost trivial, since the dynamic linker and
- all of it's structures are statically linked to the executable at
- link time. Thus the symbol for the address we are looking for has
- already been added to the minimal symbol table for the executable's
- objfile at the time the symbol file's symbols were read, and all we
- have to do is look it up there. Note that we explicitly do NOT want
- to find the copies in the shared library.
-
- The SVR4 version is much more complicated because the dynamic linker
- and it's structures are located in the shared C library, which gets
- run as the executable's "interpreter" by the kernel. We have to go
- to a lot more work to discover the address of DEBUG_BASE. Because
- of this complexity, we cache the value we find and return that value
- on subsequent invocations. Note there is no copy in the executable
- symbol tables.
-
- Irix 5 is basically like SunOS.
-
- Note that we can assume nothing about the process state at the time
- we need to find this address. We may be stopped on the first instruc-
- tion of the interpreter (C shared library), the first instruction of
- the executable itself, or somewhere else entirely (if we attached
- to the process for example).
-
- */
-
-static CORE_ADDR
-locate_base ()
-{
- struct minimal_symbol *msymbol;
- CORE_ADDR address = 0;
-
- msymbol = lookup_minimal_symbol (DEBUG_BASE, NULL, symfile_objfile);
- if ((msymbol != NULL) && (SYMBOL_VALUE_ADDRESS (msymbol) != 0))
- {
- address = SYMBOL_VALUE_ADDRESS (msymbol);
- }
- return (address);
-}
-
-/*
-
-LOCAL FUNCTION
-
- first_link_map_member -- locate first member in dynamic linker's map
-
-SYNOPSIS
-
- static struct link_map *first_link_map_member (void)
-
-DESCRIPTION
-
- Read in a copy of the first member in the inferior's dynamic
- link map from the inferior's dynamic linker structures, and return
- a pointer to the link map descriptor.
-*/
-
-static struct link_map *
-first_link_map_member ()
-{
- struct obj_list *listp;
- struct obj_list list_old;
- struct link_map *lm;
- static struct link_map first_lm;
- CORE_ADDR lladdr;
- CORE_ADDR next_lladdr;
-
- /* We have not already read in the dynamic linking structures
- from the inferior, lookup the address of the base structure. */
- debug_base = locate_base ();
- if (debug_base == 0)
- return NULL;
-
- /* Get address of first list entry. */
- read_memory (debug_base, (char *) &listp, sizeof (struct obj_list *));
-
- if (listp == NULL)
- return NULL;
-
- /* Get first list entry. */
- lladdr = (CORE_ADDR) listp;
- read_memory (lladdr, (char *) &list_old, sizeof (struct obj_list));
-
- /* The first entry in the list is the object file we are debugging,
- so skip it. */
- next_lladdr = (CORE_ADDR) list_old.next;
-
-#ifdef HANDLE_NEW_OBJ_LIST
- if (list_old.data == NEW_OBJ_INFO_MAGIC)
- {
- Elf32_Obj_Info list_32;
-
- read_memory (lladdr, (char *) &list_32, sizeof (Elf32_Obj_Info));
- if (list_32.oi_size != sizeof (Elf32_Obj_Info))
- return NULL;
- next_lladdr = (CORE_ADDR) list_32.oi_next;
- }
-#endif
-
- if (next_lladdr == 0)
- return NULL;
-
- first_lm.l_lladdr = next_lladdr;
- lm = &first_lm;
- return lm;
-}
-
-/*
-
-LOCAL FUNCTION
-
- next_link_map_member -- locate next member in dynamic linker's map
-
-SYNOPSIS
-
- static struct link_map *next_link_map_member (so_list_ptr)
-
-DESCRIPTION
-
- Read in a copy of the next member in the inferior's dynamic
- link map from the inferior's dynamic linker structures, and return
- a pointer to the link map descriptor.
-*/
-
-static struct link_map *
-next_link_map_member (so_list_ptr)
- struct so_list *so_list_ptr;
-{
- struct link_map *lm = &so_list_ptr -> lm;
- CORE_ADDR next_lladdr = lm -> l_next;
- static struct link_map next_lm;
-
- if (next_lladdr == 0)
- {
- /* We have hit the end of the list, so check to see if any were
- added, but be quiet if we can't read from the target any more. */
- int status = 0;
-
- if (lm -> l_variant == OBJ_LIST_OLD)
- {
- struct obj_list list_old;
-
- status = target_read_memory (lm -> l_lladdr,
- (char *) &list_old,
- sizeof (struct obj_list));
- next_lladdr = (CORE_ADDR) list_old.next;
- }
-#ifdef HANDLE_NEW_OBJ_LIST
- else if (lm -> l_variant == OBJ_LIST_32)
- {
- Elf32_Obj_Info list_32;
- status = target_read_memory (lm -> l_lladdr,
- (char *) &list_32,
- sizeof (Elf32_Obj_Info));
- next_lladdr = (CORE_ADDR) list_32.oi_next;
- }
-#endif
-
- if (status != 0 || next_lladdr == 0)
- return NULL;
- }
-
- next_lm.l_lladdr = next_lladdr;
- lm = &next_lm;
- return lm;
-}
-
-/*
-
-LOCAL FUNCTION
-
- xfer_link_map_member -- set local variables from dynamic linker's map
-
-SYNOPSIS
-
- static void xfer_link_map_member (so_list_ptr, lm)
-
-DESCRIPTION
-
- Read in a copy of the requested member in the inferior's dynamic
- link map from the inferior's dynamic linker structures, and fill
- in the necessary so_list_ptr elements.
-*/
-
-static void
-xfer_link_map_member (so_list_ptr, lm)
- struct so_list *so_list_ptr;
- struct link_map *lm;
-{
- struct obj_list list_old;
- CORE_ADDR lladdr = lm -> l_lladdr;
- struct link_map *new_lm = &so_list_ptr -> lm;
- int errcode;
-
- read_memory (lladdr, (char *) &list_old, sizeof (struct obj_list));
-
- new_lm -> l_variant = OBJ_LIST_OLD;
- new_lm -> l_lladdr = lladdr;
- new_lm -> l_next = (CORE_ADDR) list_old.next;
-
-#ifdef HANDLE_NEW_OBJ_LIST
- if (list_old.data == NEW_OBJ_INFO_MAGIC)
- {
- Elf32_Obj_Info list_32;
-
- read_memory (lladdr, (char *) &list_32, sizeof (Elf32_Obj_Info));
- if (list_32.oi_size != sizeof (Elf32_Obj_Info))
- return;
- new_lm -> l_variant = OBJ_LIST_32;
- new_lm -> l_next = (CORE_ADDR) list_32.oi_next;
-
- target_read_string ((CORE_ADDR) list_32.oi_pathname,
- &so_list_ptr -> so_name,
- list_32.oi_pathname_len + 1, &errcode);
- if (errcode != 0)
- memory_error (errcode, (CORE_ADDR) list_32.oi_pathname);
-
- LM_ADDR (so_list_ptr) = (CORE_ADDR) list_32.oi_ehdr;
- LM_OFFSET (so_list_ptr) =
- (CORE_ADDR) list_32.oi_ehdr - (CORE_ADDR) list_32.oi_orig_ehdr;
- }
- else
-#endif
- {
-#if defined (_MIPS_SIM_NABI32) && _MIPS_SIM == _MIPS_SIM_NABI32
- /* If we are compiling GDB under N32 ABI, the alignments in
- the obj struct are different from the O32 ABI and we will get
- wrong values when accessing the struct.
- As a workaround we use fixed values which are good for
- Irix 6.2. */
- char buf[432];
-
- read_memory ((CORE_ADDR) list_old.data, buf, sizeof (buf));
-
- target_read_string (extract_address (&buf[236], 4),
- &so_list_ptr -> so_name,
- INT_MAX, &errcode);
- if (errcode != 0)
- memory_error (errcode, extract_address (&buf[236], 4));
-
- LM_ADDR (so_list_ptr) = extract_address (&buf[196], 4);
- LM_OFFSET (so_list_ptr) =
- extract_address (&buf[196], 4) - extract_address (&buf[248], 4);
-#else
- struct obj obj_old;
-
- read_memory ((CORE_ADDR) list_old.data, (char *) &obj_old,
- sizeof (struct obj));
-
- target_read_string ((CORE_ADDR) obj_old.o_path,
- &so_list_ptr -> so_name,
- INT_MAX, &errcode);
- if (errcode != 0)
- memory_error (errcode, (CORE_ADDR) obj_old.o_path);
-
- LM_ADDR (so_list_ptr) = (CORE_ADDR) obj_old.o_praw;
- LM_OFFSET (so_list_ptr) =
- (CORE_ADDR) obj_old.o_praw - obj_old.o_base_address;
-#endif
- }
-
- catch_errors (solib_map_sections, (char *) so_list_ptr,
- "Error while mapping shared library sections:\n",
- RETURN_MASK_ALL);
-}
-
-
-/*
-
-LOCAL FUNCTION
-
- find_solib -- step through list of shared objects
-
-SYNOPSIS
-
- struct so_list *find_solib (struct so_list *so_list_ptr)
-
-DESCRIPTION
-
- This module contains the routine which finds the names of any
- loaded "images" in the current process. The argument in must be
- NULL on the first call, and then the returned value must be passed
- in on subsequent calls. This provides the capability to "step" down
- the list of loaded objects. On the last object, a NULL value is
- returned.
- */
-
-static struct so_list *
-find_solib (so_list_ptr)
- struct so_list *so_list_ptr; /* Last lm or NULL for first one */
-{
- struct so_list *so_list_next = NULL;
- struct link_map *lm = NULL;
- struct so_list *new;
-
- if (so_list_ptr == NULL)
- {
- /* We are setting up for a new scan through the loaded images. */
- if ((so_list_next = so_list_head) == NULL)
- {
- /* Find the first link map list member. */
- lm = first_link_map_member ();
- }
- }
- else
- {
- /* We have been called before, and are in the process of walking
- the shared library list. Advance to the next shared object. */
- lm = next_link_map_member (so_list_ptr);
- so_list_next = so_list_ptr -> next;
- }
- if ((so_list_next == NULL) && (lm != NULL))
- {
- new = (struct so_list *) xmalloc (sizeof (struct so_list));
- memset ((char *) new, 0, sizeof (struct so_list));
- /* Add the new node as the next node in the list, or as the root
- node if this is the first one. */
- if (so_list_ptr != NULL)
- {
- so_list_ptr -> next = new;
- }
- else
- {
- so_list_head = new;
- }
- so_list_next = new;
- xfer_link_map_member (new, lm);
- }
- return (so_list_next);
-}
-
-/* A small stub to get us past the arg-passing pinhole of catch_errors. */
-
-static int
-symbol_add_stub (arg)
- char *arg;
-{
- register struct so_list *so = (struct so_list *) arg; /* catch_errs bogon */
- CORE_ADDR text_addr = 0;
-
- if (so -> textsection)
- text_addr = so -> textsection -> addr;
- else if (so -> abfd != NULL)
- {
- asection *lowest_sect;
-
- /* If we didn't find a mapped non zero sized .text section, set up
- text_addr so that the relocation in symbol_file_add does no harm. */
-
- lowest_sect = bfd_get_section_by_name (so -> abfd, ".text");
- if (lowest_sect == NULL)
- bfd_map_over_sections (so -> abfd, find_lowest_section,
- (PTR) &lowest_sect);
- if (lowest_sect)
- text_addr = bfd_section_vma (so -> abfd, lowest_sect) + LM_OFFSET (so);
- }
-
- so -> objfile = symbol_file_add (so -> so_name, so -> from_tty,
- text_addr,
- 0, 0, 0, 0, 0);
- return (1);
-}
-
-/*
-
-GLOBAL FUNCTION
-
- solib_add -- add a shared library file to the symtab and section list