* server.c (handle_query) <qSupported>: Do two passes over the
[deliverable/binutils-gdb.git] / gdb / gdbserver / mem-break.c
CommitLineData
611cb4a5 1/* Memory breakpoint operations for the remote server for GDB.
4c38e0a4 2 Copyright (C) 2002, 2003, 2005, 2007, 2008, 2009, 2010
0fb0cc75 3 Free Software Foundation, Inc.
611cb4a5
DJ
4
5 Contributed by MontaVista Software.
6
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
a9762ec7 11 the Free Software Foundation; either version 3 of the License, or
611cb4a5
DJ
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
a9762ec7 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
611cb4a5
DJ
21
22#include "server.h"
23
f450004a 24const unsigned char *breakpoint_data;
611cb4a5
DJ
25int breakpoint_len;
26
27#define MAX_BREAKPOINT_LEN 8
28
8b07ae33
PA
29/* GDB will never try to install multiple breakpoints at the same
30 address. But, we need to keep track of internal breakpoints too,
31 and so we do need to be able to install multiple breakpoints at the
32 same address transparently. We keep track of two different, and
33 closely related structures. A raw breakpoint, which manages the
34 low level, close to the metal aspect of a breakpoint. It holds the
35 breakpoint address, and a buffer holding a copy of the instructions
36 that would be in memory had not been a breakpoint there (we call
37 that the shadow memory of the breakpoint). We occasionally need to
38 temporarilly uninsert a breakpoint without the client knowing about
39 it (e.g., to step over an internal breakpoint), so we keep an
40 `inserted' state associated with this low level breakpoint
41 structure. There can only be one such object for a given address.
42 Then, we have (a bit higher level) breakpoints. This structure
43 holds a callback to be called whenever a breakpoint is hit, a
44 high-level type, and a link to a low level raw breakpoint. There
45 can be many high-level breakpoints at the same address, and all of
46 them will point to the same raw breakpoint, which is reference
47 counted. */
48
49/* The low level, physical, raw breakpoint. */
50struct raw_breakpoint
51{
52 struct raw_breakpoint *next;
53
54 /* A reference count. Each high level breakpoint referencing this
55 raw breakpoint accounts for one reference. */
56 int refcount;
57
58 /* The breakpoint's insertion address. There can only be one raw
59 breakpoint for a given PC. */
60 CORE_ADDR pc;
61
62 /* The breakpoint's shadow memory. */
63 unsigned char old_data[MAX_BREAKPOINT_LEN];
64
65 /* Non-zero if this breakpoint is currently inserted in the
66 inferior. */
67 int inserted;
d3bbe7a0
PA
68
69 /* Non-zero if this breakpoint is currently disabled because we no
70 longer detect it as inserted. */
71 int shlib_disabled;
8b07ae33
PA
72};
73
414a389f
PA
74/* The type of a breakpoint. */
75enum bkpt_type
76 {
8b07ae33
PA
77 /* A GDB breakpoint, requested with a Z0 packet. */
78 gdb_breakpoint,
79
414a389f
PA
80 /* A basic-software-single-step breakpoint. */
81 reinsert_breakpoint,
82
83 /* Any other breakpoint type that doesn't require specific
84 treatment goes here. E.g., an event breakpoint. */
85 other_breakpoint,
86 };
87
8b07ae33 88/* A high level (in gdbserver's perspective) breakpoint. */
611cb4a5
DJ
89struct breakpoint
90{
91 struct breakpoint *next;
611cb4a5 92
414a389f
PA
93 /* The breakpoint's type. */
94 enum bkpt_type type;
95
8b07ae33
PA
96 /* Link to this breakpoint's raw breakpoint. This is always
97 non-NULL. */
98 struct raw_breakpoint *raw;
99
b65d95c5 100 /* Function to call when we hit this breakpoint. If it returns 1,
8b07ae33
PA
101 the breakpoint shall be deleted; 0 or if this callback is NULL,
102 it will be left inserted. */
b65d95c5 103 int (*handler) (CORE_ADDR);
611cb4a5
DJ
104};
105
8b07ae33
PA
106static struct raw_breakpoint *
107find_raw_breakpoint_at (CORE_ADDR where)
108{
109 struct process_info *proc = current_process ();
110 struct raw_breakpoint *bp;
414a389f 111
8b07ae33
PA
112 for (bp = proc->raw_breakpoints; bp != NULL; bp = bp->next)
113 if (bp->pc == where)
114 return bp;
115
116 return NULL;
117}
118
119static struct raw_breakpoint *
d50171e4 120set_raw_breakpoint_at (CORE_ADDR where)
611cb4a5 121{
95954743 122 struct process_info *proc = current_process ();
8b07ae33 123 struct raw_breakpoint *bp;
d50171e4 124 int err;
611cb4a5
DJ
125
126 if (breakpoint_data == NULL)
127 error ("Target does not support breakpoints.");
128
8b07ae33
PA
129 bp = find_raw_breakpoint_at (where);
130 if (bp != NULL)
131 {
132 bp->refcount++;
133 return bp;
134 }
135
d50171e4
PA
136 bp = xcalloc (1, sizeof (*bp));
137 bp->pc = where;
8b07ae33 138 bp->refcount = 1;
611cb4a5 139
d50171e4
PA
140 err = (*the_target->read_memory) (where, bp->old_data,
141 breakpoint_len);
142 if (err != 0)
143 {
144 if (debug_threads)
145 fprintf (stderr,
146 "Failed to read shadow memory of"
147 " breakpoint at 0x%s (%s).\n",
148 paddress (where), strerror (err));
149 free (bp);
150 return NULL;
151 }
611cb4a5 152
d50171e4
PA
153 err = (*the_target->write_memory) (where, breakpoint_data,
154 breakpoint_len);
155 if (err != 0)
156 {
157 if (debug_threads)
158 fprintf (stderr,
159 "Failed to insert breakpoint at 0x%s (%s).\n",
160 paddress (where), strerror (err));
161 free (bp);
162 return NULL;
163 }
164
165 /* Link the breakpoint in. */
166 bp->inserted = 1;
8b07ae33
PA
167 bp->next = proc->raw_breakpoints;
168 proc->raw_breakpoints = bp;
d50171e4
PA
169 return bp;
170}
171
414a389f 172struct breakpoint *
d50171e4
PA
173set_breakpoint_at (CORE_ADDR where, int (*handler) (CORE_ADDR))
174{
175 struct process_info *proc = current_process ();
176 struct breakpoint *bp;
8b07ae33 177 struct raw_breakpoint *raw;
d50171e4 178
8b07ae33 179 raw = set_raw_breakpoint_at (where);
d50171e4 180
8b07ae33 181 if (raw == NULL)
d50171e4
PA
182 {
183 /* warn? */
414a389f 184 return NULL;
d50171e4
PA
185 }
186
187 bp = xcalloc (1, sizeof (struct breakpoint));
414a389f 188 bp->type = other_breakpoint;
8b07ae33
PA
189
190 bp->raw = raw;
611cb4a5
DJ
191 bp->handler = handler;
192
95954743
PA
193 bp->next = proc->breakpoints;
194 proc->breakpoints = bp;
414a389f
PA
195
196 return bp;
611cb4a5
DJ
197}
198
8b07ae33
PA
199static int
200delete_raw_breakpoint (struct process_info *proc, struct raw_breakpoint *todel)
201{
202 struct raw_breakpoint *bp, **bp_link;
203 int ret;
204
205 bp = proc->raw_breakpoints;
206 bp_link = &proc->raw_breakpoints;
207
208 while (bp)
209 {
210 if (bp == todel)
211 {
212 if (bp->inserted)
213 {
214 struct raw_breakpoint *prev_bp_link = *bp_link;
215
216 *bp_link = bp->next;
217
218 ret = (*the_target->write_memory) (bp->pc, bp->old_data,
219 breakpoint_len);
220 if (ret != 0)
221 {
222 /* Something went wrong, relink the breakpoint. */
223 *bp_link = prev_bp_link;
224
225 if (debug_threads)
226 fprintf (stderr,
227 "Failed to uninsert raw breakpoint "
228 "at 0x%s (%s) while deleting it.\n",
229 paddress (bp->pc), strerror (ret));
230 return ret;
231 }
232
233 }
234 else
235 *bp_link = bp->next;
236
237 free (bp);
238 return 0;
239 }
240 else
241 {
242 bp_link = &bp->next;
243 bp = *bp_link;
244 }
245 }
246
247 warning ("Could not find raw breakpoint in list.");
248 return ENOENT;
249}
250
251static int
252release_breakpoint (struct process_info *proc, struct breakpoint *bp)
253{
254 int newrefcount;
255 int ret;
256
257 newrefcount = bp->raw->refcount - 1;
258 if (newrefcount == 0)
259 {
260 ret = delete_raw_breakpoint (proc, bp->raw);
261 if (ret != 0)
262 return ret;
263 }
264 else
265 bp->raw->refcount = newrefcount;
266
267 free (bp);
268
269 return 0;
270}
271
272static int
273delete_breakpoint_1 (struct process_info *proc, struct breakpoint *todel)
611cb4a5 274{
414a389f 275 struct breakpoint *bp, **bp_link;
8b07ae33 276 int err;
611cb4a5 277
414a389f
PA
278 bp = proc->breakpoints;
279 bp_link = &proc->breakpoints;
280
281 while (bp)
611cb4a5 282 {
414a389f 283 if (bp == todel)
611cb4a5 284 {
414a389f
PA
285 *bp_link = bp->next;
286
8b07ae33
PA
287 err = release_breakpoint (proc, bp);
288 if (err != 0)
289 return err;
290
291 bp = *bp_link;
292 return 0;
611cb4a5 293 }
414a389f
PA
294 else
295 {
296 bp_link = &bp->next;
297 bp = *bp_link;
298 }
611cb4a5 299 }
414a389f 300
611cb4a5 301 warning ("Could not find breakpoint in list.");
8b07ae33
PA
302 return ENOENT;
303}
304
219f2f23 305int
8b07ae33
PA
306delete_breakpoint (struct breakpoint *todel)
307{
308 struct process_info *proc = current_process ();
309 return delete_breakpoint_1 (proc, todel);
611cb4a5
DJ
310}
311
312static struct breakpoint *
8b07ae33 313find_gdb_breakpoint_at (CORE_ADDR where)
611cb4a5 314{
95954743 315 struct process_info *proc = current_process ();
8b07ae33 316 struct breakpoint *bp;
611cb4a5 317
8b07ae33
PA
318 for (bp = proc->breakpoints; bp != NULL; bp = bp->next)
319 if (bp->type == gdb_breakpoint && bp->raw->pc == where)
320 return bp;
611cb4a5
DJ
321
322 return NULL;
323}
324
8b07ae33
PA
325int
326set_gdb_breakpoint_at (CORE_ADDR where)
68070c10 327{
8b07ae33
PA
328 struct breakpoint *bp;
329
330 if (breakpoint_data == NULL)
331 return 1;
332
d3bbe7a0
PA
333 /* If we see GDB inserting a second breakpoint at the same address,
334 then the first breakpoint must have disappeared due to a shared
335 library unload. On targets where the shared libraries are
336 handled by userspace, like SVR4, for example, GDBserver can't
337 tell if a library was loaded or unloaded. Since we refcount
338 breakpoints, if we didn't do this, we'd just increase the
339 refcount of the previous breakpoint at this address, but the trap
340 was not planted in the inferior anymore, thus the breakpoint
341 would never be hit. */
342 bp = find_gdb_breakpoint_at (where);
343 if (bp != NULL)
344 {
345 delete_gdb_breakpoint_at (where);
346
347 /* Might as well validate all other breakpoints. */
348 validate_breakpoints ();
349 }
350
8b07ae33
PA
351 bp = set_breakpoint_at (where, NULL);
352 if (bp == NULL)
353 return -1;
354
355 bp->type = gdb_breakpoint;
356 return 0;
357}
358
359int
360delete_gdb_breakpoint_at (CORE_ADDR addr)
361{
362 struct breakpoint *bp;
363 int err;
364
365 if (breakpoint_data == NULL)
366 return 1;
367
368 bp = find_gdb_breakpoint_at (addr);
369 if (bp == NULL)
370 return -1;
371
372 err = delete_breakpoint (bp);
373 if (err)
374 return -1;
375
376 return 0;
377}
378
379int
380gdb_breakpoint_here (CORE_ADDR where)
381{
382 struct breakpoint *bp = find_gdb_breakpoint_at (where);
383
384 return (bp != NULL);
68070c10
PA
385}
386
d50171e4
PA
387void
388set_reinsert_breakpoint (CORE_ADDR stop_at)
611cb4a5 389{
414a389f
PA
390 struct breakpoint *bp;
391
392 bp = set_breakpoint_at (stop_at, NULL);
414a389f 393 bp->type = reinsert_breakpoint;
611cb4a5
DJ
394}
395
396void
d50171e4 397delete_reinsert_breakpoints (void)
611cb4a5 398{
d50171e4
PA
399 struct process_info *proc = current_process ();
400 struct breakpoint *bp, **bp_link;
611cb4a5 401
d50171e4
PA
402 bp = proc->breakpoints;
403 bp_link = &proc->breakpoints;
611cb4a5 404
d50171e4
PA
405 while (bp)
406 {
414a389f
PA
407 if (bp->type == reinsert_breakpoint)
408 {
409 *bp_link = bp->next;
8b07ae33 410 release_breakpoint (proc, bp);
414a389f
PA
411 bp = *bp_link;
412 }
413 else
414 {
415 bp_link = &bp->next;
416 bp = *bp_link;
417 }
d50171e4
PA
418 }
419}
b65d95c5 420
d50171e4 421static void
8b07ae33 422uninsert_raw_breakpoint (struct raw_breakpoint *bp)
d50171e4
PA
423{
424 if (bp->inserted)
425 {
426 int err;
427
428 bp->inserted = 0;
429 err = (*the_target->write_memory) (bp->pc, bp->old_data,
430 breakpoint_len);
431 if (err != 0)
432 {
433 bp->inserted = 1;
611cb4a5 434
d50171e4
PA
435 if (debug_threads)
436 fprintf (stderr,
437 "Failed to uninsert raw breakpoint at 0x%s (%s).\n",
438 paddress (bp->pc), strerror (err));
439 }
440 }
611cb4a5
DJ
441}
442
443void
d50171e4 444uninsert_breakpoints_at (CORE_ADDR pc)
611cb4a5 445{
8b07ae33 446 struct raw_breakpoint *bp;
611cb4a5 447
8b07ae33 448 bp = find_raw_breakpoint_at (pc);
611cb4a5 449 if (bp == NULL)
d50171e4
PA
450 {
451 /* This can happen when we remove all breakpoints while handling
452 a step-over. */
453 if (debug_threads)
454 fprintf (stderr,
455 "Could not find breakpoint at 0x%s "
456 "in list (uninserting).\n",
457 paddress (pc));
458 return;
459 }
611cb4a5 460
d50171e4 461 if (bp->inserted)
8b07ae33 462 uninsert_raw_breakpoint (bp);
611cb4a5
DJ
463}
464
d50171e4 465static void
8b07ae33 466reinsert_raw_breakpoint (struct raw_breakpoint *bp)
611cb4a5 467{
d50171e4 468 int err;
611cb4a5 469
d50171e4 470 if (bp->inserted)
611cb4a5
DJ
471 error ("Breakpoint already inserted at reinsert time.");
472
d50171e4
PA
473 err = (*the_target->write_memory) (bp->pc, breakpoint_data,
474 breakpoint_len);
475 if (err == 0)
476 bp->inserted = 1;
477 else if (debug_threads)
478 fprintf (stderr,
479 "Failed to reinsert breakpoint at 0x%s (%s).\n",
480 paddress (bp->pc), strerror (err));
611cb4a5
DJ
481}
482
d50171e4
PA
483void
484reinsert_breakpoints_at (CORE_ADDR pc)
611cb4a5 485{
8b07ae33 486 struct raw_breakpoint *bp;
611cb4a5 487
8b07ae33 488 bp = find_raw_breakpoint_at (pc);
611cb4a5 489 if (bp == NULL)
611cb4a5 490 {
d50171e4
PA
491 /* This can happen when we remove all breakpoints while handling
492 a step-over. */
493 if (debug_threads)
494 fprintf (stderr,
8b07ae33 495 "Could not find raw breakpoint at 0x%s "
d50171e4
PA
496 "in list (reinserting).\n",
497 paddress (pc));
498 return;
611cb4a5
DJ
499 }
500
414a389f 501 reinsert_raw_breakpoint (bp);
d50171e4
PA
502}
503
504void
505check_breakpoints (CORE_ADDR stop_pc)
506{
507 struct process_info *proc = current_process ();
508 struct breakpoint *bp, **bp_link;
509
510 bp = proc->breakpoints;
511 bp_link = &proc->breakpoints;
512
513 while (bp)
b65d95c5 514 {
8b07ae33 515 if (bp->raw->pc == stop_pc)
d50171e4 516 {
8b07ae33 517 if (!bp->raw->inserted)
d50171e4
PA
518 {
519 warning ("Hit a removed breakpoint?");
520 return;
521 }
522
523 if (bp->handler != NULL && (*bp->handler) (stop_pc))
524 {
525 *bp_link = bp->next;
526
8b07ae33 527 release_breakpoint (proc, bp);
d50171e4
PA
528
529 bp = *bp_link;
530 continue;
531 }
532 }
533
534 bp_link = &bp->next;
535 bp = *bp_link;
b65d95c5 536 }
611cb4a5
DJ
537}
538
539void
f450004a 540set_breakpoint_data (const unsigned char *bp_data, int bp_len)
611cb4a5
DJ
541{
542 breakpoint_data = bp_data;
543 breakpoint_len = bp_len;
544}
545
d50171e4
PA
546int
547breakpoint_here (CORE_ADDR addr)
548{
8b07ae33 549 return (find_raw_breakpoint_at (addr) != NULL);
d50171e4
PA
550}
551
552int
553breakpoint_inserted_here (CORE_ADDR addr)
554{
8b07ae33 555 struct raw_breakpoint *bp;
d50171e4 556
8b07ae33 557 bp = find_raw_breakpoint_at (addr);
d50171e4 558
8b07ae33 559 return (bp != NULL && bp->inserted);
d50171e4
PA
560}
561
d3bbe7a0
PA
562static int
563validate_inserted_breakpoint (struct raw_breakpoint *bp)
564{
565 unsigned char *buf;
566 int err;
567
568 gdb_assert (bp->inserted);
569
570 buf = alloca (breakpoint_len);
571 err = (*the_target->read_memory) (bp->pc, buf, breakpoint_len);
572 if (err || memcmp (buf, breakpoint_data, breakpoint_len) != 0)
573 {
574 /* Tag it as gone. */
575 bp->inserted = 0;
576 bp->shlib_disabled = 1;
577 return 0;
578 }
579
580 return 1;
581}
582
583static void
584delete_disabled_breakpoints (void)
585{
586 struct process_info *proc = current_process ();
587 struct breakpoint *bp, *next;
588
589 for (bp = proc->breakpoints; bp != NULL; bp = next)
590 {
591 next = bp->next;
592 if (bp->raw->shlib_disabled)
593 delete_breakpoint_1 (proc, bp);
594 }
595}
596
597/* Check if breakpoints we inserted still appear to be inserted. They
598 may disappear due to a shared library unload, and worse, a new
599 shared library may be reloaded at the same address as the
600 previously unloaded one. If that happens, we should make sure that
601 the shadow memory of the old breakpoints isn't used when reading or
602 writing memory. */
603
604void
605validate_breakpoints (void)
606{
607 struct process_info *proc = current_process ();
608 struct breakpoint *bp;
609
610 for (bp = proc->breakpoints; bp != NULL; bp = bp->next)
611 {
612 if (bp->raw->inserted)
613 validate_inserted_breakpoint (bp->raw);
614 }
615
616 delete_disabled_breakpoints ();
617}
618
611cb4a5 619void
f450004a 620check_mem_read (CORE_ADDR mem_addr, unsigned char *buf, int mem_len)
611cb4a5 621{
95954743 622 struct process_info *proc = current_process ();
8b07ae33 623 struct raw_breakpoint *bp = proc->raw_breakpoints;
611cb4a5 624 CORE_ADDR mem_end = mem_addr + mem_len;
d3bbe7a0 625 int disabled_one = 0;
611cb4a5
DJ
626
627 for (; bp != NULL; bp = bp->next)
628 {
629 CORE_ADDR bp_end = bp->pc + breakpoint_len;
630 CORE_ADDR start, end;
631 int copy_offset, copy_len, buf_offset;
632
633 if (mem_addr >= bp_end)
634 continue;
635 if (bp->pc >= mem_end)
636 continue;
637
638 start = bp->pc;
639 if (mem_addr > start)
640 start = mem_addr;
641
642 end = bp_end;
643 if (end > mem_end)
644 end = mem_end;
645
646 copy_len = end - start;
647 copy_offset = start - bp->pc;
648 buf_offset = start - mem_addr;
649
8b07ae33 650 if (bp->inserted)
d3bbe7a0
PA
651 {
652 if (validate_inserted_breakpoint (bp))
653 memcpy (buf + buf_offset, bp->old_data + copy_offset, copy_len);
654 else
655 disabled_one = 1;
656 }
611cb4a5 657 }
d3bbe7a0
PA
658
659 if (disabled_one)
660 delete_disabled_breakpoints ();
611cb4a5
DJ
661}
662
663void
f450004a 664check_mem_write (CORE_ADDR mem_addr, unsigned char *buf, int mem_len)
611cb4a5 665{
95954743 666 struct process_info *proc = current_process ();
8b07ae33 667 struct raw_breakpoint *bp = proc->raw_breakpoints;
611cb4a5 668 CORE_ADDR mem_end = mem_addr + mem_len;
d3bbe7a0 669 int disabled_one = 0;
611cb4a5
DJ
670
671 for (; bp != NULL; bp = bp->next)
672 {
673 CORE_ADDR bp_end = bp->pc + breakpoint_len;
674 CORE_ADDR start, end;
675 int copy_offset, copy_len, buf_offset;
676
677 if (mem_addr >= bp_end)
678 continue;
679 if (bp->pc >= mem_end)
680 continue;
681
682 start = bp->pc;
683 if (mem_addr > start)
684 start = mem_addr;
685
686 end = bp_end;
687 if (end > mem_end)
688 end = mem_end;
689
690 copy_len = end - start;
691 copy_offset = start - bp->pc;
692 buf_offset = start - mem_addr;
693
694 memcpy (bp->old_data + copy_offset, buf + buf_offset, copy_len);
d50171e4 695 if (bp->inserted)
d3bbe7a0
PA
696 {
697 if (validate_inserted_breakpoint (bp))
698 memcpy (buf + buf_offset, breakpoint_data + copy_offset, copy_len);
699 else
700 disabled_one = 1;
701 }
611cb4a5 702 }
d3bbe7a0
PA
703
704 if (disabled_one)
705 delete_disabled_breakpoints ();
611cb4a5 706}
ae13219e 707
95954743 708/* Delete all breakpoints, and un-insert them from the inferior. */
ae13219e
DJ
709
710void
711delete_all_breakpoints (void)
712{
95954743
PA
713 struct process_info *proc = current_process ();
714
715 while (proc->breakpoints)
8b07ae33 716 delete_breakpoint_1 (proc, proc->breakpoints);
95954743
PA
717}
718
f9e39928 719/* Clear the "inserted" flag in all breakpoints. */
95954743
PA
720
721void
f9e39928 722mark_breakpoints_out (struct process_info *proc)
95954743 723{
8b07ae33 724 struct raw_breakpoint *raw_bp;
95954743 725
8b07ae33
PA
726 for (raw_bp = proc->raw_breakpoints; raw_bp != NULL; raw_bp = raw_bp->next)
727 raw_bp->inserted = 0;
f9e39928
PA
728}
729
730/* Release all breakpoints, but do not try to un-insert them from the
731 inferior. */
732
733void
734free_all_breakpoints (struct process_info *proc)
735{
736 mark_breakpoints_out (proc);
8b07ae33
PA
737
738 /* Note: use PROC explicitly instead of deferring to
739 delete_all_breakpoints --- CURRENT_INFERIOR may already have been
740 released when we get here. There should be no call to
741 current_process from here on. */
95954743 742 while (proc->breakpoints)
8b07ae33 743 delete_breakpoint_1 (proc, proc->breakpoints);
ae13219e 744}
This page took 0.614669 seconds and 4 git commands to generate.