.. | .. |
---|
49 | 49 | return 0; |
---|
50 | 50 | } |
---|
51 | 51 | |
---|
52 | | -static int kdb_read_get_key(char *buffer, size_t bufsize) |
---|
| 52 | +/** |
---|
| 53 | + * kdb_handle_escape() - validity check on an accumulated escape sequence. |
---|
| 54 | + * @buf: Accumulated escape characters to be examined. Note that buf |
---|
| 55 | + * is not a string, it is an array of characters and need not be |
---|
| 56 | + * nil terminated. |
---|
| 57 | + * @sz: Number of accumulated escape characters. |
---|
| 58 | + * |
---|
| 59 | + * Return: -1 if the escape sequence is unwanted, 0 if it is incomplete, |
---|
| 60 | + * otherwise it returns a mapped key value to pass to the upper layers. |
---|
| 61 | + */ |
---|
| 62 | +static int kdb_handle_escape(char *buf, size_t sz) |
---|
| 63 | +{ |
---|
| 64 | + char *lastkey = buf + sz - 1; |
---|
| 65 | + |
---|
| 66 | + switch (sz) { |
---|
| 67 | + case 1: |
---|
| 68 | + if (*lastkey == '\e') |
---|
| 69 | + return 0; |
---|
| 70 | + break; |
---|
| 71 | + |
---|
| 72 | + case 2: /* \e<something> */ |
---|
| 73 | + if (*lastkey == '[') |
---|
| 74 | + return 0; |
---|
| 75 | + break; |
---|
| 76 | + |
---|
| 77 | + case 3: |
---|
| 78 | + switch (*lastkey) { |
---|
| 79 | + case 'A': /* \e[A, up arrow */ |
---|
| 80 | + return 16; |
---|
| 81 | + case 'B': /* \e[B, down arrow */ |
---|
| 82 | + return 14; |
---|
| 83 | + case 'C': /* \e[C, right arrow */ |
---|
| 84 | + return 6; |
---|
| 85 | + case 'D': /* \e[D, left arrow */ |
---|
| 86 | + return 2; |
---|
| 87 | + case '1': /* \e[<1,3,4>], may be home, del, end */ |
---|
| 88 | + case '3': |
---|
| 89 | + case '4': |
---|
| 90 | + return 0; |
---|
| 91 | + } |
---|
| 92 | + break; |
---|
| 93 | + |
---|
| 94 | + case 4: |
---|
| 95 | + if (*lastkey == '~') { |
---|
| 96 | + switch (buf[2]) { |
---|
| 97 | + case '1': /* \e[1~, home */ |
---|
| 98 | + return 1; |
---|
| 99 | + case '3': /* \e[3~, del */ |
---|
| 100 | + return 4; |
---|
| 101 | + case '4': /* \e[4~, end */ |
---|
| 102 | + return 5; |
---|
| 103 | + } |
---|
| 104 | + } |
---|
| 105 | + break; |
---|
| 106 | + } |
---|
| 107 | + |
---|
| 108 | + return -1; |
---|
| 109 | +} |
---|
| 110 | + |
---|
| 111 | +/** |
---|
| 112 | + * kdb_getchar() - Read a single character from a kdb console (or consoles). |
---|
| 113 | + * |
---|
| 114 | + * Other than polling the various consoles that are currently enabled, |
---|
| 115 | + * most of the work done in this function is dealing with escape sequences. |
---|
| 116 | + * |
---|
| 117 | + * An escape key could be the start of a vt100 control sequence such as \e[D |
---|
| 118 | + * (left arrow) or it could be a character in its own right. The standard |
---|
| 119 | + * method for detecting the difference is to wait for 2 seconds to see if there |
---|
| 120 | + * are any other characters. kdb is complicated by the lack of a timer service |
---|
| 121 | + * (interrupts are off), by multiple input sources. Escape sequence processing |
---|
| 122 | + * has to be done as states in the polling loop. |
---|
| 123 | + * |
---|
| 124 | + * Return: The key pressed or a control code derived from an escape sequence. |
---|
| 125 | + */ |
---|
| 126 | +char kdb_getchar(void) |
---|
53 | 127 | { |
---|
54 | 128 | #define ESCAPE_UDELAY 1000 |
---|
55 | 129 | #define ESCAPE_DELAY (2*1000000/ESCAPE_UDELAY) /* 2 seconds worth of udelays */ |
---|
56 | | - char escape_data[5]; /* longest vt100 escape sequence is 4 bytes */ |
---|
57 | | - char *ped = escape_data; |
---|
| 130 | + char buf[4]; /* longest vt100 escape sequence is 4 bytes */ |
---|
| 131 | + char *pbuf = buf; |
---|
58 | 132 | int escape_delay = 0; |
---|
59 | | - get_char_func *f, *f_escape = NULL; |
---|
| 133 | + get_char_func *f, *f_prev = NULL; |
---|
60 | 134 | int key; |
---|
61 | 135 | |
---|
62 | 136 | for (f = &kdb_poll_funcs[0]; ; ++f) { |
---|
.. | .. |
---|
65 | 139 | touch_nmi_watchdog(); |
---|
66 | 140 | f = &kdb_poll_funcs[0]; |
---|
67 | 141 | } |
---|
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 | | - } |
---|
| 142 | + |
---|
79 | 143 | key = (*f)(); |
---|
80 | 144 | if (key == -1) { |
---|
81 | 145 | if (escape_delay) { |
---|
82 | 146 | udelay(ESCAPE_UDELAY); |
---|
83 | | - --escape_delay; |
---|
| 147 | + if (--escape_delay == 0) |
---|
| 148 | + return '\e'; |
---|
84 | 149 | } |
---|
85 | 150 | continue; |
---|
86 | 151 | } |
---|
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') { |
---|
| 152 | + |
---|
| 153 | + /* |
---|
| 154 | + * When the first character is received (or we get a change |
---|
| 155 | + * input source) we set ourselves up to handle an escape |
---|
| 156 | + * sequences (just in case). |
---|
| 157 | + */ |
---|
| 158 | + if (f_prev != f) { |
---|
| 159 | + f_prev = f; |
---|
| 160 | + pbuf = buf; |
---|
95 | 161 | escape_delay = ESCAPE_DELAY; |
---|
96 | | - ped = escape_data; |
---|
97 | | - f_escape = f; |
---|
98 | 162 | } |
---|
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 | | - /* \e */ |
---|
107 | | - continue; |
---|
108 | | - } else if (ped - escape_data == 2) { |
---|
109 | | - /* \e<something> */ |
---|
110 | | - if (key != '[') |
---|
111 | | - escape_delay = 2; |
---|
112 | | - continue; |
---|
113 | | - } else if (ped - escape_data == 3) { |
---|
114 | | - /* \e[<something> */ |
---|
115 | | - int mapkey = 0; |
---|
116 | | - switch (key) { |
---|
117 | | - case 'A': /* \e[A, up arrow */ |
---|
118 | | - mapkey = 16; |
---|
119 | | - break; |
---|
120 | | - case 'B': /* \e[B, down arrow */ |
---|
121 | | - mapkey = 14; |
---|
122 | | - break; |
---|
123 | | - case 'C': /* \e[C, right arrow */ |
---|
124 | | - mapkey = 6; |
---|
125 | | - break; |
---|
126 | | - case 'D': /* \e[D, left arrow */ |
---|
127 | | - mapkey = 2; |
---|
128 | | - break; |
---|
129 | | - case '1': /* dropthrough */ |
---|
130 | | - case '3': /* dropthrough */ |
---|
131 | | - /* \e[<1,3,4>], may be home, del, end */ |
---|
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 | | - /* \e[<1,3,4><something> */ |
---|
146 | | - int mapkey = 0; |
---|
147 | | - if (key == '~') { |
---|
148 | | - switch (escape_data[2]) { |
---|
149 | | - case '1': /* \e[1~, home */ |
---|
150 | | - mapkey = 1; |
---|
151 | | - break; |
---|
152 | | - case '3': /* \e[3~, del */ |
---|
153 | | - mapkey = 4; |
---|
154 | | - break; |
---|
155 | | - case '4': /* \e[4~, end */ |
---|
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; /* A key to process */ |
---|
| 163 | + |
---|
| 164 | + *pbuf++ = key; |
---|
| 165 | + key = kdb_handle_escape(buf, pbuf - buf); |
---|
| 166 | + if (key < 0) /* no escape sequence; return best character */ |
---|
| 167 | + return buf[pbuf - buf == 2 ? 1 : 0]; |
---|
| 168 | + if (key > 0) |
---|
| 169 | + return key; |
---|
169 | 170 | } |
---|
170 | | - return key; |
---|
| 171 | + |
---|
| 172 | + unreachable(); |
---|
171 | 173 | } |
---|
172 | 174 | |
---|
173 | 175 | /* |
---|
.. | .. |
---|
188 | 190 | * function. It is not reentrant - it relies on the fact |
---|
189 | 191 | * that while kdb is running on only one "master debug" cpu. |
---|
190 | 192 | * Remarks: |
---|
191 | | - * |
---|
192 | | - * The buffer size must be >= 2. A buffer size of 2 means that the caller only |
---|
193 | | - * wants a single key. |
---|
194 | | - * |
---|
195 | | - * An escape key could be the start of a vt100 control sequence such as \e[D |
---|
196 | | - * (left arrow) or it could be a character in its own right. The standard |
---|
197 | | - * method for detecting the difference is to wait for 2 seconds to see if there |
---|
198 | | - * are any other characters. kdb is complicated by the lack of a timer service |
---|
199 | | - * (interrupts are off), by multiple input sources and by the need to sometimes |
---|
200 | | - * return after just one key. Escape sequence processing has to be done as |
---|
201 | | - * states in the polling loop. |
---|
| 193 | + * The buffer size must be >= 2. |
---|
202 | 194 | */ |
---|
203 | 195 | |
---|
204 | 196 | static char *kdb_read(char *buffer, size_t bufsize) |
---|
.. | .. |
---|
233 | 225 | *cp = '\0'; |
---|
234 | 226 | kdb_printf("%s", buffer); |
---|
235 | 227 | poll_again: |
---|
236 | | - key = kdb_read_get_key(buffer, bufsize); |
---|
237 | | - if (key == -1) |
---|
238 | | - return buffer; |
---|
| 228 | + key = kdb_getchar(); |
---|
239 | 229 | if (key != 9) |
---|
240 | 230 | tab = 0; |
---|
241 | 231 | switch (key) { |
---|
.. | .. |
---|
446 | 436 | char *kdb_getstr(char *buffer, size_t bufsize, const char *prompt) |
---|
447 | 437 | { |
---|
448 | 438 | if (prompt && kdb_prompt_str != prompt) |
---|
449 | | - strncpy(kdb_prompt_str, prompt, CMD_BUFLEN); |
---|
| 439 | + strscpy(kdb_prompt_str, prompt, CMD_BUFLEN); |
---|
450 | 440 | kdb_printf(kdb_prompt_str); |
---|
451 | 441 | kdb_nextline = 1; /* Prompt and input resets line number */ |
---|
452 | 442 | return kdb_read(buffer, bufsize); |
---|
.. | .. |
---|
552 | 542 | return 0; |
---|
553 | 543 | } |
---|
554 | 544 | |
---|
| 545 | +static void kdb_msg_write(const char *msg, int msg_len) |
---|
| 546 | +{ |
---|
| 547 | + struct console *c; |
---|
| 548 | + const char *cp; |
---|
| 549 | + int len; |
---|
| 550 | + |
---|
| 551 | + if (msg_len == 0) |
---|
| 552 | + return; |
---|
| 553 | + |
---|
| 554 | + cp = msg; |
---|
| 555 | + len = msg_len; |
---|
| 556 | + |
---|
| 557 | + while (len--) { |
---|
| 558 | + dbg_io_ops->write_char(*cp); |
---|
| 559 | + cp++; |
---|
| 560 | + } |
---|
| 561 | + |
---|
| 562 | + for_each_console(c) { |
---|
| 563 | + if (!(c->flags & CON_ENABLED)) |
---|
| 564 | + continue; |
---|
| 565 | + if (c == dbg_io_ops->cons) |
---|
| 566 | + continue; |
---|
| 567 | + /* |
---|
| 568 | + * Set oops_in_progress to encourage the console drivers to |
---|
| 569 | + * disregard their internal spin locks: in the current calling |
---|
| 570 | + * context the risk of deadlock is a bigger problem than risks |
---|
| 571 | + * due to re-entering the console driver. We operate directly on |
---|
| 572 | + * oops_in_progress rather than using bust_spinlocks() because |
---|
| 573 | + * the calls bust_spinlocks() makes on exit are not appropriate |
---|
| 574 | + * for this calling context. |
---|
| 575 | + */ |
---|
| 576 | + ++oops_in_progress; |
---|
| 577 | + c->write(c, msg, msg_len); |
---|
| 578 | + --oops_in_progress; |
---|
| 579 | + touch_nmi_watchdog(); |
---|
| 580 | + } |
---|
| 581 | +} |
---|
| 582 | + |
---|
555 | 583 | int vkdb_printf(enum kdb_msgsrc src, const char *fmt, va_list ap) |
---|
556 | 584 | { |
---|
557 | 585 | int diag; |
---|
.. | .. |
---|
563 | 591 | int this_cpu, old_cpu; |
---|
564 | 592 | char *cp, *cp2, *cphold = NULL, replaced_byte = ' '; |
---|
565 | 593 | char *moreprompt = "more> "; |
---|
566 | | - struct console *c = console_drivers; |
---|
567 | | - unsigned long uninitialized_var(flags); |
---|
| 594 | + unsigned long flags; |
---|
568 | 595 | |
---|
569 | 596 | /* Serialize kdb_printf if multiple cpus try to write at once. |
---|
570 | 597 | * But if any cpu goes recursive in kdb, just print the output, |
---|
.. | .. |
---|
701 | 728 | */ |
---|
702 | 729 | retlen = strlen(kdb_buffer); |
---|
703 | 730 | cp = (char *) printk_skip_headers(kdb_buffer); |
---|
704 | | - if (!dbg_kdb_mode && kgdb_connected) { |
---|
| 731 | + if (!dbg_kdb_mode && kgdb_connected) |
---|
705 | 732 | gdbstub_msg_write(cp, retlen - (cp - kdb_buffer)); |
---|
706 | | - } else { |
---|
707 | | - if (dbg_io_ops && !dbg_io_ops->is_console) { |
---|
708 | | - len = retlen - (cp - kdb_buffer); |
---|
709 | | - cp2 = cp; |
---|
710 | | - while (len--) { |
---|
711 | | - dbg_io_ops->write_char(*cp2); |
---|
712 | | - cp2++; |
---|
713 | | - } |
---|
714 | | - } |
---|
715 | | - while (c) { |
---|
716 | | - c->write(c, cp, retlen - (cp - kdb_buffer)); |
---|
717 | | - touch_nmi_watchdog(); |
---|
718 | | - c = c->next; |
---|
719 | | - } |
---|
720 | | - } |
---|
| 733 | + else |
---|
| 734 | + kdb_msg_write(cp, retlen - (cp - kdb_buffer)); |
---|
| 735 | + |
---|
721 | 736 | if (logging) { |
---|
722 | 737 | saved_loglevel = console_loglevel; |
---|
723 | 738 | console_loglevel = CONSOLE_LOGLEVEL_SILENT; |
---|
.. | .. |
---|
750 | 765 | |
---|
751 | 766 | /* check for having reached the LINES number of printed lines */ |
---|
752 | 767 | if (kdb_nextline >= linecount) { |
---|
753 | | - char buf1[16] = ""; |
---|
| 768 | + char ch; |
---|
754 | 769 | |
---|
755 | 770 | /* Watch out for recursion here. Any routine that calls |
---|
756 | 771 | * kdb_printf will come back through here. And kdb_read |
---|
.. | .. |
---|
766 | 781 | moreprompt = "more> "; |
---|
767 | 782 | |
---|
768 | 783 | kdb_input_flush(); |
---|
769 | | - c = console_drivers; |
---|
770 | | - |
---|
771 | | - if (dbg_io_ops && !dbg_io_ops->is_console) { |
---|
772 | | - len = strlen(moreprompt); |
---|
773 | | - cp = moreprompt; |
---|
774 | | - while (len--) { |
---|
775 | | - dbg_io_ops->write_char(*cp); |
---|
776 | | - cp++; |
---|
777 | | - } |
---|
778 | | - } |
---|
779 | | - while (c) { |
---|
780 | | - c->write(c, moreprompt, strlen(moreprompt)); |
---|
781 | | - touch_nmi_watchdog(); |
---|
782 | | - c = c->next; |
---|
783 | | - } |
---|
| 784 | + kdb_msg_write(moreprompt, strlen(moreprompt)); |
---|
784 | 785 | |
---|
785 | 786 | if (logging) |
---|
786 | 787 | printk("%s", moreprompt); |
---|
787 | 788 | |
---|
788 | | - kdb_read(buf1, 2); /* '2' indicates to return |
---|
789 | | - * immediately after getting one key. */ |
---|
| 789 | + ch = kdb_getchar(); |
---|
790 | 790 | kdb_nextline = 1; /* Really set output line 1 */ |
---|
791 | 791 | |
---|
792 | 792 | /* empty and reset the buffer: */ |
---|
793 | 793 | kdb_buffer[0] = '\0'; |
---|
794 | 794 | next_avail = kdb_buffer; |
---|
795 | 795 | size_avail = sizeof(kdb_buffer); |
---|
796 | | - if ((buf1[0] == 'q') || (buf1[0] == 'Q')) { |
---|
| 796 | + if ((ch == 'q') || (ch == 'Q')) { |
---|
797 | 797 | /* user hit q or Q */ |
---|
798 | 798 | KDB_FLAG_SET(CMD_INTERRUPT); /* command interrupted */ |
---|
799 | 799 | KDB_STATE_CLEAR(PAGER); |
---|
800 | 800 | /* end of command output; back to normal mode */ |
---|
801 | 801 | kdb_grepping_flag = 0; |
---|
802 | 802 | kdb_printf("\n"); |
---|
803 | | - } else if (buf1[0] == ' ') { |
---|
| 803 | + } else if (ch == ' ') { |
---|
804 | 804 | kdb_printf("\r"); |
---|
805 | 805 | suspend_grep = 1; /* for this recursion */ |
---|
806 | | - } else if (buf1[0] == '\n') { |
---|
| 806 | + } else if (ch == '\n' || ch == '\r') { |
---|
807 | 807 | kdb_nextline = linecount - 1; |
---|
808 | 808 | kdb_printf("\r"); |
---|
809 | 809 | suspend_grep = 1; /* for this recursion */ |
---|
810 | | - } else if (buf1[0] == '/' && !kdb_grepping_flag) { |
---|
| 810 | + } else if (ch == '/' && !kdb_grepping_flag) { |
---|
811 | 811 | kdb_printf("\r"); |
---|
812 | 812 | kdb_getstr(kdb_grep_string, KDB_GREP_STRLEN, |
---|
813 | 813 | kdbgetenv("SEARCHPROMPT") ?: "search> "); |
---|
814 | 814 | *strchrnul(kdb_grep_string, '\n') = '\0'; |
---|
815 | 815 | kdb_grepping_flag += KDB_GREPPING_FLAG_SEARCH; |
---|
816 | 816 | suspend_grep = 1; /* for this recursion */ |
---|
817 | | - } else if (buf1[0] && buf1[0] != '\n') { |
---|
818 | | - /* user hit something other than enter */ |
---|
| 817 | + } else if (ch) { |
---|
| 818 | + /* user hit something unexpected */ |
---|
819 | 819 | suspend_grep = 1; /* for this recursion */ |
---|
820 | | - if (buf1[0] != '/') |
---|
| 820 | + if (ch != '/') |
---|
821 | 821 | kdb_printf( |
---|
822 | 822 | "\nOnly 'q', 'Q' or '/' are processed at " |
---|
823 | 823 | "more prompt, input ignored\n"); |
---|