This source file includes following definitions.
- __assert
- tablefull
- panic
- splassert_fail
- log
- logpri
- addlog
- kputchar
- uprintf
- tprintf_open
- tprintf_close
- tprintf
- ttyprintf
- db_printf
- printf
- vprintf
- snprintf
- vsnprintf
- kprintf
- puts
- putchar
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/buf.h>
43 #include <sys/conf.h>
44 #include <sys/reboot.h>
45 #include <sys/msgbuf.h>
46 #include <sys/proc.h>
47 #include <sys/ioctl.h>
48 #include <sys/vnode.h>
49 #include <sys/file.h>
50 #include <sys/tty.h>
51 #include <sys/tprintf.h>
52 #include <sys/syslog.h>
53 #include <sys/malloc.h>
54 #include <sys/pool.h>
55 #include <sys/mutex.h>
56
57 #include <dev/cons.h>
58
59
60
61
62
63 #include <sys/stdarg.h>
64
65 #ifdef KGDB
66 #include <sys/kgdb.h>
67 #include <machine/cpu.h>
68 #endif
69 #ifdef DDB
70 #include <ddb/db_output.h>
71 #include <ddb/db_var.h>
72 #endif
73 #if defined(UVM_SWAP_ENCRYPT)
74 extern int uvm_doswapencrypt;
75 #endif
76
77
78
79
80
81
82
83 #define TOCONS 0x01
84 #define TOTTY 0x02
85 #define TOLOG 0x04
86 #define TOBUFONLY 0x08
87 #define TODDB 0x10
88 #define TOCOUNT 0x20
89
90
91 #define KPRINTF_BUFSIZE (sizeof(quad_t) * NBBY / 3 + 2)
92
93
94
95
96
97
98 int kprintf(const char *, int, void *, char *, va_list);
99 void kputchar(int, int, struct tty *);
100
101 struct mutex kprintf_mutex = MUTEX_INITIALIZER(IPL_HIGH);
102
103
104
105
106
107 extern struct tty *constty;
108 int consintr = 1;
109 extern int log_open;
110 const char *panicstr;
111
112 #ifdef DDB
113
114
115
116 int db_panic = 1;
117
118
119
120
121
122
123
124
125 #ifdef DDB_SAFE_CONSOLE
126 int db_console = 1;
127 #else
128 int db_console = 0;
129 #endif
130 #endif
131
132
133
134
135 int splassert_ctl = 1;
136
137
138
139
140
141
142
143
144 void (*v_putc)(int) = cnputc;
145
146
147
148
149
150
151
152
153
154
155 void
156 __assert(const char *t, const char *f, int l, const char *e)
157 {
158
159 panic("kernel %sassertion \"%s\" failed: file \"%s\", line %d",
160 t, e, f, l);
161 }
162
163
164
165
166
167 void
168 tablefull(const char *tab)
169 {
170 log(LOG_ERR, "%s: table is full\n", tab);
171 }
172
173
174
175
176
177
178
179
180
181 void
182 panic(const char *fmt, ...)
183 {
184 static char panicbuf[512];
185 int bootopt;
186 va_list ap;
187
188 bootopt = RB_AUTOBOOT | RB_DUMP;
189 #if defined(UVM_SWAP_ENCRYPT)
190 if (uvm_doswapencrypt)
191 bootopt &= ~RB_DUMP;
192 #endif
193 va_start(ap, fmt);
194 if (panicstr)
195 bootopt |= RB_NOSYNC;
196 else {
197 vsnprintf(panicbuf, sizeof panicbuf, fmt, ap);
198 panicstr = panicbuf;
199 }
200 va_end(ap);
201
202 printf("panic: ");
203 va_start(ap, fmt);
204 vprintf(fmt, ap);
205 printf("\n");
206 va_end(ap);
207
208 #ifdef KGDB
209 kgdb_panic();
210 #endif
211 #ifdef KADB
212 if (boothowto & RB_KDB)
213 kdbpanic();
214 #endif
215 #ifdef DDB
216 if (db_panic)
217 Debugger();
218 else
219 db_stack_dump();
220 #endif
221 boot(bootopt);
222 }
223
224
225
226
227
228 void
229 splassert_fail(int wantipl, int haveipl, const char *func)
230 {
231
232 printf("splassert: %s: want %d have %d\n", func, wantipl, haveipl);
233 switch (splassert_ctl) {
234 case 1:
235 break;
236 case 2:
237 #ifdef DDB
238 db_stack_dump();
239 #endif
240 break;
241 case 3:
242 #ifdef DDB
243 db_stack_dump();
244 Debugger();
245 #endif
246 break;
247 default:
248 panic("spl assertion failure in %s", func);
249 }
250 }
251
252
253
254
255
256
257
258
259
260
261
262
263 void
264 log(int level, const char *fmt, ...)
265 {
266 int s;
267 va_list ap;
268
269 s = splhigh();
270 logpri(level);
271 va_start(ap, fmt);
272 kprintf(fmt, TOLOG, NULL, NULL, ap);
273 va_end(ap);
274 splx(s);
275 if (!log_open) {
276 va_start(ap, fmt);
277 kprintf(fmt, TOCONS, NULL, NULL, ap);
278 va_end(ap);
279 }
280 logwakeup();
281 }
282
283
284
285
286
287 void
288 logpri(int level)
289 {
290 char *p;
291 char snbuf[KPRINTF_BUFSIZE];
292
293 kputchar('<', TOLOG, NULL);
294 snprintf(snbuf, sizeof snbuf, "%d", level);
295 for (p = snbuf ; *p ; p++)
296 kputchar(*p, TOLOG, NULL);
297 kputchar('>', TOLOG, NULL);
298 }
299
300
301
302
303
304 int
305 addlog(const char *fmt, ...)
306 {
307 int s;
308 va_list ap;
309
310 s = splhigh();
311 va_start(ap, fmt);
312 kprintf(fmt, TOLOG, NULL, NULL, ap);
313 va_end(ap);
314 splx(s);
315 if (!log_open) {
316 va_start(ap, fmt);
317 kprintf(fmt, TOCONS, NULL, NULL, ap);
318 va_end(ap);
319 }
320 logwakeup();
321 return(0);
322 }
323
324
325
326
327
328
329
330
331 void
332 kputchar(int c, int flags, struct tty *tp)
333 {
334 extern int msgbufmapped;
335
336 if (panicstr)
337 constty = NULL;
338 if ((flags & TOCONS) && tp == NULL && constty) {
339 tp = constty;
340 flags |= TOTTY;
341 }
342 if ((flags & TOTTY) && tp && tputchar(c, tp) < 0 &&
343 (flags & TOCONS) && tp == constty)
344 constty = NULL;
345 if ((flags & TOLOG) &&
346 c != '\0' && c != '\r' && c != 0177 && msgbufmapped)
347 msgbuf_putchar(c);
348 if ((flags & TOCONS) && constty == NULL && c != '\0')
349 (*v_putc)(c);
350 #ifdef DDB
351 if (flags & TODDB)
352 db_putchar(c);
353 #endif
354 }
355
356
357
358
359
360
361
362
363
364
365 void
366 uprintf(const char *fmt, ...)
367 {
368 struct proc *p = curproc;
369 va_list ap;
370
371 if (p->p_flag & P_CONTROLT && p->p_session->s_ttyvp) {
372 va_start(ap, fmt);
373 kprintf(fmt, TOTTY, p->p_session->s_ttyp, NULL, ap);
374 va_end(ap);
375 }
376 }
377
378 #if defined(NFSSERVER) || defined(NFSCLIENT)
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395 tpr_t
396 tprintf_open(struct proc *p)
397 {
398
399 if (p->p_flag & P_CONTROLT && p->p_session->s_ttyvp) {
400 SESSHOLD(p->p_session);
401 return ((tpr_t) p->p_session);
402 }
403 return ((tpr_t) NULL);
404 }
405
406
407
408
409
410 void
411 tprintf_close(tpr_t sess)
412 {
413
414 if (sess)
415 SESSRELE((struct session *) sess);
416 }
417
418
419
420
421
422
423
424 void
425 tprintf(tpr_t tpr, const char *fmt, ...)
426 {
427 struct session *sess = (struct session *)tpr;
428 struct tty *tp = NULL;
429 int flags = TOLOG;
430 va_list ap;
431
432 logpri(LOG_INFO);
433 if (sess && sess->s_ttyvp && ttycheckoutq(sess->s_ttyp, 0)) {
434 flags |= TOTTY;
435 tp = sess->s_ttyp;
436 }
437 va_start(ap, fmt);
438 kprintf(fmt, flags, tp, NULL, ap);
439 va_end(ap);
440 logwakeup();
441 }
442
443 #endif
444
445
446
447
448
449
450
451
452
453 void
454 ttyprintf(struct tty *tp, const char *fmt, ...)
455 {
456 va_list ap;
457
458 va_start(ap, fmt);
459 kprintf(fmt, TOTTY, tp, NULL, ap);
460 va_end(ap);
461 }
462
463 #ifdef DDB
464
465
466
467
468
469 int
470 db_printf(const char *fmt, ...)
471 {
472 va_list ap;
473 int flags, retval;
474
475 flags = TODDB;
476 if (db_log)
477 flags |= TOLOG;
478 va_start(ap, fmt);
479 retval = kprintf(fmt, flags, NULL, NULL, ap);
480 va_end(ap);
481 return(retval);
482 }
483
484 #endif
485
486
487
488
489
490
491
492
493
494 int
495 printf(const char *fmt, ...)
496 {
497 va_list ap;
498 int savintr, retval;
499
500 mtx_enter(&kprintf_mutex);
501
502 savintr = consintr;
503 consintr = 0;
504 va_start(ap, fmt);
505 retval = kprintf(fmt, TOCONS | TOLOG, NULL, NULL, ap);
506 va_end(ap);
507 if (!panicstr)
508 logwakeup();
509 consintr = savintr;
510
511 mtx_leave(&kprintf_mutex);
512
513 return(retval);
514 }
515
516
517
518
519
520
521 int
522 vprintf(const char *fmt, va_list ap)
523 {
524 int savintr, retval;
525
526 mtx_enter(&kprintf_mutex);
527
528 savintr = consintr;
529 consintr = 0;
530 retval = kprintf(fmt, TOCONS | TOLOG, NULL, NULL, ap);
531 if (!panicstr)
532 logwakeup();
533 consintr = savintr;
534
535 mtx_leave(&kprintf_mutex);
536
537 return (retval);
538 }
539
540
541
542
543 int
544 snprintf(char *buf, size_t size, const char *fmt, ...)
545 {
546 int retval;
547 va_list ap;
548 char *p;
549
550 p = buf + size - 1;
551 if (size < 1)
552 p = buf;
553 va_start(ap, fmt);
554 retval = kprintf(fmt, TOBUFONLY | TOCOUNT, &p, buf, ap);
555 va_end(ap);
556 if (size > 0)
557 *(p) = 0;
558 return(retval);
559 }
560
561
562
563
564 int
565 vsnprintf(char *buf, size_t size, const char *fmt, va_list ap)
566 {
567 int retval;
568 char *p;
569
570 p = buf + size - 1;
571 if (size < 1)
572 p = buf;
573 retval = kprintf(fmt, TOBUFONLY | TOCOUNT, &p, buf, ap);
574 if (size > 0)
575 *(p) = 0;
576 return(retval);
577 }
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622 #define to_digit(c) ((c) - '0')
623 #define is_digit(c) ((unsigned)to_digit(c) <= 9)
624 #define to_char(n) ((n) + '0')
625
626
627
628
629 #define ALT 0x001
630 #define HEXPREFIX 0x002
631 #define LADJUST 0x004
632 #define LONGDBL 0x008
633 #define LONGINT 0x010
634 #define QUADINT 0x020
635 #define SHORTINT 0x040
636 #define ZEROPAD 0x080
637 #define FPT 0x100
638
639
640
641
642
643 #define SARG() \
644 (flags&QUADINT ? va_arg(ap, quad_t) : \
645 flags&LONGINT ? va_arg(ap, long) : \
646 flags&SHORTINT ? (long)(short)va_arg(ap, int) : \
647 (long)va_arg(ap, int))
648 #define UARG() \
649 (flags&QUADINT ? va_arg(ap, u_quad_t) : \
650 flags&LONGINT ? va_arg(ap, u_long) : \
651 flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \
652 (u_long)va_arg(ap, u_int))
653
654 #define KPRINTF_PUTCHAR(C) do { \
655 int chr = (C); \
656 ret += 1; \
657 if (oflags & TOBUFONLY) { \
658 if ((vp != NULL) && (sbuf == tailp)) { \
659 if (!(oflags & TOCOUNT)) \
660 goto overflow; \
661 } else \
662 *sbuf++ = chr; \
663 } else { \
664 kputchar(chr, oflags, (struct tty *)vp); \
665 } \
666 } while(0)
667
668 int
669 kprintf(const char *fmt0, int oflags, void *vp, char *sbuf, va_list ap)
670 {
671 char *fmt;
672 int ch;
673 int n;
674 char *cp = NULL;
675 int flags;
676 int ret;
677 int width;
678 int prec;
679 char sign;
680
681 u_quad_t _uquad;
682 enum { OCT, DEC, HEX } base;
683 int dprec;
684 int realsz;
685 int size = 0;
686 char *xdigs = NULL;
687 char buf[KPRINTF_BUFSIZE];
688 char *tailp = NULL;
689
690 if ((oflags & TOBUFONLY) && (vp != NULL))
691 tailp = *(char **)vp;
692
693 fmt = (char *)fmt0;
694 ret = 0;
695
696
697
698
699 for (;;) {
700 while (*fmt != '%' && *fmt) {
701 KPRINTF_PUTCHAR(*fmt++);
702 }
703 if (*fmt == 0)
704 goto done;
705
706 fmt++;
707
708 flags = 0;
709 dprec = 0;
710 width = 0;
711 prec = -1;
712 sign = '\0';
713
714 rflag: ch = *fmt++;
715 reswitch: switch (ch) {
716
717 case 'b': {
718 char *b, *z;
719 int tmp;
720 _uquad = UARG();
721 b = va_arg(ap, char *);
722 if (*b == 8)
723 snprintf(buf, sizeof buf, "%llo", _uquad);
724 else if (*b == 10)
725 snprintf(buf, sizeof buf, "%lld", _uquad);
726 else if (*b == 16)
727 snprintf(buf, sizeof buf, "%llx", _uquad);
728 else
729 break;
730 b++;
731
732 z = buf;
733 while (*z) {
734 KPRINTF_PUTCHAR(*z++);
735 }
736
737 if (_uquad) {
738 tmp = 0;
739 while ((n = *b++) != 0) {
740 if (n & 0x80)
741 n &= 0x7f;
742 else if (n <= ' ')
743 n = n - 1;
744 if (_uquad & (1LL << n)) {
745 KPRINTF_PUTCHAR(tmp ? ',':'<');
746 while (*b > ' ' &&
747 (*b & 0x80) == 0) {
748 KPRINTF_PUTCHAR(*b);
749 b++;
750 }
751 tmp = 1;
752 } else {
753 while (*b > ' ' &&
754 (*b & 0x80) == 0)
755 b++;
756 }
757 }
758 if (tmp) {
759 KPRINTF_PUTCHAR('>');
760 }
761 }
762 continue;
763 }
764
765 #ifdef DDB
766
767 case 'r':
768 if ((oflags & TODDB) == 0)
769 goto default_case;
770
771 if (db_radix == 16)
772 goto case_z;
773 _uquad = SARG();
774 if ((quad_t)_uquad < 0) {
775 _uquad = -_uquad;
776 sign = '-';
777 }
778 base = (db_radix == 8) ? OCT : DEC;
779 goto number;
780
781
782
783 case 'z':
784 case_z:
785 if ((oflags & TODDB) == 0)
786 goto default_case;
787
788 xdigs = "0123456789abcdef";
789 ch = 'x';
790 _uquad = SARG();
791 base = HEX;
792
793 if (flags & ALT && _uquad != 0)
794 flags |= HEXPREFIX;
795 if ((quad_t)_uquad < 0) {
796 _uquad = -_uquad;
797 sign = '-';
798 }
799 goto number;
800 #endif
801
802 case ' ':
803
804
805
806
807
808 if (!sign)
809 sign = ' ';
810 goto rflag;
811 case '#':
812 flags |= ALT;
813 goto rflag;
814 case '*':
815
816
817
818
819
820
821 if ((width = va_arg(ap, int)) >= 0)
822 goto rflag;
823 width = -width;
824
825 case '-':
826 flags |= LADJUST;
827 goto rflag;
828 case '+':
829 sign = '+';
830 goto rflag;
831 case '.':
832 if ((ch = *fmt++) == '*') {
833 n = va_arg(ap, int);
834 prec = n < 0 ? -1 : n;
835 goto rflag;
836 }
837 n = 0;
838 while (is_digit(ch)) {
839 n = 10 * n + to_digit(ch);
840 ch = *fmt++;
841 }
842 prec = n < 0 ? -1 : n;
843 goto reswitch;
844 case '0':
845
846
847
848
849
850 flags |= ZEROPAD;
851 goto rflag;
852 case '1': case '2': case '3': case '4':
853 case '5': case '6': case '7': case '8': case '9':
854 n = 0;
855 do {
856 n = 10 * n + to_digit(ch);
857 ch = *fmt++;
858 } while (is_digit(ch));
859 width = n;
860 goto reswitch;
861 case 'h':
862 flags |= SHORTINT;
863 goto rflag;
864 case 'l':
865 if (*fmt == 'l') {
866 fmt++;
867 flags |= QUADINT;
868 } else {
869 flags |= LONGINT;
870 }
871 goto rflag;
872 case 'q':
873 flags |= QUADINT;
874 goto rflag;
875 case 'c':
876 *(cp = buf) = va_arg(ap, int);
877 size = 1;
878 sign = '\0';
879 break;
880 case 'D':
881 flags |= LONGINT;
882
883 case 'd':
884 case 'i':
885 _uquad = SARG();
886 if ((quad_t)_uquad < 0) {
887 _uquad = -_uquad;
888 sign = '-';
889 }
890 base = DEC;
891 goto number;
892 case 'n':
893 #ifdef DDB
894
895
896
897
898
899
900
901
902 if (oflags & TODDB) {
903 if (db_radix == 16)
904 ch = 'x';
905 else if (db_radix == 8)
906 ch = 'o';
907 else
908 ch = 'u';
909
910
911 goto reswitch;
912 }
913
914 #endif
915 if (flags & QUADINT)
916 *va_arg(ap, quad_t *) = ret;
917 else if (flags & LONGINT)
918 *va_arg(ap, long *) = ret;
919 else if (flags & SHORTINT)
920 *va_arg(ap, short *) = ret;
921 else
922 *va_arg(ap, int *) = ret;
923 continue;
924 case 'O':
925 flags |= LONGINT;
926
927 case 'o':
928 _uquad = UARG();
929 base = OCT;
930 goto nosign;
931 case 'p':
932
933
934
935
936
937
938
939
940 _uquad = (u_long)va_arg(ap, void *);
941 base = HEX;
942 xdigs = "0123456789abcdef";
943 flags |= HEXPREFIX;
944 ch = 'x';
945 goto nosign;
946 case 's':
947 if ((cp = va_arg(ap, char *)) == NULL)
948 cp = "(null)";
949 if (prec >= 0) {
950
951
952
953
954
955 char *p = memchr(cp, 0, prec);
956
957 if (p != NULL) {
958 size = p - cp;
959 if (size > prec)
960 size = prec;
961 } else
962 size = prec;
963 } else
964 size = strlen(cp);
965 sign = '\0';
966 break;
967 case 'U':
968 flags |= LONGINT;
969
970 case 'u':
971 _uquad = UARG();
972 base = DEC;
973 goto nosign;
974 case 'X':
975 xdigs = "0123456789ABCDEF";
976 goto hex;
977 case 'x':
978 xdigs = "0123456789abcdef";
979 hex: _uquad = UARG();
980 base = HEX;
981
982 if (flags & ALT && _uquad != 0)
983 flags |= HEXPREFIX;
984
985
986 nosign: sign = '\0';
987
988
989
990
991
992 number: if ((dprec = prec) >= 0)
993 flags &= ~ZEROPAD;
994
995
996
997
998
999
1000 cp = buf + KPRINTF_BUFSIZE;
1001 if (_uquad != 0 || prec != 0) {
1002
1003
1004
1005
1006
1007 switch (base) {
1008 case OCT:
1009 do {
1010 *--cp = to_char(_uquad & 7);
1011 _uquad >>= 3;
1012 } while (_uquad);
1013
1014 if (flags & ALT && *cp != '0')
1015 *--cp = '0';
1016 break;
1017
1018 case DEC:
1019
1020 while (_uquad >= 10) {
1021 *--cp = to_char(_uquad % 10);
1022 _uquad /= 10;
1023 }
1024 *--cp = to_char(_uquad);
1025 break;
1026
1027 case HEX:
1028 do {
1029 *--cp = xdigs[_uquad & 15];
1030 _uquad >>= 4;
1031 } while (_uquad);
1032 break;
1033
1034 default:
1035 cp = "bug in kprintf: bad base";
1036 size = strlen(cp);
1037 goto skipsize;
1038 }
1039 }
1040 size = buf + KPRINTF_BUFSIZE - cp;
1041 skipsize:
1042 break;
1043 default:
1044 #ifdef DDB
1045 default_case:
1046 #endif
1047 if (ch == '\0')
1048 goto done;
1049
1050 cp = buf;
1051 *cp = ch;
1052 size = 1;
1053 sign = '\0';
1054 break;
1055 }
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071 realsz = dprec > size ? dprec : size;
1072 if (sign)
1073 realsz++;
1074 else if (flags & HEXPREFIX)
1075 realsz+= 2;
1076
1077
1078 if ((flags & (LADJUST|ZEROPAD)) == 0) {
1079 n = width - realsz;
1080 while (n-- > 0)
1081 KPRINTF_PUTCHAR(' ');
1082 }
1083
1084
1085 if (sign) {
1086 KPRINTF_PUTCHAR(sign);
1087 } else if (flags & HEXPREFIX) {
1088 KPRINTF_PUTCHAR('0');
1089 KPRINTF_PUTCHAR(ch);
1090 }
1091
1092
1093 if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) {
1094 n = width - realsz;
1095 while (n-- > 0)
1096 KPRINTF_PUTCHAR('0');
1097 }
1098
1099
1100 n = dprec - size;
1101 while (n-- > 0)
1102 KPRINTF_PUTCHAR('0');
1103
1104
1105 while (size--)
1106 KPRINTF_PUTCHAR(*cp++);
1107
1108 if (flags & LADJUST) {
1109 n = width - realsz;
1110 while (n-- > 0)
1111 KPRINTF_PUTCHAR(' ');
1112 }
1113 }
1114
1115 done:
1116 if ((oflags & TOBUFONLY) && (vp != NULL))
1117 *(char **)vp = sbuf;
1118 overflow:
1119 return (ret);
1120
1121 }
1122
1123 #if __GNUC_PREREQ__(2,96)
1124
1125
1126
1127
1128
1129
1130
1131 int puts(const char *);
1132 int putchar(int c);
1133
1134 int
1135 puts(const char *str)
1136 {
1137 printf("%s\n", str);
1138
1139 return (0);
1140 }
1141
1142 int
1143 putchar(int c)
1144 {
1145 printf("%c", c);
1146
1147 return (c);
1148 }
1149
1150
1151 #endif