* configure: Ignore new autoconf configure options.
[binutils-gdb.git] / gdb / ptx4-nat.c
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..564b79917284368af6feda120d2fdabbccf25271 100644 (file)
@@ -0,0 +1,209 @@
+/* Native-dependent code for ptx 4.0
+   Copyright 1988, 1989, 1991, 1992 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "defs.h"
+#include "inferior.h"
+#include "gdbcore.h"
+#include <sys/procfs.h>
+#include <sys/ptrace.h>
+#include <sys/param.h>
+#include <fcntl.h>
+
+/*  Given a pointer to a general register set in /proc format (gregset_t *),
+    unpack the register contents and supply them as gdb's idea of the current
+    register values. */
+
+void
+supply_gregset (gregsetp)
+     gregset_t *gregsetp;
+{
+       supply_register(EAX_REGNUM, (char *)&(*gregsetp)[EAX]);
+       supply_register(EDX_REGNUM, (char *)&(*gregsetp)[EDX]);
+       supply_register(ECX_REGNUM, (char *)&(*gregsetp)[ECX]);
+       supply_register(EBX_REGNUM, (char *)&(*gregsetp)[EBX]);
+       supply_register(ESI_REGNUM, (char *)&(*gregsetp)[ESI]);
+       supply_register(EDI_REGNUM, (char *)&(*gregsetp)[EDI]);
+       supply_register(ESP_REGNUM, (char *)&(*gregsetp)[UESP]);
+       supply_register(EBP_REGNUM, (char *)&(*gregsetp)[EBP]);
+       supply_register(EIP_REGNUM, (char *)&(*gregsetp)[EIP]);
+       supply_register(EFLAGS_REGNUM, (char *)&(*gregsetp)[EFL]);
+}
+
+void
+fill_gregset (gregsetp, regno)
+     gregset_t *gregsetp;
+     int regno;
+{
+  int regi;
+  extern char registers[];
+
+  for (regi = 0 ; regi < NUM_REGS ; regi++)
+    {
+      if ((regno == -1) || (regno == regi))
+       {
+         (*gregsetp)[regi] = *(greg_t *)&registers[REGISTER_BYTE (regi)];
+       }
+    }
+}
+
+#if defined (FP0_REGNUM)
+
+/*  Given a pointer to a floating point register set in /proc format
+    (fpregset_t *), unpack the register contents and supply them as gdb's
+    idea of the current floating point register values. */
+
+void 
+supply_fpregset (fpregsetp)
+     fpregset_t *fpregsetp;
+{
+  supply_fpu_registers((struct fpusave *)&fpregsetp->fp_reg_set);
+  supply_fpa_registers((struct fpasave *)&fpregsetp->f_wregs);
+}
+
+/*  Given a pointer to a floating point register set in /proc format
+    (fpregset_t *), update the register specified by REGNO from gdb's idea
+    of the current floating point register set.  If REGNO is -1, update
+    them all. */
+
+void
+fill_fpregset (fpregsetp, regno)
+     fpregset_t *fpregsetp;
+     int regno;
+{
+  int regi;
+  char *to;
+  char *from;
+  extern char registers[];
+
+  /* FIXME: see m68k-tdep.c for an example, for the m68k. */
+}
+
+#endif /* defined (FP0_REGNUM) */
+
+/*
+ * This doesn't quite do the same thing as the procfs.c version, but give
+ * it the same name so we don't have to put an ifdef in solib.c.
+ */
+/* this could use elf_interpreter() from elfread.c */
+int
+proc_iterate_over_mappings(func)
+       int (*func) PARAMS ((int, CORE_ADDR));
+{
+       vaddr_t curseg, memptr;
+       pt_vseg_t pv;
+       int rv, cmperr;
+       sec_ptr interp_sec;
+       char *interp_content;
+       int interp_fd, funcstat;
+       unsigned int size;
+       char buf1[NBPG], buf2[NBPG];
+
+       /*
+        * The following is really vile.  We can get the name of the
+        * shared library from the exec_bfd, and we can get a list of
+        * each virtual memory segment, but there is no simple way to
+        * find the mapped segment from the shared library (ala
+        * procfs's PIOCOPENMEM).  As a pretty nasty kludge, we
+        * compare the virtual memory segment to the contents of the
+        * .interp file.  If they match, we assume that we've got the
+        * right one.
+        */
+
+       /*
+        * TODO: for attach, use XPT_OPENT to get the executable, in
+        * case we're attached without knowning the executable's
+        * filename.
+        */
+
+#ifdef VERBOSE_DEBUG
+       printf("proc_iter\n");
+#endif
+       interp_sec = bfd_get_section_by_name(exec_bfd, ".interp");
+       if (!interp_sec) {
+               return 0;
+       }
+
+       size = bfd_section_size(exec_bfd, interp_sec);
+       interp_content = alloca(size);
+       if (0 == bfd_get_section_contents(exec_bfd, interp_sec,
+               interp_content, (file_ptr)0, size)) {
+               return 0;
+       }
+
+#ifdef VERBOSE_DEBUG
+       printf("proc_iter: \"%s\"\n", interp_content);
+#endif
+       interp_fd = open(interp_content, O_RDONLY, 0);
+       if (-1 == interp_fd) {
+               return 0;
+       }
+
+       curseg = 0;
+       while (1) {
+               rv = ptrace(PT_NEXT_VSEG, inferior_pid, &pv, curseg);
+#ifdef VERBOSE_DEBUG
+               printf("PT_NEXT_VSEG: rv %d errno %d\n", rv, errno);
+#endif
+               if (-1 == rv)
+                       break;
+               if (0 == rv)
+                       break;
+#ifdef VERBOSE_DEBUG
+               printf("pv.pv_start 0x%x pv_size 0x%x pv_prot 0x%x\n",
+                      pv.pv_start, pv.pv_size, pv.pv_prot);
+#endif
+               curseg = pv.pv_start + pv.pv_size;
+
+               rv = lseek(interp_fd, 0, SEEK_SET);
+               if (-1 == rv) {
+                       perror("lseek");
+                       close(interp_fd);
+                       return 0;
+               }
+               for (memptr = pv.pv_start; memptr < pv.pv_start + pv.pv_size;
+                    memptr += NBPG) {
+#ifdef VERBOSE_DEBUG
+                       printf("memptr 0x%x\n", memptr);
+#endif
+                       rv = read(interp_fd, buf1, NBPG);
+                       if (-1 == rv) {
+                               perror("read");
+                               close(interp_fd);
+                               return 0;
+                       }
+                       rv = ptrace(PT_RDATA_PAGE, inferior_pid, buf2,
+                                   memptr);
+                       if (-1 == rv) {
+                               perror("ptrace");
+                               close(interp_fd);
+                               return 0;
+                       }
+                       cmperr = memcmp(buf1, buf2, NBPG);
+                       if (cmperr)
+                               break;
+               }
+               if (0 == cmperr) {
+                       /* this is it */
+                       funcstat = (*func)(interp_fd, pv.pv_start);
+                       break;
+               }
+       }
+       close(interp_fd);
+       return 0;
+}