Implement '-target-detach pid'.
[deliverable/binutils-gdb.git] / gdb / m68klinux-nat.c
CommitLineData
a4b6fc86
AC
1/* Motorola m68k native support for GNU/Linux.
2
9b254dd1
DJ
3 Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
4 2008 Free Software Foundation, Inc.
c906108c 5
c5aa993b 6 This file is part of GDB.
c906108c 7
c5aa993b
JM
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
a9762ec7 10 the Free Software Foundation; either version 3 of the License, or
c5aa993b 11 (at your option) any later version.
c906108c 12
c5aa993b
JM
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
c906108c 17
c5aa993b 18 You should have received a copy of the GNU General Public License
a9762ec7 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
20
21#include "defs.h"
22#include "frame.h"
23#include "inferior.h"
24#include "language.h"
25#include "gdbcore.h"
32eeb91a 26#include "gdb_string.h"
4e052eda 27#include "regcache.h"
10d6c8cd
DJ
28#include "target.h"
29#include "linux-nat.h"
c906108c 30
32eeb91a
AS
31#include "m68k-tdep.h"
32
c906108c
SS
33#include <sys/param.h>
34#include <sys/dir.h>
35#include <signal.h>
0280a90a 36#include <sys/ptrace.h>
c906108c
SS
37#include <sys/user.h>
38#include <sys/ioctl.h>
39#include <fcntl.h>
40#include <sys/procfs.h>
41
0280a90a
AS
42#ifdef HAVE_SYS_REG_H
43#include <sys/reg.h>
44#endif
45
c906108c
SS
46#include <sys/file.h>
47#include "gdb_stat.h"
48
49#include "floatformat.h"
50
51#include "target.h"
3e00823e
UW
52
53/* Prototypes for supply_gregset etc. */
54#include "gregset.h"
c906108c 55\f
c9f4d572 56/* This table must line up with gdbarch_register_name in "m68k-tdep.c". */
c5aa993b 57static const int regmap[] =
c906108c
SS
58{
59 PT_D0, PT_D1, PT_D2, PT_D3, PT_D4, PT_D5, PT_D6, PT_D7,
60 PT_A0, PT_A1, PT_A2, PT_A3, PT_A4, PT_A5, PT_A6, PT_USP,
61 PT_SR, PT_PC,
62 /* PT_FP0, ..., PT_FP7 */
63 21, 24, 27, 30, 33, 36, 39, 42,
64 /* PT_FPCR, PT_FPSR, PT_FPIAR */
65 45, 46, 47
66};
67
0280a90a
AS
68/* Which ptrace request retrieves which registers?
69 These apply to the corresponding SET requests as well. */
70#define NUM_GREGS (18)
71#define MAX_NUM_REGS (NUM_GREGS + 11)
72
73int
74getregs_supplies (int regno)
75{
76 return 0 <= regno && regno < NUM_GREGS;
77}
78
79int
80getfpregs_supplies (int regno)
81{
4ed226fe 82 return M68K_FP0_REGNUM <= regno && regno <= M68K_FPI_REGNUM;
0280a90a
AS
83}
84
85/* Does the current host support the GETREGS request? */
86int have_ptrace_getregs =
87#ifdef HAVE_PTRACE_GETREGS
88 1
89#else
90 0
91#endif
92;
93
94\f
95
0280a90a
AS
96/* Fetching registers directly from the U area, one at a time. */
97
98/* FIXME: This duplicates code from `inptrace.c'. The problem is that we
99 define FETCH_INFERIOR_REGISTERS since we want to use our own versions
100 of {fetch,store}_inferior_registers that use the GETREGS request. This
101 means that the code in `infptrace.c' is #ifdef'd out. But we need to
102 fall back on that code when GDB is running on top of a kernel that
103 doesn't support the GETREGS request. */
104
105#ifndef PT_READ_U
106#define PT_READ_U PTRACE_PEEKUSR
107#endif
108#ifndef PT_WRITE_U
109#define PT_WRITE_U PTRACE_POKEUSR
110#endif
111
0280a90a
AS
112/* Fetch one register. */
113
114static void
56be3814 115fetch_register (struct regcache *regcache, int regno)
0280a90a 116{
c984b7ff 117 struct gdbarch *gdbarch = get_regcache_arch (regcache);
0280a90a
AS
118 /* This isn't really an address. But ptrace thinks of it as one. */
119 CORE_ADDR regaddr;
120 char mess[128]; /* For messages */
52f0bd74 121 int i;
123a958e 122 char buf[MAX_REGISTER_SIZE];
0280a90a
AS
123 int tid;
124
c984b7ff 125 if (gdbarch_cannot_fetch_register (gdbarch, regno))
0280a90a 126 {
c984b7ff 127 memset (buf, '\0', register_size (gdbarch, regno)); /* Supply zeroes */
56be3814 128 regcache_raw_supply (regcache, regno, buf);
0280a90a
AS
129 return;
130 }
131
132 /* Overload thread id onto process id */
8de307e0
AS
133 tid = TIDGET (inferior_ptid);
134 if (tid == 0)
0280a90a
AS
135 tid = PIDGET (inferior_ptid); /* no thread id, just use process id */
136
de732108 137 regaddr = 4 * regmap[regno];
c984b7ff 138 for (i = 0; i < register_size (gdbarch, regno);
5f402660 139 i += sizeof (PTRACE_TYPE_RET))
0280a90a
AS
140 {
141 errno = 0;
5f402660
UW
142 *(PTRACE_TYPE_RET *) &buf[i] = ptrace (PT_READ_U, tid,
143 (PTRACE_TYPE_ARG3) regaddr, 0);
144 regaddr += sizeof (PTRACE_TYPE_RET);
0280a90a
AS
145 if (errno != 0)
146 {
147 sprintf (mess, "reading register %s (#%d)",
c984b7ff 148 gdbarch_register_name (gdbarch, regno), regno);
0280a90a
AS
149 perror_with_name (mess);
150 }
151 }
56be3814 152 regcache_raw_supply (regcache, regno, buf);
0280a90a
AS
153}
154
155/* Fetch register values from the inferior.
156 If REGNO is negative, do this for all registers.
157 Otherwise, REGNO specifies which register (so we can save time). */
c906108c 158
10d6c8cd 159static void
56be3814 160old_fetch_inferior_registers (struct regcache *regcache, int regno)
0280a90a
AS
161{
162 if (regno >= 0)
163 {
56be3814 164 fetch_register (regcache, regno);
0280a90a
AS
165 }
166 else
167 {
c984b7ff
UW
168 for (regno = 0;
169 regno < gdbarch_num_regs (get_regcache_arch (regcache));
170 regno++)
0280a90a 171 {
56be3814 172 fetch_register (regcache, regno);
0280a90a
AS
173 }
174 }
175}
176
177/* Store one register. */
178
179static void
56be3814 180store_register (const struct regcache *regcache, int regno)
0280a90a 181{
f36bf22c 182 struct gdbarch *gdbarch = get_regcache_arch (regcache);
0280a90a
AS
183 /* This isn't really an address. But ptrace thinks of it as one. */
184 CORE_ADDR regaddr;
185 char mess[128]; /* For messages */
52f0bd74 186 int i;
0280a90a 187 int tid;
d9d9c31f 188 char buf[MAX_REGISTER_SIZE];
0280a90a 189
c984b7ff 190 if (gdbarch_cannot_store_register (gdbarch, regno))
8d4c1ba3 191 return;
0280a90a
AS
192
193 /* Overload thread id onto process id */
8de307e0
AS
194 tid = TIDGET (inferior_ptid);
195 if (tid == 0)
0280a90a
AS
196 tid = PIDGET (inferior_ptid); /* no thread id, just use process id */
197
de732108 198 regaddr = 4 * regmap[regno];
9852326a
AS
199
200 /* Put the contents of regno into a local buffer */
56be3814 201 regcache_raw_collect (regcache, regno, buf);
9852326a
AS
202
203 /* Store the local buffer into the inferior a chunk at the time. */
c984b7ff 204 for (i = 0; i < register_size (gdbarch, regno);
5f402660 205 i += sizeof (PTRACE_TYPE_RET))
0280a90a
AS
206 {
207 errno = 0;
5f402660
UW
208 ptrace (PT_WRITE_U, tid, (PTRACE_TYPE_ARG3) regaddr,
209 *(PTRACE_TYPE_RET *) (buf + i));
210 regaddr += sizeof (PTRACE_TYPE_RET);
0280a90a
AS
211 if (errno != 0)
212 {
213 sprintf (mess, "writing register %s (#%d)",
c984b7ff 214 gdbarch_register_name (gdbarch, regno), regno);
0280a90a
AS
215 perror_with_name (mess);
216 }
217 }
218}
219
220/* Store our register values back into the inferior.
221 If REGNO is negative, do this for all registers.
222 Otherwise, REGNO specifies which register (so we can save time). */
223
10d6c8cd 224static void
56be3814 225old_store_inferior_registers (const struct regcache *regcache, int regno)
0280a90a
AS
226{
227 if (regno >= 0)
228 {
56be3814 229 store_register (regcache, regno);
0280a90a
AS
230 }
231 else
232 {
c984b7ff
UW
233 for (regno = 0;
234 regno < gdbarch_num_regs (get_regcache_arch (regcache));
235 regno++)
0280a90a 236 {
56be3814 237 store_register (regcache, regno);
0280a90a
AS
238 }
239 }
240}
241\f
f175af98
DJ
242/* Given a pointer to a general register set in /proc format
243 (elf_gregset_t *), unpack the register contents and supply
244 them as gdb's idea of the current register values. */
c906108c 245
c906108c 246void
7f7fe91e 247supply_gregset (struct regcache *regcache, const elf_gregset_t *gregsetp)
c906108c 248{
c984b7ff 249 struct gdbarch *gdbarch = get_regcache_arch (regcache);
7f7fe91e 250 const elf_greg_t *regp = (const elf_greg_t *) gregsetp;
c906108c
SS
251 int regi;
252
3e8c568d 253 for (regi = M68K_D0_REGNUM;
c984b7ff 254 regi <= gdbarch_sp_regnum (gdbarch);
3e8c568d 255 regi++)
7f7fe91e 256 regcache_raw_supply (regcache, regi, &regp[regmap[regi]]);
c984b7ff 257 regcache_raw_supply (regcache, gdbarch_ps_regnum (gdbarch),
3e8c568d
UW
258 &regp[PT_SR]);
259 regcache_raw_supply (regcache,
c984b7ff 260 gdbarch_pc_regnum (gdbarch), &regp[PT_PC]);
0280a90a
AS
261}
262
263/* Fill register REGNO (if it is a general-purpose register) in
264 *GREGSETPS with the value in GDB's register array. If REGNO is -1,
265 do this for all registers. */
266void
7f7fe91e
UW
267fill_gregset (const struct regcache *regcache,
268 elf_gregset_t *gregsetp, int regno)
0280a90a
AS
269{
270 elf_greg_t *regp = (elf_greg_t *) gregsetp;
271 int i;
272
273 for (i = 0; i < NUM_GREGS; i++)
8de307e0 274 if (regno == -1 || regno == i)
7f7fe91e 275 regcache_raw_collect (regcache, i, regp + regmap[i]);
0280a90a
AS
276}
277
278#ifdef HAVE_PTRACE_GETREGS
279
280/* Fetch all general-purpose registers from process/thread TID and
281 store their values in GDB's register array. */
282
283static void
56be3814 284fetch_regs (struct regcache *regcache, int tid)
0280a90a
AS
285{
286 elf_gregset_t regs;
287
288 if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
289 {
290 if (errno == EIO)
291 {
292 /* The kernel we're running on doesn't support the GETREGS
293 request. Reset `have_ptrace_getregs'. */
294 have_ptrace_getregs = 0;
295 return;
296 }
297
e2e0b3e5 298 perror_with_name (_("Couldn't get registers"));
0280a90a
AS
299 }
300
56be3814 301 supply_gregset (regcache, (const elf_gregset_t *) &regs);
c906108c
SS
302}
303
0280a90a
AS
304/* Store all valid general-purpose registers in GDB's register array
305 into the process/thread specified by TID. */
306
307static void
56be3814 308store_regs (const struct regcache *regcache, int tid, int regno)
0280a90a
AS
309{
310 elf_gregset_t regs;
311
312 if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
e2e0b3e5 313 perror_with_name (_("Couldn't get registers"));
0280a90a 314
56be3814 315 fill_gregset (regcache, &regs, regno);
0280a90a
AS
316
317 if (ptrace (PTRACE_SETREGS, tid, 0, (int) &regs) < 0)
e2e0b3e5 318 perror_with_name (_("Couldn't write registers"));
0280a90a
AS
319}
320
321#else
322
56be3814
UW
323static void fetch_regs (struct regcache *regcache, int tid) {}
324static void store_regs (const struct regcache *regcache, int tid, int regno) {}
0280a90a
AS
325
326#endif
327
328\f
329/* Transfering floating-point registers between GDB, inferiors and cores. */
330
331/* What is the address of fpN within the floating-point register set F? */
7f7fe91e 332#define FPREG_ADDR(f, n) (&(f)->fpregs[(n) * 3])
0280a90a
AS
333
334/* Fill GDB's register array with the floating-point register values in
335 *FPREGSETP. */
c906108c 336
c5aa993b 337void
7f7fe91e 338supply_fpregset (struct regcache *regcache, const elf_fpregset_t *fpregsetp)
c906108c 339{
c984b7ff 340 struct gdbarch *gdbarch = get_regcache_arch (regcache);
c906108c
SS
341 int regi;
342
c984b7ff
UW
343 for (regi = gdbarch_fp0_regnum (gdbarch);
344 regi < gdbarch_fp0_regnum (gdbarch) + 8; regi++)
7f7fe91e 345 regcache_raw_supply (regcache, regi,
3e8c568d 346 FPREG_ADDR (fpregsetp,
c984b7ff 347 regi - gdbarch_fp0_regnum (gdbarch)));
7f7fe91e
UW
348 regcache_raw_supply (regcache, M68K_FPC_REGNUM, &fpregsetp->fpcntl[0]);
349 regcache_raw_supply (regcache, M68K_FPS_REGNUM, &fpregsetp->fpcntl[1]);
350 regcache_raw_supply (regcache, M68K_FPI_REGNUM, &fpregsetp->fpcntl[2]);
c906108c
SS
351}
352
0280a90a
AS
353/* Fill register REGNO (if it is a floating-point register) in
354 *FPREGSETP with the value in GDB's register array. If REGNO is -1,
355 do this for all registers. */
356
357void
7f7fe91e
UW
358fill_fpregset (const struct regcache *regcache,
359 elf_fpregset_t *fpregsetp, int regno)
0280a90a 360{
c984b7ff 361 struct gdbarch *gdbarch = get_regcache_arch (regcache);
0280a90a
AS
362 int i;
363
364 /* Fill in the floating-point registers. */
c984b7ff
UW
365 for (i = gdbarch_fp0_regnum (gdbarch);
366 i < gdbarch_fp0_regnum (gdbarch) + 8; i++)
0280a90a 367 if (regno == -1 || regno == i)
7f7fe91e 368 regcache_raw_collect (regcache, i,
3e8c568d 369 FPREG_ADDR (fpregsetp,
c984b7ff 370 i - gdbarch_fp0_regnum (gdbarch)));
0280a90a
AS
371
372 /* Fill in the floating-point control registers. */
32eeb91a 373 for (i = M68K_FPC_REGNUM; i <= M68K_FPI_REGNUM; i++)
0280a90a 374 if (regno == -1 || regno == i)
7f7fe91e
UW
375 regcache_raw_collect (regcache, i,
376 &fpregsetp->fpcntl[i - M68K_FPC_REGNUM]);
0280a90a
AS
377}
378
379#ifdef HAVE_PTRACE_GETREGS
380
381/* Fetch all floating-point registers from process/thread TID and store
382 thier values in GDB's register array. */
383
384static void
56be3814 385fetch_fpregs (struct regcache *regcache, int tid)
0280a90a
AS
386{
387 elf_fpregset_t fpregs;
388
389 if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0)
e2e0b3e5 390 perror_with_name (_("Couldn't get floating point status"));
0280a90a 391
56be3814 392 supply_fpregset (regcache, (const elf_fpregset_t *) &fpregs);
0280a90a
AS
393}
394
395/* Store all valid floating-point registers in GDB's register array
396 into the process/thread specified by TID. */
397
398static void
56be3814 399store_fpregs (const struct regcache *regcache, int tid, int regno)
0280a90a
AS
400{
401 elf_fpregset_t fpregs;
402
403 if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0)
e2e0b3e5 404 perror_with_name (_("Couldn't get floating point status"));
0280a90a 405
56be3814 406 fill_fpregset (regcache, &fpregs, regno);
0280a90a
AS
407
408 if (ptrace (PTRACE_SETFPREGS, tid, 0, (int) &fpregs) < 0)
e2e0b3e5 409 perror_with_name (_("Couldn't write floating point status"));
0280a90a
AS
410}
411
412#else
413
56be3814
UW
414static void fetch_fpregs (struct regcache *regcache, int tid) {}
415static void store_fpregs (const struct regcache *regcache, int tid, int regno) {}
0280a90a 416
c906108c 417#endif
0280a90a
AS
418\f
419/* Transferring arbitrary registers between GDB and inferior. */
420
421/* Fetch register REGNO from the child process. If REGNO is -1, do
422 this for all registers (including the floating point and SSE
423 registers). */
424
10d6c8cd 425static void
56be3814 426m68k_linux_fetch_inferior_registers (struct regcache *regcache, int regno)
0280a90a
AS
427{
428 int tid;
429
430 /* Use the old method of peeking around in `struct user' if the
431 GETREGS request isn't available. */
432 if (! have_ptrace_getregs)
433 {
56be3814 434 old_fetch_inferior_registers (regcache, regno);
0280a90a
AS
435 return;
436 }
437
a4b6fc86 438 /* GNU/Linux LWP ID's are process ID's. */
8de307e0
AS
439 tid = TIDGET (inferior_ptid);
440 if (tid == 0)
0280a90a 441 tid = PIDGET (inferior_ptid); /* Not a threaded program. */
f175af98 442
0280a90a
AS
443 /* Use the PTRACE_GETFPXREGS request whenever possible, since it
444 transfers more registers in one system call, and we'll cache the
445 results. But remember that fetch_fpxregs can fail, and return
446 zero. */
447 if (regno == -1)
448 {
56be3814 449 fetch_regs (regcache, tid);
0280a90a
AS
450
451 /* The call above might reset `have_ptrace_getregs'. */
452 if (! have_ptrace_getregs)
453 {
56be3814 454 old_fetch_inferior_registers (regcache, -1);
0280a90a
AS
455 return;
456 }
457
56be3814 458 fetch_fpregs (regcache, tid);
0280a90a
AS
459 return;
460 }
461
462 if (getregs_supplies (regno))
463 {
56be3814 464 fetch_regs (regcache, tid);
0280a90a
AS
465 return;
466 }
467
468 if (getfpregs_supplies (regno))
469 {
56be3814 470 fetch_fpregs (regcache, tid);
0280a90a
AS
471 return;
472 }
473
474 internal_error (__FILE__, __LINE__,
e2e0b3e5 475 _("Got request for bad register number %d."), regno);
0280a90a
AS
476}
477
478/* Store register REGNO back into the child process. If REGNO is -1,
479 do this for all registers (including the floating point and SSE
480 registers). */
10d6c8cd 481static void
56be3814 482m68k_linux_store_inferior_registers (struct regcache *regcache, int regno)
0280a90a
AS
483{
484 int tid;
485
486 /* Use the old method of poking around in `struct user' if the
487 SETREGS request isn't available. */
488 if (! have_ptrace_getregs)
489 {
56be3814 490 old_store_inferior_registers (regcache, regno);
0280a90a
AS
491 return;
492 }
493
a4b6fc86 494 /* GNU/Linux LWP ID's are process ID's. */
8de307e0
AS
495 tid = TIDGET (inferior_ptid);
496 if (tid == 0)
0280a90a
AS
497 tid = PIDGET (inferior_ptid); /* Not a threaded program. */
498
499 /* Use the PTRACE_SETFPREGS requests whenever possible, since it
500 transfers more registers in one system call. But remember that
501 store_fpregs can fail, and return zero. */
502 if (regno == -1)
503 {
56be3814
UW
504 store_regs (regcache, tid, regno);
505 store_fpregs (regcache, tid, regno);
0280a90a
AS
506 return;
507 }
508
509 if (getregs_supplies (regno))
510 {
56be3814 511 store_regs (regcache, tid, regno);
0280a90a
AS
512 return;
513 }
514
515 if (getfpregs_supplies (regno))
516 {
56be3814 517 store_fpregs (regcache, tid, regno);
0280a90a
AS
518 return;
519 }
520
521 internal_error (__FILE__, __LINE__,
e2e0b3e5 522 _("Got request to store bad register number %d."), regno);
0280a90a 523}
f175af98
DJ
524\f
525/* Interpreting register set info found in core files. */
526
527/* Provide registers to GDB from a core file.
528
529 (We can't use the generic version of this function in
530 core-regset.c, because we need to use elf_gregset_t instead of
531 gregset_t.)
532
533 CORE_REG_SECT points to an array of bytes, which are the contents
534 of a `note' from a core file which BFD thinks might contain
535 register contents. CORE_REG_SIZE is its size.
536
537 WHICH says which register set corelow suspects this is:
538 0 --- the general-purpose register set, in elf_gregset_t format
539 2 --- the floating-point register set, in elf_fpregset_t format
540
a4b6fc86 541 REG_ADDR isn't used on GNU/Linux. */
f175af98
DJ
542
543static void
9eefc95f
UW
544fetch_core_registers (struct regcache *regcache,
545 char *core_reg_sect, unsigned core_reg_size,
f175af98
DJ
546 int which, CORE_ADDR reg_addr)
547{
548 elf_gregset_t gregset;
549 elf_fpregset_t fpregset;
550
551 switch (which)
552 {
553 case 0:
554 if (core_reg_size != sizeof (gregset))
8a3fe4f8 555 warning (_("Wrong size gregset in core file."));
f175af98
DJ
556 else
557 {
558 memcpy (&gregset, core_reg_sect, sizeof (gregset));
9eefc95f 559 supply_gregset (regcache, (const elf_gregset_t *) &gregset);
f175af98
DJ
560 }
561 break;
562
563 case 2:
564 if (core_reg_size != sizeof (fpregset))
8a3fe4f8 565 warning (_("Wrong size fpregset in core file."));
f175af98
DJ
566 else
567 {
568 memcpy (&fpregset, core_reg_sect, sizeof (fpregset));
9eefc95f 569 supply_fpregset (regcache, (const elf_fpregset_t *) &fpregset);
f175af98
DJ
570 }
571 break;
572
573 default:
574 /* We've covered all the kinds of registers we know about here,
575 so this must be something we wouldn't know what to do with
576 anyway. Just ignore it. */
577 break;
578 }
579}
c906108c 580\f
c5aa993b 581
a4b6fc86
AC
582/* Register that we are able to handle GNU/Linux ELF core file
583 formats. */
f175af98
DJ
584
585static struct core_fns linux_elf_core_fns =
586{
587 bfd_target_elf_flavour, /* core_flavour */
588 default_check_format, /* check_format */
589 default_core_sniffer, /* core_sniffer */
590 fetch_core_registers, /* core_read_registers */
591 NULL /* next */
592};
593
10d6c8cd
DJ
594void _initialize_m68k_linux_nat (void);
595
f175af98 596void
5ae5f592 597_initialize_m68k_linux_nat (void)
f175af98 598{
10d6c8cd
DJ
599 struct target_ops *t;
600
601 /* Fill in the generic GNU/Linux methods. */
602 t = linux_target ();
603
604 /* Add our register access methods. */
605 t->to_fetch_registers = m68k_linux_fetch_inferior_registers;
606 t->to_store_registers = m68k_linux_store_inferior_registers;
607
608 /* Register the target. */
f973ed9c 609 linux_nat_add_target (t);
10d6c8cd 610
00e32a35 611 deprecated_add_core_fns (&linux_elf_core_fns);
f175af98 612}
This page took 0.707189 seconds and 4 git commands to generate.