Add support for target specific command line switches to old-style simualtors.
[deliverable/binutils-gdb.git] / gdb / rs6000-nat.c
index 0bf1e32da03f6c8006e0a6303a878c8af8fc4a91..8fb2fecf91f137bcbffba58497c0fb0c1933cfc3 100644 (file)
@@ -1,5 +1,6 @@
 /* IBM RS/6000 native-dependent code for GDB, the GNU debugger.
-   Copyright 1986, 1987, 1989, 1991, 1992, 1994, 1995, 1996, 1997, 1998
+   Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+   1998, 1999, 2000, 2001, 2002
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -29,6 +30,8 @@
 #include "libbfd.h"            /* For bfd_cache_lookup (FIXME) */
 #include "bfd.h"
 #include "gdb-stabs.h"
+#include "regcache.h"
+#include "arch-utils.h"
 
 #include <sys/ptrace.h>
 #include <sys/reg.h>
@@ -157,11 +160,11 @@ static int special_regs[] =
 /* Call ptrace(REQ, ID, ADDR, DATA, BUF). */
 
 static int
-ptrace32 (int req, int id, int *addr, int data, int *buf)
+rs6000_ptrace32 (int req, int id, int *addr, int data, int *buf)
 {
   int ret = ptrace (req, id, (int *)addr, data, buf);
 #if 0
-  printf ("ptrace32 (%d, %d, 0x%x, %08x, 0x%x) = 0x%x\n",
+  printf ("rs6000_ptrace32 (%d, %d, 0x%x, %08x, 0x%x) = 0x%x\n",
          req, id, (unsigned int)addr, data, (unsigned int)buf, ret);
 #endif
   return ret;
@@ -170,7 +173,7 @@ ptrace32 (int req, int id, int *addr, int data, int *buf)
 /* Call ptracex(REQ, ID, ADDR, DATA, BUF). */
 
 static int
-ptrace64 (int req, int id, long long addr, int data, int *buf)
+rs6000_ptrace64 (int req, int id, long long addr, int data, int *buf)
 {
 #ifdef ARCH3264
   int ret = ptracex (req, id, addr, data, buf);
@@ -178,7 +181,7 @@ ptrace64 (int req, int id, long long addr, int data, int *buf)
   int ret = 0;
 #endif
 #if 0
-  printf ("ptrace64 (%d, %d, 0x%llx, %08x, 0x%x) = 0x%x\n",
+  printf ("rs6000_ptrace64 (%d, %d, 0x%llx, %08x, 0x%x) = 0x%x\n",
          req, id, addr, data, (unsigned int)buf, ret);
 #endif
   return ret;
@@ -199,14 +202,17 @@ fetch_register (int regno)
   if (regno >= FP0_REGNUM && regno <= FPLAST_REGNUM)
     {
       nr = regno - FP0_REGNUM + FPR0;
-      ptrace32 (PT_READ_FPR, inferior_pid, addr, nr, 0);
+      rs6000_ptrace32 (PT_READ_FPR, PIDGET (inferior_ptid), addr, nr, 0);
     }
 
   /* Bogus register number. */
   else if (regno > LAST_UISA_SP_REGNUM)
-    fprintf_unfiltered (gdb_stderr,
-                       "gdb error: register no %d not implemented.\n",
-                       regno);
+    {
+      if (regno >= NUM_REGS)
+       fprintf_unfiltered (gdb_stderr,
+                           "gdb error: register no %d not implemented.\n",
+                           regno);
+    }
 
   /* Fixed-point registers. */
   else
@@ -217,13 +223,13 @@ fetch_register (int regno)
        nr = regno;
 
       if (!ARCH64 ())
-       *addr = ptrace32 (PT_READ_GPR, inferior_pid, (int *)nr, 0, 0);
+       *addr = rs6000_ptrace32 (PT_READ_GPR, PIDGET (inferior_ptid), (int *)nr, 0, 0);
       else
        {
          /* PT_READ_GPR requires the buffer parameter to point to long long,
             even if the register is really only 32 bits. */
          long long buf;
-         ptrace64 (PT_READ_GPR, inferior_pid, nr, 0, (int *)&buf);
+         rs6000_ptrace64 (PT_READ_GPR, PIDGET (inferior_ptid), nr, 0, (int *)&buf);
          if (REGISTER_RAW_SIZE (regno) == 8)
            memcpy (addr, &buf, 8);
          else
@@ -258,7 +264,7 @@ store_register (int regno)
   if (regno >= FP0_REGNUM && regno <= FPLAST_REGNUM)
     {
       nr = regno - FP0_REGNUM + FPR0;
-      ptrace32 (PT_WRITE_FPR, inferior_pid, addr, nr, 0);
+      rs6000_ptrace32 (PT_WRITE_FPR, PIDGET (inferior_ptid), addr, nr, 0);
     }
 
   /* Bogus register number. */
@@ -287,7 +293,7 @@ store_register (int regno)
        nr = regno;
 
       if (!ARCH64 ())
-       ptrace32 (PT_WRITE_GPR, inferior_pid, (int *)nr, *addr, 0);
+       rs6000_ptrace32 (PT_WRITE_GPR, PIDGET (inferior_ptid), (int *)nr, *addr, 0);
       else
        {
          /* PT_WRITE_GPR requires the buffer parameter to point to an 8-byte
@@ -297,7 +303,7 @@ store_register (int regno)
            memcpy (&buf, addr, 8);
          else
            buf = *addr;
-         ptrace64 (PT_WRITE_GPR, inferior_pid, nr, 0, (int *)&buf);
+         rs6000_ptrace64 (PT_WRITE_GPR, PIDGET (inferior_ptid), nr, 0, (int *)&buf);
        }
     }
 
@@ -371,9 +377,10 @@ read_word (CORE_ADDR from, int *to, int arch64)
   errno = 0;
 
   if (arch64)
-    *to = ptrace64 (PT_READ_I, inferior_pid, from, 0, NULL);
+    *to = rs6000_ptrace64 (PT_READ_I, PIDGET (inferior_ptid), from, 0, NULL);
   else
-    *to = ptrace32 (PT_READ_I, inferior_pid, (int *)(long) from, 0, NULL);
+    *to = rs6000_ptrace32 (PT_READ_I, PIDGET (inferior_ptid), (int *)(long) from,
+                    0, NULL);
 
   return !errno;
 }
@@ -389,7 +396,8 @@ read_word (CORE_ADDR from, int *to, int arch64)
 
 int
 child_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
-                  int write, struct target_ops *target)
+                  int write, struct mem_attrib *attrib,
+                  struct target_ops *target)
 {
   /* Round starting address down to 32-bit word boundary. */
   int mask = sizeof (int) - 1;
@@ -400,6 +408,9 @@ child_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
     / sizeof (int);
 
   /* Allocate word transfer buffer. */
+  /* FIXME (alloca): This code, cloned from infptrace.c, is unsafe
+     because it uses alloca to allocate a buffer of arbitrary size.
+     For very large xfers, this could crash GDB's stack.  */
   int *buf = (int *) alloca (count * sizeof (int));
 
   int arch64 = ARCH64 ();
@@ -438,9 +449,9 @@ child_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
       for (i = 0, errno = 0; i < count; i++, addr += sizeof (int))
        {
          if (arch64)
-           ptrace64 (PT_WRITE_D, inferior_pid, addr, buf[i], NULL);
+           rs6000_ptrace64 (PT_WRITE_D, PIDGET (inferior_ptid), addr, buf[i], NULL);
          else
-           ptrace32 (PT_WRITE_D, inferior_pid, (int *)(long) addr,
+           rs6000_ptrace32 (PT_WRITE_D, PIDGET (inferior_ptid), (int *)(long) addr,
                      buf[i], NULL);
 
          if (errno)
@@ -479,9 +490,9 @@ exec_one_dummy_insn (void)
   prev_pc = read_pc ();
   write_pc (DUMMY_INSN_ADDR);
   if (ARCH64 ())
-    ret = ptrace64 (PT_CONTINUE, inferior_pid, 1, 0, NULL);
+    ret = rs6000_ptrace64 (PT_CONTINUE, PIDGET (inferior_ptid), 1, 0, NULL);
   else
-    ret = ptrace32 (PT_CONTINUE, inferior_pid, (int *)1, 0, NULL);
+    ret = rs6000_ptrace32 (PT_CONTINUE, PIDGET (inferior_ptid), (int *)1, 0, NULL);
 
   if (ret != 0)
     perror ("pt_continue");
@@ -490,7 +501,7 @@ exec_one_dummy_insn (void)
     {
       pid = wait (&status);
     }
-  while (pid != inferior_pid);
+  while (pid != PIDGET (inferior_ptid));
 
   write_pc (prev_pc);
   target_remove_breakpoint (DUMMY_INSN_ADDR, shadow_contents);
@@ -605,17 +616,20 @@ vmap_symtab (struct vmap *vp)
        return;
       objfile = symfile_objfile;
     }
+  else if (!vp->loaded)
+    /* If symbols are not yet loaded, offsets are not yet valid. */
+    return;
 
   new_offsets = (struct section_offsets *) alloca (SIZEOF_SECTION_OFFSETS);
 
   for (i = 0; i < objfile->num_sections; ++i)
-    ANOFFSET (new_offsets, i) = ANOFFSET (objfile->section_offsets, i);
+    new_offsets->offsets[i] = ANOFFSET (objfile->section_offsets, i);
 
   /* The symbols in the object file are linked to the VMA of the section,
      relocate them VMA relative.  */
-  ANOFFSET (new_offsets, SECT_OFF_TEXT (objfile)) = vp->tstart - vp->tvma;
-  ANOFFSET (new_offsets, SECT_OFF_DATA (objfile)) = vp->dstart - vp->dvma;
-  ANOFFSET (new_offsets, SECT_OFF_BSS (objfile)) = vp->dstart - vp->dvma;
+  new_offsets->offsets[SECT_OFF_TEXT (objfile)] = vp->tstart - vp->tvma;
+  new_offsets->offsets[SECT_OFF_DATA (objfile)] = vp->dstart - vp->dvma;
+  new_offsets->offsets[SECT_OFF_BSS (objfile)] = vp->dstart - vp->dvma;
 
   objfile_relocate (objfile, new_offsets);
 }
@@ -632,6 +646,23 @@ objfile_symbol_add (void *arg)
   return 1;
 }
 
+/* Add symbols for a vmap. Return zero upon error.  */
+
+int
+vmap_add_symbols (struct vmap *vp)
+{
+  if (catch_errors (objfile_symbol_add, vp->objfile,
+                   "Error while reading shared library symbols:\n",
+                   RETURN_MASK_ALL))
+    {
+      /* Note this is only done if symbol reading was successful.  */
+      vp->loaded = 1;
+      vmap_symtab (vp);
+      return 1;
+    }
+  return 0;
+}
+
 /* Add a new vmap entry based on ldinfo() information.
 
    If ldi->ldinfo_fd is not valid (e.g. this struct ld_info is from a
@@ -666,8 +697,11 @@ add_vmap (LdInfo *ldi)
   else
     abfd = bfd_fdopenr (objname, gnutarget, fd);
   if (!abfd)
-    error ("Could not open `%s' as an executable file: %s",
-          objname, bfd_errmsg (bfd_get_error ()));
+    {
+      warning ("Could not open `%s' as an executable file: %s",
+              objname, bfd_errmsg (bfd_get_error ()));
+      return NULL;
+    }
 
   /* make sure we have an object file */
 
@@ -684,41 +718,35 @@ add_vmap (LdInfo *ldi)
 
       if (!last)
        {
+         warning ("\"%s\": member \"%s\" missing.", objname, mem);
          bfd_close (abfd);
-         /* FIXME -- should be error */
-         warning ("\"%s\": member \"%s\" missing.", abfd->filename, mem);
-         return 0;
+         return NULL;
        }
 
       if (!bfd_check_format (last, bfd_object))
        {
-         bfd_close (last);     /* XXX???       */
-         goto obj_err;
+         warning ("\"%s\": member \"%s\" not in executable format: %s.",
+                  objname, mem, bfd_errmsg (bfd_get_error ()));
+         bfd_close (last);
+         bfd_close (abfd);
+         return NULL;
        }
 
       vp = map_vmap (last, abfd);
     }
   else
     {
-    obj_err:
+      warning ("\"%s\": not in executable format: %s.",
+              objname, bfd_errmsg (bfd_get_error ()));
       bfd_close (abfd);
-      error ("\"%s\": not in executable format: %s.",
-            objname, bfd_errmsg (bfd_get_error ()));
-      /*NOTREACHED */
+      return NULL;
     }
   obj = allocate_objfile (vp->bfd, 0);
   vp->objfile = obj;
 
-#ifndef SOLIB_SYMBOLS_MANUAL
-  if (catch_errors (objfile_symbol_add, obj,
-                   "Error while reading shared library symbols:\n",
-                   RETURN_MASK_ALL))
-    {
-      /* Note this is only done if symbol reading was successful.  */
-      vmap_symtab (vp);
-      vp->loaded = 1;
-    }
-#endif
+  /* Always add symbols for the main objfile.  */
+  if (vp == vmap || auto_solib_add)
+    vmap_add_symbols (vp);
   return vp;
 }
 \f
@@ -824,14 +852,12 @@ vmap_ldinfo (LdInfo *ldi)
      running a different copy of the same executable.  */
   if (symfile_objfile != NULL && !got_exec_file)
     {
-      warning_begin ();
-      fputs_unfiltered ("Symbol file ", gdb_stderr);
-      fputs_unfiltered (symfile_objfile->name, gdb_stderr);
-      fputs_unfiltered ("\nis not mapped; discarding it.\n\
+      warning ("Symbol file %s\nis not mapped; discarding it.\n\
 If in fact that file has symbols which the mapped files listed by\n\
 \"info files\" lack, you can load symbols with the \"symbol-file\" or\n\
 \"add-symbol-file\" commands (note that you must take care of relocating\n\
-symbols to the proper address).\n", gdb_stderr);
+symbols to the proper address).",
+              symfile_objfile->name);
       free_objfile (symfile_objfile);
       symfile_objfile = NULL;
     }
@@ -903,14 +929,33 @@ set_host_arch (int pid)
       arch = bfd_arch_powerpc;
       mach = bfd_mach_ppc;
     }
+
+  /* FIXME: schauer/2002-02-25:
+     We don't know if we are executing a 32 or 64 bit executable,
+     and have no way to pass the proper word size to rs6000_gdbarch_init.
+     So we have to avoid switching to a new architecture, if the architecture
+     matches already.
+     Blindly calling rs6000_gdbarch_init used to work in older versions of
+     GDB, as rs6000_gdbarch_init incorrectly used the previous tdep to
+     determine the wordsize.  */
+  if (exec_bfd)
+    {
+      const struct bfd_arch_info *exec_bfd_arch_info;
+
+      exec_bfd_arch_info = bfd_get_arch_info (exec_bfd);
+      if (arch == exec_bfd_arch_info->arch)
+       return;
+    }
+
   bfd_default_set_arch_mach (&abfd, arch, mach);
 
-  memset (&info, 0, sizeof info);
+  gdbarch_info_init (&info);
   info.bfd_arch_info = bfd_get_arch_info (&abfd);
 
   if (!gdbarch_update_p (info))
     {
-      internal_error ("set_host_arch: failed to select architecture");
+      internal_error (__FILE__, __LINE__,
+                     "set_host_arch: failed to select architecture");
     }
 }
 
@@ -931,7 +976,7 @@ xcoff_relocate_symtab (unsigned int pid)
   do
     {
       size = load_segs * ldisize;
-      ldi = (void *) xrealloc (ldi, load_segs * size);
+      ldi = (void *) xrealloc (ldi, size);
 
 #if 0
       /* According to my humble theory, AIX has some timing problems and
@@ -942,9 +987,9 @@ xcoff_relocate_symtab (unsigned int pid)
 #endif
 
       if (arch64)
-       rc = ptrace64 (PT_LDINFO, pid, (unsigned long) ldi, size, NULL);
+       rc = rs6000_ptrace64 (PT_LDINFO, pid, (unsigned long) ldi, size, NULL);
       else
-       rc = ptrace32 (PT_LDINFO, pid, (int *) ldi, size, NULL);
+       rc = rs6000_ptrace32 (PT_LDINFO, pid, (int *) ldi, size, NULL);
 
       if (rc == -1)
         {
@@ -960,7 +1005,7 @@ xcoff_relocate_symtab (unsigned int pid)
        }
     } while (rc == -1);
   if (ldi)
-    free (ldi);
+    xfree (ldi);
 }
 \f
 /* Core file stuff.  */
@@ -985,12 +1030,6 @@ xcoff_relocate_core (struct target_ops *target)
   char *buffer = xmalloc (buffer_size);
   struct cleanup *old = make_cleanup (free_current_contents, &buffer);
 
-  /* FIXME, this restriction should not exist.  For now, though I'll
-     avoid coredumps with error() pending a real fix.  */
-  if (vmap == NULL)
-    error
-      ("Can't debug a core file without an executable file (on the RS/6000)");
-
   ldinfo_sec = bfd_get_section_by_name (core_bfd, ".ldinfo");
   if (ldinfo_sec == NULL)
     {
@@ -1036,12 +1075,16 @@ xcoff_relocate_core (struct target_ops *target)
        ldi->l32.ldinfo_fd = -1;
 
       /* The first ldinfo is for the exec file, allocated elsewhere.  */
-      if (offset == 0)
+      if (offset == 0 && vmap != NULL)
        vp = vmap;
       else
        vp = add_vmap (ldi);
 
+      /* Process next shared library upon error. */
       offset += LDI_NEXT (ldi, arch64);
+      if (vp == NULL)
+       continue;
+
       vmap_secs (vp, ldi, arch64);
 
       /* Unless this is the exec file,
@@ -1125,9 +1168,5 @@ _initialize_core_rs6000 (void)
      starting a child process. */
   rs6000_set_host_arch_hook = set_host_arch;
 
-  /* For native configurations, where this module is included, inform
-     the xcoffsolib module where it can find the function for symbol table
-     relocation at runtime. */
-  xcoff_relocate_symtab_hook = xcoff_relocate_symtab;
   add_core_fns (&rs6000_core_fns);
 }
This page took 0.033183 seconds and 4 git commands to generate.