* elf.c (bfd_elf_sym_name): Rename from bfd_elf_local_sym_name.
[deliverable/binutils-gdb.git] / gdb / nto-procfs.c
CommitLineData
61bb466e
KW
1/* Machine independent support for QNX Neutrino /proc (process file system)
2 for GDB. Written by Colin Burgess at QNX Software Systems Limited.
3
4 Copyright 2003 Free Software Foundation, Inc.
5
6 Contributed by QNX Software Systems Ltd.
7
8 This file is part of GDB.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA. */
24
25#include "defs.h"
26
27#include <fcntl.h>
28#include <spawn.h>
29#include <sys/debug.h>
30#include <sys/procfs.h>
31#include <sys/neutrino.h>
32#include <sys/syspage.h>
5483d879 33#include "gdb_dirent.h"
61bb466e
KW
34#include <sys/netmgr.h>
35
36#include "gdb_string.h"
37#include "gdbcore.h"
38#include "inferior.h"
39#include "target.h"
40#include "objfiles.h"
41#include "gdbthread.h"
42#include "nto-tdep.h"
43#include "command.h"
44#include "regcache.h"
45
46#define NULL_PID 0
47#define _DEBUG_FLAG_TRACE (_DEBUG_FLAG_TRACE_EXEC|_DEBUG_FLAG_TRACE_RD|\
48 _DEBUG_FLAG_TRACE_WR|_DEBUG_FLAG_TRACE_MODIFY)
49
50static struct target_ops procfs_ops;
51
52int ctl_fd;
53
54static void (*ofunc) ();
55
56static procfs_run run;
57
58static void procfs_open (char *, int);
59
60static int procfs_can_run (void);
61
62static ptid_t procfs_wait (ptid_t, struct target_waitstatus *);
63
64static int procfs_xfer_memory (CORE_ADDR, char *, int, int,
65 struct mem_attrib *attrib,
66 struct target_ops *);
67
68static void procfs_fetch_registers (int);
69
70static void notice_signals (void);
71
72static void init_procfs_ops (void);
73
74static ptid_t do_attach (ptid_t ptid);
75
76static int procfs_can_use_hw_breakpoint (int, int, int);
77
78static int procfs_insert_hw_breakpoint (CORE_ADDR, char *);
79
80static int procfs_remove_hw_breakpoint (CORE_ADDR addr, char *);
81
82static int procfs_insert_hw_watchpoint (CORE_ADDR addr, int len, int type);
83
84static int procfs_remove_hw_watchpoint (CORE_ADDR addr, int len, int type);
85
86static int procfs_stopped_by_watchpoint (void);
87
88/* These two globals are only ever set in procfs_open(), but are
89 referenced elsewhere. 'nto_procfs_node' is a flag used to say
90 whether we are local, or we should get the current node descriptor
91 for the remote QNX node. */
92static char nto_procfs_path[PATH_MAX] = { "/proc" };
93static unsigned nto_procfs_node = ND_LOCAL_NODE;
94
95/* Return the current QNX Node, or error out. This is a simple
96 wrapper for the netmgr_strtond() function. The reason this
97 is required is because QNX node descriptors are transient so
98 we have to re-acquire them every time. */
99static unsigned
dc5dd1eb 100nto_node(void)
61bb466e
KW
101{
102 unsigned node;
103
104 if (ND_NODE_CMP(nto_procfs_node, ND_LOCAL_NODE) == 0)
105 return ND_LOCAL_NODE;
106
107 node = netmgr_strtond(nto_procfs_path,0);
108 if (node == -1)
109 error ("Lost the QNX node. Debug session probably over.");
110
111 return (node);
112}
113
114/* This is called when we call 'target procfs <arg>' from the (gdb) prompt.
115 For QNX6 (nto), the only valid arg will be a QNX node string,
116 eg: "/net/some_node". If arg is not a valid QNX node, we will
117 default to local. */
118static void
119procfs_open (char *arg, int from_tty)
120{
121 char *nodestr;
122 char *endstr;
123 char buffer[50];
124 int fd, total_size;
125 procfs_sysinfo *sysinfo;
126
127 /* Set the default node used for spawning to this one,
128 and only override it if there is a valid arg. */
129
130 nto_procfs_node = ND_LOCAL_NODE;
131 nodestr = arg ? xstrdup (arg) : arg;
132
133 init_thread_list ();
134
135 if (nodestr)
136 {
137 nto_procfs_node = netmgr_strtond (nodestr, &endstr);
138 if (nto_procfs_node == -1)
139 {
140 if (errno == ENOTSUP)
141 printf_filtered ("QNX Net Manager not found.\n");
142 printf_filtered ("Invalid QNX node %s: error %d (%s).\n", nodestr,
dc5dd1eb 143 errno, safe_strerror (errno));
61bb466e
KW
144 xfree (nodestr);
145 nodestr = NULL;
146 nto_procfs_node = ND_LOCAL_NODE;
147 }
148 else if (*endstr)
149 {
150 if (*(endstr - 1) == '/')
151 *(endstr - 1) = 0;
152 else
153 *endstr = 0;
154 }
155 }
dc5dd1eb 156 snprintf (nto_procfs_path, PATH_MAX - 1, "%s%s", nodestr ? nodestr : "", "/proc");
61bb466e
KW
157 if (nodestr)
158 xfree (nodestr);
159
160 fd = open (nto_procfs_path, O_RDONLY);
161 if (fd == -1)
162 {
163 printf_filtered ("Error opening %s : %d (%s)\n", nto_procfs_path, errno,
dc5dd1eb 164 safe_strerror (errno));
61bb466e
KW
165 error ("Invalid procfs arg");
166 }
167
168 sysinfo = (void *) buffer;
169 if (devctl (fd, DCMD_PROC_SYSINFO, sysinfo, sizeof buffer, 0) != EOK)
170 {
171 printf_filtered ("Error getting size: %d (%s)\n", errno,
dc5dd1eb 172 safe_strerror (errno));
61bb466e
KW
173 close (fd);
174 error ("Devctl failed.");
175 }
176 else
177 {
178 total_size = sysinfo->total_size;
179 sysinfo = alloca (total_size);
180 if (!sysinfo)
181 {
182 printf_filtered ("Memory error: %d (%s)\n", errno,
dc5dd1eb 183 safe_strerror (errno));
61bb466e
KW
184 close (fd);
185 error ("alloca failed.");
186 }
187 else
188 {
189 if (devctl (fd, DCMD_PROC_SYSINFO, sysinfo, total_size, 0) != EOK)
190 {
191 printf_filtered ("Error getting sysinfo: %d (%s)\n", errno,
dc5dd1eb 192 safe_strerror (errno));
61bb466e
KW
193 close (fd);
194 error ("Devctl failed.");
195 }
196 else
197 {
198 if (sysinfo->type !=
199 nto_map_arch_to_cputype (TARGET_ARCHITECTURE->arch_name))
200 {
201 close (fd);
202 error ("Invalid target CPU.");
203 }
204 }
205 }
206 }
207 close (fd);
208 printf_filtered ("Debugging using %s\n", nto_procfs_path);
209}
210
211static void
212procfs_set_thread (ptid_t ptid)
213{
214 pid_t tid;
215
216 tid = ptid_get_tid (ptid);
217 devctl (ctl_fd, DCMD_PROC_CURTHREAD, &tid, sizeof (tid), 0);
218}
219
220/* Return nonzero if the thread TH is still alive. */
221static int
222procfs_thread_alive (ptid_t ptid)
223{
224 pid_t tid;
225
226 tid = ptid_get_tid (ptid);
227 if (devctl (ctl_fd, DCMD_PROC_CURTHREAD, &tid, sizeof (tid), 0) == EOK)
228 return 1;
229 return 0;
230}
231
232void
233procfs_find_new_threads (void)
234{
235 procfs_status status;
236 pid_t pid;
237 ptid_t ptid;
238
239 if (ctl_fd == -1)
240 return;
241
242 pid = ptid_get_pid (inferior_ptid);
243
244 for (status.tid = 1;; ++status.tid)
245 {
246 if (devctl (ctl_fd, DCMD_PROC_TIDSTATUS, &status, sizeof (status), 0)
247 != EOK && status.tid != 0)
248 break;
249 ptid = ptid_build (pid, 0, status.tid);
250 if (!in_thread_list (ptid))
251 add_thread (ptid);
252 }
253 return;
254}
255
256void
257procfs_pidlist (char *args, int from_tty)
258{
259 DIR *dp = NULL;
260 struct dirent *dirp = NULL;
261 int fd = -1;
262 char buf[512];
263 procfs_info *pidinfo = NULL;
264 procfs_debuginfo *info = NULL;
265 procfs_status *status = NULL;
266 pid_t num_threads = 0;
267 pid_t pid;
268 char name[512];
269
270 dp = opendir (nto_procfs_path);
271 if (dp == NULL)
272 {
dc5dd1eb
KW
273 fprintf_unfiltered (gdb_stderr, "failed to opendir \"%s\" - %d (%s)",
274 nto_procfs_path, errno, safe_strerror (errno));
61bb466e
KW
275 return;
276 }
277
278 /* Start scan at first pid. */
279 rewinddir (dp);
280
281 do
282 {
283 /* Get the right pid and procfs path for the pid. */
284 do
285 {
286 dirp = readdir (dp);
287 if (dirp == NULL)
288 {
289 closedir (dp);
290 return;
291 }
dc5dd1eb 292 snprintf (buf, 511, "%s/%s/as", nto_procfs_path, dirp->d_name);
61bb466e
KW
293 pid = atoi (dirp->d_name);
294 }
295 while (pid == 0);
296
297 /* Open the procfs path. */
298 fd = open (buf, O_RDONLY);
299 if (fd == -1)
300 {
dc5dd1eb
KW
301 fprintf_unfiltered (gdb_stderr, "failed to open %s - %d (%s)\n",
302 buf, errno, safe_strerror (errno));
61bb466e
KW
303 closedir (dp);
304 return;
305 }
306
307 pidinfo = (procfs_info *) buf;
308 if (devctl (fd, DCMD_PROC_INFO, pidinfo, sizeof (buf), 0) != EOK)
309 {
dc5dd1eb
KW
310 fprintf_unfiltered (gdb_stderr,
311 "devctl DCMD_PROC_INFO failed - %d (%s)\n", errno,
312 safe_strerror (errno));
61bb466e
KW
313 break;
314 }
315 num_threads = pidinfo->num_threads;
316
317 info = (procfs_debuginfo *) buf;
318 if (devctl (fd, DCMD_PROC_MAPDEBUG_BASE, info, sizeof (buf), 0) != EOK)
319 strcpy (name, "unavailable");
320 else
321 strcpy (name, info->path);
322
323 /* Collect state info on all the threads. */
324 status = (procfs_status *) buf;
325 for (status->tid = 1; status->tid <= num_threads; status->tid++)
326 {
327 if (devctl (fd, DCMD_PROC_TIDSTATUS, status, sizeof (buf), 0) != EOK
328 && status->tid != 0)
329 break;
330 if (status->tid != 0)
331 printf_filtered ("%s - %d/%d\n", name, pid, status->tid);
332 }
333 close (fd);
334 }
335 while (dirp != NULL);
336
337 close (fd);
338 closedir (dp);
339 return;
340}
341
342void
343procfs_meminfo (char *args, int from_tty)
344{
345 procfs_mapinfo *mapinfos = NULL;
346 static int num_mapinfos = 0;
347 procfs_mapinfo *mapinfo_p, *mapinfo_p2;
348 int flags = ~0, err, num, i, j;
349
350 struct
351 {
352 procfs_debuginfo info;
353 char buff[_POSIX_PATH_MAX];
354 } map;
355
356 struct info
357 {
358 unsigned addr;
359 unsigned size;
360 unsigned flags;
361 unsigned debug_vaddr;
362 unsigned long long offset;
363 };
364
365 struct printinfo
366 {
367 unsigned long long ino;
368 unsigned dev;
369 struct info text;
370 struct info data;
371 char name[256];
372 } printme;
373
374 /* Get the number of map entrys. */
375 err = devctl (ctl_fd, DCMD_PROC_MAPINFO, NULL, 0, &num);
376 if (err != EOK)
377 {
5483d879 378 printf ("failed devctl num mapinfos - %d (%s)\n", err, safe_strerror (err));
61bb466e
KW
379 return;
380 }
381
382 mapinfos = xmalloc (num * sizeof (procfs_mapinfo));
383
384 num_mapinfos = num;
385 mapinfo_p = mapinfos;
386
387 /* Fill the map entrys. */
388 err = devctl (ctl_fd, DCMD_PROC_MAPINFO, mapinfo_p, num
389 * sizeof (procfs_mapinfo), &num);
390 if (err != EOK)
391 {
5483d879 392 printf ("failed devctl mapinfos - %d (%s)\n", err, safe_strerror (err));
61bb466e
KW
393 xfree (mapinfos);
394 return;
395 }
396
397 num = min (num, num_mapinfos);
398
399 /* Run through the list of mapinfos, and store the data and text info
400 so we can print it at the bottom of the loop. */
401 for (mapinfo_p = mapinfos, i = 0; i < num; i++, mapinfo_p++)
402 {
403 if (!(mapinfo_p->flags & flags))
404 mapinfo_p->ino = 0;
405
406 if (mapinfo_p->ino == 0) /* Already visited. */
407 continue;
408
409 map.info.vaddr = mapinfo_p->vaddr;
410
411 err = devctl (ctl_fd, DCMD_PROC_MAPDEBUG, &map, sizeof (map), 0);
412 if (err != EOK)
413 continue;
414
415 memset (&printme, 0, sizeof printme);
416 printme.dev = mapinfo_p->dev;
417 printme.ino = mapinfo_p->ino;
418 printme.text.addr = mapinfo_p->vaddr;
419 printme.text.size = mapinfo_p->size;
420 printme.text.flags = mapinfo_p->flags;
421 printme.text.offset = mapinfo_p->offset;
422 printme.text.debug_vaddr = map.info.vaddr;
423 strcpy (printme.name, map.info.path);
424
425 /* Check for matching data. */
426 for (mapinfo_p2 = mapinfos, j = 0; j < num; j++, mapinfo_p2++)
427 {
428 if (mapinfo_p2->vaddr != mapinfo_p->vaddr
429 && mapinfo_p2->ino == mapinfo_p->ino
430 && mapinfo_p2->dev == mapinfo_p->dev)
431 {
432 map.info.vaddr = mapinfo_p2->vaddr;
433 err =
434 devctl (ctl_fd, DCMD_PROC_MAPDEBUG, &map, sizeof (map), 0);
435 if (err != EOK)
436 continue;
437
438 if (strcmp (map.info.path, printme.name))
439 continue;
440
441 /* Lower debug_vaddr is always text, if nessessary, swap. */
442 if ((int) map.info.vaddr < (int) printme.text.debug_vaddr)
443 {
444 memcpy (&(printme.data), &(printme.text),
445 sizeof (printme.data));
446 printme.text.addr = mapinfo_p2->vaddr;
447 printme.text.size = mapinfo_p2->size;
448 printme.text.flags = mapinfo_p2->flags;
449 printme.text.offset = mapinfo_p2->offset;
450 printme.text.debug_vaddr = map.info.vaddr;
451 }
452 else
453 {
454 printme.data.addr = mapinfo_p2->vaddr;
455 printme.data.size = mapinfo_p2->size;
456 printme.data.flags = mapinfo_p2->flags;
457 printme.data.offset = mapinfo_p2->offset;
458 printme.data.debug_vaddr = map.info.vaddr;
459 }
460 mapinfo_p2->ino = 0;
461 }
462 }
463 mapinfo_p->ino = 0;
464
465 printf_filtered ("%s\n", printme.name);
466 printf_filtered ("\ttext=%08x bytes @ 0x%08x\n", printme.text.size,
467 printme.text.addr);
468 printf_filtered ("\t\tflags=%08x\n", printme.text.flags);
469 printf_filtered ("\t\tdebug=%08x\n", printme.text.debug_vaddr);
470 printf_filtered ("\t\toffset=%016llx\n", printme.text.offset);
471 if (printme.data.size)
472 {
473 printf_filtered ("\tdata=%08x bytes @ 0x%08x\n", printme.data.size,
474 printme.data.addr);
475 printf_filtered ("\t\tflags=%08x\n", printme.data.flags);
476 printf_filtered ("\t\tdebug=%08x\n", printme.data.debug_vaddr);
477 printf_filtered ("\t\toffset=%016llx\n", printme.data.offset);
478 }
479 printf_filtered ("\tdev=0x%x\n", printme.dev);
480 printf_filtered ("\tino=0x%x\n", (unsigned int) printme.ino);
481 }
482 xfree (mapinfos);
483 return;
484}
485
486/* Print status information about what we're accessing. */
487static void
488procfs_files_info (struct target_ops *ignore)
489{
490 printf_unfiltered ("\tUsing the running image of %s %s via %s.\n",
491 attach_flag ? "attached" : "child",
492 target_pid_to_str (inferior_ptid), nto_procfs_path);
493}
494
495/* Mark our target-struct as eligible for stray "run" and "attach" commands. */
496static int
5483d879 497procfs_can_run (void)
61bb466e
KW
498{
499 return 1;
500}
501
502/* Attach to process PID, then initialize for debugging it. */
503static void
504procfs_attach (char *args, int from_tty)
505{
506 char *exec_file;
507 int pid;
508
509 if (!args)
510 error_no_arg ("process-id to attach");
511
512 pid = atoi (args);
513
514 if (pid == getpid ())
515 error ("Attaching GDB to itself is not a good idea...");
516
517 if (from_tty)
518 {
519 exec_file = (char *) get_exec_file (0);
520
521 if (exec_file)
522 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
523 target_pid_to_str (pid_to_ptid (pid)));
524 else
525 printf_unfiltered ("Attaching to %s\n",
526 target_pid_to_str (pid_to_ptid (pid)));
527
528 gdb_flush (gdb_stdout);
529 }
530 inferior_ptid = do_attach (pid_to_ptid (pid));
531 push_target (&procfs_ops);
532}
533
534static void
535procfs_post_attach (pid_t pid)
536{
537#ifdef SOLIB_CREATE_INFERIOR_HOOK
538 if (exec_bfd)
539 SOLIB_CREATE_INFERIOR_HOOK (pid);
540#endif
541}
542
543static ptid_t
544do_attach (ptid_t ptid)
545{
546 procfs_status status;
547 struct sigevent event;
dc5dd1eb 548 char path[PATH_MAX];
61bb466e 549
dc5dd1eb 550 snprintf (path, PATH_MAX - 1, "%s/%d/as", nto_procfs_path, PIDGET (ptid));
61bb466e
KW
551 ctl_fd = open (path, O_RDWR);
552 if (ctl_fd == -1)
553 error ("Couldn't open proc file %s, error %d (%s)", path, errno,
dc5dd1eb 554 safe_strerror (errno));
61bb466e
KW
555 if (devctl (ctl_fd, DCMD_PROC_STOP, &status, sizeof (status), 0) != EOK)
556 error ("Couldn't stop process");
557
558 /* Define a sigevent for process stopped notification. */
559 event.sigev_notify = SIGEV_SIGNAL_THREAD;
560 event.sigev_signo = SIGUSR1;
561 event.sigev_code = 0;
562 event.sigev_value.sival_ptr = NULL;
563 event.sigev_priority = -1;
564 devctl (ctl_fd, DCMD_PROC_EVENT, &event, sizeof (event), 0);
565
566 if (devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0) == EOK
567 && status.flags & _DEBUG_FLAG_STOPPED)
568 SignalKill (nto_node(), PIDGET (ptid), 0, SIGCONT, 0, 0);
569 attach_flag = 1;
570 nto_init_solib_absolute_prefix ();
571 return ptid;
572}
573
574/* Ask the user what to do when an interrupt is received. */
575static void
dc5dd1eb 576interrupt_query (void)
61bb466e
KW
577{
578 target_terminal_ours ();
579
580 if (query ("Interrupted while waiting for the program.\n\
581Give up (and stop debugging it)? "))
582 {
583 target_mourn_inferior ();
584 throw_exception (RETURN_QUIT);
585 }
586
587 target_terminal_inferior ();
588}
589
590/* The user typed ^C twice. */
591static void
592nto_interrupt_twice (int signo)
593{
594 signal (signo, ofunc);
595 interrupt_query ();
596 signal (signo, nto_interrupt_twice);
597}
598
599static void
600nto_interrupt (int signo)
601{
602 /* If this doesn't work, try more severe steps. */
603 signal (signo, nto_interrupt_twice);
604
605 target_stop ();
606}
607
608static ptid_t
609procfs_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
610{
611 sigset_t set;
612 siginfo_t info;
613 procfs_status status;
614 static int exit_signo = 0; /* To track signals that cause termination. */
615
616 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
617
618 if (ptid_equal (inferior_ptid, null_ptid))
619 {
620 ourstatus->kind = TARGET_WAITKIND_STOPPED;
621 ourstatus->value.sig = TARGET_SIGNAL_0;
622 exit_signo = 0;
623 return null_ptid;
624 }
625
626 sigemptyset (&set);
627 sigaddset (&set, SIGUSR1);
628
629 devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0);
630 while (!(status.flags & _DEBUG_FLAG_ISTOP))
631 {
632 ofunc = (void (*)()) signal (SIGINT, nto_interrupt);
633 sigwaitinfo (&set, &info);
634 signal (SIGINT, ofunc);
635 devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0);
636 }
637
638 if (status.flags & _DEBUG_FLAG_SSTEP)
639 {
640 ourstatus->kind = TARGET_WAITKIND_STOPPED;
641 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
642 }
643 /* Was it a breakpoint? */
644 else if (status.flags & _DEBUG_FLAG_TRACE)
645 {
646 ourstatus->kind = TARGET_WAITKIND_STOPPED;
647 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
648 }
649 else if (status.flags & _DEBUG_FLAG_ISTOP)
650 {
651 switch (status.why)
652 {
653 case _DEBUG_WHY_SIGNALLED:
654 ourstatus->kind = TARGET_WAITKIND_STOPPED;
655 ourstatus->value.sig =
656 target_signal_from_host (status.info.si_signo);
657 exit_signo = 0;
658 break;
659 case _DEBUG_WHY_FAULTED:
660 ourstatus->kind = TARGET_WAITKIND_STOPPED;
661 if (status.info.si_signo == SIGTRAP)
662 {
663 ourstatus->value.sig = 0;
664 exit_signo = 0;
665 }
666 else
667 {
668 ourstatus->value.sig =
669 target_signal_from_host (status.info.si_signo);
670 exit_signo = ourstatus->value.sig;
671 }
672 break;
673
674 case _DEBUG_WHY_TERMINATED:
675 {
676 int waitval = 0;
677
678 waitpid (PIDGET (inferior_ptid), &waitval, WNOHANG);
679 if (exit_signo)
680 {
681 /* Abnormal death. */
682 ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
683 ourstatus->value.sig = exit_signo;
684 }
685 else
686 {
687 /* Normal death. */
688 ourstatus->kind = TARGET_WAITKIND_EXITED;
689 ourstatus->value.integer = WEXITSTATUS (waitval);
690 }
691 exit_signo = 0;
692 break;
693 }
694
695 case _DEBUG_WHY_REQUESTED:
696 /* We are assuming a requested stop is due to a SIGINT. */
697 ourstatus->kind = TARGET_WAITKIND_STOPPED;
698 ourstatus->value.sig = TARGET_SIGNAL_INT;
699 exit_signo = 0;
700 break;
701 }
702 }
703
704 return inferior_ptid;
705}
706
707/* Read the current values of the inferior's registers, both the
708 general register set and floating point registers (if supported)
709 and update gdb's idea of their current values. */
710static void
711procfs_fetch_registers (int regno)
712{
713 union
714 {
715 procfs_greg greg;
716 procfs_fpreg fpreg;
717 procfs_altreg altreg;
718 }
719 reg;
720 int regsize;
721
722 procfs_set_thread (inferior_ptid);
723 if (devctl (ctl_fd, DCMD_PROC_GETGREG, &reg, sizeof (reg), &regsize) == EOK)
724 nto_supply_gregset ((char *) &reg.greg);
725 if (devctl (ctl_fd, DCMD_PROC_GETFPREG, &reg, sizeof (reg), &regsize)
726 == EOK)
727 nto_supply_fpregset ((char *) &reg.fpreg);
728 if (devctl (ctl_fd, DCMD_PROC_GETALTREG, &reg, sizeof (reg), &regsize)
729 == EOK)
730 nto_supply_altregset ((char *) &reg.altreg);
731}
732
733/* Copy LEN bytes to/from inferior's memory starting at MEMADDR
734 from/to debugger memory starting at MYADDR. Copy from inferior
735 if DOWRITE is zero or to inferior if DOWRITE is nonzero.
736
737 Returns the length copied, which is either the LEN argument or
738 zero. This xfer function does not do partial moves, since procfs_ops
739 doesn't allow memory operations to cross below us in the target stack
740 anyway. */
741static int
742procfs_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int dowrite,
743 struct mem_attrib *attrib, struct target_ops *target)
744{
745 int nbytes = 0;
746
747 if (lseek (ctl_fd, (off_t) memaddr, SEEK_SET) == (off_t) memaddr)
748 {
749 if (dowrite)
750 nbytes = write (ctl_fd, myaddr, len);
751 else
752 nbytes = read (ctl_fd, myaddr, len);
753 if (nbytes < 0)
754 nbytes = 0;
755 }
756 return (nbytes);
757}
758
759/* Take a program previously attached to and detaches it.
760 The program resumes execution and will no longer stop
761 on signals, etc. We'd better not have left any breakpoints
762 in the program or it'll die when it hits one. */
763static void
764procfs_detach (char *args, int from_tty)
765{
766 int siggnal = 0;
767
768 if (from_tty)
769 {
770 char *exec_file = get_exec_file (0);
771 if (exec_file == 0)
772 exec_file = "";
773 printf_unfiltered ("Detaching from program: %s %s\n",
774 exec_file, target_pid_to_str (inferior_ptid));
775 gdb_flush (gdb_stdout);
776 }
777 if (args)
778 siggnal = atoi (args);
779
780 if (siggnal)
781 SignalKill (nto_node(), PIDGET (inferior_ptid), 0, siggnal, 0, 0);
782
783 close (ctl_fd);
784 ctl_fd = -1;
785 init_thread_list ();
786 inferior_ptid = null_ptid;
787 attach_flag = 0;
788 unpush_target (&procfs_ops); /* Pop out of handling an inferior. */
789}
790
791static int
792procfs_breakpoint (CORE_ADDR addr, int type, int size)
793{
794 procfs_break brk;
795
796 brk.type = type;
797 brk.addr = addr;
798 brk.size = size;
799 errno = devctl (ctl_fd, DCMD_PROC_BREAK, &brk, sizeof (brk), 0);
800 if (errno != EOK)
801 return 1;
802 return 0;
803}
804
805static int
806procfs_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
807{
808 return procfs_breakpoint (addr, _DEBUG_BREAK_EXEC, 0);
809}
810
811static int
812procfs_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
813{
814 return procfs_breakpoint (addr, _DEBUG_BREAK_EXEC, -1);
815}
816
817static int
818procfs_insert_hw_breakpoint (CORE_ADDR addr, char *contents_cache)
819{
820 return procfs_breakpoint (addr, _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, 0);
821}
822
823static int
824procfs_remove_hw_breakpoint (CORE_ADDR addr, char *contents_cache)
825{
826 return procfs_breakpoint (addr, _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, -1);
827}
828
829static void
830procfs_resume (ptid_t ptid, int step, enum target_signal signo)
831{
832 int signal_to_pass;
833 procfs_status status;
834
835 if (ptid_equal (inferior_ptid, null_ptid))
836 return;
837
838 procfs_set_thread (ptid_equal (ptid, minus_one_ptid) ? inferior_ptid :
839 ptid);
840
841 run.flags = _DEBUG_RUN_FAULT | _DEBUG_RUN_TRACE;
842 if (step)
843 run.flags |= _DEBUG_RUN_STEP;
844
845 sigemptyset ((sigset_t *) &run.fault);
846 sigaddset ((sigset_t *) &run.fault, FLTBPT);
847 sigaddset ((sigset_t *) &run.fault, FLTTRACE);
848 sigaddset ((sigset_t *) &run.fault, FLTILL);
849 sigaddset ((sigset_t *) &run.fault, FLTPRIV);
850 sigaddset ((sigset_t *) &run.fault, FLTBOUNDS);
851 sigaddset ((sigset_t *) &run.fault, FLTIOVF);
852 sigaddset ((sigset_t *) &run.fault, FLTIZDIV);
853 sigaddset ((sigset_t *) &run.fault, FLTFPE);
854 /* Peter V will be changing this at some point. */
855 sigaddset ((sigset_t *) &run.fault, FLTPAGE);
856
857 run.flags |= _DEBUG_RUN_ARM;
858
859 sigemptyset (&run.trace);
860 notice_signals ();
861 signal_to_pass = target_signal_to_host (signo);
862
863 if (signal_to_pass)
864 {
865 devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0);
866 signal_to_pass = target_signal_to_host (signo);
867 if (status.why & (_DEBUG_WHY_SIGNALLED | _DEBUG_WHY_FAULTED))
868 {
869 if (signal_to_pass != status.info.si_signo)
870 {
871 SignalKill (nto_node(), PIDGET (inferior_ptid), 0, signal_to_pass,
872 0, 0);
873 run.flags |= _DEBUG_RUN_CLRFLT | _DEBUG_RUN_CLRSIG;
874 }
875 else /* Let it kill the program without telling us. */
876 sigdelset (&run.trace, signal_to_pass);
877 }
878 }
879 else
880 run.flags |= _DEBUG_RUN_CLRSIG | _DEBUG_RUN_CLRFLT;
881
882 errno = devctl (ctl_fd, DCMD_PROC_RUN, &run, sizeof (run), 0);
883 if (errno != EOK)
884 {
885 perror ("run error!\n");
886 return;
887 }
888}
889
890static void
dc5dd1eb 891procfs_mourn_inferior (void)
61bb466e
KW
892{
893 if (!ptid_equal (inferior_ptid, null_ptid))
894 {
895 SignalKill (nto_node(), PIDGET (inferior_ptid), 0, SIGKILL, 0, 0);
896 close (ctl_fd);
897 }
898 inferior_ptid = null_ptid;
899 init_thread_list ();
900 unpush_target (&procfs_ops);
901 generic_mourn_inferior ();
902 attach_flag = 0;
903}
904
905/* This function breaks up an argument string into an argument
906 vector suitable for passing to execvp().
907 E.g., on "run a b c d" this routine would get as input
908 the string "a b c d", and as output it would fill in argv with
909 the four arguments "a", "b", "c", "d". The only additional
910 functionality is simple quoting. The gdb command:
911 run a "b c d" f
912 will fill in argv with the three args "a", "b c d", "e". */
913static void
914breakup_args (char *scratch, char **argv)
915{
916 char *pp, *cp = scratch;
917 char quoting = 0;
918
919 for (;;)
920 {
921 /* Scan past leading separators. */
922 quoting = 0;
923 while (*cp == ' ' || *cp == '\t' || *cp == '\n')
924 cp++;
925
926 /* Break if at end of string. */
927 if (*cp == '\0')
928 break;
929
930 /* Take an arg. */
931 if (*cp == '"')
932 {
933 cp++;
934 quoting = strchr (cp, '"') ? 1 : 0;
935 }
936
937 *argv++ = cp;
938
939 /* Scan for next arg separator. */
940 pp = cp;
941 if (quoting)
942 cp = strchr (pp, '"');
943 if ((cp == NULL) || (!quoting))
944 cp = strchr (pp, ' ');
945 if (cp == NULL)
946 cp = strchr (pp, '\t');
947 if (cp == NULL)
948 cp = strchr (pp, '\n');
949
950 /* No separators => end of string => break. */
951 if (cp == NULL)
952 {
953 pp = cp;
954 break;
955 }
956
957 /* Replace the separator with a terminator. */
958 *cp++ = '\0';
959 }
960
961 /* Execv requires a null-terminated arg vector. */
962 *argv = NULL;
963}
964
965static void
c27cda74
AC
966procfs_create_inferior (char *exec_file, char *allargs, char **env,
967 int from_tty)
61bb466e
KW
968{
969 struct inheritance inherit;
970 pid_t pid;
971 int flags, errn;
972 char **argv, *args;
973 char *in = "", *out = "", *err = "";
974 int fd, fds[3];
975 sigset_t set;
976
977 argv = xmalloc (((strlen (allargs) + 1) / (unsigned) 2 + 2) *
978 sizeof (*argv));
979 argv[0] = get_exec_file (1);
980 if (!argv[0])
981 {
982 if (exec_file)
983 argv[0] = exec_file;
984 else
985 return;
986 }
987
988 args = xstrdup (allargs);
989 breakup_args (args, exec_file ? &argv[1] : &argv[0]);
990
991 argv = nto_parse_redirection (argv, &in, &out, &err);
992
993 fds[0] = STDIN_FILENO;
994 fds[1] = STDOUT_FILENO;
995 fds[2] = STDERR_FILENO;
996
997 /* If the user specified I/O via gdb's --tty= arg, use it, but only
998 if the i/o is not also being specified via redirection. */
999 if (inferior_io_terminal)
1000 {
1001 if (!in[0])
1002 in = inferior_io_terminal;
1003 if (!out[0])
1004 out = inferior_io_terminal;
1005 if (!err[0])
1006 err = inferior_io_terminal;
1007 }
1008
1009 if (in[0])
1010 {
1011 fd = open (in, O_RDONLY);
1012 if (fd == -1)
1013 perror (in);
1014 else
1015 fds[0] = fd;
1016 }
1017 if (out[0])
1018 {
1019 fd = open (out, O_WRONLY);
1020 if (fd == -1)
1021 perror (out);
1022 else
1023 fds[1] = fd;
1024 }
1025 if (err[0])
1026 {
1027 fd = open (err, O_WRONLY);
1028 if (fd == -1)
1029 perror (err);
1030 else
1031 fds[2] = fd;
1032 }
1033
1034 /* Clear any pending SIGUSR1's but keep the behavior the same. */
1035 signal (SIGUSR1, signal (SIGUSR1, SIG_IGN));
1036
1037 sigemptyset (&set);
1038 sigaddset (&set, SIGUSR1);
1039 sigprocmask (SIG_UNBLOCK, &set, NULL);
1040
1041 memset (&inherit, 0, sizeof (inherit));
1042
1043 if (ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) != 0)
1044 {
1045 inherit.nd = nto_node();
1046 inherit.flags |= SPAWN_SETND;
1047 inherit.flags &= ~SPAWN_EXEC;
1048 }
1049 inherit.flags |= SPAWN_SETGROUP | SPAWN_HOLD;
1050 inherit.pgroup = SPAWN_NEWPGROUP;
1051 pid = spawnp (argv[0], 3, fds, &inherit, argv,
1052 ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) == 0 ? env : 0);
1053 xfree (args);
1054
1055 sigprocmask (SIG_BLOCK, &set, NULL);
1056
1057 if (pid == -1)
dc5dd1eb 1058 error ("Error spawning %s: %d (%s)", argv[0], errno, safe_strerror (errno));
61bb466e
KW
1059
1060 if (fds[0] != STDIN_FILENO)
1061 close (fds[0]);
1062 if (fds[1] != STDOUT_FILENO)
1063 close (fds[1]);
1064 if (fds[2] != STDERR_FILENO)
1065 close (fds[2]);
1066
1067 inferior_ptid = do_attach (pid_to_ptid (pid));
1068
1069 attach_flag = 0;
1070 flags = _DEBUG_FLAG_KLC; /* Kill-on-Last-Close flag. */
1071 errn = devctl (ctl_fd, DCMD_PROC_SET_FLAG, &flags, sizeof (flags), 0);
1072 if (errn != EOK)
1073 {
1074 /* FIXME: expected warning? */
1075 /* warning( "Failed to set Kill-on-Last-Close flag: errno = %d(%s)\n",
1076 errn, strerror(errn) ); */
1077 }
1078 push_target (&procfs_ops);
1079 target_terminal_init ();
1080
1081#ifdef SOLIB_CREATE_INFERIOR_HOOK
1082 if (exec_bfd != NULL
1083 || (symfile_objfile != NULL && symfile_objfile->obfd != NULL))
1084 SOLIB_CREATE_INFERIOR_HOOK (pid);
1085#endif
1086}
1087
1088static void
dc5dd1eb 1089procfs_stop (void)
61bb466e
KW
1090{
1091 devctl (ctl_fd, DCMD_PROC_STOP, NULL, 0, 0);
1092}
1093
1094static void
dc5dd1eb 1095procfs_kill_inferior (void)
61bb466e
KW
1096{
1097 target_mourn_inferior ();
1098}
1099
1100/* Store register REGNO, or all registers if REGNO == -1, from the contents
1101 of REGISTERS. */
1102static void
dc5dd1eb 1103procfs_prepare_to_store (void)
61bb466e
KW
1104{
1105}
1106
1107/* Fill buf with regset and return devctl cmd to do the setting. Return
1108 -1 if we fail to get the regset. Store size of regset in regsize. */
1109static int
1110get_regset (int regset, char *buf, int bufsize, int *regsize)
1111{
1112 int dev_get, dev_set;
1113 switch (regset)
1114 {
1115 case NTO_REG_GENERAL:
1116 dev_get = DCMD_PROC_GETGREG;
1117 dev_set = DCMD_PROC_SETGREG;
1118 break;
1119
1120 case NTO_REG_FLOAT:
1121 dev_get = DCMD_PROC_GETFPREG;
1122 dev_set = DCMD_PROC_SETFPREG;
1123 break;
1124
1125 case NTO_REG_ALT:
1126 dev_get = DCMD_PROC_GETALTREG;
1127 dev_set = DCMD_PROC_SETALTREG;
1128 break;
1129
1130 case NTO_REG_SYSTEM:
1131 default:
1132 return -1;
1133 }
1134 if (devctl (ctl_fd, dev_get, &buf, bufsize, regsize) != EOK)
1135 return -1;
1136
1137 return dev_set;
1138}
1139
1140void
1141procfs_store_registers (int regno)
1142{
1143 union
1144 {
1145 procfs_greg greg;
1146 procfs_fpreg fpreg;
1147 procfs_altreg altreg;
1148 }
1149 reg;
1150 unsigned off;
1151 int len, regset, regsize, dev_set, err;
1152 char *data;
1153
1154 if (ptid_equal (inferior_ptid, null_ptid))
1155 return;
1156 procfs_set_thread (inferior_ptid);
1157
1158 if (regno == -1)
1159 {
1160 for (regset = NTO_REG_GENERAL; regset < NTO_REG_END; regset++)
1161 {
1162 dev_set = get_regset (regset, (char *) &reg,
1163 sizeof (reg), &regsize);
1164 if (dev_set == -1)
1165 continue;
1166
1167 if (nto_regset_fill (regset, (char *) &reg) == -1)
1168 continue;
1169
1170 err = devctl (ctl_fd, dev_set, &reg, regsize, 0);
1171 if (err != EOK)
1172 fprintf_unfiltered (gdb_stderr,
1173 "Warning unable to write regset %d: %s\n",
dc5dd1eb 1174 regno, safe_strerror (err));
61bb466e
KW
1175 }
1176 }
1177 else
1178 {
1179 regset = nto_regset_id (regno);
1180 if (regset == -1)
1181 return;
1182
1183 dev_set = get_regset (regset, (char *) &reg, sizeof (reg), &regsize);
1184 if (dev_set == -1)
1185 return;
1186
1187 len = nto_register_area (regno, regset, &off);
1188
1189 if (len < 1)
1190 return;
1191
822c9732 1192 regcache_raw_collect (current_regcache, regno, (char *) &reg + off);
61bb466e
KW
1193
1194 err = devctl (ctl_fd, dev_set, &reg, regsize, 0);
1195 if (err != EOK)
1196 fprintf_unfiltered (gdb_stderr,
1197 "Warning unable to write regset %d: %s\n", regno,
dc5dd1eb 1198 safe_strerror (err));
61bb466e
KW
1199 }
1200}
1201
1202static void
1203notice_signals (void)
1204{
1205 int signo;
1206
1207 for (signo = 1; signo < NSIG; signo++)
1208 {
1209 if (signal_stop_state (target_signal_from_host (signo)) == 0
1210 && signal_print_state (target_signal_from_host (signo)) == 0
1211 && signal_pass_state (target_signal_from_host (signo)) == 1)
1212 sigdelset (&run.trace, signo);
1213 else
1214 sigaddset (&run.trace, signo);
1215 }
1216}
1217
1218/* When the user changes the state of gdb's signal handling via the
1219 "handle" command, this function gets called to see if any change
1220 in the /proc interface is required. It is also called internally
1221 by other /proc interface functions to initialize the state of
1222 the traced signal set. */
1223static void
1224procfs_notice_signals (ptid_t ptid)
1225{
1226 sigemptyset (&run.trace);
1227 notice_signals ();
1228}
1229
1230static struct tidinfo *
1231procfs_thread_info (pid_t pid, short tid)
1232{
1233/* NYI */
1234 return NULL;
1235}
1236
1237char *
1238procfs_pid_to_str (ptid_t ptid)
1239{
1240 static char buf[1024];
1241 int pid, tid, n;
1242 struct tidinfo *tip;
1243
1244 pid = ptid_get_pid (ptid);
1245 tid = ptid_get_tid (ptid);
1246
dc5dd1eb 1247 n = snprintf (buf, 1023, "process %d", pid);
61bb466e
KW
1248
1249#if 0 /* NYI */
1250 tip = procfs_thread_info (pid, tid);
1251 if (tip != NULL)
dc5dd1eb 1252 snprintf (&buf[n], 1023, " (state = 0x%02x)", tip->state);
61bb466e
KW
1253#endif
1254
1255 return buf;
1256}
1257
1258static void
dc5dd1eb 1259init_procfs_ops (void)
61bb466e
KW
1260{
1261 procfs_ops.to_shortname = "procfs";
1262 procfs_ops.to_longname = "QNX Neutrino procfs child process";
1263 procfs_ops.to_doc =
1264 "QNX Neutrino procfs child process (started by the \"run\" command).\n\
1265 target procfs <node>";
1266 procfs_ops.to_open = procfs_open;
1267 procfs_ops.to_attach = procfs_attach;
1268 procfs_ops.to_post_attach = procfs_post_attach;
1269 procfs_ops.to_detach = procfs_detach;
1270 procfs_ops.to_resume = procfs_resume;
1271 procfs_ops.to_wait = procfs_wait;
1272 procfs_ops.to_fetch_registers = procfs_fetch_registers;
1273 procfs_ops.to_store_registers = procfs_store_registers;
1274 procfs_ops.to_prepare_to_store = procfs_prepare_to_store;
c8e73a31 1275 procfs_ops.deprecated_xfer_memory = procfs_xfer_memory;
61bb466e
KW
1276 procfs_ops.to_files_info = procfs_files_info;
1277 procfs_ops.to_insert_breakpoint = procfs_insert_breakpoint;
1278 procfs_ops.to_remove_breakpoint = procfs_remove_breakpoint;
1279 procfs_ops.to_can_use_hw_breakpoint = procfs_can_use_hw_breakpoint;
1280 procfs_ops.to_insert_hw_breakpoint = procfs_insert_hw_breakpoint;
1281 procfs_ops.to_remove_hw_breakpoint = procfs_remove_breakpoint;
1282 procfs_ops.to_insert_watchpoint = procfs_insert_hw_watchpoint;
1283 procfs_ops.to_remove_watchpoint = procfs_remove_hw_watchpoint;
1284 procfs_ops.to_stopped_by_watchpoint = procfs_stopped_by_watchpoint;
1285 procfs_ops.to_terminal_init = terminal_init_inferior;
1286 procfs_ops.to_terminal_inferior = terminal_inferior;
1287 procfs_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1288 procfs_ops.to_terminal_ours = terminal_ours;
1289 procfs_ops.to_terminal_info = child_terminal_info;
1290 procfs_ops.to_kill = procfs_kill_inferior;
1291 procfs_ops.to_create_inferior = procfs_create_inferior;
1292 procfs_ops.to_mourn_inferior = procfs_mourn_inferior;
1293 procfs_ops.to_can_run = procfs_can_run;
1294 procfs_ops.to_notice_signals = procfs_notice_signals;
1295 procfs_ops.to_thread_alive = procfs_thread_alive;
1296 procfs_ops.to_find_new_threads = procfs_find_new_threads;
1297 procfs_ops.to_pid_to_str = procfs_pid_to_str;
1298 procfs_ops.to_stop = procfs_stop;
1299 procfs_ops.to_stratum = process_stratum;
1300 procfs_ops.to_has_all_memory = 1;
1301 procfs_ops.to_has_memory = 1;
1302 procfs_ops.to_has_stack = 1;
1303 procfs_ops.to_has_registers = 1;
1304 procfs_ops.to_has_execution = 1;
1305 procfs_ops.to_magic = OPS_MAGIC;
1306 procfs_ops.to_have_continuable_watchpoint = 1;
1307}
1308
1309#define OSTYPE_NTO 1
1310
1311void
dc5dd1eb 1312_initialize_procfs (void)
61bb466e
KW
1313{
1314 sigset_t set;
1315
1316 init_procfs_ops ();
1317 add_target (&procfs_ops);
1318
1319 /* We use SIGUSR1 to gain control after we block waiting for a process.
1320 We use sigwaitevent to wait. */
1321 sigemptyset (&set);
1322 sigaddset (&set, SIGUSR1);
1323 sigprocmask (SIG_BLOCK, &set, NULL);
1324
1325 /* Set up trace and fault sets, as gdb expects them. */
1326 sigemptyset (&run.trace);
1327 notice_signals ();
1328
1329 /* Stuff some information. */
1330 nto_cpuinfo_flags = SYSPAGE_ENTRY (cpuinfo)->flags;
1331 nto_cpuinfo_valid = 1;
1332
1333 add_info ("pidlist", procfs_pidlist, "pidlist");
1334 add_info ("meminfo", procfs_meminfo, "memory information");
1335}
1336
1337
1338static int
1339procfs_hw_watchpoint (int addr, int len, int type)
1340{
1341 procfs_break brk;
1342
1343 switch (type)
1344 {
1345 case 1: /* Read. */
1346 brk.type = _DEBUG_BREAK_RD;
1347 break;
1348 case 2: /* Read/Write. */
1349 brk.type = _DEBUG_BREAK_RW;
1350 break;
1351 default: /* Modify. */
1352/* FIXME: brk.type = _DEBUG_BREAK_RWM gives EINVAL for some reason. */
1353 brk.type = _DEBUG_BREAK_RW;
1354 }
1355 brk.type |= _DEBUG_BREAK_HW; /* Always ask for HW. */
1356 brk.addr = addr;
1357 brk.size = len;
1358
1359 errno = devctl (ctl_fd, DCMD_PROC_BREAK, &brk, sizeof (brk), 0);
1360 if (errno != EOK)
1361 {
1362 perror ("Failed to set hardware watchpoint");
1363 return -1;
1364 }
1365 return 0;
1366}
1367
1368static int
1369procfs_can_use_hw_breakpoint (int type, int cnt, int othertype)
1370{
1371 return 1;
1372}
1373
1374static int
1375procfs_remove_hw_watchpoint (CORE_ADDR addr, int len, int type)
1376{
1377 return procfs_hw_watchpoint (addr, -1, type);
1378}
1379
1380static int
1381procfs_insert_hw_watchpoint (CORE_ADDR addr, int len, int type)
1382{
1383 return procfs_hw_watchpoint (addr, len, type);
1384}
1385
1386static int
1387procfs_stopped_by_watchpoint (void)
1388{
1389 return 0;
1390}
This page took 0.255889 seconds and 4 git commands to generate.