* gdb.texinfo: Proofreading changes from Brian Youmans.
[external/binutils.git] / gdb / ptx4-nat.c
1 /* Native-dependent code for ptx 4.0
2    Copyright 1988, 1989, 1991, 1992 Free Software Foundation, Inc.
3
4    This file is part of GDB.
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 59 Temple Place - Suite 330,
19    Boston, MA 02111-1307, USA.  */
20
21 #include "defs.h"
22 #include "inferior.h"
23 #include "gdbcore.h"
24 #include <sys/procfs.h>
25 #include <sys/ptrace.h>
26 #include <sys/param.h>
27 #include <fcntl.h>
28
29 /*  Given a pointer to a general register set in /proc format (gregset_t *),
30    unpack the register contents and supply them as gdb's idea of the current
31    register values. */
32
33 void
34 supply_gregset (gregsetp)
35      gregset_t *gregsetp;
36 {
37   supply_register (EAX_REGNUM, (char *) &(*gregsetp)[EAX]);
38   supply_register (EDX_REGNUM, (char *) &(*gregsetp)[EDX]);
39   supply_register (ECX_REGNUM, (char *) &(*gregsetp)[ECX]);
40   supply_register (EBX_REGNUM, (char *) &(*gregsetp)[EBX]);
41   supply_register (ESI_REGNUM, (char *) &(*gregsetp)[ESI]);
42   supply_register (EDI_REGNUM, (char *) &(*gregsetp)[EDI]);
43   supply_register (ESP_REGNUM, (char *) &(*gregsetp)[UESP]);
44   supply_register (EBP_REGNUM, (char *) &(*gregsetp)[EBP]);
45   supply_register (EIP_REGNUM, (char *) &(*gregsetp)[EIP]);
46   supply_register (EFLAGS_REGNUM, (char *) &(*gregsetp)[EFL]);
47 }
48
49 void
50 fill_gregset (gregsetp, regno)
51      gregset_t *gregsetp;
52      int regno;
53 {
54   int regi;
55
56   for (regi = 0; regi < NUM_REGS; regi++)
57     {
58       if ((regno == -1) || (regno == regi))
59         {
60           (*gregsetp)[regi] = *(greg_t *) & registers[REGISTER_BYTE (regi)];
61         }
62     }
63 }
64
65 #if defined (FP0_REGNUM)
66
67 /*  Given a pointer to a floating point register set in /proc format
68    (fpregset_t *), unpack the register contents and supply them as gdb's
69    idea of the current floating point register values. */
70
71 void
72 supply_fpregset (fpregsetp)
73      fpregset_t *fpregsetp;
74 {
75   supply_fpu_registers ((struct fpusave *) &fpregsetp->fp_reg_set);
76   supply_fpa_registers ((struct fpasave *) &fpregsetp->f_wregs);
77 }
78
79 /*  Given a pointer to a floating point register set in /proc format
80    (fpregset_t *), update the register specified by REGNO from gdb's idea
81    of the current floating point register set.  If REGNO is -1, update
82    them all. */
83
84 void
85 fill_fpregset (fpregsetp, regno)
86      fpregset_t *fpregsetp;
87      int regno;
88 {
89   int regi;
90   char *to;
91   char *from;
92
93   /* FIXME: see m68k-tdep.c for an example, for the m68k. */
94 }
95
96 #endif /* defined (FP0_REGNUM) */
97
98 /*
99  * This doesn't quite do the same thing as the procfs.c version, but give
100  * it the same name so we don't have to put an ifdef in solib.c.
101  */
102 /* this could use elf_interpreter() from elfread.c */
103 int
104 proc_iterate_over_mappings (func)
105      int (*func) PARAMS ((int, CORE_ADDR));
106 {
107   vaddr_t curseg, memptr;
108   pt_vseg_t pv;
109   int rv, cmperr;
110   sec_ptr interp_sec;
111   char *interp_content;
112   int interp_fd, funcstat;
113   unsigned int size;
114   char buf1[NBPG], buf2[NBPG];
115
116   /*
117    * The following is really vile.  We can get the name of the
118    * shared library from the exec_bfd, and we can get a list of
119    * each virtual memory segment, but there is no simple way to
120    * find the mapped segment from the shared library (ala
121    * procfs's PIOCOPENMEM).  As a pretty nasty kludge, we
122    * compare the virtual memory segment to the contents of the
123    * .interp file.  If they match, we assume that we've got the
124    * right one.
125    */
126
127   /*
128    * TODO: for attach, use XPT_OPENT to get the executable, in
129    * case we're attached without knowning the executable's
130    * filename.
131    */
132
133 #ifdef VERBOSE_DEBUG
134   printf ("proc_iter\n");
135 #endif
136   interp_sec = bfd_get_section_by_name (exec_bfd, ".interp");
137   if (!interp_sec)
138     {
139       return 0;
140     }
141
142   size = bfd_section_size (exec_bfd, interp_sec);
143   interp_content = alloca (size);
144   if (0 == bfd_get_section_contents (exec_bfd, interp_sec,
145                                      interp_content, (file_ptr) 0, size))
146     {
147       return 0;
148     }
149
150 #ifdef VERBOSE_DEBUG
151   printf ("proc_iter: \"%s\"\n", interp_content);
152 #endif
153   interp_fd = open (interp_content, O_RDONLY, 0);
154   if (-1 == interp_fd)
155     {
156       return 0;
157     }
158
159   curseg = 0;
160   while (1)
161     {
162       rv = ptrace (PT_NEXT_VSEG, inferior_pid, &pv, curseg);
163 #ifdef VERBOSE_DEBUG
164       printf ("PT_NEXT_VSEG: rv %d errno %d\n", rv, errno);
165 #endif
166       if (-1 == rv)
167         break;
168       if (0 == rv)
169         break;
170 #ifdef VERBOSE_DEBUG
171       printf ("pv.pv_start 0x%x pv_size 0x%x pv_prot 0x%x\n",
172               pv.pv_start, pv.pv_size, pv.pv_prot);
173 #endif
174       curseg = pv.pv_start + pv.pv_size;
175
176       rv = lseek (interp_fd, 0, SEEK_SET);
177       if (-1 == rv)
178         {
179           perror ("lseek");
180           close (interp_fd);
181           return 0;
182         }
183       for (memptr = pv.pv_start; memptr < pv.pv_start + pv.pv_size;
184            memptr += NBPG)
185         {
186 #ifdef VERBOSE_DEBUG
187           printf ("memptr 0x%x\n", memptr);
188 #endif
189           rv = read (interp_fd, buf1, NBPG);
190           if (-1 == rv)
191             {
192               perror ("read");
193               close (interp_fd);
194               return 0;
195             }
196           rv = ptrace (PT_RDATA_PAGE, inferior_pid, buf2,
197                        memptr);
198           if (-1 == rv)
199             {
200               perror ("ptrace");
201               close (interp_fd);
202               return 0;
203             }
204           cmperr = memcmp (buf1, buf2, NBPG);
205           if (cmperr)
206             break;
207         }
208       if (0 == cmperr)
209         {
210           /* this is it */
211           funcstat = (*func) (interp_fd, pv.pv_start);
212           break;
213         }
214     }
215   close (interp_fd);
216   return 0;
217 }