2  * Copyright (c) 2000-2020 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         if (radix 
< 2 || radix 
> 36) { 
 274         while ((c 
= *fmt
) != '\0') { 
 298                         } else if (c 
== '-') { 
 300                         } else if (c 
== '+') { 
 302                         } else if (c 
== ' ') { 
 303                                 if (plus_sign 
== 0) { 
 319                                 length 
= 10 * length 
+ Ctod(c
); 
 322                 } else if (c 
== '*') { 
 323                         length 
= va_arg(argp
, int); 
 336                                         prec 
= 10 * prec 
+ Ctod(c
); 
 339                         } else if (c 
== '*') { 
 340                                 prec 
= va_arg(argp
, int); 
 346                         c 
= *++fmt
; /* need it if sizeof(int) < sizeof(long) */ 
 347                         if (sizeof(int) < sizeof(long)) { 
 354                 } else if (c 
== 'h') { 
 356                         numeric_type 
= SHORT
; 
 361                 } else if (c 
== 'q' || c 
== 'L') { 
 366                 if (c 
== 'z' || c 
== 'Z') { 
 368                         if (sizeof(size_t) == sizeof(unsigned long)) { 
 374                 capitals 
= 0;   /* Assume lower case printing */ 
 385                                 u 
= va_arg(argp
, unsigned long long); 
 387                                 u 
= va_arg(argp
, unsigned int); 
 389                         p 
= va_arg(argp
, char *); 
 391                         nprinted 
+= printnum(u
, base
, putc
, arg
); 
 398                         while ((i 
= *p
++) != '\0') { 
 418                                         for (; (c 
= *p
) > 32; p
++) { 
 422                                         nprinted 
+= printnum((unsigned)((u 
>> (j 
- 1)) & ((2 << (i 
- j
)) - 1)), 
 424                                 } else if (u 
& (1 << (i 
- 1))) { 
 432                                         for (; (c 
= *p
) > 32; p
++) { 
 437                                         for (; *p 
> 32; p
++) { 
 450                         c 
= (char)va_arg(argp
, int); 
 461                                 prec 
= 0x7fffffff; /* MAXINT */ 
 463                         p 
= va_arg(argp
, char *); 
 469                         if (length 
> 0 && !ladjust
) { 
 473                                 for (; *p 
!= '\0' && n 
< prec
; p
++) { 
 488                         while ((n 
< prec
) && (!(length 
> 0 && n 
>= length
))) { 
 497                         if (n 
< length 
&& ladjust
) { 
 509                         truncate 
= _doprnt_truncates
; 
 519                         up 
= (unsigned char *)va_arg(argp
, unsigned char *); 
 520                         p 
= (char *)va_arg(argp
, char *); 
 525                                 (*putc
)(digs
[(*up 
>> 4)], arg
); 
 526                                 (*putc
)(digs
[(*up 
& 0x0f)], arg
); 
 530                                         for (q 
= p
; *q
; q
++) { 
 541                         truncate 
= _doprnt_truncates
; 
 546                         truncate 
= _doprnt_truncates
; 
 554                         if (sizeof(int) < sizeof(void *)) { 
 559                         truncate 
= _doprnt_truncates
; 
 565                         capitals 
= 16;  /* Print in upper case */ 
 569                         truncate 
= _doprnt_truncates
; 
 576                         truncate 
= _doprnt_truncates
; 
 584                                 n 
= va_arg(argp
, long long); 
 586                                 n 
= va_arg(argp
, int); 
 588                         switch (numeric_type
) { 
 600                                 sign_char 
= plus_sign
; 
 609                                 u 
= va_arg(argp
, unsigned long long); 
 611                                 u 
= va_arg(argp
, unsigned int); 
 613                         switch (numeric_type
) { 
 615                                 u 
= (unsigned short)u
; 
 618                                 u 
= (unsigned char)u
; 
 627                                 char        buf
[MAXBUF
];/* build number here */ 
 628                                 char *      p 
= &buf
[MAXBUF 
- 1]; 
 629                                 static char digits
[] = "0123456789abcdef0123456789ABCDEF"; 
 630                                 const char *prefix 
= NULL
; 
 633                                         u 
= (long long)((int)(u
)); 
 636                                 if (doprnt_hide_pointers 
&& is_log
) { 
 637                                         const char str
[] = "<ptr>"; 
 638                                         const char* strp 
= str
; 
 639                                         int strl 
= sizeof(str
) - 1; 
 643                                          * Strip out the pointer authentication code before 
 644                                          * checking whether the pointer is a kernel address. 
 646                                         u 
= (unsigned long long)VM_KERNEL_STRIP_PTR(u
); 
 647 #endif /* HAS_APPLE_PAC */ 
 649                                         if (u 
>= VM_MIN_KERNEL_AND_KEXT_ADDRESS 
&& u 
<= VM_MAX_KERNEL_ADDRESS
) { 
 650                                                 while (*strp 
!= '\0') { 
 659                                 if (u 
!= 0 && altfmt
) { 
 662                                         } else if (base 
== 16) { 
 668                                         /* Print in the correct case */ 
 669                                         *p
-- = digits
[(u 
% base
) + capitals
]; 
 673                                 length 
-= (int)(&buf
[MAXBUF 
- 1] - p
); 
 678                                         length 
-= (int)strlen(prefix
); 
 681                                 if (padc 
== ' ' && !ladjust
) { 
 682                                         /* blank padding goes before prefix */ 
 683                                         while (--length 
>= 0) { 
 689                                         (*putc
)(sign_char
, arg
); 
 694                                                 (*putc
)(*prefix
++, arg
); 
 699                                         /* zero padding goes after sign and prefix */ 
 700                                         while (--length 
>= 0) { 
 705                                 while (++p 
!= &buf
[MAXBUF
]) { 
 711                                         while (--length 
>= 0) { 
 734 dummy_putc(int ch
, void *arg
) 
 736         void (*real_putc
)(char) = arg
; 
 739          * Attempts to panic (or otherwise log to console) during early boot 
 740          * can result in _doprnt() and _doprnt_log() being called from 
 741          * _kprintf() before PE_init_kprintf() has been called. This causes 
 742          * the "putc" param to _doprnt() and _doprnt_log() to be passed as 
 743          * NULL. That NULL makes its way here, and we would try jump to it. 
 744          * Given that this is a poor idea, and this happens at very early 
 745          * boot, there is not a way to report this easily (we are likely 
 746          * already panicing), so we'll just do nothing instead of crashing. 
 757         /* character output routine */ 
 759         int                     radix
)          /* default radix - for '%r' */ 
 761         __doprnt(fmt
, *argp
, dummy_putc
, putc
, radix
, FALSE
); 
 768         /* character output routine */ 
 770         int                     radix
)          /* default radix - for '%r' */ 
 772         __doprnt(fmt
, *argp
, dummy_putc
, putc
, radix
, TRUE
); 
 776 boolean_t       new_printf_cpu_number 
= FALSE
; 
 777 #endif  /* MP_PRINTF */ 
 779 SIMPLE_LOCK_DECLARE(bsd_log_spinlock
, 0); 
 781 bool bsd_log_lock(bool); 
 782 void bsd_log_lock_safe(void); 
 783 void bsd_log_unlock(void); 
 786  * Locks OS log lock and returns true if successful, false otherwise. Locking 
 787  * always succeeds in a safe context but may block. Locking in an unsafe context 
 788  * never blocks but fails if someone else is already holding the lock. 
 790  * A caller is responsible to decide whether the context is safe or not. 
 792  * As a rule of thumb following cases are *not* considered safe: 
 793  *   - Interrupts are disabled 
 794  *   - Pre-emption is disabled 
 795  *   - When in a debugger 
 799 bsd_log_lock(bool safe
) 
 802                 assert(!oslog_is_safe()); 
 803                 return simple_lock_try(&bsd_log_spinlock
, LCK_GRP_NULL
); 
 805         simple_lock(&bsd_log_spinlock
, LCK_GRP_NULL
); 
 810  * Locks OS log lock assuming the context is safe. See bsd_log_lock() comment 
 814 bsd_log_lock_safe(void) 
 816         (void) bsd_log_lock(true); 
 822         simple_unlock(&bsd_log_spinlock
); 
 825 /* derived from boot_gets */ 
 833         char *strmax 
= str 
+ maxlen 
- 1; /* allow space for trailing 0 */ 
 861                         if (c 
>= ' ' && c 
< '\177') { 
 866                                         printf("%c", '\007'); /* beep */ 
 873 extern int disableConsoleOutput
; 
 879         if (!disableConsoleOutput
) { 
 884         if (!kernel_debugger_entry_count
) { 
 894         if (!disableConsoleOutput
) { 
 900 vprintf_internal(const char *fmt
, va_list ap_in
, void *caller
) 
 902         cpu_data_t 
* cpu_data_p
; 
 904                 struct console_printbuf_state info_data
; 
 905                 cpu_data_p 
= current_cpu_datap(); 
 910                  * for early boot printf()s console may not be setup, 
 911                  * fallback to good old cnputc 
 913                 if (cpu_data_p
->cpu_console_buf 
!= NULL
) { 
 914                         console_printbuf_state_init(&info_data
, TRUE
, TRUE
); 
 915                         __doprnt(fmt
, ap
, console_printbuf_putc
, &info_data
, 16, TRUE
); 
 916                         console_printbuf_clear(&info_data
); 
 918                         disable_preemption(); 
 919                         _doprnt_log(fmt
, &ap
, cons_putc_locked
, 16); 
 925                 os_log_with_args(OS_LOG_DEFAULT
, OS_LOG_TYPE_DEFAULT
, fmt
, ap_in
, caller
); 
 930 __attribute__((noinline
, not_tail_called
)) 
 932 printf(const char *fmt
, ...) 
 938         ret 
= vprintf_internal(fmt
, ap
, __builtin_return_address(0)); 
 944 __attribute__((noinline
, not_tail_called
)) 
 946 vprintf(const char *fmt
, va_list ap
) 
 948         return vprintf_internal(fmt
, ap
, __builtin_return_address(0)); 
 952 consdebug_putc(char c
) 
 954         if (!disableConsoleOutput
) { 
 960         if (!console_is_serial() && !disable_serial_output
) { 
 966 consdebug_putc_unbuffered(char c
) 
 968         if (!disableConsoleOutput
) { 
 969                 cnputc_unbuffered(c
); 
 974         if (!console_is_serial() && !disable_serial_output
) { 
 980 consdebug_log(char c
) 
 986  * Append contents to the paniclog buffer but don't flush 
 987  * it. This is mainly used for writing the actual paniclog 
 988  * contents since flushing once for every line written 
 989  * would be prohibitively expensive for the paniclog 
 992 paniclog_append_noflush(const char *fmt
, ...) 
 996         va_start(listp
, fmt
); 
 997         _doprnt_log(fmt
, &listp
, consdebug_putc_unbuffered
, 16); 
1004 kdb_printf(const char *fmt
, ...) 
1008         va_start(listp
, fmt
); 
1009         _doprnt_log(fmt
, &listp
, consdebug_putc
, 16); 
1012 #if defined(__arm__) || defined(__arm64__) 
1020 kdb_log(const char *fmt
, ...) 
1024         va_start(listp
, fmt
); 
1025         _doprnt(fmt
, &listp
, consdebug_log
, 16); 
1028 #if defined(__arm__) || defined(__arm64__) 
1036 kdb_printf_unbuffered(const char *fmt
, ...) 
1040         va_start(listp
, fmt
); 
1041         _doprnt(fmt
, &listp
, consdebug_putc_unbuffered
, 16); 
1044 #if defined(__arm__) || defined(__arm64__) 
1053 copybyte(int c
, void *arg
) 
1056          * arg is a pointer (outside pointer) to the pointer 
1057          * (inside pointer) which points to the character. 
1058          * We pass a double pointer, so that we can increment 
1059          * the inside pointer. 
1061         char** p 
= arg
; /* cast outside pointer */ 
1062         **p 
= (char)c
;  /* store character */ 
1063         (*p
)++;         /* increment inside pointer */ 
1067  * Deprecation Warning: 
1068  *      sprintf() is being deprecated. Please use snprintf() instead. 
1071 sprintf(char *buf
, const char *fmt
, ...) 
1076         va_start(listp
, fmt
); 
1078         __doprnt(fmt
, listp
, copybyte
, ©byte_str
, 16, FALSE
); 
1080         *copybyte_str 
= '\0'; 
1081         return (int)strlen(buf
); 
1083 #endif /* CONFIG_VSPRINTF */