import gdb-1999-09-08 snapshot
[binutils-gdb.git] / gdb / i386-linux-nat.c
1 /* Native-dependent code for Linux running on i386's, for GDB.
2
3 This file is part of GDB.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18
19 #include "defs.h"
20 #include "inferior.h"
21 #include "gdbcore.h"
22
23 /* For i386_linux_skip_solib_resolver */
24 #include "symtab.h"
25 #include "frame.h"
26 #include "symfile.h"
27 #include "objfiles.h"
28
29 #include <sys/ptrace.h>
30 #include <sys/user.h>
31 #include <sys/procfs.h>
32
33 #ifdef HAVE_SYS_REG_H
34 #include <sys/reg.h>
35 #endif
36
37 /* This is a duplicate of the table in i386-xdep.c. */
38
39 static int regmap[] =
40 {
41 EAX, ECX, EDX, EBX,
42 UESP, EBP, ESI, EDI,
43 EIP, EFL, CS, SS,
44 DS, ES, FS, GS,
45 };
46
47
48 /* FIXME: These routine absolutely depends upon (NUM_REGS - NUM_FREGS)
49 being less than or equal to the number of registers that can be stored
50 in a gregset_t. Note that with the current scheme there will typically
51 be more registers actually stored in a gregset_t that what we know
52 about. This is bogus and should be fixed. */
53
54 /* Given a pointer to a general register set in /proc format (gregset_t *),
55 unpack the register contents and supply them as gdb's idea of the current
56 register values. */
57
58 void
59 supply_gregset (gregsetp)
60 gregset_t *gregsetp;
61 {
62 register int regi;
63 register greg_t *regp = (greg_t *) gregsetp;
64
65 for (regi = 0 ; regi < (NUM_REGS - NUM_FREGS) ; regi++)
66 {
67 supply_register (regi, (char *) (regp + regmap[regi]));
68 }
69 }
70
71 void
72 fill_gregset (gregsetp, regno)
73 gregset_t *gregsetp;
74 int regno;
75 {
76 int regi;
77 register greg_t *regp = (greg_t *) gregsetp;
78
79 for (regi = 0 ; regi < (NUM_REGS - NUM_FREGS) ; regi++)
80 {
81 if ((regno == -1) || (regno == regi))
82 {
83 *(regp + regmap[regi]) = *(int *) &registers[REGISTER_BYTE (regi)];
84 }
85 }
86 }
87
88
89 /* Given a pointer to a floating point register set in (fpregset_t *)
90 format, unpack the register contents and supply them as gdb's
91 idea of the current floating point register values. */
92
93 void
94 supply_fpregset (fpregsetp)
95 fpregset_t *fpregsetp;
96 {
97 register int regi;
98 char *from;
99 from = (char *) &(fpregsetp->st_space[0]);
100 for (regi = FPSTART_REGNUM ; regi <= FPEND_REGNUM ; regi++)
101 {
102 supply_register(regi, from);
103 from += REGISTER_RAW_SIZE(regi);
104 }
105 }
106
107 /* Given a pointer to a floating point register set in (fpregset_t *)
108 format, update all of the registers from gdb's idea
109 of the current floating point register set. */
110
111 void
112 fill_fpregset (fpregsetp, regno)
113 fpregset_t *fpregsetp;
114 int regno;
115 {
116 int regi;
117 char *to;
118 char *from;
119
120 to = (char *) &(fpregsetp->st_space[0]);
121 for (regi = FPSTART_REGNUM ; regi <= FPEND_REGNUM ; regi++)
122 {
123 from = (char *) &registers[REGISTER_BYTE (regi)];
124 memcpy (to, from, REGISTER_RAW_SIZE (regi));
125 to += REGISTER_RAW_SIZE(regi);
126 }
127 }
128
129 /*
130 Get the whole floating point state of the process and
131 store the floating point stack into registers[].
132 */
133 static void
134 fetch_fpregs(void)
135 {
136 int ret, regno;
137 char buf[FPREG_BYTES];
138
139 ret = ptrace (PTRACE_GETFPREGS, inferior_pid, 0, (int)buf);
140 if ( ret < 0 )
141 {
142 warning ("Couldn't get floating point status");
143 return;
144 }
145
146 for ( regno = 0; regno < NUM_FREGS; regno++ )
147 {
148 if ( regno < 7 )
149 supply_register (NUM_REGS-NUM_FREGS+regno, buf + regno*4);
150 else
151 supply_register (NUM_REGS-NUM_FREGS+regno,
152 buf + FPENV_BYTES + (regno-7)*FPREG_RAW_SIZE);
153 }
154
155 }
156
157
158 /*
159 Get the whole floating point state of the process and
160 replace the contents from registers[].
161 */
162 static void
163 store_fpregs(void)
164 {
165 int ret, regno;
166 char buf[FPREG_BYTES];
167
168 ret = ptrace (PTRACE_GETFPREGS, inferior_pid, 0, (int)buf);
169 if ( ret < 0 )
170 {
171 warning ("Couldn't get floating point status");
172 return;
173 }
174
175 for ( regno = 0; regno < NUM_FREGS; regno++ )
176 {
177 if ( register_valid[regno] )
178 {
179 if ( regno < 7 )
180 {
181 read_register_gen (NUM_REGS-NUM_FREGS+regno,
182 buf + regno*4);
183 }
184 else
185 {
186 read_register_gen (NUM_REGS-NUM_FREGS+regno,
187 buf + FPENV_BYTES + (regno-7)*FPREG_RAW_SIZE);
188 }
189 }
190 }
191
192 ret = ptrace (PTRACE_SETFPREGS, inferior_pid, 0, (int)buf);
193 if ( ret < 0 )
194 {
195 warning ("Couldn't write floating point status");
196 return;
197 }
198
199 }
200
201
202 /*
203 Get state of all non-fp registers of the process and
204 store into registers[].
205 */
206 static void
207 fetch_regs(void)
208 {
209 int ret, regno;
210 char buf[17*sizeof(unsigned int)];
211
212 ret = ptrace (PTRACE_GETREGS, inferior_pid, 0, (int)buf);
213 if ( ret < 0 )
214 {
215 warning ("Couldn't get registers");
216 return;
217 }
218
219 for ( regno = 0; regno < NUM_REGS-NUM_FREGS; regno++ )
220 supply_register (regno, buf + register_addr (regno, U_REGS_OFFSET));
221
222 }
223
224
225 /*
226 Get the whole non-floating-point register state of the process and
227 replace them in the process from registers[].
228 */
229 static void
230 store_regs(void)
231 {
232 int ret, regno;
233 char buf[17*sizeof(unsigned int)];
234
235 ret = ptrace (PTRACE_GETREGS, inferior_pid, 0, (int)buf);
236 if ( ret < 0 )
237 {
238 warning ("Couldn't get registers");
239 return;
240 }
241
242 for ( regno = 0; regno < NUM_REGS-NUM_FREGS; regno++ )
243 {
244 if ( register_valid[regno] )
245 read_register_gen (regno, buf + register_addr (regno, U_REGS_OFFSET));
246 }
247
248 ret = ptrace (PTRACE_SETREGS, inferior_pid, 0, (int)buf);
249
250 if ( ret < 0 )
251 {
252 warning ("Couldn't write floating point status");
253 return;
254 }
255
256 }
257
258
259 /* Fetch registers from the child process.
260 Fetch all if regno == -1, otherwise fetch all ordinary
261 registers or all floating point registers depending
262 upon the value of regno. */
263
264 void
265 fetch_inferior_registers (regno)
266 int regno;
267 {
268 if ( (regno < NUM_REGS - NUM_FREGS) || (regno == -1) )
269 fetch_regs();
270
271 if ( (regno >= NUM_REGS - NUM_FREGS) || (regno == -1) )
272 fetch_fpregs();
273 }
274
275
276 /* Store our register values back into the inferior.
277 If REGNO is -1, do this for all registers.
278 Otherwise, REGNO specifies which register, which
279 then determines whether we store all ordinary
280 registers or all of the floating point registers. */
281
282 void
283 store_inferior_registers (regno)
284 int regno;
285 {
286 if ( (regno < NUM_REGS - NUM_FREGS) || (regno == -1) )
287 store_regs();
288
289 if ( (regno >= NUM_REGS - NUM_FREGS) || (regno == -1) )
290 store_fpregs();
291 }
292
293
294 /* Find the minimal symbol named NAME, and return both the minsym
295 struct and its objfile. This probably ought to be in minsym.c, but
296 everything there is trying to deal with things like C++ and
297 SOFUN_ADDRESS_MAYBE_TURQUOISE, ... Since this is so simple, it may
298 be considered too special-purpose for general consumption. */
299
300 static struct minimal_symbol *
301 find_minsym_and_objfile (char *name, struct objfile **objfile_p)
302 {
303 struct objfile *objfile;
304
305 ALL_OBJFILES (objfile)
306 {
307 struct minimal_symbol *msym;
308
309 ALL_OBJFILE_MSYMBOLS (objfile, msym)
310 {
311 if (SYMBOL_NAME (msym)
312 && STREQ (SYMBOL_NAME (msym), name))
313 {
314 *objfile_p = objfile;
315 return msym;
316 }
317 }
318 }
319
320 return 0;
321 }
322
323
324 static CORE_ADDR
325 skip_hurd_resolver (CORE_ADDR pc)
326 {
327 /* The HURD dynamic linker is part of the GNU C library, so many
328 GNU/Linux distributions use it. (All ELF versions, as far as I
329 know.) An unresolved PLT entry points to "_dl_runtime_resolve",
330 which calls "fixup" to patch the PLT, and then passes control to
331 the function.
332
333 We look for the symbol `_dl_runtime_resolve', and find `fixup' in
334 the same objfile. If we are at the entry point of `fixup', then
335 we set a breakpoint at the return address (at the top of the
336 stack), and continue.
337
338 It's kind of gross to do all these checks every time we're
339 called, since they don't change once the executable has gotten
340 started. But this is only a temporary hack --- upcoming versions
341 of Linux will provide a portable, efficient interface for
342 debugging programs that use shared libraries. */
343
344 struct objfile *objfile;
345 struct minimal_symbol *resolver
346 = find_minsym_and_objfile ("_dl_runtime_resolve", &objfile);
347
348 if (resolver)
349 {
350 struct minimal_symbol *fixup
351 = lookup_minimal_symbol ("fixup", 0, objfile);
352
353 if (fixup && SYMBOL_VALUE_ADDRESS (fixup) == pc)
354 return (SAVED_PC_AFTER_CALL (get_current_frame ()));
355 }
356
357 return 0;
358 }
359
360
361 /* See the comments for SKIP_SOLIB_RESOLVER at the top of infrun.c.
362 This function:
363 1) decides whether a PLT has sent us into the linker to resolve
364 a function reference, and
365 2) if so, tells us where to set a temporary breakpoint that will
366 trigger when the dynamic linker is done. */
367
368 CORE_ADDR
369 i386_linux_skip_solib_resolver (CORE_ADDR pc)
370 {
371 CORE_ADDR result;
372
373 /* Plug in functions for other kinds of resolvers here. */
374 result = skip_hurd_resolver (pc);
375 if (result)
376 return result;
377
378 return 0;
379 }