OSDN Git Service

2000-01-29 Mark Kettenis <kettenis@gnu.org>
[pf3gnuchains/pf3gnuchains3x.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,
18    Boston, MA 02111-1307, USA.  */
19
20 #include "defs.h"
21 #include "inferior.h"
22 #include "gdbcore.h"
23
24 /* For i386_linux_skip_solib_resolver.  */
25 #include "symtab.h"
26 #include "frame.h"
27 #include "symfile.h"
28 #include "objfiles.h"
29
30 #include <sys/ptrace.h>
31 #include <sys/user.h>
32 #include <sys/procfs.h>
33
34 #ifdef HAVE_SYS_REG_H
35 #include <sys/reg.h>
36 #endif
37
38 /* On Linux, threads are implemented as pseudo-processes, in which
39    case we may be tracing more than one process at a time.  In that
40    case, inferior_pid will contain the main process ID and the
41    individual thread (process) ID mashed together.  These macros are
42    used to separate them out.  These definitions should be overridden
43    if thread support is included.  */
44
45 #if !defined (PIDGET)   /* Default definition for PIDGET/TIDGET.  */
46 #define PIDGET(PID)     PID
47 #define TIDGET(PID)     0
48 #endif
49
50
51 /* The register sets used in Linux ELF core-dumps are identical to the
52    register sets in `struct user' that is used for a.out core-dumps,
53    and is also used by `ptrace'.  The corresponding types are
54    `elf_gregset_t' for the general-purpose registers (with
55    `elf_greg_t' the type of a single GP register) and `elf_fpregset_t'
56    for the floating-point registers.
57
58    Those types used to be available under the names `gregset_t' and
59    `fpregset_t' too, and this file used those names in the past.  But
60    those names are now used for the register sets used in the
61    `mcontext_t' type, and have a different size and layout.  */
62
63 /* Mapping between the general-purpose registers in `struct user'
64    format and GDB's register array layout.  */
65 static int regmap[] = 
66 {
67   EAX, ECX, EDX, EBX,
68   UESP, EBP, ESI, EDI,
69   EIP, EFL, CS, SS,
70   DS, ES, FS, GS
71 };
72
73 /* Which ptrace request retrieves which registers?
74    These apply to the corresponding SET requests as well.  */
75 #define GETREGS_SUPPLIES(regno) \
76   (0 <= (regno) && (regno) <= 15)
77 #define GETFPREGS_SUPPLIES(regno) \
78   (FP0_REGNUM <= (regno) && (regno) <= LAST_FPU_CTRL_REGNUM)
79 #define GETXFPREGS_SUPPLIES(regno) \
80   (FP0_REGNUM <= (regno) && (regno) <= MXCSR_REGNUM)
81
82 /* Does the current host support the GETXFPREGS request?  The header
83    file may or may not define it, and even if it is defined, the
84    kernel will return EIO if it's running on a pre-SSE processor.
85
86    PTRACE_GETXFPREGS is a Cygnus invention, since we wrote our own
87    Linux kernel patch for SSE support.  That patch may or may not
88    actually make it into the official distribution.  If you find that
89    years have gone by since this stuff was added, and Linux isn't
90    using PTRACE_GETXFPREGS, that means that our patch didn't make it,
91    and you can delete this, and the related code.
92
93    My instinct is to attach this to some architecture- or
94    target-specific data structure, but really, a particular GDB
95    process can only run on top of one kernel at a time.  So it's okay
96    for this to be a simple variable.  */
97 int have_ptrace_getxfpregs =
98 #ifdef HAVE_PTRACE_GETXFPREGS
99   1
100 #else
101   0
102 #endif
103 ;
104
105 \f
106 /* Transfering the general-purpose registers between GDB, inferiors
107    and core files.  */
108
109 /* Fill GDB's register array with the genereal-purpose register values
110    in *GREGSETP.  */
111
112 void
113 supply_gregset (elf_gregset_t *gregsetp)
114 {
115   elf_greg_t *regp = (elf_greg_t *) gregsetp;
116   int regi;
117
118   for (regi = 0; regi < NUM_GREGS; regi++)
119     supply_register (regi, (char *) (regp + regmap[regi]));
120 }
121
122 /* Convert the valid general-purpose register values in GDB's register
123    array to `struct user' format and store them in *GREGSETP.  The
124    array VALID indicates which register values are valid.  If VALID is
125    NULL, all registers are assumed to be valid.  */
126
127 static void
128 convert_to_gregset (elf_gregset_t *gregsetp, signed char *valid)
129 {
130   elf_greg_t *regp = (elf_greg_t *) gregsetp;
131   int regi;
132
133   for (regi = 0; regi < NUM_GREGS; regi++)
134     if (! valid || valid[regi])
135       *(regp + regmap[regi]) = * (int *) &registers[REGISTER_BYTE (regi)];
136 }
137
138 /* Fill register REGNO (if it is a general-purpose register) in
139    *GREGSETPS with the value in GDB's register array.  If REGNO is -1,
140    do this for all registers.  */
141 void
142 fill_gregset (elf_gregset_t *gregsetp, int regno)
143 {
144   if (regno == -1)
145     {
146       convert_to_gregset (gregsetp, NULL);
147       return;
148     }
149
150   if (GETREGS_SUPPLIES (regno))
151     {
152       signed char valid[NUM_GREGS];
153
154       memset (valid, 0, sizeof (valid));
155       valid[regno] = 1;
156
157       convert_to_gregset (gregsetp, valid);
158     }
159 }
160
161 /* Fetch all general-purpose registers from process/thread TID and
162    store their values in GDB's register array.  */
163
164 static void
165 fetch_regs (int tid)
166 {
167   elf_gregset_t regs;
168   int ret;
169
170   ret = ptrace (PTRACE_GETREGS, tid, 0, (int) &regs);
171   if (ret < 0)
172     {
173       warning ("Couldn't get registers.");
174       return;
175     }
176
177   supply_gregset (&regs);
178 }
179
180 /* Store all valid general-purpose registers in GDB's register array
181    into the process/thread specified by TID.  */
182
183 static void
184 store_regs (int tid)
185 {
186   elf_gregset_t regs;
187   int ret;
188
189   ret = ptrace (PTRACE_GETREGS, tid, 0, (int) &regs);
190   if (ret < 0)
191     {
192       warning ("Couldn't get registers.");
193       return;
194     }
195
196   convert_to_gregset (&regs, register_valid);
197
198   ret = ptrace (PTRACE_SETREGS, tid, 0, (int) &regs);
199   if (ret < 0)
200     {
201       warning ("Couldn't write registers.");
202       return;
203     }
204 }
205
206 \f
207 /* Transfering floating-point registers between GDB, inferiors and cores.  */
208
209 /* What is the address of st(N) within the floating-point register set F?  */
210 #define FPREG_ADDR(f, n) ((char *) &(f)->st_space + (n) * 10)
211
212 /* Fill GDB's register array with the floating-point register values in
213    *FPREGSETP.  */
214
215 void 
216 supply_fpregset (elf_fpregset_t *fpregsetp)
217 {
218   int reg;
219
220   /* Supply the floating-point registers.  */
221   for (reg = 0; reg < 8; reg++)
222     supply_register (FP0_REGNUM + reg, FPREG_ADDR (fpregsetp, reg));
223
224   supply_register (FCTRL_REGNUM, (char *) &fpregsetp->cwd);
225   supply_register (FSTAT_REGNUM, (char *) &fpregsetp->swd);
226   supply_register (FTAG_REGNUM,  (char *) &fpregsetp->twd);
227   supply_register (FCOFF_REGNUM, (char *) &fpregsetp->fip);
228   supply_register (FDS_REGNUM,   (char *) &fpregsetp->fos);
229   supply_register (FDOFF_REGNUM, (char *) &fpregsetp->foo);
230   
231   /* Extract the code segment and opcode from the  "fcs" member.  */
232   {
233     long l;
234
235     l = fpregsetp->fcs & 0xffff;
236     supply_register (FCS_REGNUM, (char *) &l);
237
238     l = (fpregsetp->fcs >> 16) & ((1 << 11) - 1);
239     supply_register (FOP_REGNUM, (char *) &l);
240   }
241 }
242
243 /* Convert the valid floating-point register values in GDB's register
244    array to `struct user' format and store them in *FPREGSETP.  The
245    array VALID indicates which register values are valid.  If VALID is
246    NULL, all registers are assumed to be valid.  */
247
248 static void
249 convert_to_fpregset (elf_fpregset_t *fpregsetp, signed char *valid)
250 {
251   int reg;
252
253   /* Fill in the floating-point registers.  */
254   for (reg = 0; reg < 8; reg++)
255     if (!valid || valid[reg])
256       memcpy (FPREG_ADDR (fpregsetp, reg),
257               &registers[REGISTER_BYTE (FP0_REGNUM + reg)],
258               REGISTER_RAW_SIZE(FP0_REGNUM + reg));
259
260 #define fill(MEMBER, REGNO)                                             \
261   if (! valid || valid[(REGNO)])                                        \
262     memcpy (&fpregsetp->MEMBER, &registers[REGISTER_BYTE (REGNO)],      \
263             sizeof (fpregsetp->MEMBER))
264
265   fill (cwd, FCTRL_REGNUM);
266   fill (swd, FSTAT_REGNUM);
267   fill (twd, FTAG_REGNUM);
268   fill (fip, FCOFF_REGNUM);
269   fill (foo, FDOFF_REGNUM);
270   fill (fos, FDS_REGNUM);
271
272 #undef fill
273
274   if (! valid || valid[FCS_REGNUM])
275     fpregsetp->fcs
276       = ((fpregsetp->fcs & ~0xffff)
277          | (* (int *) &registers[REGISTER_BYTE (FCS_REGNUM)] & 0xffff));
278
279   if (! valid || valid[FOP_REGNUM])
280     fpregsetp->fcs
281       = ((fpregsetp->fcs & 0xffff)
282          | ((*(int *) &registers[REGISTER_BYTE (FOP_REGNUM)] & ((1 << 11) - 1))
283             << 16));
284 }
285
286 /* Fill register REGNO (if it is a floating-point register) in
287    *FPREGSETP with the value in GDB's register array.  If REGNO is -1,
288    do this for all registers.  */
289
290 void
291 fill_fpregset (elf_fpregset_t *fpregsetp, int regno)
292 {
293   if (regno == -1)
294     {
295       convert_to_fpregset (fpregsetp, NULL);
296       return;
297     }
298
299   if (GETFPREGS_SUPPLIES(regno))
300     {
301       signed char valid[MAX_NUM_REGS];
302       
303       memset (valid, 0, sizeof (valid));
304       valid[regno] = 1;
305               
306       convert_to_fpregset (fpregsetp, valid);
307     }
308 }
309
310 /* Fetch all floating-point registers from process/thread TID and store
311    thier values in GDB's register array.  */
312
313 static void
314 fetch_fpregs (int tid)
315 {
316   elf_fpregset_t fpregs;
317   int ret;
318
319   ret = ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs);
320   if (ret < 0)
321     {
322       warning ("Couldn't get floating point status.");
323       return;
324     }
325
326   supply_fpregset (&fpregs);
327 }
328
329 /* Store all valid floating-point registers in GDB's register array
330    into the process/thread specified by TID.  */
331
332 static void
333 store_fpregs (int tid)
334 {
335   elf_fpregset_t fpregs;
336   int ret;
337
338   ret = ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs);
339   if (ret < 0)
340     {
341       warning ("Couldn't get floating point status.");
342       return;
343     }
344
345   convert_to_fpregset (&fpregs, register_valid);
346
347   ret = ptrace (PTRACE_SETFPREGS, tid, 0, (int) &fpregs);
348   if (ret < 0)
349     {
350       warning ("Couldn't write floating point status.");
351       return;
352     }
353 }
354
355 \f
356 /* Transfering floating-point and SSE registers to and from GDB.  */
357
358 /* PTRACE_GETXFPREGS is a Cygnus invention, since we wrote our own
359    Linux kernel patch for SSE support.  That patch may or may not
360    actually make it into the official distribution.  If you find that
361    years have gone by since this code was added, and Linux isn't using
362    PTRACE_GETXFPREGS, that means that our patch didn't make it, and
363    you can delete this code.  */
364
365 #ifdef HAVE_PTRACE_GETXFPREGS
366
367 /* Fill GDB's register array with the floating-point and SSE register
368    values in *XFPREGS.  */
369
370 static void
371 supply_xfpregset (struct user_xfpregs_struct *xfpregs)
372 {
373   int reg;
374
375   /* Supply the floating-point registers.  */
376   for (reg = 0; reg < 8; reg++)
377     supply_register (FP0_REGNUM + reg, (char *) &xfpregs->st_space[reg]);
378
379   {
380     supply_register (FCTRL_REGNUM, (char *) &xfpregs->cwd);
381     supply_register (FSTAT_REGNUM, (char *) &xfpregs->swd);
382     supply_register (FTAG_REGNUM,  (char *) &xfpregs->twd);
383     supply_register (FCOFF_REGNUM, (char *) &xfpregs->fip);
384     supply_register (FDS_REGNUM,   (char *) &xfpregs->fos);
385     supply_register (FDOFF_REGNUM, (char *) &xfpregs->foo);
386   
387     /* Extract the code segment and opcode from the  "fcs" member.  */
388     {
389       long l;
390       
391       l = xfpregs->fcs & 0xffff;
392       supply_register (FCS_REGNUM, (char *) &l);
393
394       l = (xfpregs->fcs >> 16) & ((1 << 11) - 1);
395       supply_register (FOP_REGNUM, (char *) &l);
396     }
397   }
398
399   /* Supply the SSE registers.  */
400   for (reg = 0; reg < 8; reg++)
401     supply_register (XMM0_REGNUM + reg, (char *) &xfpregs->xmm_space[reg]);
402   supply_register (MXCSR_REGNUM, (char *) &xfpregs->mxcsr);
403 }
404
405 /* Convert the valid floating-point and SSE registers in GDB's
406    register array to `struct user' format and store them in *XFPREGS.
407    The array VALID indicates which registers are valid.  If VALID is
408    NULL, all registers are assumed to be valid.  */
409
410 static void
411 convert_to_xfpregset (struct user_xfpregs_struct *xfpregs,
412                       signed char *valid)
413 {
414   int reg;
415
416   /* Fill in the floating-point registers.  */
417   for (reg = 0; reg < 8; reg++)
418     if (!valid || valid[reg])
419       memcpy (&xfpregs->st_space[reg],
420               &registers[REGISTER_BYTE (FP0_REGNUM + reg)],
421               REGISTER_RAW_SIZE(FP0_REGNUM + reg));
422
423 #define fill(MEMBER, REGNO)                                             \
424   if (! valid || valid[(REGNO)])                                        \
425     memcpy (&xfpregs->MEMBER, &registers[REGISTER_BYTE (REGNO)],        \
426             sizeof (xfpregs->MEMBER))
427
428   fill (cwd, FCTRL_REGNUM);
429   fill (swd, FSTAT_REGNUM);
430   fill (twd, FTAG_REGNUM);
431   fill (fip, FCOFF_REGNUM);
432   fill (foo, FDOFF_REGNUM);
433   fill (fos, FDS_REGNUM);
434
435 #undef fill
436
437   if (! valid || valid[FCS_REGNUM])
438     xfpregs->fcs
439       = ((xfpregs->fcs & ~0xffff)
440          | (* (int *) &registers[REGISTER_BYTE (FCS_REGNUM)] & 0xffff));
441
442   if (! valid || valid[FOP_REGNUM])
443     xfpregs->fcs
444       = ((xfpregs->fcs & 0xffff)
445          | ((*(int *) &registers[REGISTER_BYTE (FOP_REGNUM)] & ((1 << 11) - 1))
446             << 16));
447
448   /* Fill in the XMM registers.  */
449   for (reg = 0; reg < 8; reg++)
450     if (! valid || valid[reg])
451       memcpy (&xfpregs->xmm_space[reg],
452               &registers[REGISTER_BYTE (XMM0_REGNUM + reg)],
453               REGISTER_RAW_SIZE (XMM0_REGNUM + reg));
454 }
455
456 /* Fetch all registers covered by the PTRACE_SETXFPREGS request from
457    process/thread TID and store their values in GDB's register array.
458    Return non-zero if successful, zero otherwise.  */
459
460 static int
461 fetch_xfpregs (int tid)
462 {
463   struct user_xfpregs_struct xfpregs;
464   int ret;
465
466   if (! have_ptrace_getxfpregs) 
467     return 0;
468
469   ret = ptrace (PTRACE_GETXFPREGS, tid, 0, &xfpregs);
470   if (ret == -1)
471     {
472       if (errno == EIO)
473         {
474           have_ptrace_getxfpregs = 0;
475           return 0;
476         }
477
478       warning ("Couldn't read floating-point and SSE registers.");
479       return 0;
480     }
481
482   supply_xfpregset (&xfpregs);
483   return 1;
484 }
485
486 /* Store all valid registers in GDB's register array covered by the
487    PTRACE_SETXFPREGS request into the process/thread specified by TID.
488    Return non-zero if successful, zero otherwise.  */
489
490 static int
491 store_xfpregs (int tid)
492 {
493   struct user_xfpregs_struct xfpregs;
494   int ret;
495
496   if (! have_ptrace_getxfpregs)
497     return 0;
498
499   ret = ptrace (PTRACE_GETXFPREGS, tid, 0, &xfpregs);
500   if (ret == -1)
501     {
502       if (errno == EIO)
503         {
504           have_ptrace_getxfpregs = 0;
505           return 0;
506         }
507
508       warning ("Couldn't read floating-point and SSE registers.");
509       return 0;
510     }
511
512   convert_to_xfpregset (&xfpregs, register_valid);
513
514   if (ptrace (PTRACE_SETXFPREGS, tid, 0, &xfpregs) < 0)
515     {
516       warning ("Couldn't write floating-point and SSE registers.");
517       return 0;
518     }
519
520   return 1;
521 }
522
523 /* Fill the XMM registers in the register array with dummy values.  For
524    cases where we don't have access to the XMM registers.  I think
525    this is cleaner than printing a warning.  For a cleaner solution,
526    we should gdbarchify the i386 family.  */
527
528 static void
529 dummy_sse_values (void)
530 {
531   /* C doesn't have a syntax for NaN's, so write it out as an array of
532      longs.  */
533   static long dummy[4] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff };
534   static long mxcsr = 0x1f80;
535   int reg;
536
537   for (reg = 0; reg < 8; reg++)
538     supply_register (XMM0_REGNUM + reg, (char *) dummy);
539   supply_register (MXCSR_REGNUM, (char *) &mxcsr);
540 }
541
542 #else
543
544 /* Stub versions of the above routines, for systems that don't have
545    PTRACE_GETXFPREGS.  */
546 static int store_xfpregs (int tid) { return 0; }
547 static int fetch_xfpregs (int tid) { return 0; }
548 static void dummy_sse_values (void) {}
549
550 #endif
551
552 \f
553 /* Transferring arbitrary registers between GDB and inferior.  */
554
555 /* Fetch register REGNO from the child process.  If REGNO is -1, do
556    this for all registers (including the floating point and SSE
557    registers).  */
558
559 void
560 fetch_inferior_registers (int regno)
561 {
562   int tid;
563
564   /* Linux LWP ID's are process ID's.  */
565   if ((tid = TIDGET (inferior_pid)) == 0)
566     tid = inferior_pid;         /* Not a threaded program.  */
567
568   /* Use the PTRACE_GETXFPREGS request whenever possible, since it
569      transfers more registers in one system call, and we'll cache the
570      results.  But remember that fetch_xfpregs can fail, and return
571      zero.  */
572   if (regno == -1)
573     {
574       fetch_regs (tid);
575       if (fetch_xfpregs (tid))
576         return;
577       fetch_fpregs (tid);
578       return;
579     }
580
581   if (GETREGS_SUPPLIES (regno))
582     {
583       fetch_regs (tid);
584       return;
585     }
586
587   if (GETXFPREGS_SUPPLIES (regno))
588     {
589       if (fetch_xfpregs (tid))
590         return;
591
592       /* Either our processor or our kernel doesn't support the SSE
593          registers, so read the FP registers in the traditional way,
594          and fill the SSE registers with dummy values.  It would be
595          more graceful to handle differences in the register set using
596          gdbarch.  Until then, this will at least make things work
597          plausibly.  */
598       fetch_fpregs (tid);
599       dummy_sse_values ();
600       return;
601     }
602
603   internal_error ("i386-linux-nat.c (fetch_inferior_registers): "
604                   "got request for bad register number %d", regno);
605 }
606
607 /* Store register REGNO back into the child process.  If REGNO is -1,
608    do this for all registers (including the floating point and SSE
609    registers).  */
610 void
611 store_inferior_registers (int regno)
612 {
613   int tid;
614
615   /* Linux LWP ID's are process ID's.  */
616   if ((tid = TIDGET (inferior_pid)) == 0)
617     tid = inferior_pid;         /* Not a threaded program.  */
618
619   /* Use the PTRACE_SETXFPREGS requests whenever possibl, since it
620      transfers more registers in one system call.  But remember that
621      store_xfpregs can fail, and return zero.  */
622   if (regno == -1)
623     {
624       store_regs (tid);
625       if (store_xfpregs (tid))
626         return;
627       store_fpregs (tid);
628       return;
629     }
630
631   if (GETREGS_SUPPLIES (regno))
632     {
633       store_regs (tid);
634       return;
635     }
636
637   if (GETXFPREGS_SUPPLIES (regno))
638     {
639       if (store_xfpregs (tid))
640         return;
641
642       /* Either our processor or our kernel doesn't support the SSE
643          registers, so just write the FP registers in the traditional
644          way.  */
645       store_fpregs (tid);
646       return;
647     }
648
649   internal_error ("Got request to store bad register number %d.", regno);
650 }
651
652 \f
653 /* Interpreting register set info found in core files.  */
654
655 /* Provide registers to GDB from a core file.
656
657    (We can't use the generic version of this function in
658    core-regset.c, because Linux has *three* different kinds of
659    register set notes.  core-regset.c would have to call
660    supply_xfpregset, which most platforms don't have.)
661
662    CORE_REG_SECT points to an array of bytes, which are the contents
663    of a `note' from a core file which BFD thinks might contain
664    register contents.  CORE_REG_SIZE is its size.
665
666    WHICH says which register set corelow suspects this is:
667      0 --- the general-purpose register set, in elf_gregset_t format
668      2 --- the floating-point register set, in elf_fpregset_t format
669      3 --- the extended floating-point register set, in struct
670            user_xfpregs_struct format
671
672    REG_ADDR isn't used on Linux.  */
673
674 static void
675 fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
676                       int which, CORE_ADDR reg_addr)
677 {
678   elf_gregset_t gregset;
679   elf_fpregset_t fpregset;
680
681   switch (which)
682     {
683     case 0:
684       if (core_reg_size != sizeof (gregset))
685         warning ("Wrong size gregset in core file.");
686       else
687         {
688           memcpy (&gregset, core_reg_sect, sizeof (gregset));
689           supply_gregset (&gregset);
690         }
691       break;
692
693     case 2:
694       if (core_reg_size != sizeof (fpregset))
695         warning ("Wrong size fpregset in core file.");
696       else
697         {
698           memcpy (&fpregset, core_reg_sect, sizeof (fpregset));
699           supply_fpregset (&fpregset);
700         }
701       break;
702
703 #ifdef HAVE_PTRACE_GETXFPREGS
704       {
705         struct user_xfpregs_struct xfpregset;
706
707       case 3:
708         if (core_reg_size != sizeof (xfpregset))
709           warning ("Wrong size user_xfpregs_struct in core file.");
710         else
711           {
712             memcpy (&xfpregset, core_reg_sect, sizeof (xfpregset));
713             supply_xfpregset (&xfpregset);
714           }
715         break;
716       }
717 #endif
718
719     default:
720       /* We've covered all the kinds of registers we know about here,
721          so this must be something we wouldn't know what to do with
722          anyway.  Just ignore it.  */
723       break;
724     }
725 }
726
727 \f
728 /* Calling functions in shared libraries.  */
729 /* FIXME: kettenis/2000-03-05: Doesn't this belong in a
730    target-dependent file?  The function
731    `i386_linux_skip_solib_resolver' is mentioned in
732    `config/i386/tm-linux.h'.  */
733
734 /* Find the minimal symbol named NAME, and return both the minsym
735    struct and its objfile.  This probably ought to be in minsym.c, but
736    everything there is trying to deal with things like C++ and
737    SOFUN_ADDRESS_MAYBE_TURQUOISE, ...  Since this is so simple, it may
738    be considered too special-purpose for general consumption.  */
739
740 static struct minimal_symbol *
741 find_minsym_and_objfile (char *name, struct objfile **objfile_p)
742 {
743   struct objfile *objfile;
744
745   ALL_OBJFILES (objfile)
746     {
747       struct minimal_symbol *msym;
748
749       ALL_OBJFILE_MSYMBOLS (objfile, msym)
750         {
751           if (SYMBOL_NAME (msym)
752               && STREQ (SYMBOL_NAME (msym), name))
753             {
754               *objfile_p = objfile;
755               return msym;
756             }
757         }
758     }
759
760   return 0;
761 }
762
763
764 static CORE_ADDR
765 skip_hurd_resolver (CORE_ADDR pc)
766 {
767   /* The HURD dynamic linker is part of the GNU C library, so many
768      GNU/Linux distributions use it.  (All ELF versions, as far as I
769      know.)  An unresolved PLT entry points to "_dl_runtime_resolve",
770      which calls "fixup" to patch the PLT, and then passes control to
771      the function.
772
773      We look for the symbol `_dl_runtime_resolve', and find `fixup' in
774      the same objfile.  If we are at the entry point of `fixup', then
775      we set a breakpoint at the return address (at the top of the
776      stack), and continue.
777   
778      It's kind of gross to do all these checks every time we're
779      called, since they don't change once the executable has gotten
780      started.  But this is only a temporary hack --- upcoming versions
781      of Linux will provide a portable, efficient interface for
782      debugging programs that use shared libraries.  */
783
784   struct objfile *objfile;
785   struct minimal_symbol *resolver 
786     = find_minsym_and_objfile ("_dl_runtime_resolve", &objfile);
787
788   if (resolver)
789     {
790       struct minimal_symbol *fixup
791         = lookup_minimal_symbol ("fixup", 0, objfile);
792
793       if (fixup && SYMBOL_VALUE_ADDRESS (fixup) == pc)
794         return (SAVED_PC_AFTER_CALL (get_current_frame ()));
795     }
796
797   return 0;
798 }      
799
800 /* See the comments for SKIP_SOLIB_RESOLVER at the top of infrun.c.
801    This function:
802    1) decides whether a PLT has sent us into the linker to resolve
803       a function reference, and 
804    2) if so, tells us where to set a temporary breakpoint that will
805       trigger when the dynamic linker is done.  */
806
807 CORE_ADDR
808 i386_linux_skip_solib_resolver (CORE_ADDR pc)
809 {
810   CORE_ADDR result;
811
812   /* Plug in functions for other kinds of resolvers here.  */
813   result = skip_hurd_resolver (pc);
814   if (result)
815     return result;
816
817   return 0;
818 }
819
820 \f
821 /* Register that we are able to handle Linux ELF core file formats.  */
822
823 static struct core_fns linux_elf_core_fns =
824 {
825   bfd_target_elf_flavour,               /* core_flavour */
826   default_check_format,                 /* check_format */
827   default_core_sniffer,                 /* core_sniffer */
828   fetch_core_registers,                 /* core_read_registers */
829   NULL                                  /* next */
830 };
831
832 void
833 _initialize_i386_linux_nat ()
834 {
835   add_core_fns (&linux_elf_core_fns);
836 }