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