OSDN Git Service

8c63a9414d948a1e80cd4a053868a5ae16630951
[pf3gnuchains/pf3gnuchains4x.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 }