2 * Copyright (c) 2000-2019 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
33 * Mach Operating System
34 * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University
35 * All Rights Reserved.
37 * Permission to use, copy, modify and distribute this software and its
38 * documentation is hereby granted, provided that both the copyright
39 * notice and this permission notice appear in all copies of the
40 * software, derivative works or modified versions, and any portions
41 * thereof, and that both notices appear in supporting documentation.
43 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
44 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
45 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
47 * Carnegie Mellon requests users of this software to return to
49 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
50 * School of Computer Science
51 * Carnegie Mellon University
52 * Pittsburgh PA 15213-3890
54 * any improvements or extensions that they make and grant Carnegie Mellon
55 * the rights to redistribute these changes.
59 * Common code for printf et al.
61 * The calling routine typically takes a variable number of arguments,
62 * and passes the address of the first one. This implementation
63 * assumes a straightforward, stack implementation, aligned to the
64 * machine's wordsize. Increasing addresses are assumed to point to
65 * successive arguments (left-to-right), as is the case for a machine
66 * with a downward-growing stack with arguments pushed right-to-left.
68 * To write, for example, fprintf() using this routine, the code
70 * fprintf(fd, format, args)
74 * _doprnt(format, &args, fd);
77 * would suffice. (This example does not handle the fprintf's "return
78 * value" correctly, but who looks at the return value of fprintf
81 * This version implements the following printf features:
83 * %d decimal conversion
84 * %u unsigned conversion
85 * %x hexadecimal conversion
86 * %X hexadecimal conversion with capital letters
87 * %D hexdump, ptr & separator string ("%6D", ptr, ":") -> XX:XX:XX:XX:XX:XX
88 * if you use, "%*D" then there's a length, the data ptr and then the separator
92 * %m.n field width, precision
93 * %-m.n left adjustment
95 * %*.* width and precision taken from arguments
97 * This version does not implement %f, %e, or %g.
99 * As mentioned, this version does not return any reasonable value.
101 * Permission is granted to use, modify, or propagate this code as
102 * long as this notice is incorporated.
104 * Steve Summit 3/25/87
106 * Tweaked for long long support and extended to support the hexdump %D
107 * specifier by dbg 05/02/02.
111 * Added formats for decoding device registers:
113 * printf("reg = %b", regval, "<base><arg>*")
115 * where <base> is the output base expressed as a control character:
116 * i.e. '\10' gives octal, '\20' gives hex. Each <arg> is a sequence of
117 * characters, the first of which gives the bit number to be inspected
118 * (origin 1), and the rest (up to a control character (<= 32)) give the
119 * name of the register. Thus
120 * printf("reg = %b\n", 3, "\10\2BITTWO\1BITONE")
122 * reg = 3<BITTWO,BITONE>
124 * If the second character in <arg> is also a control character, it
125 * indicates the last bit of a bit field. In this case, printf will extract
126 * bits <1> to <2> and print it. Characters following the second control
127 * character are printed before the bit field.
128 * printf("reg = %b\n", 0xb, "\10\4\3FIELD1=\2BITTWO\1BITONE")
130 * reg = b<FIELD1=2,BITONE>
132 * The %B format is like %b but the bits are numbered from the most
133 * significant (the bit weighted 31), which is called 1, to the least
134 * significant, called 32.
137 * Added for general use:
138 * # prefix for alternate format:
140 * leading 0 for octal
141 * + print '+' if positive
142 * blank print ' ' if positive
144 * z set length equal to size_t
146 * n unsigned, 'radix'
148 * D,U,O,Z same as corresponding lower-case versions
152 * Added support for print long long (64-bit) integers.
153 * Use %lld, %Ld or %qd to print a 64-bit int. Other
154 * output bases such as x, X, u, U, o, and O also work.
158 #include <mach_kdp.h>
159 #include <mach/boolean.h>
160 #include <kern/cpu_number.h>
161 #include <kern/thread.h>
162 #include <kern/debug.h>
163 #include <kern/sched_prim.h>
164 #include <kern/misc_protos.h>
167 #include <mach_assert.h>
169 #include <sys/msgbuf.h>
171 #include <console/serial_protos.h>
172 #include <os/log_private.h>
175 #include <i386/cpu_data.h>
176 #endif /* __x86_64__ */
178 #if __arm__ || __arm64__
179 #include <arm/cpu_data_internal.h>
183 #include <mach/vm_param.h>
185 #endif /* HAS_APPLE_PAC */
187 #define isdigit(d) ((d) >= '0' && (d) <= '9')
188 #define Ctod(c) ((c) - '0')
190 #define MAXBUF (sizeof(long long int) * 8) /* enough for binary */
191 static char digs
[] = "0123456789abcdef";
193 #if CONFIG_NO_PRINTF_STRINGS
194 /* Prevent CPP from breaking the definition below */
199 _consume_printf_args(int a __unused
, ...)
204 _consume_kprintf_args(int a __unused
, ...)
210 unsigned long long int u
, /* number to print */
212 void (*putc
)(int, void *),
215 char buf
[MAXBUF
]; /* build number here */
216 char * p
= &buf
[MAXBUF
- 1];
220 *p
-- = digs
[u
% base
];
224 while (++p
!= &buf
[MAXBUF
]) {
232 boolean_t _doprnt_truncates
= FALSE
;
234 #if (DEVELOPMENT || DEBUG)
235 boolean_t doprnt_hide_pointers
= FALSE
;
237 boolean_t doprnt_hide_pointers
= TRUE
;
244 /* character output routine */
245 void (*putc
)(int, void *arg
),
247 int radix
, /* default radix - for '%r' */
255 unsigned long long u
;
258 boolean_t altfmt
, truncate
;
267 } numeric_type
= INT
;
270 while ((c
= *fmt
) != '\0') {
294 } else if (c
== '-') {
296 } else if (c
== '+') {
298 } else if (c
== ' ') {
299 if (plus_sign
== 0) {
315 length
= 10 * length
+ Ctod(c
);
318 } else if (c
== '*') {
319 length
= va_arg(argp
, int);
332 prec
= 10 * prec
+ Ctod(c
);
335 } else if (c
== '*') {
336 prec
= va_arg(argp
, int);
342 c
= *++fmt
; /* need it if sizeof(int) < sizeof(long) */
343 if (sizeof(int) < sizeof(long)) {
350 } else if (c
== 'h') {
352 numeric_type
= SHORT
;
357 } else if (c
== 'q' || c
== 'L') {
362 if (c
== 'z' || c
== 'Z') {
364 if (sizeof(size_t) == sizeof(unsigned long)) {
370 capitals
= 0; /* Assume lower case printing */
381 u
= va_arg(argp
, unsigned long long);
383 u
= va_arg(argp
, unsigned int);
385 p
= va_arg(argp
, char *);
387 nprinted
+= printnum(u
, base
, putc
, arg
);
394 while ((i
= *p
++) != '\0') {
414 for (; (c
= *p
) > 32; p
++) {
418 nprinted
+= printnum((unsigned)((u
>> (j
- 1)) & ((2 << (i
- j
)) - 1)),
420 } else if (u
& (1 << (i
- 1))) {
428 for (; (c
= *p
) > 32; p
++) {
433 for (; *p
> 32; p
++) {
446 c
= va_arg(argp
, int);
457 prec
= 0x7fffffff; /* MAXINT */
459 p
= va_arg(argp
, char *);
465 if (length
> 0 && !ladjust
) {
469 for (; *p
!= '\0' && n
< prec
; p
++) {
484 while ((n
< prec
) && (!(length
> 0 && n
>= length
))) {
493 if (n
< length
&& ladjust
) {
505 truncate
= _doprnt_truncates
;
514 up
= (unsigned char *)va_arg(argp
, unsigned char *);
515 p
= (char *)va_arg(argp
, char *);
520 (*putc
)(digs
[(*up
>> 4)], arg
);
521 (*putc
)(digs
[(*up
& 0x0f)], arg
);
525 for (q
= p
; *q
; q
++) {
535 truncate
= _doprnt_truncates
;
540 truncate
= _doprnt_truncates
;
548 if (sizeof(int) < sizeof(void *)) {
553 truncate
= _doprnt_truncates
;
559 capitals
= 16; /* Print in upper case */
563 truncate
= _doprnt_truncates
;
570 truncate
= _doprnt_truncates
;
578 n
= va_arg(argp
, long long);
580 n
= va_arg(argp
, int);
582 switch (numeric_type
) {
594 sign_char
= plus_sign
;
603 u
= va_arg(argp
, unsigned long long);
605 u
= va_arg(argp
, unsigned int);
607 switch (numeric_type
) {
609 u
= (unsigned short)u
;
612 u
= (unsigned char)u
;
621 char buf
[MAXBUF
];/* build number here */
622 char * p
= &buf
[MAXBUF
- 1];
623 static char digits
[] = "0123456789abcdef0123456789ABCDEF";
624 const char *prefix
= NULL
;
627 u
= (long long)((int)(u
));
630 if (doprnt_hide_pointers
&& is_log
) {
631 const char str
[] = "<ptr>";
632 const char* strp
= str
;
633 int strl
= sizeof(str
) - 1;
637 * Strip out the pointer authentication code before
638 * checking whether the pointer is a kernel address.
640 u
= (unsigned long long)VM_KERNEL_STRIP_PTR(u
);
641 #endif /* HAS_APPLE_PAC */
643 if (u
>= VM_MIN_KERNEL_AND_KEXT_ADDRESS
&& u
<= VM_MAX_KERNEL_ADDRESS
) {
644 while (*strp
!= '\0') {
653 if (u
!= 0 && altfmt
) {
656 } else if (base
== 16) {
662 /* Print in the correct case */
663 *p
-- = digits
[(u
% base
) + capitals
];
667 length
-= (int)(&buf
[MAXBUF
- 1] - p
);
672 length
-= (int)strlen(prefix
);
675 if (padc
== ' ' && !ladjust
) {
676 /* blank padding goes before prefix */
677 while (--length
>= 0) {
683 (*putc
)(sign_char
, arg
);
688 (*putc
)(*prefix
++, arg
);
693 /* zero padding goes after sign and prefix */
694 while (--length
>= 0) {
699 while (++p
!= &buf
[MAXBUF
]) {
705 while (--length
>= 0) {
728 dummy_putc(int ch
, void *arg
)
730 void (*real_putc
)(char) = arg
;
733 * Attempts to panic (or otherwise log to console) during early boot
734 * can result in _doprnt() and _doprnt_log() being called from
735 * _kprintf() before PE_init_kprintf() has been called. This causes
736 * the "putc" param to _doprnt() and _doprnt_log() to be passed as
737 * NULL. That NULL makes its way here, and we would try jump to it.
738 * Given that this is a poor idea, and this happens at very early
739 * boot, there is not a way to report this easily (we are likely
740 * already panicing), so we'll just do nothing instead of crashing.
751 /* character output routine */
753 int radix
) /* default radix - for '%r' */
755 __doprnt(fmt
, *argp
, dummy_putc
, putc
, radix
, FALSE
);
762 /* character output routine */
764 int radix
) /* default radix - for '%r' */
766 __doprnt(fmt
, *argp
, dummy_putc
, putc
, radix
, TRUE
);
770 boolean_t new_printf_cpu_number
= FALSE
;
771 #endif /* MP_PRINTF */
773 decl_simple_lock_data(, printf_lock
);
774 decl_simple_lock_data(, bsd_log_spinlock
);
776 lck_grp_t oslog_stream_lock_grp
;
777 decl_lck_spin_data(, oslog_stream_lock
);
778 void oslog_lock_init(void);
780 extern void bsd_log_init(void);
781 void bsd_log_lock(void);
782 void bsd_log_unlock(void);
788 * Lock is only really needed after the first thread is created.
790 simple_lock_init(&printf_lock
, 0);
791 simple_lock_init(&bsd_log_spinlock
, 0);
798 simple_lock(&bsd_log_spinlock
, LCK_GRP_NULL
);
804 simple_unlock(&bsd_log_spinlock
);
808 oslog_lock_init(void)
810 lck_grp_init(&oslog_stream_lock_grp
, "oslog stream", LCK_GRP_ATTR_NULL
);
811 lck_spin_init(&oslog_stream_lock
, &oslog_stream_lock_grp
, LCK_ATTR_NULL
);
814 /* derived from boot_gets */
822 char *strmax
= str
+ maxlen
- 1; /* allow space for trailing 0 */
850 if (c
>= ' ' && c
< '\177') {
855 printf("%c", '\007'); /* beep */
862 extern int disableConsoleOutput
;
868 if (!disableConsoleOutput
) {
873 if (!kernel_debugger_entry_count
) {
883 if (!disableConsoleOutput
) {
889 vprintf_internal(const char *fmt
, va_list ap_in
, void *caller
)
891 cpu_data_t
* cpu_data_p
;
893 struct console_printbuf_state info_data
;
894 cpu_data_p
= current_cpu_datap();
899 * for early boot printf()s console may not be setup,
900 * fallback to good old cnputc
902 if (cpu_data_p
->cpu_console_buf
!= NULL
) {
903 console_printbuf_state_init(&info_data
, TRUE
, TRUE
);
904 __doprnt(fmt
, ap
, console_printbuf_putc
, &info_data
, 16, TRUE
);
905 console_printbuf_clear(&info_data
);
907 disable_preemption();
908 _doprnt_log(fmt
, &ap
, cons_putc_locked
, 16);
914 os_log_with_args(OS_LOG_DEFAULT
, OS_LOG_TYPE_DEFAULT
, fmt
, ap_in
, caller
);
919 __attribute__((noinline
, not_tail_called
))
921 printf(const char *fmt
, ...)
927 ret
= vprintf_internal(fmt
, ap
, __builtin_return_address(0));
933 __attribute__((noinline
, not_tail_called
))
935 vprintf(const char *fmt
, va_list ap
)
937 return vprintf_internal(fmt
, ap
, __builtin_return_address(0));
941 consdebug_putc(char c
)
943 if (!disableConsoleOutput
) {
949 if (!console_is_serial() && !disable_serial_output
) {
955 consdebug_putc_unbuffered(char c
)
957 if (!disableConsoleOutput
) {
958 cnputc_unbuffered(c
);
963 if (!console_is_serial() && !disable_serial_output
) {
969 consdebug_log(char c
)
975 * Append contents to the paniclog buffer but don't flush
976 * it. This is mainly used for writing the actual paniclog
977 * contents since flushing once for every line written
978 * would be prohibitively expensive for the paniclog
981 paniclog_append_noflush(const char *fmt
, ...)
985 va_start(listp
, fmt
);
986 _doprnt_log(fmt
, &listp
, consdebug_putc
, 16);
993 kdb_printf(const char *fmt
, ...)
997 va_start(listp
, fmt
);
998 _doprnt_log(fmt
, &listp
, consdebug_putc
, 16);
1009 kdb_log(const char *fmt
, ...)
1013 va_start(listp
, fmt
);
1014 _doprnt(fmt
, &listp
, consdebug_log
, 16);
1025 kdb_printf_unbuffered(const char *fmt
, ...)
1029 va_start(listp
, fmt
);
1030 _doprnt(fmt
, &listp
, consdebug_putc_unbuffered
, 16);
1040 #if !CONFIG_EMBEDDED
1043 copybyte(int c
, void *arg
)
1046 * arg is a pointer (outside pointer) to the pointer
1047 * (inside pointer) which points to the character.
1048 * We pass a double pointer, so that we can increment
1049 * the inside pointer.
1051 char** p
= arg
; /* cast outside pointer */
1052 **p
= c
; /* store character */
1053 (*p
)++; /* increment inside pointer */
1057 * Deprecation Warning:
1058 * sprintf() is being deprecated. Please use snprintf() instead.
1061 sprintf(char *buf
, const char *fmt
, ...)
1066 va_start(listp
, fmt
);
1068 __doprnt(fmt
, listp
, copybyte
, ©byte_str
, 16, FALSE
);
1070 *copybyte_str
= '\0';
1071 return (int)strlen(buf
);
1073 #endif /* !CONFIG_EMBEDDED */