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