import gdb-1999-11-08 snapshot
[deliverable/binutils-gdb.git] / gdb / i386-linux-nat.c
CommitLineData
d4f3574e
SS
1/* Native-dependent code for Linux running on i386's, for GDB.
2
3This file is part of GDB.
4
5This program is free software; you can redistribute it and/or modify
6it under the terms of the GNU General Public License as published by
7the Free Software Foundation; either version 2 of the License, or
8(at your option) any later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, 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
39static 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
5c44784c
JM
48/* Which ptrace request retrieves which registers?
49 These apply to the corresponding SET requests as well. */
50#define GETREGS_SUPPLIES(regno) \
51 (0 <= (regno) && (regno) <= 15)
52#define GETFPREGS_SUPPLIES(regno) \
53 (FP0_REGNUM <= (regno) && (regno) <= LAST_FPU_CTRL_REGNUM)
54#define GETXFPREGS_SUPPLIES(regno) \
55 (FP0_REGNUM <= (regno) && (regno) <= MXCSR_REGNUM)
56
57/* Does the current host support the GETXFPREGS request? The header
58 file may or may not define it, and even if it is defined, the
59 kernel will return EIO if it's running on a pre-SSE processor.
60
61 My instinct is to attach this to some architecture- or
62 target-specific data structure, but really, a particular GDB
63 process can only run on top of one kernel at a time. So it's okay
64 for this to be a simple variable. */
65int have_ptrace_getxfpregs =
66#ifdef HAVE_PTRACE_GETXFPREGS
67 1
68#else
69 0
70#endif
71;
72
73
74\f
75/* Transfering the general registers between GDB, inferiors and core files. */
76
917317f4
JM
77/* Given a pointer to a general register set in struct user format
78 (gregset_t *), unpack the register contents and supply them as
79 gdb's idea of the current register values. */
d4f3574e
SS
80void
81supply_gregset (gregsetp)
82 gregset_t *gregsetp;
83{
84 register int regi;
85 register greg_t *regp = (greg_t *) gregsetp;
86
917317f4 87 for (regi = 0; regi < NUM_GREGS; regi++)
d4f3574e
SS
88 {
89 supply_register (regi, (char *) (regp + regmap[regi]));
90 }
91}
92
5c44784c 93
917317f4
JM
94/* Fill in a gregset_t object with selected data from a gdb-format
95 register file.
96 - GREGSETP points to the gregset_t object to be filled.
97 - GDB_REGS points to the GDB-style register file providing the data.
98 - VALID is an array indicating which registers in GDB_REGS are
99 valid; the parts of *GREGSETP that would hold registers marked
100 invalid in GDB_REGS are left unchanged. If VALID is zero, all
101 registers are assumed to be valid. */
d4f3574e 102void
917317f4
JM
103convert_to_gregset (gregset_t *gregsetp,
104 char *gdb_regs,
105 signed char *valid)
d4f3574e
SS
106{
107 int regi;
108 register greg_t *regp = (greg_t *) gregsetp;
109
917317f4
JM
110 for (regi = 0; regi < NUM_GREGS; regi++)
111 if (! valid || valid[regi])
112 *(regp + regmap[regi]) = * (int *) &registers[REGISTER_BYTE (regi)];
113}
114
5c44784c
JM
115
116/* Store GDB's value for REGNO in *GREGSETP. If REGNO is -1, do all
117 of them. */
917317f4
JM
118void
119fill_gregset (gregset_t *gregsetp,
120 int regno)
121{
122 if (regno == -1)
123 convert_to_gregset (gregsetp, registers, 0);
124 else
d4f3574e 125 {
917317f4
JM
126 signed char valid[NUM_GREGS];
127 memset (valid, 0, sizeof (valid));
128 valid[regno] = 1;
129 convert_to_gregset (gregsetp, valid, valid);
d4f3574e
SS
130 }
131}
132
133
5c44784c
JM
134/* Read the general registers from the process, and store them
135 in registers[]. */
136static void
137fetch_regs ()
138{
139 int ret, regno;
140 gregset_t buf;
141
142 ret = ptrace (PTRACE_GETREGS, inferior_pid, 0, (int) &buf);
143 if (ret < 0)
144 {
145 warning ("Couldn't get registers");
146 return;
147 }
148
149 supply_gregset (&buf);
150}
151
152
153/* Set the inferior's general registers to the values in registers[]
154 --- but only those registers marked as valid. */
155static void
156store_regs ()
157{
158 int ret, regno;
159 gregset_t buf;
160
161 ret = ptrace (PTRACE_GETREGS, inferior_pid, 0, (int) &buf);
162 if (ret < 0)
163 {
164 warning ("Couldn't get registers");
165 return;
166 }
167
168 convert_to_gregset (&buf, registers, register_valid);
169
170 ret = ptrace (PTRACE_SETREGS, inferior_pid, 0, (int)buf);
171 if (ret < 0)
172 {
173 warning ("Couldn't write registers");
174 return;
175 }
176}
177
178
179\f
180/* Transfering floating-point registers between GDB, inferiors and cores. */
181
182/* What is the address of st(N) within the fpregset_t structure F? */
183#define FPREGSET_T_FPREG_ADDR(f, n) \
917317f4 184 ((char *) &(f)->st_space + (n) * 10)
d4f3574e 185
917317f4
JM
186/* Fill GDB's register file with the floating-point register values in
187 *FPREGSETP. */
d4f3574e 188void
917317f4 189supply_fpregset (fpregset_t *fpregsetp)
d4f3574e 190{
917317f4
JM
191 int i;
192
193 /* Supply the floating-point registers. */
194 for (i = 0; i < 8; i++)
5c44784c 195 supply_register (FP0_REGNUM + i, FPREGSET_T_FPREG_ADDR (fpregsetp, i));
917317f4
JM
196
197 supply_register (FCTRL_REGNUM, (char *) &fpregsetp->cwd);
198 supply_register (FSTAT_REGNUM, (char *) &fpregsetp->swd);
199 supply_register (FTAG_REGNUM, (char *) &fpregsetp->twd);
200 supply_register (FCOFF_REGNUM, (char *) &fpregsetp->fip);
201 supply_register (FDS_REGNUM, (char *) &fpregsetp->fos);
202 supply_register (FDOFF_REGNUM, (char *) &fpregsetp->foo);
203
204 /* Extract the code segment and opcode from the "fcs" member. */
205 {
206 long l;
207
208 l = fpregsetp->fcs & 0xffff;
209 supply_register (FCS_REGNUM, (char *) &l);
210
211 l = (fpregsetp->fcs >> 16) & ((1 << 11) - 1);
212 supply_register (FOP_REGNUM, (char *) &l);
213 }
d4f3574e
SS
214}
215
d4f3574e 216
917317f4
JM
217/* Fill in an fpregset_t structure with selected data from a
218 gdb-format register file.
219 - FPREGSETP points to the structure to be filled.
220 - GDB_REGS points to the GDB-style register file providing the data.
221 - VALID is an array indicating which registers in GDB_REGS are
222 valid; the parts of *FPREGSETP that would hold registers marked
223 invalid in GDB_REGS are left unchanged. If VALID is zero, all
224 registers are assumed to be valid. */
d4f3574e 225void
917317f4
JM
226convert_to_fpregset (fpregset_t *fpregsetp,
227 char *gdb_regs,
228 signed char *valid)
d4f3574e 229{
917317f4
JM
230 int i;
231
232 /* Fill in the floating-point registers. */
233 for (i = 0; i < 8; i++)
234 if (!valid || valid[i])
5c44784c 235 memcpy (FPREGSET_T_FPREG_ADDR (fpregsetp, i),
917317f4
JM
236 &registers[REGISTER_BYTE (FP0_REGNUM + i)],
237 REGISTER_RAW_SIZE(FP0_REGNUM + i));
238
239#define fill(MEMBER, REGNO) \
240 if (! valid || valid[(REGNO)]) \
241 memcpy (&fpregsetp->MEMBER, &registers[REGISTER_BYTE (REGNO)], \
242 sizeof (fpregsetp->MEMBER))
243
244 fill (cwd, FCTRL_REGNUM);
245 fill (swd, FSTAT_REGNUM);
246 fill (twd, FTAG_REGNUM);
247 fill (fip, FCOFF_REGNUM);
248 fill (foo, FDOFF_REGNUM);
249 fill (fos, FDS_REGNUM);
250
251#undef fill
252
253 if (! valid || valid[FCS_REGNUM])
254 fpregsetp->fcs
255 = ((fpregsetp->fcs & ~0xffff)
256 | (* (int *) &registers[REGISTER_BYTE (FCS_REGNUM)] & 0xffff));
257
258 if (! valid || valid[FOP_REGNUM])
259 fpregsetp->fcs
260 = ((fpregsetp->fcs & 0xffff)
261 | ((*(int *) &registers[REGISTER_BYTE (FOP_REGNUM)] & ((1 << 11) - 1))
262 << 16));
263}
d4f3574e 264
917317f4
JM
265
266/* Given a pointer to a floating point register set in (fpregset_t *)
267 format, update all of the registers from gdb's idea of the current
268 floating point register set. */
269
270void
271fill_fpregset (fpregset_t *fpregsetp,
272 int regno)
273{
274 convert_to_fpregset (fpregsetp, registers, 0);
d4f3574e
SS
275}
276
917317f4
JM
277
278/* Get the whole floating point state of the process and store the
279 floating point stack into registers[]. */
d4f3574e 280static void
917317f4 281fetch_fpregs ()
d4f3574e
SS
282{
283 int ret, regno;
917317f4 284 fpregset_t buf;
d4f3574e 285
917317f4
JM
286 ret = ptrace (PTRACE_GETFPREGS, inferior_pid, 0, (int) &buf);
287 if (ret < 0)
d4f3574e
SS
288 {
289 warning ("Couldn't get floating point status");
290 return;
291 }
292
917317f4
JM
293 /* ptrace fills an fpregset_t, so we can use the same function we do
294 for core files. */
295 supply_fpregset (&buf);
d4f3574e
SS
296}
297
298
917317f4
JM
299/* Set the inferior's floating-point registers to the values in
300 registers[] --- but only those registers marked valid. */
d4f3574e 301static void
917317f4 302store_fpregs ()
d4f3574e 303{
917317f4
JM
304 int ret;
305 fpregset_t buf;
d4f3574e 306
917317f4
JM
307 ret = ptrace (PTRACE_GETFPREGS, inferior_pid, 0, (int) &buf);
308 if (ret < 0)
d4f3574e
SS
309 {
310 warning ("Couldn't get floating point status");
311 return;
312 }
313
917317f4 314 convert_to_fpregset (&buf, registers, register_valid);
d4f3574e 315
917317f4
JM
316 ret = ptrace (PTRACE_SETFPREGS, inferior_pid, 0, (int) &buf);
317 if (ret < 0)
d4f3574e
SS
318 {
319 warning ("Couldn't write floating point status");
320 return;
321 }
d4f3574e
SS
322}
323
5c44784c
JM
324\f
325/* Transfering floating-point and SSE registers to and from GDB. */
d4f3574e 326
5c44784c 327
11cf8741
JM
328/* PTRACE_GETXFPREGS is a Cygnus invention, since we wrote our own
329 Linux kernel patch for SSE support. That patch may or may not
330 actually make it into the official distribution. If you find that
331 years have gone by since this code was added, and Linux isn't using
332 PTRACE_GETXFPREGS, that means that our patch didn't make it, and
333 you can delete this code. */
334
5c44784c 335#ifdef HAVE_PTRACE_GETXFPREGS
d4f3574e 336static void
5c44784c 337supply_xfpregset (struct user_xfpregs_struct *xfpregs)
d4f3574e 338{
5c44784c 339 int reg;
d4f3574e 340
5c44784c
JM
341 /* Supply the floating-point registers. */
342 for (reg = 0; reg < 8; reg++)
343 supply_register (FP0_REGNUM + reg, (char *) &xfpregs->st_space[reg]);
344
345 {
346 supply_register (FCTRL_REGNUM, (char *) &xfpregs->cwd);
347 supply_register (FSTAT_REGNUM, (char *) &xfpregs->swd);
348 supply_register (FTAG_REGNUM, (char *) &xfpregs->twd);
349 supply_register (FCOFF_REGNUM, (char *) &xfpregs->fip);
350 supply_register (FDS_REGNUM, (char *) &xfpregs->fos);
351 supply_register (FDOFF_REGNUM, (char *) &xfpregs->foo);
352
353 /* Extract the code segment and opcode from the "fcs" member. */
d4f3574e 354 {
5c44784c
JM
355 long l;
356
357 l = xfpregs->fcs & 0xffff;
358 supply_register (FCS_REGNUM, (char *) &l);
359
360 l = (xfpregs->fcs >> 16) & ((1 << 11) - 1);
361 supply_register (FOP_REGNUM, (char *) &l);
d4f3574e 362 }
5c44784c 363 }
d4f3574e 364
5c44784c
JM
365 /* Supply the SSE registers. */
366 for (reg = 0; reg < 8; reg++)
367 supply_register (XMM0_REGNUM + reg, (char *) &xfpregs->xmm_space[reg]);
368 supply_register (MXCSR_REGNUM, (char *) &xfpregs->mxcsr);
d4f3574e
SS
369}
370
371
d4f3574e 372static void
5c44784c
JM
373convert_to_xfpregset (struct user_xfpregs_struct *xfpregs,
374 char *gdb_regs,
375 signed char *valid)
d4f3574e 376{
5c44784c 377 int reg;
d4f3574e 378
5c44784c
JM
379 /* Fill in the floating-point registers. */
380 for (reg = 0; reg < 8; reg++)
381 if (!valid || valid[reg])
382 memcpy (&xfpregs->st_space[reg],
383 &registers[REGISTER_BYTE (FP0_REGNUM + reg)],
384 REGISTER_RAW_SIZE(FP0_REGNUM + reg));
385
386#define fill(MEMBER, REGNO) \
387 if (! valid || valid[(REGNO)]) \
388 memcpy (&xfpregs->MEMBER, &registers[REGISTER_BYTE (REGNO)], \
389 sizeof (xfpregs->MEMBER))
390
391 fill (cwd, FCTRL_REGNUM);
392 fill (swd, FSTAT_REGNUM);
393 fill (twd, FTAG_REGNUM);
394 fill (fip, FCOFF_REGNUM);
395 fill (foo, FDOFF_REGNUM);
396 fill (fos, FDS_REGNUM);
397
398#undef fill
399
400 if (! valid || valid[FCS_REGNUM])
401 xfpregs->fcs
402 = ((xfpregs->fcs & ~0xffff)
403 | (* (int *) &registers[REGISTER_BYTE (FCS_REGNUM)] & 0xffff));
404
405 if (! valid || valid[FOP_REGNUM])
406 xfpregs->fcs
407 = ((xfpregs->fcs & 0xffff)
408 | ((*(int *) &registers[REGISTER_BYTE (FOP_REGNUM)] & ((1 << 11) - 1))
409 << 16));
410
411 /* Fill in the XMM registers. */
412 for (reg = 0; reg < 8; reg++)
413 if (! valid || valid[reg])
414 memcpy (&xfpregs->xmm_space[reg],
415 &registers[REGISTER_BYTE (XMM0_REGNUM + reg)],
416 REGISTER_RAW_SIZE (XMM0_REGNUM + reg));
417}
418
419
420/* Make a PTRACE_GETXFPREGS request, and supply all the register
421 values that yields to GDB. */
422static int
423fetch_xfpregs ()
424{
425 int ret;
426 struct user_xfpregs_struct xfpregs;
427
428 if (! have_ptrace_getxfpregs)
429 return 0;
430
431 ret = ptrace (PTRACE_GETXFPREGS, inferior_pid, 0, &xfpregs);
432 if (ret == -1)
d4f3574e 433 {
5c44784c
JM
434 if (errno == EIO)
435 {
436 have_ptrace_getxfpregs = 0;
437 return 0;
438 }
439
440 warning ("couldn't read floating-point and SSE registers.");
441 return 0;
d4f3574e
SS
442 }
443
5c44784c
JM
444 supply_xfpregset (&xfpregs);
445 return 1;
446}
d4f3574e 447
5c44784c
JM
448
449/* Send all the valid register values in GDB's register file covered
450 by the PTRACE_SETXFPREGS request to the inferior. */
451static int
452store_xfpregs ()
453{
454 int ret;
455 struct user_xfpregs_struct xfpregs;
456
457 if (! have_ptrace_getxfpregs)
458 return 0;
459
460 ret = ptrace (PTRACE_GETXFPREGS, inferior_pid, 0, &xfpregs);
461 if (ret == -1)
d4f3574e 462 {
5c44784c
JM
463 if (errno == EIO)
464 {
465 have_ptrace_getxfpregs = 0;
466 return 0;
467 }
468
469 warning ("couldn't read floating-point and SSE registers.");
470 return 0;
471 }
472
473 convert_to_xfpregset (&xfpregs, registers, register_valid);
474
475 if (ptrace (PTRACE_SETXFPREGS, inferior_pid, 0, &xfpregs) < 0)
476 {
477 warning ("Couldn't write floating-point and SSE registers.");
478 return 0;
d4f3574e 479 }
5c44784c
JM
480
481 return 1;
482}
483
484
485/* Fill the XMM registers in the register file with dummy values. For
486 cases where we don't have access to the XMM registers. I think
487 this is cleaner than printing a warning. For a cleaner solution,
488 we should gdbarchify the i386 family. */
489static void
490dummy_sse_values ()
491{
492 /* C doesn't have a syntax for NaN's, so write it out as an array of
493 longs. */
494 static long dummy[4] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff };
495 static long mxcsr = 0x1f80;
496 int reg;
497
498 for (reg = 0; reg < 8; reg++)
499 supply_register (XMM0_REGNUM + reg, (char *) dummy);
500 supply_register (MXCSR_REGNUM, (char *) &mxcsr);
d4f3574e
SS
501}
502
5c44784c
JM
503#else
504
505/* Stub versions of the above routines, for systems that don't have
506 PTRACE_GETXFPREGS. */
507static int store_xfpregs () { return 0; }
508static int fetch_xfpregs () { return 0; }
509static void dummy_sse_values () {}
510
511#endif
512
513\f
514/* Transferring arbitrary registers between GDB and inferior. */
d4f3574e
SS
515
516/* Fetch registers from the child process.
517 Fetch all if regno == -1, otherwise fetch all ordinary
518 registers or all floating point registers depending
519 upon the value of regno. */
520
521void
917317f4 522fetch_inferior_registers (int regno)
d4f3574e 523{
5c44784c
JM
524 /* Use the xfpregs requests whenever possible, since they transfer
525 more registers in one system call, and we'll cache the results.
526 But remember that fetch_xfpregs can fail, and return zero. */
527 if (regno == -1)
528 {
529 fetch_regs ();
530 if (fetch_xfpregs ())
531 return;
532 fetch_fpregs ();
533 return;
534 }
d4f3574e 535
5c44784c
JM
536 if (GETREGS_SUPPLIES (regno))
537 {
538 fetch_regs ();
539 return;
540 }
541
542 if (GETXFPREGS_SUPPLIES (regno))
543 {
544 if (fetch_xfpregs ())
545 return;
546
547 /* Either our processor or our kernel doesn't support the SSE
548 registers, so read the FP registers in the traditional way,
549 and fill the SSE registers with dummy values. It would be
550 more graceful to handle differences in the register set using
551 gdbarch. Until then, this will at least make things work
552 plausibly. */
553 fetch_fpregs ();
554 dummy_sse_values ();
555 return;
556 }
557
558 internal_error ("i386-linux-nat.c (fetch_inferior_registers): "
559 "got request for bad register number %d", regno);
d4f3574e
SS
560}
561
562
563/* Store our register values back into the inferior.
564 If REGNO is -1, do this for all registers.
565 Otherwise, REGNO specifies which register, which
566 then determines whether we store all ordinary
567 registers or all of the floating point registers. */
568
569void
570store_inferior_registers (regno)
571 int regno;
572{
5c44784c
JM
573 /* Use the xfpregs requests whenever possible, since they transfer
574 more registers in one system call. But remember that
575 fetch_xfpregs can fail, and return zero. */
576 if (regno == -1)
577 {
578 store_regs ();
579 if (store_xfpregs ())
580 return;
581 store_fpregs ();
582 return;
583 }
d4f3574e 584
5c44784c
JM
585 if (GETREGS_SUPPLIES (regno))
586 {
587 store_regs ();
588 return;
589 }
590
591 if (GETXFPREGS_SUPPLIES (regno))
592 {
593 if (store_xfpregs ())
594 return;
595
596 /* Either our processor or our kernel doesn't support the SSE
597 registers, so just write the FP registers in the traditional way. */
598 store_fpregs ();
599 return;
600 }
601
602 internal_error ("i386-linux-nat.c (store_inferior_registers): "
603 "got request to store bad register number %d", regno);
d4f3574e
SS
604}
605
606
5c44784c
JM
607\f
608/* Calling functions in shared libraries. */
609
d4f3574e
SS
610/* Find the minimal symbol named NAME, and return both the minsym
611 struct and its objfile. This probably ought to be in minsym.c, but
612 everything there is trying to deal with things like C++ and
613 SOFUN_ADDRESS_MAYBE_TURQUOISE, ... Since this is so simple, it may
614 be considered too special-purpose for general consumption. */
615
616static struct minimal_symbol *
617find_minsym_and_objfile (char *name, struct objfile **objfile_p)
618{
619 struct objfile *objfile;
620
621 ALL_OBJFILES (objfile)
622 {
623 struct minimal_symbol *msym;
624
625 ALL_OBJFILE_MSYMBOLS (objfile, msym)
626 {
627 if (SYMBOL_NAME (msym)
628 && STREQ (SYMBOL_NAME (msym), name))
629 {
630 *objfile_p = objfile;
631 return msym;
632 }
633 }
634 }
635
636 return 0;
637}
638
639
640static CORE_ADDR
641skip_hurd_resolver (CORE_ADDR pc)
642{
643 /* The HURD dynamic linker is part of the GNU C library, so many
644 GNU/Linux distributions use it. (All ELF versions, as far as I
645 know.) An unresolved PLT entry points to "_dl_runtime_resolve",
646 which calls "fixup" to patch the PLT, and then passes control to
647 the function.
648
649 We look for the symbol `_dl_runtime_resolve', and find `fixup' in
650 the same objfile. If we are at the entry point of `fixup', then
651 we set a breakpoint at the return address (at the top of the
652 stack), and continue.
653
654 It's kind of gross to do all these checks every time we're
655 called, since they don't change once the executable has gotten
656 started. But this is only a temporary hack --- upcoming versions
657 of Linux will provide a portable, efficient interface for
658 debugging programs that use shared libraries. */
659
660 struct objfile *objfile;
661 struct minimal_symbol *resolver
662 = find_minsym_and_objfile ("_dl_runtime_resolve", &objfile);
663
664 if (resolver)
665 {
666 struct minimal_symbol *fixup
667 = lookup_minimal_symbol ("fixup", 0, objfile);
668
669 if (fixup && SYMBOL_VALUE_ADDRESS (fixup) == pc)
670 return (SAVED_PC_AFTER_CALL (get_current_frame ()));
671 }
672
673 return 0;
674}
675
676
677/* See the comments for SKIP_SOLIB_RESOLVER at the top of infrun.c.
678 This function:
679 1) decides whether a PLT has sent us into the linker to resolve
680 a function reference, and
681 2) if so, tells us where to set a temporary breakpoint that will
682 trigger when the dynamic linker is done. */
683
684CORE_ADDR
685i386_linux_skip_solib_resolver (CORE_ADDR pc)
686{
687 CORE_ADDR result;
688
689 /* Plug in functions for other kinds of resolvers here. */
690 result = skip_hurd_resolver (pc);
691 if (result)
692 return result;
693
694 return 0;
695}
This page took 0.070585 seconds and 4 git commands to generate.