1
2
3
4
5
6
7
8
9
10
11
12#include <linux/module.h>
13#include <linux/types.h>
14#include <linux/ctype.h>
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/kdev_t.h>
18#include <linux/console.h>
19#include <linux/string.h>
20#include <linux/sched.h>
21#include <linux/smp.h>
22#include <linux/nmi.h>
23#include <linux/delay.h>
24#include <linux/kgdb.h>
25#include <linux/kdb.h>
26#include <linux/kallsyms.h>
27#include "kdb_private.h"
28
29#define CMD_BUFLEN 256
30char kdb_prompt_str[CMD_BUFLEN];
31
32int kdb_trap_printk;
33
34static int kgdb_transition_check(char *buffer)
35{
36 if (buffer[0] != '+' && buffer[0] != '$') {
37 KDB_STATE_SET(KGDB_TRANS);
38 kdb_printf("%s", buffer);
39 } else {
40 int slen = strlen(buffer);
41 if (slen > 3 && buffer[slen - 3] == '#') {
42 kdb_gdb_state_pass(buffer);
43 strcpy(buffer, "kgdb");
44 KDB_STATE_SET(DOING_KGDB);
45 return 1;
46 }
47 }
48 return 0;
49}
50
51static int kdb_read_get_key(char *buffer, size_t bufsize)
52{
53#define ESCAPE_UDELAY 1000
54#define ESCAPE_DELAY (2*1000000/ESCAPE_UDELAY)
55 char escape_data[5];
56 char *ped = escape_data;
57 int escape_delay = 0;
58 get_char_func *f, *f_escape = NULL;
59 int key;
60
61 for (f = &kdb_poll_funcs[0]; ; ++f) {
62 if (*f == NULL) {
63
64 touch_nmi_watchdog();
65 f = &kdb_poll_funcs[0];
66 }
67 if (escape_delay == 2) {
68 *ped = '\0';
69 ped = escape_data;
70 --escape_delay;
71 }
72 if (escape_delay == 1) {
73 key = *ped++;
74 if (!*ped)
75 --escape_delay;
76 break;
77 }
78 key = (*f)();
79 if (key == -1) {
80 if (escape_delay) {
81 udelay(ESCAPE_UDELAY);
82 --escape_delay;
83 }
84 continue;
85 }
86 if (bufsize <= 2) {
87 if (key == '\r')
88 key = '\n';
89 *buffer++ = key;
90 *buffer = '\0';
91 return -1;
92 }
93 if (escape_delay == 0 && key == '\e') {
94 escape_delay = ESCAPE_DELAY;
95 ped = escape_data;
96 f_escape = f;
97 }
98 if (escape_delay) {
99 *ped++ = key;
100 if (f_escape != f) {
101 escape_delay = 2;
102 continue;
103 }
104 if (ped - escape_data == 1) {
105
106 continue;
107 } else if (ped - escape_data == 2) {
108
109 if (key != '[')
110 escape_delay = 2;
111 continue;
112 } else if (ped - escape_data == 3) {
113
114 int mapkey = 0;
115 switch (key) {
116 case 'A':
117 mapkey = 16;
118 break;
119 case 'B':
120 mapkey = 14;
121 break;
122 case 'C':
123 mapkey = 6;
124 break;
125 case 'D':
126 mapkey = 2;
127 break;
128 case '1':
129 case '3':
130
131 case '4':
132 mapkey = -1;
133 break;
134 }
135 if (mapkey != -1) {
136 if (mapkey > 0) {
137 escape_data[0] = mapkey;
138 escape_data[1] = '\0';
139 }
140 escape_delay = 2;
141 }
142 continue;
143 } else if (ped - escape_data == 4) {
144
145 int mapkey = 0;
146 if (key == '~') {
147 switch (escape_data[2]) {
148 case '1':
149 mapkey = 1;
150 break;
151 case '3':
152 mapkey = 4;
153 break;
154 case '4':
155 mapkey = 5;
156 break;
157 }
158 }
159 if (mapkey > 0) {
160 escape_data[0] = mapkey;
161 escape_data[1] = '\0';
162 }
163 escape_delay = 2;
164 continue;
165 }
166 }
167 break;
168 }
169 return key;
170}
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203static char *kdb_read(char *buffer, size_t bufsize)
204{
205 char *cp = buffer;
206 char *bufend = buffer+bufsize-2;
207
208 char *lastchar;
209 char *p_tmp;
210 char tmp;
211 static char tmpbuffer[CMD_BUFLEN];
212 int len = strlen(buffer);
213 int len_tmp;
214 int tab = 0;
215 int count;
216 int i;
217 int diag, dtab_count;
218 int key;
219
220
221 diag = kdbgetintenv("DTABCOUNT", &dtab_count);
222 if (diag)
223 dtab_count = 30;
224
225 if (len > 0) {
226 cp += len;
227 if (*(buffer+len-1) == '\n')
228 cp--;
229 }
230
231 lastchar = cp;
232 *cp = '\0';
233 kdb_printf("%s", buffer);
234poll_again:
235 key = kdb_read_get_key(buffer, bufsize);
236 if (key == -1)
237 return buffer;
238 if (key != 9)
239 tab = 0;
240 switch (key) {
241 case 8:
242 if (cp > buffer) {
243 if (cp < lastchar) {
244 memcpy(tmpbuffer, cp, lastchar - cp);
245 memcpy(cp-1, tmpbuffer, lastchar - cp);
246 }
247 *(--lastchar) = '\0';
248 --cp;
249 kdb_printf("\b%s \r", cp);
250 tmp = *cp;
251 *cp = '\0';
252 kdb_printf(kdb_prompt_str);
253 kdb_printf("%s", buffer);
254 *cp = tmp;
255 }
256 break;
257 case 13:
258 *lastchar++ = '\n';
259 *lastchar++ = '\0';
260 if (!KDB_STATE(KGDB_TRANS)) {
261 KDB_STATE_SET(KGDB_TRANS);
262 kdb_printf("%s", buffer);
263 }
264 kdb_printf("\n");
265 return buffer;
266 case 4:
267 if (cp < lastchar) {
268 memcpy(tmpbuffer, cp+1, lastchar - cp - 1);
269 memcpy(cp, tmpbuffer, lastchar - cp - 1);
270 *(--lastchar) = '\0';
271 kdb_printf("%s \r", cp);
272 tmp = *cp;
273 *cp = '\0';
274 kdb_printf(kdb_prompt_str);
275 kdb_printf("%s", buffer);
276 *cp = tmp;
277 }
278 break;
279 case 1:
280 if (cp > buffer) {
281 kdb_printf("\r");
282 kdb_printf(kdb_prompt_str);
283 cp = buffer;
284 }
285 break;
286 case 5:
287 if (cp < lastchar) {
288 kdb_printf("%s", cp);
289 cp = lastchar;
290 }
291 break;
292 case 2:
293 if (cp > buffer) {
294 kdb_printf("\b");
295 --cp;
296 }
297 break;
298 case 14:
299 memset(tmpbuffer, ' ',
300 strlen(kdb_prompt_str) + (lastchar-buffer));
301 *(tmpbuffer+strlen(kdb_prompt_str) +
302 (lastchar-buffer)) = '\0';
303 kdb_printf("\r%s\r", tmpbuffer);
304 *lastchar = (char)key;
305 *(lastchar+1) = '\0';
306 return lastchar;
307 case 6:
308 if (cp < lastchar) {
309 kdb_printf("%c", *cp);
310 ++cp;
311 }
312 break;
313 case 16:
314 memset(tmpbuffer, ' ',
315 strlen(kdb_prompt_str) + (lastchar-buffer));
316 *(tmpbuffer+strlen(kdb_prompt_str) +
317 (lastchar-buffer)) = '\0';
318 kdb_printf("\r%s\r", tmpbuffer);
319 *lastchar = (char)key;
320 *(lastchar+1) = '\0';
321 return lastchar;
322 case 9:
323 if (tab < 2)
324 ++tab;
325 p_tmp = buffer;
326 while (*p_tmp == ' ')
327 p_tmp++;
328 if (p_tmp > cp)
329 break;
330 memcpy(tmpbuffer, p_tmp, cp-p_tmp);
331 *(tmpbuffer + (cp-p_tmp)) = '\0';
332 p_tmp = strrchr(tmpbuffer, ' ');
333 if (p_tmp)
334 ++p_tmp;
335 else
336 p_tmp = tmpbuffer;
337 len = strlen(p_tmp);
338 count = kallsyms_symbol_complete(p_tmp,
339 sizeof(tmpbuffer) -
340 (p_tmp - tmpbuffer));
341 if (tab == 2 && count > 0) {
342 kdb_printf("\n%d symbols are found.", count);
343 if (count > dtab_count) {
344 count = dtab_count;
345 kdb_printf(" But only first %d symbols will"
346 " be printed.\nYou can change the"
347 " environment variable DTABCOUNT.",
348 count);
349 }
350 kdb_printf("\n");
351 for (i = 0; i < count; i++) {
352 if (kallsyms_symbol_next(p_tmp, i) < 0)
353 break;
354 kdb_printf("%s ", p_tmp);
355 *(p_tmp + len) = '\0';
356 }
357 if (i >= dtab_count)
358 kdb_printf("...");
359 kdb_printf("\n");
360 kdb_printf(kdb_prompt_str);
361 kdb_printf("%s", buffer);
362 } else if (tab != 2 && count > 0) {
363 len_tmp = strlen(p_tmp);
364 strncpy(p_tmp+len_tmp, cp, lastchar-cp+1);
365 len_tmp = strlen(p_tmp);
366 strncpy(cp, p_tmp+len, len_tmp-len + 1);
367 len = len_tmp - len;
368 kdb_printf("%s", cp);
369 cp += len;
370 lastchar += len;
371 }
372 kdb_nextline = 1;
373 break;
374 default:
375 if (key >= 32 && lastchar < bufend) {
376 if (cp < lastchar) {
377 memcpy(tmpbuffer, cp, lastchar - cp);
378 memcpy(cp+1, tmpbuffer, lastchar - cp);
379 *++lastchar = '\0';
380 *cp = key;
381 kdb_printf("%s\r", cp);
382 ++cp;
383 tmp = *cp;
384 *cp = '\0';
385 kdb_printf(kdb_prompt_str);
386 kdb_printf("%s", buffer);
387 *cp = tmp;
388 } else {
389 *++lastchar = '\0';
390 *cp++ = key;
391
392
393
394
395 if (!KDB_STATE(KGDB_TRANS)) {
396 if (kgdb_transition_check(buffer))
397 return buffer;
398 } else {
399 kdb_printf("%c", key);
400 }
401 }
402
403 if (lastchar - buffer >= 5 &&
404 strcmp(lastchar - 5, "$?#3f") == 0) {
405 kdb_gdb_state_pass(lastchar - 5);
406 strcpy(buffer, "kgdb");
407 KDB_STATE_SET(DOING_KGDB);
408 return buffer;
409 }
410 if (lastchar - buffer >= 11 &&
411 strcmp(lastchar - 11, "$qSupported") == 0) {
412 kdb_gdb_state_pass(lastchar - 11);
413 strcpy(buffer, "kgdb");
414 KDB_STATE_SET(DOING_KGDB);
415 return buffer;
416 }
417 }
418 break;
419 }
420 goto poll_again;
421}
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442char *kdb_getstr(char *buffer, size_t bufsize, char *prompt)
443{
444 if (prompt && kdb_prompt_str != prompt)
445 strncpy(kdb_prompt_str, prompt, CMD_BUFLEN);
446 kdb_printf(kdb_prompt_str);
447 kdb_nextline = 1;
448 return kdb_read(buffer, bufsize);
449}
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468static void kdb_input_flush(void)
469{
470 get_char_func *f;
471 int res;
472 int flush_delay = 1;
473 while (flush_delay) {
474 flush_delay--;
475empty:
476 touch_nmi_watchdog();
477 for (f = &kdb_poll_funcs[0]; *f; ++f) {
478 res = (*f)();
479 if (res != -1) {
480 flush_delay = 1;
481 goto empty;
482 }
483 }
484 if (flush_delay)
485 mdelay(1);
486 }
487}
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510static char kdb_buffer[256];
511static char *next_avail = kdb_buffer;
512static int size_avail;
513static int suspend_grep;
514
515
516
517
518
519
520
521static int kdb_search_string(char *searched, char *searchfor)
522{
523 char firstchar, *cp;
524 int len1, len2;
525
526
527 len1 = strlen(searched)-1;
528 len2 = strlen(searchfor);
529 if (len1 < len2)
530 return 0;
531 if (kdb_grep_leading && kdb_grep_trailing && len1 != len2)
532 return 0;
533 if (kdb_grep_leading) {
534 if (!strncmp(searched, searchfor, len2))
535 return 1;
536 } else if (kdb_grep_trailing) {
537 if (!strncmp(searched+len1-len2, searchfor, len2))
538 return 1;
539 } else {
540 firstchar = *searchfor;
541 cp = searched;
542 while ((cp = strchr(cp, firstchar))) {
543 if (!strncmp(cp, searchfor, len2))
544 return 1;
545 cp++;
546 }
547 }
548 return 0;
549}
550
551int vkdb_printf(const char *fmt, va_list ap)
552{
553 int diag;
554 int linecount;
555 int colcount;
556 int logging, saved_loglevel = 0;
557 int saved_trap_printk;
558 int got_printf_lock = 0;
559 int retlen = 0;
560 int fnd, len;
561 char *cp, *cp2, *cphold = NULL, replaced_byte = ' ';
562 char *moreprompt = "more> ";
563 struct console *c = console_drivers;
564 static DEFINE_SPINLOCK(kdb_printf_lock);
565 unsigned long uninitialized_var(flags);
566
567 preempt_disable();
568 saved_trap_printk = kdb_trap_printk;
569 kdb_trap_printk = 0;
570
571
572
573
574
575 if (!KDB_STATE(PRINTF_LOCK)) {
576 KDB_STATE_SET(PRINTF_LOCK);
577 spin_lock_irqsave(&kdb_printf_lock, flags);
578 got_printf_lock = 1;
579 atomic_inc(&kdb_event);
580 } else {
581 __acquire(kdb_printf_lock);
582 }
583
584 diag = kdbgetintenv("LINES", &linecount);
585 if (diag || linecount <= 1)
586 linecount = 24;
587
588 diag = kdbgetintenv("COLUMNS", &colcount);
589 if (diag || colcount <= 1)
590 colcount = 80;
591
592 diag = kdbgetintenv("LOGGING", &logging);
593 if (diag)
594 logging = 0;
595
596 if (!kdb_grepping_flag || suspend_grep) {
597
598 next_avail = kdb_buffer;
599 size_avail = sizeof(kdb_buffer);
600 }
601 vsnprintf(next_avail, size_avail, fmt, ap);
602
603
604
605
606
607
608
609
610
611
612 if (!suspend_grep && kdb_grepping_flag) {
613 cp = strchr(kdb_buffer, '\n');
614 if (!cp) {
615
616
617
618
619
620
621
622
623
624
625
626
627
628 if (next_avail == kdb_buffer) {
629
630
631
632
633
634 cp2 = kdb_buffer;
635 len = strlen(kdb_prompt_str);
636 if (!strncmp(cp2, kdb_prompt_str, len)) {
637
638
639
640
641
642 kdb_grepping_flag = 0;
643 goto kdb_printit;
644 }
645 }
646
647
648 len = strlen(kdb_buffer);
649 next_avail = kdb_buffer + len;
650 size_avail = sizeof(kdb_buffer) - len;
651 goto kdb_print_out;
652 }
653
654
655
656
657
658 cp++;
659 replaced_byte = *cp;
660 cphold = cp;
661 *cp = '\0';
662
663
664
665
666
667
668 fnd = kdb_search_string(kdb_buffer, kdb_grep_string);
669 if (!fnd) {
670
671
672
673
674
675
676 *cphold = replaced_byte;
677 strcpy(kdb_buffer, cphold);
678 len = strlen(kdb_buffer);
679 next_avail = kdb_buffer + len;
680 size_avail = sizeof(kdb_buffer) - len;
681 goto kdb_print_out;
682 }
683
684
685
686
687 }
688kdb_printit:
689
690
691
692
693 retlen = strlen(kdb_buffer);
694 if (!dbg_kdb_mode && kgdb_connected) {
695 gdbstub_msg_write(kdb_buffer, retlen);
696 } else {
697 if (dbg_io_ops && !dbg_io_ops->is_console) {
698 len = retlen;
699 cp = kdb_buffer;
700 while (len--) {
701 dbg_io_ops->write_char(*cp);
702 cp++;
703 }
704 }
705 while (c) {
706 c->write(c, kdb_buffer, retlen);
707 touch_nmi_watchdog();
708 c = c->next;
709 }
710 }
711 if (logging) {
712 saved_loglevel = console_loglevel;
713 console_loglevel = 0;
714 printk(KERN_INFO "%s", kdb_buffer);
715 }
716
717 if (KDB_STATE(PAGER)) {
718
719
720
721
722
723 int got = 0;
724 len = retlen;
725 while (len--) {
726 if (kdb_buffer[len] == '\n') {
727 kdb_nextline++;
728 got = 0;
729 } else if (kdb_buffer[len] == '\r') {
730 got = 0;
731 } else {
732 got++;
733 }
734 }
735 kdb_nextline += got / (colcount + 1);
736 }
737
738
739 if (kdb_nextline >= linecount) {
740 char buf1[16] = "";
741
742
743
744
745
746 kdb_nextline = 1;
747
748
749
750
751 moreprompt = kdbgetenv("MOREPROMPT");
752 if (moreprompt == NULL)
753 moreprompt = "more> ";
754
755 kdb_input_flush();
756 c = console_drivers;
757
758 if (dbg_io_ops && !dbg_io_ops->is_console) {
759 len = strlen(moreprompt);
760 cp = moreprompt;
761 while (len--) {
762 dbg_io_ops->write_char(*cp);
763 cp++;
764 }
765 }
766 while (c) {
767 c->write(c, moreprompt, strlen(moreprompt));
768 touch_nmi_watchdog();
769 c = c->next;
770 }
771
772 if (logging)
773 printk("%s", moreprompt);
774
775 kdb_read(buf1, 2);
776
777 kdb_nextline = 1;
778
779
780 kdb_buffer[0] = '\0';
781 next_avail = kdb_buffer;
782 size_avail = sizeof(kdb_buffer);
783 if ((buf1[0] == 'q') || (buf1[0] == 'Q')) {
784
785 KDB_FLAG_SET(CMD_INTERRUPT);
786 KDB_STATE_CLEAR(PAGER);
787
788 kdb_grepping_flag = 0;
789 kdb_printf("\n");
790 } else if (buf1[0] == ' ') {
791 kdb_printf("\r");
792 suspend_grep = 1;
793 } else if (buf1[0] == '\n') {
794 kdb_nextline = linecount - 1;
795 kdb_printf("\r");
796 suspend_grep = 1;
797 } else if (buf1[0] && buf1[0] != '\n') {
798
799 suspend_grep = 1;
800 kdb_printf("\nOnly 'q' or 'Q' are processed at more "
801 "prompt, input ignored\n");
802 } else if (kdb_grepping_flag) {
803
804 suspend_grep = 1;
805 kdb_printf("\n");
806 }
807 kdb_input_flush();
808 }
809
810
811
812
813
814
815
816 if (kdb_grepping_flag && !suspend_grep) {
817 *cphold = replaced_byte;
818 strcpy(kdb_buffer, cphold);
819 len = strlen(kdb_buffer);
820 next_avail = kdb_buffer + len;
821 size_avail = sizeof(kdb_buffer) - len;
822 }
823
824kdb_print_out:
825 suspend_grep = 0;
826 if (logging)
827 console_loglevel = saved_loglevel;
828 if (KDB_STATE(PRINTF_LOCK) && got_printf_lock) {
829 got_printf_lock = 0;
830 spin_unlock_irqrestore(&kdb_printf_lock, flags);
831 KDB_STATE_CLEAR(PRINTF_LOCK);
832 atomic_dec(&kdb_event);
833 } else {
834 __release(kdb_printf_lock);
835 }
836 kdb_trap_printk = saved_trap_printk;
837 preempt_enable();
838 return retlen;
839}
840
841int kdb_printf(const char *fmt, ...)
842{
843 va_list ap;
844 int r;
845
846 va_start(ap, fmt);
847 r = vkdb_printf(fmt, ap);
848 va_end(ap);
849
850 return r;
851}
852EXPORT_SYMBOL_GPL(kdb_printf);
853