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;
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 count = kallsyms_symbol_complete(p_tmp,
340 sizeof(tmpbuffer) -
341 (p_tmp - tmpbuffer));
342 if (tab == 2 && count > 0) {
343 kdb_printf("\n%d symbols are found.", count);
344 if (count > dtab_count) {
345 count = dtab_count;
346 kdb_printf(" But only first %d symbols will"
347 " be printed.\nYou can change the"
348 " environment variable DTABCOUNT.",
349 count);
350 }
351 kdb_printf("\n");
352 for (i = 0; i < count; i++) {
353 if (WARN_ON(!kallsyms_symbol_next(p_tmp, i)))
354 break;
355 kdb_printf("%s ", p_tmp);
356 *(p_tmp + len) = '\0';
357 }
358 if (i >= dtab_count)
359 kdb_printf("...");
360 kdb_printf("\n");
361 kdb_printf(kdb_prompt_str);
362 kdb_printf("%s", buffer);
363 } else if (tab != 2 && count > 0) {
364 len_tmp = strlen(p_tmp);
365 strncpy(p_tmp+len_tmp, cp, lastchar-cp+1);
366 len_tmp = strlen(p_tmp);
367 strncpy(cp, p_tmp+len, len_tmp-len + 1);
368 len = len_tmp - len;
369 kdb_printf("%s", cp);
370 cp += len;
371 lastchar += len;
372 }
373 kdb_nextline = 1;
374 break;
375 default:
376 if (key >= 32 && lastchar < bufend) {
377 if (cp < lastchar) {
378 memcpy(tmpbuffer, cp, lastchar - cp);
379 memcpy(cp+1, tmpbuffer, lastchar - cp);
380 *++lastchar = '\0';
381 *cp = key;
382 kdb_printf("%s\r", cp);
383 ++cp;
384 tmp = *cp;
385 *cp = '\0';
386 kdb_printf(kdb_prompt_str);
387 kdb_printf("%s", buffer);
388 *cp = tmp;
389 } else {
390 *++lastchar = '\0';
391 *cp++ = key;
392
393
394
395
396 if (!KDB_STATE(KGDB_TRANS)) {
397 if (kgdb_transition_check(buffer))
398 return buffer;
399 } else {
400 kdb_printf("%c", key);
401 }
402 }
403
404 if (lastchar - buffer >= 5 &&
405 strcmp(lastchar - 5, "$?#3f") == 0) {
406 kdb_gdb_state_pass(lastchar - 5);
407 strcpy(buffer, "kgdb");
408 KDB_STATE_SET(DOING_KGDB);
409 return buffer;
410 }
411 if (lastchar - buffer >= 11 &&
412 strcmp(lastchar - 11, "$qSupported") == 0) {
413 kdb_gdb_state_pass(lastchar - 11);
414 strcpy(buffer, "kgdb");
415 KDB_STATE_SET(DOING_KGDB);
416 return buffer;
417 }
418 }
419 break;
420 }
421 goto poll_again;
422}
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443char *kdb_getstr(char *buffer, size_t bufsize, const char *prompt)
444{
445 if (prompt && kdb_prompt_str != prompt)
446 strncpy(kdb_prompt_str, prompt, CMD_BUFLEN);
447 kdb_printf(kdb_prompt_str);
448 kdb_nextline = 1;
449 return kdb_read(buffer, bufsize);
450}
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469static void kdb_input_flush(void)
470{
471 get_char_func *f;
472 int res;
473 int flush_delay = 1;
474 while (flush_delay) {
475 flush_delay--;
476empty:
477 touch_nmi_watchdog();
478 for (f = &kdb_poll_funcs[0]; *f; ++f) {
479 res = (*f)();
480 if (res != -1) {
481 flush_delay = 1;
482 goto empty;
483 }
484 }
485 if (flush_delay)
486 mdelay(1);
487 }
488}
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511static char kdb_buffer[256];
512static char *next_avail = kdb_buffer;
513static int size_avail;
514static int suspend_grep;
515
516
517
518
519
520
521
522static int kdb_search_string(char *searched, char *searchfor)
523{
524 char firstchar, *cp;
525 int len1, len2;
526
527
528 len1 = strlen(searched)-1;
529 len2 = strlen(searchfor);
530 if (len1 < len2)
531 return 0;
532 if (kdb_grep_leading && kdb_grep_trailing && len1 != len2)
533 return 0;
534 if (kdb_grep_leading) {
535 if (!strncmp(searched, searchfor, len2))
536 return 1;
537 } else if (kdb_grep_trailing) {
538 if (!strncmp(searched+len1-len2, searchfor, len2))
539 return 1;
540 } else {
541 firstchar = *searchfor;
542 cp = searched;
543 while ((cp = strchr(cp, firstchar))) {
544 if (!strncmp(cp, searchfor, len2))
545 return 1;
546 cp++;
547 }
548 }
549 return 0;
550}
551
552int vkdb_printf(enum kdb_msgsrc src, const char *fmt, va_list ap)
553{
554 int diag;
555 int linecount;
556 int colcount;
557 int logging, saved_loglevel = 0;
558 int retlen = 0;
559 int fnd, len;
560 int this_cpu, old_cpu;
561 char *cp, *cp2, *cphold = NULL, replaced_byte = ' ';
562 char *moreprompt = "more> ";
563 struct console *c = console_drivers;
564 unsigned long uninitialized_var(flags);
565
566
567
568
569
570 local_irq_save(flags);
571 this_cpu = smp_processor_id();
572 for (;;) {
573 old_cpu = cmpxchg(&kdb_printf_cpu, -1, this_cpu);
574 if (old_cpu == -1 || old_cpu == this_cpu)
575 break;
576
577 cpu_relax();
578 }
579
580 diag = kdbgetintenv("LINES", &linecount);
581 if (diag || linecount <= 1)
582 linecount = 24;
583
584 diag = kdbgetintenv("COLUMNS", &colcount);
585 if (diag || colcount <= 1)
586 colcount = 80;
587
588 diag = kdbgetintenv("LOGGING", &logging);
589 if (diag)
590 logging = 0;
591
592 if (!kdb_grepping_flag || suspend_grep) {
593
594 next_avail = kdb_buffer;
595 size_avail = sizeof(kdb_buffer);
596 }
597 vsnprintf(next_avail, size_avail, fmt, ap);
598
599
600
601
602
603
604
605
606
607
608 if (!suspend_grep && kdb_grepping_flag) {
609 cp = strchr(kdb_buffer, '\n');
610 if (!cp) {
611
612
613
614
615
616
617
618
619
620
621
622
623
624 if (next_avail == kdb_buffer) {
625
626
627
628
629
630 cp2 = kdb_buffer;
631 len = strlen(kdb_prompt_str);
632 if (!strncmp(cp2, kdb_prompt_str, len)) {
633
634
635
636
637
638 kdb_grepping_flag = 0;
639 goto kdb_printit;
640 }
641 }
642
643
644 len = strlen(kdb_buffer);
645 next_avail = kdb_buffer + len;
646 size_avail = sizeof(kdb_buffer) - len;
647 goto kdb_print_out;
648 }
649
650
651
652
653
654 cp++;
655 replaced_byte = *cp;
656 cphold = cp;
657 *cp = '\0';
658
659
660
661
662
663
664 fnd = kdb_search_string(kdb_buffer, kdb_grep_string);
665 if (!fnd) {
666
667
668
669
670
671
672 *cphold = replaced_byte;
673 strcpy(kdb_buffer, cphold);
674 len = strlen(kdb_buffer);
675 next_avail = kdb_buffer + len;
676 size_avail = sizeof(kdb_buffer) - len;
677 goto kdb_print_out;
678 }
679 if (kdb_grepping_flag >= KDB_GREPPING_FLAG_SEARCH)
680
681
682
683
684 kdb_grepping_flag = 0;
685
686
687
688
689 }
690kdb_printit:
691
692
693
694
695 retlen = strlen(kdb_buffer);
696 cp = (char *) printk_skip_headers(kdb_buffer);
697 if (!dbg_kdb_mode && kgdb_connected) {
698 gdbstub_msg_write(cp, retlen - (cp - kdb_buffer));
699 } else {
700 if (dbg_io_ops && !dbg_io_ops->is_console) {
701 len = retlen - (cp - kdb_buffer);
702 cp2 = cp;
703 while (len--) {
704 dbg_io_ops->write_char(*cp2);
705 cp2++;
706 }
707 }
708 while (c) {
709 c->write(c, cp, retlen - (cp - kdb_buffer));
710 touch_nmi_watchdog();
711 c = c->next;
712 }
713 }
714 if (logging) {
715 saved_loglevel = console_loglevel;
716 console_loglevel = CONSOLE_LOGLEVEL_SILENT;
717 if (printk_get_level(kdb_buffer) || src == KDB_MSGSRC_PRINTK)
718 printk("%s", kdb_buffer);
719 else
720 pr_info("%s", kdb_buffer);
721 }
722
723 if (KDB_STATE(PAGER)) {
724
725
726
727
728
729 int got = 0;
730 len = retlen;
731 while (len--) {
732 if (kdb_buffer[len] == '\n') {
733 kdb_nextline++;
734 got = 0;
735 } else if (kdb_buffer[len] == '\r') {
736 got = 0;
737 } else {
738 got++;
739 }
740 }
741 kdb_nextline += got / (colcount + 1);
742 }
743
744
745 if (kdb_nextline >= linecount) {
746 char buf1[16] = "";
747
748
749
750
751
752 kdb_nextline = 1;
753
754
755
756
757 moreprompt = kdbgetenv("MOREPROMPT");
758 if (moreprompt == NULL)
759 moreprompt = "more> ";
760
761 kdb_input_flush();
762 c = console_drivers;
763
764 if (dbg_io_ops && !dbg_io_ops->is_console) {
765 len = strlen(moreprompt);
766 cp = moreprompt;
767 while (len--) {
768 dbg_io_ops->write_char(*cp);
769 cp++;
770 }
771 }
772 while (c) {
773 c->write(c, moreprompt, strlen(moreprompt));
774 touch_nmi_watchdog();
775 c = c->next;
776 }
777
778 if (logging)
779 printk("%s", moreprompt);
780
781 kdb_read(buf1, 2);
782
783 kdb_nextline = 1;
784
785
786 kdb_buffer[0] = '\0';
787 next_avail = kdb_buffer;
788 size_avail = sizeof(kdb_buffer);
789 if ((buf1[0] == 'q') || (buf1[0] == 'Q')) {
790
791 KDB_FLAG_SET(CMD_INTERRUPT);
792 KDB_STATE_CLEAR(PAGER);
793
794 kdb_grepping_flag = 0;
795 kdb_printf("\n");
796 } else if (buf1[0] == ' ') {
797 kdb_printf("\r");
798 suspend_grep = 1;
799 } else if (buf1[0] == '\n') {
800 kdb_nextline = linecount - 1;
801 kdb_printf("\r");
802 suspend_grep = 1;
803 } else if (buf1[0] == '/' && !kdb_grepping_flag) {
804 kdb_printf("\r");
805 kdb_getstr(kdb_grep_string, KDB_GREP_STRLEN,
806 kdbgetenv("SEARCHPROMPT") ?: "search> ");
807 *strchrnul(kdb_grep_string, '\n') = '\0';
808 kdb_grepping_flag += KDB_GREPPING_FLAG_SEARCH;
809 suspend_grep = 1;
810 } else if (buf1[0] && buf1[0] != '\n') {
811
812 suspend_grep = 1;
813 if (buf1[0] != '/')
814 kdb_printf(
815 "\nOnly 'q', 'Q' or '/' are processed at "
816 "more prompt, input ignored\n");
817 else
818 kdb_printf("\n'/' cannot be used during | "
819 "grep filtering, input ignored\n");
820 } else if (kdb_grepping_flag) {
821
822 suspend_grep = 1;
823 kdb_printf("\n");
824 }
825 kdb_input_flush();
826 }
827
828
829
830
831
832
833
834 if (kdb_grepping_flag && !suspend_grep) {
835 *cphold = replaced_byte;
836 strcpy(kdb_buffer, cphold);
837 len = strlen(kdb_buffer);
838 next_avail = kdb_buffer + len;
839 size_avail = sizeof(kdb_buffer) - len;
840 }
841
842kdb_print_out:
843 suspend_grep = 0;
844 if (logging)
845 console_loglevel = saved_loglevel;
846
847 smp_store_release(&kdb_printf_cpu, old_cpu);
848 local_irq_restore(flags);
849 return retlen;
850}
851
852int kdb_printf(const char *fmt, ...)
853{
854 va_list ap;
855 int r;
856
857 va_start(ap, fmt);
858 r = vkdb_printf(KDB_MSGSRC_INTERNAL, fmt, ap);
859 va_end(ap);
860
861 return r;
862}
863EXPORT_SYMBOL_GPL(kdb_printf);
864