X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/fe8ab488e9161c46dd9885d58fc52996dc0249ff..cc8bc92ae4a8e9f1a1ab61bf83d34ad8150b3405:/osfmk/kern/printf.c?ds=sidebyside diff --git a/osfmk/kern/printf.c b/osfmk/kern/printf.c index 2ce720c57..54a3220d3 100644 --- a/osfmk/kern/printf.c +++ b/osfmk/kern/printf.c @@ -141,7 +141,7 @@ * + print '+' if positive * blank print ' ' if positive * - * z signed hexadecimal + * z set length equal to size_t * r signed, 'radix' * n unsigned, 'radix' * @@ -159,6 +159,7 @@ #include #include #include +#include #include #include #include @@ -168,6 +169,15 @@ #include #endif #include +#include + +#ifdef __x86_64__ +#include +#endif /* __x86_64__ */ + +#if __arm__ || __arm64__ +#include +#endif #define isdigit(d) ((d) >= '0' && (d) <= '9') #define Ctod(c) ((c) - '0') @@ -214,6 +224,12 @@ printnum( boolean_t _doprnt_truncates = FALSE; +#if (DEVELOPMENT || DEBUG) +boolean_t doprnt_hide_pointers = FALSE; +#else +boolean_t doprnt_hide_pointers = TRUE; +#endif + int __doprnt( const char *fmt, @@ -221,7 +237,8 @@ __doprnt( /* character output routine */ void (*putc)(int, void *arg), void *arg, - int radix) /* default radix - for '%r' */ + int radix, /* default radix - for '%r' */ + int is_log) { int length; int prec; @@ -323,7 +340,14 @@ __doprnt( } else if (c == 'q' || c == 'L') { long_long = 1; c = *++fmt; - } + } + + if (c == 'z' || c == 'Z') { + c = *++fmt; + if (sizeof(size_t) == sizeof(unsigned long)){ + long_long = 1; + } + } truncate = FALSE; capitals=0; /* Assume lower case printing */ @@ -332,9 +356,9 @@ __doprnt( case 'b': case 'B': { - register char *p; + char *p; boolean_t any; - register int i; + int i; if (long_long) { u = va_arg(argp, unsigned long long); @@ -356,7 +380,7 @@ __doprnt( /* * Bit field */ - register int j; + int j; if (any) (*putc)(',', arg); else { @@ -407,8 +431,8 @@ __doprnt( case 's': { - register const char *p; - register const char *p2; + const char *p; + const char *p2; if (prec == -1) prec = 0x7fffffff; /* MAXINT */ @@ -510,17 +534,7 @@ __doprnt( base = 16; capitals=16; /* Print in upper case */ goto print_unsigned; - - case 'z': - truncate = _doprnt_truncates; - base = 16; - goto print_signed; - case 'Z': - base = 16; - capitals=16; /* Print in upper case */ - goto print_signed; - case 'r': truncate = _doprnt_truncates; case 'R': @@ -560,12 +574,27 @@ __doprnt( print_num: { char buf[MAXBUF]; /* build number here */ - register char * p = &buf[MAXBUF-1]; + char * p = &buf[MAXBUF-1]; static char digits[] = "0123456789abcdef0123456789ABCDEF"; const char *prefix = NULL; if (truncate) u = (long long)((int)(u)); + if (doprnt_hide_pointers && is_log) { + const char str[] = ""; + const char* strp = str; + int strl = sizeof(str) - 1; + + if (u >= VM_MIN_KERNEL_AND_KEXT_ADDRESS && u <= VM_MAX_KERNEL_ADDRESS) { + while(*strp != '\0') { + (*putc)(*strp, arg); + strp++; + } + nprinted += strl; + break; + } + } + if (u != 0 && altfmt) { if (base == 8) prefix = "0"; @@ -647,27 +676,46 @@ dummy_putc(int ch, void *arg) void _doprnt( - register const char *fmt, + const char *fmt, va_list *argp, /* character output routine */ void (*putc)(char), int radix) /* default radix - for '%r' */ { - __doprnt(fmt, *argp, dummy_putc, putc, radix); + __doprnt(fmt, *argp, dummy_putc, putc, radix, FALSE); +} + +void +_doprnt_log( + const char *fmt, + va_list *argp, + /* character output routine */ + void (*putc)(char), + int radix) /* default radix - for '%r' */ +{ + __doprnt(fmt, *argp, dummy_putc, putc, radix, TRUE); } #if MP_PRINTF boolean_t new_printf_cpu_number = FALSE; #endif /* MP_PRINTF */ - decl_simple_lock_data(,printf_lock) decl_simple_lock_data(,bsd_log_spinlock) + +/* + * Defined here to allow lock group to be statically allocated. + */ +static lck_grp_t oslog_stream_lock_grp; +decl_lck_spin_data(,oslog_stream_lock) +void oslog_lock_init(void); + extern void bsd_log_init(void); void bsd_log_lock(void); void bsd_log_unlock(void); void + printf_init(void) { /* @@ -690,14 +738,21 @@ bsd_log_unlock(void) simple_unlock(&bsd_log_spinlock); } +void +oslog_lock_init(void) +{ + lck_grp_init(&oslog_stream_lock_grp, "oslog stream", LCK_GRP_ATTR_NULL); + lck_spin_init(&oslog_stream_lock, &oslog_stream_lock_grp, LCK_ATTR_NULL); +} + /* derived from boot_gets */ void safe_gets( char *str, int maxlen) { - register char *lp; - register int c; + char *lp; + int c; char *strmax = str + maxlen - 1; /* allow space for trailing 0 */ lp = str; @@ -745,11 +800,11 @@ void conslog_putc( char c) { - if ((debug_mode && !disable_debug_output) || !disableConsoleOutput) + if (!disableConsoleOutput) cnputc(c); #ifdef MACH_BSD - if (debug_mode == 0) + if (!kernel_debugger_entry_count) log_putc(c); #endif } @@ -758,48 +813,83 @@ void cons_putc_locked( char c) { - if ((debug_mode && !disable_debug_output) || !disableConsoleOutput) + if (!disableConsoleOutput) cnputc(c); } -int -printf(const char *fmt, ...) +static int +vprintf_internal(const char *fmt, va_list ap_in, void *caller) { - va_list listp; - + cpu_data_t * cpu_data_p; if (fmt) { - disable_preemption(); - va_start(listp, fmt); - _doprnt(fmt, &listp, conslog_putc, 16); - va_end(listp); - enable_preemption(); + struct console_printbuf_state info_data; + cpu_data_p = current_cpu_datap(); + + va_list ap; + va_copy(ap, ap_in); + /* + * for early boot printf()s console may not be setup, + * fallback to good old cnputc + */ + if (cpu_data_p->cpu_console_buf != NULL) { + console_printbuf_state_init(&info_data, TRUE, TRUE); + __doprnt(fmt, ap, console_printbuf_putc, &info_data, 16, TRUE); + console_printbuf_clear(&info_data); + } else { + disable_preemption(); + _doprnt_log(fmt, &ap, cons_putc_locked, 16); + enable_preemption(); + } + + va_end(ap); + + os_log_with_args(OS_LOG_DEFAULT, OS_LOG_TYPE_DEFAULT, fmt, ap_in, caller); } return 0; } +__attribute__((noinline,not_tail_called)) +int +printf(const char *fmt, ...) +{ + int ret; + + va_list ap; + va_start(ap, fmt); + ret = vprintf_internal(fmt, ap, __builtin_return_address(0)); + va_end(ap); + + return ret; +} + +__attribute__((noinline,not_tail_called)) +int +vprintf(const char *fmt, va_list ap) +{ + return vprintf_internal(fmt, ap, __builtin_return_address(0)); +} + void consdebug_putc(char c) { - if ((debug_mode && !disable_debug_output) || !disableConsoleOutput) + if (!disableConsoleOutput) cnputc(c); debug_putc(c); - if (!console_is_serial()) - if (!disable_serial_output) - PE_kputc(c); + if (!console_is_serial() && !disable_serial_output) + PE_kputc(c); } void consdebug_putc_unbuffered(char c) { - if ((debug_mode && !disable_debug_output) || !disableConsoleOutput) + if (!disableConsoleOutput) cnputc_unbuffered(c); debug_putc(c); - if (!console_is_serial()) - if (!disable_serial_output) + if (!console_is_serial() && !disable_serial_output) PE_kputc(c); } @@ -809,14 +899,37 @@ consdebug_log(char c) debug_putc(c); } +/* + * Append contents to the paniclog buffer but don't flush + * it. This is mainly used for writing the actual paniclog + * contents since flushing once for every line written + * would be prohibitively expensive for the paniclog + */ +int +paniclog_append_noflush(const char *fmt, ...) +{ + va_list listp; + + va_start(listp, fmt); + _doprnt_log(fmt, &listp, consdebug_putc, 16); + va_end(listp); + + return 0; +} + int kdb_printf(const char *fmt, ...) { va_list listp; va_start(listp, fmt); - _doprnt(fmt, &listp, consdebug_putc, 16); + _doprnt_log(fmt, &listp, consdebug_putc, 16); va_end(listp); + +#if CONFIG_EMBEDDED + paniclog_flush(); +#endif + return 0; } @@ -828,6 +941,11 @@ kdb_log(const char *fmt, ...) va_start(listp, fmt); _doprnt(fmt, &listp, consdebug_log, 16); va_end(listp); + +#if CONFIG_EMBEDDED + paniclog_flush(); +#endif + return 0; } @@ -839,9 +957,15 @@ kdb_printf_unbuffered(const char *fmt, ...) va_start(listp, fmt); _doprnt(fmt, &listp, consdebug_putc_unbuffered, 16); va_end(listp); + +#if CONFIG_EMBEDDED + paniclog_flush(); +#endif + return 0; } +#if !CONFIG_EMBEDDED static void copybyte(int c, void *arg) @@ -869,8 +993,9 @@ sprintf(char *buf, const char *fmt, ...) va_start(listp, fmt); copybyte_str = buf; - __doprnt(fmt, listp, copybyte, ©byte_str, 16); + __doprnt(fmt, listp, copybyte, ©byte_str, 16, FALSE); va_end(listp); *copybyte_str = '\0'; return (int)strlen(buf); } +#endif /* !CONFIG_EMBEDDED */